From bd8730543cfe6c9870960f6e23b8cb7fc4ff048c Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Mon, 6 Jul 2026 17:12:36 +0200 Subject: [PATCH] tests: fix X509V3_EXT leak, C++ build, and no-client link Three more failures in the branch's added tests, found via the ASAN, C++ and no-client CI configs: - test_wolfSSL_X509V3_EXT leaked 2296 bytes: the added X509_get_ext_d2i(x509, NID, &critical, NULL) calls (used to exercise the critical-flag output) discarded their allocated result. Free each per its actual return type: BASIC_CONSTRAINTS, ASN1_STRING (key usage), AUTHORITY_KEYID, AUTHORITY_INFO_ACCESS, and - for subject_key_identifier - a STACK_OF(ASN1_OBJECT) (wolfSSL_X509_get_ext_d2i wraps a lone obj in a stack). This was the real cause of the sanitize-asan / intelasm / krb-asan job failures (the read_write_ex/ECH/dtls13 asserts printed there are retry-masked and fail identically on master). - C++ build (all-pq-cxx): void* from X509_get_ext_d2i does not implicitly convert; add explicit WOLFSSL_X509_EXTENSION* casts. - no-client link (all-no-client): wolfSSL[_CTX]_UseOCSPStapling[V2] (CSR/CSR2) are client-side APIs; guard those blocks with !NO_WOLFSSL_CLIENT. Verified: full --enable-all + ASAN run is leak-free and passes; --enable-all -DNO_WOLFSSL_CLIENT builds and links. --- tests/api.c | 6 ++++-- tests/api/test_ossl_x509_ext.c | 20 +++++++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/tests/api.c b/tests/api.c index 90ca4f951c..d7e82e6f4b 100644 --- a/tests/api.c +++ b/tests/api.c @@ -4789,7 +4789,8 @@ static int test_wolfSSL_crl_ocsp_object_api(void) #endif #endif -#ifdef HAVE_CERTIFICATE_STATUS_REQUEST +/* wolfSSL[_CTX]_UseOCSPStapling (CSR) is a client-side API. */ +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) && !defined(NO_WOLFSSL_CLIENT) ExpectIntEQ(wolfSSL_UseOCSPStapling(NULL, WOLFSSL_CSR_OCSP, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); #ifndef NO_WOLFSSL_SERVER @@ -4808,7 +4809,8 @@ static int test_wolfSSL_crl_ocsp_object_api(void) #endif #endif -#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 +/* wolfSSL[_CTX]_UseOCSPStaplingV2 (CSR2) is a client-side API. */ +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) && !defined(NO_WOLFSSL_CLIENT) ExpectIntEQ(wolfSSL_UseOCSPStaplingV2(NULL, WOLFSSL_CSR2_OCSP, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); #ifndef NO_WOLFSSL_SERVER diff --git a/tests/api/test_ossl_x509_ext.c b/tests/api/test_ossl_x509_ext.c index 1a8f24ae9d..06fdab92cd 100644 --- a/tests/api/test_ossl_x509_ext.c +++ b/tests/api/test_ossl_x509_ext.c @@ -1480,9 +1480,11 @@ int test_wolfSSL_X509V3_EXT(void) ExpectIntEQ((nid = wolfSSL_OBJ_obj2nid(obj)), NID_basic_constraints); ExpectNotNull(bc = (WOLFSSL_BASIC_CONSTRAINTS*)wolfSSL_X509V3_EXT_d2i(ext)); critical = -1; - ExpectNotNull(ext2 = X509_get_ext_d2i(x509, NID_basic_constraints, + ExpectNotNull(ext2 = (WOLFSSL_X509_EXTENSION*)X509_get_ext_d2i(x509, NID_basic_constraints, &critical, NULL)); ExpectIntNE(critical, -1); + /* X509_get_ext_d2i() returns a newly-allocated object; free before reuse. */ + wolfSSL_BASIC_CONSTRAINTS_free((WOLFSSL_BASIC_CONSTRAINTS*)ext2); ext2 = NULL; ExpectNotNull(ext2 = wolfSSL_X509V3_EXT_i2d(NID_basic_constraints, 1, bc)); X509_EXTENSION_free(ext2); @@ -1501,9 +1503,13 @@ int test_wolfSSL_X509V3_EXT(void) ExpectNotNull(asn1str = (WOLFSSL_ASN1_STRING*)wolfSSL_X509V3_EXT_d2i(ext)); critical = -1; - ExpectNotNull(ext2 = X509_get_ext_d2i(x509, NID_subject_key_identifier, + ExpectNotNull(ext2 = (WOLFSSL_X509_EXTENSION*)X509_get_ext_d2i(x509, NID_subject_key_identifier, &critical, NULL)); ExpectIntNE(critical, -1); + /* get_ext_d2i(subject_key_identifier) wraps the value in a + * STACK_OF(ASN1_OBJECT) (see wolfSSL_X509_get_ext_d2i). */ + wolfSSL_sk_ASN1_OBJECT_pop_free((WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)*)ext2, + NULL); ext2 = NULL; ExpectNotNull(ext2 = wolfSSL_X509V3_EXT_i2d(NID_subject_key_identifier, 0, asn1str)); @@ -1531,9 +1537,10 @@ int test_wolfSSL_X509V3_EXT(void) ExpectNotNull(aKeyId = (WOLFSSL_AUTHORITY_KEYID*)wolfSSL_X509V3_EXT_d2i( ext)); critical = -1; - ExpectNotNull(ext2 = X509_get_ext_d2i(x509, NID_authority_key_identifier, + ExpectNotNull(ext2 = (WOLFSSL_X509_EXTENSION*)X509_get_ext_d2i(x509, NID_authority_key_identifier, &critical, NULL)); ExpectIntNE(critical, -1); + wolfSSL_AUTHORITY_KEYID_free((WOLFSSL_AUTHORITY_KEYID*)ext2); ext2 = NULL; ExpectNotNull(ext2 = wolfSSL_X509V3_EXT_i2d(NID_authority_key_identifier, 0, aKeyId)); @@ -1562,9 +1569,10 @@ int test_wolfSSL_X509V3_EXT(void) ExpectNotNull(asn1str = (WOLFSSL_ASN1_STRING*)wolfSSL_X509V3_EXT_d2i(ext)); critical = -1; - ExpectNotNull(ext2 = X509_get_ext_d2i(x509, NID_key_usage, &critical, + ExpectNotNull(ext2 = (WOLFSSL_X509_EXTENSION*)X509_get_ext_d2i(x509, NID_key_usage, &critical, NULL)); ExpectIntNE(critical, -1); + wolfSSL_ASN1_STRING_free((WOLFSSL_ASN1_STRING*)ext2); ext2 = NULL; ExpectNotNull(ext2 = wolfSSL_X509V3_EXT_i2d(NID_key_usage, 0, asn1str)); X509_EXTENSION_free(ext2); @@ -1596,9 +1604,11 @@ int test_wolfSSL_X509V3_EXT(void) ExpectNotNull(aia = (WOLFSSL_AUTHORITY_INFO_ACCESS*)wolfSSL_X509V3_EXT_d2i( ext)); critical = -1; - ExpectNotNull(ext2 = X509_get_ext_d2i(x509, NID_info_access, &critical, + ExpectNotNull(ext2 = (WOLFSSL_X509_EXTENSION*)X509_get_ext_d2i(x509, NID_info_access, &critical, NULL)); ExpectIntNE(critical, -1); + wolfSSL_sk_ACCESS_DESCRIPTION_pop_free( + (WOLFSSL_AUTHORITY_INFO_ACCESS*)ext2, NULL); ext2 = NULL; #if defined(WOLFSSL_QT) ExpectIntEQ(OPENSSL_sk_num(aia), 1); /* Only one URI entry for this cert */