diff --git a/src/tls.c b/src/tls.c index 3c7682c30c..2d22820007 100644 --- a/src/tls.c +++ b/src/tls.c @@ -2277,37 +2277,27 @@ int TLSX_ALPN_GetRequest(TLSX* extensions, void** data, word16 *dataSz) /** Creates a new SNI object. */ static SNI* TLSX_SNI_New(byte type, const void* data, word16 size, void* heap) { - SNI* sni = (SNI*)XMALLOC(sizeof(SNI), heap, DYNAMIC_TYPE_TLSX); + SNI* sni; (void)heap; - if (sni) { - sni->type = type; - sni->next = NULL; + if (type != WOLFSSL_SNI_HOST_NAME) /* invalid type */ + return NULL; - #ifndef NO_WOLFSSL_SERVER - sni->options = 0; - sni->status = WOLFSSL_SNI_NO_MATCH; - #endif + sni = (SNI*)XMALLOC(sizeof(SNI) + size + 1, heap, DYNAMIC_TYPE_TLSX); + if (sni == NULL) + return NULL; - switch (sni->type) { - case WOLFSSL_SNI_HOST_NAME: - sni->data.host_name = (char*)XMALLOC(size + 1, heap, - DYNAMIC_TYPE_TLSX); - if (sni->data.host_name) { - XSTRNCPY(sni->data.host_name, (const char*)data, size); - sni->data.host_name[size] = '\0'; - } else { - XFREE(sni, heap, DYNAMIC_TYPE_TLSX); - sni = NULL; - } - break; + sni->type = type; + sni->next = NULL; - default: /* invalid type */ - XFREE(sni, heap, DYNAMIC_TYPE_TLSX); - sni = NULL; - } - } +#ifndef NO_WOLFSSL_SERVER + sni->options = 0; + sni->status = WOLFSSL_SNI_NO_MATCH; +#endif + + XSTRNCPY(sni->host_name, (const char*)data, size); + sni->host_name[size] = '\0'; return sni; } @@ -2316,12 +2306,6 @@ static SNI* TLSX_SNI_New(byte type, const void* data, word16 size, void* heap) static void TLSX_SNI_Free(SNI* sni, void* heap) { if (sni) { - switch (sni->type) { - case WOLFSSL_SNI_HOST_NAME: - XFREE(sni->data.host_name, heap, DYNAMIC_TYPE_TLSX); - break; - } - XFREE(sni, heap, DYNAMIC_TYPE_TLSX); } (void)heap; @@ -2351,7 +2335,7 @@ WOLFSSL_TEST_VIS word16 TLSX_SNI_GetSize(SNI* list) switch (sni->type) { case WOLFSSL_SNI_HOST_NAME: - length += (word32)XSTRLEN((char*)sni->data.host_name); + length += (word32)XSTRLEN((char*)sni->host_name); break; } @@ -2377,12 +2361,12 @@ static word16 TLSX_SNI_Write(SNI* list, byte* output) switch (sni->type) { case WOLFSSL_SNI_HOST_NAME: - length = (word16)XSTRLEN((char*)sni->data.host_name); + length = (word16)XSTRLEN((char*)sni->host_name); c16toa(length, output + offset); /* sni length */ offset += OPAQUE16_LEN; - XMEMCPY(output + offset, sni->data.host_name, length); + XMEMCPY(output + offset, sni->host_name, length); offset += length; break; @@ -2579,7 +2563,7 @@ static int TLSX_SNI_Parse(WOLFSSL* ssl, const byte* input, word16 length, #endif { const char* hostName; - hostName = (sni != NULL) ? sni->data.host_name : NULL; + hostName = (sni != NULL) ? sni->host_name : NULL; matched = cacheOnly || (hostName != NULL && XSTRLEN(hostName) == size && XSTRNCMP(hostName, (const char*)input + offset, size) == 0); @@ -2756,7 +2740,7 @@ word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, void** data, switch (sni->type) { case WOLFSSL_SNI_HOST_NAME: if (data) { - *data = sni->data.host_name; + *data = sni->host_name; return (word16)XSTRLEN((char*)*data); } } diff --git a/tests/api/test_tls_ext.c b/tests/api/test_tls_ext.c index 4907068cbe..e8fc99b6be 100644 --- a/tests/api/test_tls_ext.c +++ b/tests/api/test_tls_ext.c @@ -2371,17 +2371,12 @@ int test_TLSX_SNI_GetSize_overflow(void) /* Append many SNI nodes to force overflow in the size calculation */ for (i = 1; EXPECT_SUCCESS() && i < num_sni; i++) { - sni = (SNI*)XMALLOC(sizeof(SNI), NULL, DYNAMIC_TYPE_TLSX); + sni = (SNI*)XMALLOC(sizeof(SNI) + 2, NULL, DYNAMIC_TYPE_TLSX); ExpectNotNull(sni); if (sni != NULL) { - XMEMSET(sni, 0, sizeof(SNI)); + XMEMSET(sni, 0, sizeof(SNI) + 2); sni->type = WOLFSSL_SNI_HOST_NAME; - sni->data.host_name = (char*)XMALLOC(2, NULL, DYNAMIC_TYPE_TLSX); - ExpectNotNull(sni->data.host_name); - if (sni->data.host_name != NULL) { - sni->data.host_name[0] = 'a'; - sni->data.host_name[1] = '\0'; - } + sni->host_name[0] = 'a'; sni->next = head->next; head->next = sni; } diff --git a/tests/api/test_tls_msgtype.c b/tests/api/test_tls_msgtype.c index cce5fa1bb6..6b60671590 100644 --- a/tests/api/test_tls_msgtype.c +++ b/tests/api/test_tls_msgtype.c @@ -44,9 +44,8 @@ #if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_TLS) && \ defined(HAVE_TLS_EXTENSIONS) -/* TLSX_SNI_Free() is file-static in src/tls.c. A test that detaches an SNI - * list from its extension has to release it the same way: the host name, then - * the node. */ +/* TLSX_SNI_Free() is file-static in src/tls.c. Each SNI node is one + * allocation that also holds the host name. */ #ifdef HAVE_SNI TEST_TLS_MSGTYPE_UNUSED static void test_tls_msgtype_free_sni(void* p, void* heap) @@ -56,8 +55,6 @@ static void test_tls_msgtype_free_sni(void* p, void* heap) while (sni != NULL) { SNI* next = sni->next; - if (sni->type == WOLFSSL_SNI_HOST_NAME) - XFREE(sni->data.host_name, heap, DYNAMIC_TYPE_TLSX); XFREE(sni, heap, DYNAMIC_TYPE_TLSX); sni = next; } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index d78bcfbcab..4ca82df2cc 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3678,12 +3678,17 @@ WOLFSSL_LOCAL int TLSX_Append(TLSX** list, TLSX_Type type, typedef struct SNI { byte type; /* SNI Type */ - union { char* host_name; } data; /* SNI Data */ struct SNI* next; /* List Behavior */ byte status; /* Matching result */ #ifndef NO_WOLFSSL_SERVER byte options; /* Behavior options */ #endif + /* Ignore "nonstandard extension used : zero-sized array in struct/union" + * MSVC warning */ + #ifdef _MSC_VER + #pragma warning(disable: 4200) + #endif + char host_name[WC_FLEXIBLE_ARRAY_SIZE]; /* SNI Data */ } SNI; WOLFSSL_LOCAL int TLSX_UseSNI(TLSX** extensions, byte type, const void* data,