aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/prov/pkcs11/p11_ecdh.cpp5
-rw-r--r--src/lib/prov/pkcs11/p11_ecdh.h2
-rw-r--r--src/lib/prov/pkcs11/p11_ecdsa.cpp5
-rw-r--r--src/lib/prov/pkcs11/p11_ecdsa.h2
-rw-r--r--src/lib/prov/pkcs11/p11_rsa.cpp11
-rw-r--r--src/lib/prov/pkcs11/p11_rsa.h2
-rw-r--r--src/lib/prov/tpm/tpm.h2
-rw-r--r--src/lib/pubkey/curve25519/curve25519.cpp5
-rw-r--r--src/lib/pubkey/curve25519/curve25519.h2
-rw-r--r--src/lib/pubkey/dh/dh.cpp5
-rw-r--r--src/lib/pubkey/dh/dh.h2
-rw-r--r--src/lib/pubkey/dsa/dsa.cpp5
-rw-r--r--src/lib/pubkey/dsa/dsa.h2
-rw-r--r--src/lib/pubkey/ecdh/ecdh.cpp5
-rw-r--r--src/lib/pubkey/ecdh/ecdh.h2
-rw-r--r--src/lib/pubkey/ecdsa/ecdsa.cpp5
-rw-r--r--src/lib/pubkey/ecdsa/ecdsa.h2
-rw-r--r--src/lib/pubkey/ecgdsa/ecgdsa.cpp5
-rw-r--r--src/lib/pubkey/ecgdsa/ecgdsa.h2
-rw-r--r--src/lib/pubkey/ecies/ecies.cpp5
-rw-r--r--src/lib/pubkey/eckcdsa/eckcdsa.cpp5
-rw-r--r--src/lib/pubkey/eckcdsa/eckcdsa.h2
-rw-r--r--src/lib/pubkey/ed25519/ed25519.h2
-rw-r--r--src/lib/pubkey/ed25519/ed25519_key.cpp5
-rw-r--r--src/lib/pubkey/elgamal/elgamal.cpp5
-rw-r--r--src/lib/pubkey/elgamal/elgamal.h2
-rw-r--r--src/lib/pubkey/gost_3410/gost_3410.cpp5
-rw-r--r--src/lib/pubkey/gost_3410/gost_3410.h2
-rw-r--r--src/lib/pubkey/mce/mceliece.h2
-rw-r--r--src/lib/pubkey/mce/mceliece_key.cpp7
-rw-r--r--src/lib/pubkey/pk_keys.h12
-rw-r--r--src/lib/pubkey/rsa/rsa.cpp5
-rw-r--r--src/lib/pubkey/rsa/rsa.h2
-rw-r--r--src/lib/pubkey/sm2/sm2.cpp5
-rw-r--r--src/lib/pubkey/sm2/sm2.h2
-rw-r--r--src/lib/pubkey/xmss/xmss.h2
-rw-r--r--src/lib/pubkey/xmss/xmss_privatekey.cpp6
-rw-r--r--src/lib/pubkey/xmss/xmss_wots.h5
-rw-r--r--src/tests/test_pubkey.cpp14
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
{