diff --git a/src/ssl.c b/src/ssl.c index ea1c34f6e..66f2c924a 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -4286,6 +4286,7 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify) } signer->pathLength = cert->pathLength; signer->pathLengthSet = cert->pathLengthSet; + signer->selfSigned = cert->selfSigned; #ifndef IGNORE_NAME_CONSTRAINTS signer->permittedNames = cert->permittedNames; signer->excludedNames = cert->excludedNames; diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 4c22ecbe7..089aa2799 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -8108,16 +8108,32 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) WOLFSSL_MSG("About to verify certificate signature"); if (cert->ca) { - /* Check if cert is CA type and has path length set */ + /* Check if cert is CA type and signer has path length set */ if (cert->isCA && cert->ca->pathLengthSet) { - /* Check root CA (self-signed) has path length > 0 */ + #if defined(WOLFSSL_WPAS) && !defined(WOLFSSL_NO_ASN_STRICT) + /* WPA Supplicant - has test case that expects self-signed + root CA to have path length == 0 */ if (cert->selfSigned) { if (cert->ca->pathLength != 0) { - WOLFSSL_MSG("Root CA with path length > 0"); + WOLFSSL_MSG("Root CA with path length > 0"); + return ASN_PATHLEN_INV_E; + } + } + #endif + /* Check if signer is root CA (self-signed) */ + if (cert->ca->selfSigned) { + /* Root CA as signer: + * Must have path length > 0 to sign another CA + * If path length == 0 can only sign an end entity + * certificate, not intermediate CA + */ + if (cert->ca->pathLength == 0) { + WOLFSSL_MSG("Root CA with path length == 0"); return ASN_PATHLEN_INV_E; } } else { + /* Intermediate CA signing Intermediate CA */ /* Check path lengths are valid between two CA's */ if (cert->ca->pathLength == 0) { WOLFSSL_MSG("CA with path length 0 signing a CA"); @@ -8130,10 +8146,11 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) } } - #ifdef HAVE_OCSP - /* Need the CA's public key hash for OCSP */ - XMEMCPY(cert->issuerKeyHash, cert->ca->subjectKeyHash, KEYID_SIZE); - #endif /* HAVE_OCSP */ + #ifdef HAVE_OCSP + /* Need the CA's public key hash for OCSP */ + XMEMCPY(cert->issuerKeyHash, cert->ca->subjectKeyHash, + KEYID_SIZE); + #endif /* HAVE_OCSP */ } } } diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 0c11683ae..7446803a3 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -861,7 +861,8 @@ struct Signer { word32 keyOID; /* key type */ word16 keyUsage; byte pathLength; - byte pathLengthSet; + byte pathLengthSet : 1; + byte selfSigned : 1; const byte* publicKey; int nameLen; char* name; /* common name */