blob: 63ad71fabe271fc0c70ae351e44edc5cb4715222 [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) {
60 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
Nayna Jainc9deb182020-11-16 19:03:12 +000061 }
62
Gilles Peskine449bd832023-01-11 14:50:10 +010063 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +000064}
65
66/**
67 * version Version
68 * Version ::= INTEGER
69 **/
Gilles Peskine449bd832023-01-11 14:50:10 +010070static int pkcs7_get_version(unsigned char **p, unsigned char *end, int *ver)
Nayna Jainc9deb182020-11-16 19:03:12 +000071{
Nick Child9f4fb3e2022-09-12 16:21:02 -050072 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +000073
Gilles Peskine449bd832023-01-11 14:50:10 +010074 ret = mbedtls_asn1_get_int(p, end, ver);
75 if (ret != 0) {
76 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_VERSION, ret);
77 }
Nayna Jainc9deb182020-11-16 19:03:12 +000078
79 /* If version != 1, return invalid version */
Gilles Peskine449bd832023-01-11 14:50:10 +010080 if (*ver != MBEDTLS_PKCS7_SUPPORTED_VERSION) {
Nick Child9f4fb3e2022-09-12 16:21:02 -050081 ret = MBEDTLS_ERR_PKCS7_INVALID_VERSION;
Gilles Peskine449bd832023-01-11 14:50:10 +010082 }
Nayna Jainc9deb182020-11-16 19:03:12 +000083
Gilles Peskine449bd832023-01-11 14:50:10 +010084 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +000085}
86
87/**
88 * ContentInfo ::= SEQUENCE {
89 * contentType ContentType,
90 * content
91 * [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
92 **/
Gilles Peskine449bd832023-01-11 14:50:10 +010093static int pkcs7_get_content_info_type(unsigned char **p, unsigned char *end,
Nick Childec817092022-12-15 15:54:03 -060094 unsigned char **seq_end,
Gilles Peskine449bd832023-01-11 14:50:10 +010095 mbedtls_pkcs7_buf *pkcs7)
Nayna Jainc9deb182020-11-16 19:03:12 +000096{
97 size_t len = 0;
Nick Child9f4fb3e2022-09-12 16:21:02 -050098 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jain673a2262020-12-14 22:44:49 +000099 unsigned char *start = *p;
Nayna Jainc9deb182020-11-16 19:03:12 +0000100
Gilles Peskine449bd832023-01-11 14:50:10 +0100101 ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
102 | MBEDTLS_ASN1_SEQUENCE);
103 if (ret != 0) {
Nick Childc448c942021-07-01 15:29:50 -0400104 *p = start;
Gilles Peskine449bd832023-01-11 14:50:10 +0100105 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
Nick Childc448c942021-07-01 15:29:50 -0400106 }
Nick Childec817092022-12-15 15:54:03 -0600107 *seq_end = *p + len;
108 ret = mbedtls_asn1_get_tag(p, *seq_end, &len, MBEDTLS_ASN1_OID);
Gilles Peskine449bd832023-01-11 14:50:10 +0100109 if (ret != 0) {
Nayna Jain673a2262020-12-14 22:44:49 +0000110 *p = start;
Gilles Peskine449bd832023-01-11 14:50:10 +0100111 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
Nayna Jain673a2262020-12-14 22:44:49 +0000112 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000113
114 pkcs7->tag = MBEDTLS_ASN1_OID;
115 pkcs7->len = len;
116 pkcs7->p = *p;
Nick Childbb82ab72022-10-28 12:28:54 -0500117 *p += len;
Nayna Jainc9deb182020-11-16 19:03:12 +0000118
Gilles Peskine449bd832023-01-11 14:50:10 +0100119 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +0000120}
121
122/**
123 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
124 *
125 * This is from x509.h
126 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100127static int pkcs7_get_digest_algorithm(unsigned char **p, unsigned char *end,
128 mbedtls_x509_buf *alg)
Nayna Jainc9deb182020-11-16 19:03:12 +0000129{
Nick Child9f4fb3e2022-09-12 16:21:02 -0500130 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000131
Gilles Peskine449bd832023-01-11 14:50:10 +0100132 if ((ret = mbedtls_asn1_get_alg_null(p, end, alg)) != 0) {
133 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
134 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000135
Gilles Peskine449bd832023-01-11 14:50:10 +0100136 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +0000137}
138
139/**
140 * DigestAlgorithmIdentifiers :: SET of DigestAlgorithmIdentifier
141 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100142static int pkcs7_get_digest_algorithm_set(unsigned char **p,
143 unsigned char *end,
144 mbedtls_x509_buf *alg)
Nayna Jainc9deb182020-11-16 19:03:12 +0000145{
146 size_t len = 0;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500147 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000148
Gilles Peskine449bd832023-01-11 14:50:10 +0100149 ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
150 | MBEDTLS_ASN1_SET);
151 if (ret != 0) {
152 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
Nick Child9f4fb3e2022-09-12 16:21:02 -0500153 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000154
155 end = *p + len;
156
Gilles Peskine449bd832023-01-11 14:50:10 +0100157 ret = mbedtls_asn1_get_alg_null(p, end, alg);
158 if (ret != 0) {
159 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
Nick Child9f4fb3e2022-09-12 16:21:02 -0500160 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000161
Nick Child34d5e932022-09-14 14:44:03 -0500162 /** For now, it assumes there is only one digest algorithm specified **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100163 if (*p != end) {
164 return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
165 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000166
Gilles Peskine449bd832023-01-11 14:50:10 +0100167 return 0;
Nayna Jainc9deb182020-11-16 19:03:12 +0000168}
169
170/**
171 * certificates :: SET OF ExtendedCertificateOrCertificate,
172 * ExtendedCertificateOrCertificate ::= CHOICE {
173 * certificate Certificate -- x509,
174 * extendedCertificate[0] IMPLICIT ExtendedCertificate }
175 * Return number of certificates added to the signed data,
176 * 0 or higher is valid.
177 * Return negative error code for failure.
178 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100179static int pkcs7_get_certificates(unsigned char **p, unsigned char *end,
180 mbedtls_x509_crt *certs)
Nayna Jainc9deb182020-11-16 19:03:12 +0000181{
Nick Child9f4fb3e2022-09-12 16:21:02 -0500182 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000183 size_t len1 = 0;
184 size_t len2 = 0;
Nick Childbb82ab72022-10-28 12:28:54 -0500185 unsigned char *end_set, *end_cert, *start;
Nayna Jainc9deb182020-11-16 19:03:12 +0000186
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 if ((ret = mbedtls_asn1_get_tag(p, end, &len1, MBEDTLS_ASN1_CONSTRUCTED
188 | MBEDTLS_ASN1_CONTEXT_SPECIFIC)) != 0) {
189 if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
190 return 0;
191 } else {
192 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
193 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000194 }
195 start = *p;
196 end_set = *p + len1;
197
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 ret = mbedtls_asn1_get_tag(p, end_set, &len2, MBEDTLS_ASN1_CONSTRUCTED
199 | MBEDTLS_ASN1_SEQUENCE);
200 if (ret != 0) {
201 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CERT, ret);
Nick Child9f4fb3e2022-09-12 16:21:02 -0500202 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000203
204 end_cert = *p + len2;
205
206 /*
207 * This is to verify that there is only one signer certificate. It seems it is
208 * not easy to differentiate between the chain vs different signer's certificate.
209 * So, we support only the root certificate and the single signer.
210 * The behaviour would be improved with addition of multiple signer support.
211 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100212 if (end_cert != end_set) {
213 return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500214 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000215
216 *p = start;
Gilles Peskine449bd832023-01-11 14:50:10 +0100217 if ((ret = mbedtls_x509_crt_parse_der(certs, *p, len1)) < 0) {
218 return MBEDTLS_ERR_PKCS7_INVALID_CERT;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500219 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000220
221 *p = *p + len1;
222
Nick Child5f9456f2022-09-19 10:01:25 -0500223 /*
Nick Child9f4fb3e2022-09-12 16:21:02 -0500224 * Since in this version we strictly support single certificate, and reaching
Nick Child5f9456f2022-09-19 10:01:25 -0500225 * here implies we have parsed successfully, we return 1.
Nick Child9f4fb3e2022-09-12 16:21:02 -0500226 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 return 1;
Nayna Jainc9deb182020-11-16 19:03:12 +0000228}
229
230/**
231 * EncryptedDigest ::= OCTET STRING
232 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100233static int pkcs7_get_signature(unsigned char **p, unsigned char *end,
234 mbedtls_pkcs7_buf *signature)
Nayna Jainc9deb182020-11-16 19:03:12 +0000235{
Nick Child9f4fb3e2022-09-12 16:21:02 -0500236 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000237 size_t len = 0;
238
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
240 if (ret != 0) {
241 return ret;
242 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000243
244 signature->tag = MBEDTLS_ASN1_OCTET_STRING;
245 signature->len = len;
246 signature->p = *p;
247
248 *p = *p + len;
249
Gilles Peskine449bd832023-01-11 14:50:10 +0100250 return 0;
Nayna Jainc9deb182020-11-16 19:03:12 +0000251}
252
Gilles Peskine449bd832023-01-11 14:50:10 +0100253static void pkcs7_free_signer_info(mbedtls_pkcs7_signer_info *signer)
Bence Szépkútif7641542022-12-12 21:37:36 +0100254{
255 mbedtls_x509_name *name_cur;
256 mbedtls_x509_name *name_prv;
257
Gilles Peskine449bd832023-01-11 14:50:10 +0100258 if (signer == NULL) {
Bence Szépkútif7641542022-12-12 21:37:36 +0100259 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100260 }
Bence Szépkútif7641542022-12-12 21:37:36 +0100261
262 name_cur = signer->issuer.next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 while (name_cur != NULL) {
Bence Szépkútif7641542022-12-12 21:37:36 +0100264 name_prv = name_cur;
265 name_cur = name_cur->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100266 mbedtls_free(name_prv);
Bence Szépkútif7641542022-12-12 21:37:36 +0100267 }
268 signer->issuer.next = NULL;
269}
270
Nayna Jainc9deb182020-11-16 19:03:12 +0000271/**
Nayna Jainc9deb182020-11-16 19:03:12 +0000272 * SignerInfo ::= SEQUENCE {
273 * version Version;
274 * issuerAndSerialNumber IssuerAndSerialNumber,
275 * digestAlgorithm DigestAlgorithmIdentifier,
276 * authenticatedAttributes
277 * [0] IMPLICIT Attributes OPTIONAL,
278 * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
279 * encryptedDigest EncryptedDigest,
280 * unauthenticatedAttributes
281 * [1] IMPLICIT Attributes OPTIONAL,
Daniel Axtens35384792020-09-02 14:48:45 +1000282 * Returns 0 if the signerInfo is valid.
283 * Return negative error code for failure.
Nick Childbb82ab72022-10-28 12:28:54 -0500284 * Structure must not contain vales for authenticatedAttributes
285 * and unauthenticatedAttributes.
Daniel Axtens35384792020-09-02 14:48:45 +1000286 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100287static int pkcs7_get_signer_info(unsigned char **p, unsigned char *end,
288 mbedtls_pkcs7_signer_info *signer)
Daniel Axtens35384792020-09-02 14:48:45 +1000289{
Nick Childec817092022-12-15 15:54:03 -0600290 unsigned char *end_signer, *end_issuer_and_sn;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500291 int asn1_ret = 0, ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Axtens35384792020-09-02 14:48:45 +1000292 size_t len = 0;
293
Gilles Peskine449bd832023-01-11 14:50:10 +0100294 asn1_ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
295 | MBEDTLS_ASN1_SEQUENCE);
296 if (asn1_ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500297 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 }
Daniel Axtens35384792020-09-02 14:48:45 +1000299
300 end_signer = *p + len;
301
Gilles Peskine449bd832023-01-11 14:50:10 +0100302 ret = pkcs7_get_version(p, end_signer, &signer->version);
303 if (ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500304 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 }
Daniel Axtens35384792020-09-02 14:48:45 +1000306
Gilles Peskine449bd832023-01-11 14:50:10 +0100307 asn1_ret = mbedtls_asn1_get_tag(p, end_signer, &len,
308 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
Nick Childec817092022-12-15 15:54:03 -0600313 end_issuer_and_sn = *p + len;
Daniel Axtens35384792020-09-02 14:48:45 +1000314 /* Parsing IssuerAndSerialNumber */
315 signer->issuer_raw.p = *p;
316
Nick Child3bd17f22023-01-31 20:42:26 +0000317 asn1_ret = mbedtls_asn1_get_tag(p, end_issuer_and_sn, &len,
Gilles Peskine449bd832023-01-11 14:50:10 +0100318 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
319 if (asn1_ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500320 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100321 }
Daniel Axtens35384792020-09-02 14:48:45 +1000322
Gilles Peskine449bd832023-01-11 14:50:10 +0100323 ret = mbedtls_x509_get_name(p, *p + len, &signer->issuer);
324 if (ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500325 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100326 }
Daniel Axtens35384792020-09-02 14:48:45 +1000327
328 signer->issuer_raw.len = *p - signer->issuer_raw.p;
329
Nick Child3bd17f22023-01-31 20:42:26 +0000330 ret = mbedtls_x509_get_serial(p, end_issuer_and_sn, &signer->serial);
Gilles Peskine449bd832023-01-11 14:50:10 +0100331 if (ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500332 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100333 }
Daniel Axtens35384792020-09-02 14:48:45 +1000334
Nick Childec817092022-12-15 15:54:03 -0600335 /* ensure no extra or missing bytes */
336 if (*p != end_issuer_and_sn) {
337 ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
338 goto out;
339 }
340
Gilles Peskine449bd832023-01-11 14:50:10 +0100341 ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->alg_identifier);
342 if (ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500343 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 }
Daniel Axtens35384792020-09-02 14:48:45 +1000345
Tom Cosgrove1797b052022-12-04 17:19:59 +0000346 /* Assume authenticatedAttributes is nonexistent */
Nick Childbb82ab72022-10-28 12:28:54 -0500347
Gilles Peskine449bd832023-01-11 14:50:10 +0100348 ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->sig_alg_identifier);
349 if (ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500350 goto out;
Bence Szépkútif7641542022-12-12 21:37:36 +0100351 }
Nick Child9f4fb3e2022-09-12 16:21:02 -0500352
Gilles Peskine449bd832023-01-11 14:50:10 +0100353 ret = pkcs7_get_signature(p, end_signer, &signer->sig);
354 if (ret != 0) {
355 goto out;
356 }
357
358 /* Do not permit any unauthenticated attributes */
359 if (*p != end_signer) {
360 ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
361 }
362
363out:
364 if (asn1_ret != 0 || ret != 0) {
365 pkcs7_free_signer_info(signer);
366 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO,
367 asn1_ret);
368 }
369
370 return ret;
Daniel Axtens35384792020-09-02 14:48:45 +1000371}
372
Daniel Axtens35384792020-09-02 14:48:45 +1000373/**
374 * SignerInfos ::= SET of SignerInfo
Nayna Jainc9deb182020-11-16 19:03:12 +0000375 * Return number of signers added to the signed data,
376 * 0 or higher is valid.
377 * Return negative error code for failure.
378 **/
Gilles Peskine449bd832023-01-11 14:50:10 +0100379static int pkcs7_get_signers_info_set(unsigned char **p, unsigned char *end,
380 mbedtls_pkcs7_signer_info *signers_set)
Nayna Jainc9deb182020-11-16 19:03:12 +0000381{
Daniel Axtens35384792020-09-02 14:48:45 +1000382 unsigned char *end_set;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500383 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Daniel Axtens35384792020-09-02 14:48:45 +1000384 int count = 0;
Nayna Jainc9deb182020-11-16 19:03:12 +0000385 size_t len = 0;
386
Gilles Peskine449bd832023-01-11 14:50:10 +0100387 ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
388 | MBEDTLS_ASN1_SET);
389 if (ret != 0) {
390 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO, ret);
Nick Child9f4fb3e2022-09-12 16:21:02 -0500391 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000392
Daniel Axtens35384792020-09-02 14:48:45 +1000393 /* Detect zero signers */
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 if (len == 0) {
395 return 0;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500396 }
Daniel Axtens35384792020-09-02 14:48:45 +1000397
Nayna Jainc9deb182020-11-16 19:03:12 +0000398 end_set = *p + len;
399
Gilles Peskine449bd832023-01-11 14:50:10 +0100400 ret = pkcs7_get_signer_info(p, end_set, signers_set);
401 if (ret != 0) {
402 return ret;
403 }
Daniel Axtens35384792020-09-02 14:48:45 +1000404 count++;
Nayna Jainc9deb182020-11-16 19:03:12 +0000405
Gilles Peskine47a73262022-11-27 21:46:56 +0100406 mbedtls_pkcs7_signer_info *prev = signers_set;
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 while (*p != end_set) {
Gilles Peskine47a73262022-11-27 21:46:56 +0100408 mbedtls_pkcs7_signer_info *signer =
Gilles Peskine449bd832023-01-11 14:50:10 +0100409 mbedtls_calloc(1, sizeof(mbedtls_pkcs7_signer_info));
410 if (!signer) {
Daniel Axtens35384792020-09-02 14:48:45 +1000411 ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
412 goto cleanup;
413 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000414
Gilles Peskine449bd832023-01-11 14:50:10 +0100415 ret = pkcs7_get_signer_info(p, end_set, signer);
416 if (ret != 0) {
417 mbedtls_free(signer);
Daniel Axtens35384792020-09-02 14:48:45 +1000418 goto cleanup;
419 }
420 prev->next = signer;
421 prev = signer;
422 count++;
423 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000424
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 return count;
Nayna Jainc9deb182020-11-16 19:03:12 +0000426
Daniel Axtens35384792020-09-02 14:48:45 +1000427cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100428 pkcs7_free_signer_info(signers_set);
Gilles Peskine47a73262022-11-27 21:46:56 +0100429 mbedtls_pkcs7_signer_info *signer = signers_set->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 while (signer != NULL) {
Daniel Axtens35384792020-09-02 14:48:45 +1000431 prev = signer;
432 signer = signer->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 pkcs7_free_signer_info(prev);
434 mbedtls_free(prev);
Daniel Axtens35384792020-09-02 14:48:45 +1000435 }
Gilles Peskine290f01b2022-11-27 21:28:31 +0100436 signers_set->next = NULL;
Gilles Peskine449bd832023-01-11 14:50:10 +0100437 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +0000438}
439
440/**
441 * SignedData ::= SEQUENCE {
442 * version Version,
443 * digestAlgorithms DigestAlgorithmIdentifiers,
444 * contentInfo ContentInfo,
445 * certificates
446 * [0] IMPLICIT ExtendedCertificatesAndCertificates
447 * OPTIONAL,
448 * crls
449 * [0] IMPLICIT CertificateRevocationLists OPTIONAL,
450 * signerInfos SignerInfos }
451 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100452static int pkcs7_get_signed_data(unsigned char *buf, size_t buflen,
453 mbedtls_pkcs7_signed_data *signed_data)
Nayna Jainc9deb182020-11-16 19:03:12 +0000454{
455 unsigned char *p = buf;
456 unsigned char *end = buf + buflen;
Nick Childec817092022-12-15 15:54:03 -0600457 unsigned char *end_set, *end_content_info;
Nayna Jainc9deb182020-11-16 19:03:12 +0000458 size_t len = 0;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500459 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000460 mbedtls_md_type_t md_alg;
461
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
463 | MBEDTLS_ASN1_SEQUENCE);
464 if (ret != 0) {
465 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
Nick Child9f4fb3e2022-09-12 16:21:02 -0500466 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000467
468 end_set = p + len;
469
470 /* Get version of signed data */
Gilles Peskine449bd832023-01-11 14:50:10 +0100471 ret = pkcs7_get_version(&p, end_set, &signed_data->version);
472 if (ret != 0) {
473 return ret;
474 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000475
476 /* Get digest algorithm */
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 ret = pkcs7_get_digest_algorithm_set(&p, end_set,
478 &signed_data->digest_alg_identifiers);
479 if (ret != 0) {
480 return ret;
481 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000482
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 ret = mbedtls_oid_get_md_alg(&signed_data->digest_alg_identifiers, &md_alg);
484 if (ret != 0) {
485 return MBEDTLS_ERR_PKCS7_INVALID_ALG;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500486 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000487
488 /* Do not expect any content */
Nick Childec817092022-12-15 15:54:03 -0600489 ret = pkcs7_get_content_info_type(&p, end_set, &end_content_info,
490 &signed_data->content.oid);
Gilles Peskine449bd832023-01-11 14:50:10 +0100491 if (ret != 0) {
492 return ret;
493 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000494
Nick Child3dafc6c2023-02-07 19:59:58 +0000495 if (p != end_content_info) {
496 /* Determine if valid content is present */
497 ret = mbedtls_asn1_get_tag(&p, end_content_info, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
498 if (ret != 0) {
499 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
500 }
501 p += len;
502 if (p != end_content_info) {
503 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
504 }
505 /* Valid content is present - this is not supported */
506 return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
Nick Childec817092022-12-15 15:54:03 -0600507 }
508
Gilles Peskine449bd832023-01-11 14:50:10 +0100509 if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DATA, &signed_data->content.oid)) {
510 return MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO;
Nayna Jainc9deb182020-11-16 19:03:12 +0000511 }
512
Nayna Jainc9deb182020-11-16 19:03:12 +0000513 /* Look for certificates, there may or may not be any */
Gilles Peskine449bd832023-01-11 14:50:10 +0100514 mbedtls_x509_crt_init(&signed_data->certs);
515 ret = pkcs7_get_certificates(&p, end_set, &signed_data->certs);
516 if (ret < 0) {
517 return ret;
518 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000519
520 signed_data->no_of_certs = ret;
521
522 /*
523 * Currently CRLs are not supported. If CRL exist, the parsing will fail
524 * at next step of getting signers info and return error as invalid
525 * signer info.
526 */
527
528 signed_data->no_of_crls = 0;
529
530 /* Get signers info */
Gilles Peskine449bd832023-01-11 14:50:10 +0100531 ret = pkcs7_get_signers_info_set(&p, end_set, &signed_data->signers);
532 if (ret < 0) {
533 return ret;
534 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000535
536 signed_data->no_of_signers = ret;
537
Daniel Axtens35384792020-09-02 14:48:45 +1000538 /* Don't permit trailing data */
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 if (p != end) {
540 return MBEDTLS_ERR_PKCS7_INVALID_FORMAT;
541 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000542
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 return 0;
Nayna Jainc9deb182020-11-16 19:03:12 +0000544}
545
Gilles Peskine449bd832023-01-11 14:50:10 +0100546int mbedtls_pkcs7_parse_der(mbedtls_pkcs7 *pkcs7, const unsigned char *buf,
547 const size_t buflen)
Nayna Jainc9deb182020-11-16 19:03:12 +0000548{
Nick Childbb82ab72022-10-28 12:28:54 -0500549 unsigned char *p;
Nick Childec817092022-12-15 15:54:03 -0600550 unsigned char *end, *end_content_info;
Nayna Jainc9deb182020-11-16 19:03:12 +0000551 size_t len = 0;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500552 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jain673a2262020-12-14 22:44:49 +0000553 int isoidset = 0;
Nayna Jainc9deb182020-11-16 19:03:12 +0000554
Gilles Peskine449bd832023-01-11 14:50:10 +0100555 if (pkcs7 == NULL) {
556 return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500557 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000558
559 /* make an internal copy of the buffer for parsing */
Gilles Peskine449bd832023-01-11 14:50:10 +0100560 pkcs7->raw.p = p = mbedtls_calloc(1, buflen);
561 if (pkcs7->raw.p == NULL) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500562 ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
563 goto out;
Nayna Jainc9deb182020-11-16 19:03:12 +0000564 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100565 memcpy(p, buf, buflen);
Nayna Jainc9deb182020-11-16 19:03:12 +0000566 pkcs7->raw.len = buflen;
Nick Childbb82ab72022-10-28 12:28:54 -0500567 end = p + buflen;
Nayna Jainc9deb182020-11-16 19:03:12 +0000568
Nick Childec817092022-12-15 15:54:03 -0600569 ret = pkcs7_get_content_info_type(&p, end, &end_content_info,
570 &pkcs7->content_type_oid);
Gilles Peskine449bd832023-01-11 14:50:10 +0100571 if (ret != 0) {
Nayna Jain673a2262020-12-14 22:44:49 +0000572 len = buflen;
573 goto try_data;
574 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000575
Nick Childec817092022-12-15 15:54:03 -0600576 /* Ensure PKCS7 data uses the exact number of bytes specified in buflen */
577 if (end_content_info != end) {
578 ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
579 goto out;
580 }
581
Gilles Peskine449bd832023-01-11 14:50:10 +0100582 if (!MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DATA, &pkcs7->content_type_oid)
Gilles Peskine449bd832023-01-11 14:50:10 +0100583 || !MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_ENVELOPED_DATA, &pkcs7->content_type_oid)
584 || !MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA, &pkcs7->content_type_oid)
585 || !MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DIGESTED_DATA, &pkcs7->content_type_oid)
586 || !MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, &pkcs7->content_type_oid)) {
Nayna Jainc9deb182020-11-16 19:03:12 +0000587 ret = MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
588 goto out;
589 }
590
Gilles Peskine449bd832023-01-11 14:50:10 +0100591 if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_SIGNED_DATA, &pkcs7->content_type_oid)) {
Nayna Jainc9deb182020-11-16 19:03:12 +0000592 ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
593 goto out;
594 }
595
Nayna Jain673a2262020-12-14 22:44:49 +0000596 isoidset = 1;
Nayna Jainc9deb182020-11-16 19:03:12 +0000597
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 ret = pkcs7_get_next_content_len(&p, end, &len);
599 if (ret != 0) {
Nayna Jainc9deb182020-11-16 19:03:12 +0000600 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100601 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000602
Nick Childec817092022-12-15 15:54:03 -0600603 /* ensure no extra/missing data */
604 if (p + len != end) {
605 ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
606 goto out;
607 }
608
Nayna Jain673a2262020-12-14 22:44:49 +0000609try_data:
Gilles Peskine449bd832023-01-11 14:50:10 +0100610 ret = pkcs7_get_signed_data(p, len, &pkcs7->signed_data);
611 if (ret != 0) {
Nayna Jain673a2262020-12-14 22:44:49 +0000612 goto out;
Gilles Peskine449bd832023-01-11 14:50:10 +0100613 }
Nayna Jain673a2262020-12-14 22:44:49 +0000614
Gilles Peskine449bd832023-01-11 14:50:10 +0100615 if (!isoidset) {
Nayna Jain673a2262020-12-14 22:44:49 +0000616 pkcs7->content_type_oid.tag = MBEDTLS_ASN1_OID;
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 pkcs7->content_type_oid.len = MBEDTLS_OID_SIZE(MBEDTLS_OID_PKCS7_SIGNED_DATA);
618 pkcs7->content_type_oid.p = (unsigned char *) MBEDTLS_OID_PKCS7_SIGNED_DATA;
Nayna Jain673a2262020-12-14 22:44:49 +0000619 }
620
621 ret = MBEDTLS_PKCS7_SIGNED_DATA;
Nayna Jainc9deb182020-11-16 19:03:12 +0000622
623out:
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 if (ret < 0) {
625 mbedtls_pkcs7_free(pkcs7);
626 }
Nayna Jain673a2262020-12-14 22:44:49 +0000627
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +0000629}
630
Gilles Peskine449bd832023-01-11 14:50:10 +0100631static int mbedtls_pkcs7_data_or_hash_verify(mbedtls_pkcs7 *pkcs7,
Nick Child73621ef2022-10-28 11:23:15 -0500632 const mbedtls_x509_crt *cert,
633 const unsigned char *data,
634 size_t datalen,
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 const int is_data_hash)
Nayna Jainc9deb182020-11-16 19:03:12 +0000636{
Nick Child9f4fb3e2022-09-12 16:21:02 -0500637 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nayna Jainc9deb182020-11-16 19:03:12 +0000638 unsigned char *hash;
639 mbedtls_pk_context pk_cxt = cert->pk;
640 const mbedtls_md_info_t *md_info;
641 mbedtls_md_type_t md_alg;
Daniel Axtens35384792020-09-02 14:48:45 +1000642 mbedtls_pkcs7_signer_info *signer;
Nayna Jainc9deb182020-11-16 19:03:12 +0000643
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 if (pkcs7->signed_data.no_of_signers == 0) {
645 return MBEDTLS_ERR_PKCS7_INVALID_CERT;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500646 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000647
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 if (mbedtls_x509_time_is_past(&cert->valid_to) ||
649 mbedtls_x509_time_is_future(&cert->valid_from)) {
650 return MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID;
Nick Child73621ef2022-10-28 11:23:15 -0500651 }
652
Daniel Axtens35384792020-09-02 14:48:45 +1000653 /*
654 * Potential TODOs
655 * Currently we iterate over all signers and return success if any of them
656 * verify.
657 *
658 * However, we could make this better by checking against the certificate's
659 * identification and SignerIdentifier fields first. That would also allow
660 * us to distinguish between 'no signature for key' and 'signature for key
661 * failed to validate'.
662 *
663 * We could also cache hashes by md, so if there are several sigs all using
664 * the same algo we don't recalculate the hash each time.
665 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 for (signer = &pkcs7->signed_data.signers; signer; signer = signer->next) {
667 ret = mbedtls_oid_get_md_alg(&signer->alg_identifier, &md_alg);
668 if (ret != 0) {
Nick Child9f4fb3e2022-09-12 16:21:02 -0500669 ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
Nick Child7089ce82022-09-14 14:10:00 -0500670 continue;
Nick Child9f4fb3e2022-09-12 16:21:02 -0500671 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000672
Gilles Peskine449bd832023-01-11 14:50:10 +0100673 md_info = mbedtls_md_info_from_type(md_alg);
674 if (md_info == NULL) {
Nick Child7089ce82022-09-14 14:10:00 -0500675 ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
676 continue;
677 }
Daniel Axtens35384792020-09-02 14:48:45 +1000678
Gilles Peskine449bd832023-01-11 14:50:10 +0100679 hash = mbedtls_calloc(mbedtls_md_get_size(md_info), 1);
680 if (hash == NULL) {
681 return MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
Daniel Axtens35384792020-09-02 14:48:45 +1000682 }
Gilles Peskine47a73262022-11-27 21:46:56 +0100683 /* BEGIN must free hash before jumping out */
Gilles Peskine449bd832023-01-11 14:50:10 +0100684 if (is_data_hash) {
685 if (datalen != mbedtls_md_get_size(md_info)) {
Nick Child73621ef2022-10-28 11:23:15 -0500686 ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
Gilles Peskine449bd832023-01-11 14:50:10 +0100687 } else {
Nick Child73621ef2022-10-28 11:23:15 -0500688 memcpy(hash, data, datalen);
Gilles Peskine449bd832023-01-11 14:50:10 +0100689 }
690 } else {
691 ret = mbedtls_md(md_info, data, datalen, hash);
Nick Child73621ef2022-10-28 11:23:15 -0500692 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100693 if (ret != 0) {
Nick Child7089ce82022-09-14 14:10:00 -0500694 ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 mbedtls_free(hash);
Nick Child7089ce82022-09-14 14:10:00 -0500696 continue;
Daniel Axtens35384792020-09-02 14:48:45 +1000697 }
698
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 ret = mbedtls_pk_verify(&pk_cxt, md_alg, hash,
700 mbedtls_md_get_size(md_info),
701 signer->sig.p, signer->sig.len);
702 mbedtls_free(hash);
Gilles Peskine47a73262022-11-27 21:46:56 +0100703 /* END must free hash before jumping out */
Daniel Axtens35384792020-09-02 14:48:45 +1000704
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 if (ret == 0) {
Daniel Axtens35384792020-09-02 14:48:45 +1000706 break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 }
Daniel Axtens35384792020-09-02 14:48:45 +1000708 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000709
Gilles Peskine449bd832023-01-11 14:50:10 +0100710 return ret;
Nayna Jainc9deb182020-11-16 19:03:12 +0000711}
Gilles Peskine449bd832023-01-11 14:50:10 +0100712int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7,
713 const mbedtls_x509_crt *cert,
714 const unsigned char *data,
715 size_t datalen)
Nick Child73621ef2022-10-28 11:23:15 -0500716{
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, data, datalen, 0);
Nick Child73621ef2022-10-28 11:23:15 -0500718}
Nayna Jainc9deb182020-11-16 19:03:12 +0000719
Gilles Peskine449bd832023-01-11 14:50:10 +0100720int mbedtls_pkcs7_signed_hash_verify(mbedtls_pkcs7 *pkcs7,
721 const mbedtls_x509_crt *cert,
722 const unsigned char *hash,
723 size_t hashlen)
Nayna Jainc9deb182020-11-16 19:03:12 +0000724{
Gilles Peskine449bd832023-01-11 14:50:10 +0100725 return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, hash, hashlen, 1);
Nayna Jainc9deb182020-11-16 19:03:12 +0000726}
727
728/*
729 * Unallocate all pkcs7 data
730 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100731void mbedtls_pkcs7_free(mbedtls_pkcs7 *pkcs7)
Nayna Jainc9deb182020-11-16 19:03:12 +0000732{
Daniel Axtens35384792020-09-02 14:48:45 +1000733 mbedtls_pkcs7_signer_info *signer_cur;
734 mbedtls_pkcs7_signer_info *signer_prev;
Nayna Jainc9deb182020-11-16 19:03:12 +0000735
Gilles Peskine449bd832023-01-11 14:50:10 +0100736 if (pkcs7 == NULL || pkcs7->raw.p == NULL) {
Nayna Jainc9deb182020-11-16 19:03:12 +0000737 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000739
Gilles Peskine449bd832023-01-11 14:50:10 +0100740 mbedtls_free(pkcs7->raw.p);
Nayna Jainc9deb182020-11-16 19:03:12 +0000741
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 mbedtls_x509_crt_free(&pkcs7->signed_data.certs);
743 mbedtls_x509_crl_free(&pkcs7->signed_data.crl);
Nayna Jainc9deb182020-11-16 19:03:12 +0000744
Daniel Axtens35384792020-09-02 14:48:45 +1000745 signer_cur = pkcs7->signed_data.signers.next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 pkcs7_free_signer_info(&pkcs7->signed_data.signers);
747 while (signer_cur != NULL) {
Daniel Axtens35384792020-09-02 14:48:45 +1000748 signer_prev = signer_cur;
749 signer_cur = signer_prev->next;
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 pkcs7_free_signer_info(signer_prev);
751 mbedtls_free(signer_prev);
Nayna Jainc9deb182020-11-16 19:03:12 +0000752 }
753
754 pkcs7->raw.p = NULL;
755}
756
757#endif