Coverage Report

Created: 2021-06-10 10:30

/src/botan/build/include/botan/pkcs8.h
Line
Count
Source (jump to first uncovered line)
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 <botan/data_src.h>
15
#include <functional>
16
#include <chrono>
17
#include <memory>
18
19
namespace Botan {
20
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:
29
      explicit PKCS8_Exception(const std::string& error) :
30
251
         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
inline secure_vector<uint8_t> BER_encode(const Private_Key& key)
44
0
   {
45
0
   return key.private_key_info();
46
0
   }
47
48
/**
49
* Get a string containing a PEM encoded private key.
50
* @param key the key to encode
51
* @return encoded key
52
*/
53
BOTAN_PUBLIC_API(2,0) std::string PEM_encode(const Private_Key& key);
54
55
/**
56
* Encrypt a key using PKCS #8 encryption
57
* @param key the key to encode
58
* @param rng the rng to use
59
* @param pass the password to use for encryption
60
* @param msec number of milliseconds to run the password derivation
61
* @param pbe_algo the name of the desired password-based encryption
62
*        algorithm; if empty ("") a reasonable (portable/secure)
63
*        default will be chosen.
64
* @return encrypted key in binary BER form
65
*/
66
BOTAN_PUBLIC_API(2,0) std::vector<uint8_t>
67
BER_encode(const Private_Key& key,
68
           RandomNumberGenerator& rng,
69
           const std::string& pass,
70
           std::chrono::milliseconds msec = std::chrono::milliseconds(300),
71
           const std::string& pbe_algo = "");
72
73
/**
74
* Get a string containing a PEM encoded private key, encrypting it with a
75
* password.
76
* @param key the key to encode
77
* @param rng the rng to use
78
* @param pass the password to use for encryption
79
* @param msec number of milliseconds to run the password derivation
80
* @param pbe_algo the name of the desired password-based encryption
81
*        algorithm; if empty ("") a reasonable (portable/secure)
82
*        default will be chosen.
83
* @return encrypted key in PEM form
84
*/
85
BOTAN_PUBLIC_API(2,0) std::string
86
PEM_encode(const Private_Key& key,
87
           RandomNumberGenerator& rng,
88
           const std::string& pass,
89
           std::chrono::milliseconds msec = std::chrono::milliseconds(300),
90
           const std::string& pbe_algo = "");
91
92
/**
93
* Encrypt a key using PKCS #8 encryption and a fixed iteration count
94
* @param key the key to encode
95
* @param rng the rng to use
96
* @param pass the password to use for encryption
97
* @param pbkdf_iter number of interations to run PBKDF2
98
* @param cipher if non-empty specifies the cipher to use. CBC and GCM modes
99
*   are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC".
100
*   If empty a suitable default is chosen.
101
* @param pbkdf_hash if non-empty specifies the PBKDF hash function to use.
102
*   For example "SHA-256" or "SHA-384". If empty a suitable default is chosen.
103
* @return encrypted key in binary BER form
104
*/
105
BOTAN_PUBLIC_API(2,1) std::vector<uint8_t>
106
BER_encode_encrypted_pbkdf_iter(const Private_Key& key,
107
                                RandomNumberGenerator& rng,
108
                                const std::string& pass,
109
                                size_t pbkdf_iter,
110
                                const std::string& cipher = "",
111
                                const std::string& pbkdf_hash = "");
112
113
/**
114
* Get a string containing a PEM encoded private key, encrypting it with a
115
* password.
116
* @param key the key to encode
117
* @param rng the rng to use
118
* @param pass the password to use for encryption
119
* @param pbkdf_iter number of iterations to run PBKDF
120
* @param cipher if non-empty specifies the cipher to use. CBC and GCM modes
121
*   are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC".
122
*   If empty a suitable default is chosen.
123
* @param pbkdf_hash if non-empty specifies the PBKDF hash function to use.
124
*   For example "SHA-256" or "SHA-384". If empty a suitable default is chosen.
125
* @return encrypted key in PEM form
126
*/
127
BOTAN_PUBLIC_API(2,1) std::string
128
PEM_encode_encrypted_pbkdf_iter(const Private_Key& key,
129
                                RandomNumberGenerator& rng,
130
                                const std::string& pass,
131
                                size_t pbkdf_iter,
132
                                const std::string& cipher = "",
133
                                const std::string& pbkdf_hash = "");
134
135
/**
136
* Encrypt a key using PKCS #8 encryption and a variable iteration count
137
* @param key the key to encode
138
* @param rng the rng to use
139
* @param pass the password to use for encryption
140
* @param pbkdf_msec how long to run PBKDF2
141
* @param pbkdf_iterations if non-null, set to the number of iterations used
142
* @param cipher if non-empty specifies the cipher to use. CBC and GCM modes
143
*   are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC".
144
*   If empty a suitable default is chosen.
145
* @param pbkdf_hash if non-empty specifies the PBKDF hash function to use.
146
*   For example "SHA-256" or "SHA-384". If empty a suitable default is chosen.
147
* @return encrypted key in binary BER form
148
*/
149
BOTAN_PUBLIC_API(2,1) std::vector<uint8_t>
150
BER_encode_encrypted_pbkdf_msec(const Private_Key& key,
151
                                RandomNumberGenerator& rng,
152
                                const std::string& pass,
153
                                std::chrono::milliseconds pbkdf_msec,
154
                                size_t* pbkdf_iterations,
155
                                const std::string& cipher = "",
156
                                const std::string& pbkdf_hash = "");
157
158
/**
159
* Get a string containing a PEM encoded private key, encrypting it with a
160
* password.
161
* @param key the key to encode
162
* @param rng the rng to use
163
* @param pass the password to use for encryption
164
* @param pbkdf_msec how long in milliseconds to run PBKDF2
165
* @param pbkdf_iterations (output argument) number of iterations of PBKDF
166
*  that ended up being used
167
* @param cipher if non-empty specifies the cipher to use. CBC and GCM modes
168
*   are supported, for example "AES-128/CBC", "AES-256/GCM", "Serpent/CBC".
169
*   If empty a suitable default is chosen.
170
* @param pbkdf_hash if non-empty specifies the PBKDF hash function to use.
171
*   For example "SHA-256" or "SHA-384". If empty a suitable default is chosen.
172
* @return encrypted key in PEM form
173
*/
174
BOTAN_PUBLIC_API(2,1) std::string
175
PEM_encode_encrypted_pbkdf_msec(const Private_Key& key,
176
                                RandomNumberGenerator& rng,
177
                                const std::string& pass,
178
                                std::chrono::milliseconds pbkdf_msec,
179
                                size_t* pbkdf_iterations,
180
                                const std::string& cipher = "",
181
                                const std::string& pbkdf_hash = "");
182
183
/**
184
* Load an encrypted key from a data source.
185
* @param source the data source providing the encoded key
186
* @param get_passphrase a function that returns passphrases
187
* @return loaded private key object
188
*/
189
BOTAN_PUBLIC_API(2,3)
190
std::unique_ptr<Private_Key> load_key(DataSource& source,
191
                                      std::function<std::string ()> get_passphrase);
192
193
/** Load an encrypted key from a data source.
194
* @param source the data source providing the encoded key
195
* @param pass the passphrase to decrypt the key
196
* @return loaded private key object
197
*/
198
BOTAN_PUBLIC_API(2,3)
199
std::unique_ptr<Private_Key> load_key(DataSource& source,
200
                                      const std::string& pass);
201
202
/** Load an unencrypted key from a data source.
203
* @param source the data source providing the encoded key
204
* @return loaded private key object
205
*/
206
BOTAN_PUBLIC_API(2,3)
207
std::unique_ptr<Private_Key> load_key(DataSource& source);
208
209
/**
210
* Copy an existing encoded key object.
211
* @param key the key to copy
212
* @return new copy of the key
213
*/
214
inline std::unique_ptr<Private_Key> copy_key(const Private_Key& key)
215
0
   {
216
0
   DataSource_Memory source(key.private_key_info());
217
0
   return PKCS8::load_key(source);
218
0
   }
219
220
// Deprecated functions follow
221
222
/**
223
* Load an encrypted key from a data source.
224
* @param source the data source providing the encoded key
225
* @param rng ignored for compatibility
226
* @param get_passphrase a function that returns passphrases
227
* @return loaded private key object
228
*/
229
BOTAN_DEPRECATED("Use version that doesn't take an RNG")
230
inline Private_Key* load_key(DataSource& source,
231
                             RandomNumberGenerator& rng,
232
                             std::function<std::string ()> get_passphrase)
233
0
   {
234
0
   BOTAN_UNUSED(rng);
235
0
   return PKCS8::load_key(source, get_passphrase).release();
236
0
   }
237
238
/** Load an encrypted key from a data source.
239
* @param source the data source providing the encoded key
240
* @param rng ignored for compatibility
241
* @param pass the passphrase to decrypt the key
242
* @return loaded private key object
243
*/
244
BOTAN_DEPRECATED("Use version that doesn't take an RNG")
245
inline Private_Key* load_key(DataSource& source,
246
                             RandomNumberGenerator& rng,
247
                             const std::string& pass)
248
0
   {
249
0
   BOTAN_UNUSED(rng);
250
0
   return PKCS8::load_key(source, pass).release();
251
0
   }
252
253
/** Load an unencrypted key from a data source.
254
* @param source the data source providing the encoded key
255
* @param rng ignored for compatibility
256
* @return loaded private key object
257
*/
258
BOTAN_DEPRECATED("Use version that doesn't take an RNG")
259
inline Private_Key* load_key(DataSource& source,
260
                             RandomNumberGenerator& rng)
261
0
   {
262
0
   BOTAN_UNUSED(rng);
263
0
   return PKCS8::load_key(source).release();
264
0
   }
265
266
#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
267
/**
268
* Load an encrypted key from a file.
269
* @param filename the path to the file containing the encoded key
270
* @param rng ignored for compatibility
271
* @param get_passphrase a function that returns passphrases
272
* @return loaded private key object
273
*/
274
BOTAN_DEPRECATED("Use DataSource_Stream and another load_key variant")
275
inline Private_Key* load_key(const std::string& filename,
276
                             RandomNumberGenerator& rng,
277
                             std::function<std::string ()> get_passphrase)
278
0
   {
279
0
   BOTAN_UNUSED(rng);
280
0
   DataSource_Stream in(filename);
281
0
   return PKCS8::load_key(in, get_passphrase).release();
282
0
   }
283
284
/** Load an encrypted key from a file.
285
* @param filename the path to the file containing the encoded key
286
* @param rng ignored for compatibility
287
* @param pass the passphrase to decrypt the key
288
* @return loaded private key object
289
*/
290
BOTAN_DEPRECATED("Use DataSource_Stream and another load_key variant")
291
inline Private_Key* load_key(const std::string& filename,
292
                             RandomNumberGenerator& rng,
293
                             const std::string& pass)
294
0
   {
295
0
   BOTAN_UNUSED(rng);
296
0
   DataSource_Stream in(filename);
297
0
   // We need to use bind rather than a lambda capturing `pass` here in order to avoid a Clang 8 bug.
298
0
   // See https://github.com/randombit/botan/issues/2255.
299
0
   return PKCS8::load_key(in, std::bind([](const std::string p) { return p; }, pass)).release();
300
0
   }
301
302
/** Load an unencrypted key from a file.
303
* @param filename the path to the file containing the encoded key
304
* @param rng ignored for compatibility
305
* @return loaded private key object
306
*/
307
BOTAN_DEPRECATED("Use DataSource_Stream and another load_key variant")
308
inline Private_Key* load_key(const std::string& filename,
309
                             RandomNumberGenerator& rng)
310
0
   {
311
0
   BOTAN_UNUSED(rng);
312
0
   DataSource_Stream in(filename);
313
0
   return PKCS8::load_key(in).release();
314
0
   }
315
#endif
316
317
/**
318
* Copy an existing encoded key object.
319
* @param key the key to copy
320
* @param rng ignored for compatibility
321
* @return new copy of the key
322
*/
323
BOTAN_DEPRECATED("Use version that doesn't take an RNG")
324
inline Private_Key* copy_key(const Private_Key& key,
325
                             RandomNumberGenerator& rng)
326
0
   {
327
0
   BOTAN_UNUSED(rng);
328
0
   return PKCS8::copy_key(key).release();
329
0
   }
330
331
}
332
333
}
334
335
#endif