]> git.proxmox.com Git - mirror_edk2.git/blame - CryptoPkg/Library/BaseCryptLib/Pem/CryptPem.c
Fix several issues in BaseCryptLib:
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLib / Pem / CryptPem.c
CommitLineData
4a567c96 1/** @file\r
2 PEM (Privacy Enhanced Mail) Format Handler Wrapper Implementation over OpenSSL.\r
3\r
16d2c32c 4Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>\r
4a567c96 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#include <openssl/pem.h>\r
17\r
18/**\r
19 Callback function for password phrase conversion used for retrieving the encrypted PEM.\r
20\r
21 @param[out] Buf Pointer to the buffer to write the passphrase to.\r
22 @param[in] Size Maximum length of the passphrase (i.e. the size of Buf).\r
23 @param[in] Flag A flag which is set to 0 when reading and 1 when writing.\r
24 @param[in] Key Key data to be passed to the callback routine.\r
25\r
26 @retval The number of characters in the passphrase or 0 if an error occurred.\r
27\r
28**/\r
29INTN\r
30PasswordCallback (\r
31 OUT CHAR8 *Buf, \r
32 IN INTN Size, \r
33 IN INTN Flag, \r
34 IN VOID *Key\r
35 )\r
36{\r
37 INTN KeyLength;\r
38\r
6b8ebcb8 39 ZeroMem ((VOID *) Buf, (UINTN) Size);\r
4a567c96 40 if (Key != NULL) {\r
41 //\r
42 // Duplicate key phrase directly.\r
43 //\r
96488aa2 44 KeyLength = (INTN) AsciiStrLen ((CHAR8 *)Key);\r
4a567c96 45 KeyLength = (KeyLength > Size ) ? Size : KeyLength;\r
96488aa2 46 CopyMem (Buf, Key, (UINTN) KeyLength);\r
4a567c96 47 return KeyLength;\r
48 } else {\r
49 return 0;\r
50 }\r
51}\r
52\r
53/**\r
54 Retrieve the RSA Private Key from the password-protected PEM key data.\r
55\r
56 @param[in] PemData Pointer to the PEM-encoded key data to be retrieved.\r
57 @param[in] PemSize Size of the PEM key data in bytes.\r
58 @param[in] Password NULL-terminated passphrase used for encrypted PEM key data.\r
59 @param[out] RsaContext Pointer to new-generated RSA context which contain the retrieved\r
60 RSA private key component. Use RsaFree() function to free the\r
61 resource.\r
62\r
16d2c32c 63 If PemData is NULL, then return FALSE.\r
64 If RsaContext is NULL, then return FALSE.\r
4a567c96 65\r
66 @retval TRUE RSA Private Key was retrieved successfully.\r
67 @retval FALSE Invalid PEM key data or incorrect password.\r
68\r
69**/\r
70BOOLEAN\r
71EFIAPI\r
72RsaGetPrivateKeyFromPem (\r
73 IN CONST UINT8 *PemData,\r
74 IN UINTN PemSize,\r
75 IN CONST CHAR8 *Password,\r
76 OUT VOID **RsaContext\r
77 )\r
78{\r
79 BOOLEAN Status;\r
80 BIO *PemBio;\r
81\r
82 //\r
16d2c32c 83 // Check input parameters.\r
4a567c96 84 //\r
16d2c32c 85 if (PemData == NULL || RsaContext == NULL || PemSize > INT_MAX) {\r
86 return FALSE;\r
87 }\r
da9e7418 88\r
4a567c96 89 //\r
90 // Add possible block-cipher descriptor for PEM data decryption.\r
91 // NOTE: Only support most popular ciphers (3DES, AES) for the encrypted PEM.\r
92 //\r
dda39f3a 93 if (EVP_add_cipher (EVP_des_ede3_cbc ()) == 0) {\r
94 return FALSE;\r
95 }\r
96 if (EVP_add_cipher (EVP_aes_128_cbc ()) == 0) {\r
97 return FALSE;\r
98 }\r
99 if (EVP_add_cipher (EVP_aes_192_cbc ()) == 0) {\r
100 return FALSE;\r
101 }\r
102 if (EVP_add_cipher (EVP_aes_256_cbc ()) == 0) {\r
103 return FALSE;\r
104 }\r
105\r
106 Status = FALSE;\r
4a567c96 107\r
108 //\r
109 // Read encrypted PEM Data.\r
110 //\r
111 PemBio = BIO_new (BIO_s_mem ());\r
6b8ebcb8 112 BIO_write (PemBio, PemData, (int) PemSize);\r
4a567c96 113 if (PemBio == NULL) {\r
114 goto _Exit;\r
115 }\r
116\r
117 //\r
118 // Retrieve RSA Private Key from encrypted PEM data.\r
119 //\r
6b8ebcb8 120 *RsaContext = PEM_read_bio_RSAPrivateKey (PemBio, NULL, (pem_password_cb *) &PasswordCallback, (void *) Password);\r
4a567c96 121 if (*RsaContext != NULL) {\r
122 Status = TRUE;\r
123 }\r
124\r
125_Exit:\r
126 //\r
127 // Release Resources.\r
128 //\r
129 BIO_free (PemBio);\r
130\r
131 return Status;\r
132}\r