Merge pull request #1521 from dgarske/tlsx_returncodes

Refactor of the TLSX code to support returning error codes
This commit is contained in:
toddouska
2018-04-30 11:46:41 -07:00
committed by GitHub
4 changed files with 192 additions and 102 deletions

View File

@@ -17139,9 +17139,11 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
if (QSH_Init(ssl) != 0) if (QSH_Init(ssl) != 0)
return MEMORY_E; return MEMORY_E;
#endif #endif
extSz = TLSX_GetRequestSize(ssl, client_hello); extSz = 0;
if (extSz != 0) ret = TLSX_GetRequestSize(ssl, client_hello, &extSz);
length += extSz; if (ret != 0)
return ret;
length += extSz;
#else #else
if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
extSz += HELLO_EXT_SZ + HELLO_EXT_SIGALGO_SZ extSz += HELLO_EXT_SZ + HELLO_EXT_SIGALGO_SZ
@@ -17232,7 +17234,11 @@ void PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo,
output[idx++] = NO_COMPRESSION; output[idx++] = NO_COMPRESSION;
#ifdef HAVE_TLS_EXTENSIONS #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 */ (void)idx; /* suppress analyzer warning, keep idx current */
#else #else
@@ -21136,13 +21142,14 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
/* handle generation of server_hello (2) */ /* handle generation of server_hello (2) */
int SendServerHello(WOLFSSL* ssl) int SendServerHello(WOLFSSL* ssl)
{ {
byte *output; int ret;
word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; byte *output;
int sendSz; word16 length;
int ret; word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
byte sessIdSz = ID_LEN; int sendSz;
byte echoId = 0; /* ticket echo id flag */ byte sessIdSz = ID_LEN;
byte cacheOff = 0; /* session cache off flag */ byte echoId = 0; /* ticket echo id flag */
byte cacheOff = 0; /* session cache off flag */
WOLFSSL_START(WC_FUNC_SERVER_HELLO_SEND); WOLFSSL_START(WC_FUNC_SERVER_HELLO_SEND);
WOLFSSL_ENTER("SendServerHello"); WOLFSSL_ENTER("SendServerHello");
@@ -21153,7 +21160,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
+ ENUM_LEN; + ENUM_LEN;
#ifdef HAVE_TLS_EXTENSIONS #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 #ifdef HAVE_SESSION_TICKET
if (ssl->options.useTicket) { if (ssl->options.useTicket) {
/* echo session id sz can be 0,32 or bogus len inbetween */ /* 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 */ /* last, extensions */
#ifdef HAVE_TLS_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 #else
#ifdef HAVE_EXTENDED_MASTER #ifdef HAVE_EXTENDED_MASTER
if (ssl->options.haveEMS) { if (ssl->options.haveEMS) {

140
src/tls.c
View File

@@ -48,6 +48,7 @@
#include "libntruencrypt/ntru_crypto.h" #include "libntruencrypt/ntru_crypto.h"
#include <wolfssl/wolfcrypt/random.h> #include <wolfssl/wolfcrypt/random.h>
#endif #endif
#ifdef HAVE_QSH #ifdef HAVE_QSH
static int TLSX_AddQSHKey(QSHKey** list, QSHKey* key); static int TLSX_AddQSHKey(QSHKey** list, QSHKey* key);
static byte* TLSX_QSHKeyFind_Pub(QSHKey* qsh, word16* pubLen, word16 name); 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
#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 #ifdef WOLFSSL_SHA384
#define P_HASH_MAX_SIZE WC_SHA384_DIGEST_SIZE #define P_HASH_MAX_SIZE WC_SHA384_DIGEST_SIZE
@@ -4631,7 +4644,7 @@ int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz,
* msgType The type of the message this extension is being written into. * msgType The type of the message this extension is being written into.
* returns the length of data that will be in the extension. * 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; WOLFSSL* ssl = (WOLFSSL*)data;
@@ -4651,14 +4664,16 @@ static word16 TLSX_SupportedVersions_GetSize(void* data, byte msgType)
if (!ssl->options.downgrade) if (!ssl->options.downgrade)
cnt = 1; cnt = 1;
return (word16)(OPAQUE8_LEN + cnt * OPAQUE16_LEN); *pSz += (word16)(OPAQUE8_LEN + cnt * OPAQUE16_LEN);
} }
#ifndef WOLFSSL_TLS13_DRAFT_18 #ifndef WOLFSSL_TLS13_DRAFT_18
else if (msgType == server_hello || msgType == hello_retry_request) else if (msgType == server_hello || msgType == hello_retry_request)
return OPAQUE16_LEN; *pSz += OPAQUE16_LEN;
#endif #endif
else else
return SANITY_MSG_E; return SANITY_MSG_E;
return 0;
} }
/* Writes the SupportedVersions extension into the buffer. /* Writes the SupportedVersions extension into the buffer.
@@ -4668,8 +4683,8 @@ static word16 TLSX_SupportedVersions_GetSize(void* data, byte msgType)
* msgType The type of the message this extension is being written into. * msgType The type of the message this extension is being written into.
* returns the length of data that was written. * returns the length of data that was written.
*/ */
static word16 TLSX_SupportedVersions_Write(void* data, byte* output, static int TLSX_SupportedVersions_Write(void* data, byte* output,
byte msgType) byte msgType, word16* pSz)
{ {
WOLFSSL* ssl = (WOLFSSL*)data; WOLFSSL* ssl = (WOLFSSL*)data;
ProtocolVersion pv; ProtocolVersion pv;
@@ -4710,18 +4725,20 @@ static word16 TLSX_SupportedVersions_Write(void* data, byte* output,
*(output++) = pv.minor - i; *(output++) = pv.minor - i;
} }
return (word16)(OPAQUE8_LEN + cnt * OPAQUE16_LEN); *pSz += (word16)(OPAQUE8_LEN + cnt * OPAQUE16_LEN);
} }
#ifndef WOLFSSL_TLS13_DRAFT_18 #ifndef WOLFSSL_TLS13_DRAFT_18
else if (msgType == server_hello || msgType == hello_retry_request) { else if (msgType == server_hello || msgType == hello_retry_request) {
output[0] = ssl->version.major; output[0] = ssl->version.major;
output[1] = ssl->version.minor; output[1] = ssl->version.minor;
return OPAQUE16_LEN; *pSz += OPAQUE16_LEN;
} }
#endif #endif
else else
return SANITY_MSG_E; return SANITY_MSG_E;
return 0;
} }
/* Parse the SupportedVersions extension. /* Parse the SupportedVersions extension.
@@ -4876,8 +4893,8 @@ static int TLSX_SetSupportedVersions(TLSX** extensions, const void* data,
#else #else
#define SV_GET_SIZE(a, b) 0 #define SV_GET_SIZE(a, b, c) 0
#define SV_WRITE(a, b, c) 0 #define SV_WRITE(a, b, c, d) 0
#define SV_PARSE(a, b, c, d) 0 #define SV_PARSE(a, b, c, d) 0
#endif /* WOLFSSL_TLS13 */ #endif /* WOLFSSL_TLS13 */
@@ -4908,12 +4925,13 @@ static void TLSX_Cookie_FreeAll(Cookie* cookie, void* heap)
* msgType The type of the message this extension is being written into. * msgType The type of the message this extension is being written into.
* returns the number of bytes of the encoded Cookie extension. * 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) if (msgType == client_hello || msgType == hello_retry_request)
return OPAQUE16_LEN + cookie->len; *pSz += OPAQUE16_LEN + cookie->len;
else
return SANITY_MSG_E; return SANITY_MSG_E;
return 0;
} }
/* Writes the Cookie extension into the output buffer. /* Writes the Cookie extension into the output buffer.
@@ -4925,16 +4943,17 @@ static word16 TLSX_Cookie_GetSize(Cookie* cookie, byte msgType)
* msgType The type of the message this extension is being written into. * msgType The type of the message this extension is being written into.
* returns the number of bytes written into the buffer. * 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) { if (msgType == client_hello || msgType == hello_retry_request) {
c16toa(cookie->len, output); c16toa(cookie->len, output);
output += OPAQUE16_LEN; output += OPAQUE16_LEN;
XMEMCPY(output, &cookie->data, cookie->len); XMEMCPY(output, &cookie->data, cookie->len);
return OPAQUE16_LEN + cookie->len; *pSz += OPAQUE16_LEN + cookie->len;
} }
else
return SANITY_MSG_E; /* ! */ return SANITY_MSG_E;
return 0;
} }
/* Parse the Cookie extension. /* Parse the Cookie extension.
@@ -5040,8 +5059,8 @@ int TLSX_Cookie_Use(WOLFSSL* ssl, byte* data, word16 len, byte* mac,
#else #else
#define CKE_FREE_ALL(a, b) 0 #define CKE_FREE_ALL(a, b) 0
#define CKE_GET_SIZE(a, b) 0 #define CKE_GET_SIZE(a, b, c) 0
#define CKE_WRITE(a, b, c) 0 #define CKE_WRITE(a, b, c, d) 0
#define CKE_PARSE(a, b, c, d) 0 #define CKE_PARSE(a, b, c, d) 0
#endif #endif
@@ -7643,8 +7662,9 @@ int TLSX_SupportExtensions(WOLFSSL* ssl) {
} }
/** Tells the buffered size of the extensions in a list. */ /** 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; TLSX* extension;
word16 length = 0; word16 length = 0;
byte isRequest = (msgType == client_hello || byte isRequest = (msgType == client_hello ||
@@ -7724,11 +7744,11 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType)
#ifdef WOLFSSL_TLS13 #ifdef WOLFSSL_TLS13
case TLSX_SUPPORTED_VERSIONS: case TLSX_SUPPORTED_VERSIONS:
length += SV_GET_SIZE(extension->data, msgType); ret = SV_GET_SIZE(extension->data, msgType, &length);
break; break;
case TLSX_COOKIE: case TLSX_COOKIE:
length += CKE_GET_SIZE((Cookie*)extension->data, msgType); ret = CKE_GET_SIZE((Cookie*)extension->data, msgType, &length);
break; break;
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
@@ -7770,14 +7790,17 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType)
TURN_ON(semaphore, TLSX_ToSemaphore(extension->type)); TURN_ON(semaphore, TLSX_ToSemaphore(extension->type));
} }
return length; *pLength += length;
return ret;
} }
/** Writes the extensions of a list in a buffer. */ /** Writes the extensions of a list in a buffer. */
static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore, static int TLSX_Write(TLSX* list, byte* output, byte* semaphore,
byte msgType) byte msgType, word16* pOffset)
{ {
TLSX* extension; int ret = 0;
TLSX* extension;
word16 offset = 0; word16 offset = 0;
word16 length_offset = 0; word16 length_offset = 0;
byte isRequest = (msgType == client_hello || byte isRequest = (msgType == client_hello ||
@@ -7877,13 +7900,13 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore,
#ifdef WOLFSSL_TLS13 #ifdef WOLFSSL_TLS13
case TLSX_SUPPORTED_VERSIONS: case TLSX_SUPPORTED_VERSIONS:
WOLFSSL_MSG("Supported Versions extension to write"); 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; break;
case TLSX_COOKIE: case TLSX_COOKIE:
WOLFSSL_MSG("Cookie extension to write"); WOLFSSL_MSG("Cookie extension to write");
offset += CKE_WRITE((Cookie*)extension->data, output + offset, ret = CKE_WRITE((Cookie*)extension->data, output + offset,
msgType); msgType, &offset);
break; break;
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
@@ -7936,7 +7959,9 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore,
TURN_ON(semaphore, TLSX_ToSemaphore(extension->type)); TURN_ON(semaphore, TLSX_ToSemaphore(extension->type));
} }
return offset; *pOffset += offset;
return ret;
} }
@@ -8588,8 +8613,9 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
#ifndef NO_WOLFSSL_CLIENT #ifndef NO_WOLFSSL_CLIENT
/** Tells the buffered size of extensions to be sent into the client hello. */ /** 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; word16 length = 0;
byte semaphore[SEMAPHORE_SIZE] = {0}; byte semaphore[SEMAPHORE_SIZE] = {0};
@@ -8655,9 +8681,9 @@ word16 TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType)
#endif #endif
if (ssl->extensions) if (ssl->extensions)
length += TLSX_GetSize(ssl->extensions, semaphore, msgType); ret = TLSX_GetSize(ssl->extensions, semaphore, msgType, &length);
if (ssl->ctx && ssl->ctx->extensions) 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 #ifdef HAVE_EXTENDED_MASTER
if (msgType == client_hello && ssl->options.haveEMS && if (msgType == client_hello && ssl->options.haveEMS &&
@@ -8669,12 +8695,15 @@ word16 TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType)
if (length) if (length)
length += OPAQUE16_LEN; /* for total length storage. */ length += OPAQUE16_LEN; /* for total length storage. */
return length; *pLength += length;
return ret;
} }
/** Writes the extensions to be sent into the client hello. */ /** 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; word16 offset = 0;
byte semaphore[SEMAPHORE_SIZE] = {0}; byte semaphore[SEMAPHORE_SIZE] = {0};
@@ -8749,12 +8778,12 @@ word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType)
#endif #endif
if (ssl->extensions) { if (ssl->extensions) {
offset += TLSX_Write(ssl->extensions, output + offset, semaphore, ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
msgType); msgType, &offset);
} }
if (ssl->ctx && ssl->ctx->extensions) { if (ssl->ctx && ssl->ctx->extensions) {
offset += TLSX_Write(ssl->ctx->extensions, output + offset, semaphore, ret = TLSX_Write(ssl->ctx->extensions, output + offset, semaphore,
msgType); msgType, &offset);
} }
#ifdef HAVE_EXTENDED_MASTER #ifdef HAVE_EXTENDED_MASTER
@@ -8772,8 +8801,8 @@ word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType)
if (msgType == client_hello && IsAtLeastTLSv1_3(ssl->version)) { if (msgType == client_hello && IsAtLeastTLSv1_3(ssl->version)) {
/* Write out what we can of Pre-shared key extension. */ /* Write out what we can of Pre-shared key extension. */
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY)); TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
offset += TLSX_Write(ssl->extensions, output + offset, semaphore, ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
client_hello); client_hello, &offset);
} }
#endif #endif
#endif #endif
@@ -8781,7 +8810,9 @@ word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType)
if (offset > OPAQUE16_LEN || msgType != client_hello) if (offset > OPAQUE16_LEN || msgType != client_hello)
c16toa(offset - OPAQUE16_LEN, output); /* extensions length */ c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
return offset; *pOffset += offset;
return ret;
} }
#endif /* NO_WOLFSSL_CLIENT */ #endif /* NO_WOLFSSL_CLIENT */
@@ -8789,8 +8820,9 @@ word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType)
#ifndef NO_WOLFSSL_SERVER #ifndef NO_WOLFSSL_SERVER
/** Tells the buffered size of extensions to be sent into the server hello. */ /** 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; word16 length = 0;
byte semaphore[SEMAPHORE_SIZE] = {0}; byte semaphore[SEMAPHORE_SIZE] = {0};
@@ -8874,19 +8906,22 @@ word16 TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType)
#endif #endif
if (TLSX_SupportExtensions(ssl)) 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. */ /* All the response data is set at the ssl object only, so no ctx here. */
if (length || msgType != server_hello) if (length || msgType != server_hello)
length += OPAQUE16_LEN; /* for total length storage. */ length += OPAQUE16_LEN; /* for total length storage. */
return length; *pLength += length;
return ret;
} }
/** Writes the server hello extensions into a buffer. */ /** 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; word16 offset = 0;
if (TLSX_SupportExtensions(ssl) && output) { if (TLSX_SupportExtensions(ssl) && output) {
@@ -8959,15 +8994,15 @@ word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType)
offset += OPAQUE16_LEN; /* extensions length */ offset += OPAQUE16_LEN; /* extensions length */
offset += TLSX_Write(ssl->extensions, output + offset, semaphore, ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
msgType); msgType, &offset);
#ifdef WOLFSSL_TLS13 #ifdef WOLFSSL_TLS13
if (msgType == hello_retry_request) { if (msgType == hello_retry_request) {
XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE); XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_COOKIE)); TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
offset += TLSX_Write(ssl->extensions, output + offset, semaphore, ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
msgType); msgType, &offset);
} }
#endif #endif
@@ -8984,7 +9019,10 @@ word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType)
c16toa(offset - OPAQUE16_LEN, output); /* extensions length */ c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
} }
return offset; if (pOffset)
*pOffset += offset;
return ret;
} }
#endif /* NO_WOLFSSL_SERVER */ #endif /* NO_WOLFSSL_SERVER */

View File

@@ -128,6 +128,11 @@
#define FALSE 0 #define FALSE 0
#endif #endif
#ifndef HAVE_HKDF
#error The build option HAVE_HKDF is required for TLS 1.3
#endif
/* Set ret to error value and jump to label. /* Set ret to error value and jump to label.
* *
* err The error value to set. * err The error value to set.
@@ -2353,7 +2358,7 @@ static int WritePSKBinders(WOLFSSL* ssl, byte* output, word32 idx)
int SendTls13ClientHello(WOLFSSL* ssl) int SendTls13ClientHello(WOLFSSL* ssl)
{ {
byte* output; byte* output;
word32 length; word16 length;
word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
int sendSz; int sendSz;
int ret; int ret;
@@ -2414,7 +2419,9 @@ int SendTls13ClientHello(WOLFSSL* ssl)
return MEMORY_E; return MEMORY_E;
#endif #endif
/* Include length of TLS extensions. */ /* 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. */ /* Total message size. */
sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ; sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
@@ -2482,7 +2489,11 @@ int SendTls13ClientHello(WOLFSSL* ssl)
output[idx++] = NO_COMPRESSION; output[idx++] = NO_COMPRESSION;
/* Write out extensions for a request. */ /* 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) #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
/* Resumption has a specific set of extensions and binder is calculated /* Resumption has a specific set of extensions and binder is calculated
@@ -3988,16 +3999,17 @@ int SendTls13HelloRetryRequest(WOLFSSL* ssl)
int ret; int ret;
byte* output; byte* output;
word32 length; word32 length;
word32 len; word16 len;
word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
int sendSz; int sendSz;
WOLFSSL_ENTER("SendTls13HelloRetryRequest"); WOLFSSL_ENTER("SendTls13HelloRetryRequest");
/* Get the length of the extensions that will be written. */ /* 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. */ /* There must be extensions sent to indicate what client needs to do. */
if (len == 0) if (ret != 0)
return MISSING_HANDSHAKE_DATA; return MISSING_HANDSHAKE_DATA;
/* Protocol version + Extensions */ /* Protocol version + Extensions */
@@ -4026,7 +4038,9 @@ int SendTls13HelloRetryRequest(WOLFSSL* ssl)
output[idx++] = TLS_DRAFT_MINOR; output[idx++] = TLS_DRAFT_MINOR;
/* Add TLS extensions. */ /* 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; idx += len;
#ifdef WOLFSSL_CALLBACKS #ifdef WOLFSSL_CALLBACKS
@@ -4063,11 +4077,11 @@ static
/* handle generation of TLS 1.3 server_hello (2) */ /* handle generation of TLS 1.3 server_hello (2) */
int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType) int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType)
{ {
int ret;
byte* output; byte* output;
word32 length; word16 length;
word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
int sendSz; int sendSz;
int ret;
WOLFSSL_START(WC_FUNC_SERVER_HELLO_SEND); WOLFSSL_START(WC_FUNC_SERVER_HELLO_SEND);
WOLFSSL_ENTER("SendTls13ServerHello"); WOLFSSL_ENTER("SendTls13ServerHello");
@@ -4081,14 +4095,19 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType)
#ifdef WOLFSSL_TLS13_DRAFT_18 #ifdef WOLFSSL_TLS13_DRAFT_18
/* Protocol version, server random, cipher suite and extensions. */ /* Protocol version, server random, cipher suite and extensions. */
length = VERSION_SZ + RAN_LEN + SUITE_LEN + length = VERSION_SZ + RAN_LEN + SUITE_LEN;
TLSX_GetResponseSize(ssl, server_hello); ret = TLSX_GetResponseSize(ssl, server_hello, &length);
if (ret != 0)
return ret;
#else #else
/* Protocol version, server random, session id, cipher suite, compression /* Protocol version, server random, session id, cipher suite, compression
* and extensions. * and extensions.
*/ */
length = VERSION_SZ + RAN_LEN + ENUM_LEN + ssl->session.sessionIDSz + 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 #endif
sendSz = idx + length; sendSz = idx + length;
@@ -4158,7 +4177,9 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType)
#endif #endif
/* Extensions */ /* 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; ssl->buffers.outputBuffer.length += sendSz;
@@ -4202,7 +4223,7 @@ static int SendTls13EncryptedExtensions(WOLFSSL* ssl)
{ {
int ret; int ret;
byte* output; byte* output;
word32 length; word16 length = 0;
word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
int sendSz; int sendSz;
@@ -4238,7 +4259,10 @@ static int SendTls13EncryptedExtensions(WOLFSSL* ssl)
return ret; return ret;
#endif #endif
length = TLSX_GetResponseSize(ssl, encrypted_extensions); ret = TLSX_GetResponseSize(ssl, encrypted_extensions, &length);
if (ret != 0)
return ret;
sendSz = idx + length; sendSz = idx + length;
/* Encryption always on. */ /* Encryption always on. */
sendSz += MAX_MSG_EXTRA; sendSz += MAX_MSG_EXTRA;
@@ -4255,7 +4279,9 @@ static int SendTls13EncryptedExtensions(WOLFSSL* ssl)
/* Put the record and handshake headers on. */ /* Put the record and handshake headers on. */
AddTls13Headers(output, length, encrypted_extensions, ssl); 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; idx += length;
#ifdef WOLFSSL_CALLBACKS #ifdef WOLFSSL_CALLBACKS
@@ -4304,7 +4330,7 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx,
int ret; int ret;
int sendSz; int sendSz;
word32 i; word32 i;
int reqSz; word16 reqSz;
#ifndef WOLFSSL_TLS13_DRAFT_18 #ifndef WOLFSSL_TLS13_DRAFT_18
TLSX* ext; TLSX* ext;
#endif #endif
@@ -4363,8 +4389,10 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx,
ext->resp = 0; ext->resp = 0;
i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
reqSz = OPAQUE8_LEN + reqCtxLen + reqSz = OPAQUE8_LEN + reqCtxLen;
TLSX_GetRequestSize(ssl, certificate_request); ret = TLSX_GetRequestSize(ssl, certificate_request, &reqSz);
if (ret != 0)
return ret;
sendSz = i + reqSz; sendSz = i + reqSz;
/* Always encrypted and make room for padding. */ /* Always encrypted and make room for padding. */
@@ -4389,7 +4417,11 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx,
} }
/* Certificate extensions. */ /* 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 #endif
/* Always encrypted. */ /* Always encrypted. */
@@ -6457,7 +6489,7 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl)
byte* output; byte* output;
int ret; int ret;
int sendSz; int sendSz;
word32 extSz; word16 extSz;
word32 length; word32 length;
word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
@@ -6490,7 +6522,10 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl)
ssl->session.maxEarlyDataSz = ssl->options.maxEarlyDataSz; ssl->session.maxEarlyDataSz = ssl->options.maxEarlyDataSz;
if (ssl->session.maxEarlyDataSz > 0) if (ssl->session.maxEarlyDataSz > 0)
TLSX_EarlyData_Use(ssl, ssl->session.maxEarlyDataSz); 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 #else
extSz = EXTS_SZ; extSz = EXTS_SZ;
#endif #endif
@@ -6535,7 +6570,11 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl)
idx += ssl->session.ticketLen; idx += ssl->session.ticketLen;
#ifdef WOLFSSL_EARLY_DATA #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 #else
/* No extension support - empty extensions. */ /* No extension support - empty extensions. */
c16toa(0, output + idx); c16toa(0, output + idx);
@@ -6544,9 +6583,9 @@ static int SendTls13NewSessionTicket(WOLFSSL* ssl)
ssl->options.haveSessionId = 1; ssl->options.haveSessionId = 1;
#ifndef NO_SESSION_CACHE #ifndef NO_SESSION_CACHE
AddSession(ssl); AddSession(ssl);
#endif #endif
/* This message is always encrypted. */ /* This message is always encrypted. */
sendSz = BuildTls13Message(ssl, output, sendSz, output + RECORD_HEADER_SZ, sendSz = BuildTls13Message(ssl, output, sendSz, output + RECORD_HEADER_SZ,

View File

@@ -1946,26 +1946,28 @@ typedef struct TLSX {
struct TLSX* next; /* List Behavior */ struct TLSX* next; /* List Behavior */
} TLSX; } TLSX;
WOLFSSL_LOCAL TLSX* TLSX_Find(TLSX* list, TLSX_Type type); 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_Remove(TLSX** list, TLSX_Type type, void* heap);
WOLFSSL_LOCAL void TLSX_FreeAll(TLSX* list, void* heap); WOLFSSL_LOCAL void TLSX_FreeAll(TLSX* list, void* heap);
WOLFSSL_LOCAL int TLSX_SupportExtensions(WOLFSSL* ssl); WOLFSSL_LOCAL int TLSX_SupportExtensions(WOLFSSL* ssl);
WOLFSSL_LOCAL int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isRequest); WOLFSSL_LOCAL int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isRequest);
#ifndef NO_WOLFSSL_CLIENT #ifndef NO_WOLFSSL_CLIENT
WOLFSSL_LOCAL word16 TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType); WOLFSSL_LOCAL int TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType,
WOLFSSL_LOCAL word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output, word16* pLength);
byte msgType); WOLFSSL_LOCAL int TLSX_WriteRequest(WOLFSSL* ssl, byte* output,
byte msgType, word16* pOffset);
#endif #endif
#ifndef NO_WOLFSSL_SERVER #ifndef NO_WOLFSSL_SERVER
WOLFSSL_LOCAL word16 TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType); WOLFSSL_LOCAL int TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType,
WOLFSSL_LOCAL word16 TLSX_WriteResponse(WOLFSSL* ssl, byte* output, word16* pLength);
byte msgType); WOLFSSL_LOCAL int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType,
word16* pOffset);
#endif #endif
WOLFSSL_LOCAL int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, WOLFSSL_LOCAL int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length,
byte msgType, Suites *suites); byte msgType, Suites *suites);
#elif defined(HAVE_SNI) \ #elif defined(HAVE_SNI) \
|| defined(HAVE_MAX_FRAGMENT) \ || defined(HAVE_MAX_FRAGMENT) \