aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2021-05-22 11:49:49 -0400
committerJack Lloyd <[email protected]>2021-05-22 11:50:34 -0400
commit9745a8fed0f94d0fd26f6056572eb072d7108840 (patch)
tree6efcf45d34070e1badbb0ebca9f8b61af8a65c78
parentcb803e0c1b016428f9851eb9705498bc253bdb0f (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.h6
-rw-r--r--src/lib/pk_pad/emsa1/emsa1.h2
-rw-r--r--src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h3
-rw-r--r--src/lib/pk_pad/emsa_pssr/pssr.h4
-rw-r--r--src/lib/pk_pad/emsa_raw/emsa_raw.h2
-rw-r--r--src/lib/pk_pad/emsa_x931/emsa_x931.h2
-rw-r--r--src/lib/pk_pad/iso9796/iso9796.h5
-rw-r--r--src/lib/prov/openssl/openssl_rsa.cpp4
-rw-r--r--src/lib/pubkey/pk_ops.cpp14
-rw-r--r--src/lib/pubkey/pk_ops_impl.h5
-rw-r--r--src/lib/pubkey/rsa/rsa.cpp4
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)
{
}