From 72c7d12cfb575f0382effd3bf7e77883312e9c70 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Thu, 23 Apr 2026 16:23:07 -0600 Subject: [PATCH] exclude the trust anchor from prospective certification path with pathlen check --- tests/api.c | 9 +++++++++ wolfcrypt/src/asn.c | 17 ++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/tests/api.c b/tests/api.c index 4c15bfccc2..e9b43d8276 100644 --- a/tests/api.c +++ b/tests/api.c @@ -21763,6 +21763,15 @@ static int test_PathLenSelfIssued(void) cm), WC_NO_ERR_TRACE(ASN_PATHLEN_INV_E)); wc_FreeDecodedCert(&decodedCert); + /* Step 6: Parse the trust anchor itself as a chain cert. + * A peer is allowed to include the root in the chain it sends. + * Per RFC 5280 6.1 the trust anchor is not part of the prospective + * certification path, so its own pathLen=0 must not fire against + * itself. */ + wc_InitDecodedCert(&decodedCert, rootDer, (word32)rootDerSz, NULL); + ExpectIntEQ(wc_ParseCert(&decodedCert, CHAIN_CERT_TYPE, VERIFY, cm), 0); + wc_FreeDecodedCert(&decodedCert); + wolfSSL_CertManagerFree(cm); wc_ecc_free(&entityKey); wc_ecc_free(&icaKey); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index cbd2a9901b..176e39c2fd 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -22527,7 +22527,22 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm, * max_path_length, but the issuer's constraint still * applies. A self-issued cert from a CA with maxPathLen=0 * cannot act as an intermediate CA. */ - if (cert->ca->maxPathLen == 0) { + if (cert->publicKey != NULL && + cert->ca->publicKey != NULL && + cert->pubKeySize > 0 && + cert->pubKeySize == cert->ca->pubKeySize && + XMEMCMP(cert->publicKey, cert->ca->publicKey, + cert->pubKeySize) == 0) { + /* Exclude the trust anchor itself from step (l). Per + * RFC 5280 6.1, when the trust anchor is supplied as a + * self-signed certificate it "is not included as part + * of the prospective certification path" */ + + /* Trust anchor: honor issuer's constraint */ + cert->maxPathLen = (word16)min(cert->ca->maxPathLen, + cert->maxPathLen); + } + else if (cert->ca->maxPathLen == 0) { cert->maxPathLen = 0; if (verify != NO_VERIFY) { WOLFSSL_MSG("\tSelf-issued cert, maxPathLen is 0");