Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
d5ffe74
MC/DC: cover the 2026 RNG rework and aes.c argument-clause residuals
danielinux Sep 29, 2026
8da7720
tests: exclude the aes rework MC/DC test from selftest builds
danielinux Sep 29, 2026
7ee4778
MC/DC: decision-coverage drivers for SetSSL_CTX() and CheckVersion()
danielinux Sep 30, 2026
7310836
MC/DC: decision-coverage drivers for the src/ssl.c public-API guards
danielinux Sep 30, 2026
89d250b
MC/DC: decision-coverage drivers for the ssl_api_crl_ocsp.c argument …
danielinux Sep 30, 2026
513390f
MC/DC: decision-coverage drivers for the ssl_api_cert.c argument guards
danielinux Sep 30, 2026
c90fe17
MC/DC: decision-coverage drivers for the x509.c argument guards
danielinux Sep 30, 2026
dd1decd
MC/DC: decision-coverage drivers for the ssl_ech.c argument guards
danielinux Sep 30, 2026
260ddab
MC/DC: decision-coverage drivers for the ssl_certman.c argument guards
danielinux Oct 1, 2026
b35bdf2
MC/DC: decision-coverage drivers for the ssl_sess.c argument guards
danielinux Oct 1, 2026
3f04acc
MC/DC: decision-coverage drivers for the ssl_load.c DH argument guards
danielinux Oct 1, 2026
ab711ff
MC/DC: close the aes GCM/CCM _ex PENDING arms; make the asn_keys
danielinux Oct 1, 2026
e69588f
MC/DC: close the random.c static-entry, flag-guard and
danielinux Oct 1, 2026
fa4e690
MC/DC: drive the RSA state-machine PENDING rows via the crypto-cb device
danielinux Oct 1, 2026
aafbe4f
tests: cover the slhdsa MC/DC GAPS with white-box row drivers
danielinux Oct 1, 2026
52e8bbc
tests: cover the mldsa MC/DC GAPS with white-box row drivers
danielinux Oct 2, 2026
2ef230b
tests: cover the dtls MC/DC GAPS with white-box row drivers
danielinux Oct 2, 2026
6ca1227
tests: cover the random.c MC/DC GAPS with white-box row drivers
danielinux Oct 2, 2026
4473cac
tests: gate internal-fn MC/DC tests on WOLFSSL_TEST_STATIC_BUILD
danielinux Oct 2, 2026
a2496ae
tests: gate the MC/DC decision drivers on the library's feature gates
danielinux Oct 2, 2026
8c2402d
tests: close the wave-3 CI gaps and extend the api-guard whitelist
danielinux Oct 2, 2026
885703c
tests: gate the x509 driver on NO_RSA and surface whitebox build fail…
danielinux Oct 2, 2026
35c3f3a
tests: close the part-9 MC/DC gate regressions with decision drivers
danielinux Oct 7, 2026
6ce4725
tests: gate the crypto-cb dispatch rows on the campaign build
danielinux Oct 7, 2026
180368f
tests: fix the -Wshadow hit in the falcon decision driver
danielinux Oct 7, 2026
fe105ae
tests: gate campaign test decls and helpers per feature config
danielinux Oct 7, 2026
167b578
tests: fix C90 decl placement and dangling ctx reuse in campaign drivers
danielinux Oct 7, 2026
fe5628d
tests: fix campaign CI failures
danielinux Oct 8, 2026
6f9a6ef
tests: fix remaining CI rows
danielinux Oct 8, 2026
fc72ed8
tests: gate AES decision rows in old FIPS
danielinux Oct 8, 2026
c6a3d32
tests: register TLS white-box source
danielinux Oct 8, 2026
7518e52
tests: fix FIPS and PKCS7 checks
danielinux Oct 8, 2026
0ca325e
tests: initialize AES GCM input
danielinux Oct 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -3868,13 +3868,20 @@ int wolfssl_local_IsValidFQDN(const char* name, word32 nameSz)
if (name == NULL || nameSz == 0)
return 0;

/* Bound before touching name[]: a valid name is at most 253 octets
* plus an optional trailing dot, so longer sizes are rejected here
* without reading past the caller's buffer.
*/
if (nameSz > 254)
return 0;

/* Strip a single optional trailing dot before measuring. "example.com."
* is the absolute form of the same FQDN.
*/
if (name[nameSz - 1] == '.')
--nameSz;

if (nameSz < 1 || nameSz > 253)
if (nameSz > 253)
return 0;

for (i = 0; i < nameSz; i++) {
Expand Down
7 changes: 7 additions & 0 deletions tests/api/check-api-guards.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@
'wolfSSL_CertManagerVerify': (['NO_FILESYSTEM'], []),
'wolfSSL_CertManagerLoadCRL': (['NO_FILESYSTEM'], []),
'wolfSSL_CertManagerLoadCRLFile': (['NO_FILESYSTEM'], []),
# src/ssl.c: implemented under HAVE_SECURE_RENEGOTIATION ||
# HAVE_SERVER_RENEGOTIATION_INFO; the substring match passes a call
# site guarded by the full disjunction.
'wolfSSL_SSL_renegotiate_pending': ([], ['HAVE_SECURE_RENEGOTIATION']),
# src/ssl_load.c: implemented under !NO_FILESYSTEM && !NO_CERTS
'wolfSSL_CTX_use_PrivateKey_file': (['NO_FILESYSTEM', 'NO_CERTS'], []),
'wolfSSL_CTX_use_certificate_file': (['NO_FILESYSTEM', 'NO_CERTS'], []),
}


Expand Down
200 changes: 200 additions & 0 deletions tests/api/test_aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -13965,3 +13965,203 @@ int test_wc_AesEcb_RetCodeChecked(void)

#endif /* WOLF_CRYPTO_CB && !NO_AES && HAVE_AES_ECB && WOLFSSL_AES_128 &&
* !WOLF_CRYPTO_CB_ONLY_AES && (WOLFSSL_AES_COUNTER || HAVE_AESGCM) */

/* MC/DC pairs the 2026 upstream aes.c changes left open: the GcmInit/
* GcmSetIV argument-clause tails, the zero-length key id, the CTR
* leftover-keystream loop with an empty request, and the XTS unset-key
* guard on both sides.
*
* Excluded under HAVE_SELFTEST: the CAVP self-test leg compiles the frozen
* wolfCrypt 4.1.0 aes.c, whose GCM-stream/XTS/CTR paths predate these
* guards, so the open aes.c this measures is not the one built (same
* exclusion as the AesFeatureCoverage GCM/CCM blocks). FIPS modules also
* use different AES paths and do not provide every public size constant. */
int test_wc_AesReworkDecisionCoverage(void)
{
EXPECT_DECLS;
#if !defined(NO_AES) && !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
Aes aes;
byte key16[16];
byte iv[WC_AES_BLOCK_SIZE];
byte ivFixed[AES_IV_FIXED_SZ];
#if defined(HAVE_AESGCM)
byte tag[WC_AES_BLOCK_SIZE];
#endif
#if defined(WOLF_PRIVATE_KEY_ID)
byte id[8];
#endif
#if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_COUNTER) || \
defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_XTS)
byte in[32];
byte out[32];
#endif
#if !defined(WC_NO_RNG)
WC_RNG rng;
#endif
#if defined(WOLFSSL_AES_XTS)
XtsAes xaes;
#endif

XMEMSET(key16, 1, sizeof(key16));
XMEMSET(iv, 2, sizeof(iv));
XMEMSET(ivFixed, 3, sizeof(ivFixed));
#if defined(HAVE_AESGCM)
XMEMSET(tag, 4, sizeof(tag));
#endif
#if defined(WOLF_PRIVATE_KEY_ID)
XMEMSET(id, 4, sizeof(id));
#endif
#if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_COUNTER) || \
defined(WOLFSSL_AES_CFB) || \
defined(WOLFSSL_AES_XTS)
XMEMSET(in, 5, sizeof(in));
#endif
#if !defined(WC_NO_RNG)
XMEMSET(&rng, 0, sizeof(rng));
#endif

/* wc_AesGcmEncryptInit() -> wc_AesGcmInit(): (ivSz > 0) false with iv
* NULL, the clause tail (stream API only). */
#if defined(HAVE_AESGCM) && defined(WOLFSSL_AESGCM_STREAM)
ExpectIntEQ(wc_AesInit(&aes, NULL, INVALID_DEVID), 0);
ExpectIntEQ(wc_AesGcmEncryptInit(&aes, key16, sizeof(key16), NULL, 0),
0);
/* (ivSz > 0) true with iv NULL: the clause fires. */
ExpectIntEQ(wc_AesGcmEncryptInit(&aes, key16, sizeof(key16), NULL, 12),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
wc_AesFree(&aes);
#endif
/* wc_AesGcmSetIV(): ivFixedSz == AES_IV_FIXED_SZ (clause tail); the
* remaining IV bytes come from the RNG. */
#if defined(HAVE_AESGCM) && !defined(WC_NO_RNG)
ExpectIntEQ(wc_AesInit(&aes, NULL, INVALID_DEVID), 0);
ExpectIntEQ(wc_AesGcmSetKey(&aes, key16, sizeof(key16)), 0);
ExpectIntEQ(wc_InitRng_ex(&rng, HEAP_HINT, INVALID_DEVID), 0);
ExpectIntEQ(wc_AesGcmSetIV(&aes, GCM_NONCE_MIN_SZ, ivFixed,
sizeof(ivFixed), &rng), 0);
/* (ivFixedSz != AES_IV_FIXED_SZ) true: the clause fires. */
ExpectIntEQ(wc_AesGcmSetIV(&aes, 12, ivFixed, 12, &rng),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* rng == NULL side of the guard, isolated with a valid fixed part. */
ExpectIntEQ(wc_AesGcmSetIV(&aes, GCM_NONCE_MIN_SZ, ivFixed,
sizeof(ivFixed), NULL),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* ivFixed == NULL: the whole IV comes from the RNG. */
ExpectIntEQ(wc_AesGcmSetIV(&aes, 12, NULL, 0, &rng), 0);
/* Invalid IV size: not 8, 12, or 16. */
ExpectIntEQ(wc_AesGcmSetIV(&aes, 13, ivFixed, 12, &rng),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
wc_AesFree(&aes);
DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif

/* wc_AesInit_Id(): non-NULL id with zero length is a valid tag. */
#if defined(WOLF_PRIVATE_KEY_ID)
ExpectIntEQ(wc_AesInit_Id(&aes, id, 0, NULL, INVALID_DEVID), 0);
wc_AesFree(&aes);
#endif

/* CTR leftover-keystream loop: a partial block leaves aes->left, an
* empty request evaluates the loop with sz == 0, draining left to zero
* with data pending evaluates the loop with left == 0. */
#if defined(WOLFSSL_AES_COUNTER)
ExpectIntEQ(wc_AesInit(&aes, NULL, INVALID_DEVID), 0);
ExpectIntEQ(wc_AesSetKey(&aes, key16, sizeof(key16), iv, AES_ENCRYPTION),
0);
ExpectIntEQ(wc_AesSetIV(&aes, iv), 0);
ExpectIntEQ(wc_AesCtrEncrypt(&aes, out, in, 5), 0);
ExpectIntEQ(wc_AesCtrEncrypt(&aes, out, in, 0), 0);
ExpectIntEQ(wc_AesCtrEncrypt(&aes, out, in, 3), 0);
ExpectIntEQ(wc_AesCtrEncrypt(&aes, out, in, 8), 0);
ExpectIntEQ(wc_AesCtrEncrypt(&aes, out, in, 3), 0);
wc_AesFree(&aes);
#endif

/* CFB decrypt chunk loop: exactly two blocks drains sz below the loop
* threshold inside the loop, evaluating the false side. */
#if defined(WOLFSSL_AES_CFB)
ExpectIntEQ(wc_AesInit(&aes, NULL, INVALID_DEVID), 0);
/* CFB always uses the forward cipher for both directions. */
ExpectIntEQ(wc_AesSetKey(&aes, key16, sizeof(key16), iv, AES_ENCRYPTION),
0);
ExpectIntEQ(wc_AesSetIV(&aes, iv), 0);
ExpectIntEQ(wc_AesCfbDecrypt(&aes, out, in, 2 * WC_AES_BLOCK_SIZE), 0);
wc_AesFree(&aes);
#endif

#if defined(WOLFSSL_AES_XTS)
XMEMSET(&xaes, 0, sizeof(xaes));
/* keylen == 0 side of the unset-key guard, both directions. */
ExpectIntEQ(wc_AesXtsEncrypt(&xaes, out, in, sizeof(in), iv, sizeof(iv)),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_AesXtsDecrypt(&xaes, out, in, sizeof(in), iv, sizeof(iv)),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* rounds == 0 side: a key length with no software schedule. */
xaes.aes.keylen = (int)sizeof(key16);
ExpectIntEQ(wc_AesXtsEncrypt(&xaes, out, in, sizeof(in), iv, sizeof(iv)),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_AesXtsDecrypt(&xaes, out, in, sizeof(in), iv, sizeof(iv)),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* keylen == 0 with rounds set: the OR's first operand alone. */
xaes.aes.keylen = 0;
xaes.aes.rounds = 10;
ExpectIntEQ(wc_AesXtsEncrypt(&xaes, out, in, sizeof(in), iv, sizeof(iv)),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_AesXtsDecrypt(&xaes, out, in, sizeof(in), iv, sizeof(iv)),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif

/* wc_AesGcmInit(): direct argument checks - (ivSz > 0) with iv NULL is
* the last clause, (ivSz == 0) with iv NULL is the clean path. */
#if defined(HAVE_AESGCM) && defined(WOLFSSL_AESGCM_STREAM)
ExpectIntEQ(wc_AesInit(&aes, NULL, INVALID_DEVID), 0);
ExpectIntEQ(wc_AesGcmInit(&aes, key16, sizeof(key16), NULL, 0), 0);
ExpectIntEQ(wc_AesGcmInit(&aes, key16, sizeof(key16), NULL, 12),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
wc_AesFree(&aes);
#endif

/* wc_AesGcmSetIV(): (ivFixed == NULL) with ivFixedSz == 0 - the pair
* for the (ivFixed != NULL) clause against the size-mismatch failure
* above. */
#if defined(HAVE_AESGCM) && !defined(WC_NO_RNG)
ExpectIntEQ(wc_AesInit(&aes, NULL, INVALID_DEVID), 0);
ExpectIntEQ(wc_AesGcmSetKey(&aes, key16, sizeof(key16)), 0);
ExpectIntEQ(wc_InitRng_ex(&rng, HEAP_HINT, INVALID_DEVID), 0);
ExpectIntEQ(wc_AesGcmSetIV(&aes, 12, NULL, 0, &rng), 0);
wc_AesFree(&aes);
DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif

/* GCM tag-failure output wipe: a corrupted tag with out non-NULL and
* sz > 0 wipes the unauthenticated plaintext (AES_GCM_AUTH_E). */
#if defined(HAVE_AESGCM)
ExpectIntEQ(wc_AesInit(&aes, NULL, INVALID_DEVID), 0);
ExpectIntEQ(wc_AesGcmSetKey(&aes, key16, sizeof(key16)), 0);
ExpectIntEQ(wc_AesGcmEncrypt(&aes, out, in, sizeof(in), iv,
sizeof(iv), tag, sizeof(tag), NULL, 0), 0);
tag[0] ^= 0x01;
ExpectIntEQ(wc_AesGcmDecrypt(&aes, out, out, sizeof(in), iv,
sizeof(iv), tag, sizeof(tag), NULL, 0),
WC_NO_ERR_TRACE(AES_GCM_AUTH_E));
wc_AesFree(&aes);
#endif

/* CFB leftover-drain loop: a partial decrypt leaves aes->left, an empty
* request evaluates the loop with sz == 0, and a call longer than the
* leftover exits with left == 0 while sz is still positive. */
#if defined(WOLFSSL_AES_CFB)
ExpectIntEQ(wc_AesInit(&aes, NULL, INVALID_DEVID), 0);
/* CFB always uses the forward cipher for both directions. */
ExpectIntEQ(wc_AesSetKey(&aes, key16, sizeof(key16), iv, AES_ENCRYPTION),
0);
ExpectIntEQ(wc_AesSetIV(&aes, iv), 0);
ExpectIntEQ(wc_AesCfbDecrypt(&aes, out, in, 5), 0);
ExpectIntEQ(wc_AesCfbDecrypt(&aes, out, in, 0), 0);
ExpectIntEQ(wc_AesCfbDecrypt(&aes, out, in, 3), 0);
ExpectIntEQ(wc_AesCfbDecrypt(&aes, out, in, 10), 0);
wc_AesFree(&aes);
#endif
#endif /* !NO_AES && !HAVE_SELFTEST && !HAVE_FIPS */
return EXPECT_RESULT();
}
2 changes: 2 additions & 0 deletions tests/api/test_aes.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ int test_wc_AesGcm_MonteCarlo(void);
int test_wc_AesCcm_MonteCarlo(void);
int test_wc_AesCfb_MonteCarlo(void);
int test_wc_AesOfb_MonteCarlo(void);
int test_wc_AesReworkDecisionCoverage(void);

int test_wc_GmacSetKey(void);
int test_wc_GmacUpdate(void);
Expand Down Expand Up @@ -192,6 +193,7 @@ int test_wc_CryptoCb_AesKeyWrapEcbCompose(void);

#define TEST_AES_DECLS \
TEST_DECL_GROUP("aes", test_wc_AesSetKey), \
TEST_DECL_GROUP("aes", test_wc_AesReworkDecisionCoverage), \
TEST_DECL_GROUP("aes", test_wc_AesSetIV), \
TEST_DECL_GROUP("aes", test_wc_AesSetIV_RestartsStream), \
TEST_DECL_GROUP("aes", test_wc_AesEncryptDecryptDirect), \
Expand Down
53 changes: 53 additions & 0 deletions tests/api/test_asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -5311,3 +5311,56 @@ int test_SetCertificatePolicies_no_empty_qualifiers(void)
#endif
return EXPECT_RESULT();
}

/*
* MC/DC decision coverage for the PKCS#8 key-creation/encryption guards in
* wolfcrypt/src/asn.c: the LENGTH_ONLY_E size-query row of
* wc_CreatePKCS8Key, the GetAlgoV2-failure row of wc_EncryptPKCS8Key_ex,
* the undersized-buffer row, and the NULL-hmacOid PBES2 row. A raw key
* buffer is used (no cert-buffer dependency) so the rows run in every
* variant.
*/
int test_wc_Pkcs8EncryptDecisionCoverage(void)
{
EXPECT_DECLS;
#if defined(HAVE_PKCS8) && !defined(NO_PWDBASED) && \
defined(HAVE_AES_CBC) && !defined(NO_AES) && defined(WOLFSSL_AES_128) && \
defined(HAVE_ECC) && !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
WC_RNG rng;
byte key[32];
byte out[512];
byte salt[8];
word32 outSz;

XMEMSET(key, 3, sizeof(key));
XMEMSET(salt, 4, sizeof(salt));
XMEMSET(&rng, 0, sizeof(rng));
ExpectIntEQ(wc_InitRng_ex(&rng, HEAP_HINT, INVALID_DEVID), 0);

/* wc_CreatePKCS8Key size query: out==NULL returns LENGTH_ONLY_E, the
* (ret == LENGTH_ONLY_E) clause's true side. */
outSz = sizeof(out);
ExpectIntEQ(wc_CreatePKCS8Key(NULL, &outSz, key, sizeof(key), RSAk,
NULL, 0), WC_NO_ERR_TRACE(LENGTH_ONLY_E));

/* wc_EncryptPKCS8Key_ex: a bogus PBES2 encAlgId fails GetAlgoV2, so
* the (ret == 0) operand of the encOid check takes its false side. */
outSz = sizeof(out);
ExpectIntNE(wc_EncryptPKCS8Key_ex(key, sizeof(key), out, &outSz,
"pw", 2, 2, PBES2, 0x7FFFFFFF, salt, sizeof(salt), 1000, 0, &rng,
HEAP_HINT), 0);

/* Same call with a valid encAlgId and an undersized output buffer:
* the encoding fails, so the PBES2 hmacOid check's (ret == 0)
* operand takes its false side. (The (hmacOidBuf != NULL) operand's
* false side is structurally dead: a successful PBES2 call always
* carries an hmac OID, since PBKDF2 requires a hash. */
outSz = 16;
ExpectIntNE(wc_EncryptPKCS8Key_ex(key, sizeof(key), out, &outSz,
"pw", 2, 2, PBES2, AES128CBCb, salt, sizeof(salt), 1000,
WC_HASH_TYPE_SHA256, &rng, HEAP_HINT), 0);

ExpectIntEQ(wc_FreeRng(&rng), 0);
#endif /* HAVE_AES_CBC && !NO_AES && WOLFSSL_AES_128 && !FIPS */
return EXPECT_RESULT();
}
2 changes: 2 additions & 0 deletions tests/api/test_asn.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ int test_wc_DecodeExtKeyUsage_ssh_oid_collision(void);
int test_wc_DecodeExtKeyUsage_oidSumCollision(void);
int test_wc_AsnDecisionCoverage(void);
int test_wc_AsnFeatureCoverage(void);
int test_wc_Pkcs8EncryptDecisionCoverage(void);
int test_wc_AltNameNewEx(void);

#define TEST_ASN_DECLS \
Expand Down Expand Up @@ -101,6 +102,7 @@ int test_wc_AltNameNewEx(void);
TEST_DECL_GROUP("asn", test_wc_DecodeExtKeyUsage_oidSumCollision), \
TEST_DECL_GROUP("asn", test_wc_AsnDecisionCoverage), \
TEST_DECL_GROUP("asn", test_wc_AsnFeatureCoverage), \
TEST_DECL_GROUP("asn", test_wc_Pkcs8EncryptDecisionCoverage), \
TEST_DECL_GROUP("asn", test_wc_AltNameNewEx)

#endif /* WOLFCRYPT_TEST_ASN_H */
59 changes: 59 additions & 0 deletions tests/api/test_certman.c
Original file line number Diff line number Diff line change
Expand Up @@ -4573,3 +4573,62 @@ int test_wolfSSL_CertManagerNameConstraint_skid_disambiguates(void)
#endif
return EXPECT_RESULT();
}
int test_certman_decision_coverage(void)
{
EXPECT_DECLS;
/* Refs WOLFSSL_LOCAL certman fns, hidden from the .so - shared builds
* compile this out; WOLFSSL_TEST_STATIC_BUILD is set for static-only
* builds (configure) and by the MC/DC variant. */
#if defined(WOLFSSL_TEST_STATIC_BUILD) && !defined(WOLFCRYPT_ONLY) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_TLS) && !defined(NO_CERTS)
WOLFSSL_CTX* ctx = NULL;
WOLFSSL_CERT_MANAGER* cm = NULL;
byte hash[SIGNER_DIGEST_SIZE];
Signer signer;
Signer* hs = NULL;

XMEMSET(hash, 0, sizeof(hash));
XMEMSET(&signer, 0, sizeof(signer));
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
cm = ctx->cm;
ExpectNotNull(cm);

/* --- 2700:0/1 AlreadySigner: cm==NULL || hash==NULL ------------------ */
(void)AlreadySigner(NULL, hash);
(void)AlreadySigner(cm, NULL);
(void)AlreadySigner(cm, hash);

/* --- 2812:0/1 GetCA: cm==NULL || hash==NULL -------------------------- */
(void)GetCA(NULL, hash);
(void)GetCA(cm, NULL);
(void)GetCA(cm, hash);

/* --- 3037:0/1 AddSigner: cm==NULL || s==NULL ------------------------- */
(void)AddSigner(NULL, &signer);
(void)AddSigner(cm, NULL);
/* The all-valid case inserts the Signer into the cm's CA table, which the
* cm then owns and frees on ctx-free; use a heap Signer and remove it
* before freeing so ownership stays clean. */
hs = (Signer*)XMALLOC(sizeof(Signer), cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (hs != NULL) {
XMEMSET(hs, 0, sizeof(Signer));
(void)AddSigner(cm, hs);
/* RemoveCA frees the signer it removes; no XFREE after it. */
(void)RemoveCA(cm, hs->subjectKeyIdHash, WOLFSSL_USER_CA);
}

/* --- 3352/3372:0/1 RemoveCA: cm==NULL || hash==NULL ------------------ */
(void)RemoveCA(NULL, hash, WOLFSSL_USER_CA);
(void)RemoveCA(cm, NULL, WOLFSSL_USER_CA);
(void)RemoveCA(cm, hash, WOLFSSL_USER_CA);

/* --- 3399:0/1/2 SetCAType: cm==NULL || hash==NULL || type range ------ */
(void)SetCAType(NULL, hash, WOLFSSL_USER_CA);
(void)SetCAType(cm, NULL, WOLFSSL_USER_CA);
(void)SetCAType(cm, hash, WOLFSSL_USER_CA);
(void)SetCAType(cm, hash, 0);

wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
Loading
Loading