Botan  2.12.1
Crypto and TLS for C++11
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 
75 #if defined(BOTAN_HAS_OPENSSL)
76  #include <botan/internal/openssl.h>
77 #endif
78 
79 namespace Botan {
80 
81 std::unique_ptr<Public_Key>
83  const std::vector<uint8_t>& key_bits)
84  {
85  const std::string oid_str = alg_id.get_oid().to_formatted_string();
86  const std::vector<std::string> alg_info = split_on(oid_str, '/');
87  const std::string alg_name = alg_info[0];
88 
89 #if defined(BOTAN_HAS_RSA)
90  if(alg_name == "RSA")
91  return std::unique_ptr<Public_Key>(new RSA_PublicKey(alg_id, key_bits));
92 #endif
93 
94 #if defined(BOTAN_HAS_CURVE_25519)
95  if(alg_name == "Curve25519")
96  return std::unique_ptr<Public_Key>(new Curve25519_PublicKey(alg_id, key_bits));
97 #endif
98 
99 #if defined(BOTAN_HAS_MCELIECE)
100  if(alg_name == "McEliece")
101  return std::unique_ptr<Public_Key>(new McEliece_PublicKey(key_bits));
102 #endif
103 
104 #if defined(BOTAN_HAS_ECDSA)
105  if(alg_name == "ECDSA")
106  return std::unique_ptr<Public_Key>(new ECDSA_PublicKey(alg_id, key_bits));
107 #endif
108 
109 #if defined(BOTAN_HAS_ECDH)
110  if(alg_name == "ECDH")
111  return std::unique_ptr<Public_Key>(new ECDH_PublicKey(alg_id, key_bits));
112 #endif
113 
114 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
115  if(alg_name == "DH")
116  return std::unique_ptr<Public_Key>(new DH_PublicKey(alg_id, key_bits));
117 #endif
118 
119 #if defined(BOTAN_HAS_DSA)
120  if(alg_name == "DSA")
121  return std::unique_ptr<Public_Key>(new DSA_PublicKey(alg_id, key_bits));
122 #endif
123 
124 #if defined(BOTAN_HAS_ELGAMAL)
125  if(alg_name == "ElGamal")
126  return std::unique_ptr<Public_Key>(new ElGamal_PublicKey(alg_id, key_bits));
127 #endif
128 
129 #if defined(BOTAN_HAS_ECGDSA)
130  if(alg_name == "ECGDSA")
131  return std::unique_ptr<Public_Key>(new ECGDSA_PublicKey(alg_id, key_bits));
132 #endif
133 
134 #if defined(BOTAN_HAS_ECKCDSA)
135  if(alg_name == "ECKCDSA")
136  return std::unique_ptr<Public_Key>(new ECKCDSA_PublicKey(alg_id, key_bits));
137 #endif
138 
139 #if defined(BOTAN_HAS_ED25519)
140  if(alg_name == "Ed25519")
141  return std::unique_ptr<Public_Key>(new Ed25519_PublicKey(alg_id, key_bits));
142 #endif
143 
144 #if defined(BOTAN_HAS_GOST_34_10_2001)
145  if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512")
146  return std::unique_ptr<Public_Key>(new GOST_3410_PublicKey(alg_id, key_bits));
147 #endif
148 
149 #if defined(BOTAN_HAS_SM2)
150  if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc")
151  return std::unique_ptr<Public_Key>(new SM2_PublicKey(alg_id, key_bits));
152 #endif
153 
154 #if defined(BOTAN_HAS_XMSS_RFC8391)
155  if(alg_name == "XMSS")
156  return std::unique_ptr<Public_Key>(new XMSS_PublicKey(key_bits));
157 #endif
158 
159  throw Decoding_Error("Unknown or unavailable public key algorithm " + alg_name);
160  }
161 
162 std::unique_ptr<Private_Key>
164  const secure_vector<uint8_t>& key_bits)
165  {
166  const std::string alg_name = alg_id.get_oid().to_formatted_string();
167 
168 #if defined(BOTAN_HAS_RSA)
169  if(alg_name == "RSA")
170  return std::unique_ptr<Private_Key>(new RSA_PrivateKey(alg_id, key_bits));
171 #endif
172 
173 #if defined(BOTAN_HAS_CURVE_25519)
174  if(alg_name == "Curve25519")
175  return std::unique_ptr<Private_Key>(new Curve25519_PrivateKey(alg_id, key_bits));
176 #endif
177 
178 #if defined(BOTAN_HAS_ECDSA)
179  if(alg_name == "ECDSA")
180  return std::unique_ptr<Private_Key>(new ECDSA_PrivateKey(alg_id, key_bits));
181 #endif
182 
183 #if defined(BOTAN_HAS_ECDH)
184  if(alg_name == "ECDH")
185  return std::unique_ptr<Private_Key>(new ECDH_PrivateKey(alg_id, key_bits));
186 #endif
187 
188 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
189  if(alg_name == "DH")
190  return std::unique_ptr<Private_Key>(new DH_PrivateKey(alg_id, key_bits));
191 #endif
192 
193 #if defined(BOTAN_HAS_DSA)
194  if(alg_name == "DSA")
195  return std::unique_ptr<Private_Key>(new DSA_PrivateKey(alg_id, key_bits));
196 #endif
197 
198 #if defined(BOTAN_HAS_MCELIECE)
199  if(alg_name == "McEliece")
200  return std::unique_ptr<Private_Key>(new McEliece_PrivateKey(key_bits));
201 #endif
202 
203 #if defined(BOTAN_HAS_ECGDSA)
204  if(alg_name == "ECGDSA")
205  return std::unique_ptr<Private_Key>(new ECGDSA_PrivateKey(alg_id, key_bits));
206 #endif
207 
208 #if defined(BOTAN_HAS_ECKCDSA)
209  if(alg_name == "ECKCDSA")
210  return std::unique_ptr<Private_Key>(new ECKCDSA_PrivateKey(alg_id, key_bits));
211 #endif
212 
213 #if defined(BOTAN_HAS_ED25519)
214  if(alg_name == "Ed25519")
215  return std::unique_ptr<Private_Key>(new Ed25519_PrivateKey(alg_id, key_bits));
216 #endif
217 
218 #if defined(BOTAN_HAS_GOST_34_10_2001)
219  if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512")
220  return std::unique_ptr<Private_Key>(new GOST_3410_PrivateKey(alg_id, key_bits));
221 #endif
222 
223 #if defined(BOTAN_HAS_SM2)
224  if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc")
225  return std::unique_ptr<Private_Key>(new SM2_PrivateKey(alg_id, key_bits));
226 #endif
227 
228 #if defined(BOTAN_HAS_ELGAMAL)
229  if(alg_name == "ElGamal")
230  return std::unique_ptr<Private_Key>(new ElGamal_PrivateKey(alg_id, key_bits));
231 #endif
232 
233 #if defined(BOTAN_HAS_XMSS_RFC8391)
234  if(alg_name == "XMSS")
235  return std::unique_ptr<Private_Key>(new XMSS_PrivateKey(key_bits));
236 #endif
237 
238  throw Decoding_Error("Unknown or unavailable public key algorithm " + alg_name);
239  }
240 
241 #if defined(BOTAN_HAS_ECC_GROUP)
242 
243 namespace {
244 
245 std::string default_ec_group_for(const std::string& alg_name)
246  {
247  if(alg_name == "SM2" || alg_name == "SM2_Enc" || alg_name == "SM2_Sig")
248  return "sm2p256v1";
249  if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256")
250  return "gost_256A";
251  if(alg_name == "GOST-34.10-2012-512")
252  return "gost_512A";
253  if(alg_name == "ECGDSA")
254  return "brainpool256r1";
255  return "secp256r1";
256 
257  }
258 
259 }
260 
261 #endif
262 
263 std::unique_ptr<Private_Key>
264 create_private_key(const std::string& alg_name,
266  const std::string& params,
267  const std::string& provider)
268  {
269  /*
270  * Default paramaters are chosen for work factor > 2**128 where possible
271  */
272 
273 #if defined(BOTAN_HAS_CURVE_25519)
274  if(alg_name == "Curve25519")
275  return std::unique_ptr<Private_Key>(new Curve25519_PrivateKey(rng));
276 #endif
277 
278 #if defined(BOTAN_HAS_RSA)
279  if(alg_name == "RSA")
280  {
281  const size_t rsa_bits = (params.empty() ? 3072 : to_u32bit(params));
282 #if defined(BOTAN_HAS_OPENSSL)
283  if(provider.empty() || provider == "openssl")
284  {
285  std::unique_ptr<Botan::Private_Key> pk;
286  if((pk = make_openssl_rsa_private_key(rng, rsa_bits)))
287  return pk;
288 
289  if(!provider.empty())
290  return nullptr;
291  }
292 #endif
293  return std::unique_ptr<Private_Key>(new RSA_PrivateKey(rng, rsa_bits));
294  }
295 #endif
296 
297 #if defined(BOTAN_HAS_MCELIECE)
298  if(alg_name == "McEliece")
299  {
300  std::vector<std::string> mce_param =
301  Botan::split_on(params.empty() ? "2960,57" : params, ',');
302 
303  if(mce_param.size() != 2)
304  throw Invalid_Argument("create_private_key bad McEliece parameters " + params);
305 
306  size_t mce_n = Botan::to_u32bit(mce_param[0]);
307  size_t mce_t = Botan::to_u32bit(mce_param[1]);
308 
309  return std::unique_ptr<Botan::Private_Key>(new Botan::McEliece_PrivateKey(rng, mce_n, mce_t));
310  }
311 #endif
312 
313 #if defined(BOTAN_HAS_XMSS_RFC8391)
314  if(alg_name == "XMSS")
315  {
316  return std::unique_ptr<Private_Key>(
317  new XMSS_PrivateKey(XMSS_Parameters(params.empty() ? "XMSS-SHA2_10_512" : params).oid(), rng));
318  }
319 #endif
320 
321 #if defined(BOTAN_HAS_ED25519)
322  if(alg_name == "Ed25519")
323  {
324  return std::unique_ptr<Private_Key>(new Ed25519_PrivateKey(rng));
325  }
326 #endif
327 
328  // ECC crypto
329 #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
330 
331  if(alg_name == "ECDSA" ||
332  alg_name == "ECDH" ||
333  alg_name == "ECKCDSA" ||
334  alg_name == "ECGDSA" ||
335  alg_name == "SM2" ||
336  alg_name == "SM2_Sig" ||
337  alg_name == "SM2_Enc" ||
338  alg_name == "GOST-34.10" ||
339  alg_name == "GOST-34.10-2012-256" ||
340  alg_name == "GOST-34.10-2012-512")
341  {
342  const EC_Group ec_group(params.empty() ? default_ec_group_for(alg_name) : params);
343 
344 #if defined(BOTAN_HAS_ECDSA)
345  if(alg_name == "ECDSA")
346  return std::unique_ptr<Private_Key>(new ECDSA_PrivateKey(rng, ec_group));
347 #endif
348 
349 #if defined(BOTAN_HAS_ECDH)
350  if(alg_name == "ECDH")
351  return std::unique_ptr<Private_Key>(new ECDH_PrivateKey(rng, ec_group));
352 #endif
353 
354 #if defined(BOTAN_HAS_ECKCDSA)
355  if(alg_name == "ECKCDSA")
356  return std::unique_ptr<Private_Key>(new ECKCDSA_PrivateKey(rng, ec_group));
357 #endif
358 
359 #if defined(BOTAN_HAS_GOST_34_10_2001)
360  if(alg_name == "GOST-34.10" || alg_name == "GOST-34.10-2012-256" || alg_name == "GOST-34.10-2012-512")
361  return std::unique_ptr<Private_Key>(new GOST_3410_PrivateKey(rng, ec_group));
362 #endif
363 
364 #if defined(BOTAN_HAS_SM2)
365  if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc")
366  return std::unique_ptr<Private_Key>(new SM2_PrivateKey(rng, ec_group));
367 #endif
368 
369 #if defined(BOTAN_HAS_ECGDSA)
370  if(alg_name == "ECGDSA")
371  return std::unique_ptr<Private_Key>(new ECGDSA_PrivateKey(rng, ec_group));
372 #endif
373  }
374 #endif
375 
376  // DL crypto
377 #if defined(BOTAN_HAS_DL_GROUP)
378  if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal")
379  {
380  std::string default_group = (alg_name == "DSA") ? "dsa/botan/2048" : "modp/ietf/2048";
381  DL_Group modp_group(params.empty() ? default_group : params);
382 
383 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
384  if(alg_name == "DH")
385  return std::unique_ptr<Private_Key>(new DH_PrivateKey(rng, modp_group));
386 #endif
387 
388 #if defined(BOTAN_HAS_DSA)
389  if(alg_name == "DSA")
390  return std::unique_ptr<Private_Key>(new DSA_PrivateKey(rng, modp_group));
391 #endif
392 
393 #if defined(BOTAN_HAS_ELGAMAL)
394  if(alg_name == "ElGamal")
395  return std::unique_ptr<Private_Key>(new ElGamal_PrivateKey(rng, modp_group));
396 #endif
397  }
398 #endif
399 
400  BOTAN_UNUSED(alg_name, rng, params, provider);
401 
402  return std::unique_ptr<Private_Key>();
403  }
404 
405 std::vector<std::string>
406 probe_provider_private_key(const std::string& alg_name,
407  const std::vector<std::string> possible)
408  {
409  std::vector<std::string> providers;
410  for(auto&& prov : possible)
411  {
412  if(prov == "base" ||
413 #if defined(BOTAN_HAS_OPENSSL)
414  (prov == "openssl" && alg_name == "RSA") ||
415 #endif
416  0)
417  {
418  providers.push_back(prov); // available
419  }
420  }
421 
422  BOTAN_UNUSED(alg_name);
423 
424  return providers;
425  }
426 }
std::unique_ptr< Private_Key > load_private_key(const AlgorithmIdentifier &alg_id, const secure_vector< uint8_t > &key_bits)
Definition: pk_algs.cpp:163
std::vector< std::string > split_on(const std::string &str, char delim)
Definition: parsing.cpp:148
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:264
std::unique_ptr< Public_Key > load_public_key(const AlgorithmIdentifier &alg_id, const std::vector< uint8_t > &key_bits)
Definition: pk_algs.cpp:82
uint32_t to_u32bit(const std::string &str)
Definition: parsing.cpp:35
Definition: alg_id.cpp:13
#define BOTAN_UNUSED(...)
Definition: assert.h:142
std::vector< std::string > probe_provider_private_key(const std::string &alg_name, const std::vector< std::string > possible)
Definition: pk_algs.cpp:406
std::string to_formatted_string() const
Definition: asn1_oid.cpp:110
const OID & get_oid() const
Definition: alg_id.h:37
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65