104 [[maybe_unused]] std::span<const uint8_t> key_bits) {
106 const std::vector<std::string> alg_info =
split_on(oid_str,
'/');
107 std::string_view alg_name = alg_info[0];
109#if defined(BOTAN_HAS_RSA)
110 if(alg_name ==
"RSA") {
111 return std::make_unique<RSA_PublicKey>(alg_id, key_bits);
115#if defined(BOTAN_HAS_CURVE_25519)
116 if(alg_name ==
"Curve25519") {
117 return std::make_unique<Curve25519_PublicKey>(alg_id, key_bits);
121#if defined(BOTAN_HAS_X448)
122 if(alg_name ==
"X448") {
123 return std::make_unique<X448_PublicKey>(alg_id, key_bits);
127#if defined(BOTAN_HAS_MCELIECE)
128 if(alg_name ==
"McEliece") {
129 return std::make_unique<McEliece_PublicKey>(key_bits);
133#if defined(BOTAN_HAS_FRODOKEM)
134 if(alg_name ==
"FrodoKEM" || alg_name.starts_with(
"FrodoKEM-") || alg_name.starts_with(
"eFrodoKEM-")) {
135 return std::make_unique<FrodoKEM_PublicKey>(alg_id, key_bits);
139#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
140 if(alg_name ==
"Kyber" || alg_name.starts_with(
"Kyber-")) {
141 return std::make_unique<Kyber_PublicKey>(alg_id, key_bits);
145#if defined(BOTAN_HAS_ECDSA)
146 if(alg_name ==
"ECDSA") {
147 return std::make_unique<ECDSA_PublicKey>(alg_id, key_bits);
151#if defined(BOTAN_HAS_ECDH)
152 if(alg_name ==
"ECDH") {
153 return std::make_unique<ECDH_PublicKey>(alg_id, key_bits);
157#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
158 if(alg_name ==
"DH") {
159 return std::make_unique<DH_PublicKey>(alg_id, key_bits);
163#if defined(BOTAN_HAS_DSA)
164 if(alg_name ==
"DSA") {
165 return std::make_unique<DSA_PublicKey>(alg_id, key_bits);
169#if defined(BOTAN_HAS_ELGAMAL)
170 if(alg_name ==
"ElGamal") {
171 return std::make_unique<ElGamal_PublicKey>(alg_id, key_bits);
175#if defined(BOTAN_HAS_ECGDSA)
176 if(alg_name ==
"ECGDSA") {
177 return std::make_unique<ECGDSA_PublicKey>(alg_id, key_bits);
181#if defined(BOTAN_HAS_ECKCDSA)
182 if(alg_name ==
"ECKCDSA") {
183 return std::make_unique<ECKCDSA_PublicKey>(alg_id, key_bits);
187#if defined(BOTAN_HAS_ED25519)
188 if(alg_name ==
"Ed25519") {
189 return std::make_unique<Ed25519_PublicKey>(alg_id, key_bits);
193#if defined(BOTAN_HAS_ED448)
194 if(alg_name ==
"Ed448") {
195 return std::make_unique<Ed448_PublicKey>(alg_id, key_bits);
199#if defined(BOTAN_HAS_GOST_34_10_2001)
200 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" || alg_name ==
"GOST-34.10-2012-512") {
201 return std::make_unique<GOST_3410_PublicKey>(alg_id, key_bits);
205#if defined(BOTAN_HAS_SM2)
206 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc") {
207 return std::make_unique<SM2_PublicKey>(alg_id, key_bits);
211#if defined(BOTAN_HAS_XMSS_RFC8391)
212 if(alg_name ==
"XMSS") {
213 return std::make_unique<XMSS_PublicKey>(key_bits);
217#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
218 if(alg_name ==
"Dilithium" || alg_name.starts_with(
"Dilithium-")) {
219 return std::make_unique<Dilithium_PublicKey>(alg_id, key_bits);
223#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
224 if(alg_name ==
"SPHINCS+" || alg_name.starts_with(
"SphincsPlus-")) {
225 return std::make_unique<SphincsPlus_PublicKey>(alg_id, key_bits);
229 throw Decoding_Error(
fmt(
"Unknown or unavailable public key algorithm '{}'", alg_name));
233 [[maybe_unused]] std::span<const uint8_t> key_bits) {
235 const std::vector<std::string> alg_info =
split_on(oid_str,
'/');
236 std::string_view alg_name = alg_info[0];
238#if defined(BOTAN_HAS_RSA)
239 if(alg_name ==
"RSA") {
240 return std::make_unique<RSA_PrivateKey>(alg_id, key_bits);
244#if defined(BOTAN_HAS_CURVE_25519)
245 if(alg_name ==
"Curve25519") {
246 return std::make_unique<Curve25519_PrivateKey>(alg_id, key_bits);
250#if defined(BOTAN_HAS_X448)
251 if(alg_name ==
"X448") {
252 return std::make_unique<X448_PrivateKey>(alg_id, key_bits);
256#if defined(BOTAN_HAS_ECDSA)
257 if(alg_name ==
"ECDSA") {
258 return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits);
262#if defined(BOTAN_HAS_ECDH)
263 if(alg_name ==
"ECDH") {
264 return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits);
268#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
269 if(alg_name ==
"DH") {
270 return std::make_unique<DH_PrivateKey>(alg_id, key_bits);
274#if defined(BOTAN_HAS_DSA)
275 if(alg_name ==
"DSA") {
276 return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
280#if defined(BOTAN_HAS_FRODOKEM)
281 if(alg_name ==
"FrodoKEM" || alg_name.starts_with(
"FrodoKEM-") || alg_name.starts_with(
"eFrodoKEM-")) {
282 return std::make_unique<FrodoKEM_PrivateKey>(alg_id, key_bits);
286#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
287 if(alg_name ==
"Kyber" || alg_name.starts_with(
"Kyber-")) {
288 return std::make_unique<Kyber_PrivateKey>(alg_id, key_bits);
292#if defined(BOTAN_HAS_MCELIECE)
293 if(alg_name ==
"McEliece") {
294 return std::make_unique<McEliece_PrivateKey>(key_bits);
298#if defined(BOTAN_HAS_ECGDSA)
299 if(alg_name ==
"ECGDSA") {
300 return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits);
304#if defined(BOTAN_HAS_ECKCDSA)
305 if(alg_name ==
"ECKCDSA") {
306 return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits);
310#if defined(BOTAN_HAS_ED25519)
311 if(alg_name ==
"Ed25519") {
312 return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits);
316#if defined(BOTAN_HAS_ED448)
317 if(alg_name ==
"Ed448") {
318 return std::make_unique<Ed448_PrivateKey>(alg_id, key_bits);
322#if defined(BOTAN_HAS_GOST_34_10_2001)
323 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" || alg_name ==
"GOST-34.10-2012-512") {
324 return std::make_unique<GOST_3410_PrivateKey>(alg_id, key_bits);
328#if defined(BOTAN_HAS_SM2)
329 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc") {
330 return std::make_unique<SM2_PrivateKey>(alg_id, key_bits);
334#if defined(BOTAN_HAS_ELGAMAL)
335 if(alg_name ==
"ElGamal") {
336 return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits);
340#if defined(BOTAN_HAS_XMSS_RFC8391)
341 if(alg_name ==
"XMSS") {
342 return std::make_unique<XMSS_PrivateKey>(key_bits);
346#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
347 if(alg_name ==
"Dilithium" || alg_name.starts_with(
"Dilithium-")) {
348 return std::make_unique<Dilithium_PrivateKey>(alg_id, key_bits);
352#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
353 if(alg_name ==
"SPHINCS+" || alg_name.starts_with(
"SphincsPlus-")) {
354 return std::make_unique<SphincsPlus_PrivateKey>(alg_id, key_bits);
358 throw Decoding_Error(
fmt(
"Unknown or unavailable public key algorithm '{}'", alg_name));
367#if defined(BOTAN_HAS_ECDSA)
368 if(alg_name ==
"ECDSA") {
369 return std::make_unique<ECDSA_PrivateKey>(rng, ec_group);
373#if defined(BOTAN_HAS_ECDH)
374 if(alg_name ==
"ECDH") {
375 return std::make_unique<ECDH_PrivateKey>(rng, ec_group);
379#if defined(BOTAN_HAS_ECKCDSA)
380 if(alg_name ==
"ECKCDSA") {
381 return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group);
385#if defined(BOTAN_HAS_GOST_34_10_2001)
386 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" || alg_name ==
"GOST-34.10-2012-512") {
387 return std::make_unique<GOST_3410_PrivateKey>(rng, ec_group);
391#if defined(BOTAN_HAS_SM2)
392 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc") {
393 return std::make_unique<SM2_PrivateKey>(rng, ec_group);
397#if defined(BOTAN_HAS_ECGDSA)
398 if(alg_name ==
"ECGDSA") {
399 return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group);
408 std::string_view params,
409 std::string_view provider) {
414#if defined(BOTAN_HAS_CURVE_25519)
415 if(alg_name ==
"Curve25519") {
416 return std::make_unique<Curve25519_PrivateKey>(rng);
420#if defined(BOTAN_HAS_X448)
421 if(alg_name ==
"X448") {
422 return std::make_unique<X448_PrivateKey>(rng);
426#if defined(BOTAN_HAS_RSA)
427 if(alg_name ==
"RSA") {
428 const size_t modulus_bits = params.empty() ? 3072 :
to_u32bit(params);
429 return std::make_unique<RSA_PrivateKey>(rng, modulus_bits);
433#if defined(BOTAN_HAS_MCELIECE)
434 if(alg_name ==
"McEliece") {
435 const auto [n, t] = [&]() -> std::pair<size_t, size_t> {
440 const auto mce_params =
split_on(params,
',');
442 if(mce_params.size() != 2) {
443 throw Invalid_Argument(
fmt(
"create_private_key: invalid McEliece parameters '{}'", params));
446 const size_t mce_n =
to_u32bit(mce_params[0]);
447 const size_t mce_t =
to_u32bit(mce_params[1]);
448 return {mce_n, mce_t};
451 return std::make_unique<McEliece_PrivateKey>(rng, n, t);
455#if defined(BOTAN_HAS_FRODOKEM)
456 if(alg_name ==
"FrodoKEM") {
458 return std::make_unique<FrodoKEM_PrivateKey>(rng, mode);
462#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
463 if(alg_name ==
"Kyber") {
471 return std::make_unique<Kyber_PrivateKey>(rng, mode);
475#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
476 if(alg_name ==
"Dilithium" || alg_name ==
"Dilithium-") {
484 return std::make_unique<Dilithium_PrivateKey>(rng, mode);
488#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
489 if(alg_name ==
"SPHINCS+" || alg_name ==
"SphincsPlus-") {
492 return std::make_unique<SphincsPlus_PrivateKey>(rng, sphincs_params);
496#if defined(BOTAN_HAS_XMSS_RFC8391)
497 if(alg_name ==
"XMSS") {
505 return std::make_unique<XMSS_PrivateKey>(xmss_oid, rng);
509#if defined(BOTAN_HAS_ED25519)
510 if(alg_name ==
"Ed25519") {
511 return std::make_unique<Ed25519_PrivateKey>(rng);
515#if defined(BOTAN_HAS_ED448)
516 if(alg_name ==
"Ed448") {
517 return std::make_unique<Ed448_PrivateKey>(rng);
522#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
524 if(alg_name ==
"ECDSA" || alg_name ==
"ECDH" || alg_name ==
"ECKCDSA" || alg_name ==
"ECGDSA" || alg_name ==
"SM2" ||
525 alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc" || alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" ||
526 alg_name ==
"GOST-34.10-2012-512") {
527 const std::string group_id = [&]() -> std::string {
528 if(!params.empty()) {
529 return std::string(params);
531 if(alg_name ==
"SM2" || alg_name ==
"SM2_Enc" || alg_name ==
"SM2_Sig") {
534 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256") {
537 if(alg_name ==
"GOST-34.10-2012-512") {
540 if(alg_name ==
"ECGDSA") {
541 return "brainpool256r1";
552#if defined(BOTAN_HAS_DL_GROUP)
553 if(alg_name ==
"DH" || alg_name ==
"DSA" || alg_name ==
"ElGamal") {
554 const std::string group_id = [&]() -> std::string {
555 if(!params.empty()) {
556 return std::string(params);
558 if(alg_name ==
"DSA") {
559 return "dsa/botan/2048";
561 return "modp/ietf/2048";
566 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
567 if(alg_name ==
"DH") {
568 return std::make_unique<DH_PrivateKey>(rng, modp_group);
572 #if defined(BOTAN_HAS_DSA)
573 if(alg_name ==
"DSA") {
574 return std::make_unique<DSA_PrivateKey>(rng, modp_group);
578 #if defined(BOTAN_HAS_ELGAMAL)
579 if(alg_name ==
"ElGamal") {
580 return std::make_unique<ElGamal_PrivateKey>(rng, modp_group);
588 return std::unique_ptr<Private_Key>();