mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-12 09:04:48 +02:00
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:
14
configure.ac
14
configure.ac
@@ -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
|
||||
|
678
src/x509.c
678
src/x509.c
@@ -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);
|
||||
}
|
||||
|
12
tests/api.c
12
tests/api.c
@@ -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();
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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:
|
||||
|
Reference in New Issue
Block a user