From b2e4c8602863ae6ff8acd829e2d66d57eec68e77 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Tue, 15 Jan 2019 09:47:23 -0800 Subject: [PATCH] Changes to secure renegotiation for TLS 1.3 and Chrome --- src/internal.c | 7 +++++-- src/tls.c | 18 +++++++++++++++--- src/tls13.c | 23 +++++++++++++++++++---- wolfssl/internal.h | 5 ++++- 4 files changed, 43 insertions(+), 10 deletions(-) diff --git a/src/internal.c b/src/internal.c index 9a88638e8..191a42eee 100644 --- a/src/internal.c +++ b/src/internal.c @@ -22821,7 +22821,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef HAVE_SERVER_RENEGOTIATION_INFO /* search suites for specific one, idx on success, negative on error */ - static int FindSuite(Suites* suites, byte first, byte second) +#ifndef WOLFSSL_TLS13 + static +#endif + int FindSuite(Suites* suites, byte first, byte second) { int i; @@ -23588,7 +23591,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef HAVE_SERVER_RENEGOTIATION_INFO /* check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV suite */ if (FindSuite(&clSuites, 0, TLS_EMPTY_RENEGOTIATION_INFO_SCSV) >= 0) { - ret = TLSX_AddEmptyRenegotiationInfo(&ssl->extensions); + ret = TLSX_AddEmptyRenegotiationInfo(&ssl->extensions, ssl->heap); if (ret != WOLFSSL_SUCCESS) return ret; ssl->secure_renegotiation->enabled = 1; diff --git a/src/tls.c b/src/tls.c index fd6591d08..7aa4f1ab6 100644 --- a/src/tls.c +++ b/src/tls.c @@ -4349,8 +4349,11 @@ static int TLSX_SecureRenegotiation_Parse(WOLFSSL* ssl, byte* input, if (isRequest) { #ifndef NO_WOLFSSL_SERVER if (ssl->secure_renegotiation == NULL) { - /* already in error state */ - WOLFSSL_MSG("server SCR not available"); + ret = wolfSSL_UseSecureRenegotiation(ssl); + if (ret == WOLFSSL_SUCCESS) + ret = 0; + } + if (ret != 0 && ret != SECURE_RENEGOTIATION_E) { } else if (!ssl->secure_renegotiation->enabled) { if (*input == 0) { @@ -4442,10 +4445,19 @@ int TLSX_UseSecureRenegotiation(TLSX** extensions, void* heap) #ifdef HAVE_SERVER_RENEGOTIATION_INFO -int TLSX_AddEmptyRenegotiationInfo(TLSX** extensions) +int TLSX_AddEmptyRenegotiationInfo(TLSX** extensions, void* heap) { + int ret; + /* send empty renegotiation_info extension */ TLSX* ext = TLSX_Find(*extensions, TLSX_RENEGOTIATION_INFO); + if (ext == NULL) { + ret = TLSX_UseSecureRenegotiation(extensions, heap); + if (ret != WOLFSSL_SUCCESS) + return ret; + + ext = TLSX_Find(*extensions, TLSX_RENEGOTIATION_INFO); + } if (ext) ext->resp = 1; diff --git a/src/tls13.c b/src/tls13.c index 3a1983944..efed9ccbc 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -2178,7 +2178,7 @@ exit_buildmsg: * suite Cipher suite to look for. * returns 1 when suite is found in SSL/TLS object's list and 0 otherwise. */ -static int FindSuite(WOLFSSL* ssl, byte* suite) +static int FindSuiteSSL(WOLFSSL* ssl, byte* suite) { int i; @@ -2342,7 +2342,7 @@ static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk) suite[0] = psk->cipherSuite0; suite[1] = psk->cipherSuite; - if (!FindSuite(ssl, suite)) + if (!FindSuiteSSL(ssl, suite)) return PSK_KEY_ERROR; ssl->options.cipherSuite0 = psk->cipherSuite0; @@ -3365,7 +3365,7 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz, */ suite[0] = ssl->session.cipherSuite0; suite[1] = ssl->session.cipherSuite; - if (!FindSuite(ssl, suite)) { + if (!FindSuiteSSL(ssl, suite)) { current = current->next; continue; } @@ -3420,7 +3420,7 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz, /* Check whether PSK ciphersuite is in SSL. */ suite[0] = cipherSuite0; suite[1] = cipherSuite; - if (!FindSuite(ssl, suite)) { + if (!FindSuiteSSL(ssl, suite)) { current = current->next; continue; } @@ -3872,6 +3872,16 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, i += clSuites.suiteSz; clSuites.hashSigAlgoSz = 0; +#ifdef HAVE_SERVER_RENEGOTIATION_INFO + if (FindSuite(&clSuites, 0, TLS_EMPTY_RENEGOTIATION_INFO_SCSV) >= 0) { + /* check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV suite */ + ret = TLSX_AddEmptyRenegotiationInfo(&ssl->extensions, ssl->heap); + if (ret != WOLFSSL_SUCCESS) + return ret; + ssl->secure_renegotiation->enabled = 1; + } +#endif /* HAVE_SERVER_RENEGOTIATION_INFO */ + /* Compression */ b = input[i++]; if ((i - begin) + b > helloSz) @@ -3933,6 +3943,11 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ssl->options.haveSessionId = 1; if (IsAtLeastTLSv1_3(ssl->version)) { +#ifdef HAVE_SERVER_RENEGOTIATION_INFO + TLSX_Remove(&ssl->extensions, TLSX_RENEGOTIATION_INFO, ssl->heap); + ssl->secure_renegotiation = NULL; +#endif + #if !defined(WOLFSSL_TLS13_DRAFT_18) && defined(WOLFSSL_SEND_HRR_COOKIE) if (ssl->options.sendCookie && ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST_COMPLETE) { diff --git a/wolfssl/internal.h b/wolfssl/internal.h index f2e4853ed..b835a4e92 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1601,6 +1601,9 @@ WOLFSSL_LOCAL int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx) /* TLS v1.3 needs these */ WOLFSSL_LOCAL int HandleTlsResumption(WOLFSSL* ssl, int bogusID, Suites* clSuites); +#ifdef WOLFSSL_TLS13 +WOLFSSL_LOCAL int FindSuite(Suites* suites, byte first, byte second); +#endif WOLFSSL_LOCAL int DoClientHello(WOLFSSL* ssl, const byte* input, word32*, word32); #ifdef WOLFSSL_TLS13 @@ -2285,7 +2288,7 @@ typedef struct SecureRenegotiation { WOLFSSL_LOCAL int TLSX_UseSecureRenegotiation(TLSX** extensions, void* heap); #ifdef HAVE_SERVER_RENEGOTIATION_INFO -WOLFSSL_LOCAL int TLSX_AddEmptyRenegotiationInfo(TLSX** extensions); +WOLFSSL_LOCAL int TLSX_AddEmptyRenegotiationInfo(TLSX** extensions, void* heap); #endif #endif /* HAVE_SECURE_RENEGOTIATION */