18#include "InternalCryptLib.h"
20#include <openssl/objects.h>
21#include <openssl/x509.h>
22#include <openssl/x509v3.h>
23#include <openssl/pkcs7.h>
54 OUT BOOLEAN *WrapFlag,
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)) {
75 *WrapData = (UINT8 *)P7Data;
76 *WrapDataSize = P7Length;
81 *WrapDataSize = P7Length + 19;
82 *WrapData = malloc (*WrapDataSize);
83 if (*WrapData ==
NULL) {
88 SignedData = *WrapData;
99 SignedData[2] = (UINT8)(((UINT16)(*WrapDataSize - 4)) >> 8);
100 SignedData[3] = (UINT8)(((UINT16)(*WrapDataSize - 4)) & 0xff);
105 SignedData[4] = 0x06;
106 SignedData[5] = 0x09;
111 CopyMem (SignedData + 6, mOidValue,
sizeof (mOidValue));
116 SignedData[15] = 0xA0;
117 SignedData[16] = 0x82;
122 SignedData[17] = (UINT8)(((UINT16)P7Length) >> 8);
123 SignedData[18] = (UINT8)(((UINT16)P7Length) & 0xff);
128 CopyMem (SignedData + 19, P7Data, P7Length);
159 STACK_OF (X509) *CertStack;
168 if ((X509Stack ==
NULL) || (Cert ==
NULL) || (CertSize ==
NULL)) {
172 CertStack = (STACK_OF (X509) *) X509Stack;
174 X509Cert = sk_X509_pop (CertStack);
176 if (X509Cert ==
NULL) {
182 CertBio = BIO_new (BIO_s_mem ());
183 if (CertBio ==
NULL) {
187 Result = i2d_X509_bio (CertBio, X509Cert);
192 BIO_get_mem_ptr (CertBio, &Ptr);
193 Length = (INT32)(Ptr->length);
198 Buffer = malloc (Length);
199 if (Buffer ==
NULL) {
203 Result = BIO_read (CertBio, Buffer, Length);
204 if (Result != Length) {
217 if (!Status && (Buffer !=
NULL)) {
257 OUT UINT8 **CertStack,
259 OUT UINT8 **TrustedCert,
267 UINTN SignedDataSize;
270 STACK_OF (X509) *Stack;
277 UINTN SingleCertSize;
279 if ((P7Data ==
NULL) || (CertStack ==
NULL) || (StackLength ==
NULL) ||
280 (TrustedCert ==
NULL) || (CertLength ==
NULL) || (P7Length > INT_MAX))
285 Status =
WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
300 if (SignedDataSize > INT_MAX) {
305 Pkcs7 = d2i_PKCS7 (
NULL, (
const unsigned char **)&Temp, (
int)SignedDataSize);
313 if (!PKCS7_type_is_signed (Pkcs7)) {
317 Stack = PKCS7_get0_signers (Pkcs7,
NULL, PKCS7_BINARY);
333 BufferSize =
sizeof (UINT8);
334 OldSize = BufferSize;
336 for (Index = 0; ; Index++) {
342 OldSize = BufferSize;
344 BufferSize = OldSize + SingleCertSize +
sizeof (UINT32);
345 CertBuf = malloc (BufferSize);
347 if (CertBuf ==
NULL) {
351 if (OldBuf !=
NULL) {
352 CopyMem (CertBuf, OldBuf, OldSize);
358 CopyMem (CertBuf + OldSize +
sizeof (UINT32), SingleCert, SingleCertSize);
364 if (CertBuf !=
NULL) {
370 *CertLength = BufferSize - OldSize -
sizeof (UINT32);
371 *TrustedCert = malloc (*CertLength);
372 if (*TrustedCert ==
NULL) {
376 CopyMem (*TrustedCert, CertBuf + OldSize +
sizeof (UINT32), *CertLength);
377 *CertStack = CertBuf;
378 *StackLength = BufferSize;
395 sk_X509_pop_free (Stack, X509_free);
398 if (SingleCert !=
NULL) {
402 if (!Status && (CertBuf !=
NULL)) {
407 if (OldBuf !=
NULL) {
460 OUT UINT8 **SignerChainCerts,
462 OUT UINT8 **UnchainCerts,
472 X509_STORE_CTX *CertCtx;
474 STACK_OF (X509) *CtxChain;
475 STACK_OF (X509) *CtxUntrusted;
478 STACK_OF (X509) *Signers;
482 X509_NAME *IssuerName;
509 if ((P7Data ==
NULL) || (SignerChainCerts ==
NULL) || (ChainLength ==
NULL) ||
510 (UnchainCerts ==
NULL) || (UnchainLength ==
NULL) || (P7Length > INT_MAX))
515 *SignerChainCerts =
NULL;
517 *UnchainCerts =
NULL;
523 Status =
WrapPkcs7Data (P7Data, P7Length, &Wrapped, &NewP7Data, &NewP7Length);
524 if (!Status || (NewP7Length > INT_MAX)) {
531 Pkcs7 = d2i_PKCS7 (
NULL, (
const unsigned char **)&NewP7Data, (
int)NewP7Length);
532 if ((Pkcs7 ==
NULL) || (!PKCS7_type_is_signed (Pkcs7))) {
541 Signers = PKCS7_get0_signers (Pkcs7,
NULL, PKCS7_BINARY);
542 if ((Signers ==
NULL) || (sk_X509_num (Signers) != 1)) {
546 Signer = sk_X509_value (Signers, 0);
548 CertCtx = X509_STORE_CTX_new ();
549 if (CertCtx ==
NULL) {
553 if (!X509_STORE_CTX_init (CertCtx,
NULL, Signer, Pkcs7->d.sign->cert)) {
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)))
570 CtxUntrusted = X509_STORE_CTX_get0_untrusted (CertCtx);
571 if (CtxUntrusted !=
NULL) {
572 (VOID)sk_X509_delete_ptr (CtxUntrusted, Signer);
584 if (X509_STORE_CTX_get1_issuer (&Issuer, CertCtx, Cert) == 1) {
585 if (X509_cmp (Issuer, Cert) == 0) {
593 if (CtxUntrusted !=
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)) {
602 (VOID)sk_X509_delete_ptr (CtxUntrusted, Issuer);
624 if (CtxChain !=
NULL) {
625 BufferSize =
sizeof (UINT8);
628 for (Index = 0; ; Index++) {
634 OldSize = BufferSize;
636 BufferSize = OldSize + CertSize +
sizeof (UINT32);
637 CertBuf = malloc (BufferSize);
639 if (CertBuf ==
NULL) {
644 if (OldBuf !=
NULL) {
645 CopyMem (CertBuf, OldBuf, OldSize);
651 CopyMem (CertBuf + OldSize +
sizeof (UINT32), SingleCert, CertSize);
657 if (CertBuf !=
NULL) {
663 *SignerChainCerts = CertBuf;
664 *ChainLength = BufferSize;
668 if (CtxUntrusted !=
NULL) {
669 BufferSize =
sizeof (UINT8);
672 for (Index = 0; ; Index++) {
678 OldSize = BufferSize;
680 BufferSize = OldSize + CertSize +
sizeof (UINT32);
681 CertBuf = malloc (BufferSize);
683 if (CertBuf ==
NULL) {
688 if (OldBuf !=
NULL) {
689 CopyMem (CertBuf, OldBuf, OldSize);
695 CopyMem (CertBuf + OldSize +
sizeof (UINT32), SingleCert, CertSize);
701 if (CertBuf !=
NULL) {
707 *UnchainCerts = CertBuf;
708 *UnchainLength = BufferSize;
718 if (!Wrapped && (NewP7Data !=
NULL)) {
726 sk_X509_free (Signers);
728 if (CertCtx !=
NULL) {
729 X509_STORE_CTX_cleanup (CertCtx);
730 X509_STORE_CTX_free (CertCtx);
733 if (SingleCert !=
NULL) {
737 if (OldBuf !=
NULL) {
741 if (!Status && (CertBuf !=
NULL)) {
743 *SignerChainCerts =
NULL;
744 *UnchainCerts =
NULL;
789 X509_STORE *CertStore;
792 UINTN SignedDataSize;
798 if ((P7Data ==
NULL) || (TrustedCert ==
NULL) || (InData ==
NULL) ||
799 (P7Length > INT_MAX) || (CertLength > INT_MAX) || (DataLength > INT_MAX))
812 if (EVP_add_digest (EVP_md5 ()) == 0) {
816 if (EVP_add_digest (EVP_sha1 ()) == 0) {
820 if (EVP_add_digest (EVP_sha256 ()) == 0) {
824 if (EVP_add_digest (EVP_sha384 ()) == 0) {
828 if (EVP_add_digest (EVP_sha512 ()) == 0) {
832 if (EVP_add_digest_alias (SN_sha1WithRSAEncryption, SN_sha1WithRSA) == 0) {
836 Status =
WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
846 if (SignedDataSize > INT_MAX) {
851 Pkcs7 = d2i_PKCS7 (
NULL, (
const unsigned char **)&Temp, (
int)SignedDataSize);
859 if (!PKCS7_type_is_signed (Pkcs7)) {
867 Cert = d2i_X509 (
NULL, &Temp, (
long)CertLength);
875 CertStore = X509_STORE_new ();
876 if (CertStore ==
NULL) {
880 if (!(X509_STORE_add_cert (CertStore, Cert))) {
888 DataBio = BIO_new_mem_buf (InData, (
int)DataLength);
889 if (DataBio ==
NULL) {
897 X509_STORE_set_flags (
899 X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME
907 X509_STORE_set_purpose (CertStore, X509_PURPOSE_ANY);
912 Status = (BOOLEAN)PKCS7_verify (Pkcs7,
NULL, CertStore, DataBio,
NULL, PKCS7_BINARY);
920 X509_STORE_free (CertStore);
924 OPENSSL_free (SignedData);
UINT32 EFIAPI WriteUnaligned32(OUT UINT32 *Buffer, IN UINT32 Value)
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 GLOBAL_REMOVE_IF_UNREFERENCED
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)