From ef7b40dcab0ea3db992484c5ef5fffccb9c6b7c6 Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 26 Apr 2018 11:30:57 -0700 Subject: [PATCH 1/2] Refactor of the TLSX code to support returning error codes. * The `SANITY_MSG_E` responses in `TLSX_SupportedVersions_GetSize`, `TLSX_SupportedVersions_Write`, `TLSX_Cookie_GetSize` and `TLSX_Cookie_Write` would incorrectly be handled. * Added build-time checks in `tls13.c` for dependencies on `HAVE_HKDF` and `WC_RSA_PSS`. --- src/internal.c | 37 ++++++++----- src/tls.c | 127 +++++++++++++++++++++++++++------------------ src/tls13.c | 92 +++++++++++++++++++++++--------- wolfssl/internal.h | 28 +++++----- 4 files changed, 182 insertions(+), 102 deletions(-) diff --git a/src/internal.c b/src/internal.c index 0c3396cf5..c3dfc3495 100644 --- a/src/internal.c +++ b/src/internal.c @@ -17139,9 +17139,11 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, if (QSH_Init(ssl) != 0) return MEMORY_E; #endif - extSz = TLSX_GetRequestSize(ssl, client_hello); - if (extSz != 0) - length += extSz; + extSz = 0; + ret = TLSX_GetRequestSize(ssl, client_hello, &extSz); + if (ret != 0) + return ret; + length += extSz; #else if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) extSz += HELLO_EXT_SZ + HELLO_EXT_SIGALGO_SZ @@ -17232,7 +17234,11 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, output[idx++] = NO_COMPRESSION; #ifdef HAVE_TLS_EXTENSIONS - idx += TLSX_WriteRequest(ssl, output + idx, client_hello); + extSz = 0; + ret = TLSX_WriteRequest(ssl, output + idx, client_hello, &extSz); + if (ret != 0) + return ret; + idx += extSz; (void)idx; /* suppress analyzer warning, keep idx current */ #else @@ -21136,13 +21142,14 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* handle generation of server_hello (2) */ int SendServerHello(WOLFSSL* ssl) { - byte *output; - word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; - int sendSz; - int ret; - byte sessIdSz = ID_LEN; - byte echoId = 0; /* ticket echo id flag */ - byte cacheOff = 0; /* session cache off flag */ + int ret; + byte *output; + word16 length; + word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; + int sendSz; + byte sessIdSz = ID_LEN; + byte echoId = 0; /* ticket echo id flag */ + byte cacheOff = 0; /* session cache off flag */ WOLFSSL_START(WC_FUNC_SERVER_HELLO_SEND); WOLFSSL_ENTER("SendServerHello"); @@ -21153,7 +21160,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, + ENUM_LEN; #ifdef HAVE_TLS_EXTENSIONS - length += TLSX_GetResponseSize(ssl, server_hello); + ret = TLSX_GetResponseSize(ssl, server_hello, &length); + if (ret != 0) + return ret; #ifdef HAVE_SESSION_TICKET if (ssl->options.useTicket) { /* echo session id sz can be 0,32 or bogus len inbetween */ @@ -21280,7 +21289,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* last, extensions */ #ifdef HAVE_TLS_EXTENSIONS - TLSX_WriteResponse(ssl, output + idx, server_hello); + ret = TLSX_WriteResponse(ssl, output + idx, server_hello, NULL); + if (ret != 0) + return ret; #else #ifdef HAVE_EXTENDED_MASTER if (ssl->options.haveEMS) { diff --git a/src/tls.c b/src/tls.c index d2f638c96..6ae031a66 100755 --- a/src/tls.c +++ b/src/tls.c @@ -4631,7 +4631,7 @@ int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz, * msgType The type of the message this extension is being written into. * returns the length of data that will be in the extension. */ -static word16 TLSX_SupportedVersions_GetSize(void* data, byte msgType) +static int TLSX_SupportedVersions_GetSize(void* data, byte msgType, word16* pSz) { WOLFSSL* ssl = (WOLFSSL*)data; @@ -4651,14 +4651,16 @@ static word16 TLSX_SupportedVersions_GetSize(void* data, byte msgType) if (!ssl->options.downgrade) cnt = 1; - return (word16)(OPAQUE8_LEN + cnt * OPAQUE16_LEN); + *pSz += (word16)(OPAQUE8_LEN + cnt * OPAQUE16_LEN); } #ifndef WOLFSSL_TLS13_DRAFT_18 else if (msgType == server_hello || msgType == hello_retry_request) - return OPAQUE16_LEN; + *pSz += OPAQUE16_LEN; #endif else return SANITY_MSG_E; + + return 0; } /* Writes the SupportedVersions extension into the buffer. @@ -4668,8 +4670,8 @@ static word16 TLSX_SupportedVersions_GetSize(void* data, byte msgType) * msgType The type of the message this extension is being written into. * returns the length of data that was written. */ -static word16 TLSX_SupportedVersions_Write(void* data, byte* output, - byte msgType) +static int TLSX_SupportedVersions_Write(void* data, byte* output, + byte msgType, word16* pSz) { WOLFSSL* ssl = (WOLFSSL*)data; ProtocolVersion pv; @@ -4710,18 +4712,20 @@ static word16 TLSX_SupportedVersions_Write(void* data, byte* output, *(output++) = pv.minor - i; } - return (word16)(OPAQUE8_LEN + cnt * OPAQUE16_LEN); + *pSz += (word16)(OPAQUE8_LEN + cnt * OPAQUE16_LEN); } #ifndef WOLFSSL_TLS13_DRAFT_18 else if (msgType == server_hello || msgType == hello_retry_request) { output[0] = ssl->version.major; output[1] = ssl->version.minor; - return OPAQUE16_LEN; + *pSz += OPAQUE16_LEN; } #endif else return SANITY_MSG_E; + + return 0; } /* Parse the SupportedVersions extension. @@ -4876,8 +4880,8 @@ static int TLSX_SetSupportedVersions(TLSX** extensions, const void* data, #else -#define SV_GET_SIZE(a, b) 0 -#define SV_WRITE(a, b, c) 0 +#define SV_GET_SIZE(a, b, c) 0 +#define SV_WRITE(a, b, c, d) 0 #define SV_PARSE(a, b, c, d) 0 #endif /* WOLFSSL_TLS13 */ @@ -4908,12 +4912,13 @@ static void TLSX_Cookie_FreeAll(Cookie* cookie, void* heap) * msgType The type of the message this extension is being written into. * returns the number of bytes of the encoded Cookie extension. */ -static word16 TLSX_Cookie_GetSize(Cookie* cookie, byte msgType) +static int TLSX_Cookie_GetSize(Cookie* cookie, byte msgType, word16* pSz) { if (msgType == client_hello || msgType == hello_retry_request) - return OPAQUE16_LEN + cookie->len; - - return SANITY_MSG_E; + *pSz += OPAQUE16_LEN + cookie->len; + else + return SANITY_MSG_E; + return 0; } /* Writes the Cookie extension into the output buffer. @@ -4925,16 +4930,17 @@ static word16 TLSX_Cookie_GetSize(Cookie* cookie, byte msgType) * msgType The type of the message this extension is being written into. * returns the number of bytes written into the buffer. */ -static word16 TLSX_Cookie_Write(Cookie* cookie, byte* output, byte msgType) +static int TLSX_Cookie_Write(Cookie* cookie, byte* output, byte msgType, word16* pSz) { if (msgType == client_hello || msgType == hello_retry_request) { c16toa(cookie->len, output); output += OPAQUE16_LEN; XMEMCPY(output, &cookie->data, cookie->len); - return OPAQUE16_LEN + cookie->len; + *pSz += OPAQUE16_LEN + cookie->len; } - - return SANITY_MSG_E; /* ! */ + else + return SANITY_MSG_E; + return 0; } /* Parse the Cookie extension. @@ -5040,8 +5046,8 @@ int TLSX_Cookie_Use(WOLFSSL* ssl, byte* data, word16 len, byte* mac, #else #define CKE_FREE_ALL(a, b) 0 -#define CKE_GET_SIZE(a, b) 0 -#define CKE_WRITE(a, b, c) 0 +#define CKE_GET_SIZE(a, b, c) 0 +#define CKE_WRITE(a, b, c, d) 0 #define CKE_PARSE(a, b, c, d) 0 #endif @@ -7643,8 +7649,9 @@ int TLSX_SupportExtensions(WOLFSSL* ssl) { } /** Tells the buffered size of the extensions in a list. */ -static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType) +static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType, word16* pLength) { + int ret = 0; TLSX* extension; word16 length = 0; byte isRequest = (msgType == client_hello || @@ -7724,11 +7731,11 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType) #ifdef WOLFSSL_TLS13 case TLSX_SUPPORTED_VERSIONS: - length += SV_GET_SIZE(extension->data, msgType); + ret = SV_GET_SIZE(extension->data, msgType, &length); break; case TLSX_COOKIE: - length += CKE_GET_SIZE((Cookie*)extension->data, msgType); + ret = CKE_GET_SIZE((Cookie*)extension->data, msgType, &length); break; #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) @@ -7770,14 +7777,17 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType) TURN_ON(semaphore, TLSX_ToSemaphore(extension->type)); } - return length; + *pLength += length; + + return ret; } /** Writes the extensions of a list in a buffer. */ -static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore, - byte msgType) +static int TLSX_Write(TLSX* list, byte* output, byte* semaphore, + byte msgType, word16* pOffset) { - TLSX* extension; + int ret = 0; + TLSX* extension; word16 offset = 0; word16 length_offset = 0; byte isRequest = (msgType == client_hello || @@ -7877,13 +7887,13 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore, #ifdef WOLFSSL_TLS13 case TLSX_SUPPORTED_VERSIONS: WOLFSSL_MSG("Supported Versions extension to write"); - offset += SV_WRITE(extension->data, output + offset, msgType); + ret = SV_WRITE(extension->data, output + offset, msgType, &offset); break; case TLSX_COOKIE: WOLFSSL_MSG("Cookie extension to write"); - offset += CKE_WRITE((Cookie*)extension->data, output + offset, - msgType); + ret = CKE_WRITE((Cookie*)extension->data, output + offset, + msgType, &offset); break; #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) @@ -7936,7 +7946,9 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore, TURN_ON(semaphore, TLSX_ToSemaphore(extension->type)); } - return offset; + *pOffset += offset; + + return ret; } @@ -8588,8 +8600,9 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) #ifndef NO_WOLFSSL_CLIENT /** Tells the buffered size of extensions to be sent into the client hello. */ -word16 TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType) +int TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType, word16* pLength) { + int ret = 0; word16 length = 0; byte semaphore[SEMAPHORE_SIZE] = {0}; @@ -8655,9 +8668,9 @@ word16 TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType) #endif if (ssl->extensions) - length += TLSX_GetSize(ssl->extensions, semaphore, msgType); + ret = TLSX_GetSize(ssl->extensions, semaphore, msgType, &length); if (ssl->ctx && ssl->ctx->extensions) - length += TLSX_GetSize(ssl->ctx->extensions, semaphore, msgType); + ret = TLSX_GetSize(ssl->ctx->extensions, semaphore, msgType, &length); #ifdef HAVE_EXTENDED_MASTER if (msgType == client_hello && ssl->options.haveEMS && @@ -8669,12 +8682,15 @@ word16 TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType) if (length) length += OPAQUE16_LEN; /* for total length storage. */ - return length; + *pLength += length; + + return ret; } /** Writes the extensions to be sent into the client hello. */ -word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType) +int TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType, word16* pOffset) { + int ret = 0; word16 offset = 0; byte semaphore[SEMAPHORE_SIZE] = {0}; @@ -8749,12 +8765,12 @@ word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType) #endif if (ssl->extensions) { - offset += TLSX_Write(ssl->extensions, output + offset, semaphore, - msgType); + ret = TLSX_Write(ssl->extensions, output + offset, semaphore, + msgType, &offset); } if (ssl->ctx && ssl->ctx->extensions) { - offset += TLSX_Write(ssl->ctx->extensions, output + offset, semaphore, - msgType); + ret = TLSX_Write(ssl->ctx->extensions, output + offset, semaphore, + msgType, &offset); } #ifdef HAVE_EXTENDED_MASTER @@ -8772,8 +8788,8 @@ word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType) if (msgType == client_hello && IsAtLeastTLSv1_3(ssl->version)) { /* Write out what we can of Pre-shared key extension. */ TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY)); - offset += TLSX_Write(ssl->extensions, output + offset, semaphore, - client_hello); + ret = TLSX_Write(ssl->extensions, output + offset, semaphore, + client_hello, &offset); } #endif #endif @@ -8781,7 +8797,9 @@ word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType) if (offset > OPAQUE16_LEN || msgType != client_hello) c16toa(offset - OPAQUE16_LEN, output); /* extensions length */ - return offset; + *pOffset += offset; + + return ret; } #endif /* NO_WOLFSSL_CLIENT */ @@ -8789,8 +8807,9 @@ word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType) #ifndef NO_WOLFSSL_SERVER /** Tells the buffered size of extensions to be sent into the server hello. */ -word16 TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType) +int TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType, word16* pLength) { + int ret = 0; word16 length = 0; byte semaphore[SEMAPHORE_SIZE] = {0}; @@ -8874,19 +8893,22 @@ word16 TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType) #endif if (TLSX_SupportExtensions(ssl)) - length += TLSX_GetSize(ssl->extensions, semaphore, msgType); + ret = TLSX_GetSize(ssl->extensions, semaphore, msgType, &length); /* All the response data is set at the ssl object only, so no ctx here. */ if (length || msgType != server_hello) length += OPAQUE16_LEN; /* for total length storage. */ - return length; + *pLength += length; + + return ret; } /** Writes the server hello extensions into a buffer. */ -word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType) +int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, word16* pOffset) { + int ret = 0; word16 offset = 0; if (TLSX_SupportExtensions(ssl) && output) { @@ -8959,15 +8981,15 @@ word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType) offset += OPAQUE16_LEN; /* extensions length */ - offset += TLSX_Write(ssl->extensions, output + offset, semaphore, - msgType); + ret = TLSX_Write(ssl->extensions, output + offset, semaphore, + msgType, &offset); #ifdef WOLFSSL_TLS13 if (msgType == hello_retry_request) { XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE); TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_COOKIE)); - offset += TLSX_Write(ssl->extensions, output + offset, semaphore, - msgType); + ret = TLSX_Write(ssl->extensions, output + offset, semaphore, + msgType, &offset); } #endif @@ -8984,7 +9006,10 @@ word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType) c16toa(offset - OPAQUE16_LEN, output); /* extensions length */ } - return offset; + if (pOffset) + *pOffset += offset; + + return ret; } #endif /* NO_WOLFSSL_SERVER */ diff --git a/src/tls13.c b/src/tls13.c index 009b6341e..46b410762 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -128,6 +128,14 @@ #define FALSE 0 #endif +#ifndef HAVE_HKDF + #error The build option `HAVE_HKDF` is required for TLS 1.3 +#endif +#ifndef WC_RSA_PSS + #error The build option `WC_RSA_PSS` is required for TLS 1.3 +#endif + + /* Set ret to error value and jump to label. * * err The error value to set. @@ -2353,7 +2361,7 @@ static int WritePSKBinders(WOLFSSL* ssl, byte* output, word32 idx) int SendTls13ClientHello(WOLFSSL* ssl) { byte* output; - word32 length; + word16 length; word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; int sendSz; int ret; @@ -2414,7 +2422,9 @@ int SendTls13ClientHello(WOLFSSL* ssl) return MEMORY_E; #endif /* Include length of TLS extensions. */ - length += TLSX_GetRequestSize(ssl, client_hello); + ret = TLSX_GetRequestSize(ssl, client_hello, &length); + if (ret != 0) + return ret; /* Total message size. */ sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ; @@ -2482,7 +2492,11 @@ int SendTls13ClientHello(WOLFSSL* ssl) output[idx++] = NO_COMPRESSION; /* Write out extensions for a request. */ - idx += TLSX_WriteRequest(ssl, output + idx, client_hello); + length = 0; + ret = TLSX_WriteRequest(ssl, output + idx, client_hello, &length); + if (ret != 0) + return ret; + idx += length; #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) /* Resumption has a specific set of extensions and binder is calculated @@ -3988,16 +4002,17 @@ int SendTls13HelloRetryRequest(WOLFSSL* ssl) int ret; byte* output; word32 length; - word32 len; + word16 len; word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; int sendSz; WOLFSSL_ENTER("SendTls13HelloRetryRequest"); /* Get the length of the extensions that will be written. */ - len = TLSX_GetResponseSize(ssl, hello_retry_request); + len = 0; + ret = TLSX_GetResponseSize(ssl, hello_retry_request, &len); /* There must be extensions sent to indicate what client needs to do. */ - if (len == 0) + if (ret != 0) return MISSING_HANDSHAKE_DATA; /* Protocol version + Extensions */ @@ -4026,7 +4041,9 @@ int SendTls13HelloRetryRequest(WOLFSSL* ssl) output[idx++] = TLS_DRAFT_MINOR; /* Add TLS extensions. */ - TLSX_WriteResponse(ssl, output + idx, hello_retry_request); + ret = TLSX_WriteResponse(ssl, output + idx, hello_retry_request, NULL); + if (ret != 0) + return ret; idx += len; #ifdef WOLFSSL_CALLBACKS @@ -4063,11 +4080,11 @@ static /* handle generation of TLS 1.3 server_hello (2) */ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType) { + int ret; byte* output; - word32 length; + word16 length; word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; int sendSz; - int ret; WOLFSSL_START(WC_FUNC_SERVER_HELLO_SEND); WOLFSSL_ENTER("SendTls13ServerHello"); @@ -4081,14 +4098,19 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType) #ifdef WOLFSSL_TLS13_DRAFT_18 /* Protocol version, server random, cipher suite and extensions. */ - length = VERSION_SZ + RAN_LEN + SUITE_LEN + - TLSX_GetResponseSize(ssl, server_hello); + length = VERSION_SZ + RAN_LEN + SUITE_LEN; + ret = TLSX_GetResponseSize(ssl, server_hello, &length); + if (ret != 0) + return ret; #else /* Protocol version, server random, session id, cipher suite, compression * and extensions. */ length = VERSION_SZ + RAN_LEN + ENUM_LEN + ssl->session.sessionIDSz + - SUITE_LEN + COMP_LEN + TLSX_GetResponseSize(ssl, extMsgType); + SUITE_LEN + COMP_LEN; + ret = TLSX_GetResponseSize(ssl, extMsgType, &length); + if (ret != 0) + return ret; #endif sendSz = idx + length; @@ -4158,7 +4180,9 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType) #endif /* Extensions */ - TLSX_WriteResponse(ssl, output + idx, extMsgType); + ret = TLSX_WriteResponse(ssl, output + idx, extMsgType, NULL); + if (ret != 0) + return ret; ssl->buffers.outputBuffer.length += sendSz; @@ -4202,7 +4226,7 @@ static int SendTls13EncryptedExtensions(WOLFSSL* ssl) { int ret; byte* output; - word32 length; + word16 length = 0; word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; int sendSz; @@ -4238,7 +4262,10 @@ static int SendTls13EncryptedExtensions(WOLFSSL* ssl) return ret; #endif - length = TLSX_GetResponseSize(ssl, encrypted_extensions); + ret = TLSX_GetResponseSize(ssl, encrypted_extensions, &length); + if (ret != 0) + return ret; + sendSz = idx + length; /* Encryption always on. */ sendSz += MAX_MSG_EXTRA; @@ -4255,7 +4282,9 @@ static int SendTls13EncryptedExtensions(WOLFSSL* ssl) /* Put the record and handshake headers on. */ AddTls13Headers(output, length, encrypted_extensions, ssl); - TLSX_WriteResponse(ssl, output + idx, encrypted_extensions); + ret = TLSX_WriteResponse(ssl, output + idx, encrypted_extensions, NULL); + if (ret != 0) + return ret; idx += length; #ifdef WOLFSSL_CALLBACKS @@ -4304,7 +4333,7 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx, int ret; int sendSz; word32 i; - int reqSz; + word16 reqSz; #ifndef WOLFSSL_TLS13_DRAFT_18 TLSX* ext; #endif @@ -4363,8 +4392,10 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx, ext->resp = 0; i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; - reqSz = OPAQUE8_LEN + reqCtxLen + - TLSX_GetRequestSize(ssl, certificate_request); + reqSz = OPAQUE8_LEN + reqCtxLen; + ret = TLSX_GetRequestSize(ssl, certificate_request, &reqSz); + if (ret != 0) + return ret; sendSz = i + reqSz; /* Always encrypted and make room for padding. */ @@ -4389,7 +4420,11 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx, } /* Certificate extensions. */ - i += TLSX_WriteRequest(ssl, output + i, certificate_request); + reqSz = 0; + ret = TLSX_WriteRequest(ssl, output + i, certificate_request, &reqSz); + if (ret != 0) + return ret; + i += reqSz; #endif /* Always encrypted. */ @@ -6457,7 +6492,7 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl) byte* output; int ret; int sendSz; - word32 extSz; + word16 extSz; word32 length; word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; @@ -6490,7 +6525,10 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl) ssl->session.maxEarlyDataSz = ssl->options.maxEarlyDataSz; if (ssl->session.maxEarlyDataSz > 0) TLSX_EarlyData_Use(ssl, ssl->session.maxEarlyDataSz); - extSz = TLSX_GetResponseSize(ssl, session_ticket); + extSz = 0; + ret = TLSX_GetResponseSize(ssl, session_ticket, &extSz); + if (ret != 0) + return ret; #else extSz = EXTS_SZ; #endif @@ -6535,7 +6573,11 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl) idx += ssl->session.ticketLen; #ifdef WOLFSSL_EARLY_DATA - idx += TLSX_WriteResponse(ssl, output + idx, session_ticket); + extSz = 0; + ret = TLSX_WriteResponse(ssl, output + idx, session_ticket, &extSz); + if (ret != 0) + return ret; + idx += extSz; #else /* No extension support - empty extensions. */ c16toa(0, output + idx); @@ -6544,9 +6586,9 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl) ssl->options.haveSessionId = 1; - #ifndef NO_SESSION_CACHE +#ifndef NO_SESSION_CACHE AddSession(ssl); - #endif +#endif /* This message is always encrypted. */ sendSz = BuildTls13Message(ssl, output, sendSz, output + RECORD_HEADER_SZ, diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 1b5a8f7f8..8abcd899f 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1946,26 +1946,28 @@ typedef struct TLSX { struct TLSX* next; /* List Behavior */ } TLSX; -WOLFSSL_LOCAL TLSX* TLSX_Find(TLSX* list, TLSX_Type type); -WOLFSSL_LOCAL void TLSX_Remove(TLSX** list, TLSX_Type type, void* heap); -WOLFSSL_LOCAL void TLSX_FreeAll(TLSX* list, void* heap); -WOLFSSL_LOCAL int TLSX_SupportExtensions(WOLFSSL* ssl); -WOLFSSL_LOCAL int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isRequest); +WOLFSSL_LOCAL TLSX* TLSX_Find(TLSX* list, TLSX_Type type); +WOLFSSL_LOCAL void TLSX_Remove(TLSX** list, TLSX_Type type, void* heap); +WOLFSSL_LOCAL void TLSX_FreeAll(TLSX* list, void* heap); +WOLFSSL_LOCAL int TLSX_SupportExtensions(WOLFSSL* ssl); +WOLFSSL_LOCAL int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isRequest); #ifndef NO_WOLFSSL_CLIENT -WOLFSSL_LOCAL word16 TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType); -WOLFSSL_LOCAL word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output, - byte msgType); +WOLFSSL_LOCAL int TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType, + word16* pLength); +WOLFSSL_LOCAL int TLSX_WriteRequest(WOLFSSL* ssl, byte* output, + byte msgType, word16* pOffset); #endif #ifndef NO_WOLFSSL_SERVER -WOLFSSL_LOCAL word16 TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType); -WOLFSSL_LOCAL word16 TLSX_WriteResponse(WOLFSSL* ssl, byte* output, - byte msgType); +WOLFSSL_LOCAL int TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType, + word16* pLength); +WOLFSSL_LOCAL int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, + word16* pOffset); #endif -WOLFSSL_LOCAL int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, - byte msgType, Suites *suites); +WOLFSSL_LOCAL int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, + byte msgType, Suites *suites); #elif defined(HAVE_SNI) \ || defined(HAVE_MAX_FRAGMENT) \ From 5c97374156c624fa26721d9d1c971b5f3f48e4fe Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 26 Apr 2018 14:04:54 -0700 Subject: [PATCH 2/2] Fix for RSA RSS check to make sure RSA is enabled. Added TLS 1.3 DH check for key sizes. --- src/tls.c | 13 +++++++++++++ src/tls13.c | 5 +---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/tls.c b/src/tls.c index 6ae031a66..bfd944765 100755 --- a/src/tls.c +++ b/src/tls.c @@ -48,6 +48,7 @@ #include "libntruencrypt/ntru_crypto.h" #include #endif + #ifdef HAVE_QSH static int TLSX_AddQSHKey(QSHKey** list, QSHKey* key); static byte* TLSX_QSHKeyFind_Pub(QSHKey* qsh, word16* pubLen, word16 name); @@ -76,6 +77,18 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions); #endif #endif +#ifdef WOLFSSL_TLS13 + #if !defined(NO_DH) && \ + !defined(HAVE_FFDHE_2048) && !defined(HAVE_FFDHE_3072) && \ + !defined(HAVE_FFDHE_4096) && !defined(HAVE_FFDHE_6144) && \ + !defined(HAVE_FFDHE_8192) + #error Please configure your TLS 1.3 DH key size using either: HAVE_FFDHE_2048, HAVE_FFDHE_3072, HAVE_FFDHE_4096, HAVE_FFDHE_6144 or HAVE_FFDHE_8192 + #endif + #if !defined(NO_RSA) && !defined(WC_RSA_PSS) + #error The build option WC_RSA_PSS is required for TLS 1.3 with RSA + #endif +#endif + #ifdef WOLFSSL_SHA384 #define P_HASH_MAX_SIZE WC_SHA384_DIGEST_SIZE diff --git a/src/tls13.c b/src/tls13.c index 46b410762..09bfc9806 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -129,10 +129,7 @@ #endif #ifndef HAVE_HKDF - #error The build option `HAVE_HKDF` is required for TLS 1.3 -#endif -#ifndef WC_RSA_PSS - #error The build option `WC_RSA_PSS` is required for TLS 1.3 + #error The build option HAVE_HKDF is required for TLS 1.3 #endif