mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-10-26 17:48:26 +00:00 
			
		
		
		
	Fixes of unreleased buffer, deadcode and wrong variable type detected by coverity scan. Addresses-Coverity-ID: 510809: Resource leaks (RESOURCE_LEAK) Addresses-Coverity-ID: 510806: Control flow issues (DEADCODE) Addresses-Coverity-ID: 510794 Control flow issues (NO_EFFECT) Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
		
			
				
	
	
		
			506 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			506 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| // SPDX-License-Identifier: GPL-2.0+
 | |
| /*
 | |
|  * PKCS#7 parser using MbedTLS PKCS#7 library
 | |
|  *
 | |
|  * Copyright (c) 2024 Linaro Limited
 | |
|  * Author: Raymond Mao <raymond.mao@linaro.org>
 | |
|  */
 | |
| 
 | |
| #include <log.h>
 | |
| #include <linux/kernel.h>
 | |
| #include <linux/err.h>
 | |
| #include <crypto/public_key.h>
 | |
| #include <crypto/pkcs7_parser.h>
 | |
| 
 | |
| static void pkcs7_free_mbedtls_ctx(struct pkcs7_mbedtls_ctx *ctx)
 | |
| {
 | |
| 	if (ctx) {
 | |
| 		kfree(ctx->content_data);
 | |
| 		kfree(ctx);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static void pkcs7_free_sinfo_mbedtls_ctx(struct pkcs7_sinfo_mbedtls_ctx *ctx)
 | |
| {
 | |
| 	if (ctx) {
 | |
| 		kfree(ctx->authattrs_data);
 | |
| 		kfree(ctx->content_data_digest);
 | |
| 		kfree(ctx);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Parse Authenticate Attributes
 | |
|  * TODO: Shall we consider to integrate decoding of authenticate attribute into
 | |
|  *	 MbedTLS library?
 | |
|  *
 | |
|  * There are two kinds of structure for the Authenticate Attributes being used
 | |
|  * in U-Boot.
 | |
|  *
 | |
|  * Type 1 - contains in a PE/COFF EFI image:
 | |
|  *
 | |
|  * [C.P.0] {
 | |
|  *   U.P.SEQUENCE {
 | |
|  *     U.P.OBJECTIDENTIFIER 1.2.840.113549.1.9.3 (OID_contentType)
 | |
|  *     U.P.SET {
 | |
|  *        U.P.OBJECTIDENTIFIER 1.3.6.1.4.1.311.2.1.4 (OID_msIndirectData)
 | |
|  *     }
 | |
|  *  }
 | |
|  *  U.P.SEQUENCE {
 | |
|  *     U.P.OBJECTIDENTIFIER 1.2.840.113549.1.9.5 (OID_signingTime)
 | |
|  *     U.P.SET {
 | |
|  *        U.P.UTCTime '<siging_time>'
 | |
|  *     }
 | |
|  *  }
 | |
|  *  U.P.SEQUENCE {
 | |
|  *     U.P.OBJECTIDENTIFIER 1.2.840.113549.1.9.4 (OID_messageDigest)
 | |
|  *     U.P.SET {
 | |
|  *        U.P.OCTETSTRING <digest>
 | |
|  *     }
 | |
|  *  }
 | |
|  *    U.P.SEQUENCE {
 | |
|  *        U.P.OBJECTIDENTIFIER 1.2.840.113549.1.9.15 (OID_smimeCapabilites)
 | |
|  *       U.P.SET {
 | |
|  *          U.P.SEQUENCE {
 | |
|  *             <...>
 | |
|  *          }
 | |
|  *       }
 | |
|  *    }
 | |
|  * }
 | |
|  *
 | |
|  * Type 2 - contains in an EFI Capsule:
 | |
|  *
 | |
|  * [C.P.0] {
 | |
|  *   U.P.SEQUENCE {
 | |
|  *      U.P.OBJECTIDENTIFIER 1.2.840.113549.1.9.3 (OID_contentType)
 | |
|  *      U.P.SET {
 | |
|  *         U.P.OBJECTIDENTIFIER 1.2.840.113549.1.7.1 (OID_data)
 | |
|  *      }
 | |
|  *   }
 | |
|  *   U.P.SEQUENCE {
 | |
|  *      U.P.OBJECTIDENTIFIER 1.2.840.113549.1.9.5 (OID_signingTime)
 | |
|  *      U.P.SET {
 | |
|  *         U.P.UTCTime '<siging_time>'
 | |
|  *      }
 | |
|  *   }
 | |
|  *   U.P.SEQUENCE {
 | |
|  *      U.P.OBJECTIDENTIFIER 1.2.840.113549.1.9.4 (OID_messageDigest)
 | |
|  *      U.P.SET {
 | |
|  *         U.P.OCTETSTRING <digest>
 | |
|  *      }
 | |
|  *  }
 | |
|  *}
 | |
|  *
 | |
|  * Note:
 | |
|  * They have different Content Type (OID_msIndirectData or OID_data).
 | |
|  * OID_smimeCapabilites only exists in a PE/COFF EFI image.
 | |
|  */
 | |
| static int authattrs_parse(struct pkcs7_message *msg, void *aa, size_t aa_len,
 | |
| 			   struct pkcs7_signed_info *sinfo)
 | |
| {
 | |
| 	unsigned char *p = aa;
 | |
| 	unsigned char *end = (unsigned char *)aa + aa_len;
 | |
| 	size_t len = 0;
 | |
| 	int ret;
 | |
| 	unsigned char *inner_p;
 | |
| 	size_t seq_len = 0;
 | |
| 
 | |
| 	ret = mbedtls_asn1_get_tag(&p, end, &seq_len,
 | |
| 				   MBEDTLS_ASN1_CONTEXT_SPECIFIC |
 | |
| 				   MBEDTLS_ASN1_CONSTRUCTED);
 | |
| 	if (ret)
 | |
| 		return ret;
 | |
| 
 | |
| 	while (!mbedtls_asn1_get_tag(&p, end, &seq_len,
 | |
| 				     MBEDTLS_ASN1_CONSTRUCTED |
 | |
| 				     MBEDTLS_ASN1_SEQUENCE)) {
 | |
| 		inner_p = p;
 | |
| 		ret = mbedtls_asn1_get_tag(&inner_p, p + seq_len, &len,
 | |
| 					   MBEDTLS_ASN1_OID);
 | |
| 		if (ret)
 | |
| 			return ret;
 | |
| 
 | |
| 		if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS9_CONTENTTYPE, inner_p, len)) {
 | |
| 			inner_p += len;
 | |
| 			ret = mbedtls_asn1_get_tag(&inner_p, p + seq_len, &len,
 | |
| 						   MBEDTLS_ASN1_CONSTRUCTED |
 | |
| 						   MBEDTLS_ASN1_SET);
 | |
| 			if (ret)
 | |
| 				return ret;
 | |
| 
 | |
| 			ret = mbedtls_asn1_get_tag(&inner_p, p + seq_len, &len,
 | |
| 						   MBEDTLS_ASN1_OID);
 | |
| 			if (ret)
 | |
| 				return ret;
 | |
| 
 | |
| 			/*
 | |
| 			 * We should only support 1.2.840.113549.1.7.1 (OID_data)
 | |
| 			 * for PKCS7 DATA that is used in EFI Capsule and
 | |
| 			 * 1.3.6.1.4.1.311.2.1.4 (OID_msIndirectData) for
 | |
| 			 * MicroSoft Authentication Code that is used in EFI
 | |
| 			 * Secure Boot.
 | |
| 			 */
 | |
| 			if (MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_MICROSOFT_INDIRECTDATA,
 | |
| 						inner_p, len) &&
 | |
| 			    MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DATA,
 | |
| 						inner_p, len))
 | |
| 				return -EINVAL;
 | |
| 
 | |
| 			if (__test_and_set_bit(sinfo_has_content_type, &sinfo->aa_set))
 | |
| 				return -EINVAL;
 | |
| 		} else if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS9_MESSAGEDIGEST, inner_p,
 | |
| 						len)) {
 | |
| 			inner_p += len;
 | |
| 			ret = mbedtls_asn1_get_tag(&inner_p, p + seq_len, &len,
 | |
| 						   MBEDTLS_ASN1_CONSTRUCTED |
 | |
| 						   MBEDTLS_ASN1_SET);
 | |
| 			if (ret)
 | |
| 				return ret;
 | |
| 
 | |
| 			ret = mbedtls_asn1_get_tag(&inner_p, p + seq_len, &len,
 | |
| 						   MBEDTLS_ASN1_OCTET_STRING);
 | |
| 			if (ret)
 | |
| 				return ret;
 | |
| 
 | |
| 			sinfo->msgdigest = inner_p;
 | |
| 			sinfo->msgdigest_len = len;
 | |
| 
 | |
| 			if (__test_and_set_bit(sinfo_has_message_digest, &sinfo->aa_set))
 | |
| 				return -EINVAL;
 | |
| 		} else if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS9_SIGNINGTIME, inner_p,
 | |
| 						len)) {
 | |
| 			mbedtls_x509_time st;
 | |
| 
 | |
| 			inner_p += len;
 | |
| 			ret = mbedtls_asn1_get_tag(&inner_p, p + seq_len, &len,
 | |
| 						   MBEDTLS_ASN1_CONSTRUCTED |
 | |
| 						   MBEDTLS_ASN1_SET);
 | |
| 			if (ret)
 | |
| 				return ret;
 | |
| 
 | |
| 			ret = mbedtls_x509_get_time(&inner_p, p + seq_len, &st);
 | |
| 			if (ret)
 | |
| 				return ret;
 | |
| 			sinfo->signing_time = x509_get_timestamp(&st);
 | |
| 
 | |
| 			if (__test_and_set_bit(sinfo_has_signing_time, &sinfo->aa_set))
 | |
| 				return -EINVAL;
 | |
| 		} else if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS9_SMIMECAP, inner_p,
 | |
| 						len)) {
 | |
| 			if (__test_and_set_bit(sinfo_has_smime_caps, &sinfo->aa_set))
 | |
| 				return -EINVAL;
 | |
| 
 | |
| 			if (msg->data_type != OID_msIndirectData &&
 | |
| 			    msg->data_type != OID_data)
 | |
| 				return -EINVAL;
 | |
| 		} else if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_MICROSOFT_SPOPUSINFO, inner_p,
 | |
| 						len)) {
 | |
| 			if (__test_and_set_bit(sinfo_has_ms_opus_info, &sinfo->aa_set))
 | |
| 				return -EINVAL;
 | |
| 		} else if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_MICROSOFT_STATETYPE, inner_p,
 | |
| 						len)) {
 | |
| 			if (__test_and_set_bit(sinfo_has_ms_statement_type, &sinfo->aa_set))
 | |
| 				return -EINVAL;
 | |
| 		}
 | |
| 
 | |
| 		p += seq_len;
 | |
| 	}
 | |
| 
 | |
| 	msg->have_authattrs = true;
 | |
| 
 | |
| 	/*
 | |
| 	 * Skip the leading tag byte (MBEDTLS_ASN1_CONTEXT_SPECIFIC |
 | |
| 	 * MBEDTLS_ASN1_CONSTRUCTED) to satisfy pkcs7_digest() when calculating
 | |
| 	 * the digest of authattrs.
 | |
| 	 */
 | |
| 	sinfo->authattrs = aa + 1;
 | |
| 	sinfo->authattrs_len = aa_len - 1;
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int x509_populate_content_data(struct pkcs7_message *msg,
 | |
| 				      mbedtls_pkcs7 *pkcs7_ctx)
 | |
| {
 | |
| 	struct pkcs7_mbedtls_ctx *mctx;
 | |
| 
 | |
| 	if (!pkcs7_ctx->content_data.data ||
 | |
| 	    !pkcs7_ctx->content_data.data_len)
 | |
| 		return 0;
 | |
| 
 | |
| 	mctx = kzalloc(sizeof(*mctx), GFP_KERNEL);
 | |
| 	if (!mctx)
 | |
| 		return -ENOMEM;
 | |
| 
 | |
| 	mctx->content_data = kmemdup(pkcs7_ctx->content_data.data,
 | |
| 				     pkcs7_ctx->content_data.data_len,
 | |
| 				     GFP_KERNEL);
 | |
| 	if (!mctx->content_data) {
 | |
| 		pkcs7_free_mbedtls_ctx(mctx);
 | |
| 		return -ENOMEM;
 | |
| 	}
 | |
| 
 | |
| 	msg->data = mctx->content_data;
 | |
| 	msg->data_len = pkcs7_ctx->content_data.data_len;
 | |
| 	msg->data_hdrlen = pkcs7_ctx->content_data.data_hdrlen;
 | |
| 	msg->data_type = pkcs7_ctx->content_data.data_type;
 | |
| 
 | |
| 	msg->mbedtls_ctx = mctx;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int x509_populate_sinfo(struct pkcs7_message *msg,
 | |
| 			       mbedtls_pkcs7_signer_info *mb_sinfo,
 | |
| 			       struct pkcs7_signed_info **sinfo)
 | |
| {
 | |
| 	struct pkcs7_signed_info *signed_info;
 | |
| 	struct public_key_signature *s;
 | |
| 	mbedtls_md_type_t md_alg;
 | |
| 	struct pkcs7_sinfo_mbedtls_ctx *mctx;
 | |
| 	int ret;
 | |
| 
 | |
| 	signed_info = kzalloc(sizeof(*signed_info), GFP_KERNEL);
 | |
| 	if (!signed_info)
 | |
| 		return -ENOMEM;
 | |
| 
 | |
| 	s = kzalloc(sizeof(*s), GFP_KERNEL);
 | |
| 	if (!s) {
 | |
| 		ret = -ENOMEM;
 | |
| 		goto out_no_sig;
 | |
| 	}
 | |
| 
 | |
| 	mctx = kzalloc(sizeof(*mctx), GFP_KERNEL);
 | |
| 	if (!mctx) {
 | |
| 		ret = -ENOMEM;
 | |
| 		goto out_no_mctx;
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * Hash algorithm:
 | |
| 	 *
 | |
| 	 * alg_identifier =	digestAlgorithm (DigestAlgorithmIdentifier)
 | |
| 	 *			MbedTLS internally checks this field to ensure
 | |
| 	 *			it is the same as digest_alg_identifiers.
 | |
| 	 * sig_alg_identifier =	digestEncryptionAlgorithm
 | |
| 	 *			(DigestEncryptionAlgorithmIdentifier)
 | |
| 	 *			MbedTLS just saves this field without any actions.
 | |
| 	 * See function pkcs7_get_signer_info() for reference.
 | |
| 	 *
 | |
| 	 * Public key algorithm:
 | |
| 	 * No information related to public key algorithm under MbedTLS signer
 | |
| 	 * info. Assume that we are using RSA.
 | |
| 	 */
 | |
| 	ret = mbedtls_oid_get_md_alg(&mb_sinfo->alg_identifier, &md_alg);
 | |
| 	if (ret)
 | |
| 		goto out_err_sinfo;
 | |
| 	s->pkey_algo = "rsa";
 | |
| 
 | |
| 	/* Translate the hash algorithm */
 | |
| 	switch (md_alg) {
 | |
| 	case MBEDTLS_MD_SHA1:
 | |
| 		s->hash_algo = "sha1";
 | |
| 		s->digest_size = SHA1_SUM_LEN;
 | |
| 		break;
 | |
| 	case MBEDTLS_MD_SHA256:
 | |
| 		s->hash_algo = "sha256";
 | |
| 		s->digest_size = SHA256_SUM_LEN;
 | |
| 		break;
 | |
| 	case MBEDTLS_MD_SHA384:
 | |
| 		s->hash_algo = "sha384";
 | |
| 		s->digest_size = SHA384_SUM_LEN;
 | |
| 		break;
 | |
| 	case MBEDTLS_MD_SHA512:
 | |
| 		s->hash_algo = "sha512";
 | |
| 		s->digest_size = SHA512_SUM_LEN;
 | |
| 		break;
 | |
| 	/* Unsupported algo */
 | |
| 	case MBEDTLS_MD_MD5:
 | |
| 	case MBEDTLS_MD_SHA224:
 | |
| 	default:
 | |
| 		ret = -EINVAL;
 | |
| 		goto out_err_sinfo;
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * auth_ids holds AuthorityKeyIdentifier, aka akid
 | |
| 	 * auth_ids[0]:
 | |
| 	 *	[PKCS#7 or CMS ver 1] - generated from "Issuer + Serial number"
 | |
| 	 *	[CMS ver 3] - generated from skid (subjectKeyId)
 | |
| 	 * auth_ids[1]: generated from skid (subjectKeyId)
 | |
| 	 *
 | |
| 	 * Assume that we are using PKCS#7 (msg->version=1),
 | |
| 	 * not CMS ver 3 (msg->version=3).
 | |
| 	 */
 | |
| 	s->auth_ids[0] = asymmetric_key_generate_id(mb_sinfo->serial.p,
 | |
| 						    mb_sinfo->serial.len,
 | |
| 						    mb_sinfo->issuer_raw.p,
 | |
| 						    mb_sinfo->issuer_raw.len);
 | |
| 	if (!s->auth_ids[0]) {
 | |
| 		ret = -ENOMEM;
 | |
| 		goto out_err_sinfo;
 | |
| 	}
 | |
| 
 | |
| 	/* skip s->auth_ids[1], no subjectKeyId in MbedTLS signer info ctx */
 | |
| 
 | |
| 	/*
 | |
| 	 * Encoding can be pkcs1 or raw, but only pkcs1 is supported.
 | |
| 	 * Set the encoding explicitly to pkcs1.
 | |
| 	 */
 | |
| 	s->encoding = "pkcs1";
 | |
| 
 | |
| 	/* Copy the signature data */
 | |
| 	s->s = kmemdup(mb_sinfo->sig.p, mb_sinfo->sig.len, GFP_KERNEL);
 | |
| 	if (!s->s) {
 | |
| 		ret = -ENOMEM;
 | |
| 		goto out_err_sinfo;
 | |
| 	}
 | |
| 	s->s_size = mb_sinfo->sig.len;
 | |
| 	signed_info->sig = s;
 | |
| 
 | |
| 	/* Save the Authenticate Attributes data if exists */
 | |
| 	if (!mb_sinfo->authattrs.data || !mb_sinfo->authattrs.data_len) {
 | |
| 		kfree(mctx);
 | |
| 		goto no_authattrs;
 | |
| 	}
 | |
| 
 | |
| 	mctx->authattrs_data = kmemdup(mb_sinfo->authattrs.data,
 | |
| 				       mb_sinfo->authattrs.data_len,
 | |
| 				       GFP_KERNEL);
 | |
| 	if (!mctx->authattrs_data) {
 | |
| 		ret = -ENOMEM;
 | |
| 		goto out_err_sinfo;
 | |
| 	}
 | |
| 	signed_info->mbedtls_ctx = mctx;
 | |
| 
 | |
| 	/* If authattrs exists, decode it and parse msgdigest from it */
 | |
| 	ret = authattrs_parse(msg, mctx->authattrs_data,
 | |
| 			      mb_sinfo->authattrs.data_len,
 | |
| 			      signed_info);
 | |
| 	if (ret)
 | |
| 		goto out_err_sinfo;
 | |
| 
 | |
| no_authattrs:
 | |
| 	*sinfo = signed_info;
 | |
| 	return 0;
 | |
| 
 | |
| out_err_sinfo:
 | |
| 	pkcs7_free_sinfo_mbedtls_ctx(mctx);
 | |
| out_no_mctx:
 | |
| 	public_key_signature_free(s);
 | |
| out_no_sig:
 | |
| 	kfree(signed_info);
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Free a signed information block.
 | |
|  */
 | |
| static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo)
 | |
| {
 | |
| 	if (sinfo) {
 | |
| 		public_key_signature_free(sinfo->sig);
 | |
| 		pkcs7_free_sinfo_mbedtls_ctx(sinfo->mbedtls_ctx);
 | |
| 		kfree(sinfo);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * pkcs7_free_message - Free a PKCS#7 message
 | |
|  * @pkcs7: The PKCS#7 message to free
 | |
|  */
 | |
| void pkcs7_free_message(struct pkcs7_message *pkcs7)
 | |
| {
 | |
| 	struct x509_certificate *cert;
 | |
| 	struct pkcs7_signed_info *sinfo;
 | |
| 
 | |
| 	if (pkcs7) {
 | |
| 		while (pkcs7->certs) {
 | |
| 			cert = pkcs7->certs;
 | |
| 			pkcs7->certs = cert->next;
 | |
| 			x509_free_certificate(cert);
 | |
| 		}
 | |
| 		while (pkcs7->crl) {
 | |
| 			cert = pkcs7->crl;
 | |
| 			pkcs7->crl = cert->next;
 | |
| 			x509_free_certificate(cert);
 | |
| 		}
 | |
| 		while (pkcs7->signed_infos) {
 | |
| 			sinfo = pkcs7->signed_infos;
 | |
| 			pkcs7->signed_infos = sinfo->next;
 | |
| 			pkcs7_free_signed_info(sinfo);
 | |
| 		}
 | |
| 		pkcs7_free_mbedtls_ctx(pkcs7->mbedtls_ctx);
 | |
| 		kfree(pkcs7);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen)
 | |
| {
 | |
| 	int i;
 | |
| 	int ret;
 | |
| 	mbedtls_pkcs7 pkcs7_ctx;
 | |
| 	mbedtls_pkcs7_signer_info *mb_sinfos;
 | |
| 	mbedtls_x509_crt *mb_certs;
 | |
| 	struct pkcs7_message *msg;
 | |
| 	struct x509_certificate **cert;
 | |
| 	struct pkcs7_signed_info **sinfos;
 | |
| 
 | |
| 	msg = kzalloc(sizeof(*msg), GFP_KERNEL);
 | |
| 	if (!msg) {
 | |
| 		ret = -ENOMEM;
 | |
| 		goto out_no_msg;
 | |
| 	}
 | |
| 
 | |
| 	/* Parse the DER encoded PKCS#7 message using MbedTLS */
 | |
| 	mbedtls_pkcs7_init(&pkcs7_ctx);
 | |
| 	ret = mbedtls_pkcs7_parse_der(&pkcs7_ctx, data, datalen);
 | |
| 	/* Check if it is a PKCS#7 message with signed data */
 | |
| 	if (ret != MBEDTLS_PKCS7_SIGNED_DATA)
 | |
| 		goto parse_fail;
 | |
| 
 | |
| 	/* Assume that we are using PKCS#7, not CMS ver 3 */
 | |
| 	msg->version = 1;	/* 1 for [PKCS#7 or CMS ver 1] */
 | |
| 
 | |
| 	/* Populate the certs to msg->certs */
 | |
| 	for (i = 0, cert = &msg->certs, mb_certs = &pkcs7_ctx.signed_data.certs;
 | |
| 	     i < pkcs7_ctx.signed_data.no_of_certs && mb_certs;
 | |
| 	     i++, cert = &(*cert)->next, mb_certs = mb_certs->next) {
 | |
| 		ret = x509_populate_cert(mb_certs, cert);
 | |
| 		if (ret)
 | |
| 			goto parse_fail;
 | |
| 
 | |
| 		(*cert)->index = i + 1;
 | |
| 	}
 | |
| 
 | |
| 	/*
 | |
| 	 * Skip populating crl, that is not currently in-use.
 | |
| 	 */
 | |
| 
 | |
| 	/* Populate content data */
 | |
| 	ret = x509_populate_content_data(msg, &pkcs7_ctx);
 | |
| 	if (ret)
 | |
| 		goto parse_fail;
 | |
| 
 | |
| 	/* Populate signed info to msg->signed_infos */
 | |
| 	for (i = 0, sinfos = &msg->signed_infos,
 | |
| 	     mb_sinfos = &pkcs7_ctx.signed_data.signers;
 | |
| 	     i < pkcs7_ctx.signed_data.no_of_signers && mb_sinfos;
 | |
| 	     i++, sinfos = &(*sinfos)->next, mb_sinfos = mb_sinfos->next) {
 | |
| 		ret = x509_populate_sinfo(msg, mb_sinfos, sinfos);
 | |
| 		if (ret)
 | |
| 			goto parse_fail;
 | |
| 
 | |
| 		(*sinfos)->index = i + 1;
 | |
| 	}
 | |
| 
 | |
| 	mbedtls_pkcs7_free(&pkcs7_ctx);
 | |
| 	return msg;
 | |
| 
 | |
| parse_fail:
 | |
| 	mbedtls_pkcs7_free(&pkcs7_ctx);
 | |
| 	pkcs7_free_message(msg);
 | |
| out_no_msg:
 | |
| 	msg = ERR_PTR(ret);
 | |
| 	return msg;
 | |
| }
 |