forked from wolfSSL/wolfssl
Merge pull request #4905 from anhu/custom_ext_parse
Injection and parsing of custom extensions in X.509 certificates.
This commit is contained in:
@ -1937,3 +1937,103 @@ WOLFSSL_API int wc_SetTimeCb(wc_time_cb f);
|
||||
\sa wc_SetTimeCb
|
||||
*/
|
||||
WOLFSSL_API time_t wc_Time(time_t* t);
|
||||
|
||||
/*!
|
||||
\ingroup ASN
|
||||
|
||||
\brief This function injects a custom extension in to an X.509 certificate.
|
||||
|
||||
\return 0 Returned on success.
|
||||
\return Other negative values on failure.
|
||||
|
||||
\param cert Pointer to an initialized DecodedCert object.
|
||||
\param critical If 0, the extension will not be marked critical, otherwise
|
||||
it will be marked critical.
|
||||
\param oid Dot separted oid as a string. For example "1.2.840.10045.3.1.7"
|
||||
\param der The der encoding of the content of the extension.
|
||||
\param derSz The size in bytes of the der encoding.
|
||||
|
||||
|
||||
_Example_
|
||||
\code
|
||||
int ret = 0;
|
||||
Cert newCert;
|
||||
wc_InitCert(&newCert);
|
||||
|
||||
// Code to setup subject, public key, issuer, and other things goes here.
|
||||
|
||||
ret = wc_SetCustomExtension(&newCert, 1, "1.2.3.4.5",
|
||||
(const byte *)"This is a critical extension", 28);
|
||||
if (ret < 0) {
|
||||
// Failed to set the extension.
|
||||
}
|
||||
|
||||
ret = wc_SetCustomExtension(&newCert, 0, "1.2.3.4.6",
|
||||
(const byte *)"This is NOT a critical extension", 32)
|
||||
if (ret < 0) {
|
||||
// Failed to set the extension.
|
||||
}
|
||||
|
||||
// Code to sign the certificate and then write it out goes here.
|
||||
|
||||
\endcode
|
||||
|
||||
\sa wc_InitCert
|
||||
\sa wc_SetUnknownExtCallback
|
||||
*/
|
||||
WOLFSSL_API int wc_SetCustomExtension(Cert *cert, int critical, const char *oid,
|
||||
const byte *der, word32 derSz);
|
||||
|
||||
/*!
|
||||
\ingroup ASN
|
||||
|
||||
\brief This function registers a callback that will be used anytime
|
||||
wolfSSL encounters an unknown X.509 extension in a certificate while parsing
|
||||
a certificate. The prototype of the callback should be:
|
||||
|
||||
\return 0 Returned on success.
|
||||
\return Other negative values on failure.
|
||||
|
||||
\param cert the DecodedCert struct that is to be associated with this
|
||||
callback.
|
||||
\param cb function to register as the time callback.
|
||||
|
||||
_Example_
|
||||
\code
|
||||
int ret = 0;
|
||||
// Unkown extension callback prototype
|
||||
int myUnknownExtCallback(const word16* oid, word32 oidSz, int crit,
|
||||
const unsigned char* der, word32 derSz);
|
||||
|
||||
// Register it
|
||||
ret = wc_SetUnknownExtCallback(cert, myUnknownExtCallback);
|
||||
if (ret != 0) {
|
||||
// failed to set the callback
|
||||
}
|
||||
|
||||
// oid: Array of integers that are the dot separated values in an oid.
|
||||
// oidSz: Number of values in oid.
|
||||
// crit: Whether the extension was mark critical.
|
||||
// der: The der encoding of the content of the extension.
|
||||
// derSz: The size in bytes of the der encoding.
|
||||
int myCustomExtCallback(const word16* oid, word32 oidSz, int crit,
|
||||
const unsigned char* der, word32 derSz) {
|
||||
|
||||
// Logic to parse extension goes here.
|
||||
|
||||
// NOTE: by returning zero, we are accepting this extension and
|
||||
// informing wolfSSL that it is acceptable. If you find an extension
|
||||
// that you do not find acceptable, you should return an error. The
|
||||
// standard behavior upon encountering an unknown extension with the
|
||||
// critical flag set is to return ASN_CRIT_EXT_E. For the sake of
|
||||
// brevity, this example is always accepting every extension; you
|
||||
// should use different logic.
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
|
||||
\sa ParseCert
|
||||
\sa wc_SetCustomExtension
|
||||
*/
|
||||
WOLFSSL_ASN_API int wc_SetUnknownExtCallback(DecodedCert* cert,
|
||||
wc_UnknownExtCallback cb);
|
||||
|
@ -5119,7 +5119,7 @@ static int DumpOID(const byte* oidData, word32 oidSz, word32 oid,
|
||||
|
||||
#ifdef HAVE_OID_DECODING
|
||||
{
|
||||
word16 decOid[16];
|
||||
word16 decOid[MAX_OID_SZ];
|
||||
word32 decOidSz = sizeof(decOid);
|
||||
/* Decode the OID into dotted form. */
|
||||
ret = DecodeObjectId(oidData, oidSz, decOid, &decOidSz);
|
||||
@ -16569,11 +16569,15 @@ exit:
|
||||
* @return Other -ve value on error.
|
||||
*/
|
||||
static int DecodeExtensionType(const byte* input, int length, word32 oid,
|
||||
byte critical, DecodedCert* cert)
|
||||
byte critical, DecodedCert* cert,
|
||||
int *isUnknownExt)
|
||||
{
|
||||
int ret = 0;
|
||||
word32 idx = 0;
|
||||
|
||||
if (isUnknownExt != NULL)
|
||||
*isUnknownExt = 0;
|
||||
|
||||
switch (oid) {
|
||||
/* Basic Constraints. */
|
||||
case BASIC_CA_OID:
|
||||
@ -16757,6 +16761,8 @@ static int DecodeExtensionType(const byte* input, int length, word32 oid,
|
||||
return ASN_PARSE_E;
|
||||
break;
|
||||
default:
|
||||
if (isUnknownExt != NULL)
|
||||
*isUnknownExt = 1;
|
||||
#ifndef WOLFSSL_NO_ASN_STRICT
|
||||
/* While it is a failure to not support critical extensions,
|
||||
* still parse the certificate ignoring the unsupported
|
||||
@ -16810,6 +16816,19 @@ enum {
|
||||
#define certExtASN_Length (sizeof(certExtASN) / sizeof(ASNItem))
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ASN_TEMPLATE) \
|
||||
&& defined(HAVE_OID_DECODING)
|
||||
int wc_SetUnknownExtCallback(DecodedCert* cert,
|
||||
wc_UnknownExtCallback cb) {
|
||||
if (cert == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
cert->unknownExtCallback = cb;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Processing the Certificate Extensions. This does not modify the current
|
||||
* index. It is works starting with the recorded extensions pointer.
|
||||
@ -16897,7 +16916,8 @@ static int DecodeCertExtensions(DecodedCert* cert)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = DecodeExtensionType(input + idx, length, oid, critical, cert);
|
||||
ret = DecodeExtensionType(input + idx, length, oid, critical, cert,
|
||||
NULL);
|
||||
if (ret == ASN_CRIT_EXT_E) {
|
||||
ret = 0;
|
||||
criticalFail = 1;
|
||||
@ -16942,6 +16962,7 @@ end:
|
||||
/* Parse each extension. */
|
||||
while ((ret == 0) && (idx < (word32)sz)) {
|
||||
byte critical = 0;
|
||||
int isUnknownExt = 0;
|
||||
|
||||
/* Clear dynamic data. */
|
||||
XMEMSET(dataASN, 0, sizeof(*dataASN) * certExtASN_Length);
|
||||
@ -16957,7 +16978,30 @@ end:
|
||||
int length = dataASN[CERTEXTASN_IDX_VAL].length;
|
||||
|
||||
/* Decode the extension by type. */
|
||||
ret = DecodeExtensionType(input + idx, length, oid, critical, cert);
|
||||
ret = DecodeExtensionType(input + idx, length, oid, critical, cert,
|
||||
&isUnknownExt);
|
||||
#if defined(WOLFSSL_CUSTOM_OID) && defined(HAVE_OID_DECODING)
|
||||
if (isUnknownExt && (cert->unknownExtCallback != NULL)) {
|
||||
word16 decOid[MAX_OID_SZ];
|
||||
word32 decOidSz = sizeof(decOid);
|
||||
ret = DecodeObjectId(
|
||||
dataASN[CERTEXTASN_IDX_OID].data.oid.data,
|
||||
dataASN[CERTEXTASN_IDX_OID].data.oid.length,
|
||||
decOid, &decOidSz);
|
||||
if (ret != 0) {
|
||||
/* Should never get here as the extension was successfully
|
||||
* decoded earlier. Something might be corrupted. */
|
||||
WOLFSSL_MSG("DecodeObjectId() failed. Corruption?");
|
||||
WOLFSSL_ERROR(ret);
|
||||
}
|
||||
|
||||
ret = cert->unknownExtCallback(decOid, decOidSz, critical,
|
||||
dataASN[CERTEXTASN_IDX_VAL].data.buffer.data,
|
||||
dataASN[CERTEXTASN_IDX_VAL].length);
|
||||
}
|
||||
#endif
|
||||
(void)isUnknownExt;
|
||||
|
||||
/* Move index on to next extension. */
|
||||
idx += length;
|
||||
}
|
||||
@ -21227,7 +21271,7 @@ static int SetEccPublicKey(byte* output, ecc_key* key, int outLen,
|
||||
oidKeyType);
|
||||
/* Set the curve OID. */
|
||||
SetASN_Buffer(&dataASN[ECCPUBLICKEYASN_IDX_ALGOID_CURVEID],
|
||||
key->dp->oid, key->dp->oidSz);
|
||||
(const byte *)key->dp->oid, key->dp->oidSz);
|
||||
/* Don't try to write out explicit parameters. */
|
||||
dataASN[ECCPUBLICKEYASN_IDX_ALGOID_PARAMS].noOut = 1;
|
||||
/* Set size of public point to ensure space is made for it. */
|
||||
@ -23217,7 +23261,7 @@ static int EncodePublicKey(int keyType, byte* output, int outLen,
|
||||
* X.509: RFC 5280, 4.1 - Basic Certificate Fields.
|
||||
* All extensions supported for encoding are described.
|
||||
*/
|
||||
static const ASNItem certExtsASN[] = {
|
||||
static const ASNItem static_certExtsASN[] = {
|
||||
/* Basic Constraints Extension - 4.2.1.9 */
|
||||
/* BC_SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 },
|
||||
/* BC_OID */ { 1, ASN_OBJECT_ID, 0, 0, 0 },
|
||||
@ -23231,7 +23275,6 @@ static const ASNItem certExtsASN[] = {
|
||||
/* SAN_SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 },
|
||||
/* SAN_OID */ { 1, ASN_OBJECT_ID, 0, 0, 0 },
|
||||
/* SAN_STR */ { 1, ASN_OCTET_STRING, 0, 0, 0 },
|
||||
#ifdef WOLFSSL_CERT_EXT
|
||||
/* Subject Key Identifier - 4.2.1.2 */
|
||||
/* SKID_SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 },
|
||||
/* SKID_OID */ { 1, ASN_OBJECT_ID, 0, 0, 0 },
|
||||
@ -23257,7 +23300,7 @@ static const ASNItem certExtsASN[] = {
|
||||
/* POLICIES_SEQ, */ { 0, ASN_SEQUENCE, 1, 1, 0 },
|
||||
/* POLICIES_OID, */ { 1, ASN_OBJECT_ID, 0, 0, 0 },
|
||||
/* POLICIES_STR, */ { 1, ASN_OCTET_STRING, 0, 1, 0 },
|
||||
/* POLICIES_INFO */ { 2, ASN_SEQUENCE, 0, 0, 0 },
|
||||
/* POLICIES_INFO */ { 2, ASN_SEQUENCE, 1, 0, 0 },
|
||||
/* Netscape Certificate Type */
|
||||
/* NSTYPE_SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 },
|
||||
/* NSTYPE_OID */ { 1, ASN_OBJECT_ID, 0, 0, 0 },
|
||||
@ -23266,12 +23309,9 @@ static const ASNItem certExtsASN[] = {
|
||||
/* CRLINFO_SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 },
|
||||
/* CRLINFO_OID */ { 1, ASN_OBJECT_ID, 0, 0, 0 },
|
||||
/* CRLINFO_STR */ { 1, ASN_OCTET_STRING, 0, 0, 0 },
|
||||
#endif /* WOLFSSL_CERT_EXT */
|
||||
#ifdef WOLFSSL_CUSTOM_OID
|
||||
/* CUSTOM_SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 },
|
||||
/* CUSTOM_OID */ { 1, ASN_OBJECT_ID, 0, 0, 0 },
|
||||
/* CUSTOM_STR */ { 1, ASN_OCTET_STRING, 0, 0, 0 },
|
||||
#endif
|
||||
};
|
||||
enum {
|
||||
CERTEXTSASN_IDX_BC_SEQ = 0,
|
||||
@ -23314,10 +23354,21 @@ enum {
|
||||
CERTEXTSASN_IDX_CUSTOM_SEQ,
|
||||
CERTEXTSASN_IDX_CUSTOM_OID,
|
||||
CERTEXTSASN_IDX_CUSTOM_STR,
|
||||
CERTEXTSASN_IDX_START_CUSTOM,
|
||||
|
||||
};
|
||||
|
||||
/* Number of items in ASN.1 template for certificate extensions. */
|
||||
#define certExtsASN_Length (sizeof(certExtsASN) / sizeof(ASNItem))
|
||||
/* Number of items in ASN.1 template for certificate extensions. We multiply
|
||||
* by 4 because there are 4 things (seq, OID, crit flag, octet string). */
|
||||
#define certExtsASN_Length ((sizeof(static_certExtsASN) / sizeof(ASNItem)) \
|
||||
+ (NUM_CUSTOM_EXT * 4))
|
||||
|
||||
static const ASNItem customExtASN[] = {
|
||||
/* CUSTOM_SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 },
|
||||
/* CUSTOM_OID */ { 1, ASN_OBJECT_ID, 0, 0, 0 },
|
||||
/* CUSTOM_CRIT */ { 1, ASN_BOOLEAN, 0, 0, 0 },
|
||||
/* CUSTOM_STR */ { 1, ASN_OCTET_STRING, 0, 0, 0 },
|
||||
};
|
||||
|
||||
static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz,
|
||||
int forRequest)
|
||||
@ -23325,6 +23376,7 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz,
|
||||
DECL_ASNSETDATA(dataASN, certExtsASN_Length);
|
||||
int sz;
|
||||
int ret = 0;
|
||||
int i = 0;
|
||||
static const byte bcOID[] = { 0x55, 0x1d, 0x13 };
|
||||
#ifdef WOLFSSL_ALT_NAMES
|
||||
static const byte sanOID[] = { 0x55, 0x1d, 0x11 };
|
||||
@ -23340,6 +23392,41 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz,
|
||||
static const byte crlInfoOID[] = { 0x55, 0x1D, 0x1F };
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_CERT_EXT)
|
||||
byte *encodedOids;
|
||||
#endif
|
||||
ASNItem *certExtsASN = (ASNItem *)XMALLOC(certExtsASN_Length *
|
||||
sizeof(ASNItem), cert->heap,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (certExtsASN == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_CERT_EXT)
|
||||
encodedOids = (byte *)XMALLOC(NUM_CUSTOM_EXT * MAX_OID_SZ, cert->heap,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (encodedOids == NULL) {
|
||||
XFREE(certExtsASN, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return MEMORY_E;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
ASNItem certExtsASN[certExtsASN_Length];
|
||||
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_CERT_EXT)
|
||||
byte encodedOids[NUM_CUSTOM_EXT * MAX_OID_SZ];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Clone static_certExtsASN into a certExtsASN and then fill the rest of it
|
||||
* with (NUM_CUSTOM_EXT*4) more ASNItems specifying extensions. See comment
|
||||
* above definition of certExtsASN_Length. */
|
||||
XMEMCPY(certExtsASN, static_certExtsASN, sizeof(static_certExtsASN));
|
||||
for (i = sizeof(static_certExtsASN) / sizeof(ASNItem);
|
||||
i < (int)(sizeof(certExtsASN) / sizeof(ASNItem)); i += 4) {
|
||||
XMEMCPY(&certExtsASN[i], customExtASN, sizeof(customExtASN));
|
||||
}
|
||||
|
||||
(void)forRequest;
|
||||
|
||||
CALLOC_ASNSETDATA(dataASN, certExtsASN_Length, ret, cert->heap);
|
||||
@ -23489,7 +23576,6 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz,
|
||||
SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_CRLINFO_SEQ,
|
||||
CERTEXTSASN_IDX_CRLINFO_STR);
|
||||
}
|
||||
#endif /* WOLFSSL_CERT_EXT */
|
||||
|
||||
#ifdef WOLFSSL_CUSTOM_OID
|
||||
/* encode a custom oid and value */
|
||||
@ -23500,12 +23586,44 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz,
|
||||
SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_CUSTOM_STR],
|
||||
cert->extCustom.val, cert->extCustom.valSz);
|
||||
}
|
||||
else {
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Don't write out custom OID. */
|
||||
SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_CUSTOM_SEQ,
|
||||
CERTEXTSASN_IDX_CUSTOM_STR);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
#ifdef WOLFSSL_CUSTOM_OID
|
||||
for (; i < cert->customCertExtCount; i++) {
|
||||
int idx = CERTEXTSASN_IDX_START_CUSTOM + (i * 4);
|
||||
word32 encodedOidSz = MAX_OID_SZ;
|
||||
idx++; /* Skip one for for SEQ. */
|
||||
/* EncodePolicyOID() will never return error since we parsed this
|
||||
* OID when it was set. */
|
||||
EncodePolicyOID(&encodedOids[i * MAX_OID_SZ], &encodedOidSz,
|
||||
cert->customCertExt[i].oid, NULL);
|
||||
SetASN_Buffer(&dataASN[idx], &encodedOids[i * MAX_OID_SZ],
|
||||
encodedOidSz);
|
||||
idx++;
|
||||
if (cert->customCertExt[i].crit) {
|
||||
SetASN_Boolean(&dataASN[idx], 1);
|
||||
} else {
|
||||
dataASN[idx].noOut = 1;
|
||||
}
|
||||
idx++;
|
||||
SetASN_Buffer(&dataASN[idx], cert->customCertExt[i].val,
|
||||
cert->customCertExt[i].valSz);
|
||||
}
|
||||
#endif
|
||||
|
||||
while (i < NUM_CUSTOM_EXT) {
|
||||
SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_START_CUSTOM + (i * 4),
|
||||
CERTEXTSASN_IDX_START_CUSTOM + (i * 4) + 3);
|
||||
i++;
|
||||
}
|
||||
#endif /* WOLFSSL_CERT_EXT */
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
@ -23554,6 +23672,13 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz,
|
||||
}
|
||||
|
||||
FREE_ASNSETDATA(dataASN, cert->heap);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_CERT_EXT)
|
||||
XFREE(encodedOids, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
XFREE(certExtsASN, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSL_ASN_TEMPLATE */
|
||||
@ -26157,6 +26282,43 @@ int wc_SetExtKeyUsageOID(Cert *cert, const char *in, word32 sz, byte idx,
|
||||
return 0;
|
||||
}
|
||||
#endif /* WOLFSSL_EKU_OID */
|
||||
|
||||
#if defined(WOLFSSL_ASN_TEMPLATE) && defined(WOLFSSL_CERT_GEN) && \
|
||||
defined(WOLFSSL_CUSTOM_OID) && defined(HAVE_OID_ENCODING) && \
|
||||
defined(WOLFSSL_CERT_EXT)
|
||||
int wc_SetCustomExtension(Cert *cert, int critical, const char *oid,
|
||||
const byte *der, word32 derSz) {
|
||||
CertExtension *ext;
|
||||
byte encodedOid[MAX_OID_SZ];
|
||||
word32 encodedOidSz = MAX_OID_SZ;
|
||||
int ret;
|
||||
|
||||
if (cert == NULL || oid == NULL || der == NULL || derSz == 0) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (cert->customCertExtCount >= NUM_CUSTOM_EXT) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
/* Make sure we can properly parse the OID. */
|
||||
ret = EncodePolicyOID(encodedOid, &encodedOidSz, oid, NULL);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ext = &cert->customCertExt[cert->customCertExtCount];
|
||||
|
||||
ext->oid = oid;
|
||||
ext->crit = (critical == 0) ? 0 : 1;
|
||||
ext->val = der;
|
||||
ext->valSz = derSz;
|
||||
|
||||
cert->customCertExtCount++;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* WOLFSSL_CERT_EXT */
|
||||
|
||||
|
||||
@ -28226,8 +28388,8 @@ static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 *inLen,
|
||||
SetASN_Buffer(&dataASN[ECCKEYASN_IDX_PKEY], NULL, privSz);
|
||||
if (curveIn) {
|
||||
/* Curve OID */
|
||||
SetASN_Buffer(&dataASN[ECCKEYASN_IDX_CURVEID], key->dp->oid,
|
||||
key->dp->oidSz);
|
||||
SetASN_Buffer(&dataASN[ECCKEYASN_IDX_CURVEID],
|
||||
(const byte *)key->dp->oid, key->dp->oidSz);
|
||||
/* TODO: add support for SpecifiedECDomain curve. */
|
||||
dataASN[ECCKEYASN_IDX_CURVEPARAMS].noOut = 1;
|
||||
}
|
||||
|
@ -4072,17 +4072,37 @@ int wc_ecc_get_curve_id_from_dp_params(const ecc_set_type* dp)
|
||||
int wc_ecc_get_curve_id_from_oid(const byte* oid, word32 len)
|
||||
{
|
||||
int curve_idx;
|
||||
#ifdef HAVE_OID_DECODING
|
||||
int ret;
|
||||
word16 decOid[MAX_OID_SZ];
|
||||
word32 decOidSz = sizeof(decOid);
|
||||
#endif
|
||||
|
||||
if (oid == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef HAVE_OID_DECODING
|
||||
ret = DecodeObjectId(oid, len, decOid, &decOidSz);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
|
||||
if (
|
||||
#ifndef WOLFSSL_ECC_CURVE_STATIC
|
||||
ecc_sets[curve_idx].oid &&
|
||||
#endif
|
||||
#ifdef HAVE_OID_DECODING
|
||||
/* We double because decOidSz is a count of word16 elements. */
|
||||
ecc_sets[curve_idx].oidSz == decOidSz &&
|
||||
XMEMCMP(ecc_sets[curve_idx].oid, decOid,
|
||||
decOidSz * 2) == 0
|
||||
#else
|
||||
ecc_sets[curve_idx].oidSz == len &&
|
||||
XMEMCMP(ecc_sets[curve_idx].oid, oid, len) == 0) {
|
||||
XMEMCMP(ecc_sets[curve_idx].oid, oid, len) == 0
|
||||
#endif
|
||||
) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1459,6 +1459,11 @@ typedef struct TrustedPeerCert TrustedPeerCert;
|
||||
typedef struct SignatureCtx SignatureCtx;
|
||||
typedef struct CertSignCtx CertSignCtx;
|
||||
|
||||
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ASN_TEMPLATE) \
|
||||
&& defined(HAVE_OID_DECODING)
|
||||
typedef int (*wc_UnknownExtCallback)(const word16* oid, word32 oidSz, int crit,
|
||||
const unsigned char* der, word32 derSz);
|
||||
#endif
|
||||
|
||||
struct DecodedCert {
|
||||
const byte* publicKey;
|
||||
@ -1689,6 +1694,10 @@ struct DecodedCert {
|
||||
#ifdef WOLFSSL_CERT_REQ
|
||||
byte isCSR : 1; /* Do we intend on parsing a CSR? */
|
||||
#endif
|
||||
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ASN_TEMPLATE) \
|
||||
&& defined(HAVE_OID_DECODING)
|
||||
wc_UnknownExtCallback unknownExtCallback;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef NO_SHA
|
||||
@ -1816,6 +1825,12 @@ WOLFSSL_ASN_API void FreeDecodedCert(DecodedCert* cert);
|
||||
WOLFSSL_ASN_API int ParseCert(DecodedCert* cert, int type, int verify,
|
||||
void* cm);
|
||||
|
||||
#if defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ASN_TEMPLATE) \
|
||||
&& defined(HAVE_OID_DECODING)
|
||||
WOLFSSL_ASN_API int wc_SetUnknownExtCallback(DecodedCert* cert,
|
||||
wc_UnknownExtCallback cb);
|
||||
#endif
|
||||
|
||||
WOLFSSL_LOCAL int DecodePolicyOID(char *out, word32 outSz, const byte *in,
|
||||
word32 inSz);
|
||||
WOLFSSL_LOCAL int EncodePolicyOID(byte *out, word32 *outSz,
|
||||
|
@ -322,6 +322,13 @@ typedef struct CertOidField {
|
||||
int valSz;
|
||||
char enc;
|
||||
} CertOidField;
|
||||
|
||||
typedef struct CertExtension {
|
||||
const char* oid;
|
||||
byte crit;
|
||||
const byte* val;
|
||||
int valSz;
|
||||
} CertExtension;
|
||||
#endif
|
||||
#endif /* WOLFSSL_CERT_GEN */
|
||||
|
||||
@ -369,6 +376,10 @@ typedef struct CertName {
|
||||
|
||||
#ifdef WOLFSSL_CERT_GEN
|
||||
|
||||
#ifndef NUM_CUSTOM_EXT
|
||||
#define NUM_CUSTOM_EXT 16
|
||||
#endif
|
||||
|
||||
/* for user to fill for certificate generation */
|
||||
typedef struct Cert {
|
||||
int version; /* x509 version */
|
||||
@ -432,9 +443,13 @@ typedef struct Cert {
|
||||
int challengePwPrintableString; /* encode as PrintableString */
|
||||
#endif
|
||||
#ifdef WOLFSSL_CUSTOM_OID
|
||||
CertOidField extCustom; /* user oid and value to go in req extensions */
|
||||
#endif
|
||||
/* user oid and value to go in req extensions */
|
||||
CertOidField extCustom;
|
||||
|
||||
/* Extensions to go into X.509 certificates */
|
||||
CertExtension customCertExt[NUM_CUSTOM_EXT];
|
||||
int customCertExtCount;
|
||||
#endif
|
||||
void* decodedCert; /* internal DecodedCert allocated from heap */
|
||||
byte* der; /* Pointer to buffer of current DecodedCert cache */
|
||||
void* heap; /* heap hint */
|
||||
@ -530,6 +545,13 @@ WOLFSSL_API int wc_SetExtKeyUsage(Cert *cert, const char *value);
|
||||
WOLFSSL_API int wc_SetExtKeyUsageOID(Cert *cert, const char *oid, word32 sz,
|
||||
byte idx, void* heap);
|
||||
#endif /* WOLFSSL_EKU_OID */
|
||||
|
||||
#if defined(WOLFSSL_ASN_TEMPLATE) && defined(WOLFSSL_CUSTOM_OID) && \
|
||||
defined(HAVE_OID_ENCODING)
|
||||
WOLFSSL_API int wc_SetCustomExtension(Cert *cert, int critical, const char *oid,
|
||||
const byte *der, word32 derSz);
|
||||
#endif
|
||||
|
||||
#endif /* WOLFSSL_CERT_EXT */
|
||||
#endif /* WOLFSSL_CERT_GEN */
|
||||
|
||||
|
Reference in New Issue
Block a user