Skip to content

Commit 1468d77

Browse files
Merge pull request #6644 from julek-wolfssl/zd/16441
TLSX_CA_Names_Parse: Verify the length of the extension
2 parents 4b80dcf + 854ae0d commit 1468d77

2 files changed

Lines changed: 70 additions & 11 deletions

File tree

src/tls.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6634,6 +6634,9 @@ static int TLSX_CA_Names_Parse(WOLFSSL *ssl, const byte* input,
66346634
if (ssl->client_ca_names == NULL)
66356635
return MEMORY_ERROR;
66366636

6637+
if (length < OPAQUE16_LEN)
6638+
return BUFFER_ERROR;
6639+
66376640
ato16(input, &extLen);
66386641
input += OPAQUE16_LEN;
66396642
length -= OPAQUE16_LEN;
@@ -6644,6 +6647,7 @@ static int TLSX_CA_Names_Parse(WOLFSSL *ssl, const byte* input,
66446647
word32 idx = 0;
66456648
WOLFSSL_X509_NAME* name = NULL;
66466649
int ret = 0;
6650+
int didInit = FALSE;
66476651
/* Use a DecodedCert struct to get access to GetName to
66486652
* parse DN name */
66496653
#ifdef WOLFSSL_SMALL_STACK
@@ -6655,28 +6659,33 @@ static int TLSX_CA_Names_Parse(WOLFSSL *ssl, const byte* input,
66556659
DecodedCert cert[1];
66566660
#endif
66576661

6662+
if (length < OPAQUE16_LEN)
6663+
return BUFFER_ERROR;
66586664
ato16(input, &extLen);
66596665
idx += OPAQUE16_LEN;
66606666

66616667
if (extLen > length)
6662-
return BUFFER_ERROR;
6663-
6664-
InitDecodedCert(cert, input + idx, extLen, ssl->heap);
6665-
idx += extLen;
6668+
ret = BUFFER_ERROR;
66666669

6667-
ret = GetName(cert, SUBJECT, extLen);
6670+
if (ret == 0) {
6671+
InitDecodedCert(cert, input + idx, extLen, ssl->heap);
6672+
didInit = TRUE;
6673+
idx += extLen;
6674+
ret = GetName(cert, SUBJECT, extLen);
6675+
}
66686676

66696677
if (ret == 0 && (name = wolfSSL_X509_NAME_new()) == NULL)
66706678
ret = MEMORY_ERROR;
66716679

6672-
if (ret == 0)
6680+
if (ret == 0) {
66736681
CopyDecodedName(name, cert, SUBJECT);
6682+
if (wolfSSL_sk_X509_NAME_push(ssl->client_ca_names, name)
6683+
== WOLFSSL_FAILURE)
6684+
ret = MEMORY_ERROR;
6685+
}
66746686

6675-
if (ret == 0 && wolfSSL_sk_X509_NAME_push(ssl->client_ca_names, name)
6676-
== WOLFSSL_FAILURE)
6677-
ret = MEMORY_ERROR;
6678-
6679-
FreeDecodedCert(cert);
6687+
if (didInit)
6688+
FreeDecodedCert(cert);
66806689

66816690
#ifdef WOLFSSL_SMALL_STACK
66826691
XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);

tests/api.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63086,6 +63086,55 @@ static int test_dtls_no_extensions(void)
6308663086
return EXPECT_RESULT();
6308763087
}
6308863088

63089+
static int test_TLSX_CA_NAMES_bad_extension(void)
63090+
{
63091+
EXPECT_DECLS;
63092+
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_TLS13) && \
63093+
!defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES) && \
63094+
defined(OPENSSL_EXTRA) && defined(WOLFSSL_SHA384) && \
63095+
defined(HAVE_NULL_CIPHER)
63096+
/* This test should only fail (with BUFFER_ERROR) when we actually try to
63097+
* parse the CA Names extension. Otherwise it will return other non-related
63098+
* errors. If CA Names will be parsed in more configurations, that should
63099+
* be reflected in the macro guard above. */
63100+
WOLFSSL *ssl_c = NULL;
63101+
WOLFSSL_CTX *ctx_c = NULL;
63102+
struct test_memio_ctx test_ctx;
63103+
/* HRR + SH using TLS_DHE_PSK_WITH_NULL_SHA384 */
63104+
const byte shBadCaNamesExt[] = {
63105+
0x16, 0x03, 0x04, 0x00, 0x3f, 0x02, 0x00, 0x00, 0x3b, 0x03, 0x03, 0xcf,
63106+
0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c, 0x02, 0x1e,
63107+
0x65, 0xb8, 0x91, 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, 0x8c, 0x5e, 0x07,
63108+
0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c, 0x00, 0x13, 0x03, 0x00, 0x00,
63109+
0x13, 0x94, 0x7e, 0x00, 0x03, 0x0b, 0xf7, 0x03, 0x00, 0x2b, 0x00, 0x02,
63110+
0x03, 0x04, 0x00, 0x33, 0x00, 0x02, 0x00, 0x19, 0x16, 0x03, 0x03, 0x00,
63111+
0x5c, 0x02, 0x00, 0x00, 0x3b, 0x03, 0x03, 0x03, 0xcf, 0x21, 0xad, 0x74,
63112+
0x00, 0x00, 0x83, 0x3f, 0x3b, 0x80, 0x01, 0xac, 0x65, 0x8c, 0x19, 0x2a,
63113+
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x02, 0x00, 0x9e, 0x09, 0x1c, 0xe8,
63114+
0xa8, 0x09, 0x9c, 0x00, 0xc0, 0xb5, 0x00, 0x00, 0x11, 0x8f, 0x00, 0x00,
63115+
0x03, 0x3f, 0x00, 0x0c, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04, 0x13, 0x05,
63116+
0x00, 0x00, 0x08, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00,
63117+
0x0d, 0x00, 0x00, 0x11, 0x00, 0x00, 0x0d, 0x00, 0x2f, 0x00, 0x01, 0xff,
63118+
0xff, 0xff, 0xff, 0xfa, 0x0d, 0x00, 0x00, 0x00, 0xad, 0x02
63119+
};
63120+
63121+
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
63122+
63123+
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, NULL, &ssl_c, NULL,
63124+
wolfTLSv1_3_client_method, NULL), 0);
63125+
63126+
XMEMCPY(test_ctx.c_buff, shBadCaNamesExt, sizeof(shBadCaNamesExt));
63127+
test_ctx.c_len = sizeof(shBadCaNamesExt);
63128+
63129+
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
63130+
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), BUFFER_ERROR);
63131+
63132+
wolfSSL_free(ssl_c);
63133+
wolfSSL_CTX_free(ctx_c);
63134+
#endif
63135+
return EXPECT_RESULT();
63136+
}
63137+
6308963138
/*----------------------------------------------------------------------------*
6309063139
| Main
6309163140
*----------------------------------------------------------------------------*/
@@ -64337,6 +64386,7 @@ TEST_CASE testCases[] = {
6433764386
TEST_DECL(test_dtls_ipv6_check),
6433864387
TEST_DECL(test_wolfSSL_SCR_after_resumption),
6433964388
TEST_DECL(test_dtls_no_extensions),
64389+
TEST_DECL(test_TLSX_CA_NAMES_bad_extension),
6434064390
/* This test needs to stay at the end to clean up any caches allocated. */
6434164391
TEST_DECL(test_wolfSSL_Cleanup)
6434264392
};

0 commit comments

Comments
 (0)