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