TianoCore EDK2 master
Loading...
Searching...
No Matches
CryptPkcs7VerifyCommon.c
Go to the documentation of this file.
1
18#include "InternalCryptLib.h"
19
20#include <openssl/objects.h>
21#include <openssl/x509.h>
22#include <openssl/x509v3.h>
23#include <openssl/pkcs7.h>
24
25GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mOidValue[9] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 };
26
50BOOLEAN
52 IN CONST UINT8 *P7Data,
53 IN UINTN P7Length,
54 OUT BOOLEAN *WrapFlag,
55 OUT UINT8 **WrapData,
56 OUT UINTN *WrapDataSize
57 )
58{
59 BOOLEAN Wrapped;
60 UINT8 *SignedData;
61
62 //
63 // Check whether input P7Data is a wrapped ContentInfo structure or not.
64 //
65 Wrapped = FALSE;
66 if ((P7Data[4] == 0x06) && (P7Data[5] == 0x09)) {
67 if (CompareMem (P7Data + 6, mOidValue, sizeof (mOidValue)) == 0) {
68 if ((P7Data[15] == 0xA0) && (P7Data[16] == 0x82)) {
69 Wrapped = TRUE;
70 }
71 }
72 }
73
74 if (Wrapped) {
75 *WrapData = (UINT8 *)P7Data;
76 *WrapDataSize = P7Length;
77 } else {
78 //
79 // Wrap PKCS#7 signeddata to a ContentInfo structure - add a header in 19 bytes.
80 //
81 *WrapDataSize = P7Length + 19;
82 *WrapData = malloc (*WrapDataSize);
83 if (*WrapData == NULL) {
84 *WrapFlag = Wrapped;
85 return FALSE;
86 }
87
88 SignedData = *WrapData;
89
90 //
91 // Part1: 0x30, 0x82.
92 //
93 SignedData[0] = 0x30;
94 SignedData[1] = 0x82;
95
96 //
97 // Part2: Length1 = P7Length + 19 - 4, in big endian.
98 //
99 SignedData[2] = (UINT8)(((UINT16)(*WrapDataSize - 4)) >> 8);
100 SignedData[3] = (UINT8)(((UINT16)(*WrapDataSize - 4)) & 0xff);
101
102 //
103 // Part3: 0x06, 0x09.
104 //
105 SignedData[4] = 0x06;
106 SignedData[5] = 0x09;
107
108 //
109 // Part4: OID value -- 0x2A 0x86 0x48 0x86 0xF7 0x0D 0x01 0x07 0x02.
110 //
111 CopyMem (SignedData + 6, mOidValue, sizeof (mOidValue));
112
113 //
114 // Part5: 0xA0, 0x82.
115 //
116 SignedData[15] = 0xA0;
117 SignedData[16] = 0x82;
118
119 //
120 // Part6: Length2 = P7Length, in big endian.
121 //
122 SignedData[17] = (UINT8)(((UINT16)P7Length) >> 8);
123 SignedData[18] = (UINT8)(((UINT16)P7Length) & 0xff);
124
125 //
126 // Part7: P7Data.
127 //
128 CopyMem (SignedData + 19, P7Data, P7Length);
129 }
130
131 *WrapFlag = Wrapped;
132 return TRUE;
133}
134
148STATIC
149BOOLEAN
151 IN VOID *X509Stack,
152 OUT UINT8 **Cert,
153 OUT UINTN *CertSize
154 )
155{
156 BIO *CertBio;
157 X509 *X509Cert;
158
159 STACK_OF (X509) *CertStack;
160 BOOLEAN Status;
161 INT32 Result;
162 BUF_MEM *Ptr;
163 INT32 Length;
164 VOID *Buffer;
165
166 Status = FALSE;
167
168 if ((X509Stack == NULL) || (Cert == NULL) || (CertSize == NULL)) {
169 return Status;
170 }
171
172 CertStack = (STACK_OF (X509) *) X509Stack;
173
174 X509Cert = sk_X509_pop (CertStack);
175
176 if (X509Cert == NULL) {
177 return Status;
178 }
179
180 Buffer = NULL;
181
182 CertBio = BIO_new (BIO_s_mem ());
183 if (CertBio == NULL) {
184 return Status;
185 }
186
187 Result = i2d_X509_bio (CertBio, X509Cert);
188 if (Result == 0) {
189 goto _Exit;
190 }
191
192 BIO_get_mem_ptr (CertBio, &Ptr);
193 Length = (INT32)(Ptr->length);
194 if (Length <= 0) {
195 goto _Exit;
196 }
197
198 Buffer = malloc (Length);
199 if (Buffer == NULL) {
200 goto _Exit;
201 }
202
203 Result = BIO_read (CertBio, Buffer, Length);
204 if (Result != Length) {
205 goto _Exit;
206 }
207
208 *Cert = Buffer;
209 *CertSize = Length;
210
211 Status = TRUE;
212
213_Exit:
214
215 BIO_free (CertBio);
216
217 if (!Status && (Buffer != NULL)) {
218 free (Buffer);
219 }
220
221 return Status;
222}
223
252BOOLEAN
253EFIAPI
255 IN CONST UINT8 *P7Data,
256 IN UINTN P7Length,
257 OUT UINT8 **CertStack,
258 OUT UINTN *StackLength,
259 OUT UINT8 **TrustedCert,
260 OUT UINTN *CertLength
261 )
262{
263 PKCS7 *Pkcs7;
264 BOOLEAN Status;
265 UINT8 *SignedData;
266 CONST UINT8 *Temp;
267 UINTN SignedDataSize;
268 BOOLEAN Wrapped;
269
270 STACK_OF (X509) *Stack;
271 UINT8 Index;
272 UINT8 *CertBuf;
273 UINT8 *OldBuf;
274 UINTN BufferSize;
275 UINTN OldSize;
276 UINT8 *SingleCert;
277 UINTN SingleCertSize;
278
279 if ((P7Data == NULL) || (CertStack == NULL) || (StackLength == NULL) ||
280 (TrustedCert == NULL) || (CertLength == NULL) || (P7Length > INT_MAX))
281 {
282 return FALSE;
283 }
284
285 Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
286 if (!Status) {
287 return Status;
288 }
289
290 Status = FALSE;
291 Pkcs7 = NULL;
292 Stack = NULL;
293 CertBuf = NULL;
294 OldBuf = NULL;
295 SingleCert = NULL;
296
297 //
298 // Retrieve PKCS#7 Data (DER encoding)
299 //
300 if (SignedDataSize > INT_MAX) {
301 goto _Exit;
302 }
303
304 Temp = SignedData;
305 Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **)&Temp, (int)SignedDataSize);
306 if (Pkcs7 == NULL) {
307 goto _Exit;
308 }
309
310 //
311 // Check if it's PKCS#7 Signed Data (for Authenticode Scenario)
312 //
313 if (!PKCS7_type_is_signed (Pkcs7)) {
314 goto _Exit;
315 }
316
317 Stack = PKCS7_get0_signers (Pkcs7, NULL, PKCS7_BINARY);
318 if (Stack == NULL) {
319 goto _Exit;
320 }
321
322 //
323 // Convert CertStack to buffer in following format:
324 // UINT8 CertNumber;
325 // UINT32 Cert1Length;
326 // UINT8 Cert1[];
327 // UINT32 Cert2Length;
328 // UINT8 Cert2[];
329 // ...
330 // UINT32 CertnLength;
331 // UINT8 Certn[];
332 //
333 BufferSize = sizeof (UINT8);
334 OldSize = BufferSize;
335
336 for (Index = 0; ; Index++) {
337 Status = X509PopCertificate (Stack, &SingleCert, &SingleCertSize);
338 if (!Status) {
339 break;
340 }
341
342 OldSize = BufferSize;
343 OldBuf = CertBuf;
344 BufferSize = OldSize + SingleCertSize + sizeof (UINT32);
345 CertBuf = malloc (BufferSize);
346
347 if (CertBuf == NULL) {
348 goto _Exit;
349 }
350
351 if (OldBuf != NULL) {
352 CopyMem (CertBuf, OldBuf, OldSize);
353 free (OldBuf);
354 OldBuf = NULL;
355 }
356
357 WriteUnaligned32 ((UINT32 *)(CertBuf + OldSize), (UINT32)SingleCertSize);
358 CopyMem (CertBuf + OldSize + sizeof (UINT32), SingleCert, SingleCertSize);
359
360 free (SingleCert);
361 SingleCert = NULL;
362 }
363
364 if (CertBuf != NULL) {
365 //
366 // Update CertNumber.
367 //
368 CertBuf[0] = Index;
369
370 *CertLength = BufferSize - OldSize - sizeof (UINT32);
371 *TrustedCert = malloc (*CertLength);
372 if (*TrustedCert == NULL) {
373 goto _Exit;
374 }
375
376 CopyMem (*TrustedCert, CertBuf + OldSize + sizeof (UINT32), *CertLength);
377 *CertStack = CertBuf;
378 *StackLength = BufferSize;
379 Status = TRUE;
380 }
381
382_Exit:
383 //
384 // Release Resources
385 //
386 if (!Wrapped) {
387 free (SignedData);
388 }
389
390 if (Pkcs7 != NULL) {
391 PKCS7_free (Pkcs7);
392 }
393
394 if (Stack != NULL) {
395 sk_X509_pop_free (Stack, X509_free);
396 }
397
398 if (SingleCert != NULL) {
399 free (SingleCert);
400 }
401
402 if (!Status && (CertBuf != NULL)) {
403 free (CertBuf);
404 *CertStack = NULL;
405 }
406
407 if (OldBuf != NULL) {
408 free (OldBuf);
409 }
410
411 return Status;
412}
413
420VOID
421EFIAPI
423 IN UINT8 *Certs
424 )
425{
426 if (Certs == NULL) {
427 return;
428 }
429
430 free (Certs);
431}
432
455BOOLEAN
456EFIAPI
458 IN CONST UINT8 *P7Data,
459 IN UINTN P7Length,
460 OUT UINT8 **SignerChainCerts,
461 OUT UINTN *ChainLength,
462 OUT UINT8 **UnchainCerts,
463 OUT UINTN *UnchainLength
464 )
465{
466 BOOLEAN Status;
467 UINT8 *NewP7Data;
468 UINTN NewP7Length;
469 BOOLEAN Wrapped;
470 UINT8 Index;
471 PKCS7 *Pkcs7;
472 X509_STORE_CTX *CertCtx;
473
474 STACK_OF (X509) *CtxChain;
475 STACK_OF (X509) *CtxUntrusted;
476 X509 *CtxCert;
477
478 STACK_OF (X509) *Signers;
479 X509 *Signer;
480 X509 *Cert;
481 X509 *Issuer;
482 X509_NAME *IssuerName;
483 UINT8 *CertBuf;
484 UINT8 *OldBuf;
485 UINTN BufferSize;
486 UINTN OldSize;
487 UINT8 *SingleCert;
488 UINTN CertSize;
489
490 //
491 // Initializations
492 //
493 Status = FALSE;
494 NewP7Data = NULL;
495 Pkcs7 = NULL;
496 CertCtx = NULL;
497 CtxChain = NULL;
498 CtxCert = NULL;
499 CtxUntrusted = NULL;
500 Cert = NULL;
501 SingleCert = NULL;
502 CertBuf = NULL;
503 OldBuf = NULL;
504 Signers = NULL;
505
506 //
507 // Parameter Checking
508 //
509 if ((P7Data == NULL) || (SignerChainCerts == NULL) || (ChainLength == NULL) ||
510 (UnchainCerts == NULL) || (UnchainLength == NULL) || (P7Length > INT_MAX))
511 {
512 return Status;
513 }
514
515 *SignerChainCerts = NULL;
516 *ChainLength = 0;
517 *UnchainCerts = NULL;
518 *UnchainLength = 0;
519
520 //
521 // Construct a new PKCS#7 data wrapping with ContentInfo structure if needed.
522 //
523 Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &NewP7Data, &NewP7Length);
524 if (!Status || (NewP7Length > INT_MAX)) {
525 goto _Error;
526 }
527
528 //
529 // Decodes PKCS#7 SignedData
530 //
531 Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **)&NewP7Data, (int)NewP7Length);
532 if ((Pkcs7 == NULL) || (!PKCS7_type_is_signed (Pkcs7))) {
533 goto _Error;
534 }
535
536 //
537 // Obtains Signer's Certificate from PKCS#7 data
538 // NOTE: Only one signer case will be handled in this function, which means SignerInfos
539 // should include only one signer's certificate.
540 //
541 Signers = PKCS7_get0_signers (Pkcs7, NULL, PKCS7_BINARY);
542 if ((Signers == NULL) || (sk_X509_num (Signers) != 1)) {
543 goto _Error;
544 }
545
546 Signer = sk_X509_value (Signers, 0);
547
548 CertCtx = X509_STORE_CTX_new ();
549 if (CertCtx == NULL) {
550 goto _Error;
551 }
552
553 if (!X509_STORE_CTX_init (CertCtx, NULL, Signer, Pkcs7->d.sign->cert)) {
554 goto _Error;
555 }
556
557 //
558 // Initialize Chained & Untrusted stack
559 //
560 CtxChain = X509_STORE_CTX_get0_chain (CertCtx);
561 CtxCert = X509_STORE_CTX_get0_cert (CertCtx);
562 if (CtxChain == NULL) {
563 if (((CtxChain = sk_X509_new_null ()) == NULL) ||
564 (!sk_X509_push (CtxChain, CtxCert)))
565 {
566 goto _Error;
567 }
568 }
569
570 CtxUntrusted = X509_STORE_CTX_get0_untrusted (CertCtx);
571 if (CtxUntrusted != NULL) {
572 (VOID)sk_X509_delete_ptr (CtxUntrusted, Signer);
573 }
574
575 //
576 // Build certificates stack chained from Signer's certificate.
577 //
578 Cert = Signer;
579 for ( ; ;) {
580 //
581 // Self-Issue checking
582 //
583 Issuer = NULL;
584 if (X509_STORE_CTX_get1_issuer (&Issuer, CertCtx, Cert) == 1) {
585 if (X509_cmp (Issuer, Cert) == 0) {
586 break;
587 }
588 }
589
590 //
591 // Found the issuer of the current certificate
592 //
593 if (CtxUntrusted != NULL) {
594 Issuer = NULL;
595 IssuerName = X509_get_issuer_name (Cert);
596 Issuer = X509_find_by_subject (CtxUntrusted, IssuerName);
597 if (Issuer != NULL) {
598 if (!sk_X509_push (CtxChain, Issuer)) {
599 goto _Error;
600 }
601
602 (VOID)sk_X509_delete_ptr (CtxUntrusted, Issuer);
603
604 Cert = Issuer;
605 continue;
606 }
607 }
608
609 break;
610 }
611
612 //
613 // Converts Chained and Untrusted Certificate to Certificate Buffer in following format:
614 // UINT8 CertNumber;
615 // UINT32 Cert1Length;
616 // UINT8 Cert1[];
617 // UINT32 Cert2Length;
618 // UINT8 Cert2[];
619 // ...
620 // UINT32 CertnLength;
621 // UINT8 Certn[];
622 //
623
624 if (CtxChain != NULL) {
625 BufferSize = sizeof (UINT8);
626 CertBuf = NULL;
627
628 for (Index = 0; ; Index++) {
629 Status = X509PopCertificate (CtxChain, &SingleCert, &CertSize);
630 if (!Status) {
631 break;
632 }
633
634 OldSize = BufferSize;
635 OldBuf = CertBuf;
636 BufferSize = OldSize + CertSize + sizeof (UINT32);
637 CertBuf = malloc (BufferSize);
638
639 if (CertBuf == NULL) {
640 Status = FALSE;
641 goto _Error;
642 }
643
644 if (OldBuf != NULL) {
645 CopyMem (CertBuf, OldBuf, OldSize);
646 free (OldBuf);
647 OldBuf = NULL;
648 }
649
650 WriteUnaligned32 ((UINT32 *)(CertBuf + OldSize), (UINT32)CertSize);
651 CopyMem (CertBuf + OldSize + sizeof (UINT32), SingleCert, CertSize);
652
653 free (SingleCert);
654 SingleCert = NULL;
655 }
656
657 if (CertBuf != NULL) {
658 //
659 // Update CertNumber.
660 //
661 CertBuf[0] = Index;
662
663 *SignerChainCerts = CertBuf;
664 *ChainLength = BufferSize;
665 }
666 }
667
668 if (CtxUntrusted != NULL) {
669 BufferSize = sizeof (UINT8);
670 CertBuf = NULL;
671
672 for (Index = 0; ; Index++) {
673 Status = X509PopCertificate (CtxUntrusted, &SingleCert, &CertSize);
674 if (!Status) {
675 break;
676 }
677
678 OldSize = BufferSize;
679 OldBuf = CertBuf;
680 BufferSize = OldSize + CertSize + sizeof (UINT32);
681 CertBuf = malloc (BufferSize);
682
683 if (CertBuf == NULL) {
684 Status = FALSE;
685 goto _Error;
686 }
687
688 if (OldBuf != NULL) {
689 CopyMem (CertBuf, OldBuf, OldSize);
690 free (OldBuf);
691 OldBuf = NULL;
692 }
693
694 WriteUnaligned32 ((UINT32 *)(CertBuf + OldSize), (UINT32)CertSize);
695 CopyMem (CertBuf + OldSize + sizeof (UINT32), SingleCert, CertSize);
696
697 free (SingleCert);
698 SingleCert = NULL;
699 }
700
701 if (CertBuf != NULL) {
702 //
703 // Update CertNumber.
704 //
705 CertBuf[0] = Index;
706
707 *UnchainCerts = CertBuf;
708 *UnchainLength = BufferSize;
709 }
710 }
711
712 Status = TRUE;
713
714_Error:
715 //
716 // Release Resources.
717 //
718 if (!Wrapped && (NewP7Data != NULL)) {
719 free (NewP7Data);
720 }
721
722 if (Pkcs7 != NULL) {
723 PKCS7_free (Pkcs7);
724 }
725
726 sk_X509_free (Signers);
727
728 if (CertCtx != NULL) {
729 X509_STORE_CTX_cleanup (CertCtx);
730 X509_STORE_CTX_free (CertCtx);
731 }
732
733 if (SingleCert != NULL) {
734 free (SingleCert);
735 }
736
737 if (OldBuf != NULL) {
738 free (OldBuf);
739 }
740
741 if (!Status && (CertBuf != NULL)) {
742 free (CertBuf);
743 *SignerChainCerts = NULL;
744 *UnchainCerts = NULL;
745 }
746
747 return Status;
748}
749
774BOOLEAN
775EFIAPI
777 IN CONST UINT8 *P7Data,
778 IN UINTN P7Length,
779 IN CONST UINT8 *TrustedCert,
780 IN UINTN CertLength,
781 IN CONST UINT8 *InData,
782 IN UINTN DataLength
783 )
784{
785 PKCS7 *Pkcs7;
786 BIO *DataBio;
787 BOOLEAN Status;
788 X509 *Cert;
789 X509_STORE *CertStore;
790 UINT8 *SignedData;
791 CONST UINT8 *Temp;
792 UINTN SignedDataSize;
793 BOOLEAN Wrapped;
794
795 //
796 // Check input parameters.
797 //
798 if ((P7Data == NULL) || (TrustedCert == NULL) || (InData == NULL) ||
799 (P7Length > INT_MAX) || (CertLength > INT_MAX) || (DataLength > INT_MAX))
800 {
801 return FALSE;
802 }
803
804 Pkcs7 = NULL;
805 DataBio = NULL;
806 Cert = NULL;
807 CertStore = NULL;
808
809 //
810 // Register & Initialize necessary digest algorithms for PKCS#7 Handling
811 //
812 if (EVP_add_digest (EVP_md5 ()) == 0) {
813 return FALSE;
814 }
815
816 if (EVP_add_digest (EVP_sha1 ()) == 0) {
817 return FALSE;
818 }
819
820 if (EVP_add_digest (EVP_sha256 ()) == 0) {
821 return FALSE;
822 }
823
824 if (EVP_add_digest (EVP_sha384 ()) == 0) {
825 return FALSE;
826 }
827
828 if (EVP_add_digest (EVP_sha512 ()) == 0) {
829 return FALSE;
830 }
831
832 if (EVP_add_digest_alias (SN_sha1WithRSAEncryption, SN_sha1WithRSA) == 0) {
833 return FALSE;
834 }
835
836 Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
837 if (!Status) {
838 return Status;
839 }
840
841 Status = FALSE;
842
843 //
844 // Retrieve PKCS#7 Data (DER encoding)
845 //
846 if (SignedDataSize > INT_MAX) {
847 goto _Exit;
848 }
849
850 Temp = SignedData;
851 Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **)&Temp, (int)SignedDataSize);
852 if (Pkcs7 == NULL) {
853 goto _Exit;
854 }
855
856 //
857 // Check if it's PKCS#7 Signed Data (for Authenticode Scenario)
858 //
859 if (!PKCS7_type_is_signed (Pkcs7)) {
860 goto _Exit;
861 }
862
863 //
864 // Read DER-encoded root certificate and Construct X509 Certificate
865 //
866 Temp = TrustedCert;
867 Cert = d2i_X509 (NULL, &Temp, (long)CertLength);
868 if (Cert == NULL) {
869 goto _Exit;
870 }
871
872 //
873 // Setup X509 Store for trusted certificate
874 //
875 CertStore = X509_STORE_new ();
876 if (CertStore == NULL) {
877 goto _Exit;
878 }
879
880 if (!(X509_STORE_add_cert (CertStore, Cert))) {
881 goto _Exit;
882 }
883
884 //
885 // For generic PKCS#7 handling, InData may be NULL if the content is present
886 // in PKCS#7 structure. So ignore NULL checking here.
887 //
888 DataBio = BIO_new_mem_buf (InData, (int)DataLength);
889 if (DataBio == NULL) {
890 goto _Exit;
891 }
892
893 //
894 // Allow partial certificate chains, terminated by a non-self-signed but
895 // still trusted intermediate certificate. Also disable time checks.
896 //
897 X509_STORE_set_flags (
898 CertStore,
899 X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME
900 );
901
902 //
903 // OpenSSL PKCS7 Verification by default checks for SMIME (email signing) and
904 // doesn't support the extended key usage for Authenticode Code Signing.
905 // Bypass the certificate purpose checking by enabling any purposes setting.
906 //
907 X509_STORE_set_purpose (CertStore, X509_PURPOSE_ANY);
908
909 //
910 // Verifies the PKCS#7 signedData structure
911 //
912 Status = (BOOLEAN)PKCS7_verify (Pkcs7, NULL, CertStore, DataBio, NULL, PKCS7_BINARY);
913
914_Exit:
915 //
916 // Release Resources
917 //
918 BIO_free (DataBio);
919 X509_free (Cert);
920 X509_STORE_free (CertStore);
921 PKCS7_free (Pkcs7);
922
923 if (!Wrapped) {
924 OPENSSL_free (SignedData);
925 }
926
927 return Status;
928}
UINT64 UINTN
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)
#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
#define GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
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)
STATIC BOOLEAN X509PopCertificate(IN VOID *X509Stack, OUT UINT8 **Cert, OUT UINTN *CertSize)
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)