108 [[maybe_unused]] std::span<const uint8_t> key_bits) {
110 const std::vector<std::string> alg_info =
split_on(oid_str,
'/');
111 std::string_view alg_name = alg_info[0];
113#if defined(BOTAN_HAS_RSA)
114 if(alg_name ==
"RSA") {
115 return std::make_unique<RSA_PublicKey>(alg_id, key_bits);
119#if defined(BOTAN_HAS_X25519)
120 if(alg_name ==
"X25519" || alg_name ==
"Curve25519") {
121 return std::make_unique<X25519_PublicKey>(alg_id, key_bits);
125#if defined(BOTAN_HAS_X448)
126 if(alg_name ==
"X448") {
127 return std::make_unique<X448_PublicKey>(alg_id, key_bits);
131#if defined(BOTAN_HAS_MCELIECE)
132 if(alg_name ==
"McEliece") {
133 return std::make_unique<McEliece_PublicKey>(key_bits);
137#if defined(BOTAN_HAS_FRODOKEM)
138 if(alg_name ==
"FrodoKEM" || alg_name.starts_with(
"FrodoKEM-") || alg_name.starts_with(
"eFrodoKEM-")) {
139 return std::make_unique<FrodoKEM_PublicKey>(alg_id, key_bits);
143#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
144 if(alg_name ==
"Kyber" || alg_name.starts_with(
"Kyber-")) {
145 return std::make_unique<Kyber_PublicKey>(alg_id, key_bits);
149#if defined(BOTAN_HAS_ECDSA)
150 if(alg_name ==
"ECDSA") {
151 return std::make_unique<ECDSA_PublicKey>(alg_id, key_bits);
155#if defined(BOTAN_HAS_ECDH)
156 if(alg_name ==
"ECDH") {
157 return std::make_unique<ECDH_PublicKey>(alg_id, key_bits);
161#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
162 if(alg_name ==
"DH") {
163 return std::make_unique<DH_PublicKey>(alg_id, key_bits);
167#if defined(BOTAN_HAS_DSA)
168 if(alg_name ==
"DSA") {
169 return std::make_unique<DSA_PublicKey>(alg_id, key_bits);
173#if defined(BOTAN_HAS_ELGAMAL)
174 if(alg_name ==
"ElGamal") {
175 return std::make_unique<ElGamal_PublicKey>(alg_id, key_bits);
179#if defined(BOTAN_HAS_ECGDSA)
180 if(alg_name ==
"ECGDSA") {
181 return std::make_unique<ECGDSA_PublicKey>(alg_id, key_bits);
185#if defined(BOTAN_HAS_ECKCDSA)
186 if(alg_name ==
"ECKCDSA") {
187 return std::make_unique<ECKCDSA_PublicKey>(alg_id, key_bits);
191#if defined(BOTAN_HAS_ED25519)
192 if(alg_name ==
"Ed25519") {
193 return std::make_unique<Ed25519_PublicKey>(alg_id, key_bits);
197#if defined(BOTAN_HAS_ED448)
198 if(alg_name ==
"Ed448") {
199 return std::make_unique<Ed448_PublicKey>(alg_id, key_bits);
203#if defined(BOTAN_HAS_GOST_34_10_2001)
204 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" || alg_name ==
"GOST-34.10-2012-512") {
205 return std::make_unique<GOST_3410_PublicKey>(alg_id, key_bits);
209#if defined(BOTAN_HAS_SM2)
210 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc") {
211 return std::make_unique<SM2_PublicKey>(alg_id, key_bits);
215#if defined(BOTAN_HAS_XMSS_RFC8391)
216 if(alg_name ==
"XMSS") {
217 return std::make_unique<XMSS_PublicKey>(key_bits);
221#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
222 if(alg_name ==
"Dilithium" || alg_name.starts_with(
"Dilithium-")) {
223 return std::make_unique<Dilithium_PublicKey>(alg_id, key_bits);
227#if defined(BOTAN_HAS_HSS_LMS)
228 if(alg_name ==
"HSS-LMS") {
229 return std::make_unique<HSS_LMS_PublicKey>(key_bits);
233#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
234 if(alg_name ==
"SPHINCS+" || alg_name.starts_with(
"SphincsPlus-")) {
235 return std::make_unique<SphincsPlus_PublicKey>(alg_id, key_bits);
239 throw Decoding_Error(
fmt(
"Unknown or unavailable public key algorithm '{}'", alg_name));
243 [[maybe_unused]] std::span<const uint8_t> key_bits) {
245 const std::vector<std::string> alg_info =
split_on(oid_str,
'/');
246 std::string_view alg_name = alg_info[0];
248#if defined(BOTAN_HAS_RSA)
249 if(alg_name ==
"RSA") {
250 return std::make_unique<RSA_PrivateKey>(alg_id, key_bits);
254#if defined(BOTAN_HAS_X25519)
255 if(alg_name ==
"X25519" || alg_name ==
"Curve25519") {
256 return std::make_unique<X25519_PrivateKey>(alg_id, key_bits);
260#if defined(BOTAN_HAS_X448)
261 if(alg_name ==
"X448") {
262 return std::make_unique<X448_PrivateKey>(alg_id, key_bits);
266#if defined(BOTAN_HAS_ECDSA)
267 if(alg_name ==
"ECDSA") {
268 return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits);
272#if defined(BOTAN_HAS_ECDH)
273 if(alg_name ==
"ECDH") {
274 return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits);
278#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
279 if(alg_name ==
"DH") {
280 return std::make_unique<DH_PrivateKey>(alg_id, key_bits);
284#if defined(BOTAN_HAS_DSA)
285 if(alg_name ==
"DSA") {
286 return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
290#if defined(BOTAN_HAS_FRODOKEM)
291 if(alg_name ==
"FrodoKEM" || alg_name.starts_with(
"FrodoKEM-") || alg_name.starts_with(
"eFrodoKEM-")) {
292 return std::make_unique<FrodoKEM_PrivateKey>(alg_id, key_bits);
296#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
297 if(alg_name ==
"Kyber" || alg_name.starts_with(
"Kyber-")) {
298 return std::make_unique<Kyber_PrivateKey>(alg_id, key_bits);
302#if defined(BOTAN_HAS_MCELIECE)
303 if(alg_name ==
"McEliece") {
304 return std::make_unique<McEliece_PrivateKey>(key_bits);
308#if defined(BOTAN_HAS_ECGDSA)
309 if(alg_name ==
"ECGDSA") {
310 return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits);
314#if defined(BOTAN_HAS_ECKCDSA)
315 if(alg_name ==
"ECKCDSA") {
316 return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits);
320#if defined(BOTAN_HAS_ED25519)
321 if(alg_name ==
"Ed25519") {
322 return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits);
326#if defined(BOTAN_HAS_ED448)
327 if(alg_name ==
"Ed448") {
328 return std::make_unique<Ed448_PrivateKey>(alg_id, key_bits);
332#if defined(BOTAN_HAS_GOST_34_10_2001)
333 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" || alg_name ==
"GOST-34.10-2012-512") {
334 return std::make_unique<GOST_3410_PrivateKey>(alg_id, key_bits);
338#if defined(BOTAN_HAS_SM2)
339 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc") {
340 return std::make_unique<SM2_PrivateKey>(alg_id, key_bits);
344#if defined(BOTAN_HAS_ELGAMAL)
345 if(alg_name ==
"ElGamal") {
346 return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits);
350#if defined(BOTAN_HAS_XMSS_RFC8391)
351 if(alg_name ==
"XMSS") {
352 return std::make_unique<XMSS_PrivateKey>(key_bits);
356#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
357 if(alg_name ==
"Dilithium" || alg_name.starts_with(
"Dilithium-")) {
358 return std::make_unique<Dilithium_PrivateKey>(alg_id, key_bits);
362#if defined(BOTAN_HAS_HSS_LMS)
363 if(alg_name ==
"HSS-LMS-Private-Key") {
364 return std::make_unique<HSS_LMS_PrivateKey>(key_bits);
368#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
369 if(alg_name ==
"SPHINCS+" || alg_name.starts_with(
"SphincsPlus-")) {
370 return std::make_unique<SphincsPlus_PrivateKey>(alg_id, key_bits);
374 throw Decoding_Error(
fmt(
"Unknown or unavailable public key algorithm '{}'", alg_name));
383#if defined(BOTAN_HAS_ECDSA)
384 if(alg_name ==
"ECDSA") {
385 return std::make_unique<ECDSA_PrivateKey>(rng, ec_group);
389#if defined(BOTAN_HAS_ECDH)
390 if(alg_name ==
"ECDH") {
391 return std::make_unique<ECDH_PrivateKey>(rng, ec_group);
395#if defined(BOTAN_HAS_ECKCDSA)
396 if(alg_name ==
"ECKCDSA") {
397 return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group);
401#if defined(BOTAN_HAS_GOST_34_10_2001)
402 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" || alg_name ==
"GOST-34.10-2012-512") {
403 return std::make_unique<GOST_3410_PrivateKey>(rng, ec_group);
407#if defined(BOTAN_HAS_SM2)
408 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc") {
409 return std::make_unique<SM2_PrivateKey>(rng, ec_group);
413#if defined(BOTAN_HAS_ECGDSA)
414 if(alg_name ==
"ECGDSA") {
415 return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group);
424 std::string_view params,
425 std::string_view provider) {
430#if defined(BOTAN_HAS_X25519)
431 if(alg_name ==
"X25519" || alg_name ==
"Curve25519") {
432 return std::make_unique<X25519_PrivateKey>(rng);
436#if defined(BOTAN_HAS_X448)
437 if(alg_name ==
"X448") {
438 return std::make_unique<X448_PrivateKey>(rng);
442#if defined(BOTAN_HAS_RSA)
443 if(alg_name ==
"RSA") {
444 const size_t modulus_bits = params.empty() ? 3072 :
to_u32bit(params);
445 return std::make_unique<RSA_PrivateKey>(rng, modulus_bits);
449#if defined(BOTAN_HAS_MCELIECE)
450 if(alg_name ==
"McEliece") {
451 const auto [n, t] = [&]() -> std::pair<size_t, size_t> {
456 const auto mce_params =
split_on(params,
',');
458 if(mce_params.size() != 2) {
459 throw Invalid_Argument(
fmt(
"create_private_key: invalid McEliece parameters '{}'", params));
462 const size_t mce_n =
to_u32bit(mce_params[0]);
463 const size_t mce_t =
to_u32bit(mce_params[1]);
464 return {mce_n, mce_t};
467 return std::make_unique<McEliece_PrivateKey>(rng, n, t);
471#if defined(BOTAN_HAS_FRODOKEM)
472 if(alg_name ==
"FrodoKEM") {
474 return std::make_unique<FrodoKEM_PrivateKey>(rng, mode);
478#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
479 if(alg_name ==
"Kyber") {
487 return std::make_unique<Kyber_PrivateKey>(rng, mode);
491#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
492 if(alg_name ==
"Dilithium" || alg_name ==
"Dilithium-") {
500 return std::make_unique<Dilithium_PrivateKey>(rng, mode);
504#if defined(BOTAN_HAS_HSS_LMS)
505 if(alg_name ==
"HSS-LMS") {
506 return std::make_unique<HSS_LMS_PrivateKey>(rng, params);
510#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
511 if(alg_name ==
"SPHINCS+" || alg_name ==
"SphincsPlus-") {
514 return std::make_unique<SphincsPlus_PrivateKey>(rng, sphincs_params);
518#if defined(BOTAN_HAS_XMSS_RFC8391)
519 if(alg_name ==
"XMSS") {
527 return std::make_unique<XMSS_PrivateKey>(xmss_oid, rng);
531#if defined(BOTAN_HAS_ED25519)
532 if(alg_name ==
"Ed25519") {
533 return std::make_unique<Ed25519_PrivateKey>(rng);
537#if defined(BOTAN_HAS_ED448)
538 if(alg_name ==
"Ed448") {
539 return std::make_unique<Ed448_PrivateKey>(rng);
544#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
546 if(alg_name ==
"ECDSA" || alg_name ==
"ECDH" || alg_name ==
"ECKCDSA" || alg_name ==
"ECGDSA" || alg_name ==
"SM2" ||
547 alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc" || alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" ||
548 alg_name ==
"GOST-34.10-2012-512") {
549 const std::string group_id = [&]() -> std::string {
550 if(!params.empty()) {
551 return std::string(params);
553 if(alg_name ==
"SM2" || alg_name ==
"SM2_Enc" || alg_name ==
"SM2_Sig") {
556 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256") {
559 if(alg_name ==
"GOST-34.10-2012-512") {
562 if(alg_name ==
"ECGDSA") {
563 return "brainpool256r1";
574#if defined(BOTAN_HAS_DL_GROUP)
575 if(alg_name ==
"DH" || alg_name ==
"DSA" || alg_name ==
"ElGamal") {
576 const std::string group_id = [&]() -> std::string {
577 if(!params.empty()) {
578 return std::string(params);
580 if(alg_name ==
"DSA") {
581 return "dsa/botan/2048";
583 return "modp/ietf/2048";
588 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
589 if(alg_name ==
"DH") {
590 return std::make_unique<DH_PrivateKey>(rng, modp_group);
594 #if defined(BOTAN_HAS_DSA)
595 if(alg_name ==
"DSA") {
596 return std::make_unique<DSA_PrivateKey>(rng, modp_group);
600 #if defined(BOTAN_HAS_ELGAMAL)
601 if(alg_name ==
"ElGamal") {
602 return std::make_unique<ElGamal_PrivateKey>(rng, modp_group);
610 return std::unique_ptr<Private_Key>();