Store in extensions the full octet string (#8967)

* Store in extensions the full octet string

Store in WOLFSSL_X509_EXTENSION.value always the full contents of the
OCTET STRING of the extension, instead of different type of data
depending on the type of extension. Previously this was only done for
unknown extensions.

* Avoid local variables in 'DecodeExtKeyUsageInternal'

There is a great performance loss on configs using 'WOLFSSL_NO_MALLOC',
'WOLFSSL_STATIC_MEMORY' and 'USE_FAST_MATH' if function
'DecodeExtKeyUsageInternal' uses intermediate variables. This can be
observed running the Zephyr test 'wolfssl_test/prj-no-malloc.conf'.

Avoid using intermediate variables, and use raw pointers to the final
destination instead.

* Add missing calls to 'FreeDecodedCert'

* Return error code from 'wolfSSL_ASN1_STRING_into_old_ext_fmt'

* Fix lines larger than 80

* Allow NULL parameters for 'DecodeAuthKeyId'

* Add comment explaining build option '--enable-old-extdata-fmt'

* Test full OCTET STRING in tests/api.c

* wolfSSL_X509V3_EXT_d2i: Honor 'WOLFSSL_SMALL_STACK'

* zephyr/wolfssl_test_no_malloc: Increase test timeout

* wolfSSL_X509V3_EXT_d2i: Extract repeated code into common part

* wolfcrypt: Remove 'WOLFSSL_LOCAL' from .c files

* wolfcrypt: Change location of functions to make diff easier
This commit is contained in:
Albert Ribes
2025-08-11 19:33:15 +02:00
committed by GitHub
parent 55f30adb3e
commit e36daf41a4
6 changed files with 852 additions and 386 deletions

View File

@@ -9806,6 +9806,20 @@ then
fi
fi
# Make function 'wolfSSL_X509_EXTENSION_get_data' return different type of
# data for each type of extension, as it used to do in the past, instead of
# always returning the full OCTET STRING of the extension. Use only if you
# need to keep compatibility with older versions.
AC_ARG_ENABLE([old-extdata-fmt],
[AS_HELP_STRING([--enable-old-extdata-fmt],[Enable old format for extracting extension data (default: disabled)])],
[ ENABLED_OLD_EXTDATA_FMT=$enableval ],
[ ENABLED_OLD_EXTDATA_FMT=no ]
)
if test "x$ENABLED_OLD_EXTDATA_FMT" = "xyes"; then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_OLD_EXTDATA_FMT"
fi
# determine if we have key validation mechanism
if test "x$ENABLED_ECC" != "xno" || test "x$ENABLED_RSA" = "xyes"
then

View File

@@ -680,15 +680,6 @@ static int wolfssl_x509_alt_names_to_gn(WOLFSSL_X509* x509,
DNS_entry* dns = NULL;
WOLFSSL_STACK* sk;
#ifdef OPENSSL_ALL
ret = wolfSSL_ASN1_STRING_set(&ext->value, x509->subjAltNameSrc,
x509->subjAltNameSz);
if (ret != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("ASN1_STRING_set() failed");
goto err;
}
#endif
sk = (WOLFSSL_GENERAL_NAMES*)XMALLOC(sizeof(WOLFSSL_GENERAL_NAMES), NULL,
DYNAMIC_TYPE_ASN1);
if (sk == NULL) {
@@ -746,8 +737,6 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc)
byte* oidBuf;
word32 oid, idx = 0, tmpIdx = 0, nid;
WOLFSSL_X509_EXTENSION* ext = NULL;
WOLFSSL_ASN1_INTEGER* a;
WOLFSSL_STACK* sk;
#ifdef WOLFSSL_SMALL_STACK
DecodedCert* cert = NULL;
#else
@@ -911,12 +900,14 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc)
switch (oid) {
case BASIC_CA_OID:
{
WOLFSSL_ASN1_INTEGER* a;
word32 dataIdx = idx;
word32 dummyOid;
int dataLen = 0;
if (!isSet)
break;
/* Set pathlength */
a = wolfSSL_ASN1_INTEGER_new();
@@ -954,10 +945,13 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc)
ext->obj->pathlen = a;
ext->obj->ca = x509->isCa;
ext->crit = x509->basicConstCrit;
break;
}
case AUTH_INFO_OID:
{
WOLFSSL_STACK* sk;
if (!isSet)
break;
@@ -1046,94 +1040,8 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc)
}
}
ext->ext_sk = sk;
ext->crit = x509->authInfoCrit;
break;
case AUTH_KEY_OID:
if (!isSet)
break;
ret = wolfSSL_ASN1_STRING_set(&ext->value, x509->authKeyId,
x509->authKeyIdSz);
if (ret != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("ASN1_STRING_set() failed");
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
#endif
return NULL;
}
ext->crit = x509->authKeyIdCrit;
break;
case SUBJ_KEY_OID:
if (!isSet)
break;
ret = wolfSSL_ASN1_STRING_set(&ext->value, x509->subjKeyId,
x509->subjKeyIdSz);
if (ret != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("ASN1_STRING_set() failed");
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
#endif
return NULL;
}
ext->crit = x509->subjKeyIdCrit;
break;
case CERT_POLICY_OID:
if (!isSet)
break;
#ifdef WOLFSSL_SEP
ext->crit = x509->certPolicyCrit;
#endif
break;
case KEY_USAGE_OID:
if (!isSet)
break;
ret = wolfSSL_ASN1_STRING_set(&ext->value,
(byte*)&(x509->keyUsage), sizeof(word16));
if (ret != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("ASN1_STRING_set() failed");
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
#endif
return NULL;
}
ext->crit = x509->keyUsageCrit;
break;
case EXT_KEY_USAGE_OID:
if (!isSet)
break;
ret = wolfSSL_ASN1_STRING_set(&ext->value, x509->extKeyUsageSrc,
x509->extKeyUsageSz);
if (ret != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("ASN1_STRING_set() failed");
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
#endif
return NULL;
}
ext->crit = x509->extKeyUsageCrit;
break;
case CRL_DIST_OID:
if (!isSet)
break;
ext->crit = x509->CRLdistCrit;
break;
}
case ALT_NAMES_OID:
if (!isSet)
@@ -1147,137 +1055,161 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc)
return NULL;
}
break;
}
default:
WOLFSSL_MSG("Unknown extension type found, parsing OID");
/* If the extension type is not recognized/supported,
* set the ASN1_OBJECT in the extension with the
* parsed oid for access in later function calls */
/* The ASN1_OBJECT in the extension is set in the same way
* for recognized and for unrecognized extension types, as
* the full OCTET STRING */
/* Get OID from input */
if (GetASNObjectId(input, &idx, &length, (word32)sz) != 0) {
WOLFSSL_MSG("Failed to Get ASN Object Id");
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
#endif
return NULL;
}
oidBuf = (byte*)XMALLOC(length+1+MAX_LENGTH_SZ, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
if (oidBuf == NULL) {
WOLFSSL_MSG("Failed to malloc tmp buffer");
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
#endif
return NULL;
}
oidBuf[0] = ASN_OBJECT_ID;
objSz++;
objSz += SetLength(length, oidBuf + 1);
objSz += length;
/* Get OID from input */
if (GetASNObjectId(input, &idx, &length, (word32)sz) != 0) {
WOLFSSL_MSG("Failed to Get ASN Object Id");
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
#endif
return NULL;
}
oidBuf = (byte*)XMALLOC(length+1+MAX_LENGTH_SZ, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
if (oidBuf == NULL) {
WOLFSSL_MSG("Failed to malloc tmp buffer");
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
#endif
return NULL;
}
oidBuf[0] = ASN_OBJECT_ID;
objSz++;
objSz += SetLength(length, oidBuf + 1);
objSz += length;
/* Set object size and reallocate space in object buffer */
if (ext->obj == NULL) {
ext->obj = wolfSSL_ASN1_OBJECT_new();
if (ext->obj == NULL) {
XFREE(oidBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
#endif
return NULL;
}
}
if (((ext->obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0) ||
(ext->obj->obj == NULL)) {
#ifdef WOLFSSL_NO_REALLOC
byte* tmp = NULL;
tmp = (byte*)XMALLOC(objSz, NULL, DYNAMIC_TYPE_ASN1);
if (tmp != NULL && ext->obj->obj != NULL) {
XMEMCPY(tmp, ext->obj->obj, ext->obj->objSz);
XFREE((byte*)ext->obj->obj, NULL, DYNAMIC_TYPE_ASN1);
}
else if (tmp == NULL) {
ext->obj->obj = tmp;
}
ext->obj->obj = tmp;
#else
ext->obj->obj = (byte*)XREALLOC((byte*)ext->obj->obj, objSz,
NULL, DYNAMIC_TYPE_ASN1);
#endif
if (ext->obj->obj == NULL) {
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(cert);
XFREE(oidBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
#endif
return NULL;
}
ext->obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
}
else {
ext->obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA;
}
ext->obj->objSz = (unsigned int)objSz;
/* Get OID from input and copy to ASN1_OBJECT buffer */
XMEMCPY(oidBuf+2, input+idx, length);
XMEMCPY((byte*)ext->obj->obj, oidBuf, ext->obj->objSz);
/* Set object size and reallocate space in object buffer */
if (ext->obj == NULL) {
ext->obj = wolfSSL_ASN1_OBJECT_new();
if (ext->obj == NULL) {
XFREE(oidBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
oidBuf = NULL;
ext->obj->grp = oidCertExtType;
ext->crit = 0;
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
#endif
return NULL;
}
}
/* Get extension data and copy as ASN1_STRING */
tmpIdx = idx + length;
if ((tmpIdx >= (word32)sz) ||
(input[tmpIdx] != ASN_OCTET_STRING))
{
WOLFSSL_MSG("Error decoding unknown extension data");
wolfSSL_ASN1_OBJECT_free(ext->obj);
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
#endif
return NULL;
}
if (((ext->obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0) ||
(ext->obj->obj == NULL)) {
#ifdef WOLFSSL_NO_REALLOC
byte* tmp = NULL;
tmpIdx++;
tmp = (byte*)XMALLOC(objSz, NULL, DYNAMIC_TYPE_ASN1);
if (tmp != NULL && ext->obj->obj != NULL) {
XMEMCPY(tmp, ext->obj->obj, ext->obj->objSz);
XFREE((byte*)ext->obj->obj, NULL, DYNAMIC_TYPE_ASN1);
}
else if (tmp == NULL) {
ext->obj->obj = tmp;
}
ext->obj->obj = tmp;
#else
ext->obj->obj = (byte*)XREALLOC((byte*)ext->obj->obj, objSz,
NULL, DYNAMIC_TYPE_ASN1);
#endif
if (ext->obj->obj == NULL) {
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(cert);
XFREE(oidBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
#endif
return NULL;
}
ext->obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
}
else {
ext->obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA;
}
ext->obj->objSz = (unsigned int)objSz;
if (GetLength(input, &tmpIdx, &length, (word32)sz) <= 0) {
WOLFSSL_MSG("Error: Invalid Input Length.");
wolfSSL_ASN1_OBJECT_free(ext->obj);
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
#endif
return NULL;
}
ext->value.data = (char*)XMALLOC(length, NULL,
DYNAMIC_TYPE_ASN1);
ext->value.isDynamic = 1;
if (ext->value.data == NULL) {
WOLFSSL_MSG("Failed to malloc ASN1_STRING data");
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
#endif
return NULL;
}
XMEMCPY(ext->value.data,input+tmpIdx,length);
ext->value.length = length;
} /* switch(oid) */
/* Get OID from input and copy to ASN1_OBJECT buffer */
XMEMCPY(oidBuf+2, input+idx, length);
XMEMCPY((byte*)ext->obj->obj, oidBuf, ext->obj->objSz);
XFREE(oidBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
oidBuf = NULL;
ext->obj->grp = oidCertExtType;
ext->crit = 0;
tmpIdx = idx + length;
/* Get CRITICAL. If not present, defaults to false.
* It present, must be a valid TRUE */
if ((tmpIdx < (word32)sz) &&
(input[tmpIdx] == ASN_BOOLEAN))
{
if (((tmpIdx + 2) >= (word32)sz) ||
/* Check bool length */
(input[tmpIdx+1] != 1) ||
/* Assert true if CRITICAL present */
(input[tmpIdx+2] != 0xff))
{
WOLFSSL_MSG("Error decoding unknown extension data");
wolfSSL_ASN1_OBJECT_free(ext->obj);
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
#endif
return NULL;
}
ext->crit = 1;
tmpIdx += 3;
}
/* Get extension data and copy as ASN1_STRING */
if ((tmpIdx >= (word32)sz) ||
(input[tmpIdx] != ASN_OCTET_STRING))
{
WOLFSSL_MSG("Error decoding unknown extension data");
wolfSSL_ASN1_OBJECT_free(ext->obj);
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
#endif
return NULL;
}
tmpIdx++;
if (GetLength(input, &tmpIdx, &length, (word32)sz) <= 0) {
WOLFSSL_MSG("Error: Invalid Input Length.");
wolfSSL_ASN1_OBJECT_free(ext->obj);
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
#endif
return NULL;
}
ext->value.data = (char*)XMALLOC(length, NULL,
DYNAMIC_TYPE_ASN1);
ext->value.isDynamic = 1;
if (ext->value.data == NULL) {
WOLFSSL_MSG("Failed to malloc ASN1_STRING data");
wolfSSL_X509_EXTENSION_free(ext);
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
#endif
return NULL;
}
XMEMCPY(ext->value.data,input+tmpIdx,length);
ext->value.length = length;
break; /* Got the Extension. Now exit while loop. */
@@ -1529,6 +1461,18 @@ int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext,
return WOLFSSL_SUCCESS;
}
/* Returns pointer to ASN1_STRING in X509_EXTENSION object */
static WOLFSSL_ASN1_STRING* wolfSSL_X509_EXTENSION_get_data_internal(
WOLFSSL_X509_EXTENSION* ext)
{
WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_data_internal");
if (ext == NULL)
return NULL;
return &ext->value;
}
#ifndef NO_BIO
/* Return 0 on success and 1 on failure. Copies ext data to bio, using indent
* to pad the output. flag is ignored. */
@@ -1555,7 +1499,7 @@ int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext,
return rc;
}
str = wolfSSL_X509_EXTENSION_get_data(ext);
str = wolfSSL_X509_EXTENSION_get_data_internal(ext);
if (str == NULL) {
WOLFSSL_MSG("Error getting ASN1_STRING from X509_EXTENSION");
return rc;
@@ -1620,7 +1564,8 @@ int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext,
asn1str = wolfSSL_i2s_ASN1_STRING(NULL, str);
tmpLen = XSNPRINTF(tmp, tmpSz, "%*s%s", indent, "", asn1str);
XFREE(asn1str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (tmpLen >= tmpSz) return rc;
if (tmpLen >= tmpSz)
tmpLen = tmpSz - 1;
break;
}
case AUTH_INFO_OID:
@@ -1963,8 +1908,14 @@ void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext)
WOLFSSL_ASN1_OBJECT* object;
WOLFSSL_BASIC_CONSTRAINTS* bc;
WOLFSSL_AUTHORITY_KEYID* akey;
WOLFSSL_ASN1_STRING* asn1String, *newString;
WOLFSSL_ASN1_STRING* asn1String = NULL, *newString = NULL;
WOLFSSL_STACK* sk;
void *data = NULL;
#ifdef WOLFSSL_SMALL_STACK
DecodedCert *cert;
#else
DecodedCert cert[1];
#endif
WOLFSSL_ENTER("wolfSSL_X509V3_EXT_d2i");
@@ -1985,6 +1936,35 @@ void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext)
return NULL;
}
#ifdef WOLFSSL_SMALL_STACK
cert = (DecodedCert *)XMALLOC(sizeof(*cert), NULL,
DYNAMIC_TYPE_X509_EXT);
if (cert == NULL) {
WOLFSSL_MSG("\tout of memory");
return NULL;
}
#endif
InitDecodedCert(cert, NULL, 0, NULL);
if ((object->type != WC_NID_basic_constraints) &&
(object->type != WC_NID_subject_alt_name) &&
(object->type != WC_NID_info_access)) {
asn1String = wolfSSL_X509_EXTENSION_get_data_internal(ext);
if (asn1String == NULL) {
WOLFSSL_MSG("X509_EXTENSION_get_data() failed");
goto out;
}
ret = DecodeExtensionType((const byte*)asn1String->data,
asn1String->length, object->type, (byte)ext->crit, cert, NULL);
if (ret != 0) {
WOLFSSL_MSG("DecodeExtensionType() failed");
goto out;
}
}
/* Return pointer to proper internal structure based on NID */
switch (object->type) {
/* basicConstraints */
@@ -1994,7 +1974,7 @@ void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext)
bc = wolfSSL_BASIC_CONSTRAINTS_new();
if (bc == NULL) {
WOLFSSL_MSG("Failed to malloc basic constraints");
return NULL;
break;
}
/* Copy pathlen and CA into BASIC_CONSTRAINTS from object */
bc->ca = object->ca;
@@ -2003,38 +1983,41 @@ void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext)
if (bc->pathlen == NULL) {
WOLFSSL_MSG("Failed to duplicate ASN1_INTEGER");
wolfSSL_BASIC_CONSTRAINTS_free(bc);
return NULL;
break;
}
}
else
bc->pathlen = NULL;
return bc;
data = bc;
break;
/* subjectKeyIdentifier */
case WC_NID_subject_key_identifier:
{
WOLFSSL_MSG("subjectKeyIdentifier");
asn1String = wolfSSL_X509_EXTENSION_get_data(ext);
if (asn1String == NULL) {
WOLFSSL_MSG("X509_EXTENSION_get_data() failed");
return NULL;
}
newString = wolfSSL_ASN1_STRING_new();
if (newString == NULL) {
WOLFSSL_MSG("Failed to malloc ASN1_STRING");
return NULL;
break;
}
ret = wolfSSL_ASN1_STRING_set(newString, asn1String->data,
asn1String->length);
ret = wolfSSL_ASN1_STRING_set(newString, cert->extSubjKeyId,
cert->extSubjKeyIdSz);
if (ret != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("ASN1_STRING_set() failed");
wolfSSL_ASN1_STRING_free(newString);
return NULL;
break;
};
newString->type = asn1String->type;
return newString;
data = newString;
break;
}
/* authorityKeyIdentifier */
case WC_NID_authority_key_identifier:
{
WOLFSSL_MSG("AuthorityKeyIdentifier");
akey = (WOLFSSL_AUTHORITY_KEYID*)
@@ -2042,7 +2025,7 @@ void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext)
DYNAMIC_TYPE_X509_EXT);
if (akey == NULL) {
WOLFSSL_MSG("Failed to malloc authority key id");
return NULL;
break;
}
XMEMSET(akey, 0, sizeof(WOLFSSL_AUTHORITY_KEYID));
@@ -2051,22 +2034,15 @@ void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext)
if (akey->keyid == NULL) {
WOLFSSL_MSG("ASN1_STRING_new() failed");
wolfSSL_AUTHORITY_KEYID_free(akey);
return NULL;
break;
}
asn1String = wolfSSL_X509_EXTENSION_get_data(ext);
if (asn1String == NULL) {
WOLFSSL_MSG("X509_EXTENSION_get_data() failed");
wolfSSL_AUTHORITY_KEYID_free(akey);
return NULL;
}
ret = wolfSSL_ASN1_STRING_set(akey->keyid, asn1String->data,
asn1String->length);
ret = wolfSSL_ASN1_STRING_set(akey->keyid, cert->extAuthKeyId,
cert->extAuthKeyIdSz);
if (ret != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("ASN1_STRING_set() failed");
wolfSSL_AUTHORITY_KEYID_free(akey);
return NULL;
break;
};
akey->keyid->type = asn1String->type;
@@ -2074,71 +2050,83 @@ void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext)
updated for future use */
akey->issuer = NULL;
akey->serial = NULL;
return akey;
data = akey;
break;
}
/* keyUsage */
case WC_NID_key_usage:
{
WOLFSSL_MSG("keyUsage");
/* This may need to be updated for future use. The i2v method for
keyUsage is not currently set. For now, return the ASN1_STRING
representation of KeyUsage bit string */
asn1String = wolfSSL_X509_EXTENSION_get_data(ext);
if (asn1String == NULL) {
WOLFSSL_MSG("X509_EXTENSION_get_data() failed");
return NULL;
}
newString = wolfSSL_ASN1_STRING_new();
if (newString == NULL) {
WOLFSSL_MSG("Failed to malloc ASN1_STRING");
return NULL;
break;
}
ret = wolfSSL_ASN1_STRING_set(newString, asn1String->data,
asn1String->length);
ret = wolfSSL_ASN1_STRING_set(newString, (byte*)&cert->extKeyUsage,
sizeof(word16));
if (ret != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("ASN1_STRING_set() failed");
wolfSSL_ASN1_STRING_free(newString);
return NULL;
break;
};
newString->type = asn1String->type;
return newString;
data = newString;
break;
}
/* extKeyUsage */
case WC_NID_ext_key_usage:
WOLFSSL_MSG("extKeyUsage not supported yet");
return NULL;
break;
/* certificatePolicies */
case WC_NID_certificate_policies:
WOLFSSL_MSG("certificatePolicies not supported yet");
return NULL;
break;
/* cRLDistributionPoints */
case WC_NID_crl_distribution_points:
WOLFSSL_MSG("cRLDistributionPoints not supported yet");
return NULL;
break;
case WC_NID_subject_alt_name:
if (ext->ext_sk == NULL) {
WOLFSSL_MSG("Subject alt name stack NULL");
return NULL;
break;
}
sk = wolfSSL_sk_dup(ext->ext_sk);
if (sk == NULL) {
WOLFSSL_MSG("Failed to duplicate subject alt names stack.");
return NULL;
break;
}
return sk;
data = sk;
break;
/* authorityInfoAccess */
case WC_NID_info_access:
WOLFSSL_MSG("AuthorityInfoAccess");
return wolfssl_x509v3_ext_aia_d2i(ext);
data = wolfssl_x509v3_ext_aia_d2i(ext);
break;
default:
WOLFSSL_MSG("Extension NID not in table, returning NULL");
break;
}
return NULL;
out:
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_X509_EXT);
#endif
return data;
}
/* Looks for the extension matching the passed in nid
@@ -3288,14 +3276,154 @@ int wolfSSL_X509_EXTENSION_set_object(WOLFSSL_X509_EXTENSION* ext,
}
#endif /* OPENSSL_ALL */
#ifdef WOLFSSL_OLD_EXTDATA_FMT
/*
* Replace the current string in 'asn1str', which is the full X.509
* extension octet string with some data specific for the extension
* type. The extension is the one given in 'oid'.
* Return 0 in case of success, or a negative error code.
*/
static int wolfSSL_ASN1_STRING_into_old_ext_fmt(WOLFSSL_ASN1_STRING *asn1str,
word32 oid)
{
switch (oid)
{
case AUTH_INFO_OID:
wolfSSL_ASN1_STRING_clear(asn1str);
asn1str->data = NULL;
asn1str->length = 0;
return 0;
case AUTH_KEY_OID:
{
int ret = 0;
const byte *extAuthKeyId = NULL;
word32 extAuthKeyIdSz = 0;
char *data = NULL;
ret = DecodeAuthKeyId((const byte *)asn1str->data, asn1str->length,
&extAuthKeyId, &extAuthKeyIdSz, NULL, NULL, NULL, NULL);
if (ret != 0)
return ret;
data = (char*)XMALLOC((size_t)(extAuthKeyIdSz), NULL,
DYNAMIC_TYPE_OPENSSL);
if (data == NULL)
return MEMORY_ERROR;
XMEMCPY(data, extAuthKeyId, (size_t)extAuthKeyIdSz);
wolfSSL_ASN1_STRING_set(asn1str, data, extAuthKeyIdSz);
XFREE(data, NULL, DYNAMIC_TYPE_OPENSSL);
return 0;
}
case SUBJ_KEY_OID:
{
int ret = 0;
const byte *extSubjKeyId = NULL;
word32 extSubjKeyIdSz = 0;
char *data = NULL;
ret = DecodeSubjKeyId((const byte *)asn1str->data, asn1str->length,
&extSubjKeyId, &extSubjKeyIdSz);
if (ret != 0)
return ret;
data = (char*)XMALLOC((size_t)(extSubjKeyIdSz), NULL,
DYNAMIC_TYPE_OPENSSL);
if (data == NULL)
return MEMORY_ERROR;
XMEMCPY(data, extSubjKeyId, (size_t)extSubjKeyIdSz);
wolfSSL_ASN1_STRING_set(asn1str, data, extSubjKeyIdSz);
XFREE(data, NULL, DYNAMIC_TYPE_OPENSSL);
return 0;
}
case CERT_POLICY_OID:
wolfSSL_ASN1_STRING_clear(asn1str);
asn1str->data = NULL;
asn1str->length = 0;
return 0;
case KEY_USAGE_OID:
{
int ret = 0;
word16 extKeyUsage = 0;
ret = DecodeKeyUsage((const byte *)asn1str->data, asn1str->length,
&extKeyUsage);
if (ret != 0)
return ret;
wolfSSL_ASN1_STRING_set(asn1str, (byte*)&extKeyUsage,
sizeof(extKeyUsage));
return 0;
}
case EXT_KEY_USAGE_OID:
{
int ret = 0;
const byte *extExtKeyUsageSrc = NULL;
word32 extExtKeyUsageSz = 0;
word32 extExtKeyUsageCount = 0;
byte extExtKeyUsage = 0;
byte extExtKeyUsageSsh = 0;
char *data = NULL;
ret = DecodeExtKeyUsage((const byte*)asn1str->data, asn1str->length,
&extExtKeyUsageSrc, &extExtKeyUsageSz, &extExtKeyUsageCount,
&extExtKeyUsage, &extExtKeyUsageSsh);
if (ret != 0)
return ret;
data = (char*)XMALLOC((size_t)(extExtKeyUsageSz), NULL,
DYNAMIC_TYPE_OPENSSL);
if (data == NULL)
return MEMORY_ERROR;
XMEMCPY(data, extExtKeyUsageSrc, (size_t)extExtKeyUsageSz);
wolfSSL_ASN1_STRING_set(asn1str, data, extExtKeyUsageSz);
XFREE(data, NULL, DYNAMIC_TYPE_OPENSSL);
return 0;
}
case CRL_DIST_OID:
wolfSSL_ASN1_STRING_clear(asn1str);
asn1str->data = NULL;
asn1str->length = 0;
return 0;
default:
/* Do nothing, it is already set */
return 0;
}
}
#endif /* WOLFSSL_OLD_EXTDATA_FMT */
/* Returns pointer to ASN1_STRING in X509_EXTENSION object */
WOLFSSL_ASN1_STRING* wolfSSL_X509_EXTENSION_get_data(
WOLFSSL_X509_EXTENSION* ext)
{
WOLFSSL_ENTER("wolfSSL_X509_EXTENSION_get_data");
if (ext == NULL)
return NULL;
return &ext->value;
WOLFSSL_ASN1_STRING *ret;
ret = wolfSSL_X509_EXTENSION_get_data_internal(ext);
#ifdef WOLFSSL_OLD_EXTDATA_FMT
if (ret)
{
int error;
error = wolfSSL_ASN1_STRING_into_old_ext_fmt (ret, ext->obj->type);
if (error != 0)
{
WOLFSSL_MSG("Error calling wolfSSL_ASN1_STRING_into_old_ext_fmt");
return NULL;
}
}
#endif
return ret;
}
@@ -3311,7 +3439,7 @@ int wolfSSL_X509_EXTENSION_set_data(WOLFSSL_X509_EXTENSION* ext,
if (ext == NULL || data == NULL)
return WOLFSSL_FAILURE;
current = wolfSSL_X509_EXTENSION_get_data(ext);
current = wolfSSL_X509_EXTENSION_get_data_internal(ext);
if (current->length > 0 && current->data != NULL && current->isDynamic) {
XFREE(current->data, NULL, DYNAMIC_TYPE_OPENSSL);
}

View File

@@ -33293,6 +33293,13 @@ static int test_wolfSSL_X509_EXTENSION_get_data(void)
WOLFSSL_X509_EXTENSION* ext = NULL;
WOLFSSL_ASN1_STRING* str = NULL;
XFILE file = XBADFILE;
#ifndef WOLFSSL_OLD_EXTDATA_FMT
const byte ext_data[] = {
0x04, 0x14, 0xB3, 0x11, 0x32, 0xC9, 0x92, 0x98,
0x84, 0xE2, 0xC9, 0xF8, 0xD0, 0x3B, 0x6E, 0x03,
0x42, 0xCA, 0x1F, 0x0E, 0x8E, 0x3C,
};
#endif
ExpectTrue((file = XFOPEN("./certs/server-cert.pem", "rb")) != XBADFILE);
ExpectNotNull(x509 = wolfSSL_PEM_read_X509(file, NULL, NULL, NULL));
@@ -33303,6 +33310,11 @@ static int test_wolfSSL_X509_EXTENSION_get_data(void)
ExpectNull(str = wolfSSL_X509_EXTENSION_get_data(NULL));
ExpectNotNull(str = wolfSSL_X509_EXTENSION_get_data(ext));
#ifndef WOLFSSL_OLD_EXTDATA_FMT
ExpectIntEQ(str->length, sizeof (ext_data));
ExpectBufEQ(str->data, ext_data, sizeof (ext_data));
#endif
wolfSSL_X509_free(x509);
#endif
return EXPECT_RESULT();

View File

@@ -20664,13 +20664,15 @@ enum {
#define basicConsASN_Length (sizeof(basicConsASN) / sizeof(ASNItem))
#endif
/* Decode basic constraints extension in a certificate.
/* Decode basic constraints extension
*
* X.509: RFC 5280, 4.2.1.9 - BasicConstraints.
*
* @param [in] input Buffer holding data.
* @param [in] sz Size of data in buffer.
* @param [in, out] cert Certificate object.
* @param [in] input Buffer holding data.
* @param [in] sz Size of data in buffer.
* @param [out] isCa Whether it is a CA.
* @param [out] pathLength CA path length.
* @param [out] pathLengthSet Whether pathLength is valid on return.
* @return 0 on success.
* @return MEMORY_E on dynamic memory allocation failure.
* @return ASN_PARSE_E when CA boolean is present and false (default is false).
@@ -20683,7 +20685,8 @@ enum {
* @return ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
* non-zero length.
*/
static int DecodeBasicCaConstraint(const byte* input, int sz, DecodedCert* cert)
int DecodeBasicCaConstraint(const byte* input, int sz, byte *isCa,
word16 *pathLength, byte *pathLengthSet)
{
#ifndef WOLFSSL_ASN_TEMPLATE
word32 idx = 0;
@@ -20713,7 +20716,7 @@ static int DecodeBasicCaConstraint(const byte* input, int sz, DecodedCert* cert)
ret = 0;
}
cert->isCA = ret ? 1 : 0;
*isCa = ret ? 1 : 0;
/* If there isn't any more data, return. */
if (idx >= (word32)sz) {
@@ -20728,24 +20731,24 @@ static int DecodeBasicCaConstraint(const byte* input, int sz, DecodedCert* cert)
return ASN_PATHLEN_SIZE_E;
}
cert->pathLength = (word16)ret;
cert->pathLengthSet = 1;
*pathLength = (word16)ret;
*pathLengthSet = 1;
return 0;
#else
DECL_ASNGETDATA(dataASN, basicConsASN_Length);
int ret = 0;
word32 idx = 0;
byte isCA = 0;
byte innerIsCA = 0;
WOLFSSL_ENTER("DecodeBasicCaConstraint");
CALLOC_ASNGETDATA(dataASN, basicConsASN_Length, ret, cert->heap);
CALLOC_ASNGETDATA(dataASN, basicConsASN_Length, ret, NULL);
if (ret == 0) {
/* Get the CA boolean and path length when present. */
GetASN_Boolean(&dataASN[BASICCONSASN_IDX_CA], &isCA);
GetASN_Int16Bit(&dataASN[BASICCONSASN_IDX_PLEN], &cert->pathLength);
GetASN_Boolean(&dataASN[BASICCONSASN_IDX_CA], &innerIsCA);
GetASN_Int16Bit(&dataASN[BASICCONSASN_IDX_PLEN], pathLength);
ret = GetASN_Items(basicConsASN, dataASN, basicConsASN_Length, 1, input,
&idx, (word32)sz);
@@ -20757,26 +20760,72 @@ static int DecodeBasicCaConstraint(const byte* input, int sz, DecodedCert* cert)
* (default when not present). */
#if !defined(ASN_TEMPLATE_SKIP_ISCA_CHECK) && \
!defined(WOLFSSL_ALLOW_ENCODING_CA_FALSE)
if ((dataASN[BASICCONSASN_IDX_CA].length != 0) && (!isCA)) {
if ((dataASN[BASICCONSASN_IDX_CA].length != 0) && (!innerIsCA)) {
WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
ret = ASN_PARSE_E;
}
#endif
if ((ret == 0) && cert->pathLength > WOLFSSL_MAX_PATH_LEN) {
/* Path length must be a 7-bit value. */
if ((ret == 0) && (*pathLength >= (1 << 7))) {
WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
ret = ASN_PARSE_E;
}
if ((ret == 0) && *pathLength > WOLFSSL_MAX_PATH_LEN) {
WOLFSSL_ERROR_VERBOSE(ASN_PATHLEN_SIZE_E);
ret = ASN_PATHLEN_SIZE_E;
}
/* Store CA boolean and whether a path length was seen. */
if (ret == 0) {
/* isCA in certificate is a 1 bit of a byte. */
cert->isCA = isCA ? 1 : 0;
cert->pathLengthSet = (dataASN[BASICCONSASN_IDX_PLEN].length > 0);
*isCa = innerIsCA ? 1 : 0;
*pathLengthSet = (dataASN[BASICCONSASN_IDX_PLEN].length > 0);
}
}
FREE_ASNGETDATA(dataASN, cert->heap);
FREE_ASNGETDATA(dataASN, NULL);
return ret;
#endif
}
/* Decode basic constraints extension in a certificate.
*
* X.509: RFC 5280, 4.2.1.9 - BasicConstraints.
*
* @param [in] input Buffer holding data.
* @param [in] sz Size of data in buffer.
* @param [in, out] cert Certificate object.
* @return 0 on success.
* @return MEMORY_E on dynamic memory allocation failure.
* @return ASN_PARSE_E when CA boolean is present and false (default is false).
* @return ASN_PARSE_E when CA boolean is not present unless
* WOLFSSL_X509_BASICCONS_INT is defined. Only a CA extension.
* @return ASN_PARSE_E when path length more than 7 bits.
* @return ASN_PARSE_E when BER encoded data does not match ASN.1 items or
* is invalid.
* @return BUFFER_E when data in buffer is too small.
* @return ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
* non-zero length.
*/
static int DecodeBasicCaConstraintInternal(const byte* input, int sz,
DecodedCert* cert)
{
int ret;
byte isCa = 0;
word16 pathLength = 0;
byte pathLengthSet = 0;
ret = DecodeBasicCaConstraint(input, sz, &isCa, &pathLength,
&pathLengthSet);
if (ret != 0)
return ret;
cert->isCA = isCa ? 1 : 0;
if (pathLengthSet) {
cert->pathLength = pathLength;
cert->pathLengthSet = pathLengthSet ? 1 : 0;
}
return 0;
}
@@ -21210,20 +21259,34 @@ enum {
#define authKeyIdASN_Length (sizeof(authKeyIdASN) / sizeof(ASNItem))
#endif
/* Decode authority key identifier extension in a certificate.
/* Decode authority key identifier extension.
*
* X.509: RFC 5280, 4.2.1.1 - Authority Key Identifier.
*
* @param [in] input Buffer holding data.
* @param [in] sz Size of data in buffer.
* @param [in, out] cert Certificate object.
* @param [in] input Buffer holding data.
* @param [in] sz Size of data in buffer.
* @param [out] extAuthKeyId Beginning of the ID. NULL if not
* present.
* @param [out] extAuthKeyIdSz Size of data in extAuthKeyId. 0 if not
* present.
* @param [out] extAuthKeyIdIssuer Beginning of the Issuer. NULL if not
* present.
* @param [out] extAuthKeyIdIssuerSz Size of data in extAuthKeyIdIssuer. 0
* if not present.
* @param [out] extAuthKeyIdIssuerSN Beginning of the Issuer Serial. NULL
* if not present.
* @param [out] extAuthKeyIdIssuerSNSz Size of data in extAuthKeyIdIssuerSN.
* 0 if not present.
* @return 0 on success.
* @return MEMORY_E on dynamic memory allocation failure.
* @return ASN_PARSE_E when BER encoded data does not match ASN.1 items or
* is invalid.
* @return BUFFER_E when data in buffer is too small.
*/
static int DecodeAuthKeyId(const byte* input, word32 sz, DecodedCert* cert)
int DecodeAuthKeyId(const byte* input, word32 sz, const byte **extAuthKeyId,
word32 *extAuthKeyIdSz, const byte **extAuthKeyIdIssuer,
word32 *extAuthKeyIdIssuerSz, const byte **extAuthKeyIdIssuerSN,
word32 *extAuthKeyIdIssuerSNSz)
{
#ifndef WOLFSSL_ASN_TEMPLATE
word32 idx = 0;
@@ -21232,6 +21295,21 @@ static int DecodeAuthKeyId(const byte* input, word32 sz, DecodedCert* cert)
WOLFSSL_ENTER("DecodeAuthKeyId");
if (extAuthKeyId)
*extAuthKeyId = NULL;
if (extAuthKeyIdSz)
*extAuthKeyIdSz = 0;
if (extAuthKeyIdIssuer)
*extAuthKeyIdIssuer = NULL;
if (extAuthKeyIdIssuerSz)
*extAuthKeyIdIssuerSz = 0;
if (extAuthKeyIdIssuerSN)
*extAuthKeyIdIssuerSN = NULL;
if (extAuthKeyIdIssuerSNSz)
*extAuthKeyIdIssuerSNSz = 0;
if (GetSequence(input, &idx, &length, sz) < 0) {
WOLFSSL_MSG("\tfail: should be a SEQUENCE");
return ASN_PARSE_E;
@@ -21243,7 +21321,6 @@ static int DecodeAuthKeyId(const byte* input, word32 sz, DecodedCert* cert)
if (tag != (ASN_CONTEXT_SPECIFIC | 0)) {
WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available");
cert->extAuthKeyIdSet = 0;
return 0;
}
@@ -21252,25 +21329,34 @@ static int DecodeAuthKeyId(const byte* input, word32 sz, DecodedCert* cert)
return ASN_PARSE_E;
}
cert->extAuthKeyIdSz = length;
if (extAuthKeyIdSz)
*extAuthKeyIdSz = length;
if (extAuthKeyId)
*extAuthKeyId = &input[idx];
return 0;
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
#ifdef WOLFSSL_AKID_NAME
cert->extRawAuthKeyIdSrc = input;
cert->extRawAuthKeyIdSz = sz;
#endif
cert->extAuthKeyIdSrc = &input[idx];
#endif /* OPENSSL_EXTRA */
return GetHashId(input + idx, length, cert->extAuthKeyId,
HashIdAlg(cert->signatureOID));
#else
DECL_ASNGETDATA(dataASN, authKeyIdASN_Length);
int ret = 0;
WOLFSSL_ENTER("DecodeAuthKeyId");
CALLOC_ASNGETDATA(dataASN, authKeyIdASN_Length, ret, cert->heap);
if (extAuthKeyId)
*extAuthKeyId = NULL;
if (extAuthKeyIdSz)
*extAuthKeyIdSz = 0;
if (extAuthKeyIdIssuer)
*extAuthKeyIdIssuer = NULL;
if (extAuthKeyIdIssuerSz)
*extAuthKeyIdIssuerSz = 0;
if (extAuthKeyIdIssuerSN)
*extAuthKeyIdIssuerSN = NULL;
if (extAuthKeyIdIssuerSNSz)
*extAuthKeyIdIssuerSNSz = 0;
CALLOC_ASNGETDATA(dataASN, authKeyIdASN_Length, ret, NULL);
if (ret == 0) {
/* Parse an authority key identifier. */
@@ -21279,15 +21365,10 @@ static int DecodeAuthKeyId(const byte* input, word32 sz, DecodedCert* cert)
&idx, sz);
}
/* Each field is optional */
if (ret == 0 && dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data != NULL) {
#ifdef OPENSSL_EXTRA
if (ret == 0 && extAuthKeyId && extAuthKeyIdSz &&
dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data != NULL) {
GetASN_GetConstRef(&dataASN[AUTHKEYIDASN_IDX_KEYID],
&cert->extAuthKeyIdSrc, &cert->extAuthKeyIdSz);
#endif /* OPENSSL_EXTRA */
/* Get the hash or hash of the hash if wrong size. */
ret = GetHashId(dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data,
(int)dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.length,
cert->extAuthKeyId, HashIdAlg(cert->signatureOID));
extAuthKeyId, extAuthKeyIdSz);
}
#ifdef WOLFSSL_AKID_NAME
if (ret == 0 && dataASN[AUTHKEYIDASN_IDX_ISSUER].data.ref.data != NULL) {
@@ -21303,23 +21384,103 @@ static int DecodeAuthKeyId(const byte* input, word32 sz, DecodedCert* cert)
dataASN[AUTHKEYIDASN_IDX_ISSUER].data.ref.data, &idx,
dataASN[AUTHKEYIDASN_IDX_ISSUER].data.ref.length);
if (ret == 0) {
if (ret == 0 && extAuthKeyIdIssuer && extAuthKeyIdIssuerSz) {
GetASN_GetConstRef(&nameASN[ALTNAMEASN_IDX_GN],
&cert->extAuthKeyIdIssuer, &cert->extAuthKeyIdIssuerSz);
extAuthKeyIdIssuer, extAuthKeyIdIssuerSz);
}
}
if (ret == 0 && dataASN[AUTHKEYIDASN_IDX_SERIAL].data.ref.data != NULL) {
if (ret == 0 && extAuthKeyIdIssuerSN && extAuthKeyIdIssuerSNSz &&
dataASN[AUTHKEYIDASN_IDX_SERIAL].data.ref.data != NULL) {
GetASN_GetConstRef(&dataASN[AUTHKEYIDASN_IDX_SERIAL],
&cert->extAuthKeyIdIssuerSN, &cert->extAuthKeyIdIssuerSNSz);
extAuthKeyIdIssuerSN, extAuthKeyIdIssuerSNSz);
}
if (ret == 0) {
if ((cert->extAuthKeyIdIssuerSz > 0) ^
(cert->extAuthKeyIdIssuerSNSz > 0)) {
if (ret == 0 && extAuthKeyIdIssuerSz && extAuthKeyIdIssuerSNSz) {
if ((*extAuthKeyIdIssuerSz > 0) ^
(*extAuthKeyIdIssuerSNSz > 0)) {
WOLFSSL_MSG("authorityCertIssuer and authorityCertSerialNumber MUST"
" both be present or both be absent");
}
}
#endif /* WOLFSSL_AKID_NAME */
FREE_ASNGETDATA(dataASN, NULL);
return ret;
#endif /* WOLFSSL_ASN_TEMPLATE */
}
/* Decode authority key identifier extension in a certificate.
*
* X.509: RFC 5280, 4.2.1.1 - Authority Key Identifier.
*
* @param [in] input Buffer holding data.
* @param [in] sz Size of data in buffer.
* @param [in, out] cert Certificate object.
* @return 0 on success.
* @return MEMORY_E on dynamic memory allocation failure.
* @return ASN_PARSE_E when BER encoded data does not match ASN.1 items or
* is invalid.
* @return BUFFER_E when data in buffer is too small.
*/
static int DecodeAuthKeyIdInternal(const byte* input, word32 sz,
DecodedCert* cert)
{
int ret;
const byte *extAuthKeyId = NULL;
word32 extAuthKeyIdSz = 0;
const byte *extAuthKeyIdIssuer = NULL;
word32 extAuthKeyIdIssuerSz = 0;
const byte *extAuthKeyIdIssuerSN = NULL;
word32 extAuthKeyIdIssuerSNSz = 0;
ret = DecodeAuthKeyId(input, sz, &extAuthKeyId, &extAuthKeyIdSz,
&extAuthKeyIdIssuer, &extAuthKeyIdIssuerSz, &extAuthKeyIdIssuerSN,
&extAuthKeyIdIssuerSNSz);
if (ret != 0)
return ret;
#ifndef WOLFSSL_ASN_TEMPLATE
if (extAuthKeyIdSz == 0)
{
cert->extAuthKeyIdSet = 0;
return 0;
}
cert->extAuthKeyIdSz = extAuthKeyIdSz;
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
#ifdef WOLFSSL_AKID_NAME
cert->extRawAuthKeyIdSrc = input;
cert->extRawAuthKeyIdSz = sz;
#endif
cert->extAuthKeyIdSrc = extAuthKeyId;
#endif /* OPENSSL_EXTRA */
return GetHashId(extAuthKeyId, extAuthKeyIdSz, cert->extAuthKeyId,
HashIdAlg(cert->signatureOID));
#else
/* Each field is optional */
if (extAuthKeyIdSz > 0) {
#ifdef OPENSSL_EXTRA
cert->extAuthKeyIdSrc = extAuthKeyId;
cert->extAuthKeyIdSz = extAuthKeyIdSz;
#endif /* OPENSSL_EXTRA */
/* Get the hash or hash of the hash if wrong size. */
ret = GetHashId(extAuthKeyId, (int)extAuthKeyIdSz, cert->extAuthKeyId,
HashIdAlg(cert->signatureOID));
}
#ifdef WOLFSSL_AKID_NAME
if (ret == 0 && extAuthKeyIdIssuerSz > 0) {
cert->extAuthKeyIdIssuer = extAuthKeyIdIssuer;
cert->extAuthKeyIdIssuerSz = extAuthKeyIdIssuerSz;
}
if (ret == 0 && extAuthKeyIdIssuerSNSz > 0) {
cert->extAuthKeyIdIssuerSN = extAuthKeyIdIssuerSN;
cert->extAuthKeyIdIssuerSNSz = extAuthKeyIdIssuerSNSz;
}
#endif /* WOLFSSL_AKID_NAME */
if (ret == 0) {
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_AKID_NAME)
/* Store the raw authority key id. */
@@ -21328,11 +21489,41 @@ static int DecodeAuthKeyId(const byte* input, word32 sz, DecodedCert* cert)
#endif /* OPENSSL_EXTRA */
}
FREE_ASNGETDATA(dataASN, cert->heap);
return ret;
#endif /* WOLFSSL_ASN_TEMPLATE */
}
/* Decode subject key id extension.
*
* X.509: RFC 5280, 4.2.1.2 - Subject Key Identifier.
*
* @param [in] input Buffer holding data.
* @param [in] sz Size of data in buffer.
* @param [out] extSubjKeyId Beginning of the ID.
* @param [out] extSubjKeyIdSz Size of data in extSubjKeyId.
* @return 0 on success.
* @return ASN_PARSE_E when the OCTET_STRING tag is not found or length is
* invalid.
* @return MEMORY_E on dynamic memory allocation failure.
*/
int DecodeSubjKeyId(const byte* input, word32 sz, const byte **extSubjKeyId,
word32 *extSubjKeyIdSz)
{
word32 idx = 0;
int length = 0;
int ret = 0;
WOLFSSL_ENTER("DecodeSubjKeyId");
ret = GetOctetString(input, &idx, &length, sz);
if (ret < 0)
return ret;
*extSubjKeyIdSz = (word32)length;
*extSubjKeyId = &input[idx];
return 0;
}
/* Decode subject key id extension in a certificate.
*
* X.509: RFC 5280, 4.2.1.2 - Subject Key Identifier.
@@ -21345,25 +21536,26 @@ static int DecodeAuthKeyId(const byte* input, word32 sz, DecodedCert* cert)
* invalid.
* @return MEMORY_E on dynamic memory allocation failure.
*/
static int DecodeSubjKeyId(const byte* input, word32 sz, DecodedCert* cert)
static int DecodeSubjKeyIdInternal(const byte* input, word32 sz,
DecodedCert* cert)
{
word32 idx = 0;
int length = 0;
int ret = 0;
const byte *extSubjKeyId = NULL;
word32 extSubjKeyIdSz = 0;
WOLFSSL_ENTER("DecodeSubjKeyId");
ret = DecodeSubjKeyId(input, sz, &extSubjKeyId, &extSubjKeyIdSz);
if (ret != 0)
return ret;
ret = GetOctetString(input, &idx, &length, sz);
if (ret > 0) {
cert->extSubjKeyIdSz = (word32)length;
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
cert->extSubjKeyIdSrc = &input[idx];
#endif /* OPENSSL_EXTRA */
cert->extSubjKeyIdSz = extSubjKeyIdSz;
/* Get the hash or hash of the hash if wrong size. */
ret = GetHashId(input + idx, length, cert->extSubjKeyId,
HashIdAlg(cert->signatureOID));
}
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
cert->extSubjKeyIdSrc = extSubjKeyId;
#endif /* OPENSSL_EXTRA */
/* Get the hash or hash of the hash if wrong size. */
ret = GetHashId(extSubjKeyId, (int)extSubjKeyIdSz, cert->extSubjKeyId,
HashIdAlg(cert->signatureOID));
return ret;
}
@@ -21387,16 +21579,16 @@ enum {
*
* X.509: RFC 5280, 4.2.1.3 - Key Usage.
*
* @param [in] input Buffer holding data.
* @param [in] sz Size of data in buffer.
* @param [in, out] cert Certificate object.
* @param [in] input Buffer holding data.
* @param [in] sz Size of data in buffer.
* @param [out] extKeyUsage Key usage bitfield.
* @return 0 on success.
* @return ASN_BITSTR_E when the expected BIT_STRING tag is not found.
* @return ASN_PARSE_E when BER encoded data does not match ASN.1 items or
* is invalid.
* @return MEMORY_E on dynamic memory allocation failure.
*/
static int DecodeKeyUsage(const byte* input, word32 sz, DecodedCert* cert)
int DecodeKeyUsage(const byte* input, word32 sz, word16 *extKeyUsage)
{
#ifndef WOLFSSL_ASN_TEMPLATE
word32 idx = 0;
@@ -21411,9 +21603,9 @@ static int DecodeKeyUsage(const byte* input, word32 sz, DecodedCert* cert)
if (length == 0 || length > 2)
return ASN_PARSE_E;
cert->extKeyUsage = (word16)(input[idx]);
*extKeyUsage = (word16)(input[idx]);
if (length == 2)
cert->extKeyUsage |= (word16)(input[idx+1] << 8);
*extKeyUsage |= (word16)(input[idx+1] << 8);
return 0;
#else
@@ -21433,14 +21625,33 @@ static int DecodeKeyUsage(const byte* input, word32 sz, DecodedCert* cert)
&idx, sz);
if (ret == 0) {
/* Decode the bit string number as LE */
cert->extKeyUsage = (word16)(keyUsage[0]);
*extKeyUsage = (word16)(keyUsage[0]);
if (keyUsageSz == 2)
cert->extKeyUsage |= (word16)(keyUsage[1] << 8);
*extKeyUsage |= (word16)(keyUsage[1] << 8);
}
return ret;
#endif /* WOLFSSL_ASN_TEMPLATE */
}
/* Decode key usage extension in a certificate.
*
* X.509: RFC 5280, 4.2.1.3 - Key Usage.
*
* @param [in] input Buffer holding data.
* @param [in] sz Size of data in buffer.
* @param [in, out] cert Certificate object.
* @return 0 on success.
* @return ASN_BITSTR_E when the expected BIT_STRING tag is not found.
* @return ASN_PARSE_E when BER encoded data does not match ASN.1 items or
* is invalid.
* @return MEMORY_E on dynamic memory allocation failure.
*/
static int DecodeKeyUsageInternal(const byte* input, word32 sz,
DecodedCert* cert)
{
return DecodeKeyUsage(input, sz, &cert->extKeyUsage);
}
#ifdef WOLFSSL_ASN_TEMPLATE
/* ASN.1 template for KeyPurposeId.
* X.509: RFC 5280, 4.2.1.12 - Extended Key Usage.
@@ -21456,20 +21667,27 @@ enum {
#define keyPurposeIdASN_Length (sizeof(keyPurposeIdASN) / sizeof(ASNItem))
#endif
/* Decode extended key usage extension in a certificate.
/* Decode extended key usage extension.
*
* X.509: RFC 5280, 4.2.1.12 - Extended Key Usage.
*
* @param [in] input Buffer holding data.
* @param [in] sz Size of data in buffer.
* @param [in, out] cert Certificate object.
* @param [in] input Buffer holding data.
* @param [in] sz Size of data in buffer.
* @param [out] extExtKeyUsageSrc Beginning of the OIDs.
* @param [out] extExtKeyUsageSz Size of data in extExtKeyUsageSrc.
* @param [out] extExtKeyUsageCount Number of usages read.
* @param [out] extExtKeyUsage Usages read.
* @param [out] extExtKeyUsageSsh SSH usages read.
* @return 0 on success.
* @return ASN_BITSTR_E when the expected BIT_STRING tag is not found.
* @return ASN_PARSE_E when BER encoded data does not match ASN.1 items or
* is invalid.
* @return MEMORY_E on dynamic memory allocation failure.
*/
static int DecodeExtKeyUsage(const byte* input, word32 sz, DecodedCert* cert)
int DecodeExtKeyUsage(const byte* input, word32 sz,
const byte **extExtKeyUsageSrc, word32 *extExtKeyUsageSz,
word32 *extExtKeyUsageCount, byte *extExtKeyUsage,
byte *extExtKeyUsageSsh)
{
#ifndef WOLFSSL_ASN_TEMPLATE
word32 idx = 0, oid;
@@ -21477,14 +21695,29 @@ static int DecodeExtKeyUsage(const byte* input, word32 sz, DecodedCert* cert)
WOLFSSL_ENTER("DecodeExtKeyUsage");
(void) extExtKeyUsageSrc;
(void) extExtKeyUsageSz;
(void) extExtKeyUsageCount;
(void) extExtKeyUsageSsh;
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
*extExtKeyUsageSrc = NULL;
*extExtKeyUsageSz = 0;
*extExtKeyUsageCount = 0;
#endif
*extExtKeyUsage = 0;
#ifdef WOLFSSL_WOLFSSH
*extExtKeyUsageSsh = 0;
#endif
if (GetSequence(input, &idx, &length, sz) < 0) {
WOLFSSL_MSG("\tfail: should be a SEQUENCE");
return ASN_PARSE_E;
}
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
cert->extExtKeyUsageSrc = input + idx;
cert->extExtKeyUsageSz = length;
*extExtKeyUsageSrc = input + idx;
*extExtKeyUsageSz = length;
#endif
while (idx < (word32)sz) {
@@ -21496,35 +21729,35 @@ static int DecodeExtKeyUsage(const byte* input, word32 sz, DecodedCert* cert)
switch (oid) {
case EKU_ANY_OID:
cert->extExtKeyUsage |= EXTKEYUSE_ANY;
*extExtKeyUsage |= EXTKEYUSE_ANY;
break;
case EKU_SERVER_AUTH_OID:
cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
*extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
break;
case EKU_CLIENT_AUTH_OID:
cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
*extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
break;
case EKU_CODESIGNING_OID:
cert->extExtKeyUsage |= EXTKEYUSE_CODESIGN;
*extExtKeyUsage |= EXTKEYUSE_CODESIGN;
break;
case EKU_EMAILPROTECT_OID:
cert->extExtKeyUsage |= EXTKEYUSE_EMAILPROT;
*extExtKeyUsage |= EXTKEYUSE_EMAILPROT;
break;
case EKU_TIMESTAMP_OID:
cert->extExtKeyUsage |= EXTKEYUSE_TIMESTAMP;
*extExtKeyUsage |= EXTKEYUSE_TIMESTAMP;
break;
case EKU_OCSP_SIGN_OID:
cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
*extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
break;
#ifdef WOLFSSL_WOLFSSH
case EKU_SSH_CLIENT_AUTH_OID:
cert->extExtKeyUsageSsh |= EXTKEYUSE_SSH_CLIENT_AUTH;
*extExtKeyUsageSsh |= EXTKEYUSE_SSH_CLIENT_AUTH;
break;
case EKU_SSH_MSCL_OID:
cert->extExtKeyUsageSsh |= EXTKEYUSE_SSH_MSCL;
*extExtKeyUsageSsh |= EXTKEYUSE_SSH_MSCL;
break;
case EKU_SSH_KP_CLIENT_AUTH_OID:
cert->extExtKeyUsageSsh |= EXTKEYUSE_SSH_KP_CLIENT_AUTH;
*extExtKeyUsageSsh |= EXTKEYUSE_SSH_KP_CLIENT_AUTH;
break;
#endif /* WOLFSSL_WOLFSSH */
default:
@@ -21532,7 +21765,7 @@ static int DecodeExtKeyUsage(const byte* input, word32 sz, DecodedCert* cert)
}
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
cert->extExtKeyUsageCount++;
(*extExtKeyUsageCount)++;
#endif
}
@@ -21544,6 +21777,21 @@ static int DecodeExtKeyUsage(const byte* input, word32 sz, DecodedCert* cert)
WOLFSSL_ENTER("DecodeExtKeyUsage");
(void) extExtKeyUsageSrc;
(void) extExtKeyUsageSz;
(void) extExtKeyUsageCount;
(void) extExtKeyUsageSsh;
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
*extExtKeyUsageSrc = NULL;
*extExtKeyUsageSz = 0;
*extExtKeyUsageCount = 0;
#endif
*extExtKeyUsage = 0;
#ifdef WOLFSSL_WOLFSSH
*extExtKeyUsageSsh = 0;
#endif
/* Strip SEQUENCE OF and expect to account for all the data. */
if (GetASN_Sequence(input, &idx, &length, sz, 1) < 0) {
WOLFSSL_MSG("\tfail: should be a SEQUENCE");
@@ -21553,8 +21801,8 @@ static int DecodeExtKeyUsage(const byte* input, word32 sz, DecodedCert* cert)
if (ret == 0) {
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
/* Keep reference for WOLFSSL_X509. */
cert->extExtKeyUsageSrc = input + idx;
cert->extExtKeyUsageSz = (word32)length;
*extExtKeyUsageSrc = input + idx;
*extExtKeyUsageSz = (word32)length;
#endif
}
@@ -21576,31 +21824,31 @@ static int DecodeExtKeyUsage(const byte* input, word32 sz, DecodedCert* cert)
/* Store the bit for the OID. */
switch (dataASN[KEYPURPOSEIDASN_IDX_OID].data.oid.sum) {
case EKU_ANY_OID:
cert->extExtKeyUsage |= EXTKEYUSE_ANY;
*extExtKeyUsage |= EXTKEYUSE_ANY;
break;
case EKU_SERVER_AUTH_OID:
cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
*extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
break;
case EKU_CLIENT_AUTH_OID:
cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
*extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
break;
case EKU_CODESIGNING_OID:
cert->extExtKeyUsage |= EXTKEYUSE_CODESIGN;
*extExtKeyUsage |= EXTKEYUSE_CODESIGN;
break;
case EKU_EMAILPROTECT_OID:
cert->extExtKeyUsage |= EXTKEYUSE_EMAILPROT;
*extExtKeyUsage |= EXTKEYUSE_EMAILPROT;
break;
case EKU_TIMESTAMP_OID:
cert->extExtKeyUsage |= EXTKEYUSE_TIMESTAMP;
*extExtKeyUsage |= EXTKEYUSE_TIMESTAMP;
break;
case EKU_OCSP_SIGN_OID:
cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
*extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
break;
}
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
/* Keep count for WOLFSSL_X509. */
cert->extExtKeyUsageCount++;
(*extExtKeyUsageCount)++;
#endif
}
}
@@ -21609,6 +21857,46 @@ static int DecodeExtKeyUsage(const byte* input, word32 sz, DecodedCert* cert)
#endif /* WOLFSSL_ASN_TEMPLATE */
}
/* Decode extended key usage extension in a certificate.
*
* X.509: RFC 5280, 4.2.1.12 - Extended Key Usage.
*
* @param [in] input Buffer holding data.
* @param [in] sz Size of data in buffer.
* @param [in, out] cert Certificate object.
* @return 0 on success.
* @return ASN_BITSTR_E when the expected BIT_STRING tag is not found.
* @return ASN_PARSE_E when BER encoded data does not match ASN.1 items or
* is invalid.
* @return MEMORY_E on dynamic memory allocation failure.
*/
static int DecodeExtKeyUsageInternal(const byte* input, word32 sz,
DecodedCert* cert)
{
int ret = 0;
ret = DecodeExtKeyUsage(input, sz,
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
&cert->extExtKeyUsageSrc, &cert->extExtKeyUsageSz,
&cert->extExtKeyUsageCount,
#else
NULL, NULL, NULL,
#endif
&cert->extExtKeyUsage,
#ifdef WOLFSSL_WOLFSSH
&cert->extExtKeyUsageSsh
#else
NULL
#endif
);
if (ret != 0)
return ret;
return 0;
}
#ifndef IGNORE_NETSCAPE_CERT_TYPE
static int DecodeNsCertType(const byte* input, int sz, DecodedCert* cert)
@@ -22718,9 +23006,8 @@ static int DecodeAltSigVal(const byte* input, int sz, DecodedCert* cert)
* @return MEMORY_E on dynamic memory allocation failure.
* @return Other negative values on error.
*/
static int DecodeExtensionType(const byte* input, word32 length, word32 oid,
byte critical, DecodedCert* cert,
int *isUnknownExt)
int DecodeExtensionType(const byte* input, word32 length, word32 oid,
byte critical, DecodedCert* cert, int *isUnknownExt)
{
int ret = 0;
word32 idx = 0;
@@ -22733,7 +23020,7 @@ static int DecodeExtensionType(const byte* input, word32 length, word32 oid,
case BASIC_CA_OID:
VERIFY_AND_SET_OID(cert->extBasicConstSet);
cert->extBasicConstCrit = critical ? 1 : 0;
if (DecodeBasicCaConstraint(input, (int)length, cert) < 0) {
if (DecodeBasicCaConstraintInternal(input, (int)length, cert) < 0) {
ret = ASN_PARSE_E;
}
break;
@@ -22790,7 +23077,8 @@ static int DecodeExtensionType(const byte* input, word32 length, word32 oid,
ret = ASN_CRIT_EXT_E;
}
#endif
if ((ret == 0) && (DecodeAuthKeyId(input, length, cert) < 0)) {
if ((ret == 0) &&
(DecodeAuthKeyIdInternal(input, length, cert) < 0)) {
ret = ASN_PARSE_E;
}
break;
@@ -22811,7 +23099,8 @@ static int DecodeExtensionType(const byte* input, word32 length, word32 oid,
}
#endif
if ((ret == 0) && (DecodeSubjKeyId(input, length, cert) < 0)) {
if ((ret == 0) &&
(DecodeSubjKeyIdInternal(input, length, cert) < 0)) {
ret = ASN_PARSE_E;
}
break;
@@ -22841,7 +23130,7 @@ static int DecodeExtensionType(const byte* input, word32 length, word32 oid,
case KEY_USAGE_OID:
VERIFY_AND_SET_OID(cert->extKeyUsageSet);
cert->extKeyUsageCrit = critical ? 1 : 0;
if (DecodeKeyUsage(input, length, cert) < 0) {
if (DecodeKeyUsageInternal(input, length, cert) < 0) {
ret = ASN_PARSE_E;
}
break;
@@ -22850,7 +23139,7 @@ static int DecodeExtensionType(const byte* input, word32 length, word32 oid,
case EXT_KEY_USAGE_OID:
VERIFY_AND_SET_OID(cert->extExtKeyUsageSet);
cert->extExtKeyUsageCrit = critical ? 1 : 0;
if (DecodeExtKeyUsage(input, length, cert) < 0) {
if (DecodeExtKeyUsageInternal(input, length, cert) < 0) {
ret = ASN_PARSE_E;
}
break;
@@ -24183,7 +24472,7 @@ static int DecodeCertReq(DecodedCert* cert, int* criticalExt)
#endif /* WOLFSSL_CERT_REQ */
#endif
#endif /* WOLFSSL_ASN_TEMPLATE */
int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
{

View File

@@ -2098,6 +2098,9 @@ WOLFSSL_LOCAL int DecodePolicyOID(char *out, word32 outSz, const byte *in,
word32 inSz);
WOLFSSL_LOCAL int EncodePolicyOID(byte *out, word32 *outSz,
const char *in, void* heap);
WOLFSSL_LOCAL int DecodeExtensionType(const byte* input, word32 length,
word32 oid, byte critical,
DecodedCert* cert, int *isUnknownExt);
WOLFSSL_LOCAL int CheckCertSignaturePubKey(const byte* cert, word32 certSz,
void* heap, const byte* pubKey, word32 pubKeySz, int pubKeyOID);
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_SMALL_CERT_VERIFY)
@@ -2135,6 +2138,26 @@ WOLFSSL_LOCAL int DecodeToKey(DecodedCert* cert, int verify);
#ifdef WOLFSSL_ASN_TEMPLATE
WOLFSSL_LOCAL int DecodeCert(DecodedCert* cert, int verify, int* criticalExt);
#endif
WOLFSSL_LOCAL int DecodeBasicCaConstraint(const byte* input, int sz,
byte *isCa, word16 *pathLength, byte *pathLengthSet);
WOLFSSL_LOCAL int DecodeSubjKeyId(const byte* input, word32 sz,
const byte **extSubjKeyId, word32 *extSubjKeyIdSz);
WOLFSSL_LOCAL int DecodeAuthKeyId(const byte* input, word32 sz,
const byte **extAuthKeyId, word32 *extAuthKeyIdSz,
const byte **extAuthKeyIdIssuer, word32 *extAuthKeyIdIssuerSz,
const byte **extAuthKeyIdIssuerSN, word32 *extAuthKeyIdIssuerSNSz);
WOLFSSL_LOCAL int DecodeKeyUsage(const byte* input, word32 sz,
word16 *extKeyUsage);
WOLFSSL_LOCAL int DecodeExtKeyUsage(const byte* input, word32 sz,
const byte **extExtKeyUsageSrc, word32 *extExtKeyUsageSz,
word32 *extExtKeyUsageCount, byte *extExtKeyUsage,
byte *extExtKeyUsageSsh);
WOLFSSL_LOCAL int TryDecodeRPKToKey(DecodedCert* cert);
WOLFSSL_LOCAL int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate);

View File

@@ -14,7 +14,7 @@ tests:
integration_platforms:
- qemu_x86
sample.crypto.wolfssl_test_no_malloc:
timeout: 120
timeout: 200
platform_allow: qemu_x86
extra_args: CONF_FILE="prj-no-malloc.conf"
integration_platforms: