diff options
-rw-r--r-- | cryptography/hazmat/backends/__init__.py | 33 | ||||
-rw-r--r-- | cryptography/hazmat/primitives/asymmetric/rsa.py | 14 | ||||
-rw-r--r-- | cryptography/hazmat/primitives/ciphers/base.py | 7 | ||||
-rw-r--r-- | cryptography/hazmat/primitives/hashes.py | 7 | ||||
-rw-r--r-- | cryptography/hazmat/primitives/hmac.py | 9 | ||||
-rw-r--r-- | docs/hazmat/primitives/asymmetric/rsa.rst | 12 | ||||
-rw-r--r-- | docs/hazmat/primitives/cryptographic-hashes.rst | 4 | ||||
-rw-r--r-- | docs/hazmat/primitives/hmac.rst | 4 | ||||
-rw-r--r-- | docs/hazmat/primitives/symmetric-encryption.rst | 4 | ||||
-rw-r--r-- | tests/conftest.py | 4 | ||||
-rw-r--r-- | tests/hazmat/primitives/test_ciphers.py | 10 | ||||
-rw-r--r-- | tests/hazmat/primitives/test_hashes.py | 18 | ||||
-rw-r--r-- | tests/hazmat/primitives/test_hmac.py | 17 | ||||
-rw-r--r-- | tests/hazmat/primitives/test_rsa.py | 28 |
14 files changed, 152 insertions, 19 deletions
diff --git a/cryptography/hazmat/backends/__init__.py b/cryptography/hazmat/backends/__init__.py index 59d1bc6c..ae78822c 100644 --- a/cryptography/hazmat/backends/__init__.py +++ b/cryptography/hazmat/backends/__init__.py @@ -13,23 +13,42 @@ from __future__ import absolute_import, division, print_function -from cryptography.hazmat.backends import openssl from cryptography.hazmat.backends.multibackend import MultiBackend from cryptography.hazmat.bindings.commoncrypto.binding import ( Binding as CommonCryptoBinding ) +from cryptography.hazmat.bindings.openssl.binding import ( + Binding as OpenSSLBinding +) + + +_available_backends_list = None + -_ALL_BACKENDS = [] +def _available_backends(): + global _available_backends_list -if CommonCryptoBinding.is_available(): - from cryptography.hazmat.backends import commoncrypto - _ALL_BACKENDS.append(commoncrypto.backend) + if _available_backends_list is None: + _available_backends_list = [] -_ALL_BACKENDS.append(openssl.backend) + if CommonCryptoBinding.is_available(): + from cryptography.hazmat.backends import commoncrypto + _available_backends_list.append(commoncrypto.backend) + if OpenSSLBinding.is_available(): + from cryptography.hazmat.backends import openssl + _available_backends_list.append(openssl.backend) -_default_backend = MultiBackend(_ALL_BACKENDS) + return _available_backends_list + + +_default_backend = None def default_backend(): + global _default_backend + + if _default_backend is None: + _default_backend = MultiBackend(_available_backends()) + return _default_backend diff --git a/cryptography/hazmat/primitives/asymmetric/rsa.py b/cryptography/hazmat/primitives/asymmetric/rsa.py index dfb43340..cbef8e32 100644 --- a/cryptography/hazmat/primitives/asymmetric/rsa.py +++ b/cryptography/hazmat/primitives/asymmetric/rsa.py @@ -16,6 +16,8 @@ from __future__ import absolute_import, division, print_function import six from cryptography import utils +from cryptography.exceptions import UnsupportedInterface +from cryptography.hazmat.backends.interfaces import RSABackend from cryptography.hazmat.primitives import interfaces @@ -41,6 +43,10 @@ class RSAPublicKey(object): self._modulus = modulus def verifier(self, signature, padding, algorithm, backend): + if not isinstance(backend, RSABackend): + raise UnsupportedInterface( + "Backend object does not implement RSABackend") + return backend.create_rsa_verification_ctx(self, signature, padding, algorithm) @@ -128,9 +134,17 @@ class RSAPrivateKey(object): @classmethod def generate(cls, public_exponent, key_size, backend): + if not isinstance(backend, RSABackend): + raise UnsupportedInterface( + "Backend object does not implement RSABackend") + return backend.generate_rsa_private_key(public_exponent, key_size) def signer(self, padding, algorithm, backend): + if not isinstance(backend, RSABackend): + raise UnsupportedInterface( + "Backend object does not implement RSABackend") + return backend.create_rsa_signature_ctx(self, padding, algorithm) @property diff --git a/cryptography/hazmat/primitives/ciphers/base.py b/cryptography/hazmat/primitives/ciphers/base.py index d366e4cf..1275019e 100644 --- a/cryptography/hazmat/primitives/ciphers/base.py +++ b/cryptography/hazmat/primitives/ciphers/base.py @@ -15,13 +15,18 @@ from __future__ import absolute_import, division, print_function from cryptography import utils from cryptography.exceptions import ( - AlreadyFinalized, NotYetFinalized, AlreadyUpdated, + AlreadyFinalized, NotYetFinalized, AlreadyUpdated, UnsupportedInterface ) +from cryptography.hazmat.backends.interfaces import CipherBackend from cryptography.hazmat.primitives import interfaces class Cipher(object): def __init__(self, algorithm, mode, backend): + if not isinstance(backend, CipherBackend): + raise UnsupportedInterface( + "Backend object does not implement CipherBackend") + if not isinstance(algorithm, interfaces.CipherAlgorithm): raise TypeError("Expected interface of interfaces.CipherAlgorithm") diff --git a/cryptography/hazmat/primitives/hashes.py b/cryptography/hazmat/primitives/hashes.py index bee188b3..409f564e 100644 --- a/cryptography/hazmat/primitives/hashes.py +++ b/cryptography/hazmat/primitives/hashes.py @@ -16,13 +16,18 @@ from __future__ import absolute_import, division, print_function import six from cryptography import utils -from cryptography.exceptions import AlreadyFinalized +from cryptography.exceptions import AlreadyFinalized, UnsupportedInterface +from cryptography.hazmat.backends.interfaces import HashBackend from cryptography.hazmat.primitives import interfaces @utils.register_interface(interfaces.HashContext) class Hash(object): def __init__(self, algorithm, backend, ctx=None): + if not isinstance(backend, HashBackend): + raise UnsupportedInterface( + "Backend object does not implement HashBackend") + if not isinstance(algorithm, interfaces.HashAlgorithm): raise TypeError("Expected instance of interfaces.HashAlgorithm.") self.algorithm = algorithm diff --git a/cryptography/hazmat/primitives/hmac.py b/cryptography/hazmat/primitives/hmac.py index 76d658aa..0bcbb3cd 100644 --- a/cryptography/hazmat/primitives/hmac.py +++ b/cryptography/hazmat/primitives/hmac.py @@ -16,13 +16,20 @@ from __future__ import absolute_import, division, print_function import six from cryptography import utils -from cryptography.exceptions import AlreadyFinalized, InvalidSignature +from cryptography.exceptions import ( + AlreadyFinalized, InvalidSignature, UnsupportedInterface +) +from cryptography.hazmat.backends.interfaces import HMACBackend from cryptography.hazmat.primitives import constant_time, interfaces @utils.register_interface(interfaces.HashContext) class HMAC(object): def __init__(self, key, algorithm, backend, ctx=None): + if not isinstance(backend, HMACBackend): + raise UnsupportedInterface( + "Backend object does not implement HMACBackend") + if not isinstance(algorithm, interfaces.HashAlgorithm): raise TypeError("Expected instance of interfaces.HashAlgorithm.") self.algorithm = algorithm diff --git a/docs/hazmat/primitives/asymmetric/rsa.rst b/docs/hazmat/primitives/asymmetric/rsa.rst index 7943981e..03a7caed 100644 --- a/docs/hazmat/primitives/asymmetric/rsa.rst +++ b/docs/hazmat/primitives/asymmetric/rsa.rst @@ -50,6 +50,11 @@ RSA provider. :return: A new instance of ``RSAPrivateKey``. + :raises cryptography.exceptions.UnsupportedInterface: This is raised if + the provided ``backend`` does not implement + :class:`~cryptography.hazmat.backends.interfaces.RSABackend` + + .. method:: signer(padding, algorithm, backend) .. versionadded:: 0.3 @@ -90,6 +95,9 @@ RSA :returns: :class:`~cryptography.hazmat.primitives.interfaces.AsymmetricSignatureContext` + :raises cryptography.exceptions.UnsupportedInterface: This is raised if + the provided ``backend`` does not implement + :class:`~cryptography.hazmat.backends.interfaces.RSABackend` .. class:: RSAPublicKey(public_exponent, modulus) @@ -154,6 +162,10 @@ RSA :returns: :class:`~cryptography.hazmat.primitives.interfaces.AsymmetricVerificationContext` + :raises cryptography.exceptions.UnsupportedInterface: This is raised if + the provided ``backend`` does not implement + :class:`~cryptography.hazmat.backends.interfaces.RSABackend` + .. _`RSA`: https://en.wikipedia.org/wiki/RSA_(cryptosystem) .. _`public-key`: https://en.wikipedia.org/wiki/Public-key_cryptography .. _`use 65537`: http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html diff --git a/docs/hazmat/primitives/cryptographic-hashes.rst b/docs/hazmat/primitives/cryptographic-hashes.rst index 627ca7bd..b7eee2f5 100644 --- a/docs/hazmat/primitives/cryptographic-hashes.rst +++ b/docs/hazmat/primitives/cryptographic-hashes.rst @@ -45,6 +45,10 @@ Message Digests :class:`~cryptography.hazmat.backends.interfaces.HashBackend` provider. + :raises cryptography.exceptions.UnsupportedInterface: This is raised if the + provided ``backend`` does not implement + :class:`~cryptography.hazmat.backends.interfaces.HashBackend` + .. method:: update(data) :param bytes data: The bytes to be hashed. diff --git a/docs/hazmat/primitives/hmac.rst b/docs/hazmat/primitives/hmac.rst index 6ca9e167..ce4e8803 100644 --- a/docs/hazmat/primitives/hmac.rst +++ b/docs/hazmat/primitives/hmac.rst @@ -56,6 +56,10 @@ of a message. :class:`~cryptography.hazmat.backends.interfaces.HMACBackend` provider. + :raises cryptography.exceptions.UnsupportedInterface: This is raised if the + provided ``backend`` does not implement + :class:`~cryptography.hazmat.backends.interfaces.HMACBackend` + .. method:: update(msg) :param bytes msg: The bytes to hash and authenticate. diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index 741091b2..71a1064e 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -56,6 +56,10 @@ an "encrypt-then-MAC" formulation as `described by Colin Percival`_. :class:`~cryptography.hazmat.backends.interfaces.CipherBackend` provider. + :raises cryptography.exceptions.UnsupportedInterface: This is raised if the + provided ``backend`` does not implement + :class:`~cryptography.hazmat.backends.interfaces.CipherBackend` + .. method:: encryptor() :return: An encrypting diff --git a/tests/conftest.py b/tests/conftest.py index 0069f2c0..36183f46 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -15,7 +15,7 @@ from __future__ import absolute_import, division, print_function import pytest -from cryptography.hazmat.backends import _ALL_BACKENDS +from cryptography.hazmat.backends import _available_backends from cryptography.hazmat.backends.interfaces import ( HMACBackend, CipherBackend, HashBackend, PBKDF2HMACBackend, RSABackend ) @@ -25,7 +25,7 @@ from .utils import check_for_iface, check_backend_support, select_backends def pytest_generate_tests(metafunc): names = metafunc.config.getoption("--backend") - selected_backends = select_backends(names, _ALL_BACKENDS) + selected_backends = select_backends(names, _available_backends()) if "backend" in metafunc.fixturenames: metafunc.parametrize("backend", selected_backends) diff --git a/tests/hazmat/primitives/test_ciphers.py b/tests/hazmat/primitives/test_ciphers.py index d9f83535..bd9625e9 100644 --- a/tests/hazmat/primitives/test_ciphers.py +++ b/tests/hazmat/primitives/test_ciphers.py @@ -17,9 +17,12 @@ import binascii import pytest +from cryptography.exceptions import UnsupportedInterface +from cryptography.hazmat.primitives import ciphers from cryptography.hazmat.primitives.ciphers.algorithms import ( AES, Camellia, TripleDES, Blowfish, ARC4, CAST5, IDEA ) +from cryptography.hazmat.primitives.ciphers.modes import ECB class TestAES(object): @@ -120,3 +123,10 @@ class TestIDEA(object): def test_invalid_key_size(self): with pytest.raises(ValueError): IDEA(b"\x00" * 17) + + +def test_invalid_backend(): + pretend_backend = object() + + with pytest.raises(UnsupportedInterface): + ciphers.Cipher(AES(b"AAAAAAAAAAAAAAAA"), ECB, pretend_backend) diff --git a/tests/hazmat/primitives/test_hashes.py b/tests/hazmat/primitives/test_hashes.py index fc53d635..5b318f64 100644 --- a/tests/hazmat/primitives/test_hashes.py +++ b/tests/hazmat/primitives/test_hashes.py @@ -20,7 +20,10 @@ import pytest import six from cryptography import utils -from cryptography.exceptions import AlreadyFinalized, UnsupportedHash +from cryptography.exceptions import ( + AlreadyFinalized, UnsupportedHash, UnsupportedInterface +) +from cryptography.hazmat.backends.interfaces import HashBackend from cryptography.hazmat.primitives import hashes, interfaces from .utils import generate_base_hash_test @@ -39,7 +42,11 @@ class TestHashContext(object): m.update(six.u("\u00FC")) def test_copy_backend_object(self): - pretend_backend = pretend.stub() + @utils.register_interface(HashBackend) + class PretendBackend(object): + pass + + pretend_backend = PretendBackend() copied_ctx = pretend.stub() pretend_ctx = pretend.stub(copy=lambda: copied_ctx) h = hashes.Hash(hashes.SHA1(), backend=pretend_backend, @@ -171,3 +178,10 @@ class TestMD5(object): digest_size=16, block_size=64, ) + + +def test_invalid_backend(): + pretend_backend = object() + + with pytest.raises(UnsupportedInterface): + hashes.Hash(hashes.SHA1(), pretend_backend) diff --git a/tests/hazmat/primitives/test_hmac.py b/tests/hazmat/primitives/test_hmac.py index 88bed52c..3589e6ac 100644 --- a/tests/hazmat/primitives/test_hmac.py +++ b/tests/hazmat/primitives/test_hmac.py @@ -21,8 +21,9 @@ import six from cryptography import utils from cryptography.exceptions import ( - AlreadyFinalized, UnsupportedHash, InvalidSignature + AlreadyFinalized, UnsupportedHash, InvalidSignature, UnsupportedInterface ) +from cryptography.hazmat.backends.interfaces import HMACBackend from cryptography.hazmat.primitives import hashes, hmac, interfaces from .utils import generate_base_hmac_test @@ -52,8 +53,11 @@ class TestHMAC(object): h.update(six.u("\u00FC")) def test_copy_backend_object(self): - pretend_hmac = pretend.stub() - pretend_backend = pretend.stub(hmacs=pretend_hmac) + @utils.register_interface(HMACBackend) + class PretendBackend(object): + pass + + pretend_backend = PretendBackend() copied_ctx = pretend.stub() pretend_ctx = pretend.stub(copy=lambda: copied_ctx) h = hmac.HMAC(b"key", hashes.SHA1(), backend=pretend_backend, @@ -104,3 +108,10 @@ class TestHMAC(object): def test_unsupported_hash(self, backend): with pytest.raises(UnsupportedHash): hmac.HMAC(b"key", UnsupportedDummyHash(), backend) + + +def test_invalid_backend(): + pretend_backend = object() + + with pytest.raises(UnsupportedInterface): + hmac.HMAC(b"key", hashes.SHA1(), pretend_backend) diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index 114dc415..0e88bb7f 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -21,9 +21,9 @@ import os import pytest from cryptography import exceptions, utils +from cryptography.exceptions import UnsupportedInterface from cryptography.hazmat.primitives import hashes, interfaces -from cryptography.hazmat.primitives.asymmetric import rsa -from cryptography.hazmat.primitives.asymmetric import padding +from cryptography.hazmat.primitives.asymmetric import rsa, padding from ...utils import load_pkcs1_vectors, load_vectors_from_file @@ -385,6 +385,13 @@ class TestRSA(object): rsa.RSAPublicKey(public_exponent=6, modulus=15) +def test_rsa_generate_invalid_backend(): + pretend_backend = object() + + with pytest.raises(UnsupportedInterface): + rsa.RSAPrivateKey.generate(65537, 2048, pretend_backend) + + @pytest.mark.rsa class TestRSASignature(object): @pytest.mark.parametrize( @@ -444,6 +451,14 @@ class TestRSASignature(object): with pytest.raises(TypeError): private_key.signer("notpadding", hashes.SHA1(), backend) + def test_rsa_signer_invalid_backend(self, backend): + pretend_backend = object() + private_key = rsa.RSAPrivateKey.generate(65537, 2048, backend) + + with pytest.raises(UnsupportedInterface): + private_key.signer( + padding.PKCS1v15(), hashes.SHA256, pretend_backend) + @pytest.mark.rsa class TestRSAVerification(object): @@ -559,6 +574,15 @@ class TestRSAVerification(object): with pytest.raises(TypeError): public_key.verifier(b"sig", "notpadding", hashes.SHA1(), backend) + def test_rsa_verifier_invalid_backend(self, backend): + pretend_backend = object() + private_key = rsa.RSAPrivateKey.generate(65537, 2048, backend) + public_key = private_key.public_key() + + with pytest.raises(UnsupportedInterface): + public_key.verifier( + b"foo", padding.PKCS1v15(), hashes.SHA256(), pretend_backend) + class TestMGF1(object): def test_invalid_hash_algorithm(self): |