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