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