diff --git a/configure.ac b/configure.ac index 77c8e1012..7bab0634b 100644 --- a/configure.ac +++ b/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 diff --git a/src/x509.c b/src/x509.c index de8f7c6b5..739c53deb 100644 --- a/src/x509.c +++ b/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); } diff --git a/tests/api.c b/tests/api.c index b615eb0b4..e8c12337e 100644 --- a/tests/api.c +++ b/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(); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 360c517e7..e100a37f3 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -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) { diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 74a849fbc..60a3c1100 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -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); diff --git a/zephyr/samples/wolfssl_test/sample.yaml b/zephyr/samples/wolfssl_test/sample.yaml index 50010f76a..e9fbbcdd2 100644 --- a/zephyr/samples/wolfssl_test/sample.yaml +++ b/zephyr/samples/wolfssl_test/sample.yaml @@ -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: