diff options
33 files changed, 301 insertions, 203 deletions
diff --git a/cryptography/exceptions.py b/cryptography/exceptions.py index 88766cc1..4b4d4c37 100644 --- a/cryptography/exceptions.py +++ b/cryptography/exceptions.py @@ -14,20 +14,17 @@  from __future__ import absolute_import, division, print_function -class UnsupportedAlgorithm(Exception): -    pass +class _Reasons(object): +    BACKEND_MISSING_INTERFACE = object() +    UNSUPPORTED_HASH = object() +    UNSUPPORTED_CIPHER = object() +    UNSUPPORTED_PADDING = object() -class UnsupportedCipher(UnsupportedAlgorithm): -    pass - - -class UnsupportedHash(UnsupportedAlgorithm): -    pass - - -class UnsupportedPadding(UnsupportedAlgorithm): -    pass +class UnsupportedAlgorithm(Exception): +    def __init__(self, message, reason=None): +        super(UnsupportedAlgorithm, self).__init__(message) +        self._reason = reason  class AlreadyFinalized(Exception): @@ -60,7 +57,3 @@ class InvalidKey(Exception):  class InvalidToken(Exception):      pass - - -class UnsupportedInterface(Exception): -    pass diff --git a/cryptography/hazmat/backends/commoncrypto/backend.py b/cryptography/hazmat/backends/commoncrypto/backend.py index dc0534ee..4faca73e 100644 --- a/cryptography/hazmat/backends/commoncrypto/backend.py +++ b/cryptography/hazmat/backends/commoncrypto/backend.py @@ -17,7 +17,7 @@ from collections import namedtuple  from cryptography import utils  from cryptography.exceptions import ( -    InternalError, InvalidTag, UnsupportedCipher, UnsupportedHash +    InternalError, InvalidTag, UnsupportedAlgorithm, _Reasons  )  from cryptography.hazmat.backends.interfaces import (      CipherBackend, HMACBackend, HashBackend, PBKDF2HMACBackend @@ -273,10 +273,11 @@ class _CipherContext(object):          try:              cipher_enum, mode_enum = registry[type(cipher), type(mode)]          except KeyError: -            raise UnsupportedCipher( +            raise UnsupportedAlgorithm(                  "cipher {0} in {1} mode is not supported "                  "by this backend".format( -                    cipher.name, mode.name if mode else mode) +                    cipher.name, mode.name if mode else mode), +                _Reasons.UNSUPPORTED_CIPHER              )          ctx = self._backend._ffi.new("CCCryptorRef *") @@ -346,10 +347,11 @@ class _GCMCipherContext(object):          try:              cipher_enum, mode_enum = registry[type(cipher), type(mode)]          except KeyError: -            raise UnsupportedCipher( +            raise UnsupportedAlgorithm(                  "cipher {0} in {1} mode is not supported "                  "by this backend".format( -                    cipher.name, mode.name if mode else mode) +                    cipher.name, mode.name if mode else mode), +                _Reasons.UNSUPPORTED_CIPHER              )          ctx = self._backend._ffi.new("CCCryptorRef *") @@ -420,9 +422,10 @@ class _HashContext(object):              try:                  methods = self._backend._hash_mapping[self.algorithm.name]              except KeyError: -                raise UnsupportedHash( +                raise UnsupportedAlgorithm(                      "{0} is not a supported hash on this backend".format( -                        algorithm.name) +                        algorithm.name), +                    _Reasons.UNSUPPORTED_HASH                  )              ctx = self._backend._ffi.new(methods.ctx)              res = methods.hash_init(ctx) @@ -463,9 +466,10 @@ class _HMACContext(object):              try:                  alg = self._backend._supported_hmac_algorithms[algorithm.name]              except KeyError: -                raise UnsupportedHash( +                raise UnsupportedAlgorithm(                      "{0} is not a supported HMAC hash on this backend".format( -                        algorithm.name) +                        algorithm.name), +                    _Reasons.UNSUPPORTED_HASH                  )              self._backend._lib.CCHmacInit(ctx, alg, key, len(key)) diff --git a/cryptography/hazmat/backends/multibackend.py b/cryptography/hazmat/backends/multibackend.py index 6c57b3df..2a1ec439 100644 --- a/cryptography/hazmat/backends/multibackend.py +++ b/cryptography/hazmat/backends/multibackend.py @@ -14,9 +14,7 @@  from __future__ import absolute_import, division, print_function  from cryptography import utils -from cryptography.exceptions import ( -    UnsupportedAlgorithm, UnsupportedCipher, UnsupportedHash -) +from cryptography.exceptions import UnsupportedAlgorithm, _Reasons  from cryptography.hazmat.backends.interfaces import (      CipherBackend, HMACBackend, HashBackend, PBKDF2HMACBackend, RSABackend  ) @@ -48,17 +46,25 @@ class MultiBackend(object):          for b in self._filtered_backends(CipherBackend):              try:                  return b.create_symmetric_encryption_ctx(algorithm, mode) -            except UnsupportedCipher: +            except UnsupportedAlgorithm:                  pass -        raise UnsupportedCipher +        raise UnsupportedAlgorithm( +            "cipher {0} in {1} mode is not supported by this backend".format( +                algorithm.name, mode.name if mode else mode), +            _Reasons.UNSUPPORTED_CIPHER +        )      def create_symmetric_decryption_ctx(self, algorithm, mode):          for b in self._filtered_backends(CipherBackend):              try:                  return b.create_symmetric_decryption_ctx(algorithm, mode) -            except UnsupportedCipher: +            except UnsupportedAlgorithm:                  pass -        raise UnsupportedCipher +        raise UnsupportedAlgorithm( +            "cipher {0} in {1} mode is not supported by this backend".format( +                algorithm.name, mode.name if mode else mode), +            _Reasons.UNSUPPORTED_CIPHER +        )      def hash_supported(self, algorithm):          return any( @@ -70,9 +76,13 @@ class MultiBackend(object):          for b in self._filtered_backends(HashBackend):              try:                  return b.create_hash_ctx(algorithm) -            except UnsupportedHash: +            except UnsupportedAlgorithm:                  pass -        raise UnsupportedHash +        raise UnsupportedAlgorithm( +            "{0} is not a supported hash on this backend".format( +                algorithm.name), +            _Reasons.UNSUPPORTED_HASH +        )      def hmac_supported(self, algorithm):          return any( @@ -84,9 +94,13 @@ class MultiBackend(object):          for b in self._filtered_backends(HMACBackend):              try:                  return b.create_hmac_ctx(key, algorithm) -            except UnsupportedHash: +            except UnsupportedAlgorithm:                  pass -        raise UnsupportedHash +        raise UnsupportedAlgorithm( +            "{0} is not a supported hash on this backend".format( +                algorithm.name), +            _Reasons.UNSUPPORTED_HASH +        )      def pbkdf2_hmac_supported(self, algorithm):          return any( @@ -101,23 +115,27 @@ class MultiBackend(object):                  return b.derive_pbkdf2_hmac(                      algorithm, length, salt, iterations, key_material                  ) -            except UnsupportedHash: +            except UnsupportedAlgorithm:                  pass -        raise UnsupportedHash +        raise UnsupportedAlgorithm( +            "{0} is not a supported hash on this backend".format( +                algorithm.name), +            _Reasons.UNSUPPORTED_HASH +        )      def generate_rsa_private_key(self, public_exponent, key_size):          for b in self._filtered_backends(RSABackend):              return b.generate_rsa_private_key(public_exponent, key_size) -        raise UnsupportedAlgorithm +        raise UnsupportedAlgorithm("RSA is not supported by the backend")      def create_rsa_signature_ctx(self, private_key, padding, algorithm):          for b in self._filtered_backends(RSABackend):              return b.create_rsa_signature_ctx(private_key, padding, algorithm) -        raise UnsupportedAlgorithm +        raise UnsupportedAlgorithm("RSA is not supported by the backend")      def create_rsa_verification_ctx(self, public_key, signature, padding,                                      algorithm):          for b in self._filtered_backends(RSABackend):              return b.create_rsa_verification_ctx(public_key, signature,                                                   padding, algorithm) -        raise UnsupportedAlgorithm +        raise UnsupportedAlgorithm("RSA is not supported by the backend") diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index d2744cf3..753717d4 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -22,8 +22,7 @@ import six  from cryptography import utils  from cryptography.exceptions import (      AlreadyFinalized, InternalError, InvalidSignature, InvalidTag, -    UnsupportedAlgorithm, UnsupportedCipher, UnsupportedHash, -    UnsupportedPadding +    UnsupportedAlgorithm, _Reasons  )  from cryptography.hazmat.backends.interfaces import (      CipherBackend, HMACBackend, HashBackend, PBKDF2HMACBackend, RSABackend @@ -221,9 +220,10 @@ class Backend(object):              assert res == 1          else:              if not isinstance(algorithm, hashes.SHA1): -                raise UnsupportedHash( +                raise UnsupportedAlgorithm(                      "This version of OpenSSL only supports PBKDF2HMAC with " -                    "SHA1" +                    "SHA1", +                    _Reasons.UNSUPPORTED_HASH                  )              res = self._lib.PKCS5_PBKDF2_HMAC_SHA1(                  key_material, @@ -453,18 +453,20 @@ class _CipherContext(object):          try:              adapter = registry[type(cipher), type(mode)]          except KeyError: -            raise UnsupportedCipher( +            raise UnsupportedAlgorithm(                  "cipher {0} in {1} mode is not supported "                  "by this backend".format( -                    cipher.name, mode.name if mode else mode) +                    cipher.name, mode.name if mode else mode), +                _Reasons.UNSUPPORTED_CIPHER              )          evp_cipher = adapter(self._backend, cipher, mode)          if evp_cipher == self._backend._ffi.NULL: -            raise UnsupportedCipher( +            raise UnsupportedAlgorithm(                  "cipher {0} in {1} mode is not supported "                  "by this backend".format( -                    cipher.name, mode.name if mode else mode) +                    cipher.name, mode.name if mode else mode), +                _Reasons.UNSUPPORTED_CIPHER              )          if isinstance(mode, interfaces.ModeWithInitializationVector): @@ -602,9 +604,10 @@ class _HashContext(object):              evp_md = self._backend._lib.EVP_get_digestbyname(                  algorithm.name.encode("ascii"))              if evp_md == self._backend._ffi.NULL: -                raise UnsupportedHash( +                raise UnsupportedAlgorithm(                      "{0} is not a supported hash on this backend".format( -                        algorithm.name) +                        algorithm.name), +                    _Reasons.UNSUPPORTED_HASH                  )              res = self._backend._lib.EVP_DigestInit_ex(ctx, evp_md,                                                         self._backend._ffi.NULL) @@ -652,9 +655,10 @@ class _HMACContext(object):              evp_md = self._backend._lib.EVP_get_digestbyname(                  algorithm.name.encode('ascii'))              if evp_md == self._backend._ffi.NULL: -                raise UnsupportedHash( +                raise UnsupportedAlgorithm(                      "{0} is not a supported hash on this backend".format( -                        algorithm.name) +                        algorithm.name), +                    _Reasons.UNSUPPORTED_HASH                  )              res = self._backend._lib.Cryptography_HMAC_Init_ex(                  ctx, key, len(key), evp_md, self._backend._ffi.NULL @@ -738,9 +742,10 @@ class _RSASignatureContext(object):                                   "key.")              if not self._backend.mgf1_hash_supported(padding._mgf._algorithm): -                raise UnsupportedHash( +                raise UnsupportedAlgorithm(                      "When OpenSSL is older than 1.0.1 then only SHA1 is " -                    "supported with MGF1." +                    "supported with MGF1.", +                    _Reasons.UNSUPPORTED_HASH                  )              if self._backend._lib.Cryptography_HAS_PKEY_CTX: @@ -749,8 +754,9 @@ class _RSASignatureContext(object):              else:                  self._finalize_method = self._finalize_pss          else: -            raise UnsupportedPadding( -                "{0} is not supported by this backend".format(padding.name) +            raise UnsupportedAlgorithm( +                "{0} is not supported by this backend".format(padding.name), +                _Reasons.UNSUPPORTED_PADDING              )          self._padding = padding @@ -922,9 +928,10 @@ class _RSAVerificationContext(object):                  )              if not self._backend.mgf1_hash_supported(padding._mgf._algorithm): -                raise UnsupportedHash( +                raise UnsupportedAlgorithm(                      "When OpenSSL is older than 1.0.1 then only SHA1 is " -                    "supported with MGF1." +                    "supported with MGF1.", +                    _Reasons.UNSUPPORTED_HASH                  )              if self._backend._lib.Cryptography_HAS_PKEY_CTX: @@ -933,7 +940,10 @@ class _RSAVerificationContext(object):              else:                  self._verify_method = self._verify_pss          else: -            raise UnsupportedPadding +            raise UnsupportedAlgorithm( +                "{0} is not supported by this backend".format(padding.name), +                _Reasons.UNSUPPORTED_PADDING +            )          self._padding = padding          self._algorithm = algorithm diff --git a/cryptography/hazmat/primitives/asymmetric/rsa.py b/cryptography/hazmat/primitives/asymmetric/rsa.py index cbef8e32..94cc4645 100644 --- a/cryptography/hazmat/primitives/asymmetric/rsa.py +++ b/cryptography/hazmat/primitives/asymmetric/rsa.py @@ -16,7 +16,7 @@ from __future__ import absolute_import, division, print_function  import six  from cryptography import utils -from cryptography.exceptions import UnsupportedInterface +from cryptography.exceptions import UnsupportedAlgorithm, _Reasons  from cryptography.hazmat.backends.interfaces import RSABackend  from cryptography.hazmat.primitives import interfaces @@ -44,8 +44,10 @@ class RSAPublicKey(object):      def verifier(self, signature, padding, algorithm, backend):          if not isinstance(backend, RSABackend): -            raise UnsupportedInterface( -                "Backend object does not implement RSABackend") +            raise UnsupportedAlgorithm( +                "Backend object does not implement RSABackend", +                _Reasons.BACKEND_MISSING_INTERFACE +            )          return backend.create_rsa_verification_ctx(self, signature, padding,                                                     algorithm) @@ -135,15 +137,19 @@ 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") +            raise UnsupportedAlgorithm( +                "Backend object does not implement RSABackend", +                _Reasons.BACKEND_MISSING_INTERFACE +            )          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") +            raise UnsupportedAlgorithm( +                "Backend object does not implement RSABackend", +                _Reasons.BACKEND_MISSING_INTERFACE +            )          return backend.create_rsa_signature_ctx(self, padding, algorithm) diff --git a/cryptography/hazmat/primitives/ciphers/base.py b/cryptography/hazmat/primitives/ciphers/base.py index f5dd2ed5..2274e945 100644 --- a/cryptography/hazmat/primitives/ciphers/base.py +++ b/cryptography/hazmat/primitives/ciphers/base.py @@ -15,7 +15,8 @@ from __future__ import absolute_import, division, print_function  from cryptography import utils  from cryptography.exceptions import ( -    AlreadyFinalized, AlreadyUpdated, NotYetFinalized, UnsupportedInterface +    AlreadyFinalized, AlreadyUpdated, NotYetFinalized, UnsupportedAlgorithm, +    _Reasons  )  from cryptography.hazmat.backends.interfaces import CipherBackend  from cryptography.hazmat.primitives import interfaces @@ -24,8 +25,10 @@ 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") +            raise UnsupportedAlgorithm( +                "Backend object does not implement CipherBackend", +                _Reasons.BACKEND_MISSING_INTERFACE +            )          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 409f564e..35b677b0 100644 --- a/cryptography/hazmat/primitives/hashes.py +++ b/cryptography/hazmat/primitives/hashes.py @@ -16,7 +16,9 @@ from __future__ import absolute_import, division, print_function  import six  from cryptography import utils -from cryptography.exceptions import AlreadyFinalized, UnsupportedInterface +from cryptography.exceptions import ( +    AlreadyFinalized, UnsupportedAlgorithm, _Reasons +)  from cryptography.hazmat.backends.interfaces import HashBackend  from cryptography.hazmat.primitives import interfaces @@ -25,8 +27,10 @@ from cryptography.hazmat.primitives import interfaces  class Hash(object):      def __init__(self, algorithm, backend, ctx=None):          if not isinstance(backend, HashBackend): -            raise UnsupportedInterface( -                "Backend object does not implement HashBackend") +            raise UnsupportedAlgorithm( +                "Backend object does not implement HashBackend", +                _Reasons.BACKEND_MISSING_INTERFACE +            )          if not isinstance(algorithm, interfaces.HashAlgorithm):              raise TypeError("Expected instance of interfaces.HashAlgorithm.") diff --git a/cryptography/hazmat/primitives/hmac.py b/cryptography/hazmat/primitives/hmac.py index 0bcbb3cd..afbb2f75 100644 --- a/cryptography/hazmat/primitives/hmac.py +++ b/cryptography/hazmat/primitives/hmac.py @@ -17,7 +17,7 @@ import six  from cryptography import utils  from cryptography.exceptions import ( -    AlreadyFinalized, InvalidSignature, UnsupportedInterface +    AlreadyFinalized, InvalidSignature, UnsupportedAlgorithm, _Reasons  )  from cryptography.hazmat.backends.interfaces import HMACBackend  from cryptography.hazmat.primitives import constant_time, interfaces @@ -27,8 +27,10 @@ from cryptography.hazmat.primitives import constant_time, interfaces  class HMAC(object):      def __init__(self, key, algorithm, backend, ctx=None):          if not isinstance(backend, HMACBackend): -            raise UnsupportedInterface( -                "Backend object does not implement HMACBackend") +            raise UnsupportedAlgorithm( +                "Backend object does not implement HMACBackend", +                _Reasons.BACKEND_MISSING_INTERFACE +            )          if not isinstance(algorithm, interfaces.HashAlgorithm):              raise TypeError("Expected instance of interfaces.HashAlgorithm.") diff --git a/cryptography/hazmat/primitives/kdf/hkdf.py b/cryptography/hazmat/primitives/kdf/hkdf.py index 95396fe1..03500aaa 100644 --- a/cryptography/hazmat/primitives/kdf/hkdf.py +++ b/cryptography/hazmat/primitives/kdf/hkdf.py @@ -17,7 +17,7 @@ import six  from cryptography import utils  from cryptography.exceptions import ( -    AlreadyFinalized, InvalidKey, UnsupportedInterface +    AlreadyFinalized, InvalidKey, UnsupportedAlgorithm, _Reasons  )  from cryptography.hazmat.backends.interfaces import HMACBackend  from cryptography.hazmat.primitives import constant_time, hmac, interfaces @@ -27,8 +27,10 @@ from cryptography.hazmat.primitives import constant_time, hmac, interfaces  class HKDF(object):      def __init__(self, algorithm, length, salt, info, backend):          if not isinstance(backend, HMACBackend): -            raise UnsupportedInterface( -                "Backend object does not implement HMACBackend") +            raise UnsupportedAlgorithm( +                "Backend object does not implement HMACBackend", +                _Reasons.BACKEND_MISSING_INTERFACE +            )          self._algorithm = algorithm diff --git a/cryptography/hazmat/primitives/kdf/pbkdf2.py b/cryptography/hazmat/primitives/kdf/pbkdf2.py index 705e45d7..bec35bb2 100644 --- a/cryptography/hazmat/primitives/kdf/pbkdf2.py +++ b/cryptography/hazmat/primitives/kdf/pbkdf2.py @@ -17,7 +17,7 @@ import six  from cryptography import utils  from cryptography.exceptions import ( -    AlreadyFinalized, InvalidKey, UnsupportedHash, UnsupportedInterface +    AlreadyFinalized, InvalidKey, UnsupportedAlgorithm, _Reasons  )  from cryptography.hazmat.backends.interfaces import PBKDF2HMACBackend  from cryptography.hazmat.primitives import constant_time, interfaces @@ -27,13 +27,16 @@ from cryptography.hazmat.primitives import constant_time, interfaces  class PBKDF2HMAC(object):      def __init__(self, algorithm, length, salt, iterations, backend):          if not isinstance(backend, PBKDF2HMACBackend): -            raise UnsupportedInterface( -                "Backend object does not implement PBKDF2HMACBackend") +            raise UnsupportedAlgorithm( +                "Backend object does not implement PBKDF2HMACBackend", +                _Reasons.BACKEND_MISSING_INTERFACE +            )          if not backend.pbkdf2_hmac_supported(algorithm): -            raise UnsupportedHash( +            raise UnsupportedAlgorithm(                  "{0} is not supported for PBKDF2 by this backend".format( -                    algorithm.name) +                    algorithm.name), +                _Reasons.UNSUPPORTED_HASH              )          self._used = False          self._algorithm = algorithm diff --git a/cryptography/hazmat/primitives/twofactor/hotp.py b/cryptography/hazmat/primitives/twofactor/hotp.py index 34f820c0..41c467c8 100644 --- a/cryptography/hazmat/primitives/twofactor/hotp.py +++ b/cryptography/hazmat/primitives/twofactor/hotp.py @@ -17,7 +17,9 @@ import struct  import six -from cryptography.exceptions import InvalidToken, UnsupportedInterface +from cryptography.exceptions import ( +    InvalidToken, UnsupportedAlgorithm, _Reasons +)  from cryptography.hazmat.backends.interfaces import HMACBackend  from cryptography.hazmat.primitives import constant_time, hmac  from cryptography.hazmat.primitives.hashes import SHA1, SHA256, SHA512 @@ -26,8 +28,10 @@ from cryptography.hazmat.primitives.hashes import SHA1, SHA256, SHA512  class HOTP(object):      def __init__(self, key, length, algorithm, backend):          if not isinstance(backend, HMACBackend): -            raise UnsupportedInterface( -                "Backend object does not implement HMACBackend") +            raise UnsupportedAlgorithm( +                "Backend object does not implement HMACBackend", +                _Reasons.BACKEND_MISSING_INTERFACE +            )          if len(key) < 16:              raise ValueError("Key length has to be at least 128 bits.") diff --git a/cryptography/hazmat/primitives/twofactor/totp.py b/cryptography/hazmat/primitives/twofactor/totp.py index 08510ef5..e55ba00d 100644 --- a/cryptography/hazmat/primitives/twofactor/totp.py +++ b/cryptography/hazmat/primitives/twofactor/totp.py @@ -13,7 +13,9 @@  from __future__ import absolute_import, division, print_function -from cryptography.exceptions import InvalidToken, UnsupportedInterface +from cryptography.exceptions import ( +    InvalidToken, UnsupportedAlgorithm, _Reasons +)  from cryptography.hazmat.backends.interfaces import HMACBackend  from cryptography.hazmat.primitives import constant_time  from cryptography.hazmat.primitives.twofactor.hotp import HOTP @@ -22,8 +24,10 @@ from cryptography.hazmat.primitives.twofactor.hotp import HOTP  class TOTP(object):      def __init__(self, key, length, algorithm, time_step, backend):          if not isinstance(backend, HMACBackend): -            raise UnsupportedInterface( -                "Backend object does not implement HMACBackend") +            raise UnsupportedAlgorithm( +                "Backend object does not implement HMACBackend", +                _Reasons.BACKEND_MISSING_INTERFACE +            )          self._time_step = time_step          self._hotp = HOTP(key, length, algorithm, backend) diff --git a/docs/exceptions.rst b/docs/exceptions.rst index e5010ebe..28da8ecc 100644 --- a/docs/exceptions.rst +++ b/docs/exceptions.rst @@ -3,6 +3,13 @@ Exceptions  .. currentmodule:: cryptography.exceptions + +.. class:: UnsupportedAlgorithm + +    Raised when the requested algorithm, or combination of algorithms is not +    supported. + +  .. class:: AlreadyFinalized      This is raised when a context is used after being finalized. @@ -25,25 +32,6 @@ Exceptions      This is raised when additional data is added to a context after update      has already been called. -.. class:: UnsupportedCipher - -    .. versionadded:: 0.3 - -    This is raised when a backend doesn't support the requested cipher -    algorithm and mode combination. - -.. class:: UnsupportedHash - -    .. versionadded:: 0.3 - -    This is raised when a backend doesn't support the requested hash algorithm. - -.. class:: UnsupportedPadding - -    .. versionadded:: 0.3 - -    This is raised when the requested padding is not supported by the backend. -  .. class:: InvalidKey @@ -55,10 +43,3 @@ Exceptions      This is raised when the verify method of a one time password function's      computed token does not match the expected token. - -.. class:: UnsupportedInterface - -    .. versionadded:: 0.3 - -    This is raised when the provided backend does not support the required -    interface. diff --git a/docs/hazmat/primitives/asymmetric/rsa.rst b/docs/hazmat/primitives/asymmetric/rsa.rst index 57c8eec2..182e35d2 100644 --- a/docs/hazmat/primitives/asymmetric/rsa.rst +++ b/docs/hazmat/primitives/asymmetric/rsa.rst @@ -50,7 +50,7 @@ RSA              provider.          :return: A new instance of ``RSAPrivateKey``. -        :raises cryptography.exceptions.UnsupportedInterface: This is raised if +        :raises cryptography.exceptions.UnsupportedAlgorithm: This is raised if              the provided ``backend`` does not implement              :class:`~cryptography.hazmat.backends.interfaces.RSABackend` @@ -100,9 +100,16 @@ RSA          :returns:              :class:`~cryptography.hazmat.primitives.interfaces.AsymmetricSignatureContext` -        :raises cryptography.exceptions.UnsupportedInterface: This is raised if +        :raises cryptography.exceptions.UnsupportedAlgorithm: This is raised if              the provided ``backend`` does not implement -            :class:`~cryptography.hazmat.backends.interfaces.RSABackend` +            :class:`~cryptography.hazmat.backends.interfaces.RSABackend` or if +            the backend does not support the chosen hash or padding algorithm. +            If the padding is +            :class:`~cryptography.hazmat.primitives.asymmetric.padding.PSS` +            with the +            :class:`~cryptography.hazmat.primitives.asymmetric.padding.MGF1` +            mask generation function it may also refer to the ``MGF1`` hash +            algorithm.          :raises TypeError: This is raised when the padding is not an              :class:`~cryptography.hazmat.primitives.interfaces.AsymmetricPadding` @@ -111,17 +118,6 @@ RSA          :raises ValueError: This is raised when the chosen hash algorithm is              too large for the key size. -        :raises UnsupportedHash: This is raised when the backend does not -            support the chosen hash algorithm. If the padding is -            :class:`~cryptography.hazmat.primitives.asymmetric.padding.PSS` -            with the -            :class:`~cryptography.hazmat.primitives.asymmetric.padding.MGF1` -            mask generation function it may also refer to the `MGF1` hash -            algorithm. - -        :raises UnsupportedPadding: This is raised when the backend does not -            support the chosen padding. -  .. class:: RSAPublicKey(public_exponent, modulus) @@ -205,9 +201,16 @@ RSA          :returns:              :class:`~cryptography.hazmat.primitives.interfaces.AsymmetricVerificationContext` -        :raises cryptography.exceptions.UnsupportedInterface: This is raised if +        :raises cryptography.exceptions.UnsupportedAlgorithm: This is raised if              the provided ``backend`` does not implement -            :class:`~cryptography.hazmat.backends.interfaces.RSABackend` +            :class:`~cryptography.hazmat.backends.interfaces.RSABackend` or if +            the backend does not support the chosen hash or padding algorithm. +            If the padding is +            :class:`~cryptography.hazmat.primitives.asymmetric.padding.PSS` +            with the +            :class:`~cryptography.hazmat.primitives.asymmetric.padding.MGF1` +            mask generation function it may also refer to the ``MGF1`` hash +            algorithm.          :raises TypeError: This is raised when the padding is not an              :class:`~cryptography.hazmat.primitives.interfaces.AsymmetricPadding` @@ -216,16 +219,6 @@ RSA          :raises ValueError: This is raised when the chosen hash algorithm is              too large for the key size. -        :raises UnsupportedHash: This is raised when the backend does not -            support the chosen hash algorithm. If the padding is -            :class:`~cryptography.hazmat.primitives.asymmetric.padding.PSS` -            with the -            :class:`~cryptography.hazmat.primitives.asymmetric.padding.MGF1` -            mask generation function it may also refer to the `MGF1` hash -            algorithm. - -        :raises UnsupportedPadding: This is raised when the backend does not -            support the chosen padding.  .. _`RSA`: https://en.wikipedia.org/wiki/RSA_(cryptosystem)  .. _`public-key`: https://en.wikipedia.org/wiki/Public-key_cryptography diff --git a/docs/hazmat/primitives/cryptographic-hashes.rst b/docs/hazmat/primitives/cryptographic-hashes.rst index c318feeb..773d97f6 100644 --- a/docs/hazmat/primitives/cryptographic-hashes.rst +++ b/docs/hazmat/primitives/cryptographic-hashes.rst @@ -29,7 +29,8 @@ Message digests          'l\xa1=R\xcap\xc8\x83\xe0\xf0\xbb\x10\x1eBZ\x89\xe8bM\xe5\x1d\xb2\xd29%\x93\xafj\x84\x11\x80\x90'      If the backend doesn't support the requested ``algorithm`` an -    :class:`~cryptography.exceptions.UnsupportedHash` exception will be raised. +    :class:`~cryptography.exceptions.UnsupportedAlgorithm` exception will be +    raised.      Keep in mind that attacks against cryptographic hashes only get stronger      with time, and that often algorithms that were once thought to be strong, @@ -45,7 +46,7 @@ Message digests          :class:`~cryptography.hazmat.backends.interfaces.HashBackend`          provider. -    :raises cryptography.exceptions.UnsupportedInterface: This is raised if the +    :raises cryptography.exceptions.UnsupportedAlgorithm: This is raised if the          provided ``backend`` does not implement          :class:`~cryptography.hazmat.backends.interfaces.HashBackend` diff --git a/docs/hazmat/primitives/hmac.rst b/docs/hazmat/primitives/hmac.rst index 5d511bc4..11b10735 100644 --- a/docs/hazmat/primitives/hmac.rst +++ b/docs/hazmat/primitives/hmac.rst @@ -35,7 +35,8 @@ of a message.          '#F\xdaI\x8b"e\xc4\xf1\xbb\x9a\x8fc\xff\xf5\xdex.\xbc\xcd/+\x8a\x86\x1d\x84\'\xc3\xa6\x1d\xd8J'      If the backend doesn't support the requested ``algorithm`` an -    :class:`~cryptography.exceptions.UnsupportedHash` exception will be raised. +    :class:`~cryptography.exceptions.UnsupportedAlgorithm` exception will be +    raised.      To check that a given signature is correct use the :meth:`verify` method.      You will receive an exception if the signature is wrong: @@ -56,7 +57,7 @@ of a message.          :class:`~cryptography.hazmat.backends.interfaces.HMACBackend`          provider. -    :raises cryptography.exceptions.UnsupportedInterface: This is raised if the +    :raises cryptography.exceptions.UnsupportedAlgorithm: This is raised if the          provided ``backend`` does not implement          :class:`~cryptography.hazmat.backends.interfaces.HMACBackend` diff --git a/docs/hazmat/primitives/key-derivation-functions.rst b/docs/hazmat/primitives/key-derivation-functions.rst index 6196d951..269f949d 100644 --- a/docs/hazmat/primitives/key-derivation-functions.rst +++ b/docs/hazmat/primitives/key-derivation-functions.rst @@ -84,7 +84,7 @@ Different KDFs are suitable for different tasks such as:          :class:`~cryptography.hazmat.backends.interfaces.PBKDF2HMACBackend`          provider. -    :raises cryptography.exceptions.UnsupportedInterface: This is raised if the +    :raises cryptography.exceptions.UnsupportedAlgorithm: This is raised if the          provided ``backend`` does not implement          :class:`~cryptography.hazmat.backends.interfaces.PBKDF2HMACBackend` @@ -187,7 +187,7 @@ Different KDFs are suitable for different tasks such as:          :class:`~cryptography.hazmat.backends.interfaces.HMACBackend`          provider. -    :raises cryptography.exceptions.UnsupportedInterface: This is raised if the +    :raises cryptography.exceptions.UnsupportedAlgorithm: This is raised if the          provided ``backend`` does not implement          :class:`~cryptography.hazmat.backends.interfaces.HMACBackend` diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index f7e8d5b7..28de611e 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -56,7 +56,7 @@ 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 +    :raises cryptography.exceptions.UnsupportedAlgorithm: This is raised if the          provided ``backend`` does not implement          :class:`~cryptography.hazmat.backends.interfaces.CipherBackend` @@ -67,7 +67,7 @@ an "encrypt-then-MAC" formulation as `described by Colin Percival`_.              provider.          If the backend doesn't support the requested combination of ``cipher`` -        and ``mode`` an :class:`~cryptography.exceptions.UnsupportedCipher` +        and ``mode`` an :class:`~cryptography.exceptions.UnsupportedAlgorithm`          exception will be raised.      .. method:: decryptor() @@ -77,7 +77,7 @@ an "encrypt-then-MAC" formulation as `described by Colin Percival`_.              provider.          If the backend doesn't support the requested combination of ``cipher`` -        and ``mode`` an :class:`cryptography.exceptions.UnsupportedCipher` +        and ``mode`` an :class:`cryptography.exceptions.UnsupportedAlgorithm`          exception will be raised.  .. _symmetric-encryption-algorithms: diff --git a/docs/hazmat/primitives/twofactor.rst b/docs/hazmat/primitives/twofactor.rst index e9f5c7ff..f19cf0e6 100644 --- a/docs/hazmat/primitives/twofactor.rst +++ b/docs/hazmat/primitives/twofactor.rst @@ -52,7 +52,7 @@ codes (HMAC).          :class:`~cryptography.hazmat.primitives.hashes.SHA256()` or          :class:`~cryptography.hazmat.primitives.hashes.SHA512()` or if the          ``length`` parameter is not an integer. -    :raises cryptography.exceptions.UnsupportedInterface: This is raised if the +    :raises cryptography.exceptions.UnsupportedAlgorithm: This is raised if the          provided ``backend`` does not implement          :class:`~cryptography.hazmat.backends.interfaces.HMACBackend` @@ -151,7 +151,7 @@ similar to the following code.          :class:`~cryptography.hazmat.primitives.hashes.SHA256()` or          :class:`~cryptography.hazmat.primitives.hashes.SHA512()` or if the          ``length`` parameter is not an integer. -    :raises cryptography.exceptions.UnsupportedInterface: This is raised if the +    :raises cryptography.exceptions.UnsupportedAlgorithm: This is raised if the          provided ``backend`` does not implement          :class:`~cryptography.hazmat.backends.interfaces.HMACBackend` diff --git a/tests/hazmat/backends/test_commoncrypto.py b/tests/hazmat/backends/test_commoncrypto.py index 72ed61c0..7c703f67 100644 --- a/tests/hazmat/backends/test_commoncrypto.py +++ b/tests/hazmat/backends/test_commoncrypto.py @@ -16,13 +16,15 @@ from __future__ import absolute_import, division, print_function  import pytest  from cryptography import utils -from cryptography.exceptions import InternalError, UnsupportedCipher +from cryptography.exceptions import InternalError, _Reasons  from cryptography.hazmat.bindings.commoncrypto.binding import Binding  from cryptography.hazmat.primitives import interfaces  from cryptography.hazmat.primitives.ciphers.algorithms import AES  from cryptography.hazmat.primitives.ciphers.base import Cipher  from cryptography.hazmat.primitives.ciphers.modes import CBC, GCM +from ...utils import raises_unsupported_algorithm +  @utils.register_interface(interfaces.CipherAlgorithm)  class DummyCipher(object): @@ -63,5 +65,5 @@ class TestCommonCrypto(object):          cipher = Cipher(              DummyCipher(), GCM(b"fake_iv_here"), backend=b,          ) -        with pytest.raises(UnsupportedCipher): +        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER):              cipher.encryptor() diff --git a/tests/hazmat/backends/test_multibackend.py b/tests/hazmat/backends/test_multibackend.py index c5c0d82a..b7bcaf69 100644 --- a/tests/hazmat/backends/test_multibackend.py +++ b/tests/hazmat/backends/test_multibackend.py @@ -17,7 +17,7 @@ import pytest  from cryptography import utils  from cryptography.exceptions import ( -    UnsupportedAlgorithm, UnsupportedCipher, UnsupportedHash +    UnsupportedAlgorithm, _Reasons  )  from cryptography.hazmat.backends.interfaces import (      CipherBackend, HMACBackend, HashBackend, PBKDF2HMACBackend, RSABackend @@ -27,6 +27,8 @@ from cryptography.hazmat.primitives import hashes, hmac  from cryptography.hazmat.primitives.asymmetric import padding  from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes +from ...utils import raises_unsupported_algorithm +  @utils.register_interface(CipherBackend)  class DummyCipherBackend(object): @@ -38,11 +40,11 @@ class DummyCipherBackend(object):      def create_symmetric_encryption_ctx(self, algorithm, mode):          if not self.cipher_supported(algorithm, mode): -            raise UnsupportedCipher +            raise UnsupportedAlgorithm("", _Reasons.UNSUPPORTED_CIPHER)      def create_symmetric_decryption_ctx(self, algorithm, mode):          if not self.cipher_supported(algorithm, mode): -            raise UnsupportedCipher +            raise UnsupportedAlgorithm("", _Reasons.UNSUPPORTED_CIPHER)  @utils.register_interface(HashBackend) @@ -55,7 +57,7 @@ class DummyHashBackend(object):      def create_hash_ctx(self, algorithm):          if not self.hash_supported(algorithm): -            raise UnsupportedHash +            raise UnsupportedAlgorithm("", _Reasons.UNSUPPORTED_HASH)  @utils.register_interface(HMACBackend) @@ -68,7 +70,7 @@ class DummyHMACBackend(object):      def create_hmac_ctx(self, key, algorithm):          if not self.hmac_supported(algorithm): -            raise UnsupportedHash +            raise UnsupportedAlgorithm("", _Reasons.UNSUPPORTED_HASH)  @utils.register_interface(PBKDF2HMACBackend) @@ -82,7 +84,7 @@ class DummyPBKDF2HMACBackend(object):      def derive_pbkdf2_hmac(self, algorithm, length, salt, iterations,                             key_material):          if not self.pbkdf2_hmac_supported(algorithm): -            raise UnsupportedHash +            raise UnsupportedAlgorithm("", _Reasons.UNSUPPORTED_HASH)  @utils.register_interface(RSABackend) @@ -123,9 +125,9 @@ class TestMultiBackend(object):              modes.CBC(b"\x00" * 16),              backend=backend          ) -        with pytest.raises(UnsupportedCipher): +        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER):              cipher.encryptor() -        with pytest.raises(UnsupportedCipher): +        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER):              cipher.decryptor()      def test_hashes(self): @@ -136,7 +138,7 @@ class TestMultiBackend(object):          hashes.Hash(hashes.MD5(), backend=backend) -        with pytest.raises(UnsupportedHash): +        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_HASH):              hashes.Hash(hashes.SHA1(), backend=backend)      def test_hmac(self): @@ -147,7 +149,7 @@ class TestMultiBackend(object):          hmac.HMAC(b"", hashes.MD5(), backend=backend) -        with pytest.raises(UnsupportedHash): +        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_HASH):              hmac.HMAC(b"", hashes.SHA1(), backend=backend)      def test_pbkdf2(self): @@ -158,7 +160,7 @@ class TestMultiBackend(object):          backend.derive_pbkdf2_hmac(hashes.MD5(), 10, b"", 10, b"") -        with pytest.raises(UnsupportedHash): +        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_HASH):              backend.derive_pbkdf2_hmac(hashes.SHA1(), 10, b"", 10, b"")      def test_rsa(self): diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index 3747f436..016da0fc 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -17,7 +17,7 @@ import pytest  from cryptography import utils  from cryptography.exceptions import ( -    InternalError, UnsupportedCipher, UnsupportedHash +    InternalError, _Reasons  )  from cryptography.hazmat.backends.openssl.backend import Backend, backend  from cryptography.hazmat.primitives import hashes, interfaces @@ -26,6 +26,8 @@ from cryptography.hazmat.primitives.ciphers import Cipher  from cryptography.hazmat.primitives.ciphers.algorithms import AES  from cryptography.hazmat.primitives.ciphers.modes import CBC +from ...utils import raises_unsupported_algorithm +  @utils.register_interface(interfaces.Mode)  class DummyMode(object): @@ -78,7 +80,7 @@ class TestOpenSSL(object):          cipher = Cipher(              DummyCipher(), mode, backend=b,          ) -        with pytest.raises(UnsupportedCipher): +        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER):              cipher.encryptor()      def test_consume_errors(self): @@ -140,7 +142,7 @@ class TestOpenSSL(object):      def test_derive_pbkdf2_raises_unsupported_on_old_openssl(self):          if backend.pbkdf2_hmac_supported(hashes.SHA256()):              pytest.skip("Requires an older OpenSSL") -        with pytest.raises(UnsupportedHash): +        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_HASH):              backend.derive_pbkdf2_hmac(hashes.SHA256(), 10, b"", 1000, b"")      @pytest.mark.skipif( @@ -153,7 +155,7 @@ class TestOpenSSL(object):              key_size=512,              backend=backend          ) -        with pytest.raises(UnsupportedHash): +        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_HASH):              private_key.signer(                  padding.PSS(                      mgf=padding.MGF1( @@ -165,7 +167,7 @@ class TestOpenSSL(object):                  backend              )          public_key = private_key.public_key() -        with pytest.raises(UnsupportedHash): +        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_HASH):              public_key.verifier(                  b"sig",                  padding.PSS( diff --git a/tests/hazmat/primitives/test_block.py b/tests/hazmat/primitives/test_block.py index f2dab6cf..68d6c849 100644 --- a/tests/hazmat/primitives/test_block.py +++ b/tests/hazmat/primitives/test_block.py @@ -18,7 +18,9 @@ import binascii  import pytest  from cryptography import utils -from cryptography.exceptions import AlreadyFinalized, UnsupportedCipher +from cryptography.exceptions import ( +    AlreadyFinalized, _Reasons +)  from cryptography.hazmat.primitives import interfaces  from cryptography.hazmat.primitives.ciphers import (      Cipher, algorithms, modes @@ -27,6 +29,7 @@ from cryptography.hazmat.primitives.ciphers import (  from .utils import (      generate_aead_exception_test, generate_aead_tag_exception_test  ) +from ...utils import raises_unsupported_algorithm  @utils.register_interface(interfaces.Mode) @@ -114,10 +117,10 @@ class TestCipherContext(object):          cipher = Cipher(              DummyCipher(), mode, backend          ) -        with pytest.raises(UnsupportedCipher): +        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER):              cipher.encryptor() -        with pytest.raises(UnsupportedCipher): +        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER):              cipher.decryptor()      def test_incorrectly_padded(self, backend): diff --git a/tests/hazmat/primitives/test_ciphers.py b/tests/hazmat/primitives/test_ciphers.py index 1bea0bdb..9f8123eb 100644 --- a/tests/hazmat/primitives/test_ciphers.py +++ b/tests/hazmat/primitives/test_ciphers.py @@ -17,13 +17,15 @@ import binascii  import pytest -from cryptography.exceptions import UnsupportedInterface +from cryptography.exceptions import _Reasons  from cryptography.hazmat.primitives import ciphers  from cryptography.hazmat.primitives.ciphers.algorithms import (      AES, ARC4, Blowfish, CAST5, Camellia, IDEA, TripleDES  )  from cryptography.hazmat.primitives.ciphers.modes import ECB +from ...utils import raises_unsupported_algorithm +  class TestAES(object):      @pytest.mark.parametrize(("key", "keysize"), [ @@ -128,5 +130,5 @@ class TestIDEA(object):  def test_invalid_backend():      pretend_backend = object() -    with pytest.raises(UnsupportedInterface): +    with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE):          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 5b318f64..ffd65bde 100644 --- a/tests/hazmat/primitives/test_hashes.py +++ b/tests/hazmat/primitives/test_hashes.py @@ -21,12 +21,13 @@ import six  from cryptography import utils  from cryptography.exceptions import ( -    AlreadyFinalized, UnsupportedHash, UnsupportedInterface +    AlreadyFinalized, _Reasons  )  from cryptography.hazmat.backends.interfaces import HashBackend  from cryptography.hazmat.primitives import hashes, interfaces  from .utils import generate_base_hash_test +from ...utils import raises_unsupported_algorithm  @utils.register_interface(interfaces.HashAlgorithm) @@ -72,7 +73,7 @@ class TestHashContext(object):              h.finalize()      def test_unsupported_hash(self, backend): -        with pytest.raises(UnsupportedHash): +        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_HASH):              hashes.Hash(UnsupportedDummyHash(), backend) @@ -183,5 +184,5 @@ class TestMD5(object):  def test_invalid_backend():      pretend_backend = object() -    with pytest.raises(UnsupportedInterface): +    with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE):          hashes.Hash(hashes.SHA1(), pretend_backend) diff --git a/tests/hazmat/primitives/test_hkdf.py b/tests/hazmat/primitives/test_hkdf.py index 367addc9..2e3c0c3d 100644 --- a/tests/hazmat/primitives/test_hkdf.py +++ b/tests/hazmat/primitives/test_hkdf.py @@ -18,11 +18,13 @@ import pytest  import six  from cryptography.exceptions import ( -    AlreadyFinalized, InvalidKey, UnsupportedInterface +    AlreadyFinalized, InvalidKey, _Reasons  )  from cryptography.hazmat.primitives import hashes  from cryptography.hazmat.primitives.kdf.hkdf import HKDF +from ...utils import raises_unsupported_algorithm +  @pytest.mark.hmac  class TestHKDF(object): @@ -152,5 +154,5 @@ class TestHKDF(object):  def test_invalid_backend():      pretend_backend = object() -    with pytest.raises(UnsupportedInterface): +    with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE):          HKDF(hashes.SHA256(), 16, None, None, pretend_backend) diff --git a/tests/hazmat/primitives/test_hmac.py b/tests/hazmat/primitives/test_hmac.py index 1065359a..77dfb6be 100644 --- a/tests/hazmat/primitives/test_hmac.py +++ b/tests/hazmat/primitives/test_hmac.py @@ -21,12 +21,13 @@ import six  from cryptography import utils  from cryptography.exceptions import ( -    AlreadyFinalized, InvalidSignature, UnsupportedHash, UnsupportedInterface +    AlreadyFinalized, InvalidSignature, _Reasons  )  from cryptography.hazmat.backends.interfaces import HMACBackend  from cryptography.hazmat.primitives import hashes, hmac, interfaces  from .utils import generate_base_hmac_test +from ...utils import raises_unsupported_algorithm  @utils.register_interface(interfaces.HashAlgorithm) @@ -106,12 +107,12 @@ class TestHMAC(object):              h.verify(six.u(''))      def test_unsupported_hash(self, backend): -        with pytest.raises(UnsupportedHash): +        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_HASH):              hmac.HMAC(b"key", UnsupportedDummyHash(), backend)  def test_invalid_backend():      pretend_backend = object() -    with pytest.raises(UnsupportedInterface): +    with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE):          hmac.HMAC(b"key", hashes.SHA1(), pretend_backend) diff --git a/tests/hazmat/primitives/test_pbkdf2hmac.py b/tests/hazmat/primitives/test_pbkdf2hmac.py index 585693ea..62ca0921 100644 --- a/tests/hazmat/primitives/test_pbkdf2hmac.py +++ b/tests/hazmat/primitives/test_pbkdf2hmac.py @@ -18,12 +18,14 @@ import six  from cryptography import utils  from cryptography.exceptions import ( -    AlreadyFinalized, InvalidKey, UnsupportedHash, UnsupportedInterface +    AlreadyFinalized, InvalidKey, _Reasons  )  from cryptography.hazmat.backends import default_backend  from cryptography.hazmat.primitives import hashes, interfaces  from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC +from ...utils import raises_unsupported_algorithm +  @utils.register_interface(interfaces.HashAlgorithm)  class DummyHash(object): @@ -48,7 +50,7 @@ class TestPBKDF2HMAC(object):              kdf.verify(b"password", key)      def test_unsupported_algorithm(self): -        with pytest.raises(UnsupportedHash): +        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_HASH):              PBKDF2HMAC(DummyHash(), 20, b"salt", 10, default_backend())      def test_invalid_key(self): @@ -72,5 +74,5 @@ class TestPBKDF2HMAC(object):  def test_invalid_backend():      pretend_backend = object() -    with pytest.raises(UnsupportedInterface): +    with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE):          PBKDF2HMAC(hashes.SHA1(), 20, b"salt", 10, pretend_backend) diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index eb7e1e60..5d94e790 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -22,15 +22,14 @@ import os  import pytest  from cryptography import exceptions, utils -from cryptography.exceptions import ( -    UnsupportedAlgorithm, UnsupportedInterface -) +from cryptography.exceptions import UnsupportedAlgorithm, _Reasons  from cryptography.hazmat.primitives import hashes, interfaces  from cryptography.hazmat.primitives.asymmetric import padding, rsa  from .utils import generate_rsa_verification_test  from ...utils import ( -    load_pkcs1_vectors, load_rsa_nist_vectors, load_vectors_from_file +    load_pkcs1_vectors, load_rsa_nist_vectors, load_vectors_from_file, +    raises_unsupported_algorithm  ) @@ -398,7 +397,7 @@ class TestRSA(object):  def test_rsa_generate_invalid_backend():      pretend_backend = object() -    with pytest.raises(UnsupportedInterface): +    with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE):          rsa.RSAPrivateKey.generate(65537, 2048, pretend_backend) @@ -605,7 +604,7 @@ class TestRSASignature(object):              key_size=512,              backend=backend          ) -        with pytest.raises(exceptions.UnsupportedPadding): +        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_PADDING):              private_key.signer(DummyPadding(), hashes.SHA1(), backend)      def test_padding_incorrect_type(self, backend): @@ -621,7 +620,7 @@ class TestRSASignature(object):          pretend_backend = object()          private_key = rsa.RSAPrivateKey.generate(65537, 2048, backend) -        with pytest.raises(UnsupportedInterface): +        with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE):              private_key.signer(                  padding.PKCS1v15(), hashes.SHA256, pretend_backend) @@ -853,7 +852,7 @@ class TestRSAVerification(object):              backend=backend          )          public_key = private_key.public_key() -        with pytest.raises(exceptions.UnsupportedPadding): +        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_PADDING):              public_key.verifier(b"sig", DummyPadding(), hashes.SHA1(), backend)      def test_padding_incorrect_type(self, backend): @@ -871,7 +870,7 @@ class TestRSAVerification(object):          private_key = rsa.RSAPrivateKey.generate(65537, 2048, backend)          public_key = private_key.public_key() -        with pytest.raises(UnsupportedInterface): +        with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE):              public_key.verifier(                  b"foo", padding.PKCS1v15(), hashes.SHA256(), pretend_backend) diff --git a/tests/hazmat/primitives/twofactor/test_hotp.py b/tests/hazmat/primitives/twofactor/test_hotp.py index 4bb7c6b3..803f96f3 100644 --- a/tests/hazmat/primitives/twofactor/test_hotp.py +++ b/tests/hazmat/primitives/twofactor/test_hotp.py @@ -17,12 +17,14 @@ import os  import pytest -from cryptography.exceptions import InvalidToken, UnsupportedInterface +from cryptography.exceptions import InvalidToken, _Reasons  from cryptography.hazmat.primitives import hashes  from cryptography.hazmat.primitives.hashes import MD5, SHA1  from cryptography.hazmat.primitives.twofactor.hotp import HOTP -from ....utils import load_nist_vectors, load_vectors_from_file +from ....utils import ( +    load_nist_vectors, load_vectors_from_file, raises_unsupported_algorithm +)  vectors = load_vectors_from_file(      "twofactor/rfc-4226.txt", load_nist_vectors) @@ -103,5 +105,5 @@ def test_invalid_backend():      pretend_backend = object() -    with pytest.raises(UnsupportedInterface): +    with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE):          HOTP(secret, 8, hashes.SHA1(), pretend_backend) diff --git a/tests/hazmat/primitives/twofactor/test_totp.py b/tests/hazmat/primitives/twofactor/test_totp.py index d5b0a8ed..518d3ce8 100644 --- a/tests/hazmat/primitives/twofactor/test_totp.py +++ b/tests/hazmat/primitives/twofactor/test_totp.py @@ -15,11 +15,13 @@ from __future__ import absolute_import, division, print_function  import pytest -from cryptography.exceptions import InvalidToken, UnsupportedInterface +from cryptography.exceptions import InvalidToken, _Reasons  from cryptography.hazmat.primitives import hashes  from cryptography.hazmat.primitives.twofactor.totp import TOTP -from ....utils import load_nist_vectors, load_vectors_from_file +from ....utils import ( +    load_nist_vectors, load_vectors_from_file, raises_unsupported_algorithm +)  vectors = load_vectors_from_file(      "twofactor/rfc-6238.txt", load_nist_vectors) @@ -137,5 +139,5 @@ def test_invalid_backend():      pretend_backend = object() -    with pytest.raises(UnsupportedInterface): +    with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE):          TOTP(secret, 8, hashes.SHA1(), 30, pretend_backend) diff --git a/tests/test_utils.py b/tests/test_utils.py index b63f1bab..d0b70663 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -21,13 +21,15 @@ import pretend  import pytest  import cryptography +from cryptography.exceptions import UnsupportedAlgorithm, _Reasons +  import cryptography_vectors  from .utils import (      check_backend_support, check_for_iface, load_cryptrec_vectors,      load_fips_dsa_key_pair_vectors, load_hash_vectors, load_nist_vectors,      load_pkcs1_vectors, load_rsa_nist_vectors, load_vectors_from_file, -    select_backends +    raises_unsupported_algorithm, select_backends  ) @@ -1608,3 +1610,40 @@ de61329a78d526f65245380ce877e979c5b50de66c9c30d66382c8f254653d25a1eb1d3a4897d7\  def test_vector_version():      assert cryptography.__version__ == cryptography_vectors.__version__ + + +def test_raises_unsupported_algorithm_wrong_type(): +    # Check that it raises if the wrong type of exception is raised. +    class TestException(Exception): +        pass + +    with pytest.raises(TestException): +        with raises_unsupported_algorithm(None): +            raise TestException + + +def test_raises_unsupported_algorithm_wrong_reason(): +    # Check that it fails if the wrong reason code is raised. +    with pytest.raises(AssertionError): +        with raises_unsupported_algorithm(None): +            raise UnsupportedAlgorithm("An error.", +                                       _Reasons.BACKEND_MISSING_INTERFACE) + + +def test_raises_unsupported_no_exc(): +    # Check that it fails if no exception is raised. +    with pytest.raises(pytest.fail.Exception): +        with raises_unsupported_algorithm( +            _Reasons.BACKEND_MISSING_INTERFACE +        ): +            pass + + +def test_raises_unsupported_algorithm(): +    # Check that it doesnt assert if the right things are raised. +    with raises_unsupported_algorithm( +        _Reasons.BACKEND_MISSING_INTERFACE +    ) as exc_info: +        raise UnsupportedAlgorithm("An error.", +                                   _Reasons.BACKEND_MISSING_INTERFACE) +    assert exc_info.type is UnsupportedAlgorithm diff --git a/tests/utils.py b/tests/utils.py index 3e35970e..bdbf996f 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -14,11 +14,13 @@  from __future__ import absolute_import, division, print_function  import collections +from contextlib import contextmanager  import pytest  import six +from cryptography.exceptions import UnsupportedAlgorithm  import cryptography_vectors @@ -67,6 +69,14 @@ def check_backend_support(item):                           "backend") +@contextmanager +def raises_unsupported_algorithm(reason): +    with pytest.raises(UnsupportedAlgorithm) as exc_info: +        yield exc_info + +    assert exc_info.value._reason is reason + +  def load_vectors_from_file(filename, loader):      with cryptography_vectors.open_vector_file(filename) as vector_file:          return loader(vector_file)  | 
