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