From e581930cb751195bda955580869a5a821cba748f Mon Sep 17 00:00:00 2001 From: Anthony Hu Date: Tue, 9 Jul 2024 13:48:54 -0400 Subject: [PATCH] Extend the unknown extension callback. This will allow the user to pass in a context pointer. Allows them to avoid global variables. We also add unknown extensions callback when processing a CA in cert manager as CA certs can have unknown extensions as well. Fixes ZD 18252 --- src/ssl.c | 8 ++++++++ tests/api.c | 2 +- wolfcrypt/src/asn.c | 29 +++++++++++++++++++++++++---- wolfssl/wolfcrypt/asn.h | 8 ++++++++ 4 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 9ba891d62..9862c88a1 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -5349,6 +5349,14 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify) #endif InitDecodedCert(cert, der->buffer, der->length, cm->heap); + +#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ASN_TEMPLATE) && \ + defined(HAVE_OID_DECODING) + if (cm->unknownExtCallback != NULL) { + wc_SetUnknownExtCallback(cert, cm->unknownExtCallback); + } +#endif + ret = ParseCert(cert, CA_TYPE, verify, cm); WOLFSSL_MSG("\tParsed new CA"); diff --git a/tests/api.c b/tests/api.c index 2e23ea1fb..d0449e6ac 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1258,7 +1258,7 @@ static int myUnknownExtCallback(const word16* oid, word32 oidSz, int crit, extCount ++; /* Accept all extensions. This is only a test. Normally we would be much more * careful about critical extensions. */ - return 1; + return 0; } static int test_dual_alg_support(void) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 778d3e70f..1d2e5f120 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -21366,6 +21366,17 @@ int wc_SetUnknownExtCallback(DecodedCert* cert, cert->unknownExtCallback = cb; return 0; } + +int wc_SetUnknownExtCallbackEx(DecodedCert* cert, + wc_UnknownExtCallbackEx cb, void *ctx) { + if (cert == NULL) { + return BAD_FUNC_ARG; + } + + cert->unknownExtCallbackEx = cb; + cert->unknownExtCallbackExCtx = ctx; + return 0; +} #endif /* @@ -21521,7 +21532,8 @@ end: ret = DecodeExtensionType(input + idx, length, oid, critical, cert, &isUnknownExt); #if defined(WOLFSSL_CUSTOM_OID) && defined(HAVE_OID_DECODING) - if (isUnknownExt && (cert->unknownExtCallback != NULL)) { + if (isUnknownExt && (cert->unknownExtCallback != NULL || + cert->unknownExtCallbackEx != NULL)) { word16 decOid[MAX_OID_SZ]; word32 decOidSz = sizeof(decOid); ret = DecodeObjectId( @@ -21535,9 +21547,18 @@ end: WOLFSSL_ERROR(ret); } - ret = cert->unknownExtCallback(decOid, decOidSz, critical, - dataASN[CERTEXTASN_IDX_VAL].data.buffer.data, - dataASN[CERTEXTASN_IDX_VAL].length); + if ((ret == 0) && (cert->unknownExtCallback != NULL)) { + ret = cert->unknownExtCallback(decOid, decOidSz, critical, + dataASN[CERTEXTASN_IDX_VAL].data.buffer.data, + dataASN[CERTEXTASN_IDX_VAL].length); + } + + if ((ret == 0) && (cert->unknownExtCallbackEx != NULL)) { + ret = cert->unknownExtCallbackEx(decOid, decOidSz, critical, + dataASN[CERTEXTASN_IDX_VAL].data.buffer.data, + dataASN[CERTEXTASN_IDX_VAL].length, + cert->unknownExtCallbackExCtx); + } } #endif (void)isUnknownExt; diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 503c98579..e395b9ef6 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1645,6 +1645,9 @@ typedef struct CertSignCtx CertSignCtx; && defined(HAVE_OID_DECODING) typedef int (*wc_UnknownExtCallback)(const word16* oid, word32 oidSz, int crit, const unsigned char* der, word32 derSz); +typedef int (*wc_UnknownExtCallbackEx)(const word16* oid, word32 oidSz, + int crit, const unsigned char* der, + word32 derSz, void *ctx); #endif struct DecodedCert { @@ -1978,6 +1981,8 @@ struct DecodedCert { #if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ASN_TEMPLATE) \ && defined(HAVE_OID_DECODING) wc_UnknownExtCallback unknownExtCallback; + wc_UnknownExtCallbackEx unknownExtCallbackEx; + void *unknownExtCallbackExCtx; #endif #ifdef WOLFSSL_DUAL_ALG_CERTS /* Subject Alternative Public Key Info */ @@ -2147,6 +2152,9 @@ WOLFSSL_ASN_API int ParseCert(DecodedCert* cert, int type, int verify, && defined(HAVE_OID_DECODING) WOLFSSL_ASN_API int wc_SetUnknownExtCallback(DecodedCert* cert, wc_UnknownExtCallback cb); +WOLFSSL_ASN_API int wc_SetUnknownExtCallbackEx(DecodedCert* cert, + wc_UnknownExtCallbackEx cb, + void *ctx); #endif WOLFSSL_LOCAL int DecodePolicyOID(char *out, word32 outSz, const byte *in,