]>
git.proxmox.com Git - mirror_edk2.git/blob - CryptoPkg/Library/BaseCryptLib/Pk/CryptAuthenticode.c
2 Authenticode Portable Executable Signature Verification over OpenSSL.
4 Copyright (c) 2011, 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 "InternalCryptLib.h"
17 #include <openssl/objects.h>
18 #include <openssl/x509.h>
19 #include <openssl/pkcs7.h>
23 Verifies the validility of a PE/COFF Authenticode Signature as described in "Windows
24 Authenticode Portable Executable Signature Format".
26 If AuthData is NULL, then ASSERT().
27 If ImageHash is NULL, then ASSERT().
29 @param[in] AuthData Pointer to the Authenticode Signature retrieved from signed
30 PE/COFF image to be verified.
31 @param[in] DataSize Size of the Authenticode Signature in bytes.
32 @param[in] TrustedCert Pointer to a trusted/root certificate encoded in DER, which
33 is used for certificate chain verification.
34 @param[in] CertSize Size of the trusted certificate in bytes.
35 @param[in] ImageHash Pointer to the original image file hash value. The procudure
36 for calculating the image hash value is described in Authenticode
38 @param[in] HashSize Size of Image hash value in bytes.
40 @retval TRUE The specified Authenticode Signature is valid.
41 @retval FALSE Invalid Authenticode Signature.
47 IN CONST UINT8
*AuthData
,
49 IN CONST UINT8
*TrustedCert
,
51 IN CONST UINT8
*ImageHash
,
57 CONST UINT8
*OrigAuthData
;
58 UINT8
*SpcIndirectDataContent
;
63 // ASSERT if Authenticode Signature Data or PE Image Hash is NULL
65 ASSERT (AuthData
!= NULL
);
66 ASSERT (ImageHash
!= NULL
);
70 OrigAuthData
= AuthData
;
73 // Retrieve & Parse PKCS#7 Data (DER encoding) from Authenticode Signature
75 Pkcs7
= d2i_PKCS7 (NULL
, &AuthData
, (int)DataSize
);
81 // Check if it's PKCS#7 Signed Data (for Authenticode Scenario)
83 if (!PKCS7_type_is_signed (Pkcs7
)) {
88 // NOTE: OpenSSL PKCS7 Decoder didn't work for Authenticode-format signed data due to
89 // some authenticode-specific structure. Use opaque ASN.1 string to retrieve
90 // PKCS#7 ContentInfo here.
92 SpcIndirectDataContent
= (UINT8
*)(Pkcs7
->d
.sign
->contents
->d
.other
->value
.asn1_string
->data
);
95 // Retrieve the SEQUENCE data size from ASN.1-encoded SpcIndirectDataContent.
97 Asn1Byte
= *(SpcIndirectDataContent
+ 1);
98 if ((Asn1Byte
& 0x80) == 0) {
100 // Short Form of Length Encoding
102 ContentSize
= (UINTN
) (Asn1Byte
& 0x7F);
104 // Skip the SEQUENCE Tag;
106 SpcIndirectDataContent
+= 2;
109 // Long Form of Length Encoding (Assume Only two bytes here)
111 ContentSize
= (UINTN
) (*(SpcIndirectDataContent
+ 2));
112 ContentSize
= (ContentSize
<< 8) + (UINTN
)(*(SpcIndirectDataContent
+ 3));
114 // Skip the SEQUENCE Tag;
116 SpcIndirectDataContent
+= 4;
120 // Compare the original file hash value to the digest retrieve from SpcIndirectDataContent
121 // defined in Authenticode
122 // NOTE: Need to double-check HashLength here!
124 if (CompareMem (SpcIndirectDataContent
+ ContentSize
- HashSize
, ImageHash
, HashSize
) != 0) {
126 // Un-matched PE/COFF Hash Value
132 // Verifies the PKCS#7 Signed Data in PE/COFF Authenticode Signature
134 Status
= (BOOLEAN
) Pkcs7Verify (OrigAuthData
, DataSize
, TrustedCert
, CertSize
, SpcIndirectDataContent
, ContentSize
);