]> git.proxmox.com Git - mirror_edk2.git/blob - CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7.c
ca0dd4f286480b3c15818d4a02abb4b0164c3294
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLib / Pk / CryptPkcs7.c
1 /** @file
2 PKCS#7 SignedData Verification Wrapper Implementation over OpenSSL.
3
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
9
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.
12
13 **/
14
15 #include "InternalCryptLib.h"
16
17 #include <openssl/objects.h>
18 #include <openssl/x509.h>
19 #include <openssl/pkcs7.h>
20
21
22 /**
23 Verifies the validility of a PKCS#7 signed data as described in "PKCS #7: Cryptographic
24 Message Syntax Standard".
25
26 If P7Data is NULL, then ASSERT().
27
28 @param[in] P7Data Pointer to the PKCS#7 message to verify.
29 @param[in] P7Length Length of the PKCS#7 message in bytes.
30 @param[in] TrustedCert Pointer to a trusted/root certificate encoded in DER, which
31 is used for certificate chain verification.
32 @param[in] CertLength Length of the trusted certificate in bytes.
33 @param[in] InData Pointer to the content to be verified.
34 @param[in] DataLength Length of InData in bytes.
35
36 @retval TRUE The specified PKCS#7 signed data is valid.
37 @retval FALSE Invalid PKCS#7 signed data.
38
39 **/
40 BOOLEAN
41 EFIAPI
42 Pkcs7Verify (
43 IN CONST UINT8 *P7Data,
44 IN UINTN P7Length,
45 IN CONST UINT8 *TrustedCert,
46 IN UINTN CertLength,
47 IN CONST UINT8 *InData,
48 IN UINTN DataLength
49 )
50 {
51 PKCS7 *Pkcs7;
52 UINT8 *Content;
53 BIO *CertBio;
54 BIO *DataBio;
55 BOOLEAN Status;
56 X509 *Cert;
57 X509_STORE *CertStore;
58
59 //
60 // ASSERT if P7Data is NULL
61 //
62 ASSERT (P7Data != NULL);
63
64 Status = FALSE;
65 Pkcs7 = NULL;
66 CertBio = NULL;
67 DataBio = NULL;
68 Cert = NULL;
69 CertStore = NULL;
70
71 //
72 // Register & Initialize necessary digest algorithms for PKCS#7 Handling
73 //
74 EVP_add_digest (EVP_md5());
75 EVP_add_digest (EVP_sha1());
76 EVP_add_digest (EVP_sha256());
77
78 //
79 // Retrieve PKCS#7 Data (DER encoding)
80 //
81 Pkcs7 = d2i_PKCS7 (NULL, &P7Data, (int)P7Length);
82 if (Pkcs7 == NULL) {
83 goto _Exit;
84 }
85
86 //
87 // Check if it's PKCS#7 Signed Data (for Authenticode Scenario)
88 //
89 if (!PKCS7_type_is_signed (Pkcs7)) {
90 goto _Exit;
91 }
92
93 //
94 // Check PKCS#7 embedded signed content with InData.
95 //
96 if (InData != NULL) {
97 //
98 // NOTE: PKCS7_dataDecode() didn't work for Authenticode-format signed data due to
99 // some authenticode-specific structure. Use opaque ASN.1 string to retrieve
100 // PKCS#7 ContentInfo here.
101 //
102 Content = (UINT8 *)(Pkcs7->d.sign->contents->d.other->value.asn1_string->data);
103
104 // Ignore two bytes for DER encoding of ASN.1 "SEQUENCE"
105 if (CompareMem (Content + 2, InData, DataLength) != 0) {
106 goto _Exit;
107 }
108 }
109
110 //
111 // Read DER-encoded root certificate and Construct X509 Certificate
112 //
113 CertBio = BIO_new (BIO_s_mem ());
114 BIO_write (CertBio, TrustedCert, (int)CertLength);
115 if (CertBio == NULL) {
116 goto _Exit;
117 }
118 Cert = d2i_X509_bio (CertBio, NULL);
119 if (Cert == NULL) {
120 goto _Exit;
121 }
122
123 //
124 // Setup X509 Store for trusted certificate
125 //
126 CertStore = X509_STORE_new ();
127 if (CertStore == NULL) {
128 goto _Exit;
129 }
130 if (!(X509_STORE_add_cert (CertStore, Cert))) {
131 goto _Exit;
132 }
133
134 //
135 // For generic PKCS#7 handling, InData may be NULL if the content is present
136 // in PKCS#7 structure. So ignore NULL checking here.
137 //
138 DataBio = BIO_new (BIO_s_mem ());
139 BIO_write (DataBio, InData, (int)DataLength);
140
141 //
142 // Verifies the PKCS#7 signedData structure
143 //
144 Status = (BOOLEAN) PKCS7_verify (Pkcs7, NULL, CertStore, DataBio, NULL, 0);
145
146 _Exit:
147 //
148 // Release Resources
149 //
150 BIO_free (DataBio);
151 BIO_free (CertBio);
152 X509_free (Cert);
153 X509_STORE_free (CertStore);
154 PKCS7_free (Pkcs7);
155
156 return Status;
157 }