aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cryptography/hazmat/bindings/interfaces.py59
-rw-r--r--cryptography/hazmat/bindings/openssl/backend.py13
-rw-r--r--cryptography/hazmat/primitives/ciphers/algorithms.py13
-rw-r--r--cryptography/hazmat/primitives/ciphers/base.py3
-rw-r--r--cryptography/hazmat/primitives/ciphers/modes.py19
-rw-r--r--cryptography/hazmat/primitives/hashes.py19
-rw-r--r--cryptography/hazmat/primitives/hmac.py3
-rw-r--r--cryptography/hazmat/primitives/interfaces.py7
-rw-r--r--cryptography/hazmat/primitives/padding.py5
-rw-r--r--cryptography/utils.py21
-rw-r--r--docs/hazmat/bindings/index.rst1
-rw-r--r--docs/hazmat/bindings/interfaces.rst129
-rw-r--r--tests/hazmat/bindings/test_openssl.py3
-rw-r--r--tests/hazmat/primitives/test_block.py3
14 files changed, 258 insertions, 40 deletions
diff --git a/cryptography/hazmat/bindings/interfaces.py b/cryptography/hazmat/bindings/interfaces.py
new file mode 100644
index 00000000..ffcd5f14
--- /dev/null
+++ b/cryptography/hazmat/bindings/interfaces.py
@@ -0,0 +1,59 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from __future__ import absolute_import, division, print_function
+
+import abc
+
+import six
+
+
+class CipherBackend(six.with_metaclass(abc.ABCMeta)):
+ @abc.abstractmethod
+ def cipher_supported(self, cipher, mode):
+ """
+ """
+
+ @abc.abstractmethod
+ def register_cipher_adapter(self, cipher, mode):
+ """
+ """
+
+ @abc.abstractmethod
+ def create_symmetric_encryption_ctx(self, cipher, mode):
+ """
+ """
+
+ @abc.abstractmethod
+ def create_symmetric_decryption_ctx(self, cipher, mode):
+ """
+ """
+
+
+class HashBackend(six.with_metaclass(abc.ABCMeta)):
+ @abc.abstractmethod
+ def hash_supported(self, algorithm):
+ """
+ """
+
+ @abc.abstractmethod
+ def create_hash_ctx(self, algorithm):
+ """
+ """
+
+
+class HMACBackend(six.with_metaclass(abc.ABCMeta)):
+ @abc.abstractmethod
+ def create_hmac_ctx(self, key, algorithm):
+ """
+ """
diff --git a/cryptography/hazmat/bindings/openssl/backend.py b/cryptography/hazmat/bindings/openssl/backend.py
index 844e175f..db4d18e7 100644
--- a/cryptography/hazmat/bindings/openssl/backend.py
+++ b/cryptography/hazmat/bindings/openssl/backend.py
@@ -18,7 +18,11 @@ import sys
import cffi
+from cryptography import utils
from cryptography.exceptions import UnsupportedAlgorithm
+from cryptography.hazmat.bindings.interfaces import (
+ CipherBackend, HashBackend, HMACBackend
+)
from cryptography.hazmat.primitives import interfaces
from cryptography.hazmat.primitives.ciphers.algorithms import (
AES, Blowfish, Camellia, CAST5, TripleDES, ARC4,
@@ -28,6 +32,9 @@ from cryptography.hazmat.primitives.ciphers.modes import (
)
+@utils.register_interface(CipherBackend)
+@utils.register_interface(HashBackend)
+@utils.register_interface(HMACBackend)
class Backend(object):
"""
OpenSSL API wrapper.
@@ -196,7 +203,7 @@ class GetCipherByName(object):
return backend.lib.EVP_get_cipherbyname(cipher_name.encode("ascii"))
-@interfaces.register(interfaces.CipherContext)
+@utils.register_interface(interfaces.CipherContext)
class _CipherContext(object):
_ENCRYPT = 1
_DECRYPT = 0
@@ -267,7 +274,7 @@ class _CipherContext(object):
return self._backend.ffi.buffer(buf)[:outlen[0]]
-@interfaces.register(interfaces.HashContext)
+@utils.register_interface(interfaces.HashContext)
class _HashContext(object):
def __init__(self, backend, algorithm, ctx=None):
self.algorithm = algorithm
@@ -310,7 +317,7 @@ class _HashContext(object):
return self._backend.ffi.buffer(buf)[:]
-@interfaces.register(interfaces.HashContext)
+@utils.register_interface(interfaces.HashContext)
class _HMACContext(object):
def __init__(self, backend, key, algorithm, ctx=None):
self.algorithm = algorithm
diff --git a/cryptography/hazmat/primitives/ciphers/algorithms.py b/cryptography/hazmat/primitives/ciphers/algorithms.py
index 1ed487b6..75a87265 100644
--- a/cryptography/hazmat/primitives/ciphers/algorithms.py
+++ b/cryptography/hazmat/primitives/ciphers/algorithms.py
@@ -13,10 +13,11 @@
from __future__ import absolute_import, division, print_function
+from cryptography import utils
from cryptography.hazmat.primitives import interfaces
-@interfaces.register(interfaces.CipherAlgorithm)
+@utils.register_interface(interfaces.CipherAlgorithm)
class AES(object):
name = "AES"
block_size = 128
@@ -36,7 +37,7 @@ class AES(object):
return len(self.key) * 8
-@interfaces.register(interfaces.CipherAlgorithm)
+@utils.register_interface(interfaces.CipherAlgorithm)
class Camellia(object):
name = "camellia"
block_size = 128
@@ -56,7 +57,7 @@ class Camellia(object):
return len(self.key) * 8
-@interfaces.register(interfaces.CipherAlgorithm)
+@utils.register_interface(interfaces.CipherAlgorithm)
class TripleDES(object):
name = "3DES"
block_size = 64
@@ -80,7 +81,7 @@ class TripleDES(object):
return len(self.key) * 8
-@interfaces.register(interfaces.CipherAlgorithm)
+@utils.register_interface(interfaces.CipherAlgorithm)
class Blowfish(object):
name = "Blowfish"
block_size = 64
@@ -100,7 +101,7 @@ class Blowfish(object):
return len(self.key) * 8
-@interfaces.register(interfaces.CipherAlgorithm)
+@utils.register_interface(interfaces.CipherAlgorithm)
class CAST5(object):
name = "CAST5"
block_size = 64
@@ -120,7 +121,7 @@ class CAST5(object):
return len(self.key) * 8
-@interfaces.register(interfaces.CipherAlgorithm)
+@utils.register_interface(interfaces.CipherAlgorithm)
class ARC4(object):
name = "RC4"
block_size = 1
diff --git a/cryptography/hazmat/primitives/ciphers/base.py b/cryptography/hazmat/primitives/ciphers/base.py
index 78bf7e0c..3d733afc 100644
--- a/cryptography/hazmat/primitives/ciphers/base.py
+++ b/cryptography/hazmat/primitives/ciphers/base.py
@@ -13,6 +13,7 @@
from __future__ import absolute_import, division, print_function
+from cryptography import utils
from cryptography.exceptions import AlreadyFinalized
from cryptography.hazmat.primitives import interfaces
@@ -42,7 +43,7 @@ class Cipher(object):
))
-@interfaces.register(interfaces.CipherContext)
+@utils.register_interface(interfaces.CipherContext)
class _CipherContext(object):
def __init__(self, ctx):
self._ctx = ctx
diff --git a/cryptography/hazmat/primitives/ciphers/modes.py b/cryptography/hazmat/primitives/ciphers/modes.py
index 915fd83d..1d0de689 100644
--- a/cryptography/hazmat/primitives/ciphers/modes.py
+++ b/cryptography/hazmat/primitives/ciphers/modes.py
@@ -13,11 +13,12 @@
from __future__ import absolute_import, division, print_function
+from cryptography import utils
from cryptography.hazmat.primitives import interfaces
-@interfaces.register(interfaces.Mode)
-@interfaces.register(interfaces.ModeWithInitializationVector)
+@utils.register_interface(interfaces.Mode)
+@utils.register_interface(interfaces.ModeWithInitializationVector)
class CBC(object):
name = "CBC"
@@ -25,13 +26,13 @@ class CBC(object):
self.initialization_vector = initialization_vector
-@interfaces.register(interfaces.Mode)
+@utils.register_interface(interfaces.Mode)
class ECB(object):
name = "ECB"
-@interfaces.register(interfaces.Mode)
-@interfaces.register(interfaces.ModeWithInitializationVector)
+@utils.register_interface(interfaces.Mode)
+@utils.register_interface(interfaces.ModeWithInitializationVector)
class OFB(object):
name = "OFB"
@@ -39,8 +40,8 @@ class OFB(object):
self.initialization_vector = initialization_vector
-@interfaces.register(interfaces.Mode)
-@interfaces.register(interfaces.ModeWithInitializationVector)
+@utils.register_interface(interfaces.Mode)
+@utils.register_interface(interfaces.ModeWithInitializationVector)
class CFB(object):
name = "CFB"
@@ -48,8 +49,8 @@ class CFB(object):
self.initialization_vector = initialization_vector
-@interfaces.register(interfaces.Mode)
-@interfaces.register(interfaces.ModeWithNonce)
+@utils.register_interface(interfaces.Mode)
+@utils.register_interface(interfaces.ModeWithNonce)
class CTR(object):
name = "CTR"
diff --git a/cryptography/hazmat/primitives/hashes.py b/cryptography/hazmat/primitives/hashes.py
index 86c9fe2e..93fc8c42 100644
--- a/cryptography/hazmat/primitives/hashes.py
+++ b/cryptography/hazmat/primitives/hashes.py
@@ -15,11 +15,12 @@ from __future__ import absolute_import, division, print_function
import six
+from cryptography import utils
from cryptography.exceptions import AlreadyFinalized
from cryptography.hazmat.primitives import interfaces
-@interfaces.register(interfaces.HashContext)
+@utils.register_interface(interfaces.HashContext)
class Hash(object):
def __init__(self, algorithm, backend=None, ctx=None):
if not isinstance(algorithm, interfaces.HashAlgorithm):
@@ -59,56 +60,56 @@ class Hash(object):
return digest
-@interfaces.register(interfaces.HashAlgorithm)
+@utils.register_interface(interfaces.HashAlgorithm)
class SHA1(object):
name = "sha1"
digest_size = 20
block_size = 64
-@interfaces.register(interfaces.HashAlgorithm)
+@utils.register_interface(interfaces.HashAlgorithm)
class SHA224(object):
name = "sha224"
digest_size = 28
block_size = 64
-@interfaces.register(interfaces.HashAlgorithm)
+@utils.register_interface(interfaces.HashAlgorithm)
class SHA256(object):
name = "sha256"
digest_size = 32
block_size = 64
-@interfaces.register(interfaces.HashAlgorithm)
+@utils.register_interface(interfaces.HashAlgorithm)
class SHA384(object):
name = "sha384"
digest_size = 48
block_size = 128
-@interfaces.register(interfaces.HashAlgorithm)
+@utils.register_interface(interfaces.HashAlgorithm)
class SHA512(object):
name = "sha512"
digest_size = 64
block_size = 128
-@interfaces.register(interfaces.HashAlgorithm)
+@utils.register_interface(interfaces.HashAlgorithm)
class RIPEMD160(object):
name = "ripemd160"
digest_size = 20
block_size = 64
-@interfaces.register(interfaces.HashAlgorithm)
+@utils.register_interface(interfaces.HashAlgorithm)
class Whirlpool(object):
name = "whirlpool"
digest_size = 64
block_size = 64
-@interfaces.register(interfaces.HashAlgorithm)
+@utils.register_interface(interfaces.HashAlgorithm)
class MD5(object):
name = "md5"
digest_size = 16
diff --git a/cryptography/hazmat/primitives/hmac.py b/cryptography/hazmat/primitives/hmac.py
index 1bbe39c7..08dfae01 100644
--- a/cryptography/hazmat/primitives/hmac.py
+++ b/cryptography/hazmat/primitives/hmac.py
@@ -15,11 +15,12 @@ from __future__ import absolute_import, division, print_function
import six
+from cryptography import utils
from cryptography.exceptions import AlreadyFinalized
from cryptography.hazmat.primitives import interfaces
-@interfaces.register(interfaces.HashContext)
+@utils.register_interface(interfaces.HashContext)
class HMAC(object):
def __init__(self, key, algorithm, ctx=None, backend=None):
if not isinstance(algorithm, interfaces.HashAlgorithm):
diff --git a/cryptography/hazmat/primitives/interfaces.py b/cryptography/hazmat/primitives/interfaces.py
index bbbb266c..8cc9d42c 100644
--- a/cryptography/hazmat/primitives/interfaces.py
+++ b/cryptography/hazmat/primitives/interfaces.py
@@ -18,13 +18,6 @@ import abc
import six
-def register(iface):
- def register_decorator(klass):
- iface.register(klass)
- return klass
- return register_decorator
-
-
class CipherAlgorithm(six.with_metaclass(abc.ABCMeta)):
@abc.abstractproperty
def name(self):
diff --git a/cryptography/hazmat/primitives/padding.py b/cryptography/hazmat/primitives/padding.py
index f41c62c3..2dbac752 100644
--- a/cryptography/hazmat/primitives/padding.py
+++ b/cryptography/hazmat/primitives/padding.py
@@ -13,6 +13,7 @@
import six
+from cryptography import utils
from cryptography.hazmat.primitives import interfaces
@@ -33,7 +34,7 @@ class PKCS7(object):
return _PKCS7UnpaddingContext(self.block_size)
-@interfaces.register(interfaces.PaddingContext)
+@utils.register_interface(interfaces.PaddingContext)
class _PKCS7PaddingContext(object):
def __init__(self, block_size):
self.block_size = block_size
@@ -67,7 +68,7 @@ class _PKCS7PaddingContext(object):
return result
-@interfaces.register(interfaces.PaddingContext)
+@utils.register_interface(interfaces.PaddingContext)
class _PKCS7UnpaddingContext(object):
def __init__(self, block_size):
self.block_size = block_size
diff --git a/cryptography/utils.py b/cryptography/utils.py
new file mode 100644
index 00000000..e697d515
--- /dev/null
+++ b/cryptography/utils.py
@@ -0,0 +1,21 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from __future__ import absolute_import, division, print_function
+
+
+def register_interface(iface):
+ def register_decorator(klass):
+ iface.register(klass)
+ return klass
+ return register_decorator
diff --git a/docs/hazmat/bindings/index.rst b/docs/hazmat/bindings/index.rst
index 19e03999..11355bfa 100644
--- a/docs/hazmat/bindings/index.rst
+++ b/docs/hazmat/bindings/index.rst
@@ -7,3 +7,4 @@ Bindings
:maxdepth: 1
openssl
+ interfaces
diff --git a/docs/hazmat/bindings/interfaces.rst b/docs/hazmat/bindings/interfaces.rst
new file mode 100644
index 00000000..98c099bb
--- /dev/null
+++ b/docs/hazmat/bindings/interfaces.rst
@@ -0,0 +1,129 @@
+.. hazmat::
+
+Backend Interfaces
+==================
+
+.. currentmodule:: cryptography.hazmat.bindings.interfaces
+
+
+.. class:: CipherBackend
+
+ A backend which provides methods for using ciphers for encryption
+ and decryption.
+
+ .. method:: cipher_supported(cipher, mode)
+
+ Check if a ``cipher`` and ``mode`` combination is supported by
+ this backend.
+
+ :param cipher: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.CipherAlgorithm`
+ provider.
+ :param mode: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.Mode` provider.
+
+ :returns: ``True`` if the specified ``cipher`` and ``mode`` combination
+ is supported by this backend, otherwise ``False``
+
+ .. method:: register_cipher_adapter(cipher_cls, mode_cls, adapter)
+
+ Register an adapter which can be used to create a backend specific
+ object from instances of the
+ :class:`~cryptography.hazmat.primitives.interfaces.CipherAlgorithm` and
+ the :class:`~cryptography.hazmat.primitives.interfaces.Mode` primitives.
+
+ :param cipher_cls: A class whose instances provide
+ :class:`~cryptography.hazmat.primitives.interfaces.CipherAlgorithm`
+ :param mode_cls: A class whose instances provide:
+ :class:`~cryptography.hazmat.primitives.interfaces.Mode`
+ :param adapter: A ``function`` that takes 3 arguments, ``backend`` (a
+ :class:`CipherBackend` provider), ``cipher`` (a
+ :class:`~cryptography.hazmat.primitives.interfaces.CipherAlgorithm`
+ provider ), and ``mode`` (a
+ :class:`~cryptography.hazmat.primitives.interfaces.Mode` provider).
+ It returns a backend specific object which may be used to construct
+ a :class:`~cryptogrpahy.hazmat.primitives.interfaces.CipherContext`.
+
+
+ .. method:: create_symmetric_encryption_ctx(cipher, mode)
+
+ Create a
+ :class:`~cryptogrpahy.hazmat.primitives.interfaces.CipherContext` that
+ can be used for encrypting data with the symmetric ``cipher`` using
+ the given ``mode``.
+
+ :param cipher: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.CipherAlgorithm`
+ provider.
+ :param mode: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.Mode` provider.
+
+ :returns:
+ :class:`~cryptography.hazmat.primitives.interfaces.CipherContext`
+
+
+ .. method:: create_symmetric_decryption_ctx(cipher, mode)
+
+ Create a
+ :class:`~cryptogrpahy.hazmat.primitives.interfaces.CipherContext` that
+ can be used for decrypting data with the symmetric ``cipher`` using
+ the given ``mode``.
+
+ :param cipher: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.CipherAlgorithm`
+ provider.
+ :param mode: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.Mode` provider.
+
+ :returns:
+ :class:`~cryptography.hazmat.primitives.interfaces.CipherContext`
+
+
+.. class:: HashBackend
+
+ A backend with methods for using cryptographic hash functions.
+
+ .. method:: hash_supported(algorithm)
+
+ Check if the specified ``algorithm`` is supported by this backend.
+
+ :param algorithm: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm`
+ provider.
+
+ :returns: ``True`` if the specified ``algorithm`` is supported by this
+ backend, otherwise ``False``.
+
+
+ .. method:: create_hash_ctx(algorithm)
+
+ Create a
+ :class:`~cryptogrpahy.hazmat.primitives.interfaces.HashContext` that
+ uses the specified ``algorithm`` to calculate a message digest.
+
+ :param algorithm: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm`
+ provider.
+
+ :returns:
+ :class:`~cryptography.hazmat.primitives.interfaces.HashContext`
+
+
+.. class:: HMACBackend
+
+ A backend with methods for using cryptographic hash functions as message
+ authentication codes.
+
+ .. method:: create_hmac_ctx(algorithm)
+
+ Create a
+ :class:`~cryptogrpahy.hazmat.primitives.interfaces.HashContext` that
+ uses the specified ``algorithm`` to calculate a hash-based message
+ authentication code.
+
+ :param algorithm: An instance of a
+ :class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm`
+ provider.
+
+ :returns:
+ :class:`~cryptography.hazmat.primitives.interfaces.HashContext`
diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py
index e4f8dd8b..9f27aab7 100644
--- a/tests/hazmat/bindings/test_openssl.py
+++ b/tests/hazmat/bindings/test_openssl.py
@@ -13,6 +13,7 @@
import pytest
+from cryptography import utils
from cryptography.exceptions import UnsupportedAlgorithm
from cryptography.hazmat.bindings.openssl.backend import backend, Backend
from cryptography.hazmat.primitives import interfaces
@@ -25,7 +26,7 @@ class DummyMode(object):
pass
-@interfaces.register(interfaces.CipherAlgorithm)
+@utils.register_interface(interfaces.CipherAlgorithm)
class DummyCipher(object):
pass
diff --git a/tests/hazmat/primitives/test_block.py b/tests/hazmat/primitives/test_block.py
index 963136b9..9460c53d 100644
--- a/tests/hazmat/primitives/test_block.py
+++ b/tests/hazmat/primitives/test_block.py
@@ -17,6 +17,7 @@ import binascii
import pytest
+from cryptography import utils
from cryptography.exceptions import UnsupportedAlgorithm, AlreadyFinalized
from cryptography.hazmat.primitives import interfaces
from cryptography.hazmat.primitives.ciphers import (
@@ -24,7 +25,7 @@ from cryptography.hazmat.primitives.ciphers import (
)
-@interfaces.register(interfaces.CipherAlgorithm)
+@utils.register_interface(interfaces.CipherAlgorithm)
class DummyCipher(object):
pass