blob: 9b66bdb23f36f7aafd95d4b15cb1ac2488b8c3bb [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"
27
28#include <stdlib.h>
29#include <stdio.h>
30#include <string.h>
31#if defined(MBEDTLS_FS_IO)
32#include <sys/types.h>
33#include <sys/stat.h>
34#endif
35
36#if defined(MBEDTLS_PLATFORM_C)
37#include "mbedtls/platform.h"
38#include "mbedtls/platform_util.h"
39#else
40#include <stdio.h>
41#include <stdlib.h>
42#define mbedtls_free free
43#define mbedtls_calloc calloc
44#define mbedtls_printf printf
45#define mbedtls_snprintf snprintf
46#endif
47
48#if defined(MBEDTLS_HAVE_TIME)
49#include "mbedtls/platform_time.h"
50#endif
51#if defined(MBEDTLS_HAVE_TIME_DATE)
52#include <time.h>
53#endif
54
55/**
56 * Initializes the pkcs7 structure.
57 */
58void mbedtls_pkcs7_init( mbedtls_pkcs7 *pkcs7 )
59{
60 memset( pkcs7, 0, sizeof( mbedtls_pkcs7 ) );
61 pkcs7->raw.p = NULL;
62}
63
64static int pkcs7_get_next_content_len( unsigned char **p, unsigned char *end,
65 size_t *len )
66{
67 int ret;
68
69 if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_CONSTRUCTED
70 | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 )
71 {
72 return( MBEDTLS_ERR_PKCS7_INVALID_FORMAT + ret );
73 }
74
75 return( 0 );
76}
77
78/**
79 * version Version
80 * Version ::= INTEGER
81 **/
82static int pkcs7_get_version( unsigned char **p, unsigned char *end, int *ver )
83{
84 int ret;
85
86 if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
87 return( MBEDTLS_ERR_PKCS7_INVALID_VERSION + ret );
88
89 /* If version != 1, return invalid version */
90 if( *ver != MBEDTLS_PKCS7_SUPPORTED_VERSION )
91 return( MBEDTLS_ERR_PKCS7_INVALID_VERSION );
92
93 return( 0 );
94}
95
96/**
97 * ContentInfo ::= SEQUENCE {
98 * contentType ContentType,
99 * content
100 * [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
101 **/
102static int pkcs7_get_content_info_type( unsigned char **p, unsigned char *end,
103 mbedtls_pkcs7_buf *pkcs7 )
104{
105 size_t len = 0;
106 int ret;
Nayna Jain673a2262020-12-14 22:44:49 +0000107 unsigned char *start = *p;
Nayna Jainc9deb182020-11-16 19:03:12 +0000108
109 ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
110 | MBEDTLS_ASN1_SEQUENCE );
Nick Childc448c942021-07-01 15:29:50 -0400111 if( ret != 0 ) {
112 *p = start;
Nayna Jainc9deb182020-11-16 19:03:12 +0000113 return( MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO + ret );
Nick Childc448c942021-07-01 15:29:50 -0400114 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000115
116 ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_OID );
Nayna Jain673a2262020-12-14 22:44:49 +0000117 if( ret != 0 ) {
118 *p = start;
Nayna Jainc9deb182020-11-16 19:03:12 +0000119 return( MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO + ret );
Nayna Jain673a2262020-12-14 22:44:49 +0000120 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000121
122 pkcs7->tag = MBEDTLS_ASN1_OID;
123 pkcs7->len = len;
124 pkcs7->p = *p;
125
126 return( ret );
127}
128
129/**
130 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
131 *
132 * This is from x509.h
133 **/
134static int pkcs7_get_digest_algorithm( unsigned char **p, unsigned char *end,
135 mbedtls_x509_buf *alg )
136{
137 int ret;
138
139 if( ( ret = mbedtls_asn1_get_alg_null( p, end, alg ) ) != 0 )
140 return( MBEDTLS_ERR_PKCS7_INVALID_ALG );
141
142 return( 0 );
143}
144
145/**
146 * DigestAlgorithmIdentifiers :: SET of DigestAlgorithmIdentifier
147 **/
148static int pkcs7_get_digest_algorithm_set( unsigned char **p,
149 unsigned char *end,
150 mbedtls_x509_buf *alg )
151{
152 size_t len = 0;
153 int ret;
154
155 ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
156 | MBEDTLS_ASN1_SET );
157 if( ret != 0 )
158 return( MBEDTLS_ERR_PKCS7_INVALID_ALG + ret );
159
160 end = *p + len;
161
162 /** For now, it assumes there is only one digest algorithm specified **/
163 ret = mbedtls_asn1_get_alg_null( p, end, alg );
164 if( ret != 0 )
165 return( MBEDTLS_ERR_PKCS7_INVALID_ALG + ret );
166
167 if ( *p != end )
168 return ( MBEDTLS_ERR_PKCS7_INVALID_FORMAT );
169
170 return( 0 );
171}
172
173/**
174 * certificates :: SET OF ExtendedCertificateOrCertificate,
175 * ExtendedCertificateOrCertificate ::= CHOICE {
176 * certificate Certificate -- x509,
177 * extendedCertificate[0] IMPLICIT ExtendedCertificate }
178 * Return number of certificates added to the signed data,
179 * 0 or higher is valid.
180 * Return negative error code for failure.
181 **/
182static int pkcs7_get_certificates( unsigned char **p, unsigned char *end,
183 mbedtls_x509_crt *certs )
184{
185 int ret;
186 size_t len1 = 0;
187 size_t len2 = 0;
188 unsigned char *end_set, *end_cert;
189 unsigned char *start = *p;
190
191 if( ( ret = mbedtls_asn1_get_tag( p, end, &len1, MBEDTLS_ASN1_CONSTRUCTED
192 | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 )
193 {
194 if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
195 return( 0 );
196
197 return( MBEDTLS_ERR_PKCS7_INVALID_FORMAT + ret );
198 }
199 start = *p;
200 end_set = *p + len1;
201
202 ret = mbedtls_asn1_get_tag( p, end_set, &len2, MBEDTLS_ASN1_CONSTRUCTED
203 | MBEDTLS_ASN1_SEQUENCE );
204 if( ret != 0 )
205 return( MBEDTLS_ERR_PKCS7_INVALID_CERT + ret );
206
207 end_cert = *p + len2;
208
209 /*
210 * This is to verify that there is only one signer certificate. It seems it is
211 * not easy to differentiate between the chain vs different signer's certificate.
212 * So, we support only the root certificate and the single signer.
213 * The behaviour would be improved with addition of multiple signer support.
214 */
215 if (end_cert != end_set)
216 return ( MBEDTLS_ERR_PKCS7_INVALID_CERT );
217
218 *p = start;
219 if( ( ret = mbedtls_x509_crt_parse( certs, *p, len1 ) ) < 0 )
220 return( MBEDTLS_ERR_PKCS7_INVALID_CERT );
221
222 *p = *p + len1;
223
224 /* Since in this version we strictly support single certificate, and reaching
225 * here implies we have parsed successfully, we return 1. */
226
227 return( 1 );
228}
229
230/**
231 * EncryptedDigest ::= OCTET STRING
232 **/
233static int pkcs7_get_signature( unsigned char **p, unsigned char *end,
234 mbedtls_pkcs7_buf *signature )
235{
236 int ret;
237 size_t len = 0;
238
239 ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_OCTET_STRING );
240 if( ret != 0 )
241 return( ret );
242
243 signature->tag = MBEDTLS_ASN1_OCTET_STRING;
244 signature->len = len;
245 signature->p = *p;
246
247 *p = *p + len;
248
249 return( 0 );
250}
251
252/**
253 * SignerInfos ::= SET of SignerInfo
254 * SignerInfo ::= SEQUENCE {
255 * version Version;
256 * issuerAndSerialNumber IssuerAndSerialNumber,
257 * digestAlgorithm DigestAlgorithmIdentifier,
258 * authenticatedAttributes
259 * [0] IMPLICIT Attributes OPTIONAL,
260 * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
261 * encryptedDigest EncryptedDigest,
262 * unauthenticatedAttributes
263 * [1] IMPLICIT Attributes OPTIONAL,
264 * Return number of signers added to the signed data,
265 * 0 or higher is valid.
266 * Return negative error code for failure.
267 **/
268static int pkcs7_get_signers_info_set( unsigned char **p, unsigned char *end,
269 mbedtls_pkcs7_signer_info *signers_set )
270{
271 unsigned char *end_set, *end_set_signer;
272 int ret;
273 size_t len = 0;
274
275 ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
276 | MBEDTLS_ASN1_SET );
277 if( ret != 0 )
278 return( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO + ret );
279
280 end_set = *p + len;
281
282 ret = mbedtls_asn1_get_tag( p, end_set, &len, MBEDTLS_ASN1_CONSTRUCTED
283 | MBEDTLS_ASN1_SEQUENCE );
284 if( ret != 0 )
285 return( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO + ret );
286
287 end_set_signer = *p + len;
288 if (end_set_signer != end_set)
289 return ( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO );
290
291 end_set = end_set_signer;
292
Nick Child6427b342022-02-25 11:43:31 -0600293 ret = pkcs7_get_version( p, end_set, &signers_set->version );
Nayna Jainc9deb182020-11-16 19:03:12 +0000294 if( ret != 0 )
295 return( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO );
296
297 ret = mbedtls_asn1_get_tag( p, end_set, &len, MBEDTLS_ASN1_CONSTRUCTED
298 | MBEDTLS_ASN1_SEQUENCE );
299 if( ret != 0 )
300 return( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO + ret );
301
302 /* Parsing IssuerAndSerialNumber */
303 signers_set->issuer_raw.p = *p;
304
305 ret = mbedtls_asn1_get_tag( p, end_set, &len, MBEDTLS_ASN1_CONSTRUCTED
306 | MBEDTLS_ASN1_SEQUENCE );
307 if( ret != 0 )
308 return( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO + ret );
309
310 ret = mbedtls_x509_get_name( p, *p + len, &signers_set->issuer );
311 if( ret != 0 )
312 return( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO );
313
314 signers_set->issuer_raw.len = *p - signers_set->issuer_raw.p;
315
316 ret = mbedtls_x509_get_serial( p, end_set, &signers_set->serial );
317 if( ret != 0 )
318 return( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO );
319
320 ret = pkcs7_get_digest_algorithm( p, end_set, &signers_set->alg_identifier );
321 if( ret != 0 )
322 return( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO );
323
324 ret = pkcs7_get_digest_algorithm( p, end_set, &signers_set->sig_alg_identifier );
325 if( ret != 0 )
326 return( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO );
327
328 ret = pkcs7_get_signature( p, end_set, &signers_set->sig );
329 if( ret != 0 )
330 return( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO );
331
332 signers_set->next = NULL;
333
334 if (*p != end_set)
335 return ( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO );
336
337 /* Since in this version we strictly support single signer, and reaching
338 * here implies we have parsed successfully, we return 1. */
339
340 return( 1 );
341}
342
343/**
344 * SignedData ::= SEQUENCE {
345 * version Version,
346 * digestAlgorithms DigestAlgorithmIdentifiers,
347 * contentInfo ContentInfo,
348 * certificates
349 * [0] IMPLICIT ExtendedCertificatesAndCertificates
350 * OPTIONAL,
351 * crls
352 * [0] IMPLICIT CertificateRevocationLists OPTIONAL,
353 * signerInfos SignerInfos }
354 */
355static int pkcs7_get_signed_data( unsigned char *buf, size_t buflen,
356 mbedtls_pkcs7_signed_data *signed_data )
357{
358 unsigned char *p = buf;
359 unsigned char *end = buf + buflen;
360 unsigned char *end_set;
361 size_t len = 0;
362 int ret;
363 mbedtls_md_type_t md_alg;
364
365 ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
366 | MBEDTLS_ASN1_SEQUENCE );
367 if( ret != 0 )
368 return( MBEDTLS_ERR_PKCS7_INVALID_FORMAT + ret );
369
370 end_set = p + len;
371
372 /* Get version of signed data */
373 ret = pkcs7_get_version( &p, end_set, &signed_data->version );
374 if( ret != 0 )
375 return( ret );
376
377 /* Get digest algorithm */
378 ret = pkcs7_get_digest_algorithm_set( &p, end_set,
379 &signed_data->digest_alg_identifiers );
380 if( ret != 0 )
381 return( ret );
382
383 ret = mbedtls_oid_get_md_alg( &signed_data->digest_alg_identifiers, &md_alg );
384 if( ret != 0 )
385 return( MBEDTLS_ERR_PKCS7_INVALID_ALG );
386
387 /* Do not expect any content */
388 ret = pkcs7_get_content_info_type( &p, end_set, &signed_data->content.oid );
389 if( ret != 0 )
390 return( ret );
391
392 if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_DATA, &signed_data->content.oid ) )
393 {
394 return( MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO ) ;
395 }
396
397 p = p + signed_data->content.oid.len;
398
399 /* Look for certificates, there may or may not be any */
400 mbedtls_x509_crt_init( &signed_data->certs );
401 ret = pkcs7_get_certificates( &p, end_set, &signed_data->certs );
402 if( ret < 0 )
403 return( ret ) ;
404
405 signed_data->no_of_certs = ret;
406
407 /*
408 * Currently CRLs are not supported. If CRL exist, the parsing will fail
409 * at next step of getting signers info and return error as invalid
410 * signer info.
411 */
412
413 signed_data->no_of_crls = 0;
414
415 /* Get signers info */
416 ret = pkcs7_get_signers_info_set( &p, end_set, &signed_data->signers );
417 if( ret < 0 )
418 return( ret );
419
420 signed_data->no_of_signers = ret;
421
422 /* Support single signer */
423 if ( p != end )
424 ret = MBEDTLS_ERR_PKCS7_INVALID_FORMAT;
425
426 ret = 0;
427 return( ret );
428}
429
430int mbedtls_pkcs7_parse_der( mbedtls_pkcs7 *pkcs7, const unsigned char *buf,
431 const size_t buflen )
432{
433 unsigned char *start;
434 unsigned char *end;
435 size_t len = 0;
436 int ret;
Nayna Jain673a2262020-12-14 22:44:49 +0000437 int isoidset = 0;
Nayna Jainc9deb182020-11-16 19:03:12 +0000438
439 if( !pkcs7 )
440 return( MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA );
441
442 /* make an internal copy of the buffer for parsing */
443 pkcs7->raw.p = start = mbedtls_calloc( 1, buflen );
444 if( pkcs7->raw.p == NULL )
445 {
446 return( MBEDTLS_ERR_PKCS7_ALLOC_FAILED );
447 }
448 memcpy( start, buf, buflen );
449 pkcs7->raw.len = buflen;
450 end = start + buflen;
451
452 ret = pkcs7_get_content_info_type( &start, end, &pkcs7->content_type_oid );
453 if( ret != 0 )
Nayna Jain673a2262020-12-14 22:44:49 +0000454 {
455 len = buflen;
456 goto try_data;
457 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000458
459 if( ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_DATA, &pkcs7->content_type_oid )
460 || ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, &pkcs7->content_type_oid )
461 || ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_ENVELOPED_DATA, &pkcs7->content_type_oid )
462 || ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA, &pkcs7->content_type_oid )
463 || ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_DIGESTED_DATA, &pkcs7->content_type_oid )
464 || ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, &pkcs7->content_type_oid ) )
465 {
466 ret = MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
467 goto out;
468 }
469
470 if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_SIGNED_DATA, &pkcs7->content_type_oid ) )
471 {
472 ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
473 goto out;
474 }
475
Nayna Jain673a2262020-12-14 22:44:49 +0000476 isoidset = 1;
Nayna Jainc9deb182020-11-16 19:03:12 +0000477 start = start + pkcs7->content_type_oid.len;
478
479 ret = pkcs7_get_next_content_len( &start, end, &len );
480 if( ret != 0 )
481 goto out;
482
Nayna Jain673a2262020-12-14 22:44:49 +0000483try_data:
Nayna Jainc9deb182020-11-16 19:03:12 +0000484 ret = pkcs7_get_signed_data( start, len, &pkcs7->signed_data );
Nayna Jain673a2262020-12-14 22:44:49 +0000485 if ( ret != 0 )
486 goto out;
487
488 if ( !isoidset )
489 {
490 pkcs7->content_type_oid.tag = MBEDTLS_ASN1_OID;
491 pkcs7->content_type_oid.len = MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS7_SIGNED_DATA );
492 pkcs7->content_type_oid.p = (unsigned char *)MBEDTLS_OID_PKCS7_SIGNED_DATA;
493 }
494
495 ret = MBEDTLS_PKCS7_SIGNED_DATA;
Nayna Jainc9deb182020-11-16 19:03:12 +0000496
497out:
Nayna Jain673a2262020-12-14 22:44:49 +0000498 if ( ret < 0 )
Nayna Jainc9deb182020-11-16 19:03:12 +0000499 mbedtls_pkcs7_free( pkcs7 );
Nayna Jain673a2262020-12-14 22:44:49 +0000500
Nayna Jainc9deb182020-11-16 19:03:12 +0000501 return( ret );
502}
503
504int mbedtls_pkcs7_signed_data_verify( mbedtls_pkcs7 *pkcs7,
505 const mbedtls_x509_crt *cert,
506 const unsigned char *data,
507 size_t datalen )
508{
509
510 int ret;
511 unsigned char *hash;
512 mbedtls_pk_context pk_cxt = cert->pk;
513 const mbedtls_md_info_t *md_info;
514 mbedtls_md_type_t md_alg;
515
516 ret = mbedtls_oid_get_md_alg( &pkcs7->signed_data.digest_alg_identifiers, &md_alg );
517 if( ret != 0 )
518 return( MBEDTLS_ERR_PKCS7_VERIFY_FAIL );
519
520 md_info = mbedtls_md_info_from_type( md_alg );
521
522 hash = mbedtls_calloc( mbedtls_md_get_size( md_info ), 1 );
523 if( hash == NULL ) {
524 return( MBEDTLS_ERR_PKCS7_ALLOC_FAILED );
525 }
526
Nick Child66718412022-02-22 17:19:59 -0600527 ret = mbedtls_md( md_info, data, datalen, hash );
528 if( ret != 0 )
529 {
530 mbedtls_free( hash );
531 return( ret );
532 }
Nayna Jainc9deb182020-11-16 19:03:12 +0000533 ret = mbedtls_pk_verify( &pk_cxt, md_alg, hash, 0,
534 pkcs7->signed_data.signers.sig.p,
535 pkcs7->signed_data.signers.sig.len );
536
537 mbedtls_free( hash );
538
539 return( ret );
540}
541
542int mbedtls_pkcs7_signed_hash_verify( mbedtls_pkcs7 *pkcs7,
543 const mbedtls_x509_crt *cert,
544 const unsigned char *hash, size_t hashlen)
545{
546 int ret;
547 mbedtls_md_type_t md_alg;
548 mbedtls_pk_context pk_cxt;
549
550 ret = mbedtls_oid_get_md_alg( &pkcs7->signed_data.digest_alg_identifiers, &md_alg );
551 if( ret != 0 )
552 return( MBEDTLS_ERR_PKCS7_VERIFY_FAIL );
553
554 pk_cxt = cert->pk;
555 ret = mbedtls_pk_verify( &pk_cxt, md_alg, hash, hashlen,
556 pkcs7->signed_data.signers.sig.p,
557 pkcs7->signed_data.signers.sig.len );
558
559 return ( ret );
560}
561
562/*
563 * Unallocate all pkcs7 data
564 */
565void mbedtls_pkcs7_free( mbedtls_pkcs7 *pkcs7 )
566{
567 mbedtls_x509_name *name_cur;
568 mbedtls_x509_name *name_prv;
569
570 if( pkcs7 == NULL || pkcs7->raw.p == NULL )
571 return;
572
573 mbedtls_free( pkcs7->raw.p );
574
575 mbedtls_x509_crt_free( &pkcs7->signed_data.certs );
576 mbedtls_x509_crl_free( &pkcs7->signed_data.crl );
577
578 name_cur = pkcs7->signed_data.signers.issuer.next;
579 while( name_cur != NULL )
580 {
581 name_prv = name_cur;
582 name_cur = name_cur->next;
583 mbedtls_free( name_prv );
584 }
585
586 pkcs7->raw.p = NULL;
587}
588
589#endif