From e31abd813bdcbc466008087e19cb1d7bcdf6f062 Mon Sep 17 00:00:00 2001 From: Zackery Backman Date: Tue, 7 Apr 2026 12:30:06 -0600 Subject: [PATCH 1/9] Add test for wolfSSL_use_AltPrivateKey_Id to verify successful key ID allocation --- tests/api.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/api.c b/tests/api.c index eba7a6c301..0d573c9d70 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1683,6 +1683,38 @@ static int test_dual_alg_ecdsa_mldsa(void) return EXPECT_RESULT(); } +/* Test wolfSSL_use_AltPrivateKey_Id. + * Verify that a valid key ID can be set successfully. Guards against an + * inverted AllocDer return check (== 0 vs != 0) that would treat successful + * allocation as failure. */ +static int test_wolfSSL_use_AltPrivateKey_Id(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_DUAL_ALG_CERTS) && !defined(NO_TLS) && \ + !defined(NO_WOLFSSL_CLIENT) + WOLFSSL_CTX* ctx = NULL; + WOLFSSL* ssl = NULL; + const unsigned char id[] = { 0x01, 0x02, 0x03, 0x04 }; + + ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())); + ExpectNotNull(ssl = wolfSSL_new(ctx)); + + /* Negative tests. */ + ExpectIntEQ(wolfSSL_use_AltPrivateKey_Id(NULL, id, sizeof(id), + INVALID_DEVID), 0); + ExpectIntEQ(wolfSSL_use_AltPrivateKey_Id(ssl, NULL, sizeof(id), + INVALID_DEVID), 0); + + /* Positive test — valid ID should succeed. */ + ExpectIntEQ(wolfSSL_use_AltPrivateKey_Id(ssl, id, sizeof(id), + INVALID_DEVID), 1); + + wolfSSL_free(ssl); + wolfSSL_CTX_free(ctx); +#endif /* WOLFSSL_DUAL_ALG_CERTS && !NO_TLS && !NO_WOLFSSL_CLIENT */ + return EXPECT_RESULT(); +} + /*----------------------------------------------------------------------------* | Context @@ -35125,6 +35157,8 @@ TEST_CASE testCases[] = { TEST_DECL(test_dual_alg_ecdsa_mldsa), + TEST_DECL(test_wolfSSL_use_AltPrivateKey_Id), + /********************************* * OpenSSL compatibility API tests *********************************/ From 13af7066865876fba5a88def5d272f0bfe93bf55 Mon Sep 17 00:00:00 2001 From: Zackery Backman Date: Tue, 7 Apr 2026 12:35:04 -0600 Subject: [PATCH 2/9] Fix inverted AllocDer success check in wolfSSL_use_AltPrivateKey_Id --- src/ssl_load.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ssl_load.c b/src/ssl_load.c index 0a0fb9e467..caa9874d19 100644 --- a/src/ssl_load.c +++ b/src/ssl_load.c @@ -4684,7 +4684,7 @@ int wolfSSL_use_AltPrivateKey_Id(WOLFSSL* ssl, const unsigned char* id, long sz, #endif } if (AllocDer(&ssl->buffers.altKey, (word32)sz, ALT_PRIVATEKEY_TYPE, - ssl->heap) == 0) { + ssl->heap) != 0) { ret = 0; } } From ae3c00fa69353d8c0bef0cb062ea8d4f9903eafd Mon Sep 17 00:00:00 2001 From: Zackery Backman Date: Tue, 7 Apr 2026 12:37:18 -0600 Subject: [PATCH 3/9] Add test for wolfSSL_use_AltPrivateKey_Label to verify successful key label allocation --- tests/api.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/api.c b/tests/api.c index 0d573c9d70..eae18da7cd 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1715,6 +1715,36 @@ static int test_wolfSSL_use_AltPrivateKey_Id(void) return EXPECT_RESULT(); } +/* Test wolfSSL_use_AltPrivateKey_Label. + * Verify that a valid key label can be set successfully. Guards against an + * inverted AllocDer return check (== 0 vs != 0) that would treat successful + * allocation as failure. */ +static int test_wolfSSL_use_AltPrivateKey_Label(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_DUAL_ALG_CERTS) && !defined(NO_TLS) && \ + !defined(NO_WOLFSSL_CLIENT) + WOLFSSL_CTX* ctx = NULL; + WOLFSSL* ssl = NULL; + + ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())); + ExpectNotNull(ssl = wolfSSL_new(ctx)); + + /* Negative tests. */ + ExpectIntEQ(wolfSSL_use_AltPrivateKey_Label(NULL, "label", INVALID_DEVID), + 0); + ExpectIntEQ(wolfSSL_use_AltPrivateKey_Label(ssl, NULL, INVALID_DEVID), 0); + + /* Positive test — valid label should succeed. */ + ExpectIntEQ(wolfSSL_use_AltPrivateKey_Label(ssl, "test_label", + INVALID_DEVID), 1); + + wolfSSL_free(ssl); + wolfSSL_CTX_free(ctx); +#endif /* WOLFSSL_DUAL_ALG_CERTS && !NO_TLS && !NO_WOLFSSL_CLIENT */ + return EXPECT_RESULT(); +} + /*----------------------------------------------------------------------------* | Context @@ -35158,6 +35188,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_dual_alg_ecdsa_mldsa), TEST_DECL(test_wolfSSL_use_AltPrivateKey_Id), + TEST_DECL(test_wolfSSL_use_AltPrivateKey_Label), /********************************* * OpenSSL compatibility API tests From cf5da7b37084de5a092f6d6f1568b9bc0c7ec0eb Mon Sep 17 00:00:00 2001 From: Zackery Backman Date: Tue, 7 Apr 2026 12:38:18 -0600 Subject: [PATCH 4/9] Fix inverted AllocDer success check in wolfSSL_use_AltPrivateKey_Label --- src/ssl_load.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ssl_load.c b/src/ssl_load.c index caa9874d19..2ba4523435 100644 --- a/src/ssl_load.c +++ b/src/ssl_load.c @@ -4732,7 +4732,7 @@ int wolfSSL_use_AltPrivateKey_Label(WOLFSSL* ssl, const char* label, int devId) #endif } if (AllocDer(&ssl->buffers.altKey, (word32)sz, ALT_PRIVATEKEY_TYPE, - ssl->heap) == 0) { + ssl->heap) != 0) { ret = 0; } } From 939f978bb3027c02c577c2805d6d8fa5ca5b79d5 Mon Sep 17 00:00:00 2001 From: Zackery Backman Date: Tue, 7 Apr 2026 12:40:32 -0600 Subject: [PATCH 5/9] Fix == vs = in wolfSSL_add1_chain_cert so ret captures up_ref result instead of comparing against it, matching wolfSSL_CTX_add1_chain_cert --- src/ssl_load.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ssl_load.c b/src/ssl_load.c index 2ba4523435..33c490b7c7 100644 --- a/src/ssl_load.c +++ b/src/ssl_load.c @@ -5202,7 +5202,7 @@ int wolfSSL_add1_chain_cert(WOLFSSL* ssl, WOLFSSL_X509* x509) } /* Increase reference count on X509 object before adding. */ - if ((ret == 1) && ((ret == wolfSSL_X509_up_ref(x509)) == 1)) { + if ((ret == 1) && ((ret = wolfSSL_X509_up_ref(x509)) == 1)) { /* Add this to the chain. */ if ((ret = wolfSSL_add0_chain_cert(ssl, x509)) != 1) { /* Decrease reference count on error as not stored. */ From 5003c033eb83b6bf1566941f99ee535908403eb8 Mon Sep 17 00:00:00 2001 From: Zackery Backman Date: Tue, 7 Apr 2026 13:00:09 -0600 Subject: [PATCH 6/9] Fix DH encoding check in wolfSSL_CTX_set_tmp_dh: && to || and < to <= to catch single-param failure and zero-length, matching wolfSSL_set_tmp_dh. --- src/ssl_load.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ssl_load.c b/src/ssl_load.c index 33c490b7c7..74a5a5b6a2 100644 --- a/src/ssl_load.c +++ b/src/ssl_load.c @@ -5864,7 +5864,7 @@ long wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX* ctx, WOLFSSL_DH* dh) pSz = wolfSSL_BN_bn2bin(dh->p, p); gSz = wolfSSL_BN_bn2bin(dh->g, g); /* Check encoding worked. */ - if ((pSz < 0) && (gSz < 0)) { + if ((pSz <= 0) || (gSz <= 0)) { ret = WOLFSSL_FATAL_ERROR; } } From b06768671ceefe9769aa778ef12b79647c0d367e Mon Sep 17 00:00:00 2001 From: Zackery Backman Date: Tue, 7 Apr 2026 13:01:18 -0600 Subject: [PATCH 7/9] Copy-paste error in ProcessBufferCertPublicKey and ProcessBufferCertAltPublicKey, Fix #endif comments closing WOLFSSL_SM2/SM3 blocks, not HAVE_ED25519 --- src/ssl_load.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ssl_load.c b/src/ssl_load.c index 74a5a5b6a2..855f177922 100644 --- a/src/ssl_load.c +++ b/src/ssl_load.c @@ -1672,7 +1672,7 @@ static int ProcessBufferCertPublicKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl, ECC_KEY_SIZE_E); } break; - #endif /* HAVE_ED25519 */ + #endif /* WOLFSSL_SM2 && WOLFSSL_SM3 */ #ifdef HAVE_ED25519 case ED25519k: keyType = ed25519_sa_algo; @@ -1882,7 +1882,7 @@ static int ProcessBufferCertAltPublicKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl, ECC_KEY_SIZE_E); } break; - #endif /* HAVE_ED25519 */ + #endif /* WOLFSSL_SM2 && WOLFSSL_SM3 */ #ifdef HAVE_ED25519 case ED25519k: keyType = ed25519_sa_algo; From 7d38e9cb1fbef9f77369e44c42419336bb09cffe Mon Sep 17 00:00:00 2001 From: Zackery Backman Date: Wed, 8 Apr 2026 13:15:31 -0600 Subject: [PATCH 8/9] Fix cast-away-const in ws_ctx_ssl_set_tmp_dh: allocate DerBuffer with actual size and copy data instead of pointing at caller's const buffer, which caused FreeDer to free non-owned memory. --- src/ssl_load.c | 8 +++----- tests/api.c | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/ssl_load.c b/src/ssl_load.c index 855f177922..1dc7ccc250 100644 --- a/src/ssl_load.c +++ b/src/ssl_load.c @@ -5930,12 +5930,10 @@ static int ws_ctx_ssl_set_tmp_dh(WOLFSSL_CTX* ctx, WOLFSSL* ssl, /* PemToDer allocates its own DER buffer. */ if ((res == 1) && (format != WOLFSSL_FILETYPE_PEM)) { - /* Create an empty DER buffer. */ - ret = AllocDer(&der, 0, DH_PARAM_TYPE, heap); + /* Create a DER buffer and copy in the encoded DH parameters. */ + ret = AllocDer(&der, (word32)sz, DH_PARAM_TYPE, heap); if (ret == 0) { - /* Assign encoded DH parameters to DER buffer. */ - der->buffer = (byte*)buf; - der->length = (word32)sz; + XMEMCPY(der->buffer, buf, (word32)sz); } else { res = ret; diff --git a/tests/api.c b/tests/api.c index eae18da7cd..1416ca64fc 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1705,7 +1705,7 @@ static int test_wolfSSL_use_AltPrivateKey_Id(void) ExpectIntEQ(wolfSSL_use_AltPrivateKey_Id(ssl, NULL, sizeof(id), INVALID_DEVID), 0); - /* Positive test — valid ID should succeed. */ + /* Positive test - valid ID should succeed. */ ExpectIntEQ(wolfSSL_use_AltPrivateKey_Id(ssl, id, sizeof(id), INVALID_DEVID), 1); @@ -1735,7 +1735,7 @@ static int test_wolfSSL_use_AltPrivateKey_Label(void) 0); ExpectIntEQ(wolfSSL_use_AltPrivateKey_Label(ssl, NULL, INVALID_DEVID), 0); - /* Positive test — valid label should succeed. */ + /* Positive test - valid label should succeed. */ ExpectIntEQ(wolfSSL_use_AltPrivateKey_Label(ssl, "test_label", INVALID_DEVID), 1); From 307d3ce7667c3b6d64d689b3875893425a98b734 Mon Sep 17 00:00:00 2001 From: night1rider Date: Thu, 9 Apr 2026 15:00:58 -0600 Subject: [PATCH 9/9] Add DH regression test and incremement ref counter tests to api.c --- tests/api.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/tests/api.c b/tests/api.c index 1416ca64fc..26e4d98095 100644 --- a/tests/api.c +++ b/tests/api.c @@ -3554,6 +3554,11 @@ static int test_wolfSSL_CTX_add1_chain_cert(void) } ExpectIntEQ(SSL_CTX_add1_chain_cert(ctx, x509), 1); + /* add1 must increment ref count (was 1, now 2). Verifies the + * up_ref return value is assigned, not just compared. */ + if (EXPECT_SUCCESS() && x509 != NULL) { + ExpectIntEQ(wolfSSL_RefCur(x509->ref), 2); + } X509_free(x509); x509 = NULL; } @@ -3573,6 +3578,10 @@ static int test_wolfSSL_CTX_add1_chain_cert(void) } ExpectIntEQ(SSL_add1_chain_cert(ssl, x509), 1); + /* add1 must increment ref count (was 1, now 2) */ + if (EXPECT_SUCCESS() && x509 != NULL) { + ExpectIntEQ(wolfSSL_RefCur(x509->ref), 2); + } X509_free(x509); x509 = NULL; } @@ -13297,6 +13306,64 @@ static int test_wolfSSL_tmp_dh(void) return EXPECT_RESULT(); } +/* Tests SSL_CTX_set_tmp_dh with single-operand failure (p set, g missing) + * and wolfSSL_CTX_SetTmpDH_buffer with WOLFSSL_FILETYPE_ASN1 DER input. */ +static int test_wolfSSL_tmp_dh_regression(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_DH) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) && !defined(NO_TLS) && \ + !defined(NO_WOLFSSL_SERVER) + SSL_CTX* ctx = NULL; + + ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method())); + ExpectTrue(SSL_CTX_use_certificate_file(ctx, svrCertFile, + WOLFSSL_FILETYPE_PEM)); + ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, + WOLFSSL_FILETYPE_PEM)); + +#if defined(OPENSSL_ALL) || \ + (defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L) + { + /* Test single-operand failure: DH with p but no g. */ + DH* dh = NULL; + WOLFSSL_BIGNUM* p_bn = NULL; + + ExpectNotNull(dh = wolfSSL_DH_new()); + ExpectNotNull(p_bn = wolfSSL_BN_new()); + ExpectIntEQ(wolfSSL_BN_set_word(p_bn, 0xFFFF), 1); + if (dh != NULL && p_bn != NULL) { + if (wolfSSL_DH_set0_pqg(dh, p_bn, NULL, NULL) == 1) { + p_bn = NULL; /* ownership transferred on success */ + } + } + ExpectIntEQ((int)SSL_CTX_set_tmp_dh(ctx, dh), WOLFSSL_FATAL_ERROR); + DH_free(dh); + wolfSSL_BN_free(p_bn); + } +#endif + + /* Test ASN1/DER path through wolfSSL_CTX_SetTmpDH_buffer. */ + { + byte derBuf[4096]; + XFILE f = XBADFILE; + int derSz = 0; + + ExpectTrue((f = XFOPEN("./certs/dh2048.der", "rb")) != XBADFILE); + if (f != XBADFILE) { + derSz = (int)XFREAD(derBuf, 1, sizeof(derBuf), f); + XFCLOSE(f); + } + ExpectIntGT(derSz, 0); + ExpectIntEQ(wolfSSL_CTX_SetTmpDH_buffer(ctx, derBuf, (long)derSz, + WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS); + } + + SSL_CTX_free(ctx); +#endif + return EXPECT_RESULT(); +} + static int test_wolfSSL_ctrl(void) { EXPECT_DECLS; @@ -35461,6 +35528,7 @@ TEST_CASE testCases[] = { TEST_TLS13_DECLS, TEST_DECL(test_wolfSSL_tmp_dh), + TEST_DECL(test_wolfSSL_tmp_dh_regression), TEST_DECL(test_wolfSSL_ctrl), TEST_DECL(test_wolfSSL_get0_param),