From e96ede65ce82ce764273708963a1e84166f593c4 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Fri, 28 Jun 2019 15:17:39 +1000 Subject: [PATCH] Don't resume if stored session's ciphersuite isn't in client list Turn this check off with NO_RESUME_SUITE_CHECK. --- configure.ac | 2 +- src/internal.c | 31 +++++++++++++++++++++++++++++-- src/ssl.c | 33 +++++++++++++++++++++++++++++++-- wolfssl/internal.h | 3 +++ 4 files changed, 64 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index d67f1ba4d9..f9a7b472e1 100644 --- a/configure.ac +++ b/configure.ac @@ -538,7 +538,7 @@ fi if test "$ENABLED_OPENSSLEXTRA" = "yes" && test "x$ENABLED_OPENSSLCOEXIST" = "xno" then AM_CFLAGS="-DOPENSSL_EXTRA -DWOLFSSL_ALWAYS_VERIFY_CB $AM_CFLAGS" - AM_CFLAGS="-DWOLFSSL_VERIFY_CB_ALL_CERTS $AM_CFLAGS" + AM_CFLAGS="-DWOLFSSL_VERIFY_CB_ALL_CERTS -DWOLFSSL_EXTRA_ALERTS $AM_CFLAGS" fi if test "$ENABLED_OPENSSLEXTRA" = "yes" && test "$ENABLED_SMALL" = "yes" diff --git a/src/internal.c b/src/internal.c index ea1b2e8168..3293ae66a1 100644 --- a/src/internal.c +++ b/src/internal.c @@ -23512,11 +23512,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, int HandleTlsResumption(WOLFSSL* ssl, int bogusID, Suites* clSuites) { int ret = 0; - WOLFSSL_SESSION* session = GetSession(ssl, - ssl->arrays->masterSecret, 1); + WOLFSSL_SESSION* session; (void)bogusID; + session = GetSession(ssl, ssl->arrays->masterSecret, 1); #ifdef HAVE_SESSION_TICKET if (ssl->options.useTicket == 1) { session = &ssl->session; @@ -23543,6 +23543,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, else if (session->haveEMS && !ssl->options.haveEMS) { WOLFSSL_MSG("Trying to resume a session with EMS without " "using EMS"); + #ifdef WOLFSSL_EXTRA_ALERTS + SendAlert(ssl, alert_fatal, handshake_failure); + #endif return EXT_MASTER_SECRET_NEEDED_E; } #ifdef HAVE_EXT_CACHE @@ -23550,6 +23553,25 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif } else { + #ifndef NO_RESUME_SUITE_CHECK + int j; + + /* Check client suites include the one in session */ + for (j = 0; j < clSuites->suiteSz; j += 2) { + if (clSuites->suites[j] == session->cipherSuite0 && + clSuites->suites[j+1] == session->cipherSuite) { + break; + } + } + if (j == clSuites->suiteSz) { + WOLFSSL_MSG("Prev session's cipher suite not in ClientHello"); + #ifdef WOLFSSL_EXTRA_ALERTS + SendAlert(ssl, alert_fatal, illegal_parameter); + #endif + return UNSUPPORTED_SUITE; + } + #endif + #ifdef HAVE_EXT_CACHE wolfSSL_SESSION_free(session); #endif @@ -24734,11 +24756,16 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ssl->version.minor = it->pv.minor; } + if (!IsAtLeastTLSv1_3(ssl->version)) { XMEMCPY(ssl->arrays->masterSecret, it->msecret, SECRET_LEN); /* Copy the haveExtendedMasterSecret property from the ticket to * the saved session, so the property may be checked later. */ ssl->session.haveEMS = it->haveEMS; + #ifndef NO_RESUME_SUITE_CHECK + ssl->session.cipherSuite0 = it->suite[0]; + ssl->session.cipherSuite = it->suite[1]; + #endif } else { #ifdef WOLFSSL_TLS13 diff --git a/src/ssl.c b/src/ssl.c index 942e059ba0..fe76765186 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -10050,10 +10050,16 @@ static WC_INLINE void RestoreSession(WOLFSSL* ssl, WOLFSSL_SESSION* session, if (restoreSessionCerts) { ssl->session.chain = session->chain; ssl->session.version = session->version; + #ifdef NO_RESUME_SUITE_CHECK ssl->session.cipherSuite0 = session->cipherSuite0; ssl->session.cipherSuite = session->cipherSuite; + #endif } #endif /* SESSION_CERTS */ +#ifndef NO_RESUME_SUITE_CHECK + ssl->session.cipherSuite0 = session->cipherSuite0; + ssl->session.cipherSuite = session->cipherSuite; +#endif } WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret, @@ -10185,6 +10191,11 @@ static int GetDeepCopySession(WOLFSSL* ssl, WOLFSSL_SESSION* copyFrom) copyInto->isDynamic = 0; #endif +#ifndef NO_RESUME_SUITE_CHECK + copyInto->cipherSuite0 = copyFrom->cipherSuite0; + copyInto->cipherSuite = copyFrom->cipherSuite; +#endif + if (wc_UnLockMutex(&session_mutex) != 0) { return BAD_MUTEX_E; } @@ -10196,8 +10207,10 @@ static int GetDeepCopySession(WOLFSSL* ssl, WOLFSSL_SESSION* copyFrom) return BAD_MUTEX_E; } +#ifdef NO_RESUME_SUITE_CHECK copyInto->cipherSuite0 = copyFrom->cipherSuite0; copyInto->cipherSuite = copyFrom->cipherSuite; +#endif copyInto->namedGroup = copyFrom->namedGroup; copyInto->ticketSeen = copyFrom->ticketSeen; copyInto->ticketAdd = copyFrom->ticketAdd; @@ -10288,6 +10301,9 @@ int SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session) #if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \ defined(HAVE_SESSION_TICKET)) ssl->version = session->version; +#endif +#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \ + (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)) ssl->options.cipherSuite0 = session->cipherSuite0; ssl->options.cipherSuite = session->cipherSuite; #endif @@ -10465,10 +10481,15 @@ int AddSession(WOLFSSL* ssl) defined(HAVE_SESSION_TICKET)) if (error == 0) { session->version = ssl->version; + } +#endif /* SESSION_CERTS || (WOLFSSL_TLS13 & HAVE_SESSION_TICKET) */ +#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \ + (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)) + if (error == 0) { session->cipherSuite0 = ssl->options.cipherSuite0; session->cipherSuite = ssl->options.cipherSuite; } -#endif /* SESSION_CERTS || (WOLFSSL_TLS13 & HAVE_SESSION_TICKET) */ +#endif #if defined(WOLFSSL_TLS13) if (error == 0) { session->namedGroup = ssl->session.namedGroup; @@ -22142,7 +22163,11 @@ int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p) size += OPAQUE8_LEN; for (i = 0; i < sess->chain.count; i++) size += OPAQUE16_LEN + sess->chain.certs[i].length; - /* Protocol version + cipher suite */ + /* Protocol version */ + size += OPAQUE16_LEN; +#endif +#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) + /* cipher suite */ size += OPAQUE16_LEN + OPAQUE16_LEN; #endif #ifndef NO_CLIENT_CACHE @@ -22183,6 +22208,8 @@ int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p) } data[idx++] = sess->version.major; data[idx++] = sess->version.minor; +#endif +#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) data[idx++] = sess->cipherSuite0; data[idx++] = sess->cipherSuite; #endif @@ -22309,6 +22336,8 @@ WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess, } s->version.major = data[idx++]; s->version.minor = data[idx++]; +#endif +#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) s->cipherSuite0 = data[idx++]; s->cipherSuite = data[idx++]; #endif diff --git a/wolfssl/internal.h b/wolfssl/internal.h index b522ee5438..a198b5c73f 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2975,6 +2975,9 @@ struct WOLFSSL_SESSION { #if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \ defined(HAVE_SESSION_TICKET)) ProtocolVersion version; /* which version was used */ +#endif +#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \ + (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)) byte cipherSuite0; /* first byte, normally 0 */ byte cipherSuite; /* 2nd byte, actual suite */ #endif