diff options
author | Jack Lloyd <[email protected]> | 2016-11-12 01:53:56 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2016-11-12 01:53:56 -0500 |
commit | 9c72dabc9dc73e2603c22dfce48611b5b626238b (patch) | |
tree | bda4f84f78bfbdd28e2199ee8f9998b08cc3c634 | |
parent | 618f890fd7ede74c728612ca8bc590c72ee353f1 (diff) |
Pubkey cleanups
Add Public_Key::key_length usable for policy checking (as in
TLS::Policy::check_peer_key_acceptable)
Remove Public_Key::max_input_bits because it didn't make much sense
for most algorithms actually.
Remove message_parts and message_part_size from PK_Ops
44 files changed, 134 insertions, 308 deletions
diff --git a/src/lib/prov/openssl/openssl.h b/src/lib/prov/openssl/openssl.h index 8b2b41c1d..e28fb2931 100644 --- a/src/lib/prov/openssl/openssl.h +++ b/src/lib/prov/openssl/openssl.h @@ -8,7 +8,7 @@ #ifndef BOTAN_INTERNAL_OPENSSL_H__ #define BOTAN_INTERNAL_OPENSSL_H__ -#include <botan/internal/pk_ops.h> +#include <botan/pk_ops_fwd.h> #include <botan/secmem.h> #include <botan/exceptn.h> #include <memory> diff --git a/src/lib/prov/openssl/openssl_ec.cpp b/src/lib/prov/openssl/openssl_ec.cpp index ca4352370..51d24a119 100644 --- a/src/lib/prov/openssl/openssl_ec.cpp +++ b/src/lib/prov/openssl/openssl_ec.cpp @@ -117,8 +117,6 @@ class OpenSSL_ECDSA_Verification_Operation : public PK_Ops::Verification_with_EM m_order_bits = ::EC_GROUP_get_degree(group); } - size_t message_parts() const override { return 2; } - size_t message_part_size() const override { return (m_order_bits + 7) / 8; } size_t max_input_bits() const override { return m_order_bits; } bool with_recovery() const override { return false; } @@ -126,7 +124,8 @@ class OpenSSL_ECDSA_Verification_Operation : public PK_Ops::Verification_with_EM bool verify(const byte msg[], size_t msg_len, const byte sig_bytes[], size_t sig_len) override { - if(sig_len != message_part_size() * message_parts()) + const size_t order_bytes = (m_order_bits + 7) / 8; + if(sig_len != 2 * order_bytes) return false; std::unique_ptr<ECDSA_SIG, std::function<void (ECDSA_SIG*)>> sig(nullptr, ECDSA_SIG_free); @@ -172,7 +171,7 @@ class OpenSSL_ECDSA_Signing_Operation : public PK_Ops::Signature_with_EMSA if(!sig) throw OpenSSL_Error("ECDSA_do_sign"); - const size_t order_bytes = message_part_size(); + const size_t order_bytes = (m_order_bits + 7) / 8; const size_t r_bytes = BN_num_bytes(sig->r); const size_t s_bytes = BN_num_bytes(sig->s); secure_vector<byte> sigval(2*order_bytes); @@ -181,8 +180,6 @@ class OpenSSL_ECDSA_Signing_Operation : public PK_Ops::Signature_with_EMSA return sigval; } - size_t message_parts() const override { return 2; } - size_t message_part_size() const override { return (m_order_bits + 7) / 8; } size_t max_input_bits() const override { return m_order_bits; } private: diff --git a/src/lib/prov/openssl/openssl_rsa.cpp b/src/lib/prov/openssl/openssl_rsa.cpp index b03b747aa..77f74fab6 100644 --- a/src/lib/prov/openssl/openssl_rsa.cpp +++ b/src/lib/prov/openssl/openssl_rsa.cpp @@ -106,8 +106,6 @@ class OpenSSL_RSA_Decryption_Operation : public PK_Ops::Decryption throw OpenSSL_Error("d2i_RSAPrivateKey"); } - size_t max_input_bits() const override { return ::BN_num_bits(m_openssl_rsa->n) - 1; } - secure_vector<byte> decrypt(byte& valid_mask, const byte msg[], size_t msg_len) override { diff --git a/src/lib/prov/pkcs11/p11_ecc_key.cpp b/src/lib/prov/pkcs11/p11_ecc_key.cpp index 6ab713d3a..52f98b079 100644 --- a/src/lib/prov/pkcs11/p11_ecc_key.cpp +++ b/src/lib/prov/pkcs11/p11_ecc_key.cpp @@ -48,11 +48,6 @@ PKCS11_EC_PublicKey::PKCS11_EC_PublicKey(Session& session, ObjectHandle handle) m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT; } -size_t PKCS11_EC_PublicKey::max_input_bits() const - { - return domain().get_order().bits(); - } - PKCS11_EC_PublicKey::PKCS11_EC_PublicKey(Session& session, const EC_PublicKeyImportProperties& props) : Object(session, props) { @@ -106,7 +101,7 @@ PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session, const std::vector<b m_public_key = decode_public_point(public_key.get_attribute_value(AttributeType::EcPoint), m_domain_params.get_curve()); } -size_t PKCS11_EC_PrivateKey::max_input_bits() const +size_t PKCS11_EC_PrivateKey::key_length() const { return m_domain_params.get_order().bits(); } @@ -118,7 +113,7 @@ std::vector<byte> PKCS11_EC_PrivateKey::x509_subject_public_key() const size_t PKCS11_EC_PrivateKey::estimated_strength() const { - return ecp_work_factor(domain().get_curve().get_p().bits()); + return ecp_work_factor(key_length()); } bool PKCS11_EC_PrivateKey::check_key(RandomNumberGenerator&, bool) const diff --git a/src/lib/prov/pkcs11/p11_ecc_key.h b/src/lib/prov/pkcs11/p11_ecc_key.h index 151feed37..0a222cb79 100644 --- a/src/lib/prov/pkcs11/p11_ecc_key.h +++ b/src/lib/prov/pkcs11/p11_ecc_key.h @@ -89,8 +89,6 @@ class BOTAN_DLL PKCS11_EC_PublicKey : public virtual EC_PublicKey, * @param props the attributes of the public key */ PKCS11_EC_PublicKey(Session& session, const EC_PublicKeyImportProperties& props); - - size_t max_input_bits() const override; }; /// Properties for generating a PKCS#11 EC private key @@ -203,10 +201,10 @@ class BOTAN_DLL PKCS11_EC_PrivateKey : public virtual Private_Key, // Private_Key methods - std::size_t max_input_bits() const override; - std::vector<byte> x509_subject_public_key() const override; + std::size_t key_length() const override; + std::size_t estimated_strength() const override; bool check_key(RandomNumberGenerator&, bool) const override; diff --git a/src/lib/prov/pkcs11/p11_ecdsa.cpp b/src/lib/prov/pkcs11/p11_ecdsa.cpp index 44f116f88..c2ba02e0f 100644 --- a/src/lib/prov/pkcs11/p11_ecdsa.cpp +++ b/src/lib/prov/pkcs11/p11_ecdsa.cpp @@ -61,16 +61,6 @@ class PKCS11_ECDSA_Signature_Operation : public PK_Ops::Signature : PK_Ops::Signature(), m_key(key), m_order(key.domain().get_order()), m_mechanism(MechanismWrapper::create_ecdsa_mechanism(emsa)) {} - size_t message_parts() const override - { - return 2; - } - - size_t message_part_size() const override - { - return m_order.bytes(); - } - void update(const byte msg[], size_t msg_len) override { if(!m_initialized) @@ -126,21 +116,6 @@ class PKCS11_ECDSA_Verification_Operation : public PK_Ops::Verification : PK_Ops::Verification(), m_key(key), m_order(key.domain().get_order()), m_mechanism(MechanismWrapper::create_ecdsa_mechanism(emsa)) {} - size_t message_parts() const override - { - return 2; - } - - size_t message_part_size() const override - { - return m_order.bytes(); - } - - size_t max_input_bits() const override - { - return m_order.bits(); - } - void update(const byte msg[], size_t msg_len) override { if(!m_initialized) diff --git a/src/lib/prov/pkcs11/p11_ecdsa.h b/src/lib/prov/pkcs11/p11_ecdsa.h index aab56f1f2..a4c3df3ea 100644 --- a/src/lib/prov/pkcs11/p11_ecdsa.h +++ b/src/lib/prov/pkcs11/p11_ecdsa.h @@ -48,11 +48,6 @@ class BOTAN_DLL PKCS11_ECDSA_PublicKey final : public PKCS11_EC_PublicKey, publi return "ECDSA"; } - inline std::size_t max_input_bits() const override - { - return domain().get_order().bits(); - } - /// @return the exported ECDSA public key ECDSA_PublicKey export_key() const; @@ -100,11 +95,6 @@ class BOTAN_DLL PKCS11_ECDSA_PrivateKey final : public PKCS11_EC_PrivateKey return "ECDSA"; } - inline size_t message_parts() const override - { - return 2; - } - /// @return the exported ECDSA private key ECDSA_PrivateKey export_key() const; diff --git a/src/lib/prov/pkcs11/p11_rsa.cpp b/src/lib/prov/pkcs11/p11_rsa.cpp index 1e5f3341f..0312f76bf 100644 --- a/src/lib/prov/pkcs11/p11_rsa.cpp +++ b/src/lib/prov/pkcs11/p11_rsa.cpp @@ -128,11 +128,6 @@ class PKCS11_RSA_Decryption_Operation final : public PK_Ops::Decryption m_bits = m_key.get_n().bits() - 1; } - size_t max_input_bits() const override - { - return m_bits; - } - secure_vector<byte> decrypt(byte& valid_mask, const byte ciphertext[], size_t ciphertext_len) override { valid_mask = 0; @@ -208,11 +203,6 @@ class PKCS11_RSA_Signature_Operation : public PK_Ops::Signature : m_key(key), m_mechanism(MechanismWrapper::create_rsa_sign_mechanism(padding)) {} - size_t message_part_size() const override - { - return m_key.get_n().bytes(); - } - void update(const byte msg[], size_t msg_len) override { if(!m_initialized) @@ -268,16 +258,6 @@ class PKCS11_RSA_Verification_Operation : public PK_Ops::Verification : m_key(key), m_mechanism(MechanismWrapper::create_rsa_sign_mechanism(padding)) {} - size_t message_part_size() const override - { - return m_key.get_n().bytes(); - } - - size_t max_input_bits() const override - { - return m_key.get_n().bits() - 1; - } - void update(const byte msg[], size_t msg_len) override { if(!m_initialized) diff --git a/src/lib/prov/tpm/tpm.cpp b/src/lib/prov/tpm/tpm.cpp index 7604a9be0..cb5a242eb 100644 --- a/src/lib/prov/tpm/tpm.cpp +++ b/src/lib/prov/tpm/tpm.cpp @@ -335,10 +335,10 @@ BigInt TPM_PrivateKey::get_e() const size_t TPM_PrivateKey::estimated_strength() const { - return if_work_factor(get_n().bits()); + return if_work_factor(key_length()); } -size_t TPM_PrivateKey::max_input_bits() const +size_t TPM_PrivateKey::key_length() const { return get_n().bits(); } diff --git a/src/lib/prov/tpm/tpm.h b/src/lib/prov/tpm/tpm.h index 413896df1..804d42e70 100644 --- a/src/lib/prov/tpm/tpm.h +++ b/src/lib/prov/tpm/tpm.h @@ -150,7 +150,7 @@ class BOTAN_DLL TPM_PrivateKey : public Private_Key size_t estimated_strength() const override; - size_t max_input_bits() const override; + size_t key_length() const override; AlgorithmIdentifier algorithm_identifier() const override; diff --git a/src/lib/pubkey/curve25519/curve25519.h b/src/lib/pubkey/curve25519/curve25519.h index 3d0311ea4..938bc42d4 100644 --- a/src/lib/pubkey/curve25519/curve25519.h +++ b/src/lib/pubkey/curve25519/curve25519.h @@ -19,7 +19,7 @@ class BOTAN_DLL Curve25519_PublicKey : public virtual Public_Key size_t estimated_strength() const override { return 128; } - size_t max_input_bits() const override { return 256; } + size_t key_length() const override { return 255; } bool check_key(RandomNumberGenerator& rng, bool strong) const override; diff --git a/src/lib/pubkey/dh/dh.h b/src/lib/pubkey/dh/dh.h index 40011cb1c..7d126c749 100644 --- a/src/lib/pubkey/dh/dh.h +++ b/src/lib/pubkey/dh/dh.h @@ -21,7 +21,6 @@ class BOTAN_DLL DH_PublicKey : public virtual DL_Scheme_PublicKey std::string algo_name() const override { return "DH"; } std::vector<byte> public_value() const; - size_t max_input_bits() const override { return group_p().bits(); } DL_Group::Format group_format() const override { return DL_Group::ANSI_X9_42; } diff --git a/src/lib/pubkey/dl_algo/dl_algo.cpp b/src/lib/pubkey/dl_algo/dl_algo.cpp index d85249750..f5c6ddabb 100644 --- a/src/lib/pubkey/dl_algo/dl_algo.cpp +++ b/src/lib/pubkey/dl_algo/dl_algo.cpp @@ -13,9 +13,14 @@ namespace Botan { +size_t DL_Scheme_PublicKey::key_length() const + { + return m_group.get_p().bits(); + } + size_t DL_Scheme_PublicKey::estimated_strength() const { - return dl_work_factor(m_group.get_p().bits()); + return dl_work_factor(key_length()); } AlgorithmIdentifier DL_Scheme_PublicKey::algorithm_identifier() const diff --git a/src/lib/pubkey/dl_algo/dl_algo.h b/src/lib/pubkey/dl_algo/dl_algo.h index 78816935e..7e90bc3b7 100644 --- a/src/lib/pubkey/dl_algo/dl_algo.h +++ b/src/lib/pubkey/dl_algo/dl_algo.h @@ -60,6 +60,7 @@ class BOTAN_DLL DL_Scheme_PublicKey : public virtual Public_Key */ virtual DL_Group::Format group_format() const = 0; + size_t key_length() const override; size_t estimated_strength() const override; /** diff --git a/src/lib/pubkey/dsa/dsa.cpp b/src/lib/pubkey/dsa/dsa.cpp index 6ee633a45..f6c5989db 100644 --- a/src/lib/pubkey/dsa/dsa.cpp +++ b/src/lib/pubkey/dsa/dsa.cpp @@ -88,8 +88,6 @@ class DSA_Signature_Operation : public PK_Ops::Signature_with_EMSA { } - size_t message_parts() const override { return 2; } - size_t message_part_size() const override { return m_q.bytes(); } size_t max_input_bits() const override { return m_q.bits(); } secure_vector<byte> raw_sign(const byte msg[], size_t msg_len, @@ -152,8 +150,6 @@ class DSA_Verification_Operation : public PK_Ops::Verification_with_EMSA m_mod_q{Modular_Reducer(dsa.group_q())} {} - size_t message_parts() const override { return 2; } - size_t message_part_size() const override { return m_q.bytes(); } size_t max_input_bits() const override { return m_q.bits(); } bool with_recovery() const override { return false; } diff --git a/src/lib/pubkey/dsa/dsa.h b/src/lib/pubkey/dsa/dsa.h index 157953e71..a0aa5016c 100644 --- a/src/lib/pubkey/dsa/dsa.h +++ b/src/lib/pubkey/dsa/dsa.h @@ -23,7 +23,6 @@ class BOTAN_DLL DSA_PublicKey : public virtual DL_Scheme_PublicKey DL_Group::Format group_format() const override { return DL_Group::ANSI_X9_57; } size_t message_parts() const override { return 2; } size_t message_part_size() const override { return group_q().bytes(); } - size_t max_input_bits() const override { return group_q().bits(); } /** * Load a public key. diff --git a/src/lib/pubkey/ecc_key/ecc_key.cpp b/src/lib/pubkey/ecc_key/ecc_key.cpp index befc2cc4c..ea2bb48e9 100644 --- a/src/lib/pubkey/ecc_key/ecc_key.cpp +++ b/src/lib/pubkey/ecc_key/ecc_key.cpp @@ -18,9 +18,14 @@ namespace Botan { +size_t EC_PublicKey::key_length() const + { + return domain().get_curve().get_p().bits(); + } + size_t EC_PublicKey::estimated_strength() const { - return ecp_work_factor(domain().get_curve().get_p().bits()); + return ecp_work_factor(key_length()); } EC_PublicKey::EC_PublicKey(const EC_Group& dom_par, diff --git a/src/lib/pubkey/ecc_key/ecc_key.h b/src/lib/pubkey/ecc_key/ecc_key.h index ec6806931..375c8e85c 100644 --- a/src/lib/pubkey/ecc_key/ecc_key.h +++ b/src/lib/pubkey/ecc_key/ecc_key.h @@ -88,6 +88,7 @@ class BOTAN_DLL EC_PublicKey : public virtual Public_Key EC_Group_Encoding domain_format() const { return m_domain_encoding; } + size_t key_length() const override; size_t estimated_strength() const override; protected: diff --git a/src/lib/pubkey/ecdh/ecdh.h b/src/lib/pubkey/ecdh/ecdh.h index 132a3d47d..ce192523e 100644 --- a/src/lib/pubkey/ecdh/ecdh.h +++ b/src/lib/pubkey/ecdh/ecdh.h @@ -45,15 +45,6 @@ class BOTAN_DLL ECDH_PublicKey : public virtual EC_PublicKey std::string algo_name() const override { return "ECDH"; } /** - * Get the maximum number of bits allowed to be fed to this key. - * This is the bitlength of the order of the base point. - - * @return maximum number of input bits - */ - size_t max_input_bits() const override - { return domain().get_order().bits(); } - - /** * @return public point value */ std::vector<byte> public_value() const diff --git a/src/lib/pubkey/ecdsa/ecdsa.cpp b/src/lib/pubkey/ecdsa/ecdsa.cpp index 0ee66c628..8a6dd840b 100644 --- a/src/lib/pubkey/ecdsa/ecdsa.cpp +++ b/src/lib/pubkey/ecdsa/ecdsa.cpp @@ -56,13 +56,11 @@ class ECDSA_Signature_Operation : public PK_Ops::Signature_with_EMSA { } + size_t max_input_bits() const override { return m_order.bits(); } + secure_vector<byte> raw_sign(const byte msg[], size_t msg_len, RandomNumberGenerator& rng) override; - size_t message_parts() const override { return 2; } - size_t message_part_size() const override { return m_order.bytes(); } - size_t max_input_bits() const override { return m_order.bits(); } - private: const BigInt& m_order; Blinded_Point_Multiply m_base_point; @@ -111,8 +109,6 @@ class ECDSA_Verification_Operation : public PK_Ops::Verification_with_EMSA //m_public_point.precompute_multiples(); } - size_t message_parts() const override { return 2; } - size_t message_part_size() const override { return m_order.bytes(); } size_t max_input_bits() const override { return m_order.bits(); } bool with_recovery() const override { return false; } diff --git a/src/lib/pubkey/ecdsa/ecdsa.h b/src/lib/pubkey/ecdsa/ecdsa.h index 9fad4e921..2198434d7 100644 --- a/src/lib/pubkey/ecdsa/ecdsa.h +++ b/src/lib/pubkey/ecdsa/ecdsa.h @@ -45,14 +45,6 @@ class BOTAN_DLL ECDSA_PublicKey : public virtual EC_PublicKey */ std::string algo_name() const override { return "ECDSA"; } - /** - * Get the maximum number of bits allowed to be fed to this key. - * This is the bitlength of the order of the base point. - * @result the maximum number of input bits - */ - size_t max_input_bits() const override - { return domain().get_order().bits(); } - size_t message_parts() const override { return 2; } size_t message_part_size() const override diff --git a/src/lib/pubkey/ecgdsa/ecgdsa.cpp b/src/lib/pubkey/ecgdsa/ecgdsa.cpp index f21f1bb27..3740c3583 100644 --- a/src/lib/pubkey/ecgdsa/ecgdsa.cpp +++ b/src/lib/pubkey/ecgdsa/ecgdsa.cpp @@ -46,8 +46,6 @@ class ECGDSA_Signature_Operation : public PK_Ops::Signature_with_EMSA secure_vector<byte> raw_sign(const byte msg[], size_t msg_len, RandomNumberGenerator& rng) override; - size_t message_parts() const override { return 2; } - size_t message_part_size() const override { return m_order.bytes(); } size_t max_input_bits() const override { return m_order.bits(); } private: @@ -93,8 +91,6 @@ class ECGDSA_Verification_Operation : public PK_Ops::Verification_with_EMSA { } - size_t message_parts() const override { return 2; } - size_t message_part_size() const override { return m_order.bytes(); } size_t max_input_bits() const override { return m_order.bits(); } bool with_recovery() const override { return false; } diff --git a/src/lib/pubkey/ecgdsa/ecgdsa.h b/src/lib/pubkey/ecgdsa/ecgdsa.h index f90f7bfd4..df5b0e73f 100644 --- a/src/lib/pubkey/ecgdsa/ecgdsa.h +++ b/src/lib/pubkey/ecgdsa/ecgdsa.h @@ -43,14 +43,6 @@ class BOTAN_DLL ECGDSA_PublicKey : public virtual EC_PublicKey */ std::string algo_name() const override { return "ECGDSA"; } - /** - * Get the maximum number of bits allowed to be fed to this key. - * This is the bitlength of the order of the base point. - * @result the maximum number of input bits - */ - size_t max_input_bits() const override - { return domain().get_order().bits(); } - size_t message_parts() const override { return 2; } size_t message_part_size() const override diff --git a/src/lib/pubkey/ecies/ecies.cpp b/src/lib/pubkey/ecies/ecies.cpp index fbf98cbad..b40d21251 100644 --- a/src/lib/pubkey/ecies/ecies.cpp +++ b/src/lib/pubkey/ecies/ecies.cpp @@ -40,11 +40,6 @@ class ECIES_PrivateKey : public EC_PrivateKey, public PK_Key_Agreement_Key return "ECIES"; } - size_t max_input_bits() const override - { - return m_key.max_input_bits(); - } - 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 5e2b3394e..89b5925a2 100644 --- a/src/lib/pubkey/eckcdsa/eckcdsa.cpp +++ b/src/lib/pubkey/eckcdsa/eckcdsa.cpp @@ -60,8 +60,6 @@ class ECKCDSA_Signature_Operation : public PK_Ops::Signature_with_EMSA secure_vector<byte> raw_sign(const byte msg[], size_t msg_len, RandomNumberGenerator& rng) override; - size_t message_parts() const override { return 2; } - size_t message_part_size() const override { return m_order.bytes(); } size_t max_input_bits() const override { return m_order.bits(); } bool has_prefix() override { return true; } @@ -133,8 +131,6 @@ class ECKCDSA_Verification_Operation : public PK_Ops::Verification_with_EMSA bool has_prefix() override { return true; } secure_vector<byte> message_prefix() const override { return m_prefix; } - size_t message_parts() const override { return 2; } - size_t message_part_size() const override { return m_order.bytes(); } size_t max_input_bits() const override { return m_order.bits(); } bool with_recovery() const override { return false; } diff --git a/src/lib/pubkey/eckcdsa/eckcdsa.h b/src/lib/pubkey/eckcdsa/eckcdsa.h index be5daf2da..37c275bfe 100644 --- a/src/lib/pubkey/eckcdsa/eckcdsa.h +++ b/src/lib/pubkey/eckcdsa/eckcdsa.h @@ -43,14 +43,6 @@ class BOTAN_DLL ECKCDSA_PublicKey : public virtual EC_PublicKey */ std::string algo_name() const override { return "ECKCDSA"; } - /** - * Get the maximum number of bits allowed to be fed to this key. - * This is the bitlength of the order of the base point. - * @result the maximum number of input bits - */ - size_t max_input_bits() const override - { return domain().get_order().bits(); } - size_t message_parts() const override { return 2; } size_t message_part_size() const override diff --git a/src/lib/pubkey/elgamal/elgamal.h b/src/lib/pubkey/elgamal/elgamal.h index 6b2e1b68f..f84ffe3d7 100644 --- a/src/lib/pubkey/elgamal/elgamal.h +++ b/src/lib/pubkey/elgamal/elgamal.h @@ -21,8 +21,6 @@ class BOTAN_DLL ElGamal_PublicKey : public virtual DL_Scheme_PublicKey std::string algo_name() const override { return "ElGamal"; } DL_Group::Format group_format() const override { return DL_Group::ANSI_X9_42; } - size_t max_input_bits() const override { return (group_p().bits() - 1); } - /** * Load a public key. * @param alg_id the X.509 algorithm identifier diff --git a/src/lib/pubkey/gost_3410/gost_3410.cpp b/src/lib/pubkey/gost_3410/gost_3410.cpp index f483540d4..ed01450c8 100644 --- a/src/lib/pubkey/gost_3410/gost_3410.cpp +++ b/src/lib/pubkey/gost_3410/gost_3410.cpp @@ -105,8 +105,6 @@ class GOST_3410_Signature_Operation : public PK_Ops::Signature_with_EMSA m_base_point(gost_3410.domain().get_base_point(), m_order), m_x(gost_3410.private_value()) {} - size_t message_parts() const override { return 2; } - size_t message_part_size() const override { return m_order.bytes(); } size_t max_input_bits() const override { return m_order.bits(); } secure_vector<byte> raw_sign(const byte msg[], size_t msg_len, @@ -163,8 +161,6 @@ class GOST_3410_Verification_Operation : public PK_Ops::Verification_with_EMSA m_public_point(gost.public_point()), m_order(gost.domain().get_order()) {} - size_t message_parts() const override { return 2; } - size_t message_part_size() const override { return m_order.bytes(); } size_t max_input_bits() const override { return m_order.bits(); } bool with_recovery() const override { return false; } diff --git a/src/lib/pubkey/gost_3410/gost_3410.h b/src/lib/pubkey/gost_3410/gost_3410.h index 1fe4435c4..c844e0fab 100644 --- a/src/lib/pubkey/gost_3410/gost_3410.h +++ b/src/lib/pubkey/gost_3410/gost_3410.h @@ -48,14 +48,6 @@ class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey std::vector<byte> x509_subject_public_key() const override; - /** - * Get the maximum number of bits allowed to be fed to this key. - * This is the bitlength of the order of the base point. - - * @result the maximum number of input bits - */ - size_t max_input_bits() const override { return domain().get_order().bits(); } - size_t message_parts() const override { return 2; } size_t message_part_size() const override diff --git a/src/lib/pubkey/mce/mceliece.h b/src/lib/pubkey/mce/mceliece.h index c8b2606c5..c46be4a49 100644 --- a/src/lib/pubkey/mce/mceliece.h +++ b/src/lib/pubkey/mce/mceliece.h @@ -35,14 +35,9 @@ class BOTAN_DLL McEliece_PublicKey : public virtual Public_Key std::string algo_name() const override { return "McEliece"; } - /** - * Get the maximum number of bits allowed to be fed to this key. - * @result the maximum number of input bits - */ - size_t max_input_bits() const override { return get_message_word_bit_length(); } - AlgorithmIdentifier algorithm_identifier() const override; + size_t key_length() const override; size_t estimated_strength() const override; std::vector<byte> x509_subject_public_key() const override; @@ -75,11 +70,6 @@ class BOTAN_DLL McEliece_PrivateKey : public virtual McEliece_PublicKey, public virtual Private_Key { public: - /** - * Get the maximum number of bits allowed to be fed to this key. - * @result the maximum number of input bits - */ - size_t max_input_bits() const override { return m_Linv.size(); } /** Generate a McEliece key pair diff --git a/src/lib/pubkey/mce/mceliece_key.cpp b/src/lib/pubkey/mce/mceliece_key.cpp index be34cd746..da92479ef 100644 --- a/src/lib/pubkey/mce/mceliece_key.cpp +++ b/src/lib/pubkey/mce/mceliece_key.cpp @@ -89,6 +89,11 @@ McEliece_PublicKey::McEliece_PublicKey(const McEliece_PublicKey & other) : { } +size_t McEliece_PublicKey::key_length() const + { + return m_code_length; + } + size_t McEliece_PublicKey::estimated_strength() const { return mceliece_work_factor(m_code_length, m_t); diff --git a/src/lib/pubkey/pk_keys.h b/src/lib/pubkey/pk_keys.h index 8ebad48e7..613fbb7dd 100644 --- a/src/lib/pubkey/pk_keys.h +++ b/src/lib/pubkey/pk_keys.h @@ -44,6 +44,14 @@ class BOTAN_DLL Public_Key virtual size_t estimated_strength() const = 0; /** + * Return an integer value best approximating the length of the + * primary security parameter. For example for RSA this will be + * the size of the modulus, for ECDSA the size of the ECC group, + * and for McEliece the size of the code will be returned. + */ + virtual size_t key_length() const = 0; + + /** * Get the OID of the underlying public key scheme. * @return OID of the public key scheme */ @@ -59,23 +67,6 @@ class BOTAN_DLL Public_Key virtual bool check_key(RandomNumberGenerator& rng, bool strong) const = 0; - /** - * Find out the number of message parts supported by this scheme. - * @return number of message parts - */ - virtual size_t message_parts() const { return 1; } - - /** - * Find out the message part size supported by this scheme/key. - * @return size of the message parts in bits - */ - virtual size_t message_part_size() const { return 0; } - - /** - * Get the maximum message size in bits supported by this public key. - * @return maximum message size in bits - */ - virtual size_t max_input_bits() const = 0; /** * @return X.509 AlgorithmIdentifier for this key @@ -90,6 +81,31 @@ class BOTAN_DLL Public_Key // Internal or non-public declarations follow /** + * Returns more than 1 if the output of this algorithm + * (ciphertext, signature) should be treated as more than one + * value. This is used for algorithms like DSA and ECDSA, where + * the (r,s) output pair can be encoded as either a plain binary + * list or a TLV tagged DER encoding depending on the protocol. + * + * This function is public but applications should have few + * reasons to ever call this. + * + * @return number of message parts + */ + virtual size_t message_parts() const { return 1; } + + /** + * Returns how large each of the message parts refered to + * by message_parts() is + * + * This function is public but applications should have few + * reasons to ever call this. + * + * @return size of the message parts in bits + */ + virtual size_t message_part_size() const { return 0; } + + /** * This is an internal library function exposed on key types. * In almost all cases applications should use wrappers in pubkey.h * diff --git a/src/lib/pubkey/pk_ops.cpp b/src/lib/pubkey/pk_ops.cpp index 1017518a7..dba82345e 100644 --- a/src/lib/pubkey/pk_ops.cpp +++ b/src/lib/pubkey/pk_ops.cpp @@ -44,11 +44,6 @@ PK_Ops::Decryption_with_EME::Decryption_with_EME(const std::string& eme) PK_Ops::Decryption_with_EME::~Decryption_with_EME() {} -size_t PK_Ops::Decryption_with_EME::max_input_bits() const - { - return m_eme->maximum_input_size(max_raw_input_bits()); - } - secure_vector<byte> PK_Ops::Decryption_with_EME::decrypt(byte& valid_mask, const byte ciphertext[], diff --git a/src/lib/pubkey/pk_ops.h b/src/lib/pubkey/pk_ops.h index 2eb4b8930..57774c3f4 100644 --- a/src/lib/pubkey/pk_ops.h +++ b/src/lib/pubkey/pk_ops.h @@ -26,12 +26,12 @@ namespace PK_Ops { class BOTAN_DLL Encryption { public: - virtual size_t max_input_bits() const = 0; - virtual secure_vector<byte> encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator& rng) = 0; + virtual size_t max_input_bits() const = 0; + virtual ~Encryption() {} }; @@ -41,8 +41,6 @@ class BOTAN_DLL Encryption class BOTAN_DLL Decryption { public: - virtual size_t max_input_bits() const = 0; - virtual secure_vector<byte> decrypt(byte& valid_mask, const byte ciphertext[], size_t ciphertext_len) = 0; @@ -69,24 +67,6 @@ class BOTAN_DLL Verification */ virtual bool is_valid_signature(const byte sig[], size_t sig_len) = 0; - /** - * Get the maximum message size in bits supported by this public key. - * @return maximum message in bits - */ - virtual size_t max_input_bits() const = 0; - - /** - * Find out the number of message parts supported by this scheme. - * @return number of message parts - */ - virtual size_t message_parts() const { return 1; } - - /** - * Find out the message part size supported by this scheme/key. - * @return size of the message parts - */ - virtual size_t message_part_size() const { return 0; } - virtual ~Verification() {} }; @@ -96,18 +76,6 @@ class BOTAN_DLL Verification class BOTAN_DLL Signature { public: - /** - * Find out the number of message parts supported by this scheme. - * @return number of message parts - */ - virtual size_t message_parts() const { return 1; } - - /** - * Find out the message part size supported by this scheme/key. - * @return size of the message parts - */ - virtual size_t message_part_size() const { return 0; } - /* * Add more data to the message currently being signed * @param msg the message diff --git a/src/lib/pubkey/pk_ops_impl.h b/src/lib/pubkey/pk_ops_impl.h index 5fe5623e7..bde119ab4 100644 --- a/src/lib/pubkey/pk_ops_impl.h +++ b/src/lib/pubkey/pk_ops_impl.h @@ -1,3 +1,4 @@ + /* * (C) 2015 Jack Lloyd * @@ -35,8 +36,6 @@ class Encryption_with_EME : public Encryption class Decryption_with_EME : public Decryption { public: - size_t max_input_bits() const override; - secure_vector<byte> decrypt(byte& valid_mask, const byte msg[], size_t msg_len) override; @@ -52,6 +51,8 @@ class Decryption_with_EME : public Decryption class Verification_with_EMSA : public Verification { public: + ~Verification_with_EMSA(); + void update(const byte msg[], size_t msg_len) override; bool is_valid_signature(const byte sig[], size_t sig_len) override; @@ -59,10 +60,15 @@ class Verification_with_EMSA : public Verification const byte sig[], size_t sig_len); std::string hash_for_signature() { return m_hash; } - protected: + protected: explicit Verification_with_EMSA(const std::string& emsa); - ~Verification_with_EMSA(); + + /** + * Get the maximum message size in bits supported by this public key. + * @return maximum message in bits + */ + virtual size_t max_input_bits() const = 0; /** * @return boolean specifying if this signature scheme uses diff --git a/src/lib/pubkey/pubkey.cpp b/src/lib/pubkey/pubkey.cpp index bb76bf68e..580f990a1 100644 --- a/src/lib/pubkey/pubkey.cpp +++ b/src/lib/pubkey/pubkey.cpp @@ -207,48 +207,6 @@ SymmetricKey PK_Key_Agreement::derive_key(size_t key_len, return m_op->agree(key_len, in, in_len, salt, salt_len); } -namespace { - -std::vector<byte> der_encode_signature(const std::vector<byte>& sig, size_t parts) - { - if(sig.size() % parts) - throw Encoding_Error("PK_Signer: strange signature size found"); - const size_t SIZE_OF_PART = sig.size() / parts; - - std::vector<BigInt> sig_parts(parts); - for(size_t j = 0; j != sig_parts.size(); ++j) - sig_parts[j].binary_decode(&sig[SIZE_OF_PART*j], SIZE_OF_PART); - - return DER_Encoder() - .start_cons(SEQUENCE) - .encode_list(sig_parts) - .end_cons() - .get_contents_unlocked(); - } - -std::vector<byte> der_decode_signature(const byte sig[], size_t len, - size_t part_size, size_t parts) - { - std::vector<byte> real_sig; - BER_Decoder decoder(sig, len); - BER_Decoder ber_sig = decoder.start_cons(SEQUENCE); - - size_t count = 0; - while(ber_sig.more_items()) - { - BigInt sig_part; - ber_sig.decode(sig_part); - real_sig += BigInt::encode_1363(sig_part, part_size); - ++count; - } - - if(count != parts) - throw Decoding_Error("PK_Verifier: signature size invalid"); - return real_sig; - } - -} - PK_Signer::PK_Signer(const Private_Key& key, RandomNumberGenerator& rng, const std::string& emsa, @@ -259,6 +217,8 @@ PK_Signer::PK_Signer(const Private_Key& key, if(!m_op) throw Invalid_Argument("Key type " + key.algo_name() + " does not support signature generation"); m_sig_format = format; + m_parts = key.message_parts(); + m_part_size = key.message_part_size(); } PK_Signer::~PK_Signer() { /* for unique_ptr */ } @@ -270,16 +230,29 @@ void PK_Signer::update(const byte in[], size_t length) std::vector<byte> PK_Signer::signature(RandomNumberGenerator& rng) { - const std::vector<byte> plain_sig = unlock(m_op->sign(rng)); - const size_t parts = m_op->message_parts(); + const std::vector<byte> sig = unlock(m_op->sign(rng)); - if(parts == 1 || m_sig_format == IEEE_1363) - return plain_sig; + if(m_sig_format == IEEE_1363) + { + return sig; + } else if(m_sig_format == DER_SEQUENCE) - return der_encode_signature(plain_sig, parts); + { + if(sig.size() % m_parts != 0 || sig.size() != m_parts * m_part_size) + throw Internal_Error("PK_Signer: DER signature sizes unexpected, cannot encode"); + + std::vector<BigInt> sig_parts(m_parts); + for(size_t i = 0; i != sig_parts.size(); ++i) + sig_parts[i].binary_decode(&sig[m_part_size*i], m_part_size); + + return DER_Encoder() + .start_cons(SEQUENCE) + .encode_list(sig_parts) + .end_cons() + .get_contents_unlocked(); + } else - throw Encoding_Error("PK_Signer: Unknown signature format " + - std::to_string(m_sig_format)); + throw Internal_Error("PK_Signer: Invalid signature format enum"); } PK_Verifier::PK_Verifier(const Public_Key& key, @@ -291,14 +264,16 @@ PK_Verifier::PK_Verifier(const Public_Key& key, if(!m_op) throw Invalid_Argument("Key type " + key.algo_name() + " does not support signature verification"); m_sig_format = format; + m_parts = key.message_parts(); + m_part_size = key.message_part_size(); } PK_Verifier::~PK_Verifier() { /* for unique_ptr */ } void PK_Verifier::set_input_format(Signature_Format format) { - if(m_op->message_parts() == 1 && format != IEEE_1363) - throw Invalid_State("PK_Verifier: This algorithm always uses IEEE 1363"); + if(format != IEEE_1363 && m_parts == 1) + throw Invalid_Argument("PK_Verifier: This algorithm does not support DER encoding"); m_sig_format = format; } @@ -323,15 +298,26 @@ bool PK_Verifier::check_signature(const byte sig[], size_t length) } else if(m_sig_format == DER_SEQUENCE) { - std::vector<byte> real_sig = der_decode_signature(sig, length, - m_op->message_part_size(), - m_op->message_parts()); + std::vector<byte> real_sig; + BER_Decoder decoder(sig, length); + BER_Decoder ber_sig = decoder.start_cons(SEQUENCE); + + size_t count = 0; + while(ber_sig.more_items()) + { + BigInt sig_part; + ber_sig.decode(sig_part); + real_sig += BigInt::encode_1363(sig_part, m_part_size); + ++count; + } + + if(count != m_parts) + throw Decoding_Error("PK_Verifier: signature size invalid"); return m_op->is_valid_signature(real_sig.data(), real_sig.size()); } else - throw Decoding_Error("PK_Verifier: Unknown signature format " + - std::to_string(m_sig_format)); + throw Internal_Error("PK_Verifier: Invalid signature format enum"); } catch(Invalid_Argument&) { return false; } } diff --git a/src/lib/pubkey/pubkey.h b/src/lib/pubkey/pubkey.h index b9ad0672d..398db82d2 100644 --- a/src/lib/pubkey/pubkey.h +++ b/src/lib/pubkey/pubkey.h @@ -276,6 +276,7 @@ class BOTAN_DLL PK_Signer final private: std::unique_ptr<PK_Ops::Signature> m_op; Signature_Format m_sig_format; + size_t m_parts, m_part_size; }; /** @@ -389,6 +390,7 @@ class BOTAN_DLL PK_Verifier final private: std::unique_ptr<PK_Ops::Verification> m_op; Signature_Format m_sig_format; + size_t m_parts, m_part_size; }; /** diff --git a/src/lib/pubkey/rsa/rsa.cpp b/src/lib/pubkey/rsa/rsa.cpp index eae95fe02..4302aa88a 100644 --- a/src/lib/pubkey/rsa/rsa.cpp +++ b/src/lib/pubkey/rsa/rsa.cpp @@ -25,9 +25,14 @@ namespace Botan { +size_t RSA_PublicKey::key_length() const + { + return m_n.bits(); + } + size_t RSA_PublicKey::estimated_strength() const { - return if_work_factor(m_n.bits()); + return if_work_factor(key_length()); } AlgorithmIdentifier RSA_PublicKey::algorithm_identifier() const diff --git a/src/lib/pubkey/rsa/rsa.h b/src/lib/pubkey/rsa/rsa.h index 98d9217b8..f576a5f07 100644 --- a/src/lib/pubkey/rsa/rsa.h +++ b/src/lib/pubkey/rsa/rsa.h @@ -53,8 +53,7 @@ class BOTAN_DLL RSA_PublicKey : public virtual Public_Key */ const BigInt& get_e() const { return m_e; } - size_t max_input_bits() const override { return (m_n.bits() - 1); } - + size_t key_length() const override; size_t estimated_strength() const override; std::unique_ptr<PK_Ops::Encryption> diff --git a/src/lib/tls/tls_policy.cpp b/src/lib/tls/tls_policy.cpp index 3ed02f4c5..c7c285716 100644 --- a/src/lib/tls/tls_policy.cpp +++ b/src/lib/tls/tls_policy.cpp @@ -175,14 +175,12 @@ void Policy::check_peer_key_acceptable(const Public_Key& public_key) const { const std::string algo_name = public_key.algo_name(); - // FIXME this is not really the right way to do this - size_t keylength = public_key.max_input_bits(); + const size_t keylength = public_key.key_length(); size_t expected_keylength = 0; if(algo_name == "RSA") { expected_keylength = minimum_rsa_bits(); - keylength += 1; // fixup for use of max_input_bits above } else if(algo_name == "DH") { diff --git a/src/lib/x509/x509_ca.cpp b/src/lib/x509/x509_ca.cpp index bc3763c5a..f7f5471f4 100644 --- a/src/lib/x509/x509_ca.cpp +++ b/src/lib/x509/x509_ca.cpp @@ -234,9 +234,6 @@ PK_Signer* choose_sig_format(const Private_Key& key, std::unique_ptr<HashFunction> hash(HashFunction::create_or_throw(hash_fn)); - if(key.max_input_bits() < hash->output_length() * 8) - throw Invalid_Argument("Key is too small for chosen hash function"); - std::string padding; if(algo_name == "RSA") { diff --git a/src/lib/x509/x509_ca.h b/src/lib/x509/x509_ca.h index c96a709d5..5b5eb6fc8 100644 --- a/src/lib/x509/x509_ca.h +++ b/src/lib/x509/x509_ca.h @@ -12,7 +12,6 @@ #include <botan/x509_crl.h> #include <botan/x509_ext.h> #include <botan/pkcs10.h> -#include <botan/pubkey.h> #if defined(BOTAN_HAS_SYSTEM_RNG) #include <botan/system_rng.h> @@ -20,6 +19,8 @@ namespace Botan { +class PK_Signer; + /** * This class represents X.509 Certificate Authorities (CAs). */ diff --git a/src/lib/x509/x509self.cpp b/src/lib/x509/x509self.cpp index a59632858..b59b45f6a 100644 --- a/src/lib/x509/x509self.cpp +++ b/src/lib/x509/x509self.cpp @@ -9,6 +9,7 @@ #include <botan/x509_ext.h> #include <botan/x509_ca.h> #include <botan/der_enc.h> +#include <botan/pubkey.h> #include <botan/oids.h> namespace Botan { diff --git a/src/tests/test_pubkey.cpp b/src/tests/test_pubkey.cpp index b37077b33..a96097de1 100644 --- a/src/tests/test_pubkey.cpp +++ b/src/tests/test_pubkey.cpp @@ -198,24 +198,6 @@ PK_Encryption_Decryption_Test::run_one_test(const std::string&, const VarMap& va //std::unique_ptr<Botan::Public_Key> pubkey(Botan::X509::load_key(Botan::X509::BER_encode(*privkey))); Botan::Public_Key* pubkey = privkey.get(); - try { - // test EME::maximum_input_size() - std::unique_ptr<Botan::EME> eme(Botan::get_eme(padding)); - - if(eme) - { - size_t max_input_size = eme->maximum_input_size(1); - result.test_eq("maximum input size( 1 ) should always return 0", max_input_size, 0); - size_t keybits = pubkey->max_input_bits(); - max_input_size = eme->maximum_input_size(keybits); - result.test_gte("maximum input size( keybits ) > 0", max_input_size, 1); - } - } - catch(Botan::Lookup_Error&) - { - result.note_missing("PK padding " + padding); - } - for(auto&& enc_provider : possible_pk_providers()) { std::unique_ptr<Botan::PK_Encryptor> encryptor; |