]>
git.proxmox.com Git - mirror_edk2.git/blob - CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7.c
d0a6ea544a4ab336691660412bb1bbc175d2001d
2 PKCS#7 SignedData Verification Wrapper Implementation over OpenSSL.
4 Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include <Library/BaseLib.h>
16 #include <Library/BaseMemoryLib.h>
17 #include <Library/DebugLib.h>
19 #include <Library/BaseCryptLib.h>
20 #include <openssl/objects.h>
21 #include <openssl/x509.h>
22 #include <openssl/pkcs7.h>
26 Verifies the validility of a PKCS#7 signed data as described in "PKCS #7: Cryptographic
27 Message Syntax Standard".
29 If P7Data is NULL, then ASSERT().
31 @param[in] P7Data Pointer to the PKCS#7 message to verify.
32 @param[in] P7Length Length of the PKCS#7 message in bytes.
33 @param[in] TrustedCert Pointer to a trusted/root certificate encoded in DER, which
34 is used for certificate chain verification.
35 @param[in] CertLength Length of the trusted certificate in bytes.
36 @param[in] InData Pointer to the content to be verified.
37 @param[in] DataLength Length of InData in bytes.
39 @return TRUE The specified PKCS#7 signed data is valid.
40 @return FALSE Invalid PKCS#7 signed data.
46 IN CONST UINT8
*P7Data
,
48 IN CONST UINT8
*TrustedCert
,
50 IN CONST UINT8
*InData
,
60 X509_STORE
*CertStore
;
63 // ASSERT if P7Data is NULL
65 ASSERT (P7Data
!= NULL
);
75 // Register & Initialize necessary digest algorithms for PKCS#7 Handling
77 EVP_add_digest (EVP_md5());
78 EVP_add_digest (EVP_sha1());
79 EVP_add_digest (EVP_sha256());
82 // Retrieve PKCS#7 Data (DER encoding)
84 Pkcs7
= d2i_PKCS7 (NULL
, &P7Data
, (int)P7Length
);
90 // Check if it's PKCS#7 Signed Data (for Authenticode Scenario)
92 if (!PKCS7_type_is_signed (Pkcs7
)) {
97 // Check PKCS#7 embedded signed content with InData.
101 // NOTE: PKCS7_dataDecode() didn't work for Authenticode-format signed data due to
102 // some authenticode-specific structure. Use opaque ASN.1 string to retrieve
103 // PKCS#7 ContentInfo here.
105 Content
= (UINT8
*)(Pkcs7
->d
.sign
->contents
->d
.other
->value
.asn1_string
->data
);
107 // Ignore two bytes for DER encoding of ASN.1 "SEQUENCE"
108 if (CompareMem (Content
+ 2, InData
, DataLength
) != 0) {
114 // Read DER-encoded root certificate and Construct X509 Certificate
116 CertBio
= BIO_new (BIO_s_mem ());
117 BIO_write (CertBio
, TrustedCert
, (int)CertLength
);
118 if (CertBio
== NULL
) {
121 Cert
= d2i_X509_bio (CertBio
, NULL
);
127 // Setup X509 Store for trusted certificate
129 CertStore
= X509_STORE_new ();
130 if (CertStore
== NULL
) {
133 if (!(X509_STORE_add_cert (CertStore
, Cert
))) {
138 // For generic PKCS#7 handling, InData may be NULL if the content is present
139 // in PKCS#7 structure. So ignore NULL checking here.
141 DataBio
= BIO_new (BIO_s_mem ());
142 BIO_write (DataBio
, InData
, (int)DataLength
);
145 // Verifies the PKCS#7 signedData structure
147 Status
= (BOOLEAN
) PKCS7_verify (Pkcs7
, NULL
, CertStore
, DataBio
, NULL
, 0);
156 X509_STORE_free (CertStore
);