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