Branch data Line data Source code
1 : : /* Copyright 2019 IBM Corp.
2 : : *
3 : : * Licensed under the Apache License, Version 2.0 (the "License");
4 : : * you may not use this file except in compliance with the License.
5 : : * You may obtain a copy of the License at
6 : : *
7 : : * http://www.apache.org/licenses/LICENSE-2.0
8 : : *
9 : : * Unless required by applicable law or agreed to in writing, software
10 : : * distributed under the License is distributed on an "AS IS" BASIS,
11 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 : : * implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : #if !defined(MBEDTLS_CONFIG_FILE)
18 : : #include "mbedtls/config.h"
19 : : #else
20 : : #include MBEDTLS_CONFIG_FILE
21 : : #endif
22 : : #if defined(MBEDTLS_PKCS7_C)
23 : :
24 : : #include "mbedtls/x509.h"
25 : : #include "mbedtls/asn1.h"
26 : : #include "pkcs7.h"
27 : : #include "mbedtls/x509_crt.h"
28 : : #include "mbedtls/x509_crl.h"
29 : : #include "mbedtls/oid.h"
30 : :
31 : : #include <stdlib.h>
32 : : #include <stdio.h>
33 : : #include <string.h>
34 : : #if defined(MBEDTLS_FS_IO)
35 : : #include <sys/types.h>
36 : : #include <sys/stat.h>
37 : : #endif
38 : : #include <unistd.h>
39 : :
40 : : #if defined(MBEDTLS_PLATFORM_C)
41 : : #include "mbedtls/platform.h"
42 : : #include "mbedtls/platform_util.h"
43 : : #else
44 : : #include <stdio.h>
45 : : #include <stdlib.h>
46 : : #define mbedtls_free free
47 : : #define mbedtls_calloc calloc
48 : : #define mbedtls_printf printf
49 : : #define mbedtls_snprintf snprintf
50 : : #endif
51 : :
52 : : #if defined(MBEDTLS_HAVE_TIME)
53 : : #include "mbedtls/platform_time.h"
54 : : #endif
55 : : #if defined(MBEDTLS_HAVE_TIME_DATE)
56 : : #include <time.h>
57 : : #endif
58 : :
59 : : #if defined(MBEDTLS_FS_IO)
60 : : /*
61 : : * Load all data from a file into a given buffer.
62 : : *
63 : : * The file is expected to contain DER encoded data.
64 : : * A terminating null byte is always appended.
65 : : */
66 : : int mbedtls_pkcs7_load_file( const char *path, unsigned char **buf, size_t *n )
67 : : {
68 : : FILE *file;
69 : :
70 : : if( ( file = fopen( path, "rb" ) ) == NULL )
71 : : return( MBEDTLS_ERR_PKCS7_FILE_IO_ERROR );
72 : :
73 : : fseek( file, 0, SEEK_END );
74 : : *n = (size_t) ftell( file );
75 : : fseek( file, 0, SEEK_SET );
76 : :
77 : : *buf = mbedtls_calloc( 1, *n + 1 );
78 : : if( *buf == NULL )
79 : : return( MBEDTLS_ERR_PKCS7_ALLOC_FAILED );
80 : :
81 : : if( fread( *buf, 1, *n, file ) != *n )
82 : : {
83 : : fclose( file );
84 : :
85 : : mbedtls_platform_zeroize( *buf, *n + 1 );
86 : : mbedtls_free( *buf );
87 : :
88 : : return( MBEDTLS_ERR_PKCS7_FILE_IO_ERROR );
89 : : }
90 : :
91 : : fclose( file );
92 : :
93 : : (*buf)[*n] = '\0';
94 : :
95 : : return( 0 );
96 : : }
97 : : #endif
98 : :
99 : : /**
100 : : * Initializes the pkcs7 structure.
101 : : */
102 : 19 : void mbedtls_pkcs7_init( mbedtls_pkcs7 *pkcs7 )
103 : : {
104 : 19 : memset( pkcs7, 0, sizeof( mbedtls_pkcs7 ) );
105 : 19 : }
106 : :
107 : 15 : static int pkcs7_get_next_content_len( unsigned char **p, unsigned char *end,
108 : : size_t *len )
109 : : {
110 : : int ret;
111 : :
112 : 15 : if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_CONSTRUCTED
113 : : | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 )
114 : : {
115 : 0 : return( MBEDTLS_ERR_PKCS7_INVALID_FORMAT + ret );
116 : : }
117 : :
118 : 15 : return( 0 );
119 : : }
120 : :
121 : : /**
122 : : * version Version
123 : : * Version ::= INTEGER
124 : : **/
125 : 17 : static int pkcs7_get_version( unsigned char **p, unsigned char *end, int *ver )
126 : : {
127 : : int ret;
128 : :
129 : 17 : if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
130 : 0 : return( MBEDTLS_ERR_PKCS7_INVALID_FORMAT + ret );
131 : :
132 : : /* If version != 1, return invalid version */
133 : 17 : if( *ver != MBEDTLS_PKCS7_SUPPORTED_VERSION )
134 : 0 : return( MBEDTLS_ERR_PKCS7_INVALID_VERSION );
135 : :
136 : 17 : return( 0 );
137 : : }
138 : :
139 : : /**
140 : : * ContentInfo ::= SEQUENCE {
141 : : * contentType ContentType,
142 : : * content
143 : : * [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
144 : : **/
145 : 36 : static int pkcs7_get_content_info_type( unsigned char **p, unsigned char *end,
146 : : mbedtls_pkcs7_buf *pkcs7 )
147 : : {
148 : 36 : size_t len = 0;
149 : : int ret;
150 : 36 : unsigned char *start = *p;
151 : :
152 : 36 : ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
153 : : | MBEDTLS_ASN1_SEQUENCE );
154 : 36 : if( ret != 0 ) {
155 : 2 : *p = start;
156 : 2 : return( MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO + ret );
157 : : }
158 : :
159 : 34 : ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_OID );
160 : 34 : if( ret != 0 ) {
161 : 2 : *p = start;
162 : 2 : return( MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO + ret );
163 : : }
164 : :
165 : 32 : pkcs7->tag = MBEDTLS_ASN1_OID;
166 : 32 : pkcs7->len = len;
167 : 32 : pkcs7->p = *p;
168 : :
169 : 32 : return( ret );
170 : : }
171 : :
172 : : /**
173 : : * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
174 : : *
175 : : * This is from x509.h
176 : : **/
177 : 34 : static int pkcs7_get_digest_algorithm( unsigned char **p, unsigned char *end,
178 : : mbedtls_x509_buf *alg )
179 : : {
180 : : int ret;
181 : :
182 : 34 : if( ( ret = mbedtls_asn1_get_alg_null( p, end, alg ) ) != 0 )
183 : 0 : return( MBEDTLS_ERR_PKCS7_INVALID_ALG + ret );
184 : :
185 : 34 : return( 0 );
186 : : }
187 : :
188 : : /**
189 : : * DigestAlgorithmIdentifiers :: SET of DigestAlgorithmIdentifier
190 : : **/
191 : 17 : static int pkcs7_get_digest_algorithm_set( unsigned char **p,
192 : : unsigned char *end,
193 : : mbedtls_x509_buf *alg )
194 : : {
195 : 17 : size_t len = 0;
196 : : int ret;
197 : :
198 : 17 : ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
199 : : | MBEDTLS_ASN1_SET );
200 : 17 : if( ret != 0 )
201 : 0 : return( MBEDTLS_ERR_PKCS7_INVALID_ALG + ret );
202 : :
203 : 17 : end = *p + len;
204 : :
205 : : /** For now, it assumes there is only one digest algorithm specified **/
206 : 17 : ret = mbedtls_asn1_get_alg_null( p, end, alg );
207 : 17 : if( ret != 0 )
208 : 0 : return( MBEDTLS_ERR_PKCS7_INVALID_ALG + ret );
209 : :
210 : 17 : if (*p != end)
211 : 0 : return ( MBEDTLS_ERR_PKCS7_INVALID_FORMAT );
212 : :
213 : 17 : return( 0 );
214 : : }
215 : :
216 : : /**
217 : : * certificates :: SET OF ExtendedCertificateOrCertificate,
218 : : * ExtendedCertificateOrCertificate ::= CHOICE {
219 : : * certificate Certificate -- x509,
220 : : * extendedCertificate[0] IMPLICIT ExtendedCertificate }
221 : : **/
222 : 17 : static int pkcs7_get_certificates( unsigned char **p, unsigned char *end,
223 : : mbedtls_x509_crt *certs )
224 : : {
225 : : int ret;
226 : 17 : size_t len1 = 0;
227 : 17 : size_t len2 = 0;
228 : : unsigned char *end_set, *end_cert;
229 : 17 : unsigned char *start = *p;
230 : :
231 : 17 : if( ( ret = mbedtls_asn1_get_tag( p, end, &len1, MBEDTLS_ASN1_CONSTRUCTED
232 : : | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 )
233 : : {
234 : 0 : if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
235 : 0 : return( 0 );
236 : :
237 : 0 : return( MBEDTLS_ERR_PKCS7_INVALID_FORMAT + ret );
238 : : }
239 : 17 : start = *p;
240 : 17 : end_set = *p + len1;
241 : :
242 : : /* This is to verify that there is only signer certificate, it can
243 : : have its chain though. */
244 : 17 : ret = mbedtls_asn1_get_tag( p, end_set, &len2, MBEDTLS_ASN1_CONSTRUCTED
245 : : | MBEDTLS_ASN1_SEQUENCE );
246 : 17 : if( ret != 0 )
247 : 0 : return( MBEDTLS_ERR_PKCS7_INVALID_FORMAT + ret );
248 : :
249 : 17 : end_cert = *p + len2;
250 : :
251 : 17 : if (end_cert != end_set)
252 : 0 : return (MBEDTLS_ERR_PKCS7_INVALID_FORMAT);
253 : :
254 : : /* Since it satisfies the condition of single signer, continue parsing */
255 : 17 : *p = start;
256 : 17 : if( ( ret = mbedtls_x509_crt_parse( certs, *p, len1 ) ) < 0 )
257 : 0 : return( ret );
258 : :
259 : 17 : *p = *p + len1;
260 : :
261 : : /**
262 : : * Currently we do not check for certificate chain, so we are not handling
263 : : * "> 0" case. Return if atleast one certificate in the chain is correctly
264 : : * parsed.
265 : : **/
266 : :
267 : 17 : return( 0 );
268 : : }
269 : :
270 : : /**
271 : : * EncryptedDigest ::= OCTET STRING
272 : : **/
273 : 17 : static int pkcs7_get_signature( unsigned char **p, unsigned char *end,
274 : : mbedtls_pkcs7_buf *signature )
275 : : {
276 : : int ret;
277 : 17 : size_t len = 0;
278 : :
279 : 17 : ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_OCTET_STRING );
280 : 17 : if( ret != 0 )
281 : 0 : return( MBEDTLS_ERR_PKCS7_INVALID_SIGNATURE + ret );
282 : :
283 : 17 : signature->tag = MBEDTLS_ASN1_OCTET_STRING;
284 : 17 : signature->len = len;
285 : 17 : signature->p = *p;
286 : :
287 : 17 : *p = *p + len;
288 : :
289 : 17 : return( 0 );
290 : : }
291 : :
292 : : /**
293 : : * SignerInfos ::= SET of SignerInfo
294 : : * SignerInfo ::= SEQUENCE {
295 : : * version Version;
296 : : * issuerAndSerialNumber IssuerAndSerialNumber,
297 : : * digestAlgorithm DigestAlgorithmIdentifier,
298 : : * authenticatedAttributes
299 : : * [0] IMPLICIT Attributes OPTIONAL,
300 : : * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
301 : : * encryptedDigest EncryptedDigest,
302 : : * unauthenticatedAttributes
303 : : * [1] IMPLICIT Attributes OPTIONAL,
304 : : **/
305 : 17 : static int pkcs7_get_signers_info_set( unsigned char **p, unsigned char *end,
306 : : mbedtls_pkcs7_signer_info *signers_set )
307 : : {
308 : : unsigned char *end_set;
309 : : int ret;
310 : 17 : size_t len = 0;
311 : :
312 : 17 : ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
313 : : | MBEDTLS_ASN1_SET );
314 : 17 : if( ret != 0 )
315 : 0 : return( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO + ret );
316 : :
317 : 17 : end_set = *p + len;
318 : :
319 : 17 : ret = mbedtls_asn1_get_tag( p, end_set, &len, MBEDTLS_ASN1_CONSTRUCTED
320 : : | MBEDTLS_ASN1_SEQUENCE );
321 : 17 : if( ret != 0 )
322 : 0 : return( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO + ret );
323 : :
324 : 17 : end_set = *p + len;
325 : :
326 : 17 : ret = mbedtls_asn1_get_int( p, end_set, &signers_set->version );
327 : 17 : if( ret != 0 )
328 : 0 : return( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO + ret );
329 : :
330 : 17 : ret = mbedtls_asn1_get_tag( p, end_set, &len, MBEDTLS_ASN1_CONSTRUCTED
331 : : | MBEDTLS_ASN1_SEQUENCE );
332 : 17 : if( ret != 0 )
333 : 0 : return( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO + ret );
334 : :
335 : : /* Parsing IssuerAndSerialNumber */
336 : 17 : signers_set->issuer_raw.p = *p;
337 : :
338 : 17 : ret = mbedtls_asn1_get_tag( p, end_set, &len, MBEDTLS_ASN1_CONSTRUCTED
339 : : | MBEDTLS_ASN1_SEQUENCE );
340 : 17 : if( ret != 0 )
341 : 0 : return( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO + ret );
342 : :
343 : 17 : ret = mbedtls_x509_get_name( p, *p + len, &signers_set->issuer );
344 : 17 : if( ret != 0 )
345 : 0 : return( ret );
346 : :
347 : 17 : signers_set->issuer_raw.len = *p - signers_set->issuer_raw.p;
348 : :
349 : 17 : ret = mbedtls_x509_get_serial( p, end_set, &signers_set->serial );
350 : 17 : if( ret != 0 )
351 : 0 : return( ret );
352 : :
353 : 17 : ret = pkcs7_get_digest_algorithm( p, end_set,
354 : : &signers_set->alg_identifier );
355 : 17 : if( ret != 0 )
356 : 0 : return( ret );
357 : :
358 : 17 : ret = pkcs7_get_digest_algorithm( p, end_set,
359 : : &signers_set->sig_alg_identifier );
360 : 17 : if( ret != 0 )
361 : 0 : return( ret );
362 : :
363 : 17 : ret = pkcs7_get_signature( p, end_set, &signers_set->sig );
364 : 17 : if( ret != 0 )
365 : 0 : return( ret );
366 : :
367 : 17 : signers_set->next = NULL;
368 : :
369 : 17 : if (*p != end_set)
370 : 0 : return ( MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO );
371 : :
372 : 17 : return( 0 );
373 : : }
374 : :
375 : : /**
376 : : * SignedData ::= SEQUENCE {
377 : : * version Version,
378 : : * digestAlgorithms DigestAlgorithmIdentifiers,
379 : : * contentInfo ContentInfo,
380 : : * certificates
381 : : * [0] IMPLICIT ExtendedCertificatesAndCertificates
382 : : * OPTIONAL,
383 : : * crls
384 : : * [0] IMPLICIT CertificateRevocationLists OPTIONAL,
385 : : * signerInfos SignerInfos }
386 : : */
387 : 19 : static int pkcs7_get_signed_data( unsigned char *buf, size_t buflen,
388 : : mbedtls_pkcs7_signed_data *signed_data )
389 : : {
390 : 19 : unsigned char *p = buf;
391 : 19 : unsigned char *end = buf + buflen;
392 : : unsigned char *end_set;
393 : 19 : size_t len = 0;
394 : : int ret;
395 : : mbedtls_md_type_t md_alg;
396 : :
397 : 19 : ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
398 : : | MBEDTLS_ASN1_SEQUENCE );
399 : 19 : if( ret != 0 )
400 : 2 : return( MBEDTLS_ERR_PKCS7_INVALID_FORMAT + ret );
401 : :
402 : 17 : end_set = p + len;
403 : :
404 : : /* Get version of signed data */
405 : 17 : ret = pkcs7_get_version( &p, end_set, &signed_data->version );
406 : 17 : if( ret != 0 )
407 : 0 : return( ret );
408 : :
409 : : /* Get digest algorithm */
410 : 17 : ret = pkcs7_get_digest_algorithm_set( &p, end_set,
411 : 17 : &signed_data->digest_alg_identifiers );
412 : 17 : if( ret != 0 )
413 : 0 : return( ret );
414 : :
415 : 17 : ret = mbedtls_oid_get_md_alg( &signed_data->digest_alg_identifiers, &md_alg );
416 : 17 : if( ret != 0 )
417 : 0 : return( MBEDTLS_ERR_PKCS7_INVALID_ALG + ret );
418 : :
419 : : /* Do not expect any content */
420 : 17 : ret = pkcs7_get_content_info_type( &p, end_set, &signed_data->content.oid );
421 : 17 : if( ret != 0 )
422 : 0 : return( ret );
423 : :
424 : 17 : if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_DATA, &signed_data->content.oid ) )
425 : : {
426 : 0 : return( MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO ) ;
427 : : }
428 : :
429 : 17 : p = p + signed_data->content.oid.len;
430 : :
431 : : /* Look for certificates, there may or may not be any */
432 : 17 : mbedtls_x509_crt_init( &signed_data->certs );
433 : 17 : ret = pkcs7_get_certificates( &p, end_set, &signed_data->certs );
434 : 17 : if( ret != 0 )
435 : 0 : return( ret ) ;
436 : :
437 : : /* TODO: optional CRLs go here, currently no CRLs are expected */
438 : :
439 : : /* Get signers info */
440 : 17 : ret = pkcs7_get_signers_info_set( &p, end_set, &signed_data->signers );
441 : 17 : if( ret != 0 )
442 : 0 : return( ret );
443 : :
444 : 17 : if ( p != end )
445 : 0 : ret = MBEDTLS_ERR_PKCS7_INVALID_FORMAT;
446 : :
447 : 17 : return( ret );
448 : : }
449 : :
450 : 19 : int mbedtls_pkcs7_parse_der( const unsigned char *buf, const int buflen,
451 : : mbedtls_pkcs7 *pkcs7 )
452 : : {
453 : : unsigned char *start;
454 : : unsigned char *end;
455 : 19 : size_t len = 0;
456 : : int ret;
457 : 19 : int isoidset = 0;
458 : :
459 : : /* use internal buffer for parsing */
460 : 19 : start = (unsigned char *)buf;
461 : 19 : end = start + buflen;
462 : :
463 : 19 : if( !pkcs7 )
464 : 0 : return( MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA );
465 : :
466 : 19 : ret = pkcs7_get_content_info_type( &start, end, &pkcs7->content_type_oid );
467 : 19 : if( ret != 0 )
468 : : {
469 : 4 : len = buflen;
470 : 4 : goto try_data;
471 : : }
472 : :
473 : 15 : if( ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_DATA, &pkcs7->content_type_oid )
474 : 15 : || ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, &pkcs7->content_type_oid )
475 : 15 : || ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_ENVELOPED_DATA, &pkcs7->content_type_oid )
476 : 15 : || ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA, &pkcs7->content_type_oid )
477 : 15 : || ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_DIGESTED_DATA, &pkcs7->content_type_oid )
478 : 15 : || ! MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, &pkcs7->content_type_oid ) )
479 : : {
480 : 0 : ret = MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
481 : 0 : goto out;
482 : : }
483 : :
484 : 15 : if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS7_SIGNED_DATA, &pkcs7->content_type_oid ) )
485 : : {
486 : 0 : ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
487 : 0 : goto out;
488 : : }
489 : :
490 : 15 : isoidset = 1;
491 : 15 : start = start + pkcs7->content_type_oid.len;
492 : :
493 : 15 : ret = pkcs7_get_next_content_len( &start, end, &len );
494 : 15 : if( ret != 0 )
495 : 0 : goto out;
496 : :
497 : 15 : try_data:
498 : 19 : ret = pkcs7_get_signed_data( start, len, &pkcs7->signed_data );
499 : 19 : if (ret != 0)
500 : 2 : goto out;
501 : :
502 : 17 : if (!isoidset)
503 : : {
504 : 2 : pkcs7->content_type_oid.tag = MBEDTLS_ASN1_OID;
505 : 2 : pkcs7->content_type_oid.len = MBEDTLS_OID_SIZE(MBEDTLS_OID_PKCS7_SIGNED_DATA);
506 : 2 : pkcs7->content_type_oid.p = (unsigned char *)MBEDTLS_OID_PKCS7_SIGNED_DATA;
507 : : }
508 : :
509 : 17 : ret = MBEDTLS_PKCS7_SIGNED_DATA;
510 : :
511 : 19 : out:
512 : 19 : if ( ret < 0 )
513 : 2 : mbedtls_pkcs7_free( pkcs7 );
514 : :
515 : 19 : return( ret );
516 : : }
517 : :
518 : 0 : int mbedtls_pkcs7_signed_data_verify( mbedtls_pkcs7 *pkcs7,
519 : : mbedtls_x509_crt *cert,
520 : : const unsigned char *data,
521 : : size_t datalen )
522 : : {
523 : :
524 : : int ret;
525 : : unsigned char *hash;
526 : 0 : mbedtls_pk_context pk_cxt = cert->pk;
527 : : const mbedtls_md_info_t *md_info;
528 : : mbedtls_md_type_t md_alg;
529 : :
530 : 0 : ret = mbedtls_oid_get_md_alg( &pkcs7->signed_data.digest_alg_identifiers, &md_alg );
531 : 0 : if( ret != 0 )
532 : 0 : return( MBEDTLS_ERR_PKCS7_INVALID_ALG + ret );
533 : :
534 : 0 : md_info = mbedtls_md_info_from_type( md_alg );
535 : :
536 : 0 : hash = mbedtls_calloc( mbedtls_md_get_size( md_info ), 1 );
537 : 0 : if( hash == NULL ) {
538 : 0 : return( MBEDTLS_ERR_PKCS7_ALLOC_FAILED );
539 : : }
540 : :
541 : 0 : mbedtls_md( md_info, data, datalen, hash );
542 : :
543 : 0 : ret = mbedtls_pk_verify( &pk_cxt, md_alg, hash, 0,
544 : 0 : pkcs7->signed_data.signers.sig.p,
545 : : pkcs7->signed_data.signers.sig.len );
546 : :
547 : 0 : mbedtls_free( hash );
548 : :
549 : 0 : return( ret );
550 : : }
551 : :
552 : 16 : int mbedtls_pkcs7_signed_hash_verify( mbedtls_pkcs7 *pkcs7,
553 : : mbedtls_x509_crt *cert,
554 : : const unsigned char *hash, int hashlen)
555 : : {
556 : : int ret;
557 : : mbedtls_md_type_t md_alg;
558 : : mbedtls_pk_context pk_cxt;
559 : :
560 : 16 : ret = mbedtls_oid_get_md_alg( &pkcs7->signed_data.digest_alg_identifiers, &md_alg );
561 : 16 : if( ret != 0 )
562 : 0 : return( MBEDTLS_ERR_PKCS7_INVALID_ALG + ret );
563 : :
564 : 16 : pk_cxt = cert->pk;
565 : 16 : ret = mbedtls_pk_verify( &pk_cxt, md_alg, hash, hashlen,
566 : 16 : pkcs7->signed_data.signers.sig.p,
567 : : pkcs7->signed_data.signers.sig.len );
568 : :
569 : 16 : return ( ret );
570 : : }
571 : :
572 : : /*
573 : : * Unallocate all pkcs7 data
574 : : */
575 : 20 : void mbedtls_pkcs7_free( mbedtls_pkcs7 *pkcs7 )
576 : : {
577 : : mbedtls_x509_name *name_cur;
578 : : mbedtls_x509_name *name_prv;
579 : :
580 : 20 : if( pkcs7 == NULL )
581 : 0 : return;
582 : :
583 : 20 : mbedtls_x509_crt_free( &pkcs7->signed_data.certs );
584 : 20 : mbedtls_x509_crl_free( &pkcs7->signed_data.crl );
585 : :
586 : 20 : name_cur = pkcs7->signed_data.signers.issuer.next;
587 : 112 : while( name_cur != NULL )
588 : : {
589 : 92 : name_prv = name_cur;
590 : 92 : name_cur = name_cur->next;
591 : 92 : mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
592 : 92 : mbedtls_free( name_prv );
593 : : }
594 : :
595 : 20 : mbedtls_platform_zeroize( pkcs7, sizeof( mbedtls_pkcs7 ) );
596 : : }
597 : :
598 : : #endif
|