From 1cb2231ff595c1922dd709b0bfff2f4abf8847ca Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 19 Dec 2025 13:21:11 -0800 Subject: [PATCH] Added build option to allow certificate CA matching using AKID with signers SKID ( `WOLFSSL_ALLOW_AKID_SKID_MATCH`). Fixed issue with `cert->extAuthKeyIdSz` not being set with ASN template code. --- .wolfssl_known_macro_extras | 1 + wolfcrypt/src/asn.c | 61 +++++++++++++++++++------------------ wolfssl/wolfcrypt/asn.h | 32 +++++++++---------- 3 files changed, 48 insertions(+), 46 deletions(-) diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index b703f4db3..1b4255e69 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -653,6 +653,7 @@ WOLFSSL_AESNI_BY6 WOLFSSL_AES_CTR_EXAMPLE WOLFSSL_AFTER_DATE_CLOCK_SKEW WOLFSSL_ALGO_HW_MUTEX +WOLFSSL_ALLOW_AKID_SKID_MATCH WOLFSSL_ALLOW_BAD_TLS_LEGACY_VERSION WOLFSSL_ALLOW_CRIT_AIA WOLFSSL_ALLOW_CRIT_AKID diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 8452f99c2..e64f27892 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -104,6 +104,9 @@ ASN Options: * DO NOT enable this unless required for interoperability. * WOLFSSL_ASN_EXTRA: Make more ASN.1 APIs available regardless of internal * usage. + * WOLFSSL_ALLOW_AKID_SKID_MATCH: By default cert issuer is found using hash + * of cert subject hash with signers subject hash. This option allows fallback + * to using AKID and SKID matching. */ #ifndef NO_RSA @@ -21339,42 +21342,25 @@ static int DecodeAuthKeyIdInternal(const byte* input, word32 sz, ret = DecodeAuthKeyId(input, sz, &extAuthKeyId, &extAuthKeyIdSz, &extAuthKeyIdIssuer, &extAuthKeyIdIssuerSz, &extAuthKeyIdIssuerSN, &extAuthKeyIdIssuerSNSz); - - if (ret != 0) - return ret; - -#ifndef WOLFSSL_ASN_TEMPLATE - - if (extAuthKeyIdSz == 0) - { + if (ret != 0) { cert->extAuthKeyIdSet = 0; - return 0; + return ret; } - cert->extAuthKeyIdSz = extAuthKeyIdSz; - -#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) -#ifdef WOLFSSL_AKID_NAME - cert->extRawAuthKeyIdSrc = input; - cert->extRawAuthKeyIdSz = sz; -#endif - cert->extAuthKeyIdSrc = extAuthKeyId; -#endif /* OPENSSL_EXTRA */ - - return GetHashId(extAuthKeyId, extAuthKeyIdSz, cert->extAuthKeyId, - HashIdAlg(cert->signatureOID)); -#else - /* Each field is optional */ if (extAuthKeyIdSz > 0) { -#ifdef OPENSSL_EXTRA - cert->extAuthKeyIdSrc = extAuthKeyId; + cert->extAuthKeyIdSet = 1; cert->extAuthKeyIdSz = extAuthKeyIdSz; -#endif /* OPENSSL_EXTRA */ + +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + cert->extAuthKeyIdSrc = extAuthKeyId; +#endif + /* Get the hash or hash of the hash if wrong size. */ ret = GetHashId(extAuthKeyId, (int)extAuthKeyIdSz, cert->extAuthKeyId, HashIdAlg(cert->signatureOID)); } + #ifdef WOLFSSL_AKID_NAME if (ret == 0 && extAuthKeyIdIssuerSz > 0) { cert->extAuthKeyIdIssuer = extAuthKeyIdIssuer; @@ -21386,15 +21372,15 @@ static int DecodeAuthKeyIdInternal(const byte* input, word32 sz, } #endif /* WOLFSSL_AKID_NAME */ if (ret == 0) { -#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_AKID_NAME) +#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \ + defined(WOLFSSL_AKID_NAME) /* Store the raw authority key id. */ cert->extRawAuthKeyIdSrc = input; cert->extRawAuthKeyIdSz = sz; -#endif /* OPENSSL_EXTRA */ +#endif } return ret; -#endif /* WOLFSSL_ASN_TEMPLATE */ } /* Decode subject key id extension. @@ -25723,7 +25709,22 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm, } if (cert->ca != NULL && XMEMCMP(cert->issuerHash, cert->ca->subjectNameHash, KEYID_SIZE) != 0) { - cert->ca = NULL; + #ifdef WOLFSSL_ALLOW_AKID_SKID_MATCH + /* if hash of cert subject does not match hash of issuer + * then try with AKID/SKID if available */ + if (cert->extAuthKeyIdSet && cert->extAuthKeyIdSz > 0 && + cert->extAuthKeyIdSz == + (word32)sizeof(cert->ca->subjectKeyIdHash) && + XMEMCMP(cert->extAuthKeyId, cert->ca->subjectKeyIdHash, + cert->extAuthKeyIdSz) == 0) { + WOLFSSL_MSG("Cert AKID matches CA SKID"); + } + else + #endif + { + WOLFSSL_MSG("Cert subject hash does not match issuer hash"); + cert->ca = NULL; + } } if (cert->ca == NULL) { cert->ca = GetCAByName(cm, cert->issuerHash); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 6e08f3596..84ad93f1b 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1952,24 +1952,24 @@ struct Signer { int nameLen; char* name; /* common name */ #ifndef IGNORE_NAME_CONSTRAINTS - Base_entry* permittedNames; - Base_entry* excludedNames; -#endif /* !IGNORE_NAME_CONSTRAINTS */ + Base_entry* permittedNames; + Base_entry* excludedNames; +#endif byte subjectNameHash[SIGNER_DIGEST_SIZE]; /* sha hash of names in certificate */ - #if defined(HAVE_OCSP) || defined(HAVE_CRL) || defined(WOLFSSL_AKID_NAME) - byte issuerNameHash[SIGNER_DIGEST_SIZE]; - /* sha hash of issuer names in certificate. - * Used in OCSP to check for authorized - * responders. */ - #endif - #ifndef NO_SKID - byte subjectKeyIdHash[SIGNER_DIGEST_SIZE]; - /* sha hash of key in certificate */ - #endif - #ifdef HAVE_OCSP - byte subjectKeyHash[KEYID_SIZE]; - #endif +#if defined(HAVE_OCSP) || defined(HAVE_CRL) || defined(WOLFSSL_AKID_NAME) + byte issuerNameHash[SIGNER_DIGEST_SIZE]; + /* sha hash of issuer names in certificate. + * Used in OCSP to check for authorized + * responders. */ +#endif +#ifndef NO_SKID + byte subjectKeyIdHash[SIGNER_DIGEST_SIZE]; + /* sha hash of key in certificate */ +#endif +#ifdef HAVE_OCSP + byte subjectKeyHash[KEYID_SIZE]; +#endif #if defined(WOLFSSL_AKID_NAME) || defined(HAVE_CRL) byte serialHash[SIGNER_DIGEST_SIZE]; /* serial number hash */ #endif