Botan 2.19.3
Crypto and TLS for C&
pk_algs.cpp
Go to the documentation of this file.
1/*
2* PK Key
3* (C) 1999-2010,2016 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/pk_algs.h>
9#include <botan/parsing.h>
10
11#if defined(BOTAN_HAS_RSA)
12 #include <botan/rsa.h>
13#endif
14
15#if defined(BOTAN_HAS_DSA)
16 #include <botan/dsa.h>
17#endif
18
19#if defined(BOTAN_HAS_DL_GROUP)
20 #include <botan/dl_group.h>
21#endif
22
23#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
24 #include <botan/dh.h>
25#endif
26
27#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
28 #include <botan/ecc_key.h>
29#endif
30
31#if defined(BOTAN_HAS_ECDSA)
32 #include <botan/ecdsa.h>
33#endif
34
35#if defined(BOTAN_HAS_ECGDSA)
36 #include <botan/ecgdsa.h>
37#endif
38
39#if defined(BOTAN_HAS_ECKCDSA)
40 #include <botan/eckcdsa.h>
41#endif
42
43#if defined(BOTAN_HAS_ED25519)
44 #include <botan/ed25519.h>
45#endif
46
47#if defined(BOTAN_HAS_GOST_34_10_2001)
48 #include <botan/gost_3410.h>
49#endif
50
51#if defined(BOTAN_HAS_ELGAMAL)
52 #include <botan/elgamal.h>
53#endif
54
55#if defined(BOTAN_HAS_ECDH)
56 #include <botan/ecdh.h>
57#endif
58
59#if defined(BOTAN_HAS_CURVE_25519)
60 #include <botan/curve25519.h>
61#endif
62
63#if defined(BOTAN_HAS_MCELIECE)
64 #include <botan/mceliece.h>
65#endif
66
67#if defined(BOTAN_HAS_XMSS_RFC8391)
68 #include <botan/xmss.h>
69#endif
70
71#if defined(BOTAN_HAS_SM2)
72 #include <botan/sm2.h>
73#endif
74
75namespace Botan {
76
77std::unique_ptr<Public_Key>
79 const std::vector<uint8_t>& key_bits)
80 {
81 const std::string oid_str = alg_id.get_oid().to_formatted_string();
82 const std::vector<std::string> alg_info = split_on(oid_str, '/');
83 const std::string alg_name = alg_info[0];
84
85#if defined(BOTAN_HAS_RSA)
86 if(alg_name == "RSA")
87 return std::unique_ptr<Public_Key>(new RSA_PublicKey(alg_id, key_bits));
88#endif
89
90#if defined(BOTAN_HAS_CURVE_25519)
91 if(alg_name == "Curve25519")
92 return std::unique_ptr<Public_Key>(new Curve25519_PublicKey(alg_id, key_bits));
93#endif
94
95#if defined(BOTAN_HAS_MCELIECE)
96 if(alg_name == "McEliece")
97 return std::unique_ptr<Public_Key>(new McEliece_PublicKey(key_bits));
98#endif
99
100#if defined(BOTAN_HAS_ECDSA)
101 if(alg_name == "ECDSA")
102 return std::unique_ptr<Public_Key>(new ECDSA_PublicKey(alg_id, key_bits));
103#endif
104
105#if defined(BOTAN_HAS_ECDH)
106 if(alg_name == "ECDH")
107 return std::unique_ptr<Public_Key>(new ECDH_PublicKey(alg_id, key_bits));
108#endif
109
110#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
111 if(alg_name == "DH")
112 return std::unique_ptr<Public_Key>(new DH_PublicKey(alg_id, key_bits));
113#endif
114
115#if defined(BOTAN_HAS_DSA)
116 if(alg_name == "DSA")
117 return std::unique_ptr<Public_Key>(new DSA_PublicKey(alg_id, key_bits));
118#endif
119
120#if defined(BOTAN_HAS_ELGAMAL)
121 if(alg_name == "ElGamal")
122 return std::unique_ptr<Public_Key>(new ElGamal_PublicKey(alg_id, key_bits));
123#endif
124
125#if defined(BOTAN_HAS_ECGDSA)
126 if(alg_name == "ECGDSA")
127 return std::unique_ptr<Public_Key>(new ECGDSA_PublicKey(alg_id, key_bits));
128#endif
129
130#if defined(BOTAN_HAS_ECKCDSA)
131 if(alg_name == "ECKCDSA")
132 return std::unique_ptr<Public_Key>(new ECKCDSA_PublicKey(alg_id, key_bits));
133#endif
134
135#if defined(BOTAN_HAS_ED25519)
136 if(alg_name == "Ed25519")
137 return std::unique_ptr<Public_Key>(new Ed25519_PublicKey(alg_id, key_bits));
138#endif
139
140#if defined(BOTAN_HAS_GOST_34_10_2001)
141 if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512")
142 return std::unique_ptr<Public_Key>(new GOST_3410_PublicKey(alg_id, key_bits));
143#endif
144
145#if defined(BOTAN_HAS_SM2)
146 if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc")
147 return std::unique_ptr<Public_Key>(new SM2_PublicKey(alg_id, key_bits));
148#endif
149
150#if defined(BOTAN_HAS_XMSS_RFC8391)
151 if(alg_name == "XMSS")
152 return std::unique_ptr<Public_Key>(new XMSS_PublicKey(key_bits));
153#endif
154
155 throw Decoding_Error("Unknown or unavailable public key algorithm " + alg_name);
156 }
157
158std::unique_ptr<Private_Key>
160 const secure_vector<uint8_t>& key_bits)
161 {
162 const std::string alg_name = alg_id.get_oid().to_formatted_string();
163
164#if defined(BOTAN_HAS_RSA)
165 if(alg_name == "RSA")
166 return std::unique_ptr<Private_Key>(new RSA_PrivateKey(alg_id, key_bits));
167#endif
168
169#if defined(BOTAN_HAS_CURVE_25519)
170 if(alg_name == "Curve25519")
171 return std::unique_ptr<Private_Key>(new Curve25519_PrivateKey(alg_id, key_bits));
172#endif
173
174#if defined(BOTAN_HAS_ECDSA)
175 if(alg_name == "ECDSA")
176 return std::unique_ptr<Private_Key>(new ECDSA_PrivateKey(alg_id, key_bits));
177#endif
178
179#if defined(BOTAN_HAS_ECDH)
180 if(alg_name == "ECDH")
181 return std::unique_ptr<Private_Key>(new ECDH_PrivateKey(alg_id, key_bits));
182#endif
183
184#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
185 if(alg_name == "DH")
186 return std::unique_ptr<Private_Key>(new DH_PrivateKey(alg_id, key_bits));
187#endif
188
189#if defined(BOTAN_HAS_DSA)
190 if(alg_name == "DSA")
191 return std::unique_ptr<Private_Key>(new DSA_PrivateKey(alg_id, key_bits));
192#endif
193
194#if defined(BOTAN_HAS_MCELIECE)
195 if(alg_name == "McEliece")
196 return std::unique_ptr<Private_Key>(new McEliece_PrivateKey(key_bits));
197#endif
198
199#if defined(BOTAN_HAS_ECGDSA)
200 if(alg_name == "ECGDSA")
201 return std::unique_ptr<Private_Key>(new ECGDSA_PrivateKey(alg_id, key_bits));
202#endif
203
204#if defined(BOTAN_HAS_ECKCDSA)
205 if(alg_name == "ECKCDSA")
206 return std::unique_ptr<Private_Key>(new ECKCDSA_PrivateKey(alg_id, key_bits));
207#endif
208
209#if defined(BOTAN_HAS_ED25519)
210 if(alg_name == "Ed25519")
211 return std::unique_ptr<Private_Key>(new Ed25519_PrivateKey(alg_id, key_bits));
212#endif
213
214#if defined(BOTAN_HAS_GOST_34_10_2001)
215 if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512")
216 return std::unique_ptr<Private_Key>(new GOST_3410_PrivateKey(alg_id, key_bits));
217#endif
218
219#if defined(BOTAN_HAS_SM2)
220 if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc")
221 return std::unique_ptr<Private_Key>(new SM2_PrivateKey(alg_id, key_bits));
222#endif
223
224#if defined(BOTAN_HAS_ELGAMAL)
225 if(alg_name == "ElGamal")
226 return std::unique_ptr<Private_Key>(new ElGamal_PrivateKey(alg_id, key_bits));
227#endif
228
229#if defined(BOTAN_HAS_XMSS_RFC8391)
230 if(alg_name == "XMSS")
231 return std::unique_ptr<Private_Key>(new XMSS_PrivateKey(key_bits));
232#endif
233
234 throw Decoding_Error("Unknown or unavailable public key algorithm " + alg_name);
235 }
236
237#if defined(BOTAN_HAS_ECC_GROUP)
238
239namespace {
240
241std::string default_ec_group_for(const std::string& alg_name)
242 {
243 if(alg_name == "SM2" || alg_name == "SM2_Enc" || alg_name == "SM2_Sig")
244 return "sm2p256v1";
245 if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256")
246 return "gost_256A";
247 if(alg_name == "GOST-34.10-2012-512")
248 return "gost_512A";
249 if(alg_name == "ECGDSA")
250 return "brainpool256r1";
251 return "secp256r1";
252
253 }
254
255}
256
257#endif
258
259std::unique_ptr<Private_Key>
260create_private_key(const std::string& alg_name,
262 const std::string& params,
263 const std::string& provider)
264 {
265 /*
266 * Default paramaters are chosen for work factor > 2**128 where possible
267 */
268
269#if defined(BOTAN_HAS_CURVE_25519)
270 if(alg_name == "Curve25519")
271 return std::unique_ptr<Private_Key>(new Curve25519_PrivateKey(rng));
272#endif
273
274#if defined(BOTAN_HAS_RSA)
275 if(alg_name == "RSA")
276 {
277 const size_t rsa_bits = (params.empty() ? 3072 : to_u32bit(params));
278 return std::unique_ptr<Private_Key>(new RSA_PrivateKey(rng, rsa_bits));
279 }
280#endif
281
282#if defined(BOTAN_HAS_MCELIECE)
283 if(alg_name == "McEliece")
284 {
285 std::vector<std::string> mce_param =
286 Botan::split_on(params.empty() ? "2960,57" : params, ',');
287
288 if(mce_param.size() != 2)
289 throw Invalid_Argument("create_private_key bad McEliece parameters " + params);
290
291 size_t mce_n = Botan::to_u32bit(mce_param[0]);
292 size_t mce_t = Botan::to_u32bit(mce_param[1]);
293
294 return std::unique_ptr<Botan::Private_Key>(new Botan::McEliece_PrivateKey(rng, mce_n, mce_t));
295 }
296#endif
297
298#if defined(BOTAN_HAS_XMSS_RFC8391)
299 if(alg_name == "XMSS")
300 {
301 return std::unique_ptr<Private_Key>(
302 new XMSS_PrivateKey(XMSS_Parameters(params.empty() ? "XMSS-SHA2_10_512" : params).oid(), rng));
303 }
304#endif
305
306#if defined(BOTAN_HAS_ED25519)
307 if(alg_name == "Ed25519")
308 {
309 return std::unique_ptr<Private_Key>(new Ed25519_PrivateKey(rng));
310 }
311#endif
312
313 // ECC crypto
314#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
315
316 if(alg_name == "ECDSA" ||
317 alg_name == "ECDH" ||
318 alg_name == "ECKCDSA" ||
319 alg_name == "ECGDSA" ||
320 alg_name == "SM2" ||
321 alg_name == "SM2_Sig" ||
322 alg_name == "SM2_Enc" ||
323 alg_name == "GOST-34.10" ||
324 alg_name == "GOST-34.10-2012-256" ||
325 alg_name == "GOST-34.10-2012-512")
326 {
327 const EC_Group ec_group(params.empty() ? default_ec_group_for(alg_name) : params);
328
329#if defined(BOTAN_HAS_ECDSA)
330 if(alg_name == "ECDSA")
331 return std::unique_ptr<Private_Key>(new ECDSA_PrivateKey(rng, ec_group));
332#endif
333
334#if defined(BOTAN_HAS_ECDH)
335 if(alg_name == "ECDH")
336 return std::unique_ptr<Private_Key>(new ECDH_PrivateKey(rng, ec_group));
337#endif
338
339#if defined(BOTAN_HAS_ECKCDSA)
340 if(alg_name == "ECKCDSA")
341 return std::unique_ptr<Private_Key>(new ECKCDSA_PrivateKey(rng, ec_group));
342#endif
343
344#if defined(BOTAN_HAS_GOST_34_10_2001)
345 if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512")
346 return std::unique_ptr<Private_Key>(new GOST_3410_PrivateKey(rng, ec_group));
347#endif
348
349#if defined(BOTAN_HAS_SM2)
350 if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc")
351 return std::unique_ptr<Private_Key>(new SM2_PrivateKey(rng, ec_group));
352#endif
353
354#if defined(BOTAN_HAS_ECGDSA)
355 if(alg_name == "ECGDSA")
356 return std::unique_ptr<Private_Key>(new ECGDSA_PrivateKey(rng, ec_group));
357#endif
358 }
359#endif
360
361 // DL crypto
362#if defined(BOTAN_HAS_DL_GROUP)
363 if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal")
364 {
365 std::string default_group = (alg_name == "DSA") ? "dsa/botan/2048" : "modp/ietf/2048";
366 DL_Group modp_group(params.empty() ? default_group : params);
367
368#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
369 if(alg_name == "DH")
370 return std::unique_ptr<Private_Key>(new DH_PrivateKey(rng, modp_group));
371#endif
372
373#if defined(BOTAN_HAS_DSA)
374 if(alg_name == "DSA")
375 return std::unique_ptr<Private_Key>(new DSA_PrivateKey(rng, modp_group));
376#endif
377
378#if defined(BOTAN_HAS_ELGAMAL)
379 if(alg_name == "ElGamal")
380 return std::unique_ptr<Private_Key>(new ElGamal_PrivateKey(rng, modp_group));
381#endif
382 }
383#endif
384
385 BOTAN_UNUSED(alg_name, rng, params, provider);
386
387 return std::unique_ptr<Private_Key>();
388 }
389
390std::vector<std::string>
391probe_provider_private_key(const std::string& alg_name,
392 const std::vector<std::string> possible)
393 {
394 std::vector<std::string> providers;
395 for(auto&& prov : possible)
396 {
397 if(prov == "base")
398 {
399 providers.push_back(prov); // available
400 }
401 }
402
403 BOTAN_UNUSED(alg_name);
404
405 return providers;
406 }
407}
#define BOTAN_UNUSED(...)
Definition assert.h:142
const OID & get_oid() const
Definition asn1_obj.h:445
std::string to_formatted_string() const
Definition asn1_oid.cpp:111
std::unique_ptr< Private_Key > load_private_key(const AlgorithmIdentifier &alg_id, const secure_vector< uint8_t > &key_bits)
Definition pk_algs.cpp:159
std::vector< std::string > split_on(const std::string &str, char delim)
Definition parsing.cpp:148
std::vector< std::string > probe_provider_private_key(const std::string &alg_name, const std::vector< std::string > possible)
Definition pk_algs.cpp:391
std::unique_ptr< Private_Key > create_private_key(const std::string &alg_name, RandomNumberGenerator &rng, const std::string &params, const std::string &provider)
Definition pk_algs.cpp:260
uint32_t to_u32bit(const std::string &str)
Definition parsing.cpp:35
std::unique_ptr< Public_Key > load_public_key(const AlgorithmIdentifier &alg_id, const std::vector< uint8_t > &key_bits)
Definition pk_algs.cpp:78
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:65