diff --git a/src/ssl.c b/src/ssl.c index e1fe455b7d..6beb751818 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -5358,6 +5358,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 8a140e1819..61d95ee635 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 add9ca309f..16d773c5e7 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -21410,6 +21410,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 /* @@ -21565,7 +21576,8 @@ static int DecodeCertExtensions(DecodedCert* cert) 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( @@ -21579,9 +21591,18 @@ static int DecodeCertExtensions(DecodedCert* cert) 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/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 3632aba52b..31d8d8c63c 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -830,6 +830,15 @@ int wc_PKCS7_Init(PKCS7* pkcs7, void* heap, int devId) return 0; } +#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ASN_TEMPLATE) \ + && defined(HAVE_OID_DECODING) +void wc_PKCS7_SetUnknownExtCallback(PKCS7* pkcs7, wc_UnknownExtCallback cb) +{ + if (pkcs7 != NULL) { + pkcs7->unknownExtCallback = cb; + } +} +#endif /* Certificate structure holding der pointer, size, and pointer to next * Pkcs7Cert struct. Used when creating SignedData types with multiple @@ -1074,6 +1083,10 @@ int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* derCert, word32 derCertSz) int devId; Pkcs7Cert* cert; Pkcs7Cert* lastCert; +#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ASN_TEMPLATE) \ + && defined(HAVE_OID_DECODING) + wc_UnknownExtCallback cb; +#endif if (pkcs7 == NULL || (derCert == NULL && derCertSz != 0)) { return BAD_FUNC_ARG; @@ -1082,9 +1095,18 @@ int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* derCert, word32 derCertSz) heap = pkcs7->heap; devId = pkcs7->devId; cert = pkcs7->certList; +#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ASN_TEMPLATE) \ + && defined(HAVE_OID_DECODING) + cb = pkcs7->unknownExtCallback; +#endif ret = wc_PKCS7_Init(pkcs7, heap, devId); if (ret != 0) return ret; + +#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ASN_TEMPLATE) \ + && defined(HAVE_OID_DECODING) + pkcs7->unknownExtCallback = cb; +#endif pkcs7->certList = cert; if (derCert != NULL && derCertSz > 0) { @@ -1133,6 +1155,11 @@ int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* derCert, word32 derCertSz) } InitDecodedCert(dCert, derCert, derCertSz, pkcs7->heap); +#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ASN_TEMPLATE) \ + && defined(HAVE_OID_DECODING) + if (pkcs7->unknownExtCallback != NULL) + wc_SetUnknownExtCallback(dCert, pkcs7->unknownExtCallback); +#endif ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0); if (ret < 0) { FreeDecodedCert(dCert); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index d76108ff3b..625618e1a7 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1664,6 +1664,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 { @@ -1997,6 +2000,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 */ @@ -2166,6 +2171,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, diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index 8316954c8e..758abdcbbf 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -345,6 +345,11 @@ struct PKCS7 { word32 plainDigestSz; word32 pkcs7DigestSz; +#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ASN_TEMPLATE) \ + && defined(HAVE_OID_DECODING) + wc_UnknownExtCallback unknownExtCallback; +#endif + #if defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA) CallbackRsaSignRawDigest rsaSignRawDigestCb; #endif @@ -358,6 +363,11 @@ struct PKCS7 { }; WOLFSSL_API PKCS7* wc_PKCS7_New(void* heap, int devId); +#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ASN_TEMPLATE) \ + && defined(HAVE_OID_DECODING) + WOLFSSL_API void wc_PKCS7_SetUnknownExtCallback(PKCS7* pkcs7, + wc_UnknownExtCallback cb); +#endif WOLFSSL_API int wc_PKCS7_Init(PKCS7* pkcs7, void* heap, int devId); WOLFSSL_API int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* der, word32 derSz); WOLFSSL_API int wc_PKCS7_AddCertificate(PKCS7* pkcs7, byte* der, word32 derSz);