TianoCore EDK2 master
Loading...
Searching...
No Matches
CryptPkcs7VerifyCommon.c
Go to the documentation of this file.
1
13#include "CryptPkcs7Internal.h"
14#include <mbedtls/pkcs7.h>
15
16/* Profile for backward compatibility. Allows RSA 1024, unlike the default
17 profile. */
18STATIC mbedtls_x509_crt_profile gCompatProfile =
19{
20 /* Hashes from SHA-256 and above. Note that this selection
21 * should be aligned with ssl_preset_default_hashes in ssl_tls.c. */
22
23 #ifndef DISABLE_SHA1_DEPRECATED_INTERFACES
24 MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA1) |
25 #endif
26 MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA256) |
27 MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA384) |
28 MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA512),
29 0xFFFFFFF, /* Any PK alg */
30
31 /* Curves at or above 128-bit security level. Note that this selection
32 * should be aligned with ssl_preset_default_curves in ssl_tls.c. */
33 MBEDTLS_X509_ID_FLAG (MBEDTLS_ECP_DP_SECP256R1) |
34 MBEDTLS_X509_ID_FLAG (MBEDTLS_ECP_DP_SECP384R1) |
35 MBEDTLS_X509_ID_FLAG (MBEDTLS_ECP_DP_SECP521R1) |
36 MBEDTLS_X509_ID_FLAG (MBEDTLS_ECP_DP_BP256R1) |
37 MBEDTLS_X509_ID_FLAG (MBEDTLS_ECP_DP_BP384R1) |
38 MBEDTLS_X509_ID_FLAG (MBEDTLS_ECP_DP_BP512R1) |
39 0,
40 1024,
41};
42
49VOID
51 MbedtlsPkcs7 *Pkcs7
52 )
53{
54 ZeroMem (Pkcs7, sizeof (MbedtlsPkcs7));
55}
56
68INT32
70 UINT8 **Ptr,
71 UINT8 *End,
72 UINTN *Len
73 )
74{
75 INT32 Ret;
76
77 Ret = mbedtls_asn1_get_tag (Ptr, End, Len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
78 return Ret;
79}
80
92INT32
94 UINT8 **Ptr,
95 UINT8 *End,
96 INT32 *Ver
97 )
98{
99 INT32 Ret;
100
101 Ret = mbedtls_asn1_get_int (Ptr, End, Ver);
102 return Ret;
103}
104
118STATIC
119INT32
121 UINT8 **Ptr,
122 UINT8 *End,
123 mbedtls_asn1_buf *Pkcs7
124 )
125{
126 UINTN Len;
127 int Ret;
128
129 Len = 0;
130 Ret = mbedtls_asn1_get_tag (
131 Ptr,
132 End,
133 &Len,
134 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE
135 );
136
137 if (Ret == 0) {
138 Ret = mbedtls_asn1_get_tag (Ptr, End, &Len, MBEDTLS_ASN1_OID);
139 }
140
141 if (Ret == 0) {
142 Pkcs7->tag = MBEDTLS_ASN1_OID;
143 Pkcs7->len = Len;
144 Pkcs7->p = *Ptr;
145 }
146
147 return Ret;
148}
149
160STATIC
161INT32
163 UINT8 **Ptr,
164 UINT8 *End,
165 mbedtls_x509_buf *Alg
166 )
167{
168 INT32 Ret;
169
170 Ret = mbedtls_asn1_get_alg_null (Ptr, End, Alg);
171 return Ret;
172}
173
184STATIC
185INT32
187 UINT8 **Ptr,
188 UINT8 *End,
189 mbedtls_x509_buf *Alg
190 )
191{
192 UINTN Len;
193 INT32 Ret;
194
195 Len = 0;
196 Ret = mbedtls_asn1_get_tag (
197 Ptr,
198 End,
199 &Len,
200 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET
201 );
202
203 if (Ret == 0) {
204 End = *Ptr + Len;
205 // assume only one digest algorithm
206 Ret = mbedtls_asn1_get_alg_null (Ptr, End, Alg);
207 }
208
209 return Ret;
210}
211
225STATIC
226INT32
228 UINT8 **Ptr,
229 INTN Plen,
230 mbedtls_x509_crt *Certs
231 )
232{
233 INT32 Ret;
234
235 Ret = mbedtls_x509_crt_parse (Certs, *Ptr, Plen);
236 return Ret;
237}
238
249STATIC
250INT32
252 UINT8 **Ptr,
253 UINT8 *End,
254 mbedtls_asn1_buf *Signature
255 )
256{
257 INT32 Ret;
258 UINTN Len;
259
260 Len = 0;
261 Ret = mbedtls_asn1_get_tag (Ptr, End, &Len, MBEDTLS_ASN1_OCTET_STRING);
262 if (Ret == 0) {
263 Signature->tag = MBEDTLS_ASN1_OCTET_STRING;
264 Signature->len = Len;
265 Signature->p = *Ptr;
266 }
267
268 return Ret;
269}
270
290STATIC
291INT32
293 UINT8 **Ptr,
294 UINT8 *End,
295 MbedtlsPkcs7SignerInfo *SignersSet
296 )
297{
298 UINT8 *EndSet;
299 INT32 Ret;
300 UINTN Len;
301 UINT8 *TempP;
302
303 Len = 0;
304
305 Ret = mbedtls_asn1_get_tag (
306 Ptr,
307 End,
308 &Len,
309 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET
310 );
311
312 if (Ret == 0) {
313 EndSet = *Ptr + Len;
314
315 Ret = mbedtls_asn1_get_tag (
316 Ptr,
317 EndSet,
318 &Len,
319 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE
320 );
321 }
322
323 if (Ret == 0) {
324 Ret = mbedtls_asn1_get_int (Ptr, EndSet, &SignersSet->Version);
325 }
326
327 if (Ret == 0) {
328 Ret = mbedtls_asn1_get_tag (
329 Ptr,
330 EndSet,
331 &Len,
332 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE
333 );
334 }
335
336 if (Ret == 0) {
337 SignersSet->IssuerRaw.p = *Ptr;
338 Ret = mbedtls_asn1_get_tag (
339 Ptr,
340 EndSet,
341 &Len,
342 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE
343 );
344 }
345
346 if (Ret == 0) {
347 Ret = mbedtls_x509_get_name (Ptr, *Ptr + Len, &SignersSet->Issuer);
348 }
349
350 if (Ret == 0) {
351 SignersSet->IssuerRaw.len = *Ptr - SignersSet->IssuerRaw.p;
352
353 Ret = mbedtls_x509_get_serial (Ptr, EndSet, &SignersSet->Serial);
354 }
355
356 if (Ret == 0) {
357 Ret = MbedTlsPkcs7GetDigestAlgorithm (Ptr, EndSet, &SignersSet->AlgIdentifier);
358 }
359
360 // OPTIONAL AuthenticatedAttributes
361 if (Ret == 0) {
362 TempP = *Ptr;
363 if (mbedtls_asn1_get_tag (&TempP, EndSet, &Len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) == 0) {
364 SignersSet->AuthAttr.len = Len + (TempP - *Ptr);
365 SignersSet->AuthAttr.p = *Ptr;
366 *Ptr = TempP + Len;
367 } else {
368 SignersSet->AuthAttr.p = NULL;
369 }
370 }
371
372 if (Ret == 0) {
373 Ret = MbedTlsPkcs7GetDigestAlgorithm (Ptr, EndSet, &SignersSet->SigAlgIdentifier);
374 }
375
376 if (Ret == 0) {
377 Ret = Pkcs7GetSignature (Ptr, End, &SignersSet->Sig);
378 }
379
380 if (Ret == 0) {
381 SignersSet->Next = NULL;
382 }
383
384 return Ret;
385}
386
406STATIC
407INT32
409 UINT8 *Buffer,
410 INTN BufferLen,
411 MbedtlsPkcs7SignedData *SignedData
412 )
413{
414 UINT8 *Ptr;
415 UINT8 *End;
416 UINTN Len;
417 INT32 Ret;
418 UINT8 *CertP;
419 UINTN CertLen;
420 UINT8 *OldCertP;
421 UINTN TotalCertLen;
422 mbedtls_x509_crt *MoreCert;
423 UINT8 CertNum;
424 mbedtls_x509_crt *LastCert;
425 mbedtls_x509_crt *TempCrt;
426
427 Len = 0;
428 Ptr = Buffer;
429 End = Buffer + BufferLen;
430 MoreCert = NULL;
431
432 Ret = mbedtls_asn1_get_tag (
433 &Ptr,
434 End,
435 &Len,
436 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE
437 );
438
439 if (Ret == 0) {
440 // version
441 Ret = MbedTlsPkcs7GetVersion (&Ptr, End, &SignedData->Version);
442 }
443
444 if ((Ret == 0) && (SignedData->Version != 1)) {
445 Ret = -1;
446 }
447
448 if (Ret == 0) {
449 // digest algorithm
451 &Ptr,
452 End,
453 &SignedData->DigestAlgorithms
454 );
455 }
456
457 if (Ret == 0) {
458 if (
459 #ifndef DISABLE_SHA1_DEPRECATED_INTERFACES
460 ((SignedData->DigestAlgorithms.len == sizeof (MBEDTLS_OID_DIGEST_ALG_SHA1) - 1) &&
461 (CompareMem (
462 SignedData->DigestAlgorithms.p,
463 MBEDTLS_OID_DIGEST_ALG_SHA1,
464 SignedData->DigestAlgorithms.len
465 ) == 0)) ||
466 #endif
467 ((SignedData->DigestAlgorithms.len == sizeof (MBEDTLS_OID_DIGEST_ALG_SHA256) - 1) &&
468 (CompareMem (
469 SignedData->DigestAlgorithms.p,
470 MBEDTLS_OID_DIGEST_ALG_SHA256,
471 SignedData->DigestAlgorithms.len
472 ) == 0)) ||
473 ((SignedData->DigestAlgorithms.len == sizeof (MBEDTLS_OID_DIGEST_ALG_SHA384) - 1) &&
474 (CompareMem (
475 SignedData->DigestAlgorithms.p,
476 MBEDTLS_OID_DIGEST_ALG_SHA384,
477 SignedData->DigestAlgorithms.len
478 ) == 0)) ||
479 ((SignedData->DigestAlgorithms.len == sizeof (MBEDTLS_OID_DIGEST_ALG_SHA512) - 1) &&
480 (CompareMem (
481 SignedData->DigestAlgorithms.p,
482 MBEDTLS_OID_DIGEST_ALG_SHA512,
483 SignedData->DigestAlgorithms.len
484 ) == 0)))
485 {
486 Ret = 0;
487 } else {
488 Ret = -1;
489 }
490 }
491
492 if (Ret == 0) {
493 Ret = Pkcs7GetContentInfoType (&Ptr, End, &SignedData->ContentInfo.Oid);
494 }
495
496 if (Ret == 0) {
497 // move to next
498 Ptr = Ptr + SignedData->ContentInfo.Oid.len;
499 Ret = MbedTlsPkcs7GetNextContentLen (&Ptr, End, &Len);
500 CertP = Ptr + Len;
501
502 // move to actual cert, if there are more [0]
503 if (MbedTlsPkcs7GetNextContentLen (&CertP, End, &CertLen) == 0) {
504 Len = CertLen;
505 Ptr = CertP;
506 }
507 }
508
509 // certificates: may have many certs
510 CertP = Ptr;
511
512 TotalCertLen = 0;
513
514 MoreCert = &SignedData->Certificates;
515 CertNum = 0;
516
517 while (TotalCertLen < Len) {
518 OldCertP = CertP;
519
520 Ret = mbedtls_asn1_get_tag (&CertP, End, &CertLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
521 if (Ret != 0) {
522 goto Out;
523 }
524
525 // cert total len
526 CertLen = CertLen + (CertP - OldCertP);
527
528 // move to next cert
529 CertP = OldCertP + CertLen;
530
531 // change TotalCertLen
532 TotalCertLen += CertLen;
533
534 mbedtls_x509_crt_init (MoreCert);
535 Ret = MbedTlsPkcs7GetCertificates (&OldCertP, CertLen, MoreCert);
536 if (Ret != 0) {
537 goto Out;
538 }
539
540 CertNum++;
541 MoreCert->next = mbedtls_calloc (1, sizeof (mbedtls_x509_crt));
542 MoreCert = MoreCert->next;
543 }
544
545 if (TotalCertLen != Len) {
546 Ret = -1;
547 goto Out;
548 }
549
550 LastCert = &(SignedData->Certificates);
551
552 while (CertNum--) {
553 if (CertNum == 0) {
554 LastCert->next = NULL;
555 break;
556 } else {
557 LastCert = LastCert->next;
558 }
559 }
560
561 // signers info
562 if (Ret == 0) {
563 Ptr = Ptr + Len;
564 Ret = MbedTlsPkcs7GetSignersInfoSet (&Ptr, End, &SignedData->SignerInfos);
565 }
566
567Out:
568 if (Ret == 0) {
569 if (MoreCert != NULL) {
570 mbedtls_x509_crt_free (MoreCert);
571 MoreCert = NULL;
572 }
573 } else {
574 if (SignedData->Certificates.next != NULL) {
575 TempCrt = SignedData->Certificates.next;
576 mbedtls_x509_crt_free (TempCrt);
577 }
578 }
579
580 return Ret;
581}
582
592STATIC
593INT32
595 CONST UINT8 *Buffer,
596 INTN BufferLen,
597 MbedtlsPkcs7 *Pkcs7
598 )
599{
600 UINT8 *Ptr;
601 UINT8 *End;
602 UINTN Len;
603 INT32 Ret;
604
605 if (Pkcs7 == NULL) {
606 return -1;
607 }
608
609 Len = 0;
610 Ptr = (UINT8 *)Buffer;
611 End = Ptr + BufferLen;
612
613 Ret = Pkcs7GetContentInfoType (&Ptr, End, &Pkcs7->ContentTypeOid);
614 if (Ret != 0) {
615 goto Out;
616 }
617
618 if ((CompareMem (Pkcs7->ContentTypeOid.p, MBEDTLS_OID_PKCS7_DATA, Pkcs7->ContentTypeOid.len) == 0) ||
619 (CompareMem (Pkcs7->ContentTypeOid.p, MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, Pkcs7->ContentTypeOid.len) == 0) ||
620 (CompareMem (Pkcs7->ContentTypeOid.p, MBEDTLS_OID_PKCS7_ENVELOPED_DATA, Pkcs7->ContentTypeOid.len) == 0) ||
621 (CompareMem (Pkcs7->ContentTypeOid.p, MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA, Pkcs7->ContentTypeOid.len) == 0) ||
622 (CompareMem (Pkcs7->ContentTypeOid.p, MBEDTLS_OID_PKCS7_DIGESTED_DATA, Pkcs7->ContentTypeOid.len) == 0))
623 {
624 // Invalid PKCS7 data type;
625 Ret = -1;
626 goto Out;
627 }
628
629 if (CompareMem (Pkcs7->ContentTypeOid.p, MBEDTLS_OID_PKCS7_SIGNED_DATA, Pkcs7->ContentTypeOid.len) != 0) {
630 // Invalid PKCS7 data type;
631 Ret = -1;
632 goto Out;
633 }
634
635 // Content type is SignedData
636 Ptr = Ptr + Pkcs7->ContentTypeOid.len;
637
638 Ret = MbedTlsPkcs7GetNextContentLen (&Ptr, End, &Len);
639 if (Ret != 0) {
640 goto Out;
641 }
642
643 Ret = Pkcs7GetSignedData (Ptr, Len, &Pkcs7->SignedData);
644 if (Ret != 0) {
645 goto Out;
646 }
647
648Out:
649 return Ret;
650}
651
662STATIC
663INT32
665 MbedtlsPkcs7SignerInfo *SignerInfo,
666 mbedtls_x509_crt *Cert,
667 CONST UINT8 *Data,
668 INTN DataLen
669 )
670{
671 INT32 Ret;
672 UINT8 Hash[MBEDTLS_MD_MAX_SIZE];
673 mbedtls_pk_context Pk;
674 CONST mbedtls_md_info_t *MdInfo;
675 INTN HashLen;
676 UINT8 TempAuthAttr;
677
678 Pk = Cert->pk;
679 ZeroMem (Hash, MBEDTLS_MD_MAX_SIZE);
680
681 // all the hash algo
682 #ifndef DISABLE_SHA1_DEPRECATED_INTERFACES
683 MdInfo = mbedtls_md_info_from_type (MBEDTLS_MD_SHA1);
684 HashLen = mbedtls_md_get_size (MdInfo);
685 mbedtls_md (MdInfo, Data, DataLen, Hash);
686 if (SignerInfo->AuthAttr.p != NULL) {
687 TempAuthAttr = *(SignerInfo->AuthAttr.p);
688 *(SignerInfo->AuthAttr.p) = MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET;
689 mbedtls_md (MdInfo, SignerInfo->AuthAttr.p, SignerInfo->AuthAttr.len, Hash);
690 // Restore content
691 *(SignerInfo->AuthAttr.p) = TempAuthAttr;
692 }
693
694 Ret = mbedtls_pk_verify (&Pk, MBEDTLS_MD_SHA1, Hash, HashLen, SignerInfo->Sig.p, SignerInfo->Sig.len);
695
696 if (Ret == 0) {
697 return Ret;
698 }
699
700 #endif
701
702 MdInfo = mbedtls_md_info_from_type (MBEDTLS_MD_SHA256);
703 HashLen = mbedtls_md_get_size (MdInfo);
704 ZeroMem (Hash, MBEDTLS_MD_MAX_SIZE);
705 mbedtls_md (MdInfo, Data, DataLen, Hash);
706 if (SignerInfo->AuthAttr.p != NULL) {
707 TempAuthAttr = *(SignerInfo->AuthAttr.p);
708 *(SignerInfo->AuthAttr.p) = MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET;
709 mbedtls_md (MdInfo, SignerInfo->AuthAttr.p, SignerInfo->AuthAttr.len, Hash);
710 // Restore content
711 *(SignerInfo->AuthAttr.p) = TempAuthAttr;
712 }
713
714 Ret = mbedtls_pk_verify (&Pk, MBEDTLS_MD_SHA256, Hash, HashLen, SignerInfo->Sig.p, SignerInfo->Sig.len);
715 if (Ret == 0) {
716 return Ret;
717 }
718
719 MdInfo = mbedtls_md_info_from_type (MBEDTLS_MD_SHA384);
720 HashLen = mbedtls_md_get_size (MdInfo);
721 ZeroMem (Hash, MBEDTLS_MD_MAX_SIZE);
722 mbedtls_md (MdInfo, Data, DataLen, Hash);
723 if (SignerInfo->AuthAttr.p != NULL) {
724 TempAuthAttr = *(SignerInfo->AuthAttr.p);
725 *(SignerInfo->AuthAttr.p) = MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET;
726 mbedtls_md (MdInfo, SignerInfo->AuthAttr.p, SignerInfo->AuthAttr.len, Hash);
727 // Restore content
728 *(SignerInfo->AuthAttr.p) = TempAuthAttr;
729 }
730
731 Ret = mbedtls_pk_verify (&Pk, MBEDTLS_MD_SHA384, Hash, HashLen, SignerInfo->Sig.p, SignerInfo->Sig.len);
732 if (Ret == 0) {
733 return Ret;
734 }
735
736 MdInfo = mbedtls_md_info_from_type (MBEDTLS_MD_SHA512);
737 HashLen = mbedtls_md_get_size (MdInfo);
738 ZeroMem (Hash, MBEDTLS_MD_MAX_SIZE);
739 mbedtls_md (MdInfo, Data, DataLen, Hash);
740 if (SignerInfo->AuthAttr.p != NULL) {
741 TempAuthAttr = *(SignerInfo->AuthAttr.p);
742 *(SignerInfo->AuthAttr.p) = MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET;
743 mbedtls_md (MdInfo, SignerInfo->AuthAttr.p, SignerInfo->AuthAttr.len, Hash);
744 // Restore content
745 *(SignerInfo->AuthAttr.p) = TempAuthAttr;
746 }
747
748 Ret = mbedtls_pk_verify (&Pk, MBEDTLS_MD_SHA512, Hash, HashLen, SignerInfo->Sig.p, SignerInfo->Sig.len);
749 if (Ret == 0) {
750 return Ret;
751 }
752
753 return Ret;
754}
755
764STATIC
765mbedtls_x509_crt *
767 MbedtlsPkcs7SignerInfo *SignerInfo,
768 mbedtls_x509_crt *Certs
769 )
770{
771 mbedtls_x509_crt *Cert;
772
773 Cert = Certs;
774 while (Cert != NULL) {
775 if ((Cert->serial.p == NULL) || (Cert->issuer_raw.p == NULL)) {
776 return NULL;
777 }
778
779 if ((Cert->issuer_raw.len == SignerInfo->IssuerRaw.len) &&
780 (CompareMem (Cert->issuer_raw.p, SignerInfo->IssuerRaw.p, Cert->issuer_raw.len) == 0) &&
781 (Cert->serial.len == SignerInfo->Serial.len) &&
782 (CompareMem (Cert->serial.p, SignerInfo->Serial.p, Cert->serial.len) == 0))
783 {
784 break;
785 }
786
787 Cert = Cert->next;
788 }
789
790 return Cert;
791}
792
803STATIC
804BOOLEAN
806 mbedtls_x509_crt *Ca,
807 mbedtls_x509_crl *CaCrl,
808 mbedtls_x509_crt *End
809 )
810{
811 INT32 Ret;
812 UINT32 VFlag;
813 mbedtls_x509_crt_profile Profile;
814
815 VFlag = 0;
816 CopyMem (&Profile, &gCompatProfile, sizeof (mbedtls_x509_crt_profile));
817
818 Ret = mbedtls_x509_crt_verify_with_profile (End, Ca, CaCrl, &Profile, NULL, &VFlag, NULL, NULL);
819
820 return Ret == 0;
821}
822
833STATIC
834BOOLEAN
836 MbedtlsPkcs7 *Pkcs7,
837 mbedtls_x509_crt *Ca,
838 mbedtls_x509_crt *End
839 )
840{
841 mbedtls_x509_crt *AllCert;
842 mbedtls_x509_crt *InterCert;
843
844 AllCert = &(Pkcs7->SignedData.Certificates);
845 InterCert = NULL;
846
847 while (AllCert != NULL) {
848 if ((AllCert->next == End) && (MbedTlsPkcs7VerifyCert (AllCert, NULL, End))) {
849 InterCert = AllCert;
850 break;
851 }
852
853 AllCert = AllCert->next;
854 }
855
856 if (InterCert == NULL) {
857 return FALSE;
858 }
859
860 if (MbedTlsPkcs7VerifyCert (Ca, &(Pkcs7->SignedData.Crls), InterCert)) {
861 return TRUE;
862 } else {
863 return MbedTlsPkcs7VerifyCertChain (Pkcs7, Ca, InterCert);
864 }
865}
866
878STATIC
879BOOLEAN
881 MbedtlsPkcs7 *Pkcs7,
882 mbedtls_x509_crt *TrustCert,
883 CONST UINT8 *Data,
884 INTN DataLen
885 )
886{
887 MbedtlsPkcs7SignerInfo *SignerInfo;
888 mbedtls_x509_crt *Cert;
889 mbedtls_x509_crt *AllCert;
890 BOOLEAN Result;
891
892 SignerInfo = &(Pkcs7->SignedData.SignerInfos);
893 Result = TRUE;
894
895 //
896 // Traverse signers and verify each signers
897 //
898 while (SignerInfo != NULL) {
899 Result = FALSE;
900 // 1. Find signers cert
901 Cert = MbedTlsPkcs7FindSignerCert (SignerInfo, &(Pkcs7->SignedData.Certificates));
902 if (Cert != NULL) {
903 // 2. Check signer cert is trusted by trustCert
904 if (MbedTlsPkcs7VerifyCert (TrustCert, &(Pkcs7->SignedData.Crls), Cert)) {
905 // root cert verify pass
906 Result = TRUE;
907 } else {
908 if (MbedTlsPkcs7VerifyCertChain (Pkcs7, TrustCert, Cert)) {
909 Result = TRUE;
910 } else {
911 Result = FALSE;
912 }
913 }
914
915 if (Result == TRUE) {
916 // 3. Check signed data
917 AllCert = &(Pkcs7->SignedData.Certificates);
918 while (AllCert != NULL) {
919 if (MbedtlsPkcs7SignedDataVerifySigners (SignerInfo, AllCert, Data, DataLen) == 0) {
920 return TRUE;
921 }
922
923 AllCert = AllCert->next;
924 }
925
926 Result = FALSE;
927 }
928 }
929
930 // move to next
931 SignerInfo = SignerInfo->Next;
932 }
933
934 return Result;
935}
936
960BOOLEAN
962 IN CONST UINT8 *P7Data,
963 IN UINTN P7Length,
964 OUT BOOLEAN *WrapFlag,
965 OUT UINT8 **WrapData,
966 OUT UINTN *WrapDataSize
967 )
968{
969 BOOLEAN Wrapped;
970 UINT8 *SignedData;
971
972 //
973 // Check whether input P7Data is a wrapped ContentInfo structure or not.
974 //
975 Wrapped = FALSE;
976 if ((P7Data[4] == MBEDTLS_ASN1_OID) && (P7Data[5] == sizeof (MBEDTLS_OID_PKCS7_SIGNED_DATA) - 1)) {
977 if (CompareMem (P7Data + 6, MBEDTLS_OID_PKCS7_SIGNED_DATA, sizeof (MBEDTLS_OID_PKCS7_SIGNED_DATA) - 1) == 0) {
978 if ((P7Data[15] == (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC)) && (P7Data[16] == 0x82)) {
979 Wrapped = TRUE;
980 }
981 }
982 }
983
984 if (Wrapped) {
985 *WrapData = (UINT8 *)P7Data;
986 *WrapDataSize = P7Length;
987 } else {
988 //
989 // Wrap PKCS#7 signeddata to a ContentInfo structure - add a header in 19 bytes.
990 //
991 *WrapDataSize = P7Length + 19;
992 *WrapData = AllocateZeroPool (*WrapDataSize);
993 if (*WrapData == NULL) {
994 *WrapFlag = Wrapped;
995 return FALSE;
996 }
997
998 SignedData = *WrapData;
999
1000 //
1001 // Part1: 0x30, 0x82.
1002 //
1003 SignedData[0] = MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE;
1004 SignedData[1] = 0x82;
1005
1006 //
1007 // Part2: Length1 = P7Length + 19 - 4, in big endian.
1008 //
1009 SignedData[2] = (UINT8)(((UINT16)(*WrapDataSize - 4)) >> 8);
1010 SignedData[3] = (UINT8)(((UINT16)(*WrapDataSize - 4)) & 0xff);
1011
1012 //
1013 // Part3: 0x06, 0x09.
1014 //
1015 SignedData[4] = MBEDTLS_ASN1_OID;
1016 SignedData[5] = sizeof (MBEDTLS_OID_PKCS7_SIGNED_DATA) - 1;
1017
1018 //
1019 // Part4: OID value -- 0x2A 0x86 0x48 0x86 0xF7 0x0D 0x01 0x07 0x02.
1020 //
1021 CopyMem (SignedData + 6, MBEDTLS_OID_PKCS7_SIGNED_DATA, sizeof (MBEDTLS_OID_PKCS7_SIGNED_DATA) - 1);
1022
1023 //
1024 // Part5: 0xA0, 0x82.
1025 //
1026 SignedData[15] = MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC;
1027 SignedData[16] = 0x82;
1028
1029 //
1030 // Part6: Length2 = P7Length, in big endian.
1031 //
1032 SignedData[17] = (UINT8)(((UINT16)P7Length) >> 8);
1033 SignedData[18] = (UINT8)(((UINT16)P7Length) & 0xff);
1034
1035 //
1036 // Part7: P7Data.
1037 //
1038 CopyMem (SignedData + 19, P7Data, P7Length);
1039 }
1040
1041 *WrapFlag = Wrapped;
1042 return TRUE;
1043}
1044
1067BOOLEAN
1068EFIAPI
1070 IN CONST UINT8 *P7Data,
1071 IN UINTN P7Length,
1072 IN CONST UINT8 *TrustedCert,
1073 IN UINTN CertLength,
1074 IN CONST UINT8 *InData,
1075 IN UINTN DataLength
1076 )
1077{
1078 BOOLEAN Status;
1079 UINT8 *WrapData;
1080 UINTN WrapDataSize;
1081 BOOLEAN Wrapped;
1082 MbedtlsPkcs7 Pkcs7;
1083 INT32 Ret;
1084 mbedtls_x509_crt Crt;
1085 mbedtls_x509_crt *TempCrt;
1086
1087 //
1088 // Check input parameters.
1089 //
1090 if ((P7Data == NULL) || (TrustedCert == NULL) || (InData == NULL) ||
1091 (P7Length > INT_MAX) || (CertLength > INT_MAX) || (DataLength > INT_MAX))
1092 {
1093 return FALSE;
1094 }
1095
1096 Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &WrapData, &WrapDataSize);
1097
1098 if (!Status) {
1099 return FALSE;
1100 }
1101
1102 Status = FALSE;
1103 MbedTlsPkcs7Init (&Pkcs7);
1104 mbedtls_x509_crt_init (&Crt);
1105
1106 Ret = MbedtlsPkcs7ParseDer (WrapData, (INT32)WrapDataSize, &Pkcs7);
1107 if (Ret != 0) {
1108 goto Cleanup;
1109 }
1110
1111 Ret = mbedtls_x509_crt_parse_der (&Crt, TrustedCert, CertLength);
1112 if (Ret != 0) {
1113 goto Cleanup;
1114 }
1115
1116 Status = MbedTlsPkcs7SignedDataVerify (&Pkcs7, &Crt, InData, (INT32)DataLength);
1117
1118Cleanup:
1119 if (&Crt != NULL) {
1120 mbedtls_x509_crt_free (&Crt);
1121 }
1122
1123 if (Pkcs7.SignedData.Certificates.next != NULL) {
1124 TempCrt = Pkcs7.SignedData.Certificates.next;
1125 mbedtls_x509_crt_free (TempCrt);
1126 }
1127
1128 return Status;
1129}
1130
1137VOID
1138EFIAPI
1140 IN UINT8 *Certs
1141 )
1142{
1143 if (Certs == NULL) {
1144 return;
1145 }
1146
1147 FreePool (Certs);
1148}
1149
1178BOOLEAN
1179EFIAPI
1181 IN CONST UINT8 *P7Data,
1182 IN UINTN P7Length,
1183 OUT UINT8 **CertStack,
1184 OUT UINTN *StackLength,
1185 OUT UINT8 **TrustedCert,
1186 OUT UINTN *CertLength
1187 )
1188{
1189 MbedtlsPkcs7SignerInfo *SignerInfo;
1190 mbedtls_x509_crt *Cert;
1191 MbedtlsPkcs7 Pkcs7;
1192 BOOLEAN Status;
1193 UINT8 *WrapData;
1194 UINTN WrapDataSize;
1195 BOOLEAN Wrapped;
1196 mbedtls_x509_crt *TempCrt;
1197
1198 UINTN CertSize;
1199 UINT8 Index;
1200 UINT8 *CertBuf;
1201 UINT8 *OldBuf;
1202 UINTN BufferSize;
1203 UINTN OldSize;
1204
1205 if ((P7Data == NULL) || (CertStack == NULL) || (StackLength == NULL) ||
1206 (TrustedCert == NULL) || (CertLength == NULL) || (P7Length > INT_MAX))
1207 {
1208 return FALSE;
1209 }
1210
1211 Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &WrapData, &WrapDataSize);
1212
1213 if (!Status) {
1214 return FALSE;
1215 }
1216
1217 Status = FALSE;
1218 CertBuf = NULL;
1219 OldBuf = NULL;
1220 Cert = NULL;
1221
1222 MbedTlsPkcs7Init (&Pkcs7);
1223 if (MbedtlsPkcs7ParseDer (WrapData, (INT32)WrapDataSize, &Pkcs7) != 0) {
1224 goto _Exit;
1225 }
1226
1227 SignerInfo = &(Pkcs7.SignedData.SignerInfos);
1228
1229 //
1230 // Traverse each signers
1231 //
1232 // Convert CertStack to buffer in following format:
1233 // UINT8 CertNumber;
1234 // UINT32 Cert1Length;
1235 // UINT8 Cert1[];
1236 // UINT32 Cert2Length;
1237 // UINT8 Cert2[];
1238 // ...
1239 // UINT32 CertnLength;
1240 // UINT8 Certn[];
1241 //
1242 BufferSize = sizeof (UINT8);
1243 OldSize = BufferSize;
1244 Index = 0;
1245
1246 while (SignerInfo != NULL) {
1247 // Find signers cert
1248 Cert = MbedTlsPkcs7FindSignerCert (SignerInfo, &(Pkcs7.SignedData.Certificates));
1249 if (Cert == NULL) {
1250 goto _Exit;
1251 }
1252
1253 CertSize = Cert->raw.len;
1254 OldSize = BufferSize;
1255 OldBuf = CertBuf;
1256 BufferSize = OldSize + CertSize + sizeof (UINT32);
1257
1258 CertBuf = AllocateZeroPool (BufferSize);
1259 if (CertBuf == NULL) {
1260 goto _Exit;
1261 }
1262
1263 if (OldBuf != NULL) {
1264 CopyMem (CertBuf, OldBuf, OldSize);
1265 FreePool (OldBuf);
1266 OldBuf = NULL;
1267 }
1268
1269 WriteUnaligned32 ((UINT32 *)(CertBuf + OldSize), (UINT32)CertSize);
1270 CopyMem (CertBuf + OldSize + sizeof (UINT32), Cert->raw.p, CertSize);
1271
1272 Index++;
1273
1274 // move to next
1275 SignerInfo = SignerInfo->Next;
1276 }
1277
1278 if (CertBuf != NULL) {
1279 //
1280 // Update CertNumber.
1281 //
1282 CertBuf[0] = Index;
1283
1284 *CertLength = BufferSize - OldSize - sizeof (UINT32);
1285 *TrustedCert = AllocateZeroPool (*CertLength);
1286 if (*TrustedCert == NULL) {
1287 goto _Exit;
1288 }
1289
1290 CopyMem (*TrustedCert, CertBuf + OldSize + sizeof (UINT32), *CertLength);
1291 *CertStack = CertBuf;
1292 *StackLength = BufferSize;
1293 Status = TRUE;
1294 }
1295
1296_Exit:
1297 //
1298 // Release Resources
1299 //
1300 if (!Status && (CertBuf != NULL)) {
1301 FreePool (CertBuf);
1302 *CertStack = NULL;
1303 }
1304
1305 if (Status) {
1306 if (Pkcs7.SignedData.Certificates.next != NULL) {
1307 TempCrt = Pkcs7.SignedData.Certificates.next;
1308 mbedtls_x509_crt_free (TempCrt);
1309 }
1310 }
1311
1312 if (OldBuf != NULL) {
1313 FreePool (OldBuf);
1314 }
1315
1316 return Status;
1317}
1318
1341BOOLEAN
1342EFIAPI
1344 IN CONST UINT8 *P7Data,
1345 IN UINTN P7Length,
1346 OUT UINT8 **SignerChainCerts,
1347 OUT UINTN *ChainLength,
1348 OUT UINT8 **UnchainCerts,
1349 OUT UINTN *UnchainLength
1350 )
1351{
1352 ASSERT (FALSE);
1353 return FALSE;
1354}
UINT64 UINTN
INT64 INTN
UINT32 EFIAPI WriteUnaligned32(OUT UINT32 *Buffer, IN UINT32 Value)
Definition: Unaligned.c:177
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
BOOLEAN EFIAPI Pkcs7GetSigners(IN CONST UINT8 *P7Data, IN UINTN P7Length, OUT UINT8 **CertStack, OUT UINTN *StackLength, OUT UINT8 **TrustedCert, OUT UINTN *CertLength)
BOOLEAN WrapPkcs7Data(IN CONST UINT8 *P7Data, IN UINTN P7Length, OUT BOOLEAN *WrapFlag, OUT UINT8 **WrapData, OUT UINTN *WrapDataSize)
BOOLEAN EFIAPI Pkcs7Verify(IN CONST UINT8 *P7Data, IN UINTN P7Length, IN CONST UINT8 *TrustedCert, IN UINTN CertLength, IN CONST UINT8 *InData, IN UINTN DataLength)
VOID EFIAPI Pkcs7FreeSigners(IN UINT8 *Certs)
BOOLEAN EFIAPI Pkcs7GetCertificatesList(IN CONST UINT8 *P7Data, IN UINTN P7Length, OUT UINT8 **SignerChainCerts, OUT UINTN *ChainLength, OUT UINT8 **UnchainCerts, OUT UINTN *UnchainLength)
STATIC INT32 MbedTlsPkcs7GetDigestAlgorithm(UINT8 **Ptr, UINT8 *End, mbedtls_x509_buf *Alg)
STATIC INT32 MbedTlsPkcs7GetDigestAlgorithmSet(UINT8 **Ptr, UINT8 *End, mbedtls_x509_buf *Alg)
STATIC VOID MbedTlsPkcs7Init(MbedtlsPkcs7 *Pkcs7)
STATIC INT32 MbedTlsPkcs7GetCertificates(UINT8 **Ptr, INTN Plen, mbedtls_x509_crt *Certs)
STATIC BOOLEAN MbedTlsPkcs7SignedDataVerify(MbedtlsPkcs7 *Pkcs7, mbedtls_x509_crt *TrustCert, CONST UINT8 *Data, INTN DataLen)
STATIC INT32 Pkcs7GetSignature(UINT8 **Ptr, UINT8 *End, mbedtls_asn1_buf *Signature)
STATIC INT32 MbedtlsPkcs7ParseDer(CONST UINT8 *Buffer, INTN BufferLen, MbedtlsPkcs7 *Pkcs7)
STATIC INT32 MbedTlsPkcs7GetNextContentLen(UINT8 **Ptr, UINT8 *End, UINTN *Len)
STATIC mbedtls_x509_crt * MbedTlsPkcs7FindSignerCert(MbedtlsPkcs7SignerInfo *SignerInfo, mbedtls_x509_crt *Certs)
STATIC INT32 MbedTlsPkcs7GetVersion(UINT8 **Ptr, UINT8 *End, INT32 *Ver)
STATIC INT32 Pkcs7GetContentInfoType(UINT8 **Ptr, UINT8 *End, mbedtls_asn1_buf *Pkcs7)
STATIC BOOLEAN MbedTlsPkcs7VerifyCertChain(MbedtlsPkcs7 *Pkcs7, mbedtls_x509_crt *Ca, mbedtls_x509_crt *End)
STATIC BOOLEAN MbedTlsPkcs7VerifyCert(mbedtls_x509_crt *Ca, mbedtls_x509_crl *CaCrl, mbedtls_x509_crt *End)
STATIC INT32 Pkcs7GetSignedData(UINT8 *Buffer, INTN BufferLen, MbedtlsPkcs7SignedData *SignedData)
STATIC INT32 MbedTlsPkcs7GetSignersInfoSet(UINT8 **Ptr, UINT8 *End, MbedtlsPkcs7SignerInfo *SignersSet)
STATIC INT32 MbedtlsPkcs7SignedDataVerifySigners(MbedtlsPkcs7SignerInfo *SignerInfo, mbedtls_x509_crt *Cert, CONST UINT8 *Data, INTN DataLen)