blob: 9b53ceea35a26b8efd6ed0c0365bb6722362646a [file] [log] [blame]
Nick Child5d881c32022-02-28 10:09:16 -06001/*
2 * Copyright The Mbed TLS Contributors
Dave Rodgman16799db2023-11-02 19:47:20 +00003 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Nayna Jainc9deb182020-11-16 19:03:12 +00004 */
Harry Ramsey0f6bc412024-10-04 10:36:54 +01005#include "x509_internal.h"
Nayna Jainc9deb182020-11-16 19:03:12 +00006
7#include "mbedtls/build_info.h"
8#if defined(MBEDTLS_PKCS7_C)
9#include "mbedtls/pkcs7.h"
Nayna Jainc9deb182020-11-16 19:03:12 +000010#include "mbedtls/asn1.h"
11#include "mbedtls/x509_crt.h"
12#include "mbedtls/x509_crl.h"
13#include "mbedtls/oid.h"
Nick Child9f4fb3e2022-09-12 16:21:02 -050014#include "mbedtls/error.h"
Nayna Jainc9deb182020-11-16 19:03:12 +000015
Nayna Jainc9deb182020-11-16 19:03:12 +000016#if defined(MBEDTLS_FS_IO)
17#include <sys/types.h>
18#include <sys/stat.h>
19#endif
20
Nayna Jainc9deb182020-11-16 19:03:12 +000021#include "mbedtls/platform.h"
22#include "mbedtls/platform_util.h"
Nayna Jainc9deb182020-11-16 19:03:12 +000023
24#if defined(MBEDTLS_HAVE_TIME)
25#include "mbedtls/platform_time.h"
26#endif
27#if defined(MBEDTLS_HAVE_TIME_DATE)
28#include <time.h>
29#endif
30
31/**
Dave Rodgmanefbc5f72023-03-13 12:15:49 +000032 * Initializes the mbedtls_pkcs7 structure.
Nayna Jainc9deb182020-11-16 19:03:12 +000033 */
Gilles Peskine449bd832023-01-11 14:50:10 +010034void mbedtls_pkcs7_init(mbedtls_pkcs7 *pkcs7)
Nayna Jainc9deb182020-11-16 19:03:12 +000035{
Gilles Peskine449bd832023-01-11 14:50:10 +010036 memset(pkcs7, 0, sizeof(*pkcs7));
Nayna Jainc9deb182020-11-16 19:03:12 +000037}
38
Gilles Peskine449bd832023-01-11 14:50:10 +010039static int pkcs7_get_next_content_len(unsigned char **p, unsigned char *end,
40 size_t *len)
Nayna Jainc9deb182020-11-16 19:03:12 +000041{
Nick Child9f4fb3e2022-09-12 16:21:02 -050042 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +000043
Gilles Peskine449bd832023-01-11 14:50:10 +010044 ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_CONSTRUCTED
45 | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
46 if (ret != 0) {
Demi Marie Obenour6cfc4692022-11-28 00:46:00 -050047 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
Demi Marie Obenour512818b2022-11-27 22:48:55 -050048 } else if ((size_t) (end - *p) != *len) {
Demi Marie Obenour6cfc4692022-11-28 00:46:00 -050049 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO,
Demi Marie Obenour512818b2022-11-27 22:48:55 -050050 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
Nayna Jainc9deb182020-11-16 19:03:12 +000051 }
52
Gilles Peskine449bd832023-01-11 14:50:10 +010053 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +000054}
55
56/**
57 * version Version
58 * Version ::= INTEGER
59 **/
Gilles Peskine449bd832023-01-11 14:50:10 +010060static int pkcs7_get_version(unsigned char **p, unsigned char *end, int *ver)
Nayna Jainc9deb182020-11-16 19:03:12 +000061{
Nick Child9f4fb3e2022-09-12 16:21:02 -050062 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +000063
Gilles Peskine449bd832023-01-11 14:50:10 +010064 ret = mbedtls_asn1_get_int(p, end, ver);
65 if (ret != 0) {
66 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_VERSION, ret);
67 }
Nayna Jainc9deb182020-11-16 19:03:12 +000068
69 /* If version != 1, return invalid version */
Gilles Peskine449bd832023-01-11 14:50:10 +010070 if (*ver != MBEDTLS_PKCS7_SUPPORTED_VERSION) {
Nick Child9f4fb3e2022-09-12 16:21:02 -050071 ret = MBEDTLS_ERR_PKCS7_INVALID_VERSION;
Gilles Peskine449bd832023-01-11 14:50:10 +010072 }
Nayna Jainc9deb182020-11-16 19:03:12 +000073
Gilles Peskine449bd832023-01-11 14:50:10 +010074 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +000075}
76
77/**
78 * ContentInfo ::= SEQUENCE {
79 * contentType ContentType,
80 * content
81 * [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
82 **/
Gilles Peskine449bd832023-01-11 14:50:10 +010083static int pkcs7_get_content_info_type(unsigned char **p, unsigned char *end,
Nick Childec817092022-12-15 15:54:03 -060084 unsigned char **seq_end,
Gilles Peskine449bd832023-01-11 14:50:10 +010085 mbedtls_pkcs7_buf *pkcs7)
Nayna Jainc9deb182020-11-16 19:03:12 +000086{
87 size_t len = 0;
Nick Child9f4fb3e2022-09-12 16:21:02 -050088 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jain673a2262020-12-14 22:44:49 +000089 unsigned char *start = *p;
Nayna Jainc9deb182020-11-16 19:03:12 +000090
Gilles Peskine449bd832023-01-11 14:50:10 +010091 ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
92 | MBEDTLS_ASN1_SEQUENCE);
93 if (ret != 0) {
Nick Childc448c942021-07-01 15:29:50 -040094 *p = start;
Gilles Peskine449bd832023-01-11 14:50:10 +010095 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
Nick Childc448c942021-07-01 15:29:50 -040096 }
Nick Childec817092022-12-15 15:54:03 -060097 *seq_end = *p + len;
98 ret = mbedtls_asn1_get_tag(p, *seq_end, &len, MBEDTLS_ASN1_OID);
Gilles Peskine449bd832023-01-11 14:50:10 +010099 if (ret != 0) {
Nayna Jain673a2262020-12-14 22:44:49 +0000100 *p = start;
Gilles Peskine449bd832023-01-11 14:50:10 +0100101 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
Nayna Jain673a2262020-12-14 22:44:49 +0000102 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000103
104 pkcs7->tag = MBEDTLS_ASN1_OID;
105 pkcs7->len = len;
106 pkcs7->p = *p;
Nick Childbb82ab72022-10-28 12:28:54 -0500107 *p += len;
Nayna Jainc9deb182020-11-16 19:03:12 +0000108
Gilles Peskine449bd832023-01-11 14:50:10 +0100109 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +0000110}
111
112/**
113 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
114 *
115 * This is from x509.h
116 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100117static int pkcs7_get_digest_algorithm(unsigned char **p, unsigned char *end,
118 mbedtls_x509_buf *alg)
Nayna Jainc9deb182020-11-16 19:03:12 +0000119{
Nick Child9f4fb3e2022-09-12 16:21:02 -0500120 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000121
Gilles Peskine449bd832023-01-11 14:50:10 +0100122 if ((ret = mbedtls_asn1_get_alg_null(p, end, alg)) != 0) {
123 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
124 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000125
Gilles Peskine449bd832023-01-11 14:50:10 +0100126 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +0000127}
128
129/**
130 * DigestAlgorithmIdentifiers :: SET of DigestAlgorithmIdentifier
131 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100132static int pkcs7_get_digest_algorithm_set(unsigned char **p,
133 unsigned char *end,
134 mbedtls_x509_buf *alg)
Nayna Jainc9deb182020-11-16 19:03:12 +0000135{
136 size_t len = 0;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500137 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000138
Gilles Peskine449bd832023-01-11 14:50:10 +0100139 ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
140 | MBEDTLS_ASN1_SET);
141 if (ret != 0) {
142 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
Nick Child9f4fb3e2022-09-12 16:21:02 -0500143 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000144
145 end = *p + len;
146
Gilles Peskine449bd832023-01-11 14:50:10 +0100147 ret = mbedtls_asn1_get_alg_null(p, end, alg);
148 if (ret != 0) {
149 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
Nick Child9f4fb3e2022-09-12 16:21:02 -0500150 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000151
Nick Child34d5e932022-09-14 14:44:03 -0500152 /** For now, it assumes there is only one digest algorithm specified **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100153 if (*p != end) {
154 return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
155 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000156
Gilles Peskine449bd832023-01-11 14:50:10 +0100157 return 0;
Nayna Jainc9deb182020-11-16 19:03:12 +0000158}
159
160/**
161 * certificates :: SET OF ExtendedCertificateOrCertificate,
162 * ExtendedCertificateOrCertificate ::= CHOICE {
163 * certificate Certificate -- x509,
164 * extendedCertificate[0] IMPLICIT ExtendedCertificate }
165 * Return number of certificates added to the signed data,
166 * 0 or higher is valid.
167 * Return negative error code for failure.
168 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100169static int pkcs7_get_certificates(unsigned char **p, unsigned char *end,
170 mbedtls_x509_crt *certs)
Nayna Jainc9deb182020-11-16 19:03:12 +0000171{
Nick Child9f4fb3e2022-09-12 16:21:02 -0500172 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000173 size_t len1 = 0;
174 size_t len2 = 0;
Nick Childbb82ab72022-10-28 12:28:54 -0500175 unsigned char *end_set, *end_cert, *start;
Nayna Jainc9deb182020-11-16 19:03:12 +0000176
Demi Marie Obenour6cfc4692022-11-28 00:46:00 -0500177 ret = mbedtls_asn1_get_tag(p, end, &len1, MBEDTLS_ASN1_CONSTRUCTED
178 | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
179 if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
180 return 0;
181 }
182 if (ret != 0) {
183 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
Nayna Jainc9deb182020-11-16 19:03:12 +0000184 }
185 start = *p;
186 end_set = *p + len1;
187
Gilles Peskine449bd832023-01-11 14:50:10 +0100188 ret = mbedtls_asn1_get_tag(p, end_set, &len2, MBEDTLS_ASN1_CONSTRUCTED
189 | MBEDTLS_ASN1_SEQUENCE);
190 if (ret != 0) {
191 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CERT, ret);
Nick Child9f4fb3e2022-09-12 16:21:02 -0500192 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000193
194 end_cert = *p + len2;
195
196 /*
197 * This is to verify that there is only one signer certificate. It seems it is
198 * not easy to differentiate between the chain vs different signer's certificate.
199 * So, we support only the root certificate and the single signer.
200 * The behaviour would be improved with addition of multiple signer support.
201 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100202 if (end_cert != end_set) {
203 return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500204 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000205
Demi Marie Obenour55d9df22022-11-28 00:29:32 -0500206 if ((ret = mbedtls_x509_crt_parse_der(certs, start, len1)) < 0) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100207 return MBEDTLS_ERR_PKCS7_INVALID_CERT;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500208 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000209
Demi Marie Obenour55d9df22022-11-28 00:29:32 -0500210 *p = end_cert;
Nayna Jainc9deb182020-11-16 19:03:12 +0000211
Nick Child5f9456f2022-09-19 10:01:25 -0500212 /*
Nick Child9f4fb3e2022-09-12 16:21:02 -0500213 * Since in this version we strictly support single certificate, and reaching
Nick Child5f9456f2022-09-19 10:01:25 -0500214 * here implies we have parsed successfully, we return 1.
Nick Child9f4fb3e2022-09-12 16:21:02 -0500215 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100216 return 1;
Nayna Jainc9deb182020-11-16 19:03:12 +0000217}
218
219/**
220 * EncryptedDigest ::= OCTET STRING
221 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100222static int pkcs7_get_signature(unsigned char **p, unsigned char *end,
223 mbedtls_pkcs7_buf *signature)
Nayna Jainc9deb182020-11-16 19:03:12 +0000224{
Nick Child9f4fb3e2022-09-12 16:21:02 -0500225 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000226 size_t len = 0;
227
Gilles Peskine449bd832023-01-11 14:50:10 +0100228 ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
229 if (ret != 0) {
230 return ret;
231 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000232
233 signature->tag = MBEDTLS_ASN1_OCTET_STRING;
234 signature->len = len;
235 signature->p = *p;
236
237 *p = *p + len;
238
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 return 0;
Nayna Jainc9deb182020-11-16 19:03:12 +0000240}
241
Gilles Peskine449bd832023-01-11 14:50:10 +0100242static void pkcs7_free_signer_info(mbedtls_pkcs7_signer_info *signer)
Bence Szépkútif7641542022-12-12 21:37:36 +0100243{
244 mbedtls_x509_name *name_cur;
245 mbedtls_x509_name *name_prv;
246
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 if (signer == NULL) {
Bence Szépkútif7641542022-12-12 21:37:36 +0100248 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 }
Bence Szépkútif7641542022-12-12 21:37:36 +0100250
251 name_cur = signer->issuer.next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 while (name_cur != NULL) {
Bence Szépkútif7641542022-12-12 21:37:36 +0100253 name_prv = name_cur;
254 name_cur = name_cur->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 mbedtls_free(name_prv);
Bence Szépkútif7641542022-12-12 21:37:36 +0100256 }
257 signer->issuer.next = NULL;
258}
259
Nayna Jainc9deb182020-11-16 19:03:12 +0000260/**
Nayna Jainc9deb182020-11-16 19:03:12 +0000261 * SignerInfo ::= SEQUENCE {
262 * version Version;
263 * issuerAndSerialNumber IssuerAndSerialNumber,
264 * digestAlgorithm DigestAlgorithmIdentifier,
265 * authenticatedAttributes
266 * [0] IMPLICIT Attributes OPTIONAL,
267 * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
268 * encryptedDigest EncryptedDigest,
269 * unauthenticatedAttributes
270 * [1] IMPLICIT Attributes OPTIONAL,
Daniel Axtens35384792020-09-02 14:48:45 +1000271 * Returns 0 if the signerInfo is valid.
272 * Return negative error code for failure.
Nick Childbb82ab72022-10-28 12:28:54 -0500273 * Structure must not contain vales for authenticatedAttributes
274 * and unauthenticatedAttributes.
Daniel Axtens35384792020-09-02 14:48:45 +1000275 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100276static int pkcs7_get_signer_info(unsigned char **p, unsigned char *end,
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500277 mbedtls_pkcs7_signer_info *signer,
278 mbedtls_x509_buf *alg)
Daniel Axtens35384792020-09-02 14:48:45 +1000279{
Nick Childec817092022-12-15 15:54:03 -0600280 unsigned char *end_signer, *end_issuer_and_sn;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500281 int asn1_ret = 0, ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Axtens35384792020-09-02 14:48:45 +1000282 size_t len = 0;
283
Gilles Peskine449bd832023-01-11 14:50:10 +0100284 asn1_ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
285 | MBEDTLS_ASN1_SEQUENCE);
286 if (asn1_ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500287 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100288 }
Daniel Axtens35384792020-09-02 14:48:45 +1000289
290 end_signer = *p + len;
291
Gilles Peskine449bd832023-01-11 14:50:10 +0100292 ret = pkcs7_get_version(p, end_signer, &signer->version);
293 if (ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500294 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100295 }
Daniel Axtens35384792020-09-02 14:48:45 +1000296
Gilles Peskine449bd832023-01-11 14:50:10 +0100297 asn1_ret = mbedtls_asn1_get_tag(p, end_signer, &len,
298 MBEDTLS_ASN1_CONSTRUCTED | 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
Nick Childec817092022-12-15 15:54:03 -0600303 end_issuer_and_sn = *p + len;
Daniel Axtens35384792020-09-02 14:48:45 +1000304 /* Parsing IssuerAndSerialNumber */
305 signer->issuer_raw.p = *p;
306
Nick Child3bd17f22023-01-31 20:42:26 +0000307 asn1_ret = mbedtls_asn1_get_tag(p, end_issuer_and_sn, &len,
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
309 if (asn1_ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500310 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 }
Daniel Axtens35384792020-09-02 14:48:45 +1000312
Gilles Peskine449bd832023-01-11 14:50:10 +0100313 ret = mbedtls_x509_get_name(p, *p + len, &signer->issuer);
314 if (ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500315 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100316 }
Daniel Axtens35384792020-09-02 14:48:45 +1000317
Dave Rodgmane4a6f5a2023-11-04 12:20:09 +0000318 signer->issuer_raw.len = (size_t) (*p - signer->issuer_raw.p);
Daniel Axtens35384792020-09-02 14:48:45 +1000319
Nick Child3bd17f22023-01-31 20:42:26 +0000320 ret = mbedtls_x509_get_serial(p, end_issuer_and_sn, &signer->serial);
Gilles Peskine449bd832023-01-11 14:50:10 +0100321 if (ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500322 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100323 }
Daniel Axtens35384792020-09-02 14:48:45 +1000324
Nick Childec817092022-12-15 15:54:03 -0600325 /* ensure no extra or missing bytes */
326 if (*p != end_issuer_and_sn) {
327 ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
328 goto out;
329 }
330
Gilles Peskine449bd832023-01-11 14:50:10 +0100331 ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->alg_identifier);
332 if (ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500333 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100334 }
Daniel Axtens35384792020-09-02 14:48:45 +1000335
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500336 /* Check that the digest algorithm used matches the one provided earlier */
337 if (signer->alg_identifier.tag != alg->tag ||
338 signer->alg_identifier.len != alg->len ||
339 memcmp(signer->alg_identifier.p, alg->p, alg->len) != 0) {
340 ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
341 goto out;
342 }
Nick Childbb82ab72022-10-28 12:28:54 -0500343
Tom Cosgrove5c8505f2023-03-07 11:39:52 +0000344 /* Assume authenticatedAttributes is nonexistent */
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->sig_alg_identifier);
346 if (ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500347 goto out;
Bence Szépkútif7641542022-12-12 21:37:36 +0100348 }
Nick Child9f4fb3e2022-09-12 16:21:02 -0500349
Gilles Peskine449bd832023-01-11 14:50:10 +0100350 ret = pkcs7_get_signature(p, end_signer, &signer->sig);
351 if (ret != 0) {
352 goto out;
353 }
354
355 /* Do not permit any unauthenticated attributes */
356 if (*p != end_signer) {
357 ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
358 }
359
360out:
361 if (asn1_ret != 0 || ret != 0) {
362 pkcs7_free_signer_info(signer);
363 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO,
364 asn1_ret);
365 }
366
367 return ret;
Daniel Axtens35384792020-09-02 14:48:45 +1000368}
369
Daniel Axtens35384792020-09-02 14:48:45 +1000370/**
371 * SignerInfos ::= SET of SignerInfo
Nayna Jainc9deb182020-11-16 19:03:12 +0000372 * Return number of signers added to the signed data,
373 * 0 or higher is valid.
374 * Return negative error code for failure.
375 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100376static int pkcs7_get_signers_info_set(unsigned char **p, unsigned char *end,
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500377 mbedtls_pkcs7_signer_info *signers_set,
378 mbedtls_x509_buf *digest_alg)
Nayna Jainc9deb182020-11-16 19:03:12 +0000379{
Daniel Axtens35384792020-09-02 14:48:45 +1000380 unsigned char *end_set;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500381 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Axtens35384792020-09-02 14:48:45 +1000382 int count = 0;
Nayna Jainc9deb182020-11-16 19:03:12 +0000383 size_t len = 0;
384
Gilles Peskine449bd832023-01-11 14:50:10 +0100385 ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
386 | MBEDTLS_ASN1_SET);
387 if (ret != 0) {
388 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO, ret);
Nick Child9f4fb3e2022-09-12 16:21:02 -0500389 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000390
Daniel Axtens35384792020-09-02 14:48:45 +1000391 /* Detect zero signers */
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 if (len == 0) {
393 return 0;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500394 }
Daniel Axtens35384792020-09-02 14:48:45 +1000395
Nayna Jainc9deb182020-11-16 19:03:12 +0000396 end_set = *p + len;
397
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500398 ret = pkcs7_get_signer_info(p, end_set, signers_set, digest_alg);
Gilles Peskine449bd832023-01-11 14:50:10 +0100399 if (ret != 0) {
400 return ret;
401 }
Daniel Axtens35384792020-09-02 14:48:45 +1000402 count++;
Nayna Jainc9deb182020-11-16 19:03:12 +0000403
Gilles Peskine47a73262022-11-27 21:46:56 +0100404 mbedtls_pkcs7_signer_info *prev = signers_set;
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 while (*p != end_set) {
Gilles Peskine47a73262022-11-27 21:46:56 +0100406 mbedtls_pkcs7_signer_info *signer =
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 mbedtls_calloc(1, sizeof(mbedtls_pkcs7_signer_info));
408 if (!signer) {
Daniel Axtens35384792020-09-02 14:48:45 +1000409 ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
410 goto cleanup;
411 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000412
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500413 ret = pkcs7_get_signer_info(p, end_set, signer, digest_alg);
Gilles Peskine449bd832023-01-11 14:50:10 +0100414 if (ret != 0) {
415 mbedtls_free(signer);
Daniel Axtens35384792020-09-02 14:48:45 +1000416 goto cleanup;
417 }
418 prev->next = signer;
419 prev = signer;
420 count++;
421 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000422
Gilles Peskine449bd832023-01-11 14:50:10 +0100423 return count;
Nayna Jainc9deb182020-11-16 19:03:12 +0000424
Daniel Axtens35384792020-09-02 14:48:45 +1000425cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100426 pkcs7_free_signer_info(signers_set);
Gilles Peskine47a73262022-11-27 21:46:56 +0100427 mbedtls_pkcs7_signer_info *signer = signers_set->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100428 while (signer != NULL) {
Daniel Axtens35384792020-09-02 14:48:45 +1000429 prev = signer;
430 signer = signer->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100431 pkcs7_free_signer_info(prev);
432 mbedtls_free(prev);
Daniel Axtens35384792020-09-02 14:48:45 +1000433 }
Gilles Peskine290f01b2022-11-27 21:28:31 +0100434 signers_set->next = NULL;
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +0000436}
437
438/**
439 * SignedData ::= SEQUENCE {
440 * version Version,
441 * digestAlgorithms DigestAlgorithmIdentifiers,
442 * contentInfo ContentInfo,
443 * certificates
444 * [0] IMPLICIT ExtendedCertificatesAndCertificates
445 * OPTIONAL,
446 * crls
447 * [0] IMPLICIT CertificateRevocationLists OPTIONAL,
448 * signerInfos SignerInfos }
449 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100450static int pkcs7_get_signed_data(unsigned char *buf, size_t buflen,
451 mbedtls_pkcs7_signed_data *signed_data)
Nayna Jainc9deb182020-11-16 19:03:12 +0000452{
453 unsigned char *p = buf;
454 unsigned char *end = buf + buflen;
Dave Rodgmanf6912682023-02-09 17:55:41 +0000455 unsigned char *end_content_info = NULL;
Nayna Jainc9deb182020-11-16 19:03:12 +0000456 size_t len = 0;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500457 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000458 mbedtls_md_type_t md_alg;
459
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
461 | MBEDTLS_ASN1_SEQUENCE);
462 if (ret != 0) {
463 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
Nick Child9f4fb3e2022-09-12 16:21:02 -0500464 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000465
Demi Marie Obenour4ec83552022-11-28 00:23:00 -0500466 if (p + len != end) {
467 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT,
468 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
469 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000470
471 /* Get version of signed data */
Demi Marie Obenour4ec83552022-11-28 00:23:00 -0500472 ret = pkcs7_get_version(&p, end, &signed_data->version);
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 if (ret != 0) {
474 return ret;
475 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000476
477 /* Get digest algorithm */
Demi Marie Obenour4ec83552022-11-28 00:23:00 -0500478 ret = pkcs7_get_digest_algorithm_set(&p, end,
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 &signed_data->digest_alg_identifiers);
480 if (ret != 0) {
481 return ret;
482 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000483
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 ret = mbedtls_oid_get_md_alg(&signed_data->digest_alg_identifiers, &md_alg);
485 if (ret != 0) {
486 return MBEDTLS_ERR_PKCS7_INVALID_ALG;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500487 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000488
Demi Marie Obenoure373a252022-12-13 23:50:03 -0500489 mbedtls_pkcs7_buf content_type;
Dave Rodgmanf6912682023-02-09 17:55:41 +0000490 memset(&content_type, 0, sizeof(content_type));
Demi Marie Obenoure373a252022-12-13 23:50:03 -0500491 ret = pkcs7_get_content_info_type(&p, end, &end_content_info, &content_type);
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 if (ret != 0) {
493 return ret;
494 }
Demi Marie Obenoure373a252022-12-13 23:50:03 -0500495 if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DATA, &content_type)) {
496 return MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO;
497 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000498
Nick Child3dafc6c2023-02-07 19:59:58 +0000499 if (p != end_content_info) {
500 /* Determine if valid content is present */
Dave Rodgman78c6f402023-02-09 09:21:14 +0000501 ret = mbedtls_asn1_get_tag(&p,
502 end_content_info,
503 &len,
504 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
Nick Child3dafc6c2023-02-07 19:59:58 +0000505 if (ret != 0) {
506 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
507 }
508 p += len;
509 if (p != end_content_info) {
510 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
511 }
512 /* Valid content is present - this is not supported */
513 return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
Nick Childec817092022-12-15 15:54:03 -0600514 }
515
Nayna Jainc9deb182020-11-16 19:03:12 +0000516 /* Look for certificates, there may or may not be any */
Gilles Peskine449bd832023-01-11 14:50:10 +0100517 mbedtls_x509_crt_init(&signed_data->certs);
Demi Marie Obenour4ec83552022-11-28 00:23:00 -0500518 ret = pkcs7_get_certificates(&p, end, &signed_data->certs);
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 if (ret < 0) {
520 return ret;
521 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000522
523 signed_data->no_of_certs = ret;
524
525 /*
526 * Currently CRLs are not supported. If CRL exist, the parsing will fail
527 * at next step of getting signers info and return error as invalid
528 * signer info.
529 */
530
531 signed_data->no_of_crls = 0;
532
533 /* Get signers info */
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500534 ret = pkcs7_get_signers_info_set(&p,
535 end,
536 &signed_data->signers,
537 &signed_data->digest_alg_identifiers);
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 if (ret < 0) {
539 return ret;
540 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000541
542 signed_data->no_of_signers = ret;
543
Daniel Axtens35384792020-09-02 14:48:45 +1000544 /* Don't permit trailing data */
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 if (p != end) {
546 return MBEDTLS_ERR_PKCS7_INVALID_FORMAT;
547 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000548
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 return 0;
Nayna Jainc9deb182020-11-16 19:03:12 +0000550}
551
Gilles Peskine449bd832023-01-11 14:50:10 +0100552int mbedtls_pkcs7_parse_der(mbedtls_pkcs7 *pkcs7, const unsigned char *buf,
553 const size_t buflen)
Nayna Jainc9deb182020-11-16 19:03:12 +0000554{
Nick Childbb82ab72022-10-28 12:28:54 -0500555 unsigned char *p;
Demi Marie Obenour4ec83552022-11-28 00:23:00 -0500556 unsigned char *end;
Nayna Jainc9deb182020-11-16 19:03:12 +0000557 size_t len = 0;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500558 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000559
Gilles Peskine449bd832023-01-11 14:50:10 +0100560 if (pkcs7 == NULL) {
561 return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500562 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000563
564 /* make an internal copy of the buffer for parsing */
Gilles Peskine449bd832023-01-11 14:50:10 +0100565 pkcs7->raw.p = p = mbedtls_calloc(1, buflen);
566 if (pkcs7->raw.p == NULL) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500567 ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
568 goto out;
Nayna Jainc9deb182020-11-16 19:03:12 +0000569 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100570 memcpy(p, buf, buflen);
Nayna Jainc9deb182020-11-16 19:03:12 +0000571 pkcs7->raw.len = buflen;
Nick Childbb82ab72022-10-28 12:28:54 -0500572 end = p + buflen;
Nayna Jainc9deb182020-11-16 19:03:12 +0000573
Demi Marie Obenouraaf3c002022-11-28 00:20:42 -0500574 ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
575 | MBEDTLS_ASN1_SEQUENCE);
Gilles Peskine449bd832023-01-11 14:50:10 +0100576 if (ret != 0) {
Demi Marie Obenouraaf3c002022-11-28 00:20:42 -0500577 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
578 goto out;
579 }
580
581 if ((size_t) (end - p) != len) {
582 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT,
583 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
584 goto out;
585 }
586
587 if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) {
588 if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
589 goto out;
590 }
591 p = pkcs7->raw.p;
Nayna Jain673a2262020-12-14 22:44:49 +0000592 len = buflen;
593 goto try_data;
594 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000595
Demi Marie Obenouraaf3c002022-11-28 00:20:42 -0500596 if (MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_SIGNED_DATA, p, len)) {
Dave Rodgmana1b2bff2023-02-20 14:45:09 +0000597 /* OID is not MBEDTLS_OID_PKCS7_SIGNED_DATA, which is the only supported feature */
Demi Marie Obenouraaf3c002022-11-28 00:20:42 -0500598 if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DATA, p, len)
599 || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, p, len)
600 || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_ENVELOPED_DATA, p, len)
601 || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA, p, len)
602 || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DIGESTED_DATA, p, len)) {
Dave Rodgmana1b2bff2023-02-20 14:45:09 +0000603 /* OID is valid according to the spec, but unsupported */
Demi Marie Obenouraaf3c002022-11-28 00:20:42 -0500604 ret = MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
605 } else {
Dave Rodgmana1b2bff2023-02-20 14:45:09 +0000606 /* OID is invalid according to the spec */
Demi Marie Obenouraaf3c002022-11-28 00:20:42 -0500607 ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
608 }
Nick Childec817092022-12-15 15:54:03 -0600609 goto out;
610 }
611
Demi Marie Obenouraaf3c002022-11-28 00:20:42 -0500612 p += len;
Nayna Jainc9deb182020-11-16 19:03:12 +0000613
Gilles Peskine449bd832023-01-11 14:50:10 +0100614 ret = pkcs7_get_next_content_len(&p, end, &len);
615 if (ret != 0) {
Nayna Jainc9deb182020-11-16 19:03:12 +0000616 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000618
Nick Childec817092022-12-15 15:54:03 -0600619 /* ensure no extra/missing data */
620 if (p + len != end) {
621 ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
622 goto out;
623 }
624
Nayna Jain673a2262020-12-14 22:44:49 +0000625try_data:
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 ret = pkcs7_get_signed_data(p, len, &pkcs7->signed_data);
627 if (ret != 0) {
Nayna Jain673a2262020-12-14 22:44:49 +0000628 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100629 }
Nayna Jain673a2262020-12-14 22:44:49 +0000630
Nayna Jain673a2262020-12-14 22:44:49 +0000631 ret = MBEDTLS_PKCS7_SIGNED_DATA;
Nayna Jainc9deb182020-11-16 19:03:12 +0000632
633out:
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 if (ret < 0) {
635 mbedtls_pkcs7_free(pkcs7);
636 }
Nayna Jain673a2262020-12-14 22:44:49 +0000637
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +0000639}
640
Gilles Peskine449bd832023-01-11 14:50:10 +0100641static int mbedtls_pkcs7_data_or_hash_verify(mbedtls_pkcs7 *pkcs7,
Nick Child73621ef2022-10-28 11:23:15 -0500642 const mbedtls_x509_crt *cert,
643 const unsigned char *data,
644 size_t datalen,
Gilles Peskine449bd832023-01-11 14:50:10 +0100645 const int is_data_hash)
Nayna Jainc9deb182020-11-16 19:03:12 +0000646{
Nick Child9f4fb3e2022-09-12 16:21:02 -0500647 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000648 unsigned char *hash;
649 mbedtls_pk_context pk_cxt = cert->pk;
650 const mbedtls_md_info_t *md_info;
651 mbedtls_md_type_t md_alg;
Daniel Axtens35384792020-09-02 14:48:45 +1000652 mbedtls_pkcs7_signer_info *signer;
Nayna Jainc9deb182020-11-16 19:03:12 +0000653
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 if (pkcs7->signed_data.no_of_signers == 0) {
655 return MBEDTLS_ERR_PKCS7_INVALID_CERT;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500656 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000657
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 if (mbedtls_x509_time_is_past(&cert->valid_to) ||
659 mbedtls_x509_time_is_future(&cert->valid_from)) {
660 return MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID;
Nick Child73621ef2022-10-28 11:23:15 -0500661 }
662
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500663 ret = mbedtls_oid_get_md_alg(&pkcs7->signed_data.digest_alg_identifiers, &md_alg);
664 if (ret != 0) {
665 return ret;
666 }
667
668 md_info = mbedtls_md_info_from_type(md_alg);
669 if (md_info == NULL) {
670 return MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
671 }
672
673 hash = mbedtls_calloc(mbedtls_md_get_size(md_info), 1);
674 if (hash == NULL) {
675 return MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
676 }
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500677
Dave Rodgmanfc643522023-02-16 16:23:09 +0000678 /* BEGIN must free hash before jumping out */
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500679 if (is_data_hash) {
680 if (datalen != mbedtls_md_get_size(md_info)) {
681 ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
682 } else {
683 memcpy(hash, data, datalen);
684 }
685 } else {
686 ret = mbedtls_md(md_info, data, datalen, hash);
687 }
688 if (ret != 0) {
689 mbedtls_free(hash);
690 return MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
691 }
692
693 /* assume failure */
694 ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
695
Daniel Axtens35384792020-09-02 14:48:45 +1000696 /*
697 * Potential TODOs
698 * Currently we iterate over all signers and return success if any of them
699 * verify.
700 *
701 * However, we could make this better by checking against the certificate's
702 * identification and SignerIdentifier fields first. That would also allow
703 * us to distinguish between 'no signature for key' and 'signature for key
704 * failed to validate'.
Daniel Axtens35384792020-09-02 14:48:45 +1000705 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100706 for (signer = &pkcs7->signed_data.signers; signer; signer = signer->next) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 ret = mbedtls_pk_verify(&pk_cxt, md_alg, hash,
708 mbedtls_md_get_size(md_info),
709 signer->sig.p, signer->sig.len);
Daniel Axtens35384792020-09-02 14:48:45 +1000710
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 if (ret == 0) {
Daniel Axtens35384792020-09-02 14:48:45 +1000712 break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 }
Daniel Axtens35384792020-09-02 14:48:45 +1000714 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000715
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500716 mbedtls_free(hash);
717 /* END must free hash before jumping out */
Gilles Peskine449bd832023-01-11 14:50:10 +0100718 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +0000719}
Demi Marie Obenour6cfc4692022-11-28 00:46:00 -0500720
Gilles Peskine449bd832023-01-11 14:50:10 +0100721int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7,
722 const mbedtls_x509_crt *cert,
723 const unsigned char *data,
724 size_t datalen)
Nick Child73621ef2022-10-28 11:23:15 -0500725{
Demi Marie Obenour6cfc4692022-11-28 00:46:00 -0500726 if (data == NULL) {
727 return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
728 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100729 return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, data, datalen, 0);
Nick Child73621ef2022-10-28 11:23:15 -0500730}
Nayna Jainc9deb182020-11-16 19:03:12 +0000731
Gilles Peskine449bd832023-01-11 14:50:10 +0100732int mbedtls_pkcs7_signed_hash_verify(mbedtls_pkcs7 *pkcs7,
733 const mbedtls_x509_crt *cert,
734 const unsigned char *hash,
735 size_t hashlen)
Nayna Jainc9deb182020-11-16 19:03:12 +0000736{
Demi Marie Obenour6cfc4692022-11-28 00:46:00 -0500737 if (hash == NULL) {
738 return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
739 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100740 return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, hash, hashlen, 1);
Nayna Jainc9deb182020-11-16 19:03:12 +0000741}
742
743/*
744 * Unallocate all pkcs7 data
745 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100746void mbedtls_pkcs7_free(mbedtls_pkcs7 *pkcs7)
Nayna Jainc9deb182020-11-16 19:03:12 +0000747{
Daniel Axtens35384792020-09-02 14:48:45 +1000748 mbedtls_pkcs7_signer_info *signer_cur;
749 mbedtls_pkcs7_signer_info *signer_prev;
Nayna Jainc9deb182020-11-16 19:03:12 +0000750
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 if (pkcs7 == NULL || pkcs7->raw.p == NULL) {
Nayna Jainc9deb182020-11-16 19:03:12 +0000752 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000754
Gilles Peskine449bd832023-01-11 14:50:10 +0100755 mbedtls_free(pkcs7->raw.p);
Nayna Jainc9deb182020-11-16 19:03:12 +0000756
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 mbedtls_x509_crt_free(&pkcs7->signed_data.certs);
758 mbedtls_x509_crl_free(&pkcs7->signed_data.crl);
Nayna Jainc9deb182020-11-16 19:03:12 +0000759
Daniel Axtens35384792020-09-02 14:48:45 +1000760 signer_cur = pkcs7->signed_data.signers.next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100761 pkcs7_free_signer_info(&pkcs7->signed_data.signers);
762 while (signer_cur != NULL) {
Daniel Axtens35384792020-09-02 14:48:45 +1000763 signer_prev = signer_cur;
764 signer_cur = signer_prev->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 pkcs7_free_signer_info(signer_prev);
766 mbedtls_free(signer_prev);
Nayna Jainc9deb182020-11-16 19:03:12 +0000767 }
768
769 pkcs7->raw.p = NULL;
770}
771
772#endif