Skip to content

Commit 98dd440

Browse files
committed
support custom oid callback in EKU
1 parent 9102df3 commit 98dd440

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
@@ -3602,7 +3602,7 @@ static int wolfSSL_ASN1_STRING_into_old_ext_fmt(WOLFSSL_ASN1_STRING *asn1str,
36023602

36033603
ret = DecodeExtKeyUsage((const byte*)asn1str->data, asn1str->length,
36043604
&extExtKeyUsageSrc, &extExtKeyUsageSz, &extExtKeyUsageCount,
3605-
&extExtKeyUsage, &extExtKeyUsageSsh);
3605+
&extExtKeyUsage, &extExtKeyUsageSsh, NULL);
36063606
if (ret != 0)
36073607
return ret;
36083608

wolfcrypt/src/asn.c

Lines changed: 103 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22031,6 +22031,7 @@ enum {
2203122031
* @param [out] extExtKeyUsageCount Number of usages read.
2203222032
* @param [out] extExtKeyUsage Usages read.
2203322033
* @param [out] extExtKeyUsageSsh SSH usages read.
22034+
* @param [in] unknownCb Callback for unknown EKU OIDs.
2203422035
* @return 0 on success.
2203522036
* @return ASN_BITSTR_E when the expected BIT_STRING tag is not found.
2203622037
* @return ASN_PARSE_E when BER encoded data does not match ASN.1 items or
@@ -22040,18 +22041,30 @@ enum {
2204022041
int DecodeExtKeyUsage(const byte* input, word32 sz,
2204122042
const byte **extExtKeyUsageSrc, word32 *extExtKeyUsageSz,
2204222043
word32 *extExtKeyUsageCount, byte *extExtKeyUsage,
22043-
byte *extExtKeyUsageSsh)
22044+
byte *extExtKeyUsageSsh,
22045+
#ifdef WC_ASN_UNKNOWN_EXT_CB
22046+
wc_UnknownExtKeyUsageCallback unknownCb
22047+
#else
22048+
void *unknownCb
22049+
#endif
22050+
)
2204422051
{
2204522052
#ifndef WOLFSSL_ASN_TEMPLATE
2204622053
word32 idx = 0, oid;
2204722054
int length, ret;
22055+
#ifdef WC_ASN_UNKNOWN_EXT_CB
22056+
word32 oidStartIdx;
22057+
#endif
2204822058

2204922059
WOLFSSL_ENTER("DecodeExtKeyUsage");
2205022060

2205122061
(void) extExtKeyUsageSrc;
2205222062
(void) extExtKeyUsageSz;
2205322063
(void) extExtKeyUsageCount;
2205422064
(void) extExtKeyUsageSsh;
22065+
#ifndef WC_ASN_UNKNOWN_EXT_CB
22066+
(void) unknownCb;
22067+
#endif
2205522068

2205622069
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
2205722070
*extExtKeyUsageSrc = NULL;
@@ -22074,9 +22087,34 @@ int DecodeExtKeyUsage(const byte* input, word32 sz,
2207422087
#endif
2207522088

2207622089
while (idx < (word32)sz) {
22090+
#ifdef WC_ASN_UNKNOWN_EXT_CB
22091+
oidStartIdx = idx;
22092+
#endif
2207722093
ret = GetObjectId(input, &idx, &oid, oidCertKeyUseType, sz);
22078-
if (ret == WC_NO_ERR_TRACE(ASN_UNKNOWN_OID_E))
22094+
if (ret == WC_NO_ERR_TRACE(ASN_UNKNOWN_OID_E)) {
22095+
#ifdef WC_ASN_UNKNOWN_EXT_CB
22096+
if (unknownCb != NULL) {
22097+
word16 decOid[MAX_OID_SZ];
22098+
word32 decOidSz = sizeof(decOid);
22099+
/* Skip past the tag and length to get raw OID bytes */
22100+
word32 oidIdx = oidStartIdx;
22101+
int oidLen;
22102+
byte tag;
22103+
if (GetASNTag(input, &oidIdx, &tag, sz) == 0 &&
22104+
tag == ASN_OBJECT_ID &&
22105+
GetLength(input, &oidIdx, &oidLen, sz) >= 0) {
22106+
ret = DecodeObjectId(input + oidIdx, (word32)oidLen,
22107+
decOid, &decOidSz);
22108+
if (ret == 0) {
22109+
ret = unknownCb(decOid, decOidSz);
22110+
}
22111+
if (ret != 0)
22112+
return ret;
22113+
}
22114+
}
22115+
#endif
2207922116
continue;
22117+
}
2208022118
else if (ret < 0)
2208122119
return ret;
2208222120

@@ -22127,13 +22165,19 @@ int DecodeExtKeyUsage(const byte* input, word32 sz,
2212722165
word32 idx = 0;
2212822166
int length;
2212922167
int ret = 0;
22168+
#ifdef WC_ASN_UNKNOWN_EXT_CB
22169+
int isKnownOid;
22170+
#endif
2213022171

2213122172
WOLFSSL_ENTER("DecodeExtKeyUsage");
2213222173

2213322174
(void) extExtKeyUsageSrc;
2213422175
(void) extExtKeyUsageSz;
2213522176
(void) extExtKeyUsageCount;
2213622177
(void) extExtKeyUsageSsh;
22178+
#ifndef WC_ASN_UNKNOWN_EXT_CB
22179+
(void) unknownCb;
22180+
#endif
2213722181

2213822182
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
2213922183
*extExtKeyUsageSrc = NULL;
@@ -22171,9 +22215,29 @@ int DecodeExtKeyUsage(const byte* input, word32 sz,
2217122215
input, &idx, sz);
2217222216
/* Skip unknown OIDs. */
2217322217
if (ret == WC_NO_ERR_TRACE(ASN_UNKNOWN_OID_E)) {
22218+
#ifdef WC_ASN_UNKNOWN_EXT_CB
22219+
if (unknownCb != NULL) {
22220+
word16 decOid[MAX_OID_SZ];
22221+
word32 decOidSz = sizeof(decOid);
22222+
ret = DecodeObjectId(
22223+
dataASN[KEYPURPOSEIDASN_IDX_OID].data.oid.data,
22224+
dataASN[KEYPURPOSEIDASN_IDX_OID].data.oid.length,
22225+
decOid, &decOidSz);
22226+
if (ret == 0) {
22227+
ret = unknownCb(decOid, decOidSz);
22228+
}
22229+
}
22230+
else {
22231+
ret = 0;
22232+
}
22233+
#else
2217422234
ret = 0;
22235+
#endif
2217522236
}
2217622237
else if (ret == 0) {
22238+
#ifdef WC_ASN_UNKNOWN_EXT_CB
22239+
isKnownOid = 1;
22240+
#endif
2217722241
/* Store the bit for the OID. */
2217822242
switch (dataASN[KEYPURPOSEIDASN_IDX_OID].data.oid.sum) {
2217922243
case EKU_ANY_OID:
@@ -22197,7 +22261,28 @@ int DecodeExtKeyUsage(const byte* input, word32 sz,
2219722261
case EKU_OCSP_SIGN_OID:
2219822262
*extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
2219922263
break;
22264+
#ifdef WC_ASN_UNKNOWN_EXT_CB
22265+
default:
22266+
isKnownOid = 0;
22267+
break;
22268+
#endif
22269+
}
22270+
22271+
#ifdef WC_ASN_UNKNOWN_EXT_CB
22272+
/* Handle unknown OIDs that parsed successfully but aren't
22273+
* recognized */
22274+
if (!isKnownOid && unknownCb != NULL) {
22275+
word16 decOid[MAX_OID_SZ];
22276+
word32 decOidSz = sizeof(decOid);
22277+
ret = DecodeObjectId(
22278+
dataASN[KEYPURPOSEIDASN_IDX_OID].data.oid.data,
22279+
dataASN[KEYPURPOSEIDASN_IDX_OID].data.oid.length,
22280+
decOid, &decOidSz);
22281+
if (ret == 0) {
22282+
ret = unknownCb(decOid, decOidSz);
22283+
}
2220022284
}
22285+
#endif
2220122286

2220222287
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
2220322288
/* Keep count for WOLFSSL_X509. */
@@ -22238,7 +22323,12 @@ static int DecodeExtKeyUsageInternal(const byte* input, word32 sz,
2223822323
#endif
2223922324
&cert->extExtKeyUsage,
2224022325
#ifdef WOLFSSL_WOLFSSH
22241-
&cert->extExtKeyUsageSsh
22326+
&cert->extExtKeyUsageSsh,
22327+
#else
22328+
NULL,
22329+
#endif
22330+
#ifdef WC_ASN_UNKNOWN_EXT_CB
22331+
cert->unknownExtKeyUsageCallback
2224222332
#else
2224322333
NULL
2224422334
#endif
@@ -23663,6 +23753,16 @@ int wc_SetUnknownExtCallbackEx(DecodedCert* cert,
2366323753
cert->unknownExtCallbackExCtx = ctx;
2366423754
return 0;
2366523755
}
23756+
23757+
int wc_SetUnknownExtKeyUsageCallback(DecodedCert* cert,
23758+
wc_UnknownExtKeyUsageCallback cb) {
23759+
if (cert == NULL) {
23760+
return BAD_FUNC_ARG;
23761+
}
23762+
23763+
cert->unknownExtKeyUsageCallback = cb;
23764+
return 0;
23765+
}
2366623766
#endif /* WC_ASN_UNKNOWN_EXT_CB */
2366723767

2366823768
/*

wolfssl/wolfcrypt/asn.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1721,6 +1721,7 @@ typedef int (*wc_UnknownExtCallback)(const word16* oid, word32 oidSz, int crit,
17211721
typedef int (*wc_UnknownExtCallbackEx)(const word16* oid, word32 oidSz,
17221722
int crit, const unsigned char* der,
17231723
word32 derSz, void *ctx);
1724+
typedef int (*wc_UnknownExtKeyUsageCallback)(const word16* oid, word32 oidSz);
17241725
#endif
17251726

17261727
struct DecodedCert {
@@ -2052,6 +2053,7 @@ struct DecodedCert {
20522053
wc_UnknownExtCallback unknownExtCallback;
20532054
wc_UnknownExtCallbackEx unknownExtCallbackEx;
20542055
void *unknownExtCallbackExCtx;
2056+
wc_UnknownExtKeyUsageCallback unknownExtKeyUsageCallback;
20552057
#endif
20562058
#ifdef WOLFSSL_DUAL_ALG_CERTS
20572059
/* Subject Alternative Public Key Info */
@@ -2277,6 +2279,8 @@ WOLFSSL_API int wc_SetUnknownExtCallback(DecodedCert* cert,
22772279
WOLFSSL_API int wc_SetUnknownExtCallbackEx(DecodedCert* cert,
22782280
wc_UnknownExtCallbackEx cb,
22792281
void *ctx);
2282+
WOLFSSL_API int wc_SetUnknownExtKeyUsageCallback(DecodedCert* cert,
2283+
wc_UnknownExtKeyUsageCallback cb);
22802284
#endif
22812285

22822286
WOLFSSL_LOCAL int DecodePolicyOID(char *out, word32 outSz, const byte *in,
@@ -2341,7 +2345,13 @@ WOLFSSL_LOCAL int DecodeKeyUsage(const byte* input, word32 sz,
23412345
WOLFSSL_LOCAL int DecodeExtKeyUsage(const byte* input, word32 sz,
23422346
const byte **extExtKeyUsageSrc, word32 *extExtKeyUsageSz,
23432347
word32 *extExtKeyUsageCount, byte *extExtKeyUsage,
2344-
byte *extExtKeyUsageSsh);
2348+
byte *extExtKeyUsageSsh,
2349+
#ifdef WC_ASN_UNKNOWN_EXT_CB
2350+
wc_UnknownExtKeyUsageCallback unknownCb
2351+
#else
2352+
void *unknownCb
2353+
#endif
2354+
);
23452355

23462356
WOLFSSL_LOCAL int TryDecodeRPKToKey(DecodedCert* cert);
23472357
WOLFSSL_LOCAL int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate);

0 commit comments

Comments
 (0)