8 #include <botan/pk_algs.h>
9 #include <botan/parsing.h>
11 #if defined(BOTAN_HAS_RSA)
12 #include <botan/rsa.h>
15 #if defined(BOTAN_HAS_DSA)
16 #include <botan/dsa.h>
19 #if defined(BOTAN_HAS_DL_GROUP)
20 #include <botan/dl_group.h>
23 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
27 #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
28 #include <botan/ecc_key.h>
31 #if defined(BOTAN_HAS_ECDSA)
32 #include <botan/ecdsa.h>
35 #if defined(BOTAN_HAS_ECGDSA)
36 #include <botan/ecgdsa.h>
39 #if defined(BOTAN_HAS_ECKCDSA)
40 #include <botan/eckcdsa.h>
43 #if defined(BOTAN_HAS_ED25519)
44 #include <botan/ed25519.h>
47 #if defined(BOTAN_HAS_GOST_34_10_2001)
48 #include <botan/gost_3410.h>
51 #if defined(BOTAN_HAS_ELGAMAL)
52 #include <botan/elgamal.h>
55 #if defined(BOTAN_HAS_ECDH)
56 #include <botan/ecdh.h>
59 #if defined(BOTAN_HAS_CURVE_25519)
60 #include <botan/curve25519.h>
63 #if defined(BOTAN_HAS_MCELIECE)
64 #include <botan/mceliece.h>
67 #if defined(BOTAN_HAS_XMSS_RFC8391)
68 #include <botan/xmss.h>
71 #if defined(BOTAN_HAS_SM2)
72 #include <botan/sm2.h>
75 #if defined(BOTAN_HAS_OPENSSL)
76 #include <botan/internal/openssl.h>
81 std::unique_ptr<Public_Key>
83 const std::vector<uint8_t>& key_bits)
86 const std::vector<std::string> alg_info =
split_on(oid_str,
'/');
87 const std::string alg_name = alg_info[0];
89 #if defined(BOTAN_HAS_RSA)
91 return std::unique_ptr<Public_Key>(
new RSA_PublicKey(alg_id, key_bits));
94 #if defined(BOTAN_HAS_CURVE_25519)
95 if(alg_name ==
"Curve25519")
99 #if defined(BOTAN_HAS_MCELIECE)
100 if(alg_name ==
"McEliece")
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));
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));
114 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
116 return std::unique_ptr<Public_Key>(
new DH_PublicKey(alg_id, key_bits));
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));
124 #if defined(BOTAN_HAS_ELGAMAL)
125 if(alg_name ==
"ElGamal")
129 #if defined(BOTAN_HAS_ECGDSA)
130 if(alg_name ==
"ECGDSA")
134 #if defined(BOTAN_HAS_ECKCDSA)
135 if(alg_name ==
"ECKCDSA")
139 #if defined(BOTAN_HAS_ED25519)
140 if(alg_name ==
"Ed25519")
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")
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));
154 #if defined(BOTAN_HAS_XMSS_RFC8391)
155 if(alg_name ==
"XMSS")
159 throw Decoding_Error(
"Unknown or unavailable public key algorithm " + alg_name);
162 std::unique_ptr<Private_Key>
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));
173 #if defined(BOTAN_HAS_CURVE_25519)
174 if(alg_name ==
"Curve25519")
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));
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));
188 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
190 return std::unique_ptr<Private_Key>(
new DH_PrivateKey(alg_id, key_bits));
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));
198 #if defined(BOTAN_HAS_MCELIECE)
199 if(alg_name ==
"McEliece")
203 #if defined(BOTAN_HAS_ECGDSA)
204 if(alg_name ==
"ECGDSA")
208 #if defined(BOTAN_HAS_ECKCDSA)
209 if(alg_name ==
"ECKCDSA")
213 #if defined(BOTAN_HAS_ED25519)
214 if(alg_name ==
"Ed25519")
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")
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));
228 #if defined(BOTAN_HAS_ELGAMAL)
229 if(alg_name ==
"ElGamal")
233 #if defined(BOTAN_HAS_XMSS_RFC8391)
234 if(alg_name ==
"XMSS")
238 throw Decoding_Error(
"Unknown or unavailable public key algorithm " + alg_name);
241 #if defined(BOTAN_HAS_ECC_GROUP)
245 std::string default_ec_group_for(
const std::string& alg_name)
247 if(alg_name ==
"SM2" || alg_name ==
"SM2_Enc" || alg_name ==
"SM2_Sig")
249 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256")
251 if(alg_name ==
"GOST-34.10-2012-512")
253 if(alg_name ==
"ECGDSA")
254 return "brainpool256r1";
263 std::unique_ptr<Private_Key>
266 const std::string& params,
267 const std::string& provider)
273 #if defined(BOTAN_HAS_CURVE_25519)
274 if(alg_name ==
"Curve25519")
278 #if defined(BOTAN_HAS_RSA)
279 if(alg_name ==
"RSA")
281 const size_t rsa_bits = (params.empty() ? 3072 :
to_u32bit(params));
282 #if defined(BOTAN_HAS_OPENSSL)
283 if(provider.empty() || provider ==
"openssl")
285 std::unique_ptr<Botan::Private_Key> pk;
286 if((pk = make_openssl_rsa_private_key(rng, rsa_bits)))
289 if(!provider.empty())
293 return std::unique_ptr<Private_Key>(
new RSA_PrivateKey(rng, rsa_bits));
297 #if defined(BOTAN_HAS_MCELIECE)
298 if(alg_name ==
"McEliece")
300 std::vector<std::string> mce_param =
303 if(mce_param.size() != 2)
304 throw Invalid_Argument(
"create_private_key bad McEliece parameters " + params);
313 #if defined(BOTAN_HAS_XMSS_RFC8391)
314 if(alg_name ==
"XMSS")
316 return std::unique_ptr<Private_Key>(
321 #if defined(BOTAN_HAS_ED25519)
322 if(alg_name ==
"Ed25519")
329 #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
331 if(alg_name ==
"ECDSA" ||
332 alg_name ==
"ECDH" ||
333 alg_name ==
"ECKCDSA" ||
334 alg_name ==
"ECGDSA" ||
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")
342 const EC_Group ec_group(params.empty() ? default_ec_group_for(alg_name) : params);
344 #if defined(BOTAN_HAS_ECDSA)
345 if(alg_name ==
"ECDSA")
349 #if defined(BOTAN_HAS_ECDH)
350 if(alg_name ==
"ECDH")
351 return std::unique_ptr<Private_Key>(
new ECDH_PrivateKey(rng, ec_group));
354 #if defined(BOTAN_HAS_ECKCDSA)
355 if(alg_name ==
"ECKCDSA")
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")
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));
369 #if defined(BOTAN_HAS_ECGDSA)
370 if(alg_name ==
"ECGDSA")
377 #if defined(BOTAN_HAS_DL_GROUP)
378 if(alg_name ==
"DH" || alg_name ==
"DSA" || alg_name ==
"ElGamal")
380 std::string default_group = (alg_name ==
"DSA") ?
"dsa/botan/2048" :
"modp/ietf/2048";
381 DL_Group modp_group(params.empty() ? default_group : params);
383 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
385 return std::unique_ptr<Private_Key>(
new DH_PrivateKey(rng, modp_group));
388 #if defined(BOTAN_HAS_DSA)
389 if(alg_name ==
"DSA")
390 return std::unique_ptr<Private_Key>(
new DSA_PrivateKey(rng, modp_group));
393 #if defined(BOTAN_HAS_ELGAMAL)
394 if(alg_name ==
"ElGamal")
402 return std::unique_ptr<Private_Key>();
405 std::vector<std::string>
407 const std::vector<std::string> possible)
409 std::vector<std::string> providers;
410 for(
auto&& prov : possible)
413 #
if defined(BOTAN_HAS_OPENSSL)
414 (prov ==
"openssl" && alg_name ==
"RSA") ||
418 providers.push_back(prov);
std::unique_ptr< Private_Key > load_private_key(const AlgorithmIdentifier &alg_id, const secure_vector< uint8_t > &key_bits)
std::vector< std::string > split_on(const std::string &str, char delim)
std::unique_ptr< Private_Key > create_private_key(const std::string &alg_name, RandomNumberGenerator &rng, const std::string ¶ms, const std::string &provider)
std::unique_ptr< Public_Key > load_public_key(const AlgorithmIdentifier &alg_id, const std::vector< uint8_t > &key_bits)
std::string to_formatted_string() const
uint32_t to_u32bit(const std::string &str)
std::vector< T, secure_allocator< T >> secure_vector
const OID & get_oid() const
#define BOTAN_UNUSED(...)
std::vector< std::string > probe_provider_private_key(const std::string &alg_name, const std::vector< std::string > possible)