@@ -39248,6 +39248,47 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
3924839248 return ret;
3924939249 }
3925039250
39251+ #ifdef HAVE_SNI
39252+ /* Hash the server-selected SNI into dst (TICKET_BINDING_HASH_SZ bytes).
39253+ * Zeros dst when no SNI is present. */
39254+ static int TicketSniHash(WOLFSSL* ssl, byte* dst)
39255+ {
39256+ char* name = NULL;
39257+ word16 nameLen;
39258+
39259+ nameLen = TLSX_SNI_GetRequest(ssl->extensions,
39260+ WOLFSSL_SNI_HOST_NAME,
39261+ (void**)&name, 0);
39262+ if (name != NULL && nameLen > 0) {
39263+ return wc_Hash(TICKET_BINDING_HASH_TYPE, (const byte*)name,
39264+ nameLen, dst, TICKET_BINDING_HASH_SZ);
39265+ }
39266+
39267+ XMEMSET(dst, 0, TICKET_BINDING_HASH_SZ);
39268+ return 0;
39269+ }
39270+ #endif
39271+
39272+ #ifdef HAVE_ALPN
39273+ /* Hash the negotiated ALPN protocol into dst (TICKET_BINDING_HASH_SZ
39274+ * bytes). Zeros dst when no ALPN was negotiated. */
39275+ static int TicketAlpnHash(WOLFSSL* ssl, byte* dst)
39276+ {
39277+ char* proto = NULL;
39278+ word16 protoLen = 0;
39279+
39280+ if (TLSX_ALPN_GetRequest(ssl->extensions, (void**)&proto,
39281+ &protoLen) == WOLFSSL_SUCCESS &&
39282+ proto != NULL && protoLen > 0) {
39283+ return wc_Hash(TICKET_BINDING_HASH_TYPE, (const byte*)proto,
39284+ protoLen, dst, TICKET_BINDING_HASH_SZ);
39285+ }
39286+
39287+ XMEMSET(dst, 0, TICKET_BINDING_HASH_SZ);
39288+ return 0;
39289+ }
39290+ #endif
39291+
3925139292 /* create a new session ticket, 0 on success
3925239293 * Do any kind of setup in SetupTicket */
3925339294 int CreateTicket(WOLFSSL* ssl)
@@ -39346,6 +39387,18 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
3934639387 it->sessionCtxSz = ssl->sessionCtxSz;
3934739388 XMEMCPY(it->sessionCtx, ssl->sessionCtx, ID_LEN);
3934839389#endif
39390+ #ifdef HAVE_SNI
39391+ ret = TicketSniHash(ssl, it->sniHash);
39392+ if (ret != 0)
39393+ goto error;
39394+ XMEMCPY(ssl->session->sniHash, it->sniHash, TICKET_BINDING_HASH_SZ);
39395+ #endif
39396+ #ifdef HAVE_ALPN
39397+ ret = TicketAlpnHash(ssl, it->alpnHash);
39398+ if (ret != 0)
39399+ goto error;
39400+ XMEMCPY(ssl->session->alpnHash, it->alpnHash, TICKET_BINDING_HASH_SZ);
39401+ #endif
3934939402
3935039403#if defined(OPENSSL_ALL) && defined(KEEP_PEER_CERT) && \
3935139404 !defined(NO_CERT_IN_TICKET)
@@ -39700,6 +39753,28 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
3970039753 XMEMCMP(psk->it->sessionCtx, ssl->sessionCtx,
3970139754 ssl->sessionCtxSz) != 0))
3970239755 return WOLFSSL_FATAL_ERROR;
39756+ #endif
39757+ #ifdef HAVE_SNI
39758+ {
39759+ byte curHash[TICKET_BINDING_HASH_SZ];
39760+ if (TicketSniHash((WOLFSSL*)ssl, curHash) != 0 ||
39761+ XMEMCMP(curHash, psk->it->sniHash,
39762+ TICKET_BINDING_HASH_SZ) != 0) {
39763+ WOLFSSL_MSG("Ticket SNI mismatch");
39764+ return WOLFSSL_FATAL_ERROR;
39765+ }
39766+ }
39767+ #endif
39768+ #ifdef HAVE_ALPN
39769+ {
39770+ byte curHash[TICKET_BINDING_HASH_SZ];
39771+ if (TicketAlpnHash((WOLFSSL*)ssl, curHash) != 0 ||
39772+ XMEMCMP(curHash, psk->it->alpnHash,
39773+ TICKET_BINDING_HASH_SZ) != 0) {
39774+ WOLFSSL_MSG("Ticket ALPN mismatch");
39775+ return WOLFSSL_FATAL_ERROR;
39776+ }
39777+ }
3970339778#endif
3970439779 return 0;
3970539780 }
@@ -39712,36 +39787,54 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
3971239787 word16 peerCertLen = 0;
3971339788 ato16(it->peerCertLen, &peerCertLen);
3971439789
39715- if (peerCertLen > 0 && peerCertLen <= MAX_TICKET_PEER_CERT_SZ) {
39790+ /* Clear any peer cert state that may have been copied from the session
39791+ * cache by wolfSSL_DupSession before we got here. */
39792+ FreeX509(&ssl->peerCert);
39793+ InitX509(&ssl->peerCert, 0, ssl->heap);
3971639794#ifdef SESSION_CERTS
39717- /* Clear existing chain and add the peer certificate */
39718- ssl->session->chain.count = 0;
39719- AddSessionCertToChain(&ssl->session->chain,
39720- it->peerCert, peerCertLen);
39795+ ssl->session->chain.count = 0;
3972139796#endif
39722- /* Also decode into ssl->peerCert for direct access */
39723- {
39724- int ret;
39725- DecodedCert* dCert;
39726-
39727- dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap,
39728- DYNAMIC_TYPE_DCERT);
39729- if (dCert != NULL) {
39730- InitDecodedCert(dCert, it->peerCert, peerCertLen, ssl->heap);
39731- ret = ParseCertRelative(dCert, CERT_TYPE, 0, NULL, NULL);
39732- if (ret == 0) {
39797+
39798+ if (peerCertLen > 0 && peerCertLen <= MAX_TICKET_PEER_CERT_SZ) {
39799+ int ret;
39800+ DecodedCert* dCert;
39801+
39802+ dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap,
39803+ DYNAMIC_TYPE_DCERT);
39804+ if (dCert != NULL) {
39805+ int verify = ssl->options.verifyPeer ? VERIFY : NO_VERIFY;
39806+ InitDecodedCert(dCert, it->peerCert, peerCertLen, ssl->heap);
39807+ /* Re-verify against the current trust store so that CA
39808+ * removal since ticket issue is enforced. */
39809+ ret = ParseCertRelative(dCert, CERT_TYPE, verify,
39810+ SSL_CM(ssl), NULL);
39811+ #ifdef HAVE_OCSP
39812+ /* ParseCertRelative does not check revocation status.
39813+ * Run OCSP if the CertManager has it enabled. */
39814+ if (ret == 0 && SSL_CM(ssl)->ocspEnabled) {
39815+ ret = CheckCertOCSP_ex(SSL_CM(ssl)->ocsp, dCert, ssl);
39816+ }
39817+ #endif
39818+ #ifdef HAVE_CRL
39819+ if (ret == 0 && SSL_CM(ssl)->crlEnabled) {
39820+ ret = CheckCertCRL(SSL_CM(ssl)->crl, dCert);
39821+ }
39822+ #endif
39823+ if (ret == 0) {
39824+ #ifdef SESSION_CERTS
39825+ AddSessionCertToChain(&ssl->session->chain,
39826+ it->peerCert, peerCertLen);
39827+ #endif
39828+ FreeX509(&ssl->peerCert);
39829+ InitX509(&ssl->peerCert, 0, ssl->heap);
39830+ ret = CopyDecodedToX509(&ssl->peerCert, dCert);
39831+ if (ret != 0) {
3973339832 FreeX509(&ssl->peerCert);
3973439833 InitX509(&ssl->peerCert, 0, ssl->heap);
39735- ret = CopyDecodedToX509(&ssl->peerCert, dCert);
39736- if (ret != 0) {
39737- /* Failed to copy - clear peerCert */
39738- FreeX509(&ssl->peerCert);
39739- InitX509(&ssl->peerCert, 0, ssl->heap);
39740- }
3974139834 }
39742- FreeDecodedCert(dCert);
39743- XFREE(dCert, ssl->heap, DYNAMIC_TYPE_DCERT);
3974439835 }
39836+ FreeDecodedCert(dCert);
39837+ XFREE(dCert, ssl->heap, DYNAMIC_TYPE_DCERT);
3974539838 }
3974639839 }
3974739840 }
@@ -39887,6 +39980,12 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
3988739980 it->sessionCtxSz = sess->sessionCtxSz;
3988839981 XMEMCPY(it->sessionCtx, sess->sessionCtx, sess->sessionCtxSz);
3988939982#endif
39983+ #ifdef HAVE_SNI
39984+ XMEMCPY(it->sniHash, sess->sniHash, TICKET_BINDING_HASH_SZ);
39985+ #endif
39986+ #ifdef HAVE_ALPN
39987+ XMEMCPY(it->alpnHash, sess->alpnHash, TICKET_BINDING_HASH_SZ);
39988+ #endif
3989039989#if defined(OPENSSL_ALL) && defined(KEEP_PEER_CERT) && \
3989139990 defined(SESSION_CERTS) && !defined(NO_CERT_IN_TICKET)
3989239991 /* Store peer certificate from session chain */
@@ -40131,6 +40230,31 @@ static int AddPSKtoPreMasterSecret(WOLFSSL* ssl)
4013140230 goto cleanup;
4013240231 }
4013340232
40233+ #ifdef HAVE_SNI
40234+ {
40235+ byte curHash[TICKET_BINDING_HASH_SZ];
40236+ if (TicketSniHash(ssl, curHash) != 0 ||
40237+ XMEMCMP(curHash, it->sniHash,
40238+ TICKET_BINDING_HASH_SZ) != 0) {
40239+ WOLFSSL_MSG("Ticket SNI mismatch");
40240+ decryptRet = WOLFSSL_TICKET_RET_REJECT;
40241+ goto cleanup;
40242+ }
40243+ }
40244+ #endif
40245+ #ifdef HAVE_ALPN
40246+ {
40247+ byte curHash[TICKET_BINDING_HASH_SZ];
40248+ if (TicketAlpnHash(ssl, curHash) != 0 ||
40249+ XMEMCMP(curHash, it->alpnHash,
40250+ TICKET_BINDING_HASH_SZ) != 0) {
40251+ WOLFSSL_MSG("Ticket ALPN mismatch");
40252+ decryptRet = WOLFSSL_TICKET_RET_REJECT;
40253+ goto cleanup;
40254+ }
40255+ }
40256+ #endif
40257+
4013440258 DoClientTicketFinalize(ssl, it, NULL);
4013540259
4013640260cleanup:
0 commit comments