aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cryptography/hazmat/backends/interfaces.py6
-rw-r--r--cryptography/hazmat/backends/multibackend.py6
-rw-r--r--cryptography/hazmat/backends/openssl/backend.py10
-rw-r--r--docs/hazmat/backends/interfaces.rst11
-rw-r--r--tests/hazmat/backends/test_multibackend.py10
-rw-r--r--tests/hazmat/backends/test_openssl.py47
6 files changed, 90 insertions, 0 deletions
diff --git a/cryptography/hazmat/backends/interfaces.py b/cryptography/hazmat/backends/interfaces.py
index 264c5afb..11b13788 100644
--- a/cryptography/hazmat/backends/interfaces.py
+++ b/cryptography/hazmat/backends/interfaces.py
@@ -129,6 +129,12 @@ class RSABackend(object):
Returns encrypted bytes.
"""
+ @abc.abstractmethod
+ def rsa_padding_supported(self, padding):
+ """
+ Returns True if the backend supports the given padding options.
+ """
+
@six.add_metaclass(abc.ABCMeta)
class DSABackend(object):
diff --git a/cryptography/hazmat/backends/multibackend.py b/cryptography/hazmat/backends/multibackend.py
index 21d307cf..21630ba8 100644
--- a/cryptography/hazmat/backends/multibackend.py
+++ b/cryptography/hazmat/backends/multibackend.py
@@ -164,6 +164,12 @@ class MultiBackend(object):
raise UnsupportedAlgorithm("RSA is not supported by the backend.",
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
+ def rsa_padding_supported(self, padding):
+ for b in self._filtered_backends(RSABackend):
+ return b.rsa_padding_supported(padding)
+ raise UnsupportedAlgorithm("RSA is not supported by the backend.",
+ _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
+
def generate_dsa_parameters(self, key_size):
for b in self._filtered_backends(DSABackend):
return b.generate_dsa_parameters(key_size)
diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py
index 5d9626d0..e5d6eaa1 100644
--- a/cryptography/hazmat/backends/openssl/backend.py
+++ b/cryptography/hazmat/backends/openssl/backend.py
@@ -534,6 +534,16 @@ class Backend(object):
else:
return isinstance(algorithm, hashes.SHA1)
+ def rsa_padding_supported(self, padding):
+ if isinstance(padding, PKCS1v15):
+ return True
+ elif isinstance(padding, PSS) and isinstance(padding._mgf, MGF1):
+ return self.mgf1_hash_supported(padding._mgf._algorithm)
+ elif isinstance(padding, OAEP) and isinstance(padding._mgf, MGF1):
+ return isinstance(padding._mgf._algorithm, hashes.SHA1)
+ else:
+ return False
+
def generate_dsa_parameters(self, key_size):
if key_size not in (1024, 2048, 3072):
raise ValueError(
diff --git a/docs/hazmat/backends/interfaces.rst b/docs/hazmat/backends/interfaces.rst
index ff389cb5..e98b9a59 100644
--- a/docs/hazmat/backends/interfaces.rst
+++ b/docs/hazmat/backends/interfaces.rst
@@ -263,6 +263,17 @@ A specific ``backend`` may provide one or more of these interfaces.
:returns: ``True`` if the specified ``algorithm`` is supported by this
backend, otherwise ``False``.
+ .. method:: rsa_padding_supported(padding)
+
+ Check if the specified ``padding`` is supported by the backend.
+
+ :param padding: An instance of an
+ :class:`~cryptography.hazmat.primitives.interfaces.AsymmetricPadding`
+ provider.
+
+ :returns: ``True`` if the specified ``padding`` is supported by this
+ backend, otherwise ``False``.
+
.. method:: decrypt_rsa(private_key, ciphertext, padding)
:param private_key: An instance of an
diff --git a/tests/hazmat/backends/test_multibackend.py b/tests/hazmat/backends/test_multibackend.py
index 088465a1..63d7dd23 100644
--- a/tests/hazmat/backends/test_multibackend.py
+++ b/tests/hazmat/backends/test_multibackend.py
@@ -101,6 +101,9 @@ class DummyRSABackend(object):
def mgf1_hash_supported(self, algorithm):
pass
+ def rsa_padding_supported(self, padding):
+ pass
+
def decrypt_rsa(self, private_key, ciphertext, padding):
pass
@@ -222,6 +225,8 @@ class TestMultiBackend(object):
backend.mgf1_hash_supported(hashes.MD5())
+ backend.rsa_padding_supported(padding.PKCS1v15())
+
backend.encrypt_rsa("public_key", "encryptme", padding.PKCS1v15())
backend.decrypt_rsa("private_key", "encrypted", padding.PKCS1v15())
@@ -252,6 +257,11 @@ class TestMultiBackend(object):
with raises_unsupported_algorithm(
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM
):
+ backend.rsa_padding_supported(padding.PKCS1v15())
+
+ with raises_unsupported_algorithm(
+ _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM
+ ):
backend.encrypt_rsa("public_key", "encryptme", padding.PKCS1v15())
with raises_unsupported_algorithm(
diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py
index 19274bf8..b3432003 100644
--- a/tests/hazmat/backends/test_openssl.py
+++ b/tests/hazmat/backends/test_openssl.py
@@ -43,11 +43,20 @@ class DummyCipher(object):
name = "dummy-cipher"
+@utils.register_interface(interfaces.AsymmetricPadding)
+class DummyPadding(object):
+ name = "dummy-cipher"
+
+
@utils.register_interface(interfaces.HashAlgorithm)
class DummyHash(object):
name = "dummy-hash"
+class DummyMGF(object):
+ _salt_length = 0
+
+
class TestOpenSSL(object):
def test_backend_exists(self):
assert backend
@@ -300,6 +309,44 @@ class TestOpenSSLRSA(object):
def test_unsupported_mgf1_hash_algorithm(self):
assert backend.mgf1_hash_supported(DummyHash()) is False
+ def test_rsa_padding_unsupported_pss_mgf1_hash(self):
+ assert backend.rsa_padding_supported(
+ padding.PSS(mgf=padding.MGF1(DummyHash()), salt_length=0)
+ ) is False
+
+ def test_rsa_padding_unsupported(self):
+ assert backend.rsa_padding_supported(DummyPadding()) is False
+
+ def test_rsa_padding_supported_pkcs1v15(self):
+ assert backend.rsa_padding_supported(padding.PKCS1v15()) is True
+
+ def test_rsa_padding_supported_pss(self):
+ assert backend.rsa_padding_supported(
+ padding.PSS(mgf=padding.MGF1(hashes.SHA1()), salt_length=0)
+ ) is True
+
+ def test_rsa_padding_supported_oaep(self):
+ assert backend.rsa_padding_supported(
+ padding.OAEP(
+ mgf=padding.MGF1(algorithm=hashes.SHA1()),
+ algorithm=hashes.SHA1(),
+ label=None
+ ),
+ ) is True
+
+ def test_rsa_padding_unsupported_mgf(self):
+ assert backend.rsa_padding_supported(
+ padding.OAEP(
+ mgf=DummyMGF(),
+ algorithm=hashes.SHA1(),
+ label=None
+ ),
+ ) is False
+
+ assert backend.rsa_padding_supported(
+ padding.PSS(mgf=DummyMGF(), salt_length=0)
+ ) is False
+
def test_unsupported_mgf1_hash_algorithm_decrypt(self):
private_key = rsa.RSAPrivateKey.generate(
public_exponent=65537,