Add test case

This commit is contained in:
Eric Blankenhorn
2026-02-24 08:35:51 -06:00
parent 187534855d
commit be7f934157
5 changed files with 77 additions and 6 deletions
+9 -5
View File
@@ -2135,7 +2135,7 @@ static void TLSX_SNI_FreeAll(SNI* list, void* heap)
}
/** Tells the buffered size of the SNI objects in a list. */
static word16 TLSX_SNI_GetSize(SNI* list)
WOLFSSL_TEST_VIS word16 TLSX_SNI_GetSize(SNI* list)
{
SNI* sni;
word32 length = OPAQUE16_LEN; /* list length */
@@ -3241,15 +3241,19 @@ word16 TLSX_CSR_GetSize_ex(CertificateStatusRequest* csr, byte isRequest,
if (csr->ssl != NULL && SSL_CM(csr->ssl) != NULL &&
SSL_CM(csr->ssl)->ocsp_stapling != NULL &&
SSL_CM(csr->ssl)->ocsp_stapling->statusCb != NULL) {
if (WOLFSSL_MAX_16BIT - OPAQUE8_LEN - OPAQUE24_LEN <
csr->ssl->ocspCsrResp[idx].length) {
return 0;
}
size = OPAQUE8_LEN + OPAQUE24_LEN +
csr->ssl->ocspCsrResp[idx].length;
if (size > WOLFSSL_MAX_16BIT)
return 0;
return (word16)size;
}
size = OPAQUE8_LEN + OPAQUE24_LEN + csr->responses[idx].length;
if (size > WOLFSSL_MAX_16BIT)
if (WOLFSSL_MAX_16BIT - OPAQUE8_LEN - OPAQUE24_LEN <
csr->responses[idx].length) {
return 0;
}
size = OPAQUE8_LEN + OPAQUE24_LEN + csr->responses[idx].length;
return (word16)size;
}
#else
+1
View File
@@ -32914,6 +32914,7 @@ TEST_CASE testCases[] = {
TEST_DECL(test_certificate_authorities_certificate_request),
TEST_DECL(test_certificate_authorities_client_hello),
TEST_DECL(test_TLSX_TCA_Find),
TEST_DECL(test_TLSX_SNI_GetSize_overflow),
TEST_DECL(test_wolfSSL_wolfSSL_UseSecureRenegotiation),
TEST_DECL(test_wolfSSL_SCR_Reconnect),
TEST_DECL(test_wolfSSL_SCR_check_enabled),
+64
View File
@@ -545,3 +545,67 @@ int test_certificate_authorities_client_hello(void) {
#endif
return EXPECT_RESULT();
}
/* Test that the SNI size calculation returns 0 on overflow instead of
* wrapping around to a small value (integer overflow vulnerability). */
int test_TLSX_SNI_GetSize_overflow(void)
{
EXPECT_DECLS;
#if defined(HAVE_SNI) && !defined(NO_WOLFSSL_CLIENT) && !defined(NO_TLS)
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
TLSX* sni_ext = NULL;
SNI* head = NULL;
SNI* sni = NULL;
int i;
/* Each SNI adds ENUM_LEN(1) + OPAQUE16_LEN(2) + hostname_len to the size.
* With a 1-byte hostname, each entry adds 4 bytes. Starting from
* OPAQUE16_LEN(2) base, we need enough entries to exceed UINT16_MAX. */
const int num_sni = (0xFFFF / 4) + 2;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
ExpectNotNull(ssl = wolfSSL_new(ctx));
/* Add initial SNI via public API */
ExpectIntEQ(WOLFSSL_SUCCESS,
wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME, "a", 1));
/* Find the SNI extension and manually build a long chain */
if (EXPECT_SUCCESS()) {
sni_ext = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME);
ExpectNotNull(sni_ext);
}
if (EXPECT_SUCCESS()) {
head = (SNI*)sni_ext->data;
ExpectNotNull(head);
}
/* 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);
ExpectNotNull(sni);
if (sni != NULL) {
XMEMSET(sni, 0, sizeof(SNI));
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->next = head->next;
head->next = sni;
}
}
if (EXPECT_SUCCESS()) {
/* The fixed calculation should return 0 (overflow detected) */
ExpectIntEQ(TLSX_SNI_GetSize((SNI*)sni_ext->data), 0);
}
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
+1
View File
@@ -27,5 +27,6 @@ int test_wolfSSL_DisableExtendedMasterSecret(void);
int test_certificate_authorities_certificate_request(void);
int test_certificate_authorities_client_hello(void);
int test_TLSX_TCA_Find(void);
int test_TLSX_SNI_GetSize_overflow(void);
#endif /* TESTS_API_TEST_TLS_EMS_H */
+2 -1
View File
@@ -3169,7 +3169,7 @@ struct TLSX {
struct TLSX* next; /* List Behavior */
};
WOLFSSL_LOCAL TLSX* TLSX_Find(TLSX* list, TLSX_Type type);
WOLFSSL_TEST_VIS 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);
@@ -3237,6 +3237,7 @@ WOLFSSL_LOCAL int TLSX_UseSNI(TLSX** extensions, byte type, const void* data,
WOLFSSL_LOCAL byte TLSX_SNI_Status(TLSX* extensions, byte type);
WOLFSSL_LOCAL word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type,
void** data, byte ignoreStatus);
WOLFSSL_TEST_VIS word16 TLSX_SNI_GetSize(SNI* list);
#ifndef NO_WOLFSSL_SERVER
WOLFSSL_LOCAL void TLSX_SNI_SetOptions(TLSX* extensions, byte type,