1 /*
2 * PKCS #8
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #ifndef BOTAN_PKCS8_H_
9 #define BOTAN_PKCS8_H_
10 
11 #include <botan/pk_keys.h>
12 #include <botan/exceptn.h>
13 #include <botan/secmem.h>
14 #include <functional>
15 #include <chrono>
16 #include <memory>
17 
18 namespace Botan {
19 
20 class DataSource;
21 class RandomNumberGenerator;
22 
23 /**
24 * PKCS #8 General Exception
25 */
26 class BOTAN_PUBLIC_API(2,0) PKCS8_Exception final : public Decoding_Error
27    {
28    public:
PKCS8_Exception(const std::string & error)29       explicit PKCS8_Exception(const std::string& error) :
30          Decoding_Error("PKCS #8: " + error) {}
31    };
32 
33 /**
34 * This namespace contains functions for handling PKCS #8 private keys
35 */
36 namespace PKCS8 {
37 
38 /**
39 * BER encode a private key
40 * @param key the private key to encode
41 * @return BER encoded key
42 */
43 BOTAN_PUBLIC_API(2,0) secure_vector<uint8_t> BER_encode(const Private_Key& key);
44 
45 /**
46 * Get a string containing a PEM encoded private key.
47 * @param key the key to encode
48 * @return encoded key
49 */
50 BOTAN_PUBLIC_API(2,0) std::string PEM_encode(const Private_Key& key);
51 
52 /**
53 * Encrypt a key using PKCS #8 encryption
54 * @param key the key to encode
55 * @param rng the rng to use
56 * @param pass the password to use for encryption
57 * @param msec number of milliseconds to run the password derivation
58 * @param pbe_algo the name of the desired password-based encryption
59 *        algorithm; if empty ("") a reasonable (portable/secure)
60 *        default will be chosen.
61 * @return encrypted key in binary BER form
62 */
63 BOTAN_PUBLIC_API(2,0) std::vector<uint8_t>
64 BER_encode(const Private_Key& key,
65            RandomNumberGenerator& rng,
66            const std::string& pass,
67            std::chrono::milliseconds msec = std::chrono::milliseconds(300),
68            const std::string& pbe_algo = "");
69 
70 /**
71 * Get a string containing a PEM encoded private key, encrypting it with a
72 * password.
73 * @param key the key to encode
74 * @param rng the rng to use
75 * @param pass the password to use for encryption
76 * @param msec number of milliseconds to run the password derivation
77 * @param pbe_algo the name of the desired password-based encryption
78 *        algorithm; if empty ("") a reasonable (portable/secure)
79 *        default will be chosen.
80 * @return encrypted key in PEM form
81 */
82 BOTAN_PUBLIC_API(2,0) std::string
83 PEM_encode(const Private_Key& key,
84            RandomNumberGenerator& rng,
85            const std::string& pass,
86            std::chrono::milliseconds msec = std::chrono::milliseconds(300),
87            const std::string& pbe_algo = "");
88 
89 /**
90 * Encrypt a key using PKCS #8 encryption and a fixed iteration count
91 * @param key the key to encode
92 * @param rng the rng to use
93 * @param pass the password to use for encryption
94 * @param pbkdf_iter number of interations to run PBKDF2
95 * @param cipher if non-empty specifies the cipher to use. CBC and GCM modes
96 *   are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC".
97 *   If empty a suitable default is chosen.
98 * @param pbkdf_hash if non-empty specifies the PBKDF hash function to use.
99 *   For example "SHA-256" or "SHA-384". If empty a suitable default is chosen.
100 * @return encrypted key in binary BER form
101 */
102 BOTAN_PUBLIC_API(2,1) std::vector<uint8_t>
103 BER_encode_encrypted_pbkdf_iter(const Private_Key& key,
104                                 RandomNumberGenerator& rng,
105                                 const std::string& pass,
106                                 size_t pbkdf_iter,
107                                 const std::string& cipher = "",
108                                 const std::string& pbkdf_hash = "");
109 
110 /**
111 * Get a string containing a PEM encoded private key, encrypting it with a
112 * password.
113 * @param key the key to encode
114 * @param rng the rng to use
115 * @param pass the password to use for encryption
116 * @param pbkdf_iter number of iterations to run PBKDF
117 * @param cipher if non-empty specifies the cipher to use. CBC and GCM modes
118 *   are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC".
119 *   If empty a suitable default is chosen.
120 * @param pbkdf_hash if non-empty specifies the PBKDF hash function to use.
121 *   For example "SHA-256" or "SHA-384". If empty a suitable default is chosen.
122 * @return encrypted key in PEM form
123 */
124 BOTAN_PUBLIC_API(2,1) std::string
125 PEM_encode_encrypted_pbkdf_iter(const Private_Key& key,
126                                 RandomNumberGenerator& rng,
127                                 const std::string& pass,
128                                 size_t pbkdf_iter,
129                                 const std::string& cipher = "",
130                                 const std::string& pbkdf_hash = "");
131 
132 /**
133 * Encrypt a key using PKCS #8 encryption and a variable iteration count
134 * @param key the key to encode
135 * @param rng the rng to use
136 * @param pass the password to use for encryption
137 * @param pbkdf_msec how long to run PBKDF2
138 * @param pbkdf_iterations if non-null, set to the number of iterations used
139 * @param cipher if non-empty specifies the cipher to use. CBC and GCM modes
140 *   are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC".
141 *   If empty a suitable default is chosen.
142 * @param pbkdf_hash if non-empty specifies the PBKDF hash function to use.
143 *   For example "SHA-256" or "SHA-384". If empty a suitable default is chosen.
144 * @return encrypted key in binary BER form
145 */
146 BOTAN_PUBLIC_API(2,1) std::vector<uint8_t>
147 BER_encode_encrypted_pbkdf_msec(const Private_Key& key,
148                                 RandomNumberGenerator& rng,
149                                 const std::string& pass,
150                                 std::chrono::milliseconds pbkdf_msec,
151                                 size_t* pbkdf_iterations,
152                                 const std::string& cipher = "",
153                                 const std::string& pbkdf_hash = "");
154 
155 /**
156 * Get a string containing a PEM encoded private key, encrypting it with a
157 * password.
158 * @param key the key to encode
159 * @param rng the rng to use
160 * @param pass the password to use for encryption
161 * @param pbkdf_msec how long in milliseconds to run PBKDF2
162 * @param pbkdf_iterations (output argument) number of iterations of PBKDF
163 *  that ended up being used
164 * @param cipher if non-empty specifies the cipher to use. CBC and GCM modes
165 *   are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC".
166 *   If empty a suitable default is chosen.
167 * @param pbkdf_hash if non-empty specifies the PBKDF hash function to use.
168 *   For example "SHA-256" or "SHA-384". If empty a suitable default is chosen.
169 * @return encrypted key in PEM form
170 */
171 BOTAN_PUBLIC_API(2,1) std::string
172 PEM_encode_encrypted_pbkdf_msec(const Private_Key& key,
173                                 RandomNumberGenerator& rng,
174                                 const std::string& pass,
175                                 std::chrono::milliseconds pbkdf_msec,
176                                 size_t* pbkdf_iterations,
177                                 const std::string& cipher = "",
178                                 const std::string& pbkdf_hash = "");
179 
180 /**
181 * Load an encrypted key from a data source.
182 * @param source the data source providing the encoded key
183 * @param rng ignored for compatibility
184 * @param get_passphrase a function that returns passphrases
185 * @return loaded private key object
186 */
187 BOTAN_PUBLIC_API(2,0) Private_Key* load_key(DataSource& source,
188                                             RandomNumberGenerator& rng,
189                                             std::function<std::string ()> get_passphrase);
190 
191 /** Load an encrypted key from a data source.
192 * @param source the data source providing the encoded key
193 * @param rng ignored for compatibility
194 * @param pass the passphrase to decrypt the key
195 * @return loaded private key object
196 */
197 BOTAN_PUBLIC_API(2,0) Private_Key* load_key(DataSource& source,
198                                             RandomNumberGenerator& rng,
199                                             const std::string& pass);
200 
201 /** Load an unencrypted key from a data source.
202 * @param source the data source providing the encoded key
203 * @param rng ignored for compatibility
204 * @return loaded private key object
205 */
206 BOTAN_PUBLIC_API(2,0) Private_Key* load_key(DataSource& source,
207                                             RandomNumberGenerator& rng);
208 
209 #if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
210 /**
211 * Load an encrypted key from a file.
212 * @param filename the path to the file containing the encoded key
213 * @param rng ignored for compatibility
214 * @param get_passphrase a function that returns passphrases
215 * @return loaded private key object
216 */
217 BOTAN_PUBLIC_API(2,0) Private_Key* load_key(const std::string& filename,
218                                             RandomNumberGenerator& rng,
219                                             std::function<std::string ()> get_passphrase);
220 
221 /** Load an encrypted key from a file.
222 * @param filename the path to the file containing the encoded key
223 * @param rng ignored for compatibility
224 * @param pass the passphrase to decrypt the key
225 * @return loaded private key object
226 */
227 BOTAN_PUBLIC_API(2,0) Private_Key* load_key(const std::string& filename,
228                                             RandomNumberGenerator& rng,
229                                             const std::string& pass);
230 
231 /** Load an unencrypted key from a file.
232 * @param filename the path to the file containing the encoded key
233 * @param rng ignored for compatibility
234 * @return loaded private key object
235 */
236 BOTAN_PUBLIC_API(2,0) Private_Key* load_key(const std::string& filename,
237                                             RandomNumberGenerator& rng);
238 #endif
239 
240 /**
241 * Copy an existing encoded key object.
242 * @param key the key to copy
243 * @param rng ignored for compatibility
244 * @return new copy of the key
245 */
246 BOTAN_PUBLIC_API(2,0) Private_Key* copy_key(const Private_Key& key,
247                                             RandomNumberGenerator& rng);
248 
249 
250 /**
251 * Load an encrypted key from a data source.
252 * @param source the data source providing the encoded key
253 * @param get_passphrase a function that returns passphrases
254 * @return loaded private key object
255 */
256 BOTAN_PUBLIC_API(2,3)
257 std::unique_ptr<Private_Key> load_key(DataSource& source,
258                                       std::function<std::string ()> get_passphrase);
259 
260 /** Load an encrypted key from a data source.
261 * @param source the data source providing the encoded key
262 * @param pass the passphrase to decrypt the key
263 * @return loaded private key object
264 */
265 BOTAN_PUBLIC_API(2,3)
266 std::unique_ptr<Private_Key> load_key(DataSource& source,
267                                       const std::string& pass);
268 
269 /** Load an unencrypted key from a data source.
270 * @param source the data source providing the encoded key
271 * @return loaded private key object
272 */
273 BOTAN_PUBLIC_API(2,3)
274 std::unique_ptr<Private_Key> load_key(DataSource& source);
275 
276 /**
277 * Copy an existing encoded key object.
278 * @param key the key to copy
279 * @return new copy of the key
280 */
281 BOTAN_PUBLIC_API(2,3)
282 std::unique_ptr<Private_Key> copy_key(const Private_Key& key);
283 
284 }
285 
286 }
287 
288 #endif
289