blob: 0869c2e077a437dcb02952004ef972d611253655 [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 */
5#include "common.h"
6
7#include "mbedtls/build_info.h"
8#if defined(MBEDTLS_PKCS7_C)
9#include "mbedtls/pkcs7.h"
10#include "mbedtls/x509.h"
11#include "mbedtls/asn1.h"
12#include "mbedtls/x509_crt.h"
13#include "mbedtls/x509_crl.h"
14#include "mbedtls/oid.h"
Nick Child9f4fb3e2022-09-12 16:21:02 -050015#include "mbedtls/error.h"
Nayna Jainc9deb182020-11-16 19:03:12 +000016
Nayna Jainc9deb182020-11-16 19:03:12 +000017#if defined(MBEDTLS_FS_IO)
18#include <sys/types.h>
19#include <sys/stat.h>
20#endif
21
Nayna Jainc9deb182020-11-16 19:03:12 +000022#include "mbedtls/platform.h"
23#include "mbedtls/platform_util.h"
Nayna Jainc9deb182020-11-16 19:03:12 +000024
25#if defined(MBEDTLS_HAVE_TIME)
26#include "mbedtls/platform_time.h"
27#endif
28#if defined(MBEDTLS_HAVE_TIME_DATE)
29#include <time.h>
30#endif
31
32/**
Dave Rodgmanefbc5f72023-03-13 12:15:49 +000033 * Initializes the mbedtls_pkcs7 structure.
Nayna Jainc9deb182020-11-16 19:03:12 +000034 */
Gilles Peskine449bd832023-01-11 14:50:10 +010035void mbedtls_pkcs7_init(mbedtls_pkcs7 *pkcs7)
Nayna Jainc9deb182020-11-16 19:03:12 +000036{
Gilles Peskine449bd832023-01-11 14:50:10 +010037 memset(pkcs7, 0, sizeof(*pkcs7));
Nayna Jainc9deb182020-11-16 19:03:12 +000038}
39
Gilles Peskine449bd832023-01-11 14:50:10 +010040static int pkcs7_get_next_content_len(unsigned char **p, unsigned char *end,
41 size_t *len)
Nayna Jainc9deb182020-11-16 19:03:12 +000042{
Nick Child9f4fb3e2022-09-12 16:21:02 -050043 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +000044
Gilles Peskine449bd832023-01-11 14:50:10 +010045 ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_CONSTRUCTED
46 | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
47 if (ret != 0) {
Demi Marie Obenour6cfc4692022-11-28 00:46:00 -050048 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
Demi Marie Obenour512818b2022-11-27 22:48:55 -050049 } else if ((size_t) (end - *p) != *len) {
Demi Marie Obenour6cfc4692022-11-28 00:46:00 -050050 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO,
Demi Marie Obenour512818b2022-11-27 22:48:55 -050051 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
Nayna Jainc9deb182020-11-16 19:03:12 +000052 }
53
Gilles Peskine449bd832023-01-11 14:50:10 +010054 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +000055}
56
57/**
58 * version Version
59 * Version ::= INTEGER
60 **/
Gilles Peskine449bd832023-01-11 14:50:10 +010061static int pkcs7_get_version(unsigned char **p, unsigned char *end, int *ver)
Nayna Jainc9deb182020-11-16 19:03:12 +000062{
Nick Child9f4fb3e2022-09-12 16:21:02 -050063 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +000064
Gilles Peskine449bd832023-01-11 14:50:10 +010065 ret = mbedtls_asn1_get_int(p, end, ver);
66 if (ret != 0) {
67 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_VERSION, ret);
68 }
Nayna Jainc9deb182020-11-16 19:03:12 +000069
70 /* If version != 1, return invalid version */
Gilles Peskine449bd832023-01-11 14:50:10 +010071 if (*ver != MBEDTLS_PKCS7_SUPPORTED_VERSION) {
Nick Child9f4fb3e2022-09-12 16:21:02 -050072 ret = MBEDTLS_ERR_PKCS7_INVALID_VERSION;
Gilles Peskine449bd832023-01-11 14:50:10 +010073 }
Nayna Jainc9deb182020-11-16 19:03:12 +000074
Gilles Peskine449bd832023-01-11 14:50:10 +010075 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +000076}
77
78/**
79 * ContentInfo ::= SEQUENCE {
80 * contentType ContentType,
81 * content
82 * [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
83 **/
Gilles Peskine449bd832023-01-11 14:50:10 +010084static int pkcs7_get_content_info_type(unsigned char **p, unsigned char *end,
Nick Childec817092022-12-15 15:54:03 -060085 unsigned char **seq_end,
Gilles Peskine449bd832023-01-11 14:50:10 +010086 mbedtls_pkcs7_buf *pkcs7)
Nayna Jainc9deb182020-11-16 19:03:12 +000087{
88 size_t len = 0;
Nick Child9f4fb3e2022-09-12 16:21:02 -050089 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jain673a2262020-12-14 22:44:49 +000090 unsigned char *start = *p;
Nayna Jainc9deb182020-11-16 19:03:12 +000091
Gilles Peskine449bd832023-01-11 14:50:10 +010092 ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
93 | MBEDTLS_ASN1_SEQUENCE);
94 if (ret != 0) {
Nick Childc448c942021-07-01 15:29:50 -040095 *p = start;
Gilles Peskine449bd832023-01-11 14:50:10 +010096 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
Nick Childc448c942021-07-01 15:29:50 -040097 }
Nick Childec817092022-12-15 15:54:03 -060098 *seq_end = *p + len;
99 ret = mbedtls_asn1_get_tag(p, *seq_end, &len, MBEDTLS_ASN1_OID);
Gilles Peskine449bd832023-01-11 14:50:10 +0100100 if (ret != 0) {
Nayna Jain673a2262020-12-14 22:44:49 +0000101 *p = start;
Gilles Peskine449bd832023-01-11 14:50:10 +0100102 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
Nayna Jain673a2262020-12-14 22:44:49 +0000103 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000104
105 pkcs7->tag = MBEDTLS_ASN1_OID;
106 pkcs7->len = len;
107 pkcs7->p = *p;
Nick Childbb82ab72022-10-28 12:28:54 -0500108 *p += len;
Nayna Jainc9deb182020-11-16 19:03:12 +0000109
Gilles Peskine449bd832023-01-11 14:50:10 +0100110 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +0000111}
112
113/**
114 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
115 *
116 * This is from x509.h
117 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100118static int pkcs7_get_digest_algorithm(unsigned char **p, unsigned char *end,
119 mbedtls_x509_buf *alg)
Nayna Jainc9deb182020-11-16 19:03:12 +0000120{
Nick Child9f4fb3e2022-09-12 16:21:02 -0500121 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000122
Gilles Peskine449bd832023-01-11 14:50:10 +0100123 if ((ret = mbedtls_asn1_get_alg_null(p, end, alg)) != 0) {
124 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
125 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000126
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +0000128}
129
130/**
131 * DigestAlgorithmIdentifiers :: SET of DigestAlgorithmIdentifier
132 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100133static int pkcs7_get_digest_algorithm_set(unsigned char **p,
134 unsigned char *end,
135 mbedtls_x509_buf *alg)
Nayna Jainc9deb182020-11-16 19:03:12 +0000136{
137 size_t len = 0;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500138 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000139
Gilles Peskine449bd832023-01-11 14:50:10 +0100140 ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
141 | MBEDTLS_ASN1_SET);
142 if (ret != 0) {
143 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
Nick Child9f4fb3e2022-09-12 16:21:02 -0500144 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000145
146 end = *p + len;
147
Gilles Peskine449bd832023-01-11 14:50:10 +0100148 ret = mbedtls_asn1_get_alg_null(p, end, alg);
149 if (ret != 0) {
150 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
Nick Child9f4fb3e2022-09-12 16:21:02 -0500151 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000152
Nick Child34d5e932022-09-14 14:44:03 -0500153 /** For now, it assumes there is only one digest algorithm specified **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100154 if (*p != end) {
155 return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
156 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000157
Gilles Peskine449bd832023-01-11 14:50:10 +0100158 return 0;
Nayna Jainc9deb182020-11-16 19:03:12 +0000159}
160
161/**
162 * certificates :: SET OF ExtendedCertificateOrCertificate,
163 * ExtendedCertificateOrCertificate ::= CHOICE {
164 * certificate Certificate -- x509,
165 * extendedCertificate[0] IMPLICIT ExtendedCertificate }
166 * Return number of certificates added to the signed data,
167 * 0 or higher is valid.
168 * Return negative error code for failure.
169 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100170static int pkcs7_get_certificates(unsigned char **p, unsigned char *end,
171 mbedtls_x509_crt *certs)
Nayna Jainc9deb182020-11-16 19:03:12 +0000172{
Nick Child9f4fb3e2022-09-12 16:21:02 -0500173 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000174 size_t len1 = 0;
175 size_t len2 = 0;
Nick Childbb82ab72022-10-28 12:28:54 -0500176 unsigned char *end_set, *end_cert, *start;
Nayna Jainc9deb182020-11-16 19:03:12 +0000177
Demi Marie Obenour6cfc4692022-11-28 00:46:00 -0500178 ret = mbedtls_asn1_get_tag(p, end, &len1, MBEDTLS_ASN1_CONSTRUCTED
179 | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
180 if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
181 return 0;
182 }
183 if (ret != 0) {
184 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
Nayna Jainc9deb182020-11-16 19:03:12 +0000185 }
186 start = *p;
187 end_set = *p + len1;
188
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 ret = mbedtls_asn1_get_tag(p, end_set, &len2, MBEDTLS_ASN1_CONSTRUCTED
190 | MBEDTLS_ASN1_SEQUENCE);
191 if (ret != 0) {
192 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CERT, ret);
Nick Child9f4fb3e2022-09-12 16:21:02 -0500193 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000194
195 end_cert = *p + len2;
196
197 /*
198 * This is to verify that there is only one signer certificate. It seems it is
199 * not easy to differentiate between the chain vs different signer's certificate.
200 * So, we support only the root certificate and the single signer.
201 * The behaviour would be improved with addition of multiple signer support.
202 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 if (end_cert != end_set) {
204 return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500205 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000206
Demi Marie Obenour55d9df22022-11-28 00:29:32 -0500207 if ((ret = mbedtls_x509_crt_parse_der(certs, start, len1)) < 0) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 return MBEDTLS_ERR_PKCS7_INVALID_CERT;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500209 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000210
Demi Marie Obenour55d9df22022-11-28 00:29:32 -0500211 *p = end_cert;
Nayna Jainc9deb182020-11-16 19:03:12 +0000212
Nick Child5f9456f2022-09-19 10:01:25 -0500213 /*
Nick Child9f4fb3e2022-09-12 16:21:02 -0500214 * Since in this version we strictly support single certificate, and reaching
Nick Child5f9456f2022-09-19 10:01:25 -0500215 * here implies we have parsed successfully, we return 1.
Nick Child9f4fb3e2022-09-12 16:21:02 -0500216 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100217 return 1;
Nayna Jainc9deb182020-11-16 19:03:12 +0000218}
219
220/**
221 * EncryptedDigest ::= OCTET STRING
222 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100223static int pkcs7_get_signature(unsigned char **p, unsigned char *end,
224 mbedtls_pkcs7_buf *signature)
Nayna Jainc9deb182020-11-16 19:03:12 +0000225{
Nick Child9f4fb3e2022-09-12 16:21:02 -0500226 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000227 size_t len = 0;
228
Gilles Peskine449bd832023-01-11 14:50:10 +0100229 ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
230 if (ret != 0) {
231 return ret;
232 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000233
234 signature->tag = MBEDTLS_ASN1_OCTET_STRING;
235 signature->len = len;
236 signature->p = *p;
237
238 *p = *p + len;
239
Gilles Peskine449bd832023-01-11 14:50:10 +0100240 return 0;
Nayna Jainc9deb182020-11-16 19:03:12 +0000241}
242
Gilles Peskine449bd832023-01-11 14:50:10 +0100243static void pkcs7_free_signer_info(mbedtls_pkcs7_signer_info *signer)
Bence Szépkútif7641542022-12-12 21:37:36 +0100244{
245 mbedtls_x509_name *name_cur;
246 mbedtls_x509_name *name_prv;
247
Gilles Peskine449bd832023-01-11 14:50:10 +0100248 if (signer == NULL) {
Bence Szépkútif7641542022-12-12 21:37:36 +0100249 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100250 }
Bence Szépkútif7641542022-12-12 21:37:36 +0100251
252 name_cur = signer->issuer.next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100253 while (name_cur != NULL) {
Bence Szépkútif7641542022-12-12 21:37:36 +0100254 name_prv = name_cur;
255 name_cur = name_cur->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100256 mbedtls_free(name_prv);
Bence Szépkútif7641542022-12-12 21:37:36 +0100257 }
258 signer->issuer.next = NULL;
259}
260
Nayna Jainc9deb182020-11-16 19:03:12 +0000261/**
Nayna Jainc9deb182020-11-16 19:03:12 +0000262 * SignerInfo ::= SEQUENCE {
263 * version Version;
264 * issuerAndSerialNumber IssuerAndSerialNumber,
265 * digestAlgorithm DigestAlgorithmIdentifier,
266 * authenticatedAttributes
267 * [0] IMPLICIT Attributes OPTIONAL,
268 * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
269 * encryptedDigest EncryptedDigest,
270 * unauthenticatedAttributes
271 * [1] IMPLICIT Attributes OPTIONAL,
Daniel Axtens35384792020-09-02 14:48:45 +1000272 * Returns 0 if the signerInfo is valid.
273 * Return negative error code for failure.
Nick Childbb82ab72022-10-28 12:28:54 -0500274 * Structure must not contain vales for authenticatedAttributes
275 * and unauthenticatedAttributes.
Daniel Axtens35384792020-09-02 14:48:45 +1000276 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100277static int pkcs7_get_signer_info(unsigned char **p, unsigned char *end,
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500278 mbedtls_pkcs7_signer_info *signer,
279 mbedtls_x509_buf *alg)
Daniel Axtens35384792020-09-02 14:48:45 +1000280{
Nick Childec817092022-12-15 15:54:03 -0600281 unsigned char *end_signer, *end_issuer_and_sn;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500282 int asn1_ret = 0, ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Axtens35384792020-09-02 14:48:45 +1000283 size_t len = 0;
284
Gilles Peskine449bd832023-01-11 14:50:10 +0100285 asn1_ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
286 | MBEDTLS_ASN1_SEQUENCE);
287 if (asn1_ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500288 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100289 }
Daniel Axtens35384792020-09-02 14:48:45 +1000290
291 end_signer = *p + len;
292
Gilles Peskine449bd832023-01-11 14:50:10 +0100293 ret = pkcs7_get_version(p, end_signer, &signer->version);
294 if (ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500295 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100296 }
Daniel Axtens35384792020-09-02 14:48:45 +1000297
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 asn1_ret = mbedtls_asn1_get_tag(p, end_signer, &len,
299 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
300 if (asn1_ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500301 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100302 }
Daniel Axtens35384792020-09-02 14:48:45 +1000303
Nick Childec817092022-12-15 15:54:03 -0600304 end_issuer_and_sn = *p + len;
Daniel Axtens35384792020-09-02 14:48:45 +1000305 /* Parsing IssuerAndSerialNumber */
306 signer->issuer_raw.p = *p;
307
Nick Child3bd17f22023-01-31 20:42:26 +0000308 asn1_ret = mbedtls_asn1_get_tag(p, end_issuer_and_sn, &len,
Gilles Peskine449bd832023-01-11 14:50:10 +0100309 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
310 if (asn1_ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500311 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 }
Daniel Axtens35384792020-09-02 14:48:45 +1000313
Gilles Peskine449bd832023-01-11 14:50:10 +0100314 ret = mbedtls_x509_get_name(p, *p + len, &signer->issuer);
315 if (ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500316 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 }
Daniel Axtens35384792020-09-02 14:48:45 +1000318
Dave Rodgmane4a6f5a2023-11-04 12:20:09 +0000319 signer->issuer_raw.len = (size_t) (*p - signer->issuer_raw.p);
Daniel Axtens35384792020-09-02 14:48:45 +1000320
Nick Child3bd17f22023-01-31 20:42:26 +0000321 ret = mbedtls_x509_get_serial(p, end_issuer_and_sn, &signer->serial);
Gilles Peskine449bd832023-01-11 14:50:10 +0100322 if (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
Nick Childec817092022-12-15 15:54:03 -0600326 /* ensure no extra or missing bytes */
327 if (*p != end_issuer_and_sn) {
328 ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
329 goto out;
330 }
331
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->alg_identifier);
333 if (ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500334 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100335 }
Daniel Axtens35384792020-09-02 14:48:45 +1000336
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500337 /* Check that the digest algorithm used matches the one provided earlier */
338 if (signer->alg_identifier.tag != alg->tag ||
339 signer->alg_identifier.len != alg->len ||
340 memcmp(signer->alg_identifier.p, alg->p, alg->len) != 0) {
341 ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
342 goto out;
343 }
Nick Childbb82ab72022-10-28 12:28:54 -0500344
Tom Cosgrove5c8505f2023-03-07 11:39:52 +0000345 /* Assume authenticatedAttributes is nonexistent */
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->sig_alg_identifier);
347 if (ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500348 goto out;
Bence Szépkútif7641542022-12-12 21:37:36 +0100349 }
Nick Child9f4fb3e2022-09-12 16:21:02 -0500350
Gilles Peskine449bd832023-01-11 14:50:10 +0100351 ret = pkcs7_get_signature(p, end_signer, &signer->sig);
352 if (ret != 0) {
353 goto out;
354 }
355
356 /* Do not permit any unauthenticated attributes */
357 if (*p != end_signer) {
358 ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
359 }
360
361out:
362 if (asn1_ret != 0 || ret != 0) {
363 pkcs7_free_signer_info(signer);
364 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO,
365 asn1_ret);
366 }
367
368 return ret;
Daniel Axtens35384792020-09-02 14:48:45 +1000369}
370
Daniel Axtens35384792020-09-02 14:48:45 +1000371/**
372 * SignerInfos ::= SET of SignerInfo
Nayna Jainc9deb182020-11-16 19:03:12 +0000373 * Return number of signers added to the signed data,
374 * 0 or higher is valid.
375 * Return negative error code for failure.
376 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100377static int pkcs7_get_signers_info_set(unsigned char **p, unsigned char *end,
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500378 mbedtls_pkcs7_signer_info *signers_set,
379 mbedtls_x509_buf *digest_alg)
Nayna Jainc9deb182020-11-16 19:03:12 +0000380{
Daniel Axtens35384792020-09-02 14:48:45 +1000381 unsigned char *end_set;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500382 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Axtens35384792020-09-02 14:48:45 +1000383 int count = 0;
Nayna Jainc9deb182020-11-16 19:03:12 +0000384 size_t len = 0;
385
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
387 | MBEDTLS_ASN1_SET);
388 if (ret != 0) {
389 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO, ret);
Nick Child9f4fb3e2022-09-12 16:21:02 -0500390 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000391
Daniel Axtens35384792020-09-02 14:48:45 +1000392 /* Detect zero signers */
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 if (len == 0) {
394 return 0;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500395 }
Daniel Axtens35384792020-09-02 14:48:45 +1000396
Nayna Jainc9deb182020-11-16 19:03:12 +0000397 end_set = *p + len;
398
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500399 ret = pkcs7_get_signer_info(p, end_set, signers_set, digest_alg);
Gilles Peskine449bd832023-01-11 14:50:10 +0100400 if (ret != 0) {
401 return ret;
402 }
Daniel Axtens35384792020-09-02 14:48:45 +1000403 count++;
Nayna Jainc9deb182020-11-16 19:03:12 +0000404
Gilles Peskine47a73262022-11-27 21:46:56 +0100405 mbedtls_pkcs7_signer_info *prev = signers_set;
Gilles Peskine449bd832023-01-11 14:50:10 +0100406 while (*p != end_set) {
Gilles Peskine47a73262022-11-27 21:46:56 +0100407 mbedtls_pkcs7_signer_info *signer =
Gilles Peskine449bd832023-01-11 14:50:10 +0100408 mbedtls_calloc(1, sizeof(mbedtls_pkcs7_signer_info));
409 if (!signer) {
Daniel Axtens35384792020-09-02 14:48:45 +1000410 ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
411 goto cleanup;
412 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000413
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500414 ret = pkcs7_get_signer_info(p, end_set, signer, digest_alg);
Gilles Peskine449bd832023-01-11 14:50:10 +0100415 if (ret != 0) {
416 mbedtls_free(signer);
Daniel Axtens35384792020-09-02 14:48:45 +1000417 goto cleanup;
418 }
419 prev->next = signer;
420 prev = signer;
421 count++;
422 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000423
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 return count;
Nayna Jainc9deb182020-11-16 19:03:12 +0000425
Daniel Axtens35384792020-09-02 14:48:45 +1000426cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100427 pkcs7_free_signer_info(signers_set);
Gilles Peskine47a73262022-11-27 21:46:56 +0100428 mbedtls_pkcs7_signer_info *signer = signers_set->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 while (signer != NULL) {
Daniel Axtens35384792020-09-02 14:48:45 +1000430 prev = signer;
431 signer = signer->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100432 pkcs7_free_signer_info(prev);
433 mbedtls_free(prev);
Daniel Axtens35384792020-09-02 14:48:45 +1000434 }
Gilles Peskine290f01b2022-11-27 21:28:31 +0100435 signers_set->next = NULL;
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +0000437}
438
439/**
440 * SignedData ::= SEQUENCE {
441 * version Version,
442 * digestAlgorithms DigestAlgorithmIdentifiers,
443 * contentInfo ContentInfo,
444 * certificates
445 * [0] IMPLICIT ExtendedCertificatesAndCertificates
446 * OPTIONAL,
447 * crls
448 * [0] IMPLICIT CertificateRevocationLists OPTIONAL,
449 * signerInfos SignerInfos }
450 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100451static int pkcs7_get_signed_data(unsigned char *buf, size_t buflen,
452 mbedtls_pkcs7_signed_data *signed_data)
Nayna Jainc9deb182020-11-16 19:03:12 +0000453{
454 unsigned char *p = buf;
455 unsigned char *end = buf + buflen;
Dave Rodgmanf6912682023-02-09 17:55:41 +0000456 unsigned char *end_content_info = NULL;
Nayna Jainc9deb182020-11-16 19:03:12 +0000457 size_t len = 0;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500458 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000459 mbedtls_md_type_t md_alg;
460
Gilles Peskine449bd832023-01-11 14:50:10 +0100461 ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
462 | MBEDTLS_ASN1_SEQUENCE);
463 if (ret != 0) {
464 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
Nick Child9f4fb3e2022-09-12 16:21:02 -0500465 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000466
Demi Marie Obenour4ec83552022-11-28 00:23:00 -0500467 if (p + len != end) {
468 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT,
469 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
470 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000471
472 /* Get version of signed data */
Demi Marie Obenour4ec83552022-11-28 00:23:00 -0500473 ret = pkcs7_get_version(&p, end, &signed_data->version);
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 if (ret != 0) {
475 return ret;
476 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000477
478 /* Get digest algorithm */
Demi Marie Obenour4ec83552022-11-28 00:23:00 -0500479 ret = pkcs7_get_digest_algorithm_set(&p, end,
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 &signed_data->digest_alg_identifiers);
481 if (ret != 0) {
482 return ret;
483 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000484
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 ret = mbedtls_oid_get_md_alg(&signed_data->digest_alg_identifiers, &md_alg);
486 if (ret != 0) {
487 return MBEDTLS_ERR_PKCS7_INVALID_ALG;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500488 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000489
Demi Marie Obenoure373a252022-12-13 23:50:03 -0500490 mbedtls_pkcs7_buf content_type;
Dave Rodgmanf6912682023-02-09 17:55:41 +0000491 memset(&content_type, 0, sizeof(content_type));
Demi Marie Obenoure373a252022-12-13 23:50:03 -0500492 ret = pkcs7_get_content_info_type(&p, end, &end_content_info, &content_type);
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 if (ret != 0) {
494 return ret;
495 }
Demi Marie Obenoure373a252022-12-13 23:50:03 -0500496 if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DATA, &content_type)) {
497 return MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO;
498 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000499
Nick Child3dafc6c2023-02-07 19:59:58 +0000500 if (p != end_content_info) {
501 /* Determine if valid content is present */
Dave Rodgman78c6f402023-02-09 09:21:14 +0000502 ret = mbedtls_asn1_get_tag(&p,
503 end_content_info,
504 &len,
505 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
Nick Child3dafc6c2023-02-07 19:59:58 +0000506 if (ret != 0) {
507 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
508 }
509 p += len;
510 if (p != end_content_info) {
511 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
512 }
513 /* Valid content is present - this is not supported */
514 return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
Nick Childec817092022-12-15 15:54:03 -0600515 }
516
Nayna Jainc9deb182020-11-16 19:03:12 +0000517 /* Look for certificates, there may or may not be any */
Gilles Peskine449bd832023-01-11 14:50:10 +0100518 mbedtls_x509_crt_init(&signed_data->certs);
Demi Marie Obenour4ec83552022-11-28 00:23:00 -0500519 ret = pkcs7_get_certificates(&p, end, &signed_data->certs);
Gilles Peskine449bd832023-01-11 14:50:10 +0100520 if (ret < 0) {
521 return ret;
522 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000523
524 signed_data->no_of_certs = ret;
525
526 /*
527 * Currently CRLs are not supported. If CRL exist, the parsing will fail
528 * at next step of getting signers info and return error as invalid
529 * signer info.
530 */
531
532 signed_data->no_of_crls = 0;
533
534 /* Get signers info */
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500535 ret = pkcs7_get_signers_info_set(&p,
536 end,
537 &signed_data->signers,
538 &signed_data->digest_alg_identifiers);
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 if (ret < 0) {
540 return ret;
541 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000542
543 signed_data->no_of_signers = ret;
544
Daniel Axtens35384792020-09-02 14:48:45 +1000545 /* Don't permit trailing data */
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 if (p != end) {
547 return MBEDTLS_ERR_PKCS7_INVALID_FORMAT;
548 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000549
Gilles Peskine449bd832023-01-11 14:50:10 +0100550 return 0;
Nayna Jainc9deb182020-11-16 19:03:12 +0000551}
552
Gilles Peskine449bd832023-01-11 14:50:10 +0100553int mbedtls_pkcs7_parse_der(mbedtls_pkcs7 *pkcs7, const unsigned char *buf,
554 const size_t buflen)
Nayna Jainc9deb182020-11-16 19:03:12 +0000555{
Nick Childbb82ab72022-10-28 12:28:54 -0500556 unsigned char *p;
Demi Marie Obenour4ec83552022-11-28 00:23:00 -0500557 unsigned char *end;
Nayna Jainc9deb182020-11-16 19:03:12 +0000558 size_t len = 0;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500559 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000560
Gilles Peskine449bd832023-01-11 14:50:10 +0100561 if (pkcs7 == NULL) {
562 return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500563 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000564
565 /* make an internal copy of the buffer for parsing */
Gilles Peskine449bd832023-01-11 14:50:10 +0100566 pkcs7->raw.p = p = mbedtls_calloc(1, buflen);
567 if (pkcs7->raw.p == NULL) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500568 ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
569 goto out;
Nayna Jainc9deb182020-11-16 19:03:12 +0000570 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100571 memcpy(p, buf, buflen);
Nayna Jainc9deb182020-11-16 19:03:12 +0000572 pkcs7->raw.len = buflen;
Nick Childbb82ab72022-10-28 12:28:54 -0500573 end = p + buflen;
Nayna Jainc9deb182020-11-16 19:03:12 +0000574
Demi Marie Obenouraaf3c002022-11-28 00:20:42 -0500575 ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
576 | MBEDTLS_ASN1_SEQUENCE);
Gilles Peskine449bd832023-01-11 14:50:10 +0100577 if (ret != 0) {
Demi Marie Obenouraaf3c002022-11-28 00:20:42 -0500578 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
579 goto out;
580 }
581
582 if ((size_t) (end - p) != len) {
583 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT,
584 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
585 goto out;
586 }
587
588 if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) {
589 if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
590 goto out;
591 }
592 p = pkcs7->raw.p;
Nayna Jain673a2262020-12-14 22:44:49 +0000593 len = buflen;
594 goto try_data;
595 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000596
Demi Marie Obenouraaf3c002022-11-28 00:20:42 -0500597 if (MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_SIGNED_DATA, p, len)) {
Dave Rodgmana1b2bff2023-02-20 14:45:09 +0000598 /* OID is not MBEDTLS_OID_PKCS7_SIGNED_DATA, which is the only supported feature */
Demi Marie Obenouraaf3c002022-11-28 00:20:42 -0500599 if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DATA, p, len)
600 || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, p, len)
601 || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_ENVELOPED_DATA, p, len)
602 || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA, p, len)
603 || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DIGESTED_DATA, p, len)) {
Dave Rodgmana1b2bff2023-02-20 14:45:09 +0000604 /* OID is valid according to the spec, but unsupported */
Demi Marie Obenouraaf3c002022-11-28 00:20:42 -0500605 ret = MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
606 } else {
Dave Rodgmana1b2bff2023-02-20 14:45:09 +0000607 /* OID is invalid according to the spec */
Demi Marie Obenouraaf3c002022-11-28 00:20:42 -0500608 ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
609 }
Nick Childec817092022-12-15 15:54:03 -0600610 goto out;
611 }
612
Demi Marie Obenouraaf3c002022-11-28 00:20:42 -0500613 p += len;
Nayna Jainc9deb182020-11-16 19:03:12 +0000614
Gilles Peskine449bd832023-01-11 14:50:10 +0100615 ret = pkcs7_get_next_content_len(&p, end, &len);
616 if (ret != 0) {
Nayna Jainc9deb182020-11-16 19:03:12 +0000617 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100618 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000619
Nick Childec817092022-12-15 15:54:03 -0600620 /* ensure no extra/missing data */
621 if (p + len != end) {
622 ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
623 goto out;
624 }
625
Nayna Jain673a2262020-12-14 22:44:49 +0000626try_data:
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 ret = pkcs7_get_signed_data(p, len, &pkcs7->signed_data);
628 if (ret != 0) {
Nayna Jain673a2262020-12-14 22:44:49 +0000629 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 }
Nayna Jain673a2262020-12-14 22:44:49 +0000631
Nayna Jain673a2262020-12-14 22:44:49 +0000632 ret = MBEDTLS_PKCS7_SIGNED_DATA;
Nayna Jainc9deb182020-11-16 19:03:12 +0000633
634out:
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 if (ret < 0) {
636 mbedtls_pkcs7_free(pkcs7);
637 }
Nayna Jain673a2262020-12-14 22:44:49 +0000638
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +0000640}
641
Gilles Peskine449bd832023-01-11 14:50:10 +0100642static int mbedtls_pkcs7_data_or_hash_verify(mbedtls_pkcs7 *pkcs7,
Nick Child73621ef2022-10-28 11:23:15 -0500643 const mbedtls_x509_crt *cert,
644 const unsigned char *data,
645 size_t datalen,
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 const int is_data_hash)
Nayna Jainc9deb182020-11-16 19:03:12 +0000647{
Nick Child9f4fb3e2022-09-12 16:21:02 -0500648 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000649 unsigned char *hash;
650 mbedtls_pk_context pk_cxt = cert->pk;
651 const mbedtls_md_info_t *md_info;
652 mbedtls_md_type_t md_alg;
Daniel Axtens35384792020-09-02 14:48:45 +1000653 mbedtls_pkcs7_signer_info *signer;
Nayna Jainc9deb182020-11-16 19:03:12 +0000654
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 if (pkcs7->signed_data.no_of_signers == 0) {
656 return MBEDTLS_ERR_PKCS7_INVALID_CERT;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500657 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000658
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 if (mbedtls_x509_time_is_past(&cert->valid_to) ||
660 mbedtls_x509_time_is_future(&cert->valid_from)) {
661 return MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID;
Nick Child73621ef2022-10-28 11:23:15 -0500662 }
663
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500664 ret = mbedtls_oid_get_md_alg(&pkcs7->signed_data.digest_alg_identifiers, &md_alg);
665 if (ret != 0) {
666 return ret;
667 }
668
669 md_info = mbedtls_md_info_from_type(md_alg);
670 if (md_info == NULL) {
671 return MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
672 }
673
674 hash = mbedtls_calloc(mbedtls_md_get_size(md_info), 1);
675 if (hash == NULL) {
676 return MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
677 }
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500678
Dave Rodgmanfc643522023-02-16 16:23:09 +0000679 /* BEGIN must free hash before jumping out */
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500680 if (is_data_hash) {
681 if (datalen != mbedtls_md_get_size(md_info)) {
682 ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
683 } else {
684 memcpy(hash, data, datalen);
685 }
686 } else {
687 ret = mbedtls_md(md_info, data, datalen, hash);
688 }
689 if (ret != 0) {
690 mbedtls_free(hash);
691 return MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
692 }
693
694 /* assume failure */
695 ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
696
Daniel Axtens35384792020-09-02 14:48:45 +1000697 /*
698 * Potential TODOs
699 * Currently we iterate over all signers and return success if any of them
700 * verify.
701 *
702 * However, we could make this better by checking against the certificate's
703 * identification and SignerIdentifier fields first. That would also allow
704 * us to distinguish between 'no signature for key' and 'signature for key
705 * failed to validate'.
Daniel Axtens35384792020-09-02 14:48:45 +1000706 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 for (signer = &pkcs7->signed_data.signers; signer; signer = signer->next) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100708 ret = mbedtls_pk_verify(&pk_cxt, md_alg, hash,
709 mbedtls_md_get_size(md_info),
710 signer->sig.p, signer->sig.len);
Daniel Axtens35384792020-09-02 14:48:45 +1000711
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 if (ret == 0) {
Daniel Axtens35384792020-09-02 14:48:45 +1000713 break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100714 }
Daniel Axtens35384792020-09-02 14:48:45 +1000715 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000716
Demi Marie Obenour35598ad2022-11-30 02:06:07 -0500717 mbedtls_free(hash);
718 /* END must free hash before jumping out */
Gilles Peskine449bd832023-01-11 14:50:10 +0100719 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +0000720}
Demi Marie Obenour6cfc4692022-11-28 00:46:00 -0500721
Gilles Peskine449bd832023-01-11 14:50:10 +0100722int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7,
723 const mbedtls_x509_crt *cert,
724 const unsigned char *data,
725 size_t datalen)
Nick Child73621ef2022-10-28 11:23:15 -0500726{
Demi Marie Obenour6cfc4692022-11-28 00:46:00 -0500727 if (data == NULL) {
728 return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
729 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, data, datalen, 0);
Nick Child73621ef2022-10-28 11:23:15 -0500731}
Nayna Jainc9deb182020-11-16 19:03:12 +0000732
Gilles Peskine449bd832023-01-11 14:50:10 +0100733int mbedtls_pkcs7_signed_hash_verify(mbedtls_pkcs7 *pkcs7,
734 const mbedtls_x509_crt *cert,
735 const unsigned char *hash,
736 size_t hashlen)
Nayna Jainc9deb182020-11-16 19:03:12 +0000737{
Demi Marie Obenour6cfc4692022-11-28 00:46:00 -0500738 if (hash == NULL) {
739 return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
740 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100741 return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, hash, hashlen, 1);
Nayna Jainc9deb182020-11-16 19:03:12 +0000742}
743
744/*
745 * Unallocate all pkcs7 data
746 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100747void mbedtls_pkcs7_free(mbedtls_pkcs7 *pkcs7)
Nayna Jainc9deb182020-11-16 19:03:12 +0000748{
Daniel Axtens35384792020-09-02 14:48:45 +1000749 mbedtls_pkcs7_signer_info *signer_cur;
750 mbedtls_pkcs7_signer_info *signer_prev;
Nayna Jainc9deb182020-11-16 19:03:12 +0000751
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 if (pkcs7 == NULL || pkcs7->raw.p == NULL) {
Nayna Jainc9deb182020-11-16 19:03:12 +0000753 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100754 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000755
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 mbedtls_free(pkcs7->raw.p);
Nayna Jainc9deb182020-11-16 19:03:12 +0000757
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 mbedtls_x509_crt_free(&pkcs7->signed_data.certs);
759 mbedtls_x509_crl_free(&pkcs7->signed_data.crl);
Nayna Jainc9deb182020-11-16 19:03:12 +0000760
Daniel Axtens35384792020-09-02 14:48:45 +1000761 signer_cur = pkcs7->signed_data.signers.next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100762 pkcs7_free_signer_info(&pkcs7->signed_data.signers);
763 while (signer_cur != NULL) {
Daniel Axtens35384792020-09-02 14:48:45 +1000764 signer_prev = signer_cur;
765 signer_cur = signer_prev->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100766 pkcs7_free_signer_info(signer_prev);
767 mbedtls_free(signer_prev);
Nayna Jainc9deb182020-11-16 19:03:12 +0000768 }
769
770 pkcs7->raw.p = NULL;
771}
772
773#endif