Skip to content

Commit 188db55

Browse files
committed
support custom oid callback in EKU
1 parent 11ddec3 commit 188db55

File tree

4 files changed

+171
-5
lines changed

4 files changed

+171
-5
lines changed

doc/dox_comments/header_files/asn_public.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3889,6 +3889,62 @@ int wc_SetCustomExtension(Cert *cert, int critical, const char *oid,
38893889
*/
38903890
int wc_SetUnknownExtCallback(DecodedCert* cert,
38913891
wc_UnknownExtCallback cb);
3892+
3893+
/*!
3894+
\ingroup ASN
3895+
3896+
\brief This function registers a callback that will be used anytime
3897+
wolfSSL encounters an unknown OID within the Extended Key Usage (EKU)
3898+
extension in a certificate while parsing. The prototype of the callback
3899+
should be:
3900+
3901+
\code
3902+
int myUnknownEKUCallback(const word16* oid, word32 oidSz);
3903+
\endcode
3904+
3905+
\return 0 Returned on success.
3906+
\return BAD_FUNC_ARG Returned when cert is NULL.
3907+
3908+
\param cert the DecodedCert struct that is to be associated with this
3909+
callback.
3910+
\param cb function to register as the unknown EKU OID callback.
3911+
3912+
_Example_
3913+
\code
3914+
int ret = 0;
3915+
DecodedCert cert;
3916+
3917+
// Unknown EKU callback prototype
3918+
int myUnknownEKUCallback(const word16* oid, word32 oidSz);
3919+
3920+
// Initialize cert, then register callback
3921+
ret = wc_SetUnknownExtKeyUsageCallback(&cert, myUnknownEKUCallback);
3922+
if (ret != 0) {
3923+
// failed to set the callback
3924+
}
3925+
3926+
// oid: Array of integers that are the dot separated values in an OID.
3927+
// For example, OID 1.2.3.4.5 would be {1, 2, 3, 4, 5}.
3928+
// oidSz: Number of values in oid array.
3929+
int myUnknownEKUCallback(const word16* oid, word32 oidSz) {
3930+
3931+
// Logic to handle unknown EKU OID goes here.
3932+
// For example, check if the OID is acceptable for your application.
3933+
3934+
// NOTE: by returning zero, we are accepting this OID and
3935+
// informing wolfSSL that it is acceptable. If you find an OID
3936+
// that you do not find acceptable, you should return an error
3937+
// which will cause certificate parsing to fail.
3938+
return 0;
3939+
}
3940+
\endcode
3941+
3942+
\sa ParseCert
3943+
\sa wc_SetUnknownExtCallback
3944+
*/
3945+
int wc_SetUnknownExtKeyUsageCallback(DecodedCert* cert,
3946+
wc_UnknownExtKeyUsageCallback cb);
3947+
38923948
/*!
38933949
\ingroup ASN
38943950

src/x509.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3359,7 +3359,7 @@ static int wolfSSL_ASN1_STRING_into_old_ext_fmt(WOLFSSL_ASN1_STRING *asn1str,
33593359

33603360
ret = DecodeExtKeyUsage((const byte*)asn1str->data, asn1str->length,
33613361
&extExtKeyUsageSrc, &extExtKeyUsageSz, &extExtKeyUsageCount,
3362-
&extExtKeyUsage, &extExtKeyUsageSsh);
3362+
&extExtKeyUsage, &extExtKeyUsageSsh, NULL);
33633363
if (ret != 0)
33643364
return ret;
33653365

wolfcrypt/src/asn.c

Lines changed: 103 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21626,6 +21626,7 @@ enum {
2162621626
* @param [out] extExtKeyUsageCount Number of usages read.
2162721627
* @param [out] extExtKeyUsage Usages read.
2162821628
* @param [out] extExtKeyUsageSsh SSH usages read.
21629+
* @param [in] unknownCb Callback for unknown EKU OIDs.
2162921630
* @return 0 on success.
2163021631
* @return ASN_BITSTR_E when the expected BIT_STRING tag is not found.
2163121632
* @return ASN_PARSE_E when BER encoded data does not match ASN.1 items or
@@ -21635,18 +21636,30 @@ enum {
2163521636
int DecodeExtKeyUsage(const byte* input, word32 sz,
2163621637
const byte **extExtKeyUsageSrc, word32 *extExtKeyUsageSz,
2163721638
word32 *extExtKeyUsageCount, byte *extExtKeyUsage,
21638-
byte *extExtKeyUsageSsh)
21639+
byte *extExtKeyUsageSsh,
21640+
#ifdef WC_ASN_UNKNOWN_EXT_CB
21641+
wc_UnknownExtKeyUsageCallback unknownCb
21642+
#else
21643+
void *unknownCb
21644+
#endif
21645+
)
2163921646
{
2164021647
#ifndef WOLFSSL_ASN_TEMPLATE
2164121648
word32 idx = 0, oid;
2164221649
int length, ret;
21650+
#ifdef WC_ASN_UNKNOWN_EXT_CB
21651+
word32 oidStartIdx;
21652+
#endif
2164321653

2164421654
WOLFSSL_ENTER("DecodeExtKeyUsage");
2164521655

2164621656
(void) extExtKeyUsageSrc;
2164721657
(void) extExtKeyUsageSz;
2164821658
(void) extExtKeyUsageCount;
2164921659
(void) extExtKeyUsageSsh;
21660+
#ifndef WC_ASN_UNKNOWN_EXT_CB
21661+
(void) unknownCb;
21662+
#endif
2165021663

2165121664
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
2165221665
*extExtKeyUsageSrc = NULL;
@@ -21669,9 +21682,34 @@ int DecodeExtKeyUsage(const byte* input, word32 sz,
2166921682
#endif
2167021683

2167121684
while (idx < (word32)sz) {
21685+
#ifdef WC_ASN_UNKNOWN_EXT_CB
21686+
oidStartIdx = idx;
21687+
#endif
2167221688
ret = GetObjectId(input, &idx, &oid, oidCertKeyUseType, sz);
21673-
if (ret == WC_NO_ERR_TRACE(ASN_UNKNOWN_OID_E))
21689+
if (ret == WC_NO_ERR_TRACE(ASN_UNKNOWN_OID_E)) {
21690+
#ifdef WC_ASN_UNKNOWN_EXT_CB
21691+
if (unknownCb != NULL) {
21692+
word16 decOid[MAX_OID_SZ];
21693+
word32 decOidSz = sizeof(decOid);
21694+
/* Skip past the tag and length to get raw OID bytes */
21695+
word32 oidIdx = oidStartIdx;
21696+
int oidLen;
21697+
byte tag;
21698+
if (GetASNTag(input, &oidIdx, &tag, sz) == 0 &&
21699+
tag == ASN_OBJECT_ID &&
21700+
GetLength(input, &oidIdx, &oidLen, sz) >= 0) {
21701+
ret = DecodeObjectId(input + oidIdx, (word32)oidLen,
21702+
decOid, &decOidSz);
21703+
if (ret == 0) {
21704+
ret = unknownCb(decOid, decOidSz);
21705+
}
21706+
if (ret != 0)
21707+
return ret;
21708+
}
21709+
}
21710+
#endif
2167421711
continue;
21712+
}
2167521713
else if (ret < 0)
2167621714
return ret;
2167721715

@@ -21722,13 +21760,19 @@ int DecodeExtKeyUsage(const byte* input, word32 sz,
2172221760
word32 idx = 0;
2172321761
int length;
2172421762
int ret = 0;
21763+
#ifdef WC_ASN_UNKNOWN_EXT_CB
21764+
int isKnownOid;
21765+
#endif
2172521766

2172621767
WOLFSSL_ENTER("DecodeExtKeyUsage");
2172721768

2172821769
(void) extExtKeyUsageSrc;
2172921770
(void) extExtKeyUsageSz;
2173021771
(void) extExtKeyUsageCount;
2173121772
(void) extExtKeyUsageSsh;
21773+
#ifndef WC_ASN_UNKNOWN_EXT_CB
21774+
(void) unknownCb;
21775+
#endif
2173221776

2173321777
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
2173421778
*extExtKeyUsageSrc = NULL;
@@ -21766,9 +21810,29 @@ int DecodeExtKeyUsage(const byte* input, word32 sz,
2176621810
input, &idx, sz);
2176721811
/* Skip unknown OIDs. */
2176821812
if (ret == WC_NO_ERR_TRACE(ASN_UNKNOWN_OID_E)) {
21813+
#ifdef WC_ASN_UNKNOWN_EXT_CB
21814+
if (unknownCb != NULL) {
21815+
word16 decOid[MAX_OID_SZ];
21816+
word32 decOidSz = sizeof(decOid);
21817+
ret = DecodeObjectId(
21818+
dataASN[KEYPURPOSEIDASN_IDX_OID].data.oid.data,
21819+
dataASN[KEYPURPOSEIDASN_IDX_OID].data.oid.length,
21820+
decOid, &decOidSz);
21821+
if (ret == 0) {
21822+
ret = unknownCb(decOid, decOidSz);
21823+
}
21824+
}
21825+
else {
21826+
ret = 0;
21827+
}
21828+
#else
2176921829
ret = 0;
21830+
#endif
2177021831
}
2177121832
else if (ret == 0) {
21833+
#ifdef WC_ASN_UNKNOWN_EXT_CB
21834+
isKnownOid = 1;
21835+
#endif
2177221836
/* Store the bit for the OID. */
2177321837
switch (dataASN[KEYPURPOSEIDASN_IDX_OID].data.oid.sum) {
2177421838
case EKU_ANY_OID:
@@ -21792,7 +21856,28 @@ int DecodeExtKeyUsage(const byte* input, word32 sz,
2179221856
case EKU_OCSP_SIGN_OID:
2179321857
*extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
2179421858
break;
21859+
#ifdef WC_ASN_UNKNOWN_EXT_CB
21860+
default:
21861+
isKnownOid = 0;
21862+
break;
21863+
#endif
21864+
}
21865+
21866+
#ifdef WC_ASN_UNKNOWN_EXT_CB
21867+
/* Handle unknown OIDs that parsed successfully but aren't
21868+
* recognized */
21869+
if (!isKnownOid && unknownCb != NULL) {
21870+
word16 decOid[MAX_OID_SZ];
21871+
word32 decOidSz = sizeof(decOid);
21872+
ret = DecodeObjectId(
21873+
dataASN[KEYPURPOSEIDASN_IDX_OID].data.oid.data,
21874+
dataASN[KEYPURPOSEIDASN_IDX_OID].data.oid.length,
21875+
decOid, &decOidSz);
21876+
if (ret == 0) {
21877+
ret = unknownCb(decOid, decOidSz);
21878+
}
2179521879
}
21880+
#endif
2179621881

2179721882
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
2179821883
/* Keep count for WOLFSSL_X509. */
@@ -21833,7 +21918,12 @@ static int DecodeExtKeyUsageInternal(const byte* input, word32 sz,
2183321918
#endif
2183421919
&cert->extExtKeyUsage,
2183521920
#ifdef WOLFSSL_WOLFSSH
21836-
&cert->extExtKeyUsageSsh
21921+
&cert->extExtKeyUsageSsh,
21922+
#else
21923+
NULL,
21924+
#endif
21925+
#ifdef WC_ASN_UNKNOWN_EXT_CB
21926+
cert->unknownExtKeyUsageCallback
2183721927
#else
2183821928
NULL
2183921929
#endif
@@ -23255,6 +23345,16 @@ int wc_SetUnknownExtCallbackEx(DecodedCert* cert,
2325523345
cert->unknownExtCallbackExCtx = ctx;
2325623346
return 0;
2325723347
}
23348+
23349+
int wc_SetUnknownExtKeyUsageCallback(DecodedCert* cert,
23350+
wc_UnknownExtKeyUsageCallback cb) {
23351+
if (cert == NULL) {
23352+
return BAD_FUNC_ARG;
23353+
}
23354+
23355+
cert->unknownExtKeyUsageCallback = cb;
23356+
return 0;
23357+
}
2325823358
#endif /* WC_ASN_UNKNOWN_EXT_CB */
2325923359

2326023360
/*

wolfssl/wolfcrypt/asn.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1708,6 +1708,7 @@ typedef int (*wc_UnknownExtCallback)(const word16* oid, word32 oidSz, int crit,
17081708
typedef int (*wc_UnknownExtCallbackEx)(const word16* oid, word32 oidSz,
17091709
int crit, const unsigned char* der,
17101710
word32 derSz, void *ctx);
1711+
typedef int (*wc_UnknownExtKeyUsageCallback)(const word16* oid, word32 oidSz);
17111712
#endif
17121713

17131714
struct DecodedCert {
@@ -2039,6 +2040,7 @@ struct DecodedCert {
20392040
wc_UnknownExtCallback unknownExtCallback;
20402041
wc_UnknownExtCallbackEx unknownExtCallbackEx;
20412042
void *unknownExtCallbackExCtx;
2043+
wc_UnknownExtKeyUsageCallback unknownExtKeyUsageCallback;
20422044
#endif
20432045
#ifdef WOLFSSL_DUAL_ALG_CERTS
20442046
/* Subject Alternative Public Key Info */
@@ -2258,6 +2260,8 @@ WOLFSSL_API int wc_SetUnknownExtCallback(DecodedCert* cert,
22582260
WOLFSSL_API int wc_SetUnknownExtCallbackEx(DecodedCert* cert,
22592261
wc_UnknownExtCallbackEx cb,
22602262
void *ctx);
2263+
WOLFSSL_API int wc_SetUnknownExtKeyUsageCallback(DecodedCert* cert,
2264+
wc_UnknownExtKeyUsageCallback cb);
22612265
#endif
22622266

22632267
WOLFSSL_LOCAL int DecodePolicyOID(char *out, word32 outSz, const byte *in,
@@ -2322,7 +2326,13 @@ WOLFSSL_LOCAL int DecodeKeyUsage(const byte* input, word32 sz,
23222326
WOLFSSL_LOCAL int DecodeExtKeyUsage(const byte* input, word32 sz,
23232327
const byte **extExtKeyUsageSrc, word32 *extExtKeyUsageSz,
23242328
word32 *extExtKeyUsageCount, byte *extExtKeyUsage,
2325-
byte *extExtKeyUsageSsh);
2329+
byte *extExtKeyUsageSsh,
2330+
#ifdef WC_ASN_UNKNOWN_EXT_CB
2331+
wc_UnknownExtKeyUsageCallback unknownCb
2332+
#else
2333+
void *unknownCb
2334+
#endif
2335+
);
23262336

23272337
WOLFSSL_LOCAL int TryDecodeRPKToKey(DecodedCert* cert);
23282338
WOLFSSL_LOCAL int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate);

0 commit comments

Comments
 (0)