From 452622bf65b41e517709c06cde3355ac71226192 Mon Sep 17 00:00:00 2001 From: Roy Carter Date: Fri, 22 May 2026 19:31:44 +0300 Subject: [PATCH 1/3] bugfix - in TLS 1.3 handshake we're dependent on the cert chain cnt in SendTls13Certificate not updating the chain count made TLS 1.3 handshake fail and leave with leaft-only certficiate and then peer rejected the chain --- src/ssl_load.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ssl_load.c b/src/ssl_load.c index f71ccf3467..68b7f436f5 100644 --- a/src/ssl_load.c +++ b/src/ssl_load.c @@ -5218,6 +5218,7 @@ int wolfSSL_add0_chain_cert(WOLFSSL* ssl, WOLFSSL_X509* x509) ssl->buffers.weOwnCertChain, x509->derCert->buffer, x509->derCert->length, ssl->heap); if (ret == 1) { + ssl->buffers.certChainCnt++; /* We now own cert chain. */ ssl->buffers.weOwnCertChain = 1; /* Create a stack to put certificate into. */ From f7dc5b2bbd828c8a8bdd7ddf8c98336ef82821fc Mon Sep 17 00:00:00 2001 From: Roy Carter Date: Fri, 22 May 2026 19:37:13 +0300 Subject: [PATCH 2/3] Implement a simple test case to check the chain counter increases. --- tests/api.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/tests/api.c b/tests/api.c index 1c3ced8e86..4d2806283b 100644 --- a/tests/api.c +++ b/tests/api.c @@ -3693,6 +3693,53 @@ static int test_wolfSSL_CTX_add1_chain_cert(void) return EXPECT_RESULT(); } +static int test_wolfSSL_add0_chain_cert_increments_count(void) +{ + EXPECT_DECLS; +#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && defined(OPENSSL_EXTRA) && \ + defined(KEEP_OUR_CERT) && !defined(NO_RSA) && !defined(NO_TLS) && \ + !defined(NO_WOLFSSL_CLIENT) + WOLFSSL_CTX* ctx = NULL; + WOLFSSL* ssl = NULL; + const char* chainCerts[] = { + "./certs/intermediate/ca-int2-cert.pem", + "./certs/intermediate/ca-int-cert.pem", + "./certs/ca-cert.pem", + NULL + }; + const char** cert; + WOLFSSL_X509* x509 = NULL; + int expectedCnt = 0; + + ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())); + ExpectNotNull(ssl = wolfSSL_new(ctx)); + + ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file( + "./certs/intermediate/client-int-cert.pem", WOLFSSL_FILETYPE_PEM)); + ExpectIntEQ(SSL_add0_chain_cert(ssl, x509), 1); + /* Leaf -> ssl->buffers.certificate, not chain. certChainCnt unchanged. */ + if (ssl != NULL) { + ExpectIntEQ(ssl->buffers.certChainCnt, 0); + } + x509 = NULL; + + for (cert = chainCerts; EXPECT_SUCCESS() && *cert != NULL; cert++) { + ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(*cert, + WOLFSSL_FILETYPE_PEM)); + ExpectIntEQ(SSL_add0_chain_cert(ssl, x509), 1); + x509 = NULL; + expectedCnt++; + if (ssl != NULL) { + ExpectIntEQ(ssl->buffers.certChainCnt, expectedCnt); + } + } + + SSL_free(ssl); + SSL_CTX_free(ctx); +#endif + return EXPECT_RESULT(); +} + /* Test that wolfssl_add_to_chain rejects sizes that would overflow word32. * ZD #21241 */ static int test_wolfSSL_add_to_chain_overflow(void) @@ -40634,6 +40681,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_CTX_load_verify_buffer_ex), TEST_DECL(test_wolfSSL_CTX_load_verify_chain_buffer_format), TEST_DECL(test_wolfSSL_CTX_add1_chain_cert), + TEST_DECL(test_wolfSSL_add0_chain_cert_increments_count), TEST_DECL(test_wolfSSL_add_to_chain_overflow), TEST_DECL(test_wolfSSL_CTX_use_certificate_chain_buffer_format), TEST_DECL(test_wolfSSL_CTX_use_certificate_chain_file_format), From 416d317ee959f3b42f0931ba251c82036c66dd1b Mon Sep 17 00:00:00 2001 From: Roy Carter Date: Sun, 24 May 2026 13:56:23 +0300 Subject: [PATCH 3/3] Cosmetic - delete trailing whitespace in PR --- tests/api.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/api.c b/tests/api.c index 4d2806283b..7df5e17932 100644 --- a/tests/api.c +++ b/tests/api.c @@ -3721,13 +3721,12 @@ static int test_wolfSSL_add0_chain_cert_increments_count(void) if (ssl != NULL) { ExpectIntEQ(ssl->buffers.certChainCnt, 0); } - x509 = NULL; - + x509 = NULL; for (cert = chainCerts; EXPECT_SUCCESS() && *cert != NULL; cert++) { ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(*cert, WOLFSSL_FILETYPE_PEM)); ExpectIntEQ(SSL_add0_chain_cert(ssl, x509), 1); - x509 = NULL; + x509 = NULL; expectedCnt++; if (ssl != NULL) { ExpectIntEQ(ssl->buffers.certChainCnt, expectedCnt);