@@ -3515,6 +3515,57 @@ static int test_wolfSSL_CTX_add1_chain_cert(void)
35153515 return EXPECT_RESULT();
35163516}
35173517
3518+ /* Test that wolfssl_add_to_chain rejects sizes that would overflow word32.
3519+ * ZD #21241 */
3520+ static int test_wolfSSL_add_to_chain_overflow(void)
3521+ {
3522+ EXPECT_DECLS;
3523+ #if !defined(NO_CERTS) && defined(OPENSSL_EXTRA) && \
3524+ defined(KEEP_OUR_CERT) && !defined(NO_RSA) && !defined(NO_TLS) && \
3525+ !defined(NO_WOLFSSL_CLIENT) && !defined(NO_FILESYSTEM)
3526+ WOLFSSL_CTX* ctx = NULL;
3527+ WOLFSSL_X509* x509 = NULL;
3528+ DerBuffer* fakeChain = NULL;
3529+
3530+ ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
3531+
3532+ /* Load a real cert so ctx->certificate is set (first add goes there). */
3533+ ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(
3534+ "./certs/intermediate/client-int-cert.pem", WOLFSSL_FILETYPE_PEM));
3535+ ExpectIntEQ(SSL_CTX_add1_chain_cert(ctx, x509), 1);
3536+ wolfSSL_X509_free(x509);
3537+ x509 = NULL;
3538+
3539+ /* Now ctx->certificate is set, next add goes to certChain via
3540+ * wolfssl_add_to_chain. Fake a chain whose length is near UINT32_MAX
3541+ * so the size calculation (len + CERT_HEADER_SZ + certSz) overflows. */
3542+ fakeChain = (DerBuffer*)XMALLOC(sizeof(DerBuffer) + 16, ctx->heap,
3543+ DYNAMIC_TYPE_CERT);
3544+ ExpectNotNull(fakeChain);
3545+ if (EXPECT_SUCCESS()) {
3546+ XMEMSET(fakeChain, 0, sizeof(DerBuffer) + 16);
3547+ fakeChain->buffer = (byte*)(fakeChain + 1);
3548+ fakeChain->length = WOLFSSL_MAX_32BIT - 2; /* will overflow with any cert */
3549+ fakeChain->type = CERT_TYPE;
3550+ fakeChain->dynType = DYNAMIC_TYPE_CERT;
3551+ /* Replace the real chain with our fake one. */
3552+ if (ctx->certChain != NULL) {
3553+ XFREE(ctx->certChain, ctx->heap, DYNAMIC_TYPE_CERT);
3554+ }
3555+ ctx->certChain = fakeChain;
3556+ }
3557+
3558+ /* Try to add another cert - this MUST fail due to overflow guard. */
3559+ ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(
3560+ "./certs/intermediate/ca-int2-cert.pem", WOLFSSL_FILETYPE_PEM));
3561+ ExpectIntEQ(SSL_CTX_add1_chain_cert(ctx, x509), 0);
3562+ wolfSSL_X509_free(x509);
3563+
3564+ wolfSSL_CTX_free(ctx);
3565+ #endif
3566+ return EXPECT_RESULT();
3567+ }
3568+
35183569static int test_wolfSSL_CTX_use_certificate_chain_buffer_format(void)
35193570{
35203571 EXPECT_DECLS;
@@ -32759,6 +32810,7 @@ TEST_CASE testCases[] = {
3275932810 TEST_DECL(test_wolfSSL_CTX_load_verify_buffer_ex),
3276032811 TEST_DECL(test_wolfSSL_CTX_load_verify_chain_buffer_format),
3276132812 TEST_DECL(test_wolfSSL_CTX_add1_chain_cert),
32813+ TEST_DECL(test_wolfSSL_add_to_chain_overflow),
3276232814 TEST_DECL(test_wolfSSL_CTX_use_certificate_chain_buffer_format),
3276332815 TEST_DECL(test_wolfSSL_CTX_use_certificate_chain_file_format),
3276432816 TEST_DECL(test_wolfSSL_use_certificate_chain_file),
0 commit comments