diff --git a/src/internal.c b/src/internal.c index eefafce52..00a5e8be3 100644 --- a/src/internal.c +++ b/src/internal.c @@ -17820,6 +17820,28 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, return ret; } +#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) + { + int i; + + if (suites == NULL) { + WOLFSSL_MSG("Suites pointer error"); + return SUITES_ERROR; + } + + for (i = 0; i < suites->suiteSz; i += 2) { + if (suites->suites[i] == first && + suites->suites[i+1] == second ) + return i; + } + + return MATCH_SUITE_ERROR; + } + +#endif /* Make sure server cert/key are valid for this suite, true on success */ static int VerifyServerSuite(WOLFSSL* ssl, word16 idx) @@ -18351,6 +18373,18 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, return BUFFER_ERROR; XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz); + +#ifdef HAVE_SERVER_RENEGOTIATION_INFO + /* check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV suite */ + if (FindSuite(&clSuites, 0, TLS_EMPTY_RENEGOTIATION_INFO_SCSV) >= 0) { + int ret = 0; + + ret = TLSX_AddEmptyRenegotiationInfo(&ssl->extensions, ssl->heap); + if (ret != SSL_SUCCESS) + return ret; + } +#endif /* HAVE_SERVER_RENEGOTIATION_INFO */ + #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl)) { int ret = wc_HmacUpdate(&cookieHmac, diff --git a/src/tls.c b/src/tls.c index 6f4389c5d..91779820b 100644 --- a/src/tls.c +++ b/src/tls.c @@ -3093,14 +3093,16 @@ int TLSX_UseSupportedCurve(TLSX** extensions, word16 name, void* heap) /* Renegotiation Indication */ /******************************************************************************/ -#ifdef HAVE_SECURE_RENEGOTIATION +#if defined(HAVE_SECURE_RENEGOTIATION) \ + || defined(HAVE_SERVER_RENEGOTIATION_INFO) static byte TLSX_SecureRenegotiation_GetSize(SecureRenegotiation* data, int isRequest) { byte length = OPAQUE8_LEN; /* empty info length */ - if (data->enabled) { + /* data will be NULL for HAVE_SERVER_RENEGOTIATION_INFO only */ + if (data && data->enabled) { /* client sends client_verify_data only */ length += TLS_FINISHED_SZ; @@ -3117,7 +3119,7 @@ static word16 TLSX_SecureRenegotiation_Write(SecureRenegotiation* data, { word16 offset = OPAQUE8_LEN; /* RenegotiationInfo length */ - if (data->enabled) { + if (data && data->enabled) { /* client sends client_verify_data only */ XMEMCPY(output + offset, data->client_verify_data, TLS_FINISHED_SZ); offset += TLS_FINISHED_SZ; @@ -3143,8 +3145,29 @@ static int TLSX_SecureRenegotiation_Parse(WOLFSSL* ssl, byte* input, if (ssl->secure_renegotiation == NULL) { #ifndef NO_WOLFSSL_SERVER if (isRequest && *input == 0) { + #ifdef HAVE_SERVER_RENEGOTIATION_INFO + if (length == OPAQUE8_LEN) { + if (TLSX_Find(ssl->extensions, + TLSX_RENEGOTIATION_INFO) == NULL) { + ret = TLSX_AddEmptyRenegotiationInfo(&ssl->extensions, + ssl->heap); + if (ret == SSL_SUCCESS) + ret = 0; + + } else { + ret = 0; + } + } + #else ret = 0; /* don't reply, user didn't enable */ + #endif /* HAVE_SERVER_RENEGOTIATION_INFO */ } + #ifdef HAVE_SERVER_RENEGOTIATION_INFO + else if (!isRequest) { + /* don't do anything on client side */ + ret = 0; + } + #endif #endif } else if (isRequest) { @@ -3213,6 +3236,26 @@ int TLSX_UseSecureRenegotiation(TLSX** extensions, void* heap) return SSL_SUCCESS; } +#ifdef HAVE_SERVER_RENEGOTIATION_INFO + +int TLSX_AddEmptyRenegotiationInfo(TLSX** extensions, void* heap) +{ + int ret; + + ret = TLSX_Push(extensions, TLSX_RENEGOTIATION_INFO, NULL, heap); + if (ret != 0) + return ret; + + /* send empty renegotiation_info extension */ + TLSX* ext = TLSX_Find(*extensions, TLSX_RENEGOTIATION_INFO); + if (ext) + ext->resp = 1; + + return SSL_SUCCESS; +} + +#endif /* HAVE_SERVER_RENEGOTIATION_INFO */ + #define SCR_FREE_ALL(data, heap) XFREE(data, (heap), DYNAMIC_TYPE_TLSX) #define SCR_GET_SIZE TLSX_SecureRenegotiation_GetSize diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 79671a68a..bbe53b9f5 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1694,7 +1694,8 @@ WOLFSSL_LOCAL int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, || defined(HAVE_ALPN) \ || defined(HAVE_QSH) \ || defined(HAVE_SESSION_TICKET) \ - || defined(HAVE_SECURE_RENEGOTIATION) + || defined(HAVE_SECURE_RENEGOTIATION) \ + || defined(HAVE_SERVER_RENEGOTIATION_INFO) #error Using TLS extensions requires HAVE_TLS_EXTENSIONS to be defined. @@ -1823,7 +1824,8 @@ WOLFSSL_LOCAL int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, #endif /* HAVE_SUPPORTED_CURVES */ /** Renegotiation Indication - RFC 5746 */ -#ifdef HAVE_SECURE_RENEGOTIATION +#if defined(HAVE_SECURE_RENEGOTIATION) \ + || defined(HAVE_SERVER_RENEGOTIATION_INFO) enum key_cache_state { SCR_CACHE_NULL = 0, /* empty / begin state */ @@ -1846,6 +1848,10 @@ typedef struct SecureRenegotiation { WOLFSSL_LOCAL int TLSX_UseSecureRenegotiation(TLSX** extensions, void* heap); +#ifdef HAVE_SERVER_RENEGOTIATION_INFO +WOLFSSL_LOCAL int TLSX_AddEmptyRenegotiationInfo(TLSX** extensions, void* heap); +#endif + #endif /* HAVE_SECURE_RENEGOTIATION */ /** Session Ticket - RFC 5077 (session 3.2) */ @@ -2814,7 +2820,8 @@ struct WOLFSSL { #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 byte status_request_v2; #endif - #ifdef HAVE_SECURE_RENEGOTIATION + #if defined(HAVE_SECURE_RENEGOTIATION) \ + || defined(HAVE_SERVER_RENEGOTIATION_INFO) SecureRenegotiation* secure_renegotiation; /* valid pointer indicates */ #endif /* user turned on */ #ifdef HAVE_ALPN