diff options
Diffstat (limited to 'src')
39 files changed, 163 insertions, 3 deletions
diff --git a/src/lib/prov/pkcs11/p11_ecdh.cpp b/src/lib/prov/pkcs11/p11_ecdh.cpp index bd598143a..82f09e4cd 100644 --- a/src/lib/prov/pkcs11/p11_ecdh.cpp +++ b/src/lib/prov/pkcs11/p11_ecdh.cpp @@ -32,6 +32,11 @@ ECDH_PrivateKey PKCS11_ECDH_PrivateKey::export_key() const return ECDH_PrivateKey(rng, domain(), BigInt::decode(priv_key)); } +std::unique_ptr<Public_Key> PKCS11_ECDH_PrivateKey::public_key() const + { + return std::unique_ptr<Public_Key>(new ECDH_PublicKey(domain(), public_point())); + } + secure_vector<uint8_t> PKCS11_ECDH_PrivateKey::private_key_bits() const { return export_key().private_key_bits(); diff --git a/src/lib/prov/pkcs11/p11_ecdh.h b/src/lib/prov/pkcs11/p11_ecdh.h index bbef9a3e5..aa2975a42 100644 --- a/src/lib/prov/pkcs11/p11_ecdh.h +++ b/src/lib/prov/pkcs11/p11_ecdh.h @@ -93,6 +93,8 @@ class BOTAN_PUBLIC_API(2,0) PKCS11_ECDH_PrivateKey final : public virtual PKCS11 return "ECDH"; } + std::unique_ptr<Public_Key> public_key() const override; + inline std::vector<uint8_t> public_value() const override { return public_point().encode(PointGFp::UNCOMPRESSED); diff --git a/src/lib/prov/pkcs11/p11_ecdsa.cpp b/src/lib/prov/pkcs11/p11_ecdsa.cpp index eebb13020..f35da4892 100644 --- a/src/lib/prov/pkcs11/p11_ecdsa.cpp +++ b/src/lib/prov/pkcs11/p11_ecdsa.cpp @@ -52,6 +52,11 @@ secure_vector<uint8_t> PKCS11_ECDSA_PrivateKey::private_key_bits() const return export_key().private_key_bits(); } +std::unique_ptr<Public_Key> PKCS11_ECDSA_PrivateKey::public_key() const + { + return std::unique_ptr<Public_Key>(new ECDSA_PublicKey(domain(), public_point())); + } + namespace { class PKCS11_ECDSA_Signature_Operation final : public PK_Ops::Signature diff --git a/src/lib/prov/pkcs11/p11_ecdsa.h b/src/lib/prov/pkcs11/p11_ecdsa.h index 82721a466..ccf07a513 100644 --- a/src/lib/prov/pkcs11/p11_ecdsa.h +++ b/src/lib/prov/pkcs11/p11_ecdsa.h @@ -105,6 +105,8 @@ class BOTAN_PUBLIC_API(2,0) PKCS11_ECDSA_PrivateKey final : public PKCS11_EC_Pri /// @return the exported ECDSA private key ECDSA_PrivateKey export_key() const; + std::unique_ptr<Public_Key> public_key() const override; + secure_vector<uint8_t> private_key_bits() const override; bool check_key(RandomNumberGenerator&, bool) const override; diff --git a/src/lib/prov/pkcs11/p11_rsa.cpp b/src/lib/prov/pkcs11/p11_rsa.cpp index 93147fee2..eb990b19a 100644 --- a/src/lib/prov/pkcs11/p11_rsa.cpp +++ b/src/lib/prov/pkcs11/p11_rsa.cpp @@ -106,6 +106,17 @@ RSA_PrivateKey PKCS11_RSA_PrivateKey::export_key() const , BigInt::decode(n)); } +std::unique_ptr<Public_Key> PKCS11_RSA_PrivateKey::public_key() const + { + auto p = get_attribute_value(AttributeType::Prime1); + auto q = get_attribute_value(AttributeType::Prime2); + auto e = get_attribute_value(AttributeType::PublicExponent); + + BigInt n = BigInt::decode(p) * BigInt::decode(q); + + return std::unique_ptr<Public_Key>(new RSA_PublicKey(n, BigInt::decode(e))); + } + secure_vector<uint8_t> PKCS11_RSA_PrivateKey::private_key_bits() const { return export_key().private_key_bits(); diff --git a/src/lib/prov/pkcs11/p11_rsa.h b/src/lib/prov/pkcs11/p11_rsa.h index 41d9bc134..e3b557f94 100644 --- a/src/lib/prov/pkcs11/p11_rsa.h +++ b/src/lib/prov/pkcs11/p11_rsa.h @@ -200,6 +200,8 @@ class BOTAN_PUBLIC_API(2,0) PKCS11_RSA_PrivateKey final : secure_vector<uint8_t> private_key_bits() const override; + std::unique_ptr<Public_Key> public_key() const override; + std::unique_ptr<PK_Ops::Decryption> create_decryption_op(RandomNumberGenerator& rng, const std::string& params, diff --git a/src/lib/prov/tpm/tpm.h b/src/lib/prov/tpm/tpm.h index 8a25458b7..d5fe929c3 100644 --- a/src/lib/prov/tpm/tpm.h +++ b/src/lib/prov/tpm/tpm.h @@ -138,7 +138,7 @@ class BOTAN_PUBLIC_API(2,0) TPM_PrivateKey final : public Private_Key /** * Returns a copy of the public key */ - std::unique_ptr<Public_Key> public_key() const; + std::unique_ptr<Public_Key> public_key() const override; std::vector<uint8_t> export_blob() const; diff --git a/src/lib/pubkey/curve25519/curve25519.cpp b/src/lib/pubkey/curve25519/curve25519.cpp index 515fdc5e6..a06e700c4 100644 --- a/src/lib/pubkey/curve25519/curve25519.cpp +++ b/src/lib/pubkey/curve25519/curve25519.cpp @@ -87,6 +87,11 @@ Curve25519_PrivateKey::Curve25519_PrivateKey(const AlgorithmIdentifier&, curve25519_basepoint(m_public.data(), m_private.data()); } +std::unique_ptr<Public_Key> Curve25519_PrivateKey::public_key() const + { + return std::unique_ptr<Public_Key>(new Curve25519_PublicKey(public_value())); + } + secure_vector<uint8_t> Curve25519_PrivateKey::private_key_bits() const { return DER_Encoder().encode(m_private, OCTET_STRING).get_contents(); diff --git a/src/lib/pubkey/curve25519/curve25519.h b/src/lib/pubkey/curve25519/curve25519.h index c2f8f42b3..99860630e 100644 --- a/src/lib/pubkey/curve25519/curve25519.h +++ b/src/lib/pubkey/curve25519/curve25519.h @@ -88,6 +88,8 @@ class BOTAN_PUBLIC_API(2,0) Curve25519_PrivateKey final : public Curve25519_Publ secure_vector<uint8_t> private_key_bits() const override; + std::unique_ptr<Public_Key> public_key() const override; + bool check_key(RandomNumberGenerator& rng, bool strong) const override; std::unique_ptr<PK_Ops::Key_Agreement> diff --git a/src/lib/pubkey/dh/dh.cpp b/src/lib/pubkey/dh/dh.cpp index e4b6e825e..77ac19da4 100644 --- a/src/lib/pubkey/dh/dh.cpp +++ b/src/lib/pubkey/dh/dh.cpp @@ -66,6 +66,11 @@ DH_PrivateKey::DH_PrivateKey(const AlgorithmIdentifier& alg_id, } } +std::unique_ptr<Public_Key> DH_PrivateKey::public_key() const + { + return std::unique_ptr<Public_Key>(new DH_PublicKey(get_group(), get_y())); + } + /* * Return the public value for key agreement */ diff --git a/src/lib/pubkey/dh/dh.h b/src/lib/pubkey/dh/dh.h index e3aa0d2c5..bb6d5dae4 100644 --- a/src/lib/pubkey/dh/dh.h +++ b/src/lib/pubkey/dh/dh.h @@ -70,6 +70,8 @@ class BOTAN_PUBLIC_API(2,0) DH_PrivateKey final : public DH_PublicKey, DH_PrivateKey(RandomNumberGenerator& rng, const DL_Group& grp, const BigInt& x = 0); + std::unique_ptr<Public_Key> public_key() const override; + std::unique_ptr<PK_Ops::Key_Agreement> create_key_agreement_op(RandomNumberGenerator& rng, const std::string& params, diff --git a/src/lib/pubkey/dsa/dsa.cpp b/src/lib/pubkey/dsa/dsa.cpp index 5c0d048c9..a135bc962 100644 --- a/src/lib/pubkey/dsa/dsa.cpp +++ b/src/lib/pubkey/dsa/dsa.cpp @@ -67,6 +67,11 @@ bool DSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const return KeyPair::signature_consistency_check(rng, *this, "EMSA1(SHA-256)"); } +std::unique_ptr<Public_Key> DSA_PrivateKey::public_key() const + { + return std::unique_ptr<Public_Key>(new DSA_PublicKey(get_group(), get_y())); + } + namespace { /** diff --git a/src/lib/pubkey/dsa/dsa.h b/src/lib/pubkey/dsa/dsa.h index b219a1cf3..1834737b5 100644 --- a/src/lib/pubkey/dsa/dsa.h +++ b/src/lib/pubkey/dsa/dsa.h @@ -74,6 +74,8 @@ class BOTAN_PUBLIC_API(2,0) DSA_PrivateKey final : public DSA_PublicKey, const DL_Group& group, const BigInt& private_key = 0); + std::unique_ptr<Public_Key> public_key() const override; + bool check_key(RandomNumberGenerator& rng, bool strong) const override; std::unique_ptr<PK_Ops::Signature> diff --git a/src/lib/pubkey/ecdh/ecdh.cpp b/src/lib/pubkey/ecdh/ecdh.cpp index e7e49a74f..74c385fcf 100644 --- a/src/lib/pubkey/ecdh/ecdh.cpp +++ b/src/lib/pubkey/ecdh/ecdh.cpp @@ -17,6 +17,11 @@ namespace Botan { +std::unique_ptr<Public_Key> ECDH_PrivateKey::public_key() const + { + return std::unique_ptr<Public_Key>(new ECDH_PublicKey(domain(), public_point())); + } + namespace { /** diff --git a/src/lib/pubkey/ecdh/ecdh.h b/src/lib/pubkey/ecdh/ecdh.h index f88955ac4..4be7e656c 100644 --- a/src/lib/pubkey/ecdh/ecdh.h +++ b/src/lib/pubkey/ecdh/ecdh.h @@ -89,6 +89,8 @@ class BOTAN_PUBLIC_API(2,0) ECDH_PrivateKey final : public ECDH_PublicKey, const BigInt& x = 0) : EC_PrivateKey(rng, domain, x) {} + std::unique_ptr<Public_Key> public_key() const override; + std::vector<uint8_t> public_value() const override { return ECDH_PublicKey::public_value(PointGFp::UNCOMPRESSED); } diff --git a/src/lib/pubkey/ecdsa/ecdsa.cpp b/src/lib/pubkey/ecdsa/ecdsa.cpp index 11ec37ff4..96c1b7751 100644 --- a/src/lib/pubkey/ecdsa/ecdsa.cpp +++ b/src/lib/pubkey/ecdsa/ecdsa.cpp @@ -109,6 +109,11 @@ uint8_t ECDSA_PublicKey::recovery_param(const std::vector<uint8_t>& msg, throw Internal_Error("Could not determine ECDSA recovery parameter"); } +std::unique_ptr<Public_Key> ECDSA_PrivateKey::public_key() const + { + return std::unique_ptr<Public_Key>(new ECDSA_PublicKey(domain(), public_point())); + } + bool ECDSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const { diff --git a/src/lib/pubkey/ecdsa/ecdsa.h b/src/lib/pubkey/ecdsa/ecdsa.h index 8423a9c20..2bdb9e79b 100644 --- a/src/lib/pubkey/ecdsa/ecdsa.h +++ b/src/lib/pubkey/ecdsa/ecdsa.h @@ -106,6 +106,8 @@ class BOTAN_PUBLIC_API(2,0) ECDSA_PrivateKey final : public ECDSA_PublicKey, bool check_key(RandomNumberGenerator& rng, bool) const override; + std::unique_ptr<Public_Key> public_key() const override; + std::unique_ptr<PK_Ops::Signature> create_signature_op(RandomNumberGenerator& rng, const std::string& params, diff --git a/src/lib/pubkey/ecgdsa/ecgdsa.cpp b/src/lib/pubkey/ecgdsa/ecgdsa.cpp index 26045be6b..f4331677b 100644 --- a/src/lib/pubkey/ecgdsa/ecgdsa.cpp +++ b/src/lib/pubkey/ecgdsa/ecgdsa.cpp @@ -14,6 +14,11 @@ namespace Botan { +std::unique_ptr<Public_Key> ECGDSA_PrivateKey::public_key() const + { + return std::unique_ptr<Public_Key>(new ECGDSA_PublicKey(domain(), public_point())); + } + bool ECGDSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const { diff --git a/src/lib/pubkey/ecgdsa/ecgdsa.h b/src/lib/pubkey/ecgdsa/ecgdsa.h index 31d0e2be5..cf9f09de2 100644 --- a/src/lib/pubkey/ecgdsa/ecgdsa.h +++ b/src/lib/pubkey/ecgdsa/ecgdsa.h @@ -83,6 +83,8 @@ class BOTAN_PUBLIC_API(2,0) ECGDSA_PrivateKey final : public ECGDSA_PublicKey, const BigInt& x = 0) : EC_PrivateKey(rng, domain, x, true) {} + std::unique_ptr<Public_Key> public_key() const override; + bool check_key(RandomNumberGenerator& rng, bool) const override; std::unique_ptr<PK_Ops::Signature> diff --git a/src/lib/pubkey/ecies/ecies.cpp b/src/lib/pubkey/ecies/ecies.cpp index a8c277b3a..dcdf318c1 100644 --- a/src/lib/pubkey/ecies/ecies.cpp +++ b/src/lib/pubkey/ecies/ecies.cpp @@ -40,6 +40,11 @@ class ECIES_PrivateKey final : public EC_PrivateKey, public PK_Key_Agreement_Key return "ECIES"; } + std::unique_ptr<Public_Key> public_key() const override + { + return m_key.public_key(); + } + std::unique_ptr<PK_Ops::Key_Agreement> create_key_agreement_op(RandomNumberGenerator& rng, const std::string& params, diff --git a/src/lib/pubkey/eckcdsa/eckcdsa.cpp b/src/lib/pubkey/eckcdsa/eckcdsa.cpp index 3321a713d..d232e35e4 100644 --- a/src/lib/pubkey/eckcdsa/eckcdsa.cpp +++ b/src/lib/pubkey/eckcdsa/eckcdsa.cpp @@ -17,6 +17,11 @@ namespace Botan { +std::unique_ptr<Public_Key> ECKCDSA_PrivateKey::public_key() const + { + return std::unique_ptr<Public_Key>(new ECKCDSA_PublicKey(domain(), public_point())); + } + bool ECKCDSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const { diff --git a/src/lib/pubkey/eckcdsa/eckcdsa.h b/src/lib/pubkey/eckcdsa/eckcdsa.h index aa04cb146..924f56c4c 100644 --- a/src/lib/pubkey/eckcdsa/eckcdsa.h +++ b/src/lib/pubkey/eckcdsa/eckcdsa.h @@ -85,6 +85,8 @@ class BOTAN_PUBLIC_API(2,0) ECKCDSA_PrivateKey final : public ECKCDSA_PublicKey, bool check_key(RandomNumberGenerator& rng, bool) const override; + std::unique_ptr<Public_Key> public_key() const override; + std::unique_ptr<PK_Ops::Signature> create_signature_op(RandomNumberGenerator& rng, const std::string& params, diff --git a/src/lib/pubkey/ed25519/ed25519.h b/src/lib/pubkey/ed25519/ed25519.h index 97ed023f2..65bee1353 100644 --- a/src/lib/pubkey/ed25519/ed25519.h +++ b/src/lib/pubkey/ed25519/ed25519.h @@ -83,6 +83,8 @@ class BOTAN_PUBLIC_API(2,2) Ed25519_PrivateKey final : public Ed25519_PublicKey, secure_vector<uint8_t> private_key_bits() const override; + std::unique_ptr<Public_Key> public_key() const override; + bool check_key(RandomNumberGenerator& rng, bool strong) const override; std::unique_ptr<PK_Ops::Signature> diff --git a/src/lib/pubkey/ed25519/ed25519_key.cpp b/src/lib/pubkey/ed25519/ed25519_key.cpp index c4b260c4c..ad8646111 100644 --- a/src/lib/pubkey/ed25519/ed25519_key.cpp +++ b/src/lib/pubkey/ed25519/ed25519_key.cpp @@ -87,6 +87,11 @@ Ed25519_PrivateKey::Ed25519_PrivateKey(const AlgorithmIdentifier&, ed25519_gen_keypair(m_public.data(), m_private.data(), bits.data()); } +std::unique_ptr<Public_Key> Ed25519_PrivateKey::public_key() const + { + return std::unique_ptr<Public_Key>(new Ed25519_PublicKey(get_public_key())); + } + secure_vector<uint8_t> Ed25519_PrivateKey::private_key_bits() const { secure_vector<uint8_t> bits(&m_private[0], &m_private[32]); diff --git a/src/lib/pubkey/elgamal/elgamal.cpp b/src/lib/pubkey/elgamal/elgamal.cpp index 6f8019723..73e091d0a 100644 --- a/src/lib/pubkey/elgamal/elgamal.cpp +++ b/src/lib/pubkey/elgamal/elgamal.cpp @@ -50,6 +50,11 @@ ElGamal_PrivateKey::ElGamal_PrivateKey(const AlgorithmIdentifier& alg_id, m_y = m_group.power_g_p(m_x, m_group.p_bits()); } +std::unique_ptr<Public_Key> ElGamal_PrivateKey::public_key() const + { + return std::unique_ptr<Public_Key>(new ElGamal_PublicKey(get_group(), get_y())); + } + /* * Check Private ElGamal Parameters */ diff --git a/src/lib/pubkey/elgamal/elgamal.h b/src/lib/pubkey/elgamal/elgamal.h index e4d932f6a..4147f5037 100644 --- a/src/lib/pubkey/elgamal/elgamal.h +++ b/src/lib/pubkey/elgamal/elgamal.h @@ -74,6 +74,8 @@ class BOTAN_PUBLIC_API(2,0) ElGamal_PrivateKey final : public ElGamal_PublicKey, const DL_Group& group, const BigInt& priv_key = 0); + std::unique_ptr<Public_Key> public_key() const override; + std::unique_ptr<PK_Ops::Decryption> create_decryption_op(RandomNumberGenerator& rng, const std::string& params, diff --git a/src/lib/pubkey/gost_3410/gost_3410.cpp b/src/lib/pubkey/gost_3410/gost_3410.cpp index d1f8fc786..f378a7998 100644 --- a/src/lib/pubkey/gost_3410/gost_3410.cpp +++ b/src/lib/pubkey/gost_3410/gost_3410.cpp @@ -109,6 +109,11 @@ GOST_3410_PrivateKey::GOST_3410_PrivateKey(RandomNumberGenerator& rng, std::to_string(p_bits)); } +std::unique_ptr<Public_Key> GOST_3410_PrivateKey::public_key() const + { + return std::unique_ptr<Public_Key>(new GOST_3410_PublicKey(domain(), public_point())); + } + namespace { BigInt decode_le(const uint8_t msg[], size_t msg_len) diff --git a/src/lib/pubkey/gost_3410/gost_3410.h b/src/lib/pubkey/gost_3410/gost_3410.h index 9eedaf122..ffce3ef97 100644 --- a/src/lib/pubkey/gost_3410/gost_3410.h +++ b/src/lib/pubkey/gost_3410/gost_3410.h @@ -90,6 +90,8 @@ class BOTAN_PUBLIC_API(2,0) GOST_3410_PrivateKey final : const EC_Group& domain, const BigInt& x = 0); + std::unique_ptr<Public_Key> public_key() const override; + AlgorithmIdentifier pkcs8_algorithm_identifier() const override { return EC_PublicKey::algorithm_identifier(); } diff --git a/src/lib/pubkey/mce/mceliece.h b/src/lib/pubkey/mce/mceliece.h index 255898b63..3ac48aeb4 100644 --- a/src/lib/pubkey/mce/mceliece.h +++ b/src/lib/pubkey/mce/mceliece.h @@ -116,6 +116,8 @@ class BOTAN_PUBLIC_API(2,0) McEliece_PrivateKey final : public virtual McEliece_ secure_vector<uint8_t> private_key_bits() const override; + std::unique_ptr<Public_Key> public_key() const override; + bool operator==(const McEliece_PrivateKey & other) const; bool operator!=(const McEliece_PrivateKey& other) const { return !(*this == other); } diff --git a/src/lib/pubkey/mce/mceliece_key.cpp b/src/lib/pubkey/mce/mceliece_key.cpp index 9db90112f..f0bd8e61d 100644 --- a/src/lib/pubkey/mce/mceliece_key.cpp +++ b/src/lib/pubkey/mce/mceliece_key.cpp @@ -292,6 +292,13 @@ bool McEliece_PrivateKey::operator==(const McEliece_PrivateKey & other) const return true; } +std::unique_ptr<Public_Key> McEliece_PrivateKey::public_key() const + { + return std::unique_ptr<Public_Key>(new McEliece_PublicKey( + get_public_matrix(), + get_t(), get_code_length())); + } + bool McEliece_PublicKey::operator==(const McEliece_PublicKey& other) const { if(m_public_matrix != other.m_public_matrix) diff --git a/src/lib/pubkey/pk_keys.h b/src/lib/pubkey/pk_keys.h index 404cd683f..38b902cf3 100644 --- a/src/lib/pubkey/pk_keys.h +++ b/src/lib/pubkey/pk_keys.h @@ -1,6 +1,6 @@ /* * PK Key Types -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2007,2018 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -28,7 +28,7 @@ enum Signature_Format { IEEE_1363, DER_SEQUENCE }; class BOTAN_PUBLIC_API(2,0) Public_Key { public: - Public_Key() =default; + Public_Key() = default; Public_Key(const Public_Key& other) = default; Public_Key& operator=(const Public_Key& other) = default; virtual ~Public_Key() = default; @@ -193,6 +193,14 @@ class BOTAN_PUBLIC_API(2,0) Private_Key : public virtual Public_Key virtual secure_vector<uint8_t> private_key_bits() const = 0; /** + * Allocate a new object for the public key associated with this + * private key. + * + * @return public key + */ + virtual std::unique_ptr<Public_Key> public_key() const = 0; + + /** * @return PKCS #8 private key encoding for this key object */ secure_vector<uint8_t> private_key_info() const; diff --git a/src/lib/pubkey/rsa/rsa.cpp b/src/lib/pubkey/rsa/rsa.cpp index b7d05e456..8899c9a63 100644 --- a/src/lib/pubkey/rsa/rsa.cpp +++ b/src/lib/pubkey/rsa/rsa.cpp @@ -313,6 +313,11 @@ RSA_PrivateKey::RSA_PrivateKey(RandomNumberGenerator& rng, std::move(d1), std::move(d2), std::move(c)); } +std::unique_ptr<Public_Key> RSA_PrivateKey::public_key() const + { + return std::unique_ptr<Public_Key>(new RSA_PublicKey(get_n(), get_e())); + } + /* * Check Private RSA Parameters */ diff --git a/src/lib/pubkey/rsa/rsa.h b/src/lib/pubkey/rsa/rsa.h index 2a02c89d5..ccea7c310 100644 --- a/src/lib/pubkey/rsa/rsa.h +++ b/src/lib/pubkey/rsa/rsa.h @@ -124,6 +124,8 @@ class BOTAN_PUBLIC_API(2,0) RSA_PrivateKey final : public Private_Key, public RS RSA_PrivateKey(RandomNumberGenerator& rng, size_t bits, size_t exp = 65537); + std::unique_ptr<Public_Key> public_key() const override; + bool check_key(RandomNumberGenerator& rng, bool) const override; /** diff --git a/src/lib/pubkey/sm2/sm2.cpp b/src/lib/pubkey/sm2/sm2.cpp index a73823448..67dbacce9 100644 --- a/src/lib/pubkey/sm2/sm2.cpp +++ b/src/lib/pubkey/sm2/sm2.cpp @@ -22,6 +22,11 @@ std::string SM2_PublicKey::algo_name() const return "SM2"; } +std::unique_ptr<Public_Key> SM2_PrivateKey::public_key() const + { + return std::unique_ptr<Public_Key>(new SM2_Signature_PublicKey(domain(), public_point())); + } + bool SM2_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const { diff --git a/src/lib/pubkey/sm2/sm2.h b/src/lib/pubkey/sm2/sm2.h index 7b5f38858..2341ed861 100644 --- a/src/lib/pubkey/sm2/sm2.h +++ b/src/lib/pubkey/sm2/sm2.h @@ -89,6 +89,8 @@ class BOTAN_PUBLIC_API(2,2) SM2_PrivateKey final : bool check_key(RandomNumberGenerator& rng, bool) const override; + std::unique_ptr<Public_Key> public_key() const override; + std::unique_ptr<PK_Ops::Signature> create_signature_op(RandomNumberGenerator& rng, const std::string& params, diff --git a/src/lib/pubkey/xmss/xmss.h b/src/lib/pubkey/xmss/xmss.h index af8e8a41e..566f58282 100644 --- a/src/lib/pubkey/xmss/xmss.h +++ b/src/lib/pubkey/xmss/xmss.h @@ -314,6 +314,8 @@ class BOTAN_PUBLIC_API(2,0) XMSS_PrivateKey final : public virtual XMSS_PublicKe bool stateful_operation() const override { return true; } + std::unique_ptr<Public_Key> public_key() const override; + /** * Retrieves the last unused leaf index of the private key. Reusing a leaf * by utilizing leaf indices lower than the last unused leaf index will diff --git a/src/lib/pubkey/xmss/xmss_privatekey.cpp b/src/lib/pubkey/xmss/xmss_privatekey.cpp index c497be003..5d2171266 100644 --- a/src/lib/pubkey/xmss/xmss_privatekey.cpp +++ b/src/lib/pubkey/xmss/xmss_privatekey.cpp @@ -390,6 +390,12 @@ secure_vector<uint8_t> XMSS_PrivateKey::raw_private_key() const return result; } +std::unique_ptr<Public_Key> XMSS_PrivateKey::public_key() const + { + return std::unique_ptr<Public_Key>( + new XMSS_PublicKey(xmss_oid(), root(), public_seed())); + } + std::unique_ptr<PK_Ops::Signature> XMSS_PrivateKey::create_signature_op(RandomNumberGenerator&, const std::string&, diff --git a/src/lib/pubkey/xmss/xmss_wots.h b/src/lib/pubkey/xmss/xmss_wots.h index d85e889bf..060d54711 100644 --- a/src/lib/pubkey/xmss/xmss_wots.h +++ b/src/lib/pubkey/xmss/xmss_wots.h @@ -536,6 +536,11 @@ class XMSS_WOTS_PrivateKey final : public virtual XMSS_WOTS_PublicKey, set_key_data(generate(private_seed)); } + std::unique_ptr<Public_Key> public_key() const override + { + throw Not_Implemented("Not possible to derive WOTS public key from private key"); + } + /** * Retrieves the i-th WOTS private key using pseudo random key * (re-)generation. diff --git a/src/tests/test_pubkey.cpp b/src/tests/test_pubkey.cpp index 703f7360f..3e3001a86 100644 --- a/src/tests/test_pubkey.cpp +++ b/src/tests/test_pubkey.cpp @@ -667,6 +667,12 @@ std::vector<Test::Result> PK_Key_Generation_Test::run() std::unique_ptr<Botan::Private_Key> key_p = Botan::create_private_key(algo_name(), Test::rng(), param, prov); + if(key_p == nullptr) + { + result.test_failure("create_private_key returned null, should throw instead"); + continue; + } + const Botan::Private_Key& key = *key_p; try @@ -678,6 +684,14 @@ std::vector<Test::Result> PK_Key_Generation_Test::run() result.test_gte("Key has reasonable estimated strength (lower)", key.estimated_strength(), 64); result.test_lt("Key has reasonable estimated strength (upper)", key.estimated_strength(), 512); + std::unique_ptr<Botan::Public_Key> public_key = key.public_key(); + + result.test_eq("public_key has same name", public_key->algo_name(), key.algo_name()); + + result.test_eq("public_key has same encoding", + Botan::X509::PEM_encode(key), + Botan::X509::PEM_encode(*public_key)); + // Test PEM public key round trips OK try { |