Hi Raymond On Tue, 7 May 2024 at 20:57, Raymond Mao <raymond....@linaro.org> wrote: > > Support decoding multiple signer's cert in the signed data within > a PKCS7 message.
For all similar external mbedTLS patches, try to explain which belong to mbedTLS must be sent upstream and which ones we need to carry internally. I don't expect us to have to carry anything in U-Boot Thanks /Ilias > > Signed-off-by: Raymond Mao <raymond....@linaro.org> > --- > Changes in v2 > - None. > > lib/mbedtls/external/mbedtls/library/pkcs7.c | 75 ++++++++++++-------- > 1 file changed, 47 insertions(+), 28 deletions(-) > > diff --git a/lib/mbedtls/external/mbedtls/library/pkcs7.c > b/lib/mbedtls/external/mbedtls/library/pkcs7.c > index da73fb341d6..01105227d7a 100644 > --- a/lib/mbedtls/external/mbedtls/library/pkcs7.c > +++ b/lib/mbedtls/external/mbedtls/library/pkcs7.c > @@ -61,6 +61,36 @@ static int pkcs7_get_next_content_len(unsigned char **p, > unsigned char *end, > return ret; > } > > +/** > + * Get and decode one cert from a sequence. > + * Return 0 for success, > + * Return negative error code for failure. > + **/ > +static int pkcs7_get_one_cert(unsigned char **p, unsigned char *end, > + mbedtls_x509_crt *certs) > +{ > + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; > + size_t len = 0; > + unsigned char *start = *p; > + unsigned char *end_cert; > + > + ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED > + | MBEDTLS_ASN1_SEQUENCE); > + if (ret != 0) { > + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CERT, ret); > + } > + > + end_cert = *p + len; > + > + if ((ret = mbedtls_x509_crt_parse_der(certs, start, end_cert - start)) < > 0) { > + return MBEDTLS_ERR_PKCS7_INVALID_CERT; > + } > + > + *p = end_cert; > + > + return 0; > +} > + > /** > * version Version > * Version ::= INTEGER > @@ -178,11 +208,12 @@ static int pkcs7_get_certificates(unsigned char **p, > unsigned char *end, > mbedtls_x509_crt *certs) > { > int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; > - size_t len1 = 0; > - size_t len2 = 0; > - unsigned char *end_set, *end_cert, *start; > + size_t len = 0; > + unsigned char *end_set; > + int num_of_certs = 0; > > - ret = mbedtls_asn1_get_tag(p, end, &len1, MBEDTLS_ASN1_CONSTRUCTED > + /* Get the set of certs */ > + ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED > | MBEDTLS_ASN1_CONTEXT_SPECIFIC); > if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { > return 0; > @@ -190,38 +221,26 @@ static int pkcs7_get_certificates(unsigned char **p, > unsigned char *end, > if (ret != 0) { > return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret); > } > - start = *p; > - end_set = *p + len1; > + end_set = *p + len; > > - ret = mbedtls_asn1_get_tag(p, end_set, &len2, MBEDTLS_ASN1_CONSTRUCTED > - | MBEDTLS_ASN1_SEQUENCE); > + ret = pkcs7_get_one_cert(p, end_set, certs); > if (ret != 0) { > - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CERT, ret); > + return ret; > } > > - end_cert = *p + len2; > + num_of_certs++; > > - /* > - * This is to verify that there is only one signer certificate. It seems > it is > - * not easy to differentiate between the chain vs different signer's > certificate. > - * So, we support only the root certificate and the single signer. > - * The behaviour would be improved with addition of multiple signer > support. > - */ > - if (end_cert != end_set) { > - return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE; > - } > - > - if ((ret = mbedtls_x509_crt_parse_der(certs, start, len1)) < 0) { > - return MBEDTLS_ERR_PKCS7_INVALID_CERT; > + while (*p != end_set) { > + ret = pkcs7_get_one_cert(p, end_set, certs); > + if (ret != 0) { > + return ret; > + } > + num_of_certs++; > } > > - *p = end_cert; > + *p = end_set; > > - /* > - * Since in this version we strictly support single certificate, and > reaching > - * here implies we have parsed successfully, we return 1. > - */ > - return 1; > + return num_of_certs; > } > > /** > -- > 2.25.1 >