Skip to content

Commit 710e376

Browse files
committed
walk up cert chain and call ConfirmNameConstraints() for each ancestor cert
Add to Signer struct to retrieve AKID data in NC cert walk
1 parent fb80740 commit 710e376

2 files changed

Lines changed: 83 additions & 16 deletions

File tree

wolfcrypt/src/asn.c

Lines changed: 68 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23156,6 +23156,11 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm,
2315623156
int idx = 0;
2315723157
#endif
2315823158
byte* sce_tsip_encRsaKeyIdx;
23159+
#ifndef IGNORE_NAME_CONSTRAINTS
23160+
int ncDepth = 0;
23161+
Signer* ncAncestor = NULL;
23162+
Signer* ncParent = NULL;
23163+
#endif
2315923164
(void)extraCAList;
2316023165

2316123166
if (cert == NULL) {
@@ -23788,18 +23793,6 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm,
2378823793
}
2378923794
#endif /* WOLFSSL_DUAL_ALG_CERTS */
2379023795
}
23791-
#ifndef IGNORE_NAME_CONSTRAINTS
23792-
if (verify == VERIFY || verify == VERIFY_OCSP ||
23793-
verify == VERIFY_NAME || verify == VERIFY_SKIP_DATE) {
23794-
/* check that this cert's name is permitted by the signer's
23795-
* name constraints */
23796-
if (!ConfirmNameConstraints(cert->ca, cert)) {
23797-
WOLFSSL_MSG("Confirm name constraint failed");
23798-
WOLFSSL_ERROR_VERBOSE(ASN_NAME_INVALID_E);
23799-
return ASN_NAME_INVALID_E;
23800-
}
23801-
}
23802-
#endif /* IGNORE_NAME_CONSTRAINTS */
2380323796
} /* cert->ca */
2380423797
#ifdef WOLFSSL_CERT_REQ
2380523798
else if (type == CERTREQ_TYPE) {
@@ -23881,6 +23874,60 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm,
2388123874
}
2388223875
} /* verify != NO_VERIFY && type != CA_TYPE && type != TRUSTED_PEER_TYPE */
2388323876

23877+
#ifndef IGNORE_NAME_CONSTRAINTS
23878+
/* Apply each ancestor CA's name constraints to this cert. */
23879+
if ((verify == VERIFY || verify == VERIFY_OCSP ||
23880+
verify == VERIFY_NAME || verify == VERIFY_SKIP_DATE) &&
23881+
type != TRUSTED_PEER_TYPE && type != CA_TYPE &&
23882+
(!cert->selfSigned || type == CERT_TYPE) && cert->ca != NULL) {
23883+
ncAncestor = cert->ca;
23884+
while (ncAncestor != NULL && ncDepth < WOLFSSL_MAX_PATH_LEN) {
23885+
if (!ConfirmNameConstraints(ncAncestor, cert)) {
23886+
WOLFSSL_MSG("Confirm name constraint failed");
23887+
WOLFSSL_ERROR_VERBOSE(ASN_NAME_INVALID_E);
23888+
return ASN_NAME_INVALID_E;
23889+
}
23890+
/* Stop at trust anchor (self-issued). */
23891+
if (XMEMCMP(ncAncestor->subjectNameHash,
23892+
ncAncestor->issuerNameHash,
23893+
SIGNER_DIGEST_SIZE) == 0)
23894+
break;
23895+
ncParent = NULL;
23896+
#ifndef NO_SKID
23897+
/* Prefer AKID->SKID lookup: more specific than name and
23898+
* resistant to same-DN CA collisions in the CM. */
23899+
if (ncAncestor->authKeyIdSet) {
23900+
ncParent = GetCA(cm, ncAncestor->authKeyIdHash);
23901+
if (ncParent != NULL &&
23902+
XMEMCMP(ncParent->subjectNameHash,
23903+
ncAncestor->issuerNameHash,
23904+
SIGNER_DIGEST_SIZE) != 0) {
23905+
ncParent = NULL;
23906+
}
23907+
}
23908+
if (ncParent == NULL) {
23909+
ncParent = GetCAByName(cm, ncAncestor->issuerNameHash);
23910+
}
23911+
#else
23912+
/* NO_SKID: name-only lookup. A same-DN sibling CA loaded into
23913+
* the CM (different key, weaker or absent NCs) can shadow the
23914+
* real signer and bypass the ancestor NC walk. NO_SKID builds
23915+
* cannot disambiguate without SKID. */
23916+
ncParent = GetCA(cm, ncAncestor->issuerNameHash);
23917+
#endif
23918+
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
23919+
if (ncParent == NULL && extraCAList != NULL) {
23920+
ncParent = findSignerByName(extraCAList,
23921+
ncAncestor->issuerNameHash);
23922+
}
23923+
#endif
23924+
if (ncParent == NULL || ncParent == ncAncestor)
23925+
break;
23926+
ncAncestor = ncParent;
23927+
ncDepth++;
23928+
}
23929+
}
23930+
#endif /* IGNORE_NAME_CONSTRAINTS */
2388423931
#if defined(WOLFSSL_NO_TRUSTED_CERTS_VERIFY) && !defined(NO_SKID)
2388523932
exit_pcr:
2388623933
#endif
@@ -23959,10 +24006,18 @@ int FillSigner(Signer* signer, DecodedCert* cert, int type, DerBuffer *der)
2395924006
#ifndef NO_SKID
2396024007
XMEMCPY(signer->subjectKeyIdHash, cert->extSubjKeyId,
2396124008
SIGNER_DIGEST_SIZE);
24009+
#ifndef IGNORE_NAME_CONSTRAINTS
24010+
if (cert->extAuthKeyIdSet) {
24011+
XMEMCPY(signer->authKeyIdHash, cert->extAuthKeyId,
24012+
SIGNER_DIGEST_SIZE);
24013+
signer->authKeyIdSet = 1;
24014+
}
24015+
#endif
2396224016
#endif
2396324017
XMEMCPY(signer->subjectNameHash, cert->subjectHash,
2396424018
SIGNER_DIGEST_SIZE);
23965-
#if defined(HAVE_OCSP) || defined(HAVE_CRL) || defined(WOLFSSL_AKID_NAME)
24019+
#if defined(HAVE_OCSP) || defined(HAVE_CRL) || \
24020+
defined(WOLFSSL_AKID_NAME) || !defined(IGNORE_NAME_CONSTRAINTS)
2396624021
XMEMCPY(signer->issuerNameHash, cert->issuerHash,
2396724022
SIGNER_DIGEST_SIZE);
2396824023
#endif

wolfssl/wolfcrypt/asn.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2207,6 +2207,11 @@ struct Signer {
22072207
*/
22082208
WC_BITFIELD extNameConstraintCrit:1;
22092209
WC_BITFIELD extNameConstraintHasUnsupported:1;
2210+
#ifndef NO_SKID
2211+
/* True when this cert had an AKID extension and authKeyIdHash was
2212+
* copied from it. */
2213+
WC_BITFIELD authKeyIdSet:1;
2214+
#endif
22102215
#endif
22112216
const byte* publicKey;
22122217
int nameLen;
@@ -2218,15 +2223,22 @@ struct Signer {
22182223
#endif
22192224
byte subjectNameHash[SIGNER_DIGEST_SIZE];
22202225
/* sha hash of names in certificate */
2221-
#if defined(HAVE_OCSP) || defined(HAVE_CRL) || defined(WOLFSSL_AKID_NAME)
2226+
#if defined(HAVE_OCSP) || defined(HAVE_CRL) || defined(WOLFSSL_AKID_NAME) || \
2227+
!defined(IGNORE_NAME_CONSTRAINTS)
22222228
byte issuerNameHash[SIGNER_DIGEST_SIZE];
22232229
/* sha hash of issuer names in certificate.
2224-
* Used in OCSP to check for authorized
2225-
* responders. */
2230+
* Used for OCSP authorized responder checks
2231+
* and name constraint ancestor walk. */
22262232
#endif
22272233
#ifndef NO_SKID
22282234
byte subjectKeyIdHash[SIGNER_DIGEST_SIZE];
22292235
/* sha hash of key in certificate */
2236+
#ifndef IGNORE_NAME_CONSTRAINTS
2237+
byte authKeyIdHash[SIGNER_DIGEST_SIZE];
2238+
/* AKID keyId from this cert; used to
2239+
* locate the actual signer during the
2240+
* name-constraint ancestor walk. */
2241+
#endif
22302242
#endif
22312243
#ifdef HAVE_OCSP
22322244
byte subjectKeyHash[KEYID_SIZE];

0 commit comments

Comments
 (0)