]> git.proxmox.com Git - mirror_edk2.git/blame - CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7Sign.c
CryptoPkg: Clean up source files
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLib / Pk / CryptPkcs7Sign.c
CommitLineData
532616bb 1/** @file\r
2 PKCS#7 SignedData Sign Wrapper Implementation over OpenSSL.\r
3\r
630f67dd 4Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
532616bb 5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "InternalCryptLib.h"\r
16\r
17#include <openssl/objects.h>\r
18#include <openssl/x509.h>\r
19#include <openssl/pkcs7.h>\r
20\r
532616bb 21/**\r
22 Creates a PKCS#7 signedData as described in "PKCS #7: Cryptographic Message\r
23 Syntax Standard, version 1.5". This interface is only intended to be used for\r
24 application to perform PKCS#7 functionality validation.\r
25\r
26 @param[in] PrivateKey Pointer to the PEM-formatted private key data for\r
27 data signing.\r
28 @param[in] PrivateKeySize Size of the PEM private key data in bytes.\r
29 @param[in] KeyPassword NULL-terminated passphrase used for encrypted PEM\r
30 key data.\r
31 @param[in] InData Pointer to the content to be signed.\r
32 @param[in] InDataSize Size of InData in bytes.\r
33 @param[in] SignCert Pointer to signer's DER-encoded certificate to sign with.\r
34 @param[in] OtherCerts Pointer to an optional additional set of certificates to\r
35 include in the PKCS#7 signedData (e.g. any intermediate\r
36 CAs in the chain).\r
6fe575d0
LQ
37 @param[out] SignedData Pointer to output PKCS#7 signedData. It's caller's\r
38 responsibility to free the buffer with FreePool().\r
532616bb 39 @param[out] SignedDataSize Size of SignedData in bytes.\r
40\r
41 @retval TRUE PKCS#7 data signing succeeded.\r
42 @retval FALSE PKCS#7 data signing failed.\r
43\r
44**/\r
45BOOLEAN\r
46EFIAPI\r
47Pkcs7Sign (\r
48 IN CONST UINT8 *PrivateKey,\r
49 IN UINTN PrivateKeySize,\r
50 IN CONST UINT8 *KeyPassword,\r
51 IN UINT8 *InData,\r
52 IN UINTN InDataSize,\r
53 IN UINT8 *SignCert,\r
54 IN UINT8 *OtherCerts OPTIONAL,\r
55 OUT UINT8 **SignedData,\r
56 OUT UINTN *SignedDataSize\r
57 )\r
58{\r
59 BOOLEAN Status;\r
60 EVP_PKEY *Key;\r
61 BIO *DataBio;\r
62 PKCS7 *Pkcs7;\r
63 UINT8 *RsaContext;\r
64 UINT8 *P7Data;\r
65 UINTN P7DataSize;\r
66 UINT8 *Tmp;\r
67\r
68 //\r
69 // Check input parameters.\r
70 //\r
71 if (PrivateKey == NULL || KeyPassword == NULL || InData == NULL ||\r
72 SignCert == NULL || SignedData == NULL || SignedDataSize == NULL || InDataSize > INT_MAX) {\r
73 return FALSE;\r
74 }\r
75\r
76 RsaContext = NULL;\r
77 Key = NULL;\r
78 Pkcs7 = NULL;\r
79 DataBio = NULL;\r
80 Status = FALSE;\r
81\r
82 //\r
83 // Retrieve RSA private key from PEM data.\r
84 //\r
85 Status = RsaGetPrivateKeyFromPem (\r
86 PrivateKey,\r
87 PrivateKeySize,\r
88 (CONST CHAR8 *) KeyPassword,\r
89 (VOID **) &RsaContext\r
90 );\r
91 if (!Status) {\r
92 return Status;\r
93 }\r
94\r
dda39f3a 95 Status = FALSE;\r
96\r
532616bb 97 //\r
98 // Register & Initialize necessary digest algorithms and PRNG for PKCS#7 Handling\r
99 //\r
dda39f3a 100 if (EVP_add_digest (EVP_md5 ()) == 0) {\r
101 goto _Exit;\r
102 }\r
103 if (EVP_add_digest (EVP_sha1 ()) == 0) {\r
104 goto _Exit;\r
105 }\r
106 if (EVP_add_digest (EVP_sha256 ()) == 0) {\r
107 goto _Exit;\r
108 }\r
109\r
532616bb 110 RandomSeed (NULL, 0);\r
111\r
112 //\r
113 // Construct OpenSSL EVP_PKEY for private key.\r
114 //\r
115 Key = EVP_PKEY_new ();\r
116 if (Key == NULL) {\r
532616bb 117 goto _Exit;\r
118 }\r
1463ce18
QL
119 if (EVP_PKEY_assign_RSA (Key, (RSA *) RsaContext) == 0) {\r
120 goto _Exit;\r
121 }\r
532616bb 122\r
123 //\r
630f67dd 124 // Convert the data to be signed to BIO format.\r
532616bb 125 //\r
126 DataBio = BIO_new (BIO_s_mem ());\r
5b2956ea
YT
127 if (DataBio == NULL) {\r
128 goto _Exit;\r
129 }\r
130\r
131 if (BIO_write (DataBio, InData, (int) InDataSize) <= 0) {\r
132 goto _Exit;\r
133 }\r
532616bb 134\r
135 //\r
136 // Create the PKCS#7 signedData structure.\r
137 //\r
138 Pkcs7 = PKCS7_sign (\r
139 (X509 *) SignCert,\r
140 Key,\r
141 (STACK_OF(X509) *) OtherCerts,\r
142 DataBio,\r
143 PKCS7_BINARY | PKCS7_NOATTR | PKCS7_DETACHED\r
144 );\r
145 if (Pkcs7 == NULL) {\r
532616bb 146 goto _Exit;\r
147 }\r
148\r
149 //\r
150 // Convert PKCS#7 signedData structure into DER-encoded buffer.\r
151 //\r
152 P7DataSize = i2d_PKCS7 (Pkcs7, NULL);\r
153 if (P7DataSize <= 19) {\r
532616bb 154 goto _Exit;\r
155 }\r
156\r
157 P7Data = malloc (P7DataSize);\r
158 if (P7Data == NULL) {\r
532616bb 159 goto _Exit;\r
160 }\r
161\r
162 Tmp = P7Data;\r
163 P7DataSize = i2d_PKCS7 (Pkcs7, (unsigned char **) &Tmp);\r
5b2956ea 164 ASSERT (P7DataSize > 19);\r
532616bb 165\r
166 //\r
167 // Strip ContentInfo to content only for signeddata. The data be trimmed off\r
168 // is totally 19 bytes.\r
169 //\r
170 *SignedDataSize = P7DataSize - 19;\r
6fe575d0 171 *SignedData = AllocatePool (*SignedDataSize);\r
532616bb 172 if (*SignedData == NULL) {\r
532616bb 173 OPENSSL_free (P7Data);\r
174 goto _Exit;\r
175 }\r
176\r
177 CopyMem (*SignedData, P7Data + 19, *SignedDataSize);\r
1463ce18 178\r
532616bb 179 OPENSSL_free (P7Data);\r
180\r
181 Status = TRUE;\r
182\r
183_Exit:\r
184 //\r
185 // Release Resources\r
186 //\r
532616bb 187 if (Key != NULL) {\r
188 EVP_PKEY_free (Key);\r
189 }\r
190\r
191 if (DataBio != NULL) {\r
192 BIO_free (DataBio);\r
193 }\r
194\r
195 if (Pkcs7 != NULL) {\r
196 PKCS7_free (Pkcs7);\r
197 }\r
198\r
199 return Status;\r
200}\r