Botan  1.11.34
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 
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_DIFFIE_HELLMAN)
20  #include <botan/dh.h>
21 #endif
22 
23 #if defined(BOTAN_HAS_ECDSA)
24  #include <botan/ecdsa.h>
25 #endif
26 
27 #if defined(BOTAN_HAS_ECGDSA)
28  #include <botan/ecgdsa.h>
29 #endif
30 
31 #if defined(BOTAN_HAS_ECKCDSA)
32  #include <botan/eckcdsa.h>
33 #endif
34 
35 #if defined(BOTAN_HAS_GOST_34_10_2001)
36  #include <botan/gost_3410.h>
37 #endif
38 
39 #if defined(BOTAN_HAS_ELGAMAL)
40  #include <botan/elgamal.h>
41 #endif
42 
43 #if defined(BOTAN_HAS_ECDH)
44  #include <botan/ecdh.h>
45 #endif
46 
47 #if defined(BOTAN_HAS_CURVE_25519)
48  #include <botan/curve25519.h>
49 #endif
50 
51 #if defined(BOTAN_HAS_MCELIECE)
52  #include <botan/mceliece.h>
53 #endif
54 
55 #if defined(BOTAN_HAS_XMSS)
56  #include <botan/xmss.h>
57 #endif
58 
59 namespace Botan {
60 
61 std::unique_ptr<Public_Key>
63  const secure_vector<byte>& key_bits)
64  {
65  const std::string alg_name = OIDS::lookup(alg_id.oid);
66  if(alg_name == "")
67  throw Decoding_Error("Unknown algorithm OID: " + alg_id.oid.as_string());
68 
69 #if defined(BOTAN_HAS_RSA)
70  if(alg_name == "RSA")
71  return std::unique_ptr<Public_Key>(new RSA_PublicKey(alg_id, key_bits));
72 #endif
73 
74 #if defined(BOTAN_HAS_CURVE_25519)
75  if(alg_name == "Curve25519")
76  return std::unique_ptr<Public_Key>(new Curve25519_PublicKey(alg_id, key_bits));
77 #endif
78 
79 #if defined(BOTAN_HAS_MCELIECE)
80  if(alg_name == "McEliece")
81  return std::unique_ptr<Public_Key>(new McEliece_PublicKey(unlock(key_bits)));
82 #endif
83 
84 #if defined(BOTAN_HAS_ECDSA)
85  if(alg_name == "ECDSA")
86  return std::unique_ptr<Public_Key>(new ECDSA_PublicKey(alg_id, key_bits));
87 #endif
88 
89 #if defined(BOTAN_HAS_ECDH)
90  if(alg_name == "ECDH")
91  return std::unique_ptr<Public_Key>(new ECDH_PublicKey(alg_id, key_bits));
92 #endif
93 
94 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
95  if(alg_name == "DH")
96  return std::unique_ptr<Public_Key>(new DH_PublicKey(alg_id, key_bits));
97 #endif
98 
99 #if defined(BOTAN_HAS_DSA)
100  if(alg_name == "DSA")
101  return std::unique_ptr<Public_Key>(new DSA_PublicKey(alg_id, key_bits));
102 #endif
103 
104 #if defined(BOTAN_HAS_ELGAMAL)
105  if(alg_name == "ElGamal")
106  return std::unique_ptr<Public_Key>(new ElGamal_PublicKey(alg_id, key_bits));
107 #endif
108 
109 #if defined(BOTAN_HAS_ECGDSA)
110  if(alg_name == "ECGDSA")
111  return std::unique_ptr<Public_Key>(new ECGDSA_PublicKey(alg_id, key_bits));
112 #endif
113 
114 #if defined(BOTAN_HAS_ECKCDSA)
115  if(alg_name == "ECKCDSA")
116  return std::unique_ptr<Public_Key>(new ECKCDSA_PublicKey(alg_id, key_bits));
117 #endif
118 
119 #if defined(BOTAN_HAS_GOST_34_10_2001)
120  if(alg_name == "GOST-34.10")
121  return std::unique_ptr<Public_Key>(new GOST_3410_PublicKey(alg_id, key_bits));
122 #endif
123 
124 #if defined(BOTAN_HAS_XMSS)
125  if(alg_name == "XMSS")
126  return std::unique_ptr<Public_Key>(new XMSS_PublicKey(key_bits));
127 #endif
128 
129  throw Decoding_Error("Unhandled PK algorithm " + alg_name);
130  }
131 
132 std::unique_ptr<Private_Key>
134  const secure_vector<byte>& key_bits)
135  {
136  const std::string alg_name = OIDS::lookup(alg_id.oid);
137  if(alg_name == "")
138  throw Decoding_Error("Unknown algorithm OID: " + alg_id.oid.as_string());
139 
140 #if defined(BOTAN_HAS_RSA)
141  if(alg_name == "RSA")
142  return std::unique_ptr<Private_Key>(new RSA_PrivateKey(alg_id, key_bits));
143 #endif
144 
145 #if defined(BOTAN_HAS_CURVE_25519)
146  if(alg_name == "Curve25519")
147  return std::unique_ptr<Private_Key>(new Curve25519_PrivateKey(alg_id, key_bits));
148 #endif
149 
150 #if defined(BOTAN_HAS_ECDSA)
151  if(alg_name == "ECDSA")
152  return std::unique_ptr<Private_Key>(new ECDSA_PrivateKey(alg_id, key_bits));
153 #endif
154 
155 #if defined(BOTAN_HAS_ECDH)
156  if(alg_name == "ECDH")
157  return std::unique_ptr<Private_Key>(new ECDH_PrivateKey(alg_id, key_bits));
158 #endif
159 
160 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
161  if(alg_name == "DH")
162  return std::unique_ptr<Private_Key>(new DH_PrivateKey(alg_id, key_bits));
163 #endif
164 
165 #if defined(BOTAN_HAS_DSA)
166  if(alg_name == "DSA")
167  return std::unique_ptr<Private_Key>(new DSA_PrivateKey(alg_id, key_bits));
168 #endif
169 
170 #if defined(BOTAN_HAS_MCELIECE)
171  if(alg_name == "McEliece")
172  return std::unique_ptr<Private_Key>(new McEliece_PrivateKey(key_bits));
173 #endif
174 
175 #if defined(BOTAN_HAS_ECGDSA)
176  if(alg_name == "ECGDSA")
177  return std::unique_ptr<Private_Key>(new ECGDSA_PrivateKey(alg_id, key_bits));
178 #endif
179 
180 #if defined(BOTAN_HAS_ECKCDSA)
181  if(alg_name == "ECKCDSA")
182  return std::unique_ptr<Private_Key>(new ECKCDSA_PrivateKey(alg_id, key_bits));
183 #endif
184 
185 #if defined(BOTAN_HAS_GOST_34_10_2001)
186  if(alg_name == "GOST-34.10")
187  return std::unique_ptr<Private_Key>(new GOST_3410_PrivateKey(alg_id, key_bits));
188 #endif
189 
190 #if defined(BOTAN_HAS_ELGAMAL)
191  if(alg_name == "ElGamal")
192  return std::unique_ptr<Private_Key>(new ElGamal_PrivateKey(alg_id, key_bits));
193 #endif
194 
195 #if defined(BOTAN_HAS_XMSS)
196  if(alg_name == "XMSS")
197  return std::unique_ptr<Private_Key>(new XMSS_PrivateKey(key_bits));
198 #endif
199 
200  throw Decoding_Error("Unhandled PK algorithm " + alg_name);
201  }
202 
203 std::unique_ptr<Private_Key>
204 create_private_key(const std::string& alg_name,
206  const std::string& params)
207  {
208  /*
209  * Default paramaters are chosen for work factor > 2**128 where possible
210  */
211 
212 #if defined(BOTAN_HAS_CURVE_25519)
213  if(alg_name == "Curve25519")
214  return std::unique_ptr<Private_Key>(new Curve25519_PrivateKey(rng));
215 #endif
216 
217 #if defined(BOTAN_HAS_RSA)
218  if(alg_name == "RSA")
219  {
220  const size_t rsa_bits = (params.empty() ? 3072 : to_u32bit(params));
221  return std::unique_ptr<Private_Key>(new RSA_PrivateKey(rng, rsa_bits));
222  }
223 #endif
224 
225 #if defined(BOTAN_HAS_MCELIECE)
226  if(alg_name == "McEliece")
227  {
228  std::vector<std::string> mce_param =
229  Botan::split_on(params.empty() ? "2960,57" : params, ',');
230 
231  if(mce_param.size() != 2)
232  throw Invalid_Argument("create_private_key bad McEliece parameters " + params);
233 
234  size_t mce_n = Botan::to_u32bit(mce_param[0]);
235  size_t mce_t = Botan::to_u32bit(mce_param[1]);
236 
237  return std::unique_ptr<Botan::Private_Key>(new Botan::McEliece_PrivateKey(rng, mce_n, mce_t));
238  }
239 #endif
240 
241 #if defined(BOTAN_HAS_XMSS)
242  if(alg_name == "XMSS")
243  {
244  return std::unique_ptr<Private_Key>(
245  new XMSS_PrivateKey(XMSS_Parameters(params.empty() ? "XMSS_SHA2-512_W16_H10" : params).oid(), rng));
246  }
247 #endif
248 
249  // ECC crypto
250 #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
251 
252  if(alg_name == "ECDSA" ||
253  alg_name == "ECDH" ||
254  alg_name == "ECKCDSA" ||
255  alg_name == "ECGDSA" ||
256  alg_name == "GOST-34.10")
257  {
258  const EC_Group ec_group(params.empty() ? "secp256r1" : params);
259 
260 #if defined(BOTAN_HAS_ECDSA)
261  if(alg_name == "ECDSA")
262  return std::unique_ptr<Private_Key>(new ECDSA_PrivateKey(rng, ec_group));
263 #endif
264 
265 #if defined(BOTAN_HAS_ECDH)
266  if(alg_name == "ECDH")
267  return std::unique_ptr<Private_Key>(new ECDH_PrivateKey(rng, ec_group));
268 #endif
269 
270 #if defined(BOTAN_HAS_ECKCDSA)
271  if(alg_name == "ECKCDSA")
272  return std::unique_ptr<Private_Key>(new ECKCDSA_PrivateKey(rng, ec_group));
273 #endif
274 
275 #if defined(BOTAN_HAS_GOST_34_10_2001)
276  if(alg_name == "GOST-34.10")
277  return std::unique_ptr<Private_Key>(new GOST_3410_PrivateKey(rng, ec_group));
278 #endif
279 
280 #if defined(BOTAN_HAS_ECGDSA)
281  if(alg_name == "ECGDSA")
282  return std::unique_ptr<Private_Key>(new ECGDSA_PrivateKey(rng, ec_group));
283 #endif
284  }
285 #endif
286 
287  // DL crypto
288 #if defined(BOTAN_HAS_DL_GROUP)
289  if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal")
290  {
291  std::string default_group = (alg_name == "DSA") ? "dsa/botan/2048" : "modp/ietf/2048";
292  DL_Group modp_group(params.empty() ? default_group : params);
293 
294 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
295  if(alg_name == "DH")
296  return std::unique_ptr<Private_Key>(new DH_PrivateKey(rng, modp_group));
297 #endif
298 
299 #if defined(BOTAN_HAS_DSA)
300  if(alg_name == "DSA")
301  return std::unique_ptr<Private_Key>(new DSA_PrivateKey(rng, modp_group));
302 #endif
303 
304 #if defined(BOTAN_HAS_ELGAMAL)
305  if(alg_name == "ElGamal")
306  return std::unique_ptr<Private_Key>(new ElGamal_PrivateKey(rng, modp_group));
307 #endif
308  }
309 #endif
310 
311  return std::unique_ptr<Private_Key>();
312  }
313 
314 }
std::string as_string() const
Definition: asn1_oid.cpp:50
std::vector< std::string > split_on(const std::string &str, char delim)
Definition: parsing.cpp:138
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:113
std::unique_ptr< Private_Key > load_private_key(const AlgorithmIdentifier &alg_id, const secure_vector< byte > &key_bits)
Definition: pk_algs.cpp:133
std::string lookup(const OID &oid)
Definition: oids.cpp:18
Definition: alg_id.cpp:13
std::vector< T > unlock(const secure_vector< T > &in)
Definition: secmem.h:117
std::unique_ptr< Public_Key > load_public_key(const AlgorithmIdentifier &alg_id, const secure_vector< byte > &key_bits)
Definition: pk_algs.cpp:62
u32bit to_u32bit(const std::string &str)
Definition: parsing.cpp:18
std::unique_ptr< Private_Key > create_private_key(const std::string &alg_name, RandomNumberGenerator &rng, const std::string &params)
Definition: pk_algs.cpp:204