diff --git a/src/ssl_load.c b/src/ssl_load.c index 0a0fb9e467..1dc7ccc250 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; @@ -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; } } @@ -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; } } @@ -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. */ @@ -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; } } @@ -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 eba7a6c301..26e4d98095 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1683,6 +1683,68 @@ 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(); +} + +/* 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 @@ -3492,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; } @@ -3511,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; } @@ -13235,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; @@ -35125,6 +35254,9 @@ 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 *********************************/ @@ -35396,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),