diff options
author | Jack Lloyd <[email protected]> | 2021-05-22 11:49:49 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2021-05-22 11:50:34 -0400 |
commit | 9745a8fed0f94d0fd26f6056572eb072d7108840 (patch) | |
tree | 6efcf45d34070e1badbb0ebca9f8b61af8a65c78 | |
parent | cb803e0c1b016428f9851eb9705498bc253bdb0f (diff) |
Prevent using non-sensical padding schemes
Most padding schemes require message recovery, which, now that NR and
RW have both been removed, limits their usage to RSA.
-rw-r--r-- | src/lib/pk_pad/emsa.h | 6 | ||||
-rw-r--r-- | src/lib/pk_pad/emsa1/emsa1.h | 2 | ||||
-rw-r--r-- | src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h | 3 | ||||
-rw-r--r-- | src/lib/pk_pad/emsa_pssr/pssr.h | 4 | ||||
-rw-r--r-- | src/lib/pk_pad/emsa_raw/emsa_raw.h | 2 | ||||
-rw-r--r-- | src/lib/pk_pad/emsa_x931/emsa_x931.h | 2 | ||||
-rw-r--r-- | src/lib/pk_pad/iso9796/iso9796.h | 5 | ||||
-rw-r--r-- | src/lib/prov/openssl/openssl_rsa.cpp | 4 | ||||
-rw-r--r-- | src/lib/pubkey/pk_ops.cpp | 14 | ||||
-rw-r--r-- | src/lib/pubkey/pk_ops_impl.h | 5 | ||||
-rw-r--r-- | src/lib/pubkey/rsa/rsa.cpp | 4 |
11 files changed, 43 insertions, 8 deletions
diff --git a/src/lib/pk_pad/emsa.h b/src/lib/pk_pad/emsa.h index 5a8f0daec..7aaba47fd 100644 --- a/src/lib/pk_pad/emsa.h +++ b/src/lib/pk_pad/emsa.h @@ -56,6 +56,12 @@ class BOTAN_TEST_API EMSA virtual secure_vector<uint8_t> raw_data() = 0; /** + * Return true if using this EMSA correctly requires a signature scheme + * with message recovery + */ + virtual bool requires_message_recovery() const = 0; + + /** * Return the encoding of a message * @param msg the result of raw_data() * @param output_bits the desired output bit size diff --git a/src/lib/pk_pad/emsa1/emsa1.h b/src/lib/pk_pad/emsa1/emsa1.h index 514f2ee9e..2646fcfa7 100644 --- a/src/lib/pk_pad/emsa1/emsa1.h +++ b/src/lib/pk_pad/emsa1/emsa1.h @@ -29,6 +29,8 @@ class EMSA1 final : public EMSA std::string name() const override; + bool requires_message_recovery() const override { return false; } + AlgorithmIdentifier config_for_x509(const Private_Key& key, const std::string& cert_hash_name) const override; private: diff --git a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h index 82d70651a..2739cd257 100644 --- a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h +++ b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h @@ -46,6 +46,8 @@ class EMSA_PKCS1v15 final : public EMSA AlgorithmIdentifier config_for_x509(const Private_Key& key, const std::string& cert_hash_name) const override; + + bool requires_message_recovery() const override { return true; } private: std::unique_ptr<HashFunction> m_hash; std::vector<uint8_t> m_hash_id; @@ -83,6 +85,7 @@ class EMSA_PKCS1v15_Raw final : public EMSA else return "EMSA3(Raw," + m_hash_name + ")"; } + bool requires_message_recovery() const override { return true; } private: size_t m_hash_output_len = 0; std::string m_hash_name; diff --git a/src/lib/pk_pad/emsa_pssr/pssr.h b/src/lib/pk_pad/emsa_pssr/pssr.h index 62af37b7d..b6bb0fd17 100644 --- a/src/lib/pk_pad/emsa_pssr/pssr.h +++ b/src/lib/pk_pad/emsa_pssr/pssr.h @@ -37,6 +37,8 @@ class PSSR final : public EMSA AlgorithmIdentifier config_for_x509(const Private_Key& key, const std::string& cert_hash_name) const override; + + bool requires_message_recovery() const override { return true; } private: void update(const uint8_t input[], size_t length) override; @@ -77,6 +79,8 @@ class PSSR_Raw final : public EMSA std::unique_ptr<EMSA> new_object() override; std::string name() const override; + + bool requires_message_recovery() const override { return true; } private: void update(const uint8_t input[], size_t length) override; diff --git a/src/lib/pk_pad/emsa_raw/emsa_raw.h b/src/lib/pk_pad/emsa_raw/emsa_raw.h index 10c39bd35..c8c1c401d 100644 --- a/src/lib/pk_pad/emsa_raw/emsa_raw.h +++ b/src/lib/pk_pad/emsa_raw/emsa_raw.h @@ -25,6 +25,8 @@ class EMSA_Raw final : public EMSA m_expected_size(expected_hash_size) {} std::string name() const override; + + bool requires_message_recovery() const override { return false; } private: void update(const uint8_t[], size_t) override; secure_vector<uint8_t> raw_data() override; diff --git a/src/lib/pk_pad/emsa_x931/emsa_x931.h b/src/lib/pk_pad/emsa_x931/emsa_x931.h index b9906904f..edf7eb2f1 100644 --- a/src/lib/pk_pad/emsa_x931/emsa_x931.h +++ b/src/lib/pk_pad/emsa_x931/emsa_x931.h @@ -30,6 +30,8 @@ class EMSA_X931 final : public EMSA std::string name() const override; + bool requires_message_recovery() const override { return true; } + private: void update(const uint8_t[], size_t) override; secure_vector<uint8_t> raw_data() override; diff --git a/src/lib/pk_pad/iso9796/iso9796.h b/src/lib/pk_pad/iso9796/iso9796.h index fb2a6f699..7e8ad0f68 100644 --- a/src/lib/pk_pad/iso9796/iso9796.h +++ b/src/lib/pk_pad/iso9796/iso9796.h @@ -43,6 +43,8 @@ class ISO_9796_DS2 final : public EMSA std::unique_ptr<EMSA> new_object() override; std::string name() const override; + + bool requires_message_recovery() const override { return true; } private: void update(const uint8_t input[], size_t length) override; @@ -80,6 +82,9 @@ class ISO_9796_DS3 final : public EMSA std::unique_ptr<EMSA> new_object() override; std::string name() const override; + + bool requires_message_recovery() const override { return true; } + private: void update(const uint8_t input[], size_t length) override; diff --git a/src/lib/prov/openssl/openssl_rsa.cpp b/src/lib/prov/openssl/openssl_rsa.cpp index 875dab1d3..4fc9b15b9 100644 --- a/src/lib/prov/openssl/openssl_rsa.cpp +++ b/src/lib/prov/openssl/openssl_rsa.cpp @@ -150,7 +150,7 @@ class OpenSSL_RSA_Verification_Operation final : public PK_Ops::Verification_wit public: OpenSSL_RSA_Verification_Operation(const RSA_PublicKey& rsa, const std::string& emsa) : - PK_Ops::Verification_with_EMSA(emsa), + PK_Ops::Verification_with_EMSA(emsa, true), m_openssl_rsa(nullptr, ::RSA_free) { const std::vector<uint8_t> der = rsa.public_key_bits(); @@ -202,7 +202,7 @@ class OpenSSL_RSA_Signing_Operation final : public PK_Ops::Signature_with_EMSA public: OpenSSL_RSA_Signing_Operation(const RSA_PrivateKey& rsa, const std::string& emsa) : - PK_Ops::Signature_with_EMSA(emsa), + PK_Ops::Signature_with_EMSA(emsa, true), m_openssl_rsa(nullptr, ::RSA_free) { const secure_vector<uint8_t> der = rsa.private_key_bits(); diff --git a/src/lib/pubkey/pk_ops.cpp b/src/lib/pubkey/pk_ops.cpp index d9a0a71a9..c9f25b748 100644 --- a/src/lib/pubkey/pk_ops.cpp +++ b/src/lib/pubkey/pk_ops.cpp @@ -59,12 +59,17 @@ secure_vector<uint8_t> PK_Ops::Key_Agreement_with_KDF::agree(size_t key_len, return z; } -PK_Ops::Signature_with_EMSA::Signature_with_EMSA(const std::string& emsa) : +PK_Ops::Signature_with_EMSA::Signature_with_EMSA(const std::string& emsa, bool with_message_recovery) : Signature(), m_emsa(EMSA::create_or_throw(emsa)), m_hash(hash_for_emsa(emsa)), m_prefix_used(false) { + if(!with_message_recovery && m_emsa->requires_message_recovery()) + { + throw Invalid_Argument("Signature padding method " + emsa + + " requires message recovery, which is not supported by this scheme"); + } } void PK_Ops::Signature_with_EMSA::update(const uint8_t msg[], size_t msg_len) @@ -86,12 +91,17 @@ secure_vector<uint8_t> PK_Ops::Signature_with_EMSA::sign(RandomNumberGenerator& return raw_sign(padded.data(), padded.size(), rng); } -PK_Ops::Verification_with_EMSA::Verification_with_EMSA(const std::string& emsa) : +PK_Ops::Verification_with_EMSA::Verification_with_EMSA(const std::string& emsa, bool with_message_recovery) : Verification(), m_emsa(EMSA::create_or_throw(emsa)), m_hash(hash_for_emsa(emsa)), m_prefix_used(false) { + if(!with_message_recovery && m_emsa->requires_message_recovery()) + { + throw Invalid_Argument("Signature padding method " + emsa + + " requires message recovery, which is not supported by this scheme"); + } } void PK_Ops::Verification_with_EMSA::update(const uint8_t msg[], size_t msg_len) diff --git a/src/lib/pubkey/pk_ops_impl.h b/src/lib/pubkey/pk_ops_impl.h index fffcc87f8..68c819608 100644 --- a/src/lib/pubkey/pk_ops_impl.h +++ b/src/lib/pubkey/pk_ops_impl.h @@ -64,7 +64,7 @@ class Verification_with_EMSA : public Verification std::string hash_for_signature() { return m_hash; } protected: - explicit Verification_with_EMSA(const std::string& emsa); + explicit Verification_with_EMSA(const std::string& emsa, bool has_message_recovery = false); /** * Get the maximum message size in bits supported by this public key. @@ -131,7 +131,8 @@ class Signature_with_EMSA : public Signature secure_vector<uint8_t> sign(RandomNumberGenerator& rng) override; protected: - explicit Signature_with_EMSA(const std::string& emsa); + explicit Signature_with_EMSA(const std::string& emsa, bool with_message_recovery = false); + ~Signature_with_EMSA() = default; std::string hash_for_signature() { return m_hash; } diff --git a/src/lib/pubkey/rsa/rsa.cpp b/src/lib/pubkey/rsa/rsa.cpp index e1c3c4b0d..b551a33c8 100644 --- a/src/lib/pubkey/rsa/rsa.cpp +++ b/src/lib/pubkey/rsa/rsa.cpp @@ -491,7 +491,7 @@ class RSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA, size_t signature_length() const override { return public_modulus_bytes(); } RSA_Signature_Operation(const RSA_PrivateKey& rsa, const std::string& emsa, RandomNumberGenerator& rng) : - PK_Ops::Signature_with_EMSA(emsa), + PK_Ops::Signature_with_EMSA(emsa, true), RSA_Private_Operation(rsa, rng) { } @@ -611,7 +611,7 @@ class RSA_Verify_Operation final : public PK_Ops::Verification_with_EMSA, size_t max_input_bits() const override { return get_max_input_bits(); } RSA_Verify_Operation(const RSA_PublicKey& rsa, const std::string& emsa) : - PK_Ops::Verification_with_EMSA(emsa), + PK_Ops::Verification_with_EMSA(emsa, true), RSA_Public_Operation(rsa) { } |