blob: 60d1175289547930a112a072e8d9b23ea8fbdcef [file] [log] [blame]
Nick Child5d881c32022-02-28 10:09:16 -06001/*
2 * Copyright The Mbed TLS Contributors
3 * SPDX-License-Identifier: Apache-2.0
Nayna Jainc9deb182020-11-16 19:03:12 +00004 *
Nick Child5d881c32022-02-28 10:09:16 -06005 * Licensed under the Apache License, Version 2.0 (the "License"); you may
6 * not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
Nayna Jainc9deb182020-11-16 19:03:12 +00008 *
Nick Child5d881c32022-02-28 10:09:16 -06009 * http://www.apache.org/licenses/LICENSE-2.0
Nayna Jainc9deb182020-11-16 19:03:12 +000010 *
Nick Child5d881c32022-02-28 10:09:16 -060011 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
Nayna Jainc9deb182020-11-16 19:03:12 +000016 */
17#include "common.h"
18
19#include "mbedtls/build_info.h"
20#if defined(MBEDTLS_PKCS7_C)
21#include "mbedtls/pkcs7.h"
22#include "mbedtls/x509.h"
23#include "mbedtls/asn1.h"
24#include "mbedtls/x509_crt.h"
25#include "mbedtls/x509_crl.h"
26#include "mbedtls/oid.h"
Nick Child9f4fb3e2022-09-12 16:21:02 -050027#include "mbedtls/error.h"
Nayna Jainc9deb182020-11-16 19:03:12 +000028
Nayna Jainc9deb182020-11-16 19:03:12 +000029#if defined(MBEDTLS_FS_IO)
30#include <sys/types.h>
31#include <sys/stat.h>
32#endif
33
Nayna Jainc9deb182020-11-16 19:03:12 +000034#include "mbedtls/platform.h"
35#include "mbedtls/platform_util.h"
Nayna Jainc9deb182020-11-16 19:03:12 +000036
37#if defined(MBEDTLS_HAVE_TIME)
38#include "mbedtls/platform_time.h"
39#endif
40#if defined(MBEDTLS_HAVE_TIME_DATE)
41#include <time.h>
42#endif
43
44/**
45 * Initializes the pkcs7 structure.
46 */
Gilles Peskine449bd832023-01-11 14:50:10 +010047void mbedtls_pkcs7_init(mbedtls_pkcs7 *pkcs7)
Nayna Jainc9deb182020-11-16 19:03:12 +000048{
Gilles Peskine449bd832023-01-11 14:50:10 +010049 memset(pkcs7, 0, sizeof(*pkcs7));
Nayna Jainc9deb182020-11-16 19:03:12 +000050}
51
Gilles Peskine449bd832023-01-11 14:50:10 +010052static int pkcs7_get_next_content_len(unsigned char **p, unsigned char *end,
53 size_t *len)
Nayna Jainc9deb182020-11-16 19:03:12 +000054{
Nick Child9f4fb3e2022-09-12 16:21:02 -050055 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +000056
Gilles Peskine449bd832023-01-11 14:50:10 +010057 ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_CONSTRUCTED
58 | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
59 if (ret != 0) {
Demi Marie Obenour6cfc4692022-11-28 00:46:00 -050060 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
Demi Marie Obenour512818b2022-11-27 22:48:55 -050061 } else if ((size_t) (end - *p) != *len) {
Demi Marie Obenour6cfc4692022-11-28 00:46:00 -050062 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO,
Demi Marie Obenour512818b2022-11-27 22:48:55 -050063 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
Nayna Jainc9deb182020-11-16 19:03:12 +000064 }
65
Gilles Peskine449bd832023-01-11 14:50:10 +010066 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +000067}
68
69/**
70 * version Version
71 * Version ::= INTEGER
72 **/
Gilles Peskine449bd832023-01-11 14:50:10 +010073static int pkcs7_get_version(unsigned char **p, unsigned char *end, int *ver)
Nayna Jainc9deb182020-11-16 19:03:12 +000074{
Nick Child9f4fb3e2022-09-12 16:21:02 -050075 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +000076
Gilles Peskine449bd832023-01-11 14:50:10 +010077 ret = mbedtls_asn1_get_int(p, end, ver);
78 if (ret != 0) {
79 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_VERSION, ret);
80 }
Nayna Jainc9deb182020-11-16 19:03:12 +000081
82 /* If version != 1, return invalid version */
Gilles Peskine449bd832023-01-11 14:50:10 +010083 if (*ver != MBEDTLS_PKCS7_SUPPORTED_VERSION) {
Nick Child9f4fb3e2022-09-12 16:21:02 -050084 ret = MBEDTLS_ERR_PKCS7_INVALID_VERSION;
Gilles Peskine449bd832023-01-11 14:50:10 +010085 }
Nayna Jainc9deb182020-11-16 19:03:12 +000086
Gilles Peskine449bd832023-01-11 14:50:10 +010087 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +000088}
89
90/**
91 * ContentInfo ::= SEQUENCE {
92 * contentType ContentType,
93 * content
94 * [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
95 **/
Gilles Peskine449bd832023-01-11 14:50:10 +010096static int pkcs7_get_content_info_type(unsigned char **p, unsigned char *end,
Nick Childec817092022-12-15 15:54:03 -060097 unsigned char **seq_end,
Gilles Peskine449bd832023-01-11 14:50:10 +010098 mbedtls_pkcs7_buf *pkcs7)
Nayna Jainc9deb182020-11-16 19:03:12 +000099{
100 size_t len = 0;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500101 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jain673a2262020-12-14 22:44:49 +0000102 unsigned char *start = *p;
Nayna Jainc9deb182020-11-16 19:03:12 +0000103
Gilles Peskine449bd832023-01-11 14:50:10 +0100104 ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
105 | MBEDTLS_ASN1_SEQUENCE);
106 if (ret != 0) {
Nick Childc448c942021-07-01 15:29:50 -0400107 *p = start;
Gilles Peskine449bd832023-01-11 14:50:10 +0100108 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
Nick Childc448c942021-07-01 15:29:50 -0400109 }
Nick Childec817092022-12-15 15:54:03 -0600110 *seq_end = *p + len;
111 ret = mbedtls_asn1_get_tag(p, *seq_end, &len, MBEDTLS_ASN1_OID);
Gilles Peskine449bd832023-01-11 14:50:10 +0100112 if (ret != 0) {
Nayna Jain673a2262020-12-14 22:44:49 +0000113 *p = start;
Gilles Peskine449bd832023-01-11 14:50:10 +0100114 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
Nayna Jain673a2262020-12-14 22:44:49 +0000115 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000116
117 pkcs7->tag = MBEDTLS_ASN1_OID;
118 pkcs7->len = len;
119 pkcs7->p = *p;
Nick Childbb82ab72022-10-28 12:28:54 -0500120 *p += len;
Nayna Jainc9deb182020-11-16 19:03:12 +0000121
Gilles Peskine449bd832023-01-11 14:50:10 +0100122 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +0000123}
124
125/**
126 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
127 *
128 * This is from x509.h
129 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100130static int pkcs7_get_digest_algorithm(unsigned char **p, unsigned char *end,
131 mbedtls_x509_buf *alg)
Nayna Jainc9deb182020-11-16 19:03:12 +0000132{
Nick Child9f4fb3e2022-09-12 16:21:02 -0500133 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000134
Gilles Peskine449bd832023-01-11 14:50:10 +0100135 if ((ret = mbedtls_asn1_get_alg_null(p, end, alg)) != 0) {
136 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
137 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000138
Gilles Peskine449bd832023-01-11 14:50:10 +0100139 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +0000140}
141
142/**
143 * DigestAlgorithmIdentifiers :: SET of DigestAlgorithmIdentifier
144 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100145static int pkcs7_get_digest_algorithm_set(unsigned char **p,
146 unsigned char *end,
147 mbedtls_x509_buf *alg)
Nayna Jainc9deb182020-11-16 19:03:12 +0000148{
149 size_t len = 0;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500150 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000151
Gilles Peskine449bd832023-01-11 14:50:10 +0100152 ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
153 | MBEDTLS_ASN1_SET);
154 if (ret != 0) {
155 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
Nick Child9f4fb3e2022-09-12 16:21:02 -0500156 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000157
158 end = *p + len;
159
Gilles Peskine449bd832023-01-11 14:50:10 +0100160 ret = mbedtls_asn1_get_alg_null(p, end, alg);
161 if (ret != 0) {
162 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
Nick Child9f4fb3e2022-09-12 16:21:02 -0500163 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000164
Nick Child34d5e932022-09-14 14:44:03 -0500165 /** For now, it assumes there is only one digest algorithm specified **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100166 if (*p != end) {
167 return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
168 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000169
Gilles Peskine449bd832023-01-11 14:50:10 +0100170 return 0;
Nayna Jainc9deb182020-11-16 19:03:12 +0000171}
172
173/**
174 * certificates :: SET OF ExtendedCertificateOrCertificate,
175 * ExtendedCertificateOrCertificate ::= CHOICE {
176 * certificate Certificate -- x509,
177 * extendedCertificate[0] IMPLICIT ExtendedCertificate }
178 * Return number of certificates added to the signed data,
179 * 0 or higher is valid.
180 * Return negative error code for failure.
181 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100182static int pkcs7_get_certificates(unsigned char **p, unsigned char *end,
183 mbedtls_x509_crt *certs)
Nayna Jainc9deb182020-11-16 19:03:12 +0000184{
Nick Child9f4fb3e2022-09-12 16:21:02 -0500185 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000186 size_t len1 = 0;
187 size_t len2 = 0;
Nick Childbb82ab72022-10-28 12:28:54 -0500188 unsigned char *end_set, *end_cert, *start;
Nayna Jainc9deb182020-11-16 19:03:12 +0000189
Demi Marie Obenour6cfc4692022-11-28 00:46:00 -0500190 ret = mbedtls_asn1_get_tag(p, end, &len1, MBEDTLS_ASN1_CONSTRUCTED
191 | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
192 if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
193 return 0;
194 }
195 if (ret != 0) {
196 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
Nayna Jainc9deb182020-11-16 19:03:12 +0000197 }
198 start = *p;
199 end_set = *p + len1;
200
Gilles Peskine449bd832023-01-11 14:50:10 +0100201 ret = mbedtls_asn1_get_tag(p, end_set, &len2, MBEDTLS_ASN1_CONSTRUCTED
202 | MBEDTLS_ASN1_SEQUENCE);
203 if (ret != 0) {
204 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CERT, ret);
Nick Child9f4fb3e2022-09-12 16:21:02 -0500205 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000206
207 end_cert = *p + len2;
208
209 /*
210 * This is to verify that there is only one signer certificate. It seems it is
211 * not easy to differentiate between the chain vs different signer's certificate.
212 * So, we support only the root certificate and the single signer.
213 * The behaviour would be improved with addition of multiple signer support.
214 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100215 if (end_cert != end_set) {
216 return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500217 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000218
Demi Marie Obenour55d9df22022-11-28 00:29:32 -0500219 if ((ret = mbedtls_x509_crt_parse_der(certs, start, len1)) < 0) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100220 return MBEDTLS_ERR_PKCS7_INVALID_CERT;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500221 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000222
Demi Marie Obenour55d9df22022-11-28 00:29:32 -0500223 *p = end_cert;
Nayna Jainc9deb182020-11-16 19:03:12 +0000224
Nick Child5f9456f2022-09-19 10:01:25 -0500225 /*
Nick Child9f4fb3e2022-09-12 16:21:02 -0500226 * Since in this version we strictly support single certificate, and reaching
Nick Child5f9456f2022-09-19 10:01:25 -0500227 * here implies we have parsed successfully, we return 1.
Nick Child9f4fb3e2022-09-12 16:21:02 -0500228 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100229 return 1;
Nayna Jainc9deb182020-11-16 19:03:12 +0000230}
231
232/**
233 * EncryptedDigest ::= OCTET STRING
234 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100235static int pkcs7_get_signature(unsigned char **p, unsigned char *end,
236 mbedtls_pkcs7_buf *signature)
Nayna Jainc9deb182020-11-16 19:03:12 +0000237{
Nick Child9f4fb3e2022-09-12 16:21:02 -0500238 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000239 size_t len = 0;
240
Gilles Peskine449bd832023-01-11 14:50:10 +0100241 ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
242 if (ret != 0) {
243 return ret;
244 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000245
246 signature->tag = MBEDTLS_ASN1_OCTET_STRING;
247 signature->len = len;
248 signature->p = *p;
249
250 *p = *p + len;
251
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 return 0;
Nayna Jainc9deb182020-11-16 19:03:12 +0000253}
254
Gilles Peskine449bd832023-01-11 14:50:10 +0100255static void pkcs7_free_signer_info(mbedtls_pkcs7_signer_info *signer)
Bence Szépkútif7641542022-12-12 21:37:36 +0100256{
257 mbedtls_x509_name *name_cur;
258 mbedtls_x509_name *name_prv;
259
Gilles Peskine449bd832023-01-11 14:50:10 +0100260 if (signer == NULL) {
Bence Szépkútif7641542022-12-12 21:37:36 +0100261 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100262 }
Bence Szépkútif7641542022-12-12 21:37:36 +0100263
264 name_cur = signer->issuer.next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100265 while (name_cur != NULL) {
Bence Szépkútif7641542022-12-12 21:37:36 +0100266 name_prv = name_cur;
267 name_cur = name_cur->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 mbedtls_free(name_prv);
Bence Szépkútif7641542022-12-12 21:37:36 +0100269 }
270 signer->issuer.next = NULL;
271}
272
Nayna Jainc9deb182020-11-16 19:03:12 +0000273/**
Nayna Jainc9deb182020-11-16 19:03:12 +0000274 * SignerInfo ::= SEQUENCE {
275 * version Version;
276 * issuerAndSerialNumber IssuerAndSerialNumber,
277 * digestAlgorithm DigestAlgorithmIdentifier,
278 * authenticatedAttributes
279 * [0] IMPLICIT Attributes OPTIONAL,
280 * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
281 * encryptedDigest EncryptedDigest,
282 * unauthenticatedAttributes
283 * [1] IMPLICIT Attributes OPTIONAL,
Daniel Axtens35384792020-09-02 14:48:45 +1000284 * Returns 0 if the signerInfo is valid.
285 * Return negative error code for failure.
Nick Childbb82ab72022-10-28 12:28:54 -0500286 * Structure must not contain vales for authenticatedAttributes
287 * and unauthenticatedAttributes.
Daniel Axtens35384792020-09-02 14:48:45 +1000288 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100289static int pkcs7_get_signer_info(unsigned char **p, unsigned char *end,
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500290 mbedtls_pkcs7_signer_info *signer,
291 mbedtls_x509_buf *alg)
Daniel Axtens35384792020-09-02 14:48:45 +1000292{
Nick Childec817092022-12-15 15:54:03 -0600293 unsigned char *end_signer, *end_issuer_and_sn;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500294 int asn1_ret = 0, ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Axtens35384792020-09-02 14:48:45 +1000295 size_t len = 0;
296
Gilles Peskine449bd832023-01-11 14:50:10 +0100297 asn1_ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
298 | MBEDTLS_ASN1_SEQUENCE);
299 if (asn1_ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500300 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100301 }
Daniel Axtens35384792020-09-02 14:48:45 +1000302
303 end_signer = *p + len;
304
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 ret = pkcs7_get_version(p, end_signer, &signer->version);
306 if (ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500307 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 }
Daniel Axtens35384792020-09-02 14:48:45 +1000309
Gilles Peskine449bd832023-01-11 14:50:10 +0100310 asn1_ret = mbedtls_asn1_get_tag(p, end_signer, &len,
311 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
312 if (asn1_ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500313 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100314 }
Daniel Axtens35384792020-09-02 14:48:45 +1000315
Nick Childec817092022-12-15 15:54:03 -0600316 end_issuer_and_sn = *p + len;
Daniel Axtens35384792020-09-02 14:48:45 +1000317 /* Parsing IssuerAndSerialNumber */
318 signer->issuer_raw.p = *p;
319
Nick Child3bd17f22023-01-31 20:42:26 +0000320 asn1_ret = mbedtls_asn1_get_tag(p, end_issuer_and_sn, &len,
Gilles Peskine449bd832023-01-11 14:50:10 +0100321 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
322 if (asn1_ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500323 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100324 }
Daniel Axtens35384792020-09-02 14:48:45 +1000325
Gilles Peskine449bd832023-01-11 14:50:10 +0100326 ret = mbedtls_x509_get_name(p, *p + len, &signer->issuer);
327 if (ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500328 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100329 }
Daniel Axtens35384792020-09-02 14:48:45 +1000330
331 signer->issuer_raw.len = *p - signer->issuer_raw.p;
332
Nick Child3bd17f22023-01-31 20:42:26 +0000333 ret = mbedtls_x509_get_serial(p, end_issuer_and_sn, &signer->serial);
Gilles Peskine449bd832023-01-11 14:50:10 +0100334 if (ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500335 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100336 }
Daniel Axtens35384792020-09-02 14:48:45 +1000337
Nick Childec817092022-12-15 15:54:03 -0600338 /* ensure no extra or missing bytes */
339 if (*p != end_issuer_and_sn) {
340 ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
341 goto out;
342 }
343
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->alg_identifier);
345 if (ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500346 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100347 }
Daniel Axtens35384792020-09-02 14:48:45 +1000348
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500349 /* Check that the digest algorithm used matches the one provided earlier */
350 if (signer->alg_identifier.tag != alg->tag ||
351 signer->alg_identifier.len != alg->len ||
352 memcmp(signer->alg_identifier.p, alg->p, alg->len) != 0) {
353 ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
354 goto out;
355 }
Nick Childbb82ab72022-10-28 12:28:54 -0500356
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500357 /* Asssume authenticatedAttributes is nonexistent */
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->sig_alg_identifier);
359 if (ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500360 goto out;
Bence Szépkútif7641542022-12-12 21:37:36 +0100361 }
Nick Child9f4fb3e2022-09-12 16:21:02 -0500362
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 ret = pkcs7_get_signature(p, end_signer, &signer->sig);
364 if (ret != 0) {
365 goto out;
366 }
367
368 /* Do not permit any unauthenticated attributes */
369 if (*p != end_signer) {
370 ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
371 }
372
373out:
374 if (asn1_ret != 0 || ret != 0) {
375 pkcs7_free_signer_info(signer);
376 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO,
377 asn1_ret);
378 }
379
380 return ret;
Daniel Axtens35384792020-09-02 14:48:45 +1000381}
382
Daniel Axtens35384792020-09-02 14:48:45 +1000383/**
384 * SignerInfos ::= SET of SignerInfo
Nayna Jainc9deb182020-11-16 19:03:12 +0000385 * Return number of signers added to the signed data,
386 * 0 or higher is valid.
387 * Return negative error code for failure.
388 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100389static int pkcs7_get_signers_info_set(unsigned char **p, unsigned char *end,
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500390 mbedtls_pkcs7_signer_info *signers_set,
391 mbedtls_x509_buf *digest_alg)
Nayna Jainc9deb182020-11-16 19:03:12 +0000392{
Daniel Axtens35384792020-09-02 14:48:45 +1000393 unsigned char *end_set;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500394 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Axtens35384792020-09-02 14:48:45 +1000395 int count = 0;
Nayna Jainc9deb182020-11-16 19:03:12 +0000396 size_t len = 0;
397
Gilles Peskine449bd832023-01-11 14:50:10 +0100398 ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
399 | MBEDTLS_ASN1_SET);
400 if (ret != 0) {
401 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO, ret);
Nick Child9f4fb3e2022-09-12 16:21:02 -0500402 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000403
Daniel Axtens35384792020-09-02 14:48:45 +1000404 /* Detect zero signers */
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 if (len == 0) {
406 return 0;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500407 }
Daniel Axtens35384792020-09-02 14:48:45 +1000408
Nayna Jainc9deb182020-11-16 19:03:12 +0000409 end_set = *p + len;
410
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500411 ret = pkcs7_get_signer_info(p, end_set, signers_set, digest_alg);
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 if (ret != 0) {
413 return ret;
414 }
Daniel Axtens35384792020-09-02 14:48:45 +1000415 count++;
Nayna Jainc9deb182020-11-16 19:03:12 +0000416
Gilles Peskine47a73262022-11-27 21:46:56 +0100417 mbedtls_pkcs7_signer_info *prev = signers_set;
Gilles Peskine449bd832023-01-11 14:50:10 +0100418 while (*p != end_set) {
Gilles Peskine47a73262022-11-27 21:46:56 +0100419 mbedtls_pkcs7_signer_info *signer =
Gilles Peskine449bd832023-01-11 14:50:10 +0100420 mbedtls_calloc(1, sizeof(mbedtls_pkcs7_signer_info));
421 if (!signer) {
Daniel Axtens35384792020-09-02 14:48:45 +1000422 ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
423 goto cleanup;
424 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000425
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500426 ret = pkcs7_get_signer_info(p, end_set, signer, digest_alg);
Gilles Peskine449bd832023-01-11 14:50:10 +0100427 if (ret != 0) {
428 mbedtls_free(signer);
Daniel Axtens35384792020-09-02 14:48:45 +1000429 goto cleanup;
430 }
431 prev->next = signer;
432 prev = signer;
433 count++;
434 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000435
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 return count;
Nayna Jainc9deb182020-11-16 19:03:12 +0000437
Daniel Axtens35384792020-09-02 14:48:45 +1000438cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100439 pkcs7_free_signer_info(signers_set);
Gilles Peskine47a73262022-11-27 21:46:56 +0100440 mbedtls_pkcs7_signer_info *signer = signers_set->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100441 while (signer != NULL) {
Daniel Axtens35384792020-09-02 14:48:45 +1000442 prev = signer;
443 signer = signer->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100444 pkcs7_free_signer_info(prev);
445 mbedtls_free(prev);
Daniel Axtens35384792020-09-02 14:48:45 +1000446 }
Gilles Peskine290f01b2022-11-27 21:28:31 +0100447 signers_set->next = NULL;
Gilles Peskine449bd832023-01-11 14:50:10 +0100448 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +0000449}
450
451/**
452 * SignedData ::= SEQUENCE {
453 * version Version,
454 * digestAlgorithms DigestAlgorithmIdentifiers,
455 * contentInfo ContentInfo,
456 * certificates
457 * [0] IMPLICIT ExtendedCertificatesAndCertificates
458 * OPTIONAL,
459 * crls
460 * [0] IMPLICIT CertificateRevocationLists OPTIONAL,
461 * signerInfos SignerInfos }
462 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100463static int pkcs7_get_signed_data(unsigned char *buf, size_t buflen,
464 mbedtls_pkcs7_signed_data *signed_data)
Nayna Jainc9deb182020-11-16 19:03:12 +0000465{
466 unsigned char *p = buf;
467 unsigned char *end = buf + buflen;
Dave Rodgmanf6912682023-02-09 17:55:41 +0000468 unsigned char *end_content_info = NULL;
Nayna Jainc9deb182020-11-16 19:03:12 +0000469 size_t len = 0;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500470 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000471 mbedtls_md_type_t md_alg;
472
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
474 | MBEDTLS_ASN1_SEQUENCE);
475 if (ret != 0) {
476 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
Nick Child9f4fb3e2022-09-12 16:21:02 -0500477 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000478
Demi Marie Obenour4ec83552022-11-28 00:23:00 -0500479 if (p + len != end) {
480 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT,
481 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
482 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000483
484 /* Get version of signed data */
Demi Marie Obenour4ec83552022-11-28 00:23:00 -0500485 ret = pkcs7_get_version(&p, end, &signed_data->version);
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 if (ret != 0) {
487 return ret;
488 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000489
490 /* Get digest algorithm */
Demi Marie Obenour4ec83552022-11-28 00:23:00 -0500491 ret = pkcs7_get_digest_algorithm_set(&p, end,
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 &signed_data->digest_alg_identifiers);
493 if (ret != 0) {
494 return ret;
495 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000496
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 ret = mbedtls_oid_get_md_alg(&signed_data->digest_alg_identifiers, &md_alg);
498 if (ret != 0) {
499 return MBEDTLS_ERR_PKCS7_INVALID_ALG;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500500 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000501
Demi Marie Obenoure373a252022-12-13 23:50:03 -0500502 mbedtls_pkcs7_buf content_type;
Dave Rodgmanf6912682023-02-09 17:55:41 +0000503 memset(&content_type, 0, sizeof(content_type));
Demi Marie Obenoure373a252022-12-13 23:50:03 -0500504 ret = pkcs7_get_content_info_type(&p, end, &end_content_info, &content_type);
Gilles Peskine449bd832023-01-11 14:50:10 +0100505 if (ret != 0) {
506 return ret;
507 }
Demi Marie Obenoure373a252022-12-13 23:50:03 -0500508 if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DATA, &content_type)) {
509 return MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO;
510 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000511
Nick Child3dafc6c2023-02-07 19:59:58 +0000512 if (p != end_content_info) {
513 /* Determine if valid content is present */
Dave Rodgman78c6f402023-02-09 09:21:14 +0000514 ret = mbedtls_asn1_get_tag(&p,
515 end_content_info,
516 &len,
517 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
Nick Child3dafc6c2023-02-07 19:59:58 +0000518 if (ret != 0) {
519 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
520 }
521 p += len;
522 if (p != end_content_info) {
523 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
524 }
525 /* Valid content is present - this is not supported */
526 return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
Nick Childec817092022-12-15 15:54:03 -0600527 }
528
Nayna Jainc9deb182020-11-16 19:03:12 +0000529 /* Look for certificates, there may or may not be any */
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 mbedtls_x509_crt_init(&signed_data->certs);
Demi Marie Obenour4ec83552022-11-28 00:23:00 -0500531 ret = pkcs7_get_certificates(&p, end, &signed_data->certs);
Gilles Peskine449bd832023-01-11 14:50:10 +0100532 if (ret < 0) {
533 return ret;
534 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000535
536 signed_data->no_of_certs = ret;
537
538 /*
539 * Currently CRLs are not supported. If CRL exist, the parsing will fail
540 * at next step of getting signers info and return error as invalid
541 * signer info.
542 */
543
544 signed_data->no_of_crls = 0;
545
546 /* Get signers info */
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500547 ret = pkcs7_get_signers_info_set(&p,
548 end,
549 &signed_data->signers,
550 &signed_data->digest_alg_identifiers);
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 if (ret < 0) {
552 return ret;
553 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000554
555 signed_data->no_of_signers = ret;
556
Daniel Axtens35384792020-09-02 14:48:45 +1000557 /* Don't permit trailing data */
Gilles Peskine449bd832023-01-11 14:50:10 +0100558 if (p != end) {
559 return MBEDTLS_ERR_PKCS7_INVALID_FORMAT;
560 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000561
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 return 0;
Nayna Jainc9deb182020-11-16 19:03:12 +0000563}
564
Gilles Peskine449bd832023-01-11 14:50:10 +0100565int mbedtls_pkcs7_parse_der(mbedtls_pkcs7 *pkcs7, const unsigned char *buf,
566 const size_t buflen)
Nayna Jainc9deb182020-11-16 19:03:12 +0000567{
Nick Childbb82ab72022-10-28 12:28:54 -0500568 unsigned char *p;
Demi Marie Obenour4ec83552022-11-28 00:23:00 -0500569 unsigned char *end;
Nayna Jainc9deb182020-11-16 19:03:12 +0000570 size_t len = 0;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500571 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000572
Gilles Peskine449bd832023-01-11 14:50:10 +0100573 if (pkcs7 == NULL) {
574 return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500575 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000576
577 /* make an internal copy of the buffer for parsing */
Gilles Peskine449bd832023-01-11 14:50:10 +0100578 pkcs7->raw.p = p = mbedtls_calloc(1, buflen);
579 if (pkcs7->raw.p == NULL) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500580 ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
581 goto out;
Nayna Jainc9deb182020-11-16 19:03:12 +0000582 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100583 memcpy(p, buf, buflen);
Nayna Jainc9deb182020-11-16 19:03:12 +0000584 pkcs7->raw.len = buflen;
Nick Childbb82ab72022-10-28 12:28:54 -0500585 end = p + buflen;
Nayna Jainc9deb182020-11-16 19:03:12 +0000586
Demi Marie Obenouraaf3c002022-11-28 00:20:42 -0500587 ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
588 | MBEDTLS_ASN1_SEQUENCE);
Gilles Peskine449bd832023-01-11 14:50:10 +0100589 if (ret != 0) {
Demi Marie Obenouraaf3c002022-11-28 00:20:42 -0500590 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
591 goto out;
592 }
593
594 if ((size_t) (end - p) != len) {
595 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT,
596 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
597 goto out;
598 }
599
600 if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) {
601 if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
602 goto out;
603 }
604 p = pkcs7->raw.p;
Nayna Jain673a2262020-12-14 22:44:49 +0000605 len = buflen;
606 goto try_data;
607 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000608
Demi Marie Obenouraaf3c002022-11-28 00:20:42 -0500609 if (MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_SIGNED_DATA, p, len)) {
610 if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DATA, p, len)
611 || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, p, len)
612 || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_ENVELOPED_DATA, p, len)
613 || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA, p, len)
614 || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DIGESTED_DATA, p, len)) {
615 ret = MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
616 } else {
617 ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
618 }
Nick Childec817092022-12-15 15:54:03 -0600619 goto out;
620 }
621
Demi Marie Obenouraaf3c002022-11-28 00:20:42 -0500622 p += len;
Nayna Jainc9deb182020-11-16 19:03:12 +0000623
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 ret = pkcs7_get_next_content_len(&p, end, &len);
625 if (ret != 0) {
Nayna Jainc9deb182020-11-16 19:03:12 +0000626 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000628
Nick Childec817092022-12-15 15:54:03 -0600629 /* ensure no extra/missing data */
630 if (p + len != end) {
631 ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
632 goto out;
633 }
634
Nayna Jain673a2262020-12-14 22:44:49 +0000635try_data:
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 ret = pkcs7_get_signed_data(p, len, &pkcs7->signed_data);
637 if (ret != 0) {
Nayna Jain673a2262020-12-14 22:44:49 +0000638 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 }
Nayna Jain673a2262020-12-14 22:44:49 +0000640
Nayna Jain673a2262020-12-14 22:44:49 +0000641 ret = MBEDTLS_PKCS7_SIGNED_DATA;
Nayna Jainc9deb182020-11-16 19:03:12 +0000642
643out:
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 if (ret < 0) {
645 mbedtls_pkcs7_free(pkcs7);
646 }
Nayna Jain673a2262020-12-14 22:44:49 +0000647
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +0000649}
650
Gilles Peskine449bd832023-01-11 14:50:10 +0100651static int mbedtls_pkcs7_data_or_hash_verify(mbedtls_pkcs7 *pkcs7,
Nick Child73621ef2022-10-28 11:23:15 -0500652 const mbedtls_x509_crt *cert,
653 const unsigned char *data,
654 size_t datalen,
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 const int is_data_hash)
Nayna Jainc9deb182020-11-16 19:03:12 +0000656{
Nick Child9f4fb3e2022-09-12 16:21:02 -0500657 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000658 unsigned char *hash;
659 mbedtls_pk_context pk_cxt = cert->pk;
660 const mbedtls_md_info_t *md_info;
661 mbedtls_md_type_t md_alg;
Daniel Axtens35384792020-09-02 14:48:45 +1000662 mbedtls_pkcs7_signer_info *signer;
Nayna Jainc9deb182020-11-16 19:03:12 +0000663
Gilles Peskine449bd832023-01-11 14:50:10 +0100664 if (pkcs7->signed_data.no_of_signers == 0) {
665 return MBEDTLS_ERR_PKCS7_INVALID_CERT;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500666 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000667
Gilles Peskine449bd832023-01-11 14:50:10 +0100668 if (mbedtls_x509_time_is_past(&cert->valid_to) ||
669 mbedtls_x509_time_is_future(&cert->valid_from)) {
670 return MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID;
Nick Child73621ef2022-10-28 11:23:15 -0500671 }
672
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500673 ret = mbedtls_oid_get_md_alg(&pkcs7->signed_data.digest_alg_identifiers, &md_alg);
674 if (ret != 0) {
675 return ret;
676 }
677
678 md_info = mbedtls_md_info_from_type(md_alg);
679 if (md_info == NULL) {
680 return MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
681 }
682
683 hash = mbedtls_calloc(mbedtls_md_get_size(md_info), 1);
684 if (hash == NULL) {
685 return MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
686 }
687 /* BEGIN must free hash before jumping out */
688
689 if (is_data_hash) {
690 if (datalen != mbedtls_md_get_size(md_info)) {
691 ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
692 } else {
693 memcpy(hash, data, datalen);
694 }
695 } else {
696 ret = mbedtls_md(md_info, data, datalen, hash);
697 }
698 if (ret != 0) {
699 mbedtls_free(hash);
700 return MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
701 }
702
703 /* assume failure */
704 ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
705
Daniel Axtens35384792020-09-02 14:48:45 +1000706 /*
707 * Potential TODOs
708 * Currently we iterate over all signers and return success if any of them
709 * verify.
710 *
711 * However, we could make this better by checking against the certificate's
712 * identification and SignerIdentifier fields first. That would also allow
713 * us to distinguish between 'no signature for key' and 'signature for key
714 * failed to validate'.
Daniel Axtens35384792020-09-02 14:48:45 +1000715 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100716 for (signer = &pkcs7->signed_data.signers; signer; signer = signer->next) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 ret = mbedtls_pk_verify(&pk_cxt, md_alg, hash,
718 mbedtls_md_get_size(md_info),
719 signer->sig.p, signer->sig.len);
Daniel Axtens35384792020-09-02 14:48:45 +1000720
Gilles Peskine449bd832023-01-11 14:50:10 +0100721 if (ret == 0) {
Daniel Axtens35384792020-09-02 14:48:45 +1000722 break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 }
Daniel Axtens35384792020-09-02 14:48:45 +1000724 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000725
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500726 mbedtls_free(hash);
727 /* END must free hash before jumping out */
Gilles Peskine449bd832023-01-11 14:50:10 +0100728 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +0000729}
Demi Marie Obenour6cfc4692022-11-28 00:46:00 -0500730
Gilles Peskine449bd832023-01-11 14:50:10 +0100731int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7,
732 const mbedtls_x509_crt *cert,
733 const unsigned char *data,
734 size_t datalen)
Nick Child73621ef2022-10-28 11:23:15 -0500735{
Demi Marie Obenour6cfc4692022-11-28 00:46:00 -0500736 if (data == NULL) {
737 return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
738 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100739 return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, data, datalen, 0);
Nick Child73621ef2022-10-28 11:23:15 -0500740}
Nayna Jainc9deb182020-11-16 19:03:12 +0000741
Gilles Peskine449bd832023-01-11 14:50:10 +0100742int mbedtls_pkcs7_signed_hash_verify(mbedtls_pkcs7 *pkcs7,
743 const mbedtls_x509_crt *cert,
744 const unsigned char *hash,
745 size_t hashlen)
Nayna Jainc9deb182020-11-16 19:03:12 +0000746{
Demi Marie Obenour6cfc4692022-11-28 00:46:00 -0500747 if (hash == NULL) {
748 return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
749 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, hash, hashlen, 1);
Nayna Jainc9deb182020-11-16 19:03:12 +0000751}
752
753/*
754 * Unallocate all pkcs7 data
755 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100756void mbedtls_pkcs7_free(mbedtls_pkcs7 *pkcs7)
Nayna Jainc9deb182020-11-16 19:03:12 +0000757{
Daniel Axtens35384792020-09-02 14:48:45 +1000758 mbedtls_pkcs7_signer_info *signer_cur;
759 mbedtls_pkcs7_signer_info *signer_prev;
Nayna Jainc9deb182020-11-16 19:03:12 +0000760
Gilles Peskine449bd832023-01-11 14:50:10 +0100761 if (pkcs7 == NULL || pkcs7->raw.p == NULL) {
Nayna Jainc9deb182020-11-16 19:03:12 +0000762 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100763 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000764
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 mbedtls_free(pkcs7->raw.p);
Nayna Jainc9deb182020-11-16 19:03:12 +0000766
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 mbedtls_x509_crt_free(&pkcs7->signed_data.certs);
768 mbedtls_x509_crl_free(&pkcs7->signed_data.crl);
Nayna Jainc9deb182020-11-16 19:03:12 +0000769
Daniel Axtens35384792020-09-02 14:48:45 +1000770 signer_cur = pkcs7->signed_data.signers.next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100771 pkcs7_free_signer_info(&pkcs7->signed_data.signers);
772 while (signer_cur != NULL) {
Daniel Axtens35384792020-09-02 14:48:45 +1000773 signer_prev = signer_cur;
774 signer_cur = signer_prev->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 pkcs7_free_signer_info(signer_prev);
776 mbedtls_free(signer_prev);
Nayna Jainc9deb182020-11-16 19:03:12 +0000777 }
778
779 pkcs7->raw.p = NULL;
780}
781
782#endif