8#include <botan/pk_algs.h>
9#include <botan/internal/parsing.h>
10#include <botan/internal/fmt.h>
12#if defined(BOTAN_HAS_RSA)
13 #include <botan/rsa.h>
16#if defined(BOTAN_HAS_DSA)
17 #include <botan/dsa.h>
20#if defined(BOTAN_HAS_DL_GROUP)
21 #include <botan/dl_group.h>
24#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
28#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
29 #include <botan/ecc_key.h>
32#if defined(BOTAN_HAS_ECDSA)
33 #include <botan/ecdsa.h>
36#if defined(BOTAN_HAS_ECGDSA)
37 #include <botan/ecgdsa.h>
40#if defined(BOTAN_HAS_ECKCDSA)
41 #include <botan/eckcdsa.h>
44#if defined(BOTAN_HAS_ED25519)
45 #include <botan/ed25519.h>
48#if defined(BOTAN_HAS_GOST_34_10_2001)
49 #include <botan/gost_3410.h>
52#if defined(BOTAN_HAS_ELGAMAL)
53 #include <botan/elgamal.h>
56#if defined(BOTAN_HAS_ECDH)
57 #include <botan/ecdh.h>
60#if defined(BOTAN_HAS_CURVE_25519)
61 #include <botan/curve25519.h>
64#if defined(BOTAN_HAS_MCELIECE)
65 #include <botan/mceliece.h>
68#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
69 #include <botan/kyber.h>
72#if defined(BOTAN_HAS_XMSS_RFC8391)
73 #include <botan/xmss.h>
76#if defined(BOTAN_HAS_SM2)
77 #include <botan/sm2.h>
80#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
81 #include <botan/dilithium.h>
86std::unique_ptr<Public_Key>
88 [[maybe_unused]] std::span<const uint8_t> key_bits)
91 const std::vector<std::string> alg_info =
split_on(oid_str,
'/');
92 std::string_view alg_name = alg_info[0];
94#if defined(BOTAN_HAS_RSA)
96 return std::make_unique<RSA_PublicKey>(alg_id, key_bits);
99#if defined(BOTAN_HAS_CURVE_25519)
100 if(alg_name ==
"Curve25519")
101 return std::make_unique<Curve25519_PublicKey>(alg_id, key_bits);
104#if defined(BOTAN_HAS_MCELIECE)
105 if(alg_name ==
"McEliece")
106 return std::make_unique<McEliece_PublicKey>(key_bits);
109#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
110 if(alg_name ==
"Kyber" || alg_name.starts_with(
"Kyber-"))
111 return std::make_unique<Kyber_PublicKey>(alg_id, key_bits);
114#if defined(BOTAN_HAS_ECDSA)
115 if(alg_name ==
"ECDSA")
116 return std::make_unique<ECDSA_PublicKey>(alg_id, key_bits);
119#if defined(BOTAN_HAS_ECDH)
120 if(alg_name ==
"ECDH")
121 return std::make_unique<ECDH_PublicKey>(alg_id, key_bits);
124#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
126 return std::make_unique<DH_PublicKey>(alg_id, key_bits);
129#if defined(BOTAN_HAS_DSA)
130 if(alg_name ==
"DSA")
131 return std::make_unique<DSA_PublicKey>(alg_id, key_bits);
134#if defined(BOTAN_HAS_ELGAMAL)
135 if(alg_name ==
"ElGamal")
136 return std::make_unique<ElGamal_PublicKey>(alg_id, key_bits);
139#if defined(BOTAN_HAS_ECGDSA)
140 if(alg_name ==
"ECGDSA")
141 return std::make_unique<ECGDSA_PublicKey>(alg_id, key_bits);
144#if defined(BOTAN_HAS_ECKCDSA)
145 if(alg_name ==
"ECKCDSA")
146 return std::make_unique<ECKCDSA_PublicKey>(alg_id, key_bits);
149#if defined(BOTAN_HAS_ED25519)
150 if(alg_name ==
"Ed25519")
151 return std::make_unique<Ed25519_PublicKey>(alg_id, key_bits);
154#if defined(BOTAN_HAS_GOST_34_10_2001)
155 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" || alg_name ==
"GOST-34.10-2012-512")
156 return std::make_unique<GOST_3410_PublicKey>(alg_id, key_bits);
159#if defined(BOTAN_HAS_SM2)
160 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc")
161 return std::make_unique<SM2_PublicKey>(alg_id, key_bits);
164#if defined(BOTAN_HAS_XMSS_RFC8391)
165 if(alg_name ==
"XMSS")
166 return std::make_unique<XMSS_PublicKey>(key_bits);
169#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
170 if(alg_name ==
"Dilithium" || alg_name.starts_with(
"Dilithium-"))
171 return std::make_unique<Dilithium_PublicKey>(alg_id, key_bits);
174 throw Decoding_Error(
fmt(
"Unknown or unavailable public key algorithm '{}'", alg_name));
177std::unique_ptr<Private_Key>
179 [[maybe_unused]] std::span<const uint8_t> key_bits)
182 const std::vector<std::string> alg_info =
split_on(oid_str,
'/');
183 std::string_view alg_name = alg_info[0];
185#if defined(BOTAN_HAS_RSA)
186 if(alg_name ==
"RSA")
187 return std::make_unique<RSA_PrivateKey>(alg_id, key_bits);
190#if defined(BOTAN_HAS_CURVE_25519)
191 if(alg_name ==
"Curve25519")
192 return std::make_unique<Curve25519_PrivateKey>(alg_id, key_bits);
195#if defined(BOTAN_HAS_ECDSA)
196 if(alg_name ==
"ECDSA")
197 return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits);
200#if defined(BOTAN_HAS_ECDH)
201 if(alg_name ==
"ECDH")
202 return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits);
205#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
207 return std::make_unique<DH_PrivateKey>(alg_id, key_bits);
210#if defined(BOTAN_HAS_DSA)
211 if(alg_name ==
"DSA")
212 return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
215#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
216 if(alg_name ==
"Kyber" || alg_name.starts_with(
"Kyber-"))
217 return std::make_unique<Kyber_PrivateKey>(alg_id, key_bits);
220#if defined(BOTAN_HAS_MCELIECE)
221 if(alg_name ==
"McEliece")
222 return std::make_unique<McEliece_PrivateKey>(key_bits);
225#if defined(BOTAN_HAS_ECGDSA)
226 if(alg_name ==
"ECGDSA")
227 return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits);
230#if defined(BOTAN_HAS_ECKCDSA)
231 if(alg_name ==
"ECKCDSA")
232 return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits);
235#if defined(BOTAN_HAS_ED25519)
236 if(alg_name ==
"Ed25519")
237 return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits);
240#if defined(BOTAN_HAS_GOST_34_10_2001)
241 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" || alg_name ==
"GOST-34.10-2012-512")
242 return std::make_unique<GOST_3410_PrivateKey>(alg_id, key_bits);
245#if defined(BOTAN_HAS_SM2)
246 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc")
247 return std::make_unique<SM2_PrivateKey>(alg_id, key_bits);
250#if defined(BOTAN_HAS_ELGAMAL)
251 if(alg_name ==
"ElGamal")
252 return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits);
255#if defined(BOTAN_HAS_XMSS_RFC8391)
256 if(alg_name ==
"XMSS")
257 return std::make_unique<XMSS_PrivateKey>(key_bits);
260#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
261 if(alg_name ==
"Dilithium" || alg_name.starts_with(
"Dilithium-"))
262 return std::make_unique<Dilithium_PrivateKey>(alg_id, key_bits);
265 throw Decoding_Error(
fmt(
"Unknown or unavailable public key algorithm '{}'", alg_name));
276#if defined(BOTAN_HAS_ECDSA)
277 if(alg_name ==
"ECDSA")
278 return std::make_unique<ECDSA_PrivateKey>(rng, ec_group);
281#if defined(BOTAN_HAS_ECDH)
282 if(alg_name ==
"ECDH")
283 return std::make_unique<ECDH_PrivateKey>(rng, ec_group);
286#if defined(BOTAN_HAS_ECKCDSA)
287 if(alg_name ==
"ECKCDSA")
288 return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group);
291#if defined(BOTAN_HAS_GOST_34_10_2001)
292 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" || alg_name ==
"GOST-34.10-2012-512")
293 return std::make_unique<GOST_3410_PrivateKey>(rng, ec_group);
296#if defined(BOTAN_HAS_SM2)
297 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc")
298 return std::make_unique<SM2_PrivateKey>(rng, ec_group);
301#if defined(BOTAN_HAS_ECGDSA)
302 if(alg_name ==
"ECGDSA")
303 return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group);
310std::unique_ptr<Private_Key>
313 std::string_view params,
314 std::string_view provider)
320#if defined(BOTAN_HAS_CURVE_25519)
321 if(alg_name ==
"Curve25519")
322 return std::make_unique<Curve25519_PrivateKey>(rng);
325#if defined(BOTAN_HAS_RSA)
326 if(alg_name ==
"RSA")
328 const size_t modulus_bits = params.empty() ? 3072 :
to_u32bit(params);
329 return std::make_unique<RSA_PrivateKey>(rng, modulus_bits);
333#if defined(BOTAN_HAS_MCELIECE)
334 if(alg_name ==
"McEliece")
336 const auto [n, t] = [&]() -> std::pair<size_t, size_t>
341 const auto mce_params =
split_on(params,
',');
343 if(mce_params.size() != 2)
345 throw Invalid_Argument(
fmt(
"create_private_key: invalid McEliece parameters '{}'", params));
348 const size_t mce_n =
to_u32bit(mce_params[0]);
349 const size_t mce_t =
to_u32bit(mce_params[1]);
350 return {mce_n, mce_t};
353 return std::make_unique<McEliece_PrivateKey>(rng, n, t);
357#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
358 if(alg_name ==
"Kyber")
367 return std::make_unique<Kyber_PrivateKey>(rng, mode);
371#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
372 if(alg_name ==
"Dilithium" || alg_name ==
"Dilithium-")
381 return std::make_unique<Dilithium_PrivateKey>(rng, mode);
385#if defined(BOTAN_HAS_XMSS_RFC8391)
386 if(alg_name ==
"XMSS")
395 return std::make_unique<XMSS_PrivateKey>(xmss_oid, rng);
399#if defined(BOTAN_HAS_ED25519)
400 if(alg_name ==
"Ed25519")
402 return std::make_unique<Ed25519_PrivateKey>(rng);
407#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
409 if(alg_name ==
"ECDSA" ||
410 alg_name ==
"ECDH" ||
411 alg_name ==
"ECKCDSA" ||
412 alg_name ==
"ECGDSA" ||
414 alg_name ==
"SM2_Sig" ||
415 alg_name ==
"SM2_Enc" ||
416 alg_name ==
"GOST-34.10" ||
417 alg_name ==
"GOST-34.10-2012-256" ||
418 alg_name ==
"GOST-34.10-2012-512")
420 const std::string group_id = [&]() -> std::string
423 return std::string(params);
424 if(alg_name ==
"SM2" || alg_name ==
"SM2_Enc" || alg_name ==
"SM2_Sig")
426 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256")
428 if(alg_name ==
"GOST-34.10-2012-512")
430 if(alg_name ==
"ECGDSA")
431 return "brainpool256r1";
441#if defined(BOTAN_HAS_DL_GROUP)
442 if(alg_name ==
"DH" || alg_name ==
"DSA" || alg_name ==
"ElGamal")
444 const std::string group_id = [&]() -> std::string
447 return std::string(params);
448 if(alg_name ==
"DSA")
449 return "dsa/botan/2048";
450 return "modp/ietf/2048";
455#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
457 return std::make_unique<DH_PrivateKey>(rng, modp_group);
460#if defined(BOTAN_HAS_DSA)
461 if(alg_name ==
"DSA")
462 return std::make_unique<DSA_PrivateKey>(rng, modp_group);
465#if defined(BOTAN_HAS_ELGAMAL)
466 if(alg_name ==
"ElGamal")
467 return std::make_unique<ElGamal_PrivateKey>(rng, modp_group);
474 return std::unique_ptr<Private_Key>();
477std::vector<std::string>
479 const std::vector<std::string>& possible)
481 std::vector<std::string> providers;
483 for(
auto&& prov : possible)
486 providers.push_back(prov);
#define BOTAN_UNUSED(...)
std::string to_formatted_string() const
xmss_algorithm_t oid() const
#define BOTAN_PUBLIC_API(maj, min)
uint32_t to_u32bit(std::string_view str_view)
std::unique_ptr< Private_Key > create_private_key(std::string_view alg_name, RandomNumberGenerator &rng, std::string_view params, std::string_view provider)
std::string fmt(std::string_view format, const T &... args)
std::vector< std::string > split_on(std::string_view str, char delim)
std::vector< std::string > probe_provider_private_key(std::string_view alg_name, const std::vector< std::string > &possible)
std::unique_ptr< Private_Key > load_private_key(const AlgorithmIdentifier &alg_id, std::span< const uint8_t > key_bits)
std::unique_ptr< Public_Key > load_public_key(const AlgorithmIdentifier &alg_id, std::span< const uint8_t > key_bits)
std::unique_ptr< Private_Key > create_ec_private_key(std::string_view alg_name, const EC_Group &ec_group, RandomNumberGenerator &rng)