Merge "refactor(auth): use a single function for parsing extensions" into integration

This commit is contained in:
Sandrine Bailleux 2023-03-03 08:39:16 +01:00 committed by TrustedFirmware Code Review
commit d26cb4f46e

View file

@ -66,46 +66,63 @@ static void clear_temp_vars(void)
* Get X509v3 extension * Get X509v3 extension
* *
* Global variable 'v3_ext' must point to the extensions region * Global variable 'v3_ext' must point to the extensions region
* in the certificate. No need to check for errors since the image has passed * in the certificate. OID may be NULL to request that get_ext()
* the integrity check. * is only being called for integrity checking.
*/ */
static int get_ext(const char *oid, void **ext, unsigned int *ext_len) static int get_ext(const char *oid, void **ext, unsigned int *ext_len)
{ {
int oid_len; int oid_len, ret, is_critical;
size_t len; size_t len;
unsigned char *end_ext_data, *end_ext_octet;
unsigned char *p; unsigned char *p;
const unsigned char *end; const unsigned char *end;
char oid_str[MAX_OID_STR_LEN]; char oid_str[MAX_OID_STR_LEN];
mbedtls_asn1_buf extn_oid; mbedtls_asn1_buf extn_oid;
int is_critical;
assert(oid != NULL);
p = v3_ext.p; p = v3_ext.p;
end = v3_ext.p + v3_ext.len; end = v3_ext.p + v3_ext.len;
while (p < end) { /*
zeromem(&extn_oid, sizeof(extn_oid)); * Check extensions integrity. At least one extension is
is_critical = 0; /* DEFAULT FALSE */ * required: the ASN.1 specifies a minimum size of 1, and at
* least one extension is needed to authenticate the next stage
* in the boot chain.
*/
do {
unsigned char *end_ext_data;
mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | ret = mbedtls_asn1_get_tag(&p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE); MBEDTLS_ASN1_SEQUENCE);
if (ret != 0) {
return IMG_PARSER_ERR_FORMAT;
}
end_ext_data = p + len; end_ext_data = p + len;
/* Get extension ID */ /* Get extension ID */
extn_oid.tag = *p; ret = mbedtls_asn1_get_tag(&p, end_ext_data, &extn_oid.len,
mbedtls_asn1_get_tag(&p, end, &extn_oid.len, MBEDTLS_ASN1_OID); MBEDTLS_ASN1_OID);
if (ret != 0) {
return IMG_PARSER_ERR_FORMAT;
}
extn_oid.tag = MBEDTLS_ASN1_OID;
extn_oid.p = p; extn_oid.p = p;
p += extn_oid.len; p += extn_oid.len;
/* Get optional critical */ /* Get optional critical */
mbedtls_asn1_get_bool(&p, end_ext_data, &is_critical); ret = mbedtls_asn1_get_bool(&p, end_ext_data, &is_critical);
if ((ret != 0) && (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) {
return IMG_PARSER_ERR_FORMAT;
}
/* Extension data */ /*
mbedtls_asn1_get_tag(&p, end_ext_data, &len, * Data should be octet string type and must use all bytes in
* the Extension.
*/
ret = mbedtls_asn1_get_tag(&p, end_ext_data, &len,
MBEDTLS_ASN1_OCTET_STRING); MBEDTLS_ASN1_OCTET_STRING);
end_ext_octet = p + len; if ((ret != 0) || ((p + len) != end_ext_data)) {
return IMG_PARSER_ERR_FORMAT;
}
/* Detect requested extension */ /* Detect requested extension */
oid_len = mbedtls_oid_get_numeric_string(oid_str, oid_len = mbedtls_oid_get_numeric_string(oid_str,
@ -114,17 +131,20 @@ static int get_ext(const char *oid, void **ext, unsigned int *ext_len)
if ((oid_len == MBEDTLS_ERR_OID_BUF_TOO_SMALL) || (oid_len < 0)) { if ((oid_len == MBEDTLS_ERR_OID_BUF_TOO_SMALL) || (oid_len < 0)) {
return IMG_PARSER_ERR; return IMG_PARSER_ERR;
} }
if (((size_t)oid_len == strlen(oid_str)) && !strcmp(oid, oid_str)) {
if ((oid != NULL) &&
((size_t)oid_len == strlen(oid_str)) &&
(strcmp(oid, oid_str) == 0)) {
*ext = (void *)p; *ext = (void *)p;
*ext_len = (unsigned int)len; *ext_len = (unsigned int)len;
return IMG_PARSER_OK; return IMG_PARSER_OK;
} }
/* Next */ /* Next */
p = end_ext_octet; p = end_ext_data;
} } while (p < end);
return IMG_PARSER_ERR_NOT_FOUND; return (oid == NULL) ? IMG_PARSER_OK : IMG_PARSER_ERR_NOT_FOUND;
} }
@ -139,7 +159,7 @@ static int get_ext(const char *oid, void **ext, unsigned int *ext_len)
*/ */
static int cert_parse(void *img, unsigned int img_len) static int cert_parse(void *img, unsigned int img_len)
{ {
int ret, is_critical; int ret;
size_t len; size_t len;
unsigned char *p, *end, *crt_end, *pk_end; unsigned char *p, *end, *crt_end, *pk_end;
mbedtls_asn1_buf sig_alg1; mbedtls_asn1_buf sig_alg1;
@ -334,51 +354,12 @@ static int cert_parse(void *img, unsigned int img_len)
} }
v3_ext.p = p; v3_ext.p = p;
v3_ext.len = len; v3_ext.len = len;
/*
* Check extensions integrity. At least one extension is
* required: the ASN.1 specifies a minimum size of 1, and at
* least one extension is needed to authenticate the next stage
* in the boot chain.
*/
do {
unsigned char *end_ext_data;
ret = mbedtls_asn1_get_tag(&p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE);
if (ret != 0) {
return IMG_PARSER_ERR_FORMAT;
}
end_ext_data = p + len;
/* Get extension ID */
ret = mbedtls_asn1_get_tag(&p, end_ext_data, &len, MBEDTLS_ASN1_OID);
if (ret != 0) {
return IMG_PARSER_ERR_FORMAT;
}
p += len; p += len;
/* Get optional critical */ /* Check extensions integrity */
ret = mbedtls_asn1_get_bool(&p, end_ext_data, &is_critical); ret = get_ext(NULL, NULL, NULL);
if ((ret != 0) && (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) { if (ret != IMG_PARSER_OK) {
return IMG_PARSER_ERR_FORMAT; return ret;
}
/*
* Data should be octet string type and must use all bytes in
* the Extension.
*/
ret = mbedtls_asn1_get_tag(&p, end_ext_data, &len,
MBEDTLS_ASN1_OCTET_STRING);
if ((ret != 0) || ((p + len) != end_ext_data)) {
return IMG_PARSER_ERR_FORMAT;
}
p = end_ext_data;
} while (p < end);
if (p != end) {
return IMG_PARSER_ERR_FORMAT;
} }
end = crt_end; end = crt_end;