]> git.proxmox.com Git - mirror_edk2.git/blame - CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7Sign.c
Fix some typo and coding style issues in BaseCryptLib instances.
[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
4Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
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
21\r
22/**\r
23 Creates a PKCS#7 signedData as described in "PKCS #7: Cryptographic Message\r
24 Syntax Standard, version 1.5". This interface is only intended to be used for\r
25 application to perform PKCS#7 functionality validation.\r
26\r
27 @param[in] PrivateKey Pointer to the PEM-formatted private key data for\r
28 data signing.\r
29 @param[in] PrivateKeySize Size of the PEM private key data in bytes.\r
30 @param[in] KeyPassword NULL-terminated passphrase used for encrypted PEM\r
31 key data.\r
32 @param[in] InData Pointer to the content to be signed.\r
33 @param[in] InDataSize Size of InData in bytes.\r
34 @param[in] SignCert Pointer to signer's DER-encoded certificate to sign with.\r
35 @param[in] OtherCerts Pointer to an optional additional set of certificates to\r
36 include in the PKCS#7 signedData (e.g. any intermediate\r
37 CAs in the chain).\r
38 @param[out] SignedData Pointer to output PKCS#7 signedData.\r
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
95 //\r
96 // Register & Initialize necessary digest algorithms and PRNG for PKCS#7 Handling\r
97 //\r
98 EVP_add_digest (EVP_md5());\r
99 EVP_add_digest (EVP_sha1());\r
100 EVP_add_digest (EVP_sha256());\r
101 RandomSeed (NULL, 0);\r
102\r
103 //\r
104 // Construct OpenSSL EVP_PKEY for private key.\r
105 //\r
106 Key = EVP_PKEY_new ();\r
107 if (Key == NULL) {\r
108 Status = FALSE;\r
109 goto _Exit;\r
110 }\r
111 Key->save_type = EVP_PKEY_RSA;\r
112 Key->type = EVP_PKEY_type (EVP_PKEY_RSA);\r
113 Key->pkey.rsa = (RSA *) RsaContext;\r
114\r
115 //\r
116 // Convert the data to be signed to BIO format. \r
117 //\r
118 DataBio = BIO_new (BIO_s_mem ());\r
119 BIO_write (DataBio, InData, (int) InDataSize);\r
120\r
121 //\r
122 // Create the PKCS#7 signedData structure.\r
123 //\r
124 Pkcs7 = PKCS7_sign (\r
125 (X509 *) SignCert,\r
126 Key,\r
127 (STACK_OF(X509) *) OtherCerts,\r
128 DataBio,\r
129 PKCS7_BINARY | PKCS7_NOATTR | PKCS7_DETACHED\r
130 );\r
131 if (Pkcs7 == NULL) {\r
132 Status = FALSE;\r
133 goto _Exit;\r
134 }\r
135\r
136 //\r
137 // Convert PKCS#7 signedData structure into DER-encoded buffer.\r
138 //\r
139 P7DataSize = i2d_PKCS7 (Pkcs7, NULL);\r
140 if (P7DataSize <= 19) {\r
141 Status = FALSE;\r
142 goto _Exit;\r
143 }\r
144\r
145 P7Data = malloc (P7DataSize);\r
146 if (P7Data == NULL) {\r
147 Status = FALSE;\r
148 goto _Exit;\r
149 }\r
150\r
151 Tmp = P7Data;\r
152 P7DataSize = i2d_PKCS7 (Pkcs7, (unsigned char **) &Tmp);\r
153\r
154 //\r
155 // Strip ContentInfo to content only for signeddata. The data be trimmed off\r
156 // is totally 19 bytes.\r
157 //\r
158 *SignedDataSize = P7DataSize - 19;\r
159 *SignedData = malloc (*SignedDataSize);\r
160 if (*SignedData == NULL) {\r
161 Status = FALSE;\r
162 OPENSSL_free (P7Data);\r
163 goto _Exit;\r
164 }\r
165\r
166 CopyMem (*SignedData, P7Data + 19, *SignedDataSize);\r
167 \r
168 OPENSSL_free (P7Data);\r
169\r
170 Status = TRUE;\r
171\r
172_Exit:\r
173 //\r
174 // Release Resources\r
175 //\r
176 if (RsaContext != NULL) {\r
177 RsaFree (RsaContext);\r
178 if (Key != NULL) {\r
179 Key->pkey.rsa = NULL;\r
180 }\r
181 }\r
182\r
183 if (Key != NULL) {\r
184 EVP_PKEY_free (Key);\r
185 }\r
186\r
187 if (DataBio != NULL) {\r
188 BIO_free (DataBio);\r
189 }\r
190\r
191 if (Pkcs7 != NULL) {\r
192 PKCS7_free (Pkcs7);\r
193 }\r
194\r
195 return Status;\r
196}\r