aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--.travis.yml8
-rwxr-xr-x.travis/install.sh13
-rwxr-xr-x.travis/run.sh7
-rw-r--r--AUTHORS.rst2
-rw-r--r--CHANGELOG.rst8
-rw-r--r--MANIFEST.in3
-rw-r--r--README.rst2
-rw-r--r--docs/hazmat/primitives/key-derivation-functions.rst184
-rw-r--r--setup.py79
-rw-r--r--src/_cffi_src/__init__.py0
-rw-r--r--src/_cffi_src/build_commoncrypto.py29
-rw-r--r--src/_cffi_src/build_constant_time.py26
-rw-r--r--src/_cffi_src/build_openssl.py98
-rw-r--r--src/_cffi_src/build_padding.py26
-rw-r--r--src/_cffi_src/commoncrypto/__init__.py5
-rw-r--r--src/_cffi_src/commoncrypto/cf.py (renamed from src/cryptography/hazmat/bindings/commoncrypto/cf.py)0
-rw-r--r--src/_cffi_src/commoncrypto/common_cryptor.py (renamed from src/cryptography/hazmat/bindings/commoncrypto/common_cryptor.py)0
-rw-r--r--src/_cffi_src/commoncrypto/common_digest.py (renamed from src/cryptography/hazmat/bindings/commoncrypto/common_digest.py)0
-rw-r--r--src/_cffi_src/commoncrypto/common_hmac.py (renamed from src/cryptography/hazmat/bindings/commoncrypto/common_hmac.py)0
-rw-r--r--src/_cffi_src/commoncrypto/common_key_derivation.py (renamed from src/cryptography/hazmat/bindings/commoncrypto/common_key_derivation.py)0
-rw-r--r--src/_cffi_src/commoncrypto/common_symmetric_key_wrap.py (renamed from src/cryptography/hazmat/bindings/commoncrypto/common_symmetric_key_wrap.py)0
-rw-r--r--src/_cffi_src/commoncrypto/secimport.py (renamed from src/cryptography/hazmat/bindings/commoncrypto/secimport.py)0
-rw-r--r--src/_cffi_src/commoncrypto/secitem.py (renamed from src/cryptography/hazmat/bindings/commoncrypto/secitem.py)0
-rw-r--r--src/_cffi_src/commoncrypto/seckey.py (renamed from src/cryptography/hazmat/bindings/commoncrypto/seckey.py)0
-rw-r--r--src/_cffi_src/commoncrypto/seckeychain.py (renamed from src/cryptography/hazmat/bindings/commoncrypto/seckeychain.py)0
-rw-r--r--src/_cffi_src/commoncrypto/sectransform.py (renamed from src/cryptography/hazmat/bindings/commoncrypto/sectransform.py)0
-rw-r--r--src/_cffi_src/hazmat_src/constant_time.c (renamed from src/cryptography/hazmat/primitives/src/constant_time.c)0
-rw-r--r--src/_cffi_src/hazmat_src/constant_time.h (renamed from src/cryptography/hazmat/primitives/src/constant_time.h)0
-rw-r--r--src/_cffi_src/hazmat_src/padding.c (renamed from src/cryptography/hazmat/primitives/src/padding.c)0
-rw-r--r--src/_cffi_src/hazmat_src/padding.h (renamed from src/cryptography/hazmat/primitives/src/padding.h)0
-rw-r--r--src/_cffi_src/openssl/__init__.py5
-rw-r--r--src/_cffi_src/openssl/aes.py (renamed from src/cryptography/hazmat/bindings/openssl/aes.py)0
-rw-r--r--src/_cffi_src/openssl/asn1.py (renamed from src/cryptography/hazmat/bindings/openssl/asn1.py)0
-rw-r--r--src/_cffi_src/openssl/bignum.py (renamed from src/cryptography/hazmat/bindings/openssl/bignum.py)0
-rw-r--r--src/_cffi_src/openssl/bio.py (renamed from src/cryptography/hazmat/bindings/openssl/bio.py)0
-rw-r--r--src/_cffi_src/openssl/cmac.py (renamed from src/cryptography/hazmat/bindings/openssl/cmac.py)0
-rw-r--r--src/_cffi_src/openssl/cms.py (renamed from src/cryptography/hazmat/bindings/openssl/cms.py)0
-rw-r--r--src/_cffi_src/openssl/conf.py (renamed from src/cryptography/hazmat/bindings/openssl/conf.py)0
-rw-r--r--src/_cffi_src/openssl/crypto.py (renamed from src/cryptography/hazmat/bindings/openssl/crypto.py)0
-rw-r--r--src/_cffi_src/openssl/dh.py (renamed from src/cryptography/hazmat/bindings/openssl/dh.py)0
-rw-r--r--src/_cffi_src/openssl/dsa.py (renamed from src/cryptography/hazmat/bindings/openssl/dsa.py)0
-rw-r--r--src/_cffi_src/openssl/ec.py (renamed from src/cryptography/hazmat/bindings/openssl/ec.py)0
-rw-r--r--src/_cffi_src/openssl/ecdh.py (renamed from src/cryptography/hazmat/bindings/openssl/ecdh.py)0
-rw-r--r--src/_cffi_src/openssl/ecdsa.py (renamed from src/cryptography/hazmat/bindings/openssl/ecdsa.py)0
-rw-r--r--src/_cffi_src/openssl/engine.py (renamed from src/cryptography/hazmat/bindings/openssl/engine.py)0
-rw-r--r--src/_cffi_src/openssl/err.py (renamed from src/cryptography/hazmat/bindings/openssl/err.py)0
-rw-r--r--src/_cffi_src/openssl/evp.py (renamed from src/cryptography/hazmat/bindings/openssl/evp.py)0
-rw-r--r--src/_cffi_src/openssl/hmac.py (renamed from src/cryptography/hazmat/bindings/openssl/hmac.py)0
-rw-r--r--src/_cffi_src/openssl/nid.py (renamed from src/cryptography/hazmat/bindings/openssl/nid.py)0
-rw-r--r--src/_cffi_src/openssl/objects.py (renamed from src/cryptography/hazmat/bindings/openssl/objects.py)0
-rw-r--r--src/_cffi_src/openssl/opensslv.py (renamed from src/cryptography/hazmat/bindings/openssl/opensslv.py)0
-rw-r--r--src/_cffi_src/openssl/osrandom_engine.py (renamed from src/cryptography/hazmat/bindings/openssl/osrandom_engine.py)0
-rw-r--r--src/_cffi_src/openssl/pem.py (renamed from src/cryptography/hazmat/bindings/openssl/pem.py)0
-rw-r--r--src/_cffi_src/openssl/pkcs12.py (renamed from src/cryptography/hazmat/bindings/openssl/pkcs12.py)0
-rw-r--r--src/_cffi_src/openssl/pkcs7.py (renamed from src/cryptography/hazmat/bindings/openssl/pkcs7.py)0
-rw-r--r--src/_cffi_src/openssl/rand.py (renamed from src/cryptography/hazmat/bindings/openssl/rand.py)0
-rw-r--r--src/_cffi_src/openssl/rsa.py (renamed from src/cryptography/hazmat/bindings/openssl/rsa.py)0
-rw-r--r--src/_cffi_src/openssl/src/osrandom_engine.c (renamed from src/cryptography/hazmat/bindings/openssl/src/osrandom_engine.c)0
-rw-r--r--src/_cffi_src/openssl/src/osrandom_engine.h (renamed from src/cryptography/hazmat/bindings/openssl/src/osrandom_engine.h)0
-rw-r--r--src/_cffi_src/openssl/ssl.py (renamed from src/cryptography/hazmat/bindings/openssl/ssl.py)0
-rw-r--r--src/_cffi_src/openssl/x509.py (renamed from src/cryptography/hazmat/bindings/openssl/x509.py)0
-rw-r--r--src/_cffi_src/openssl/x509_vfy.py (renamed from src/cryptography/hazmat/bindings/openssl/x509_vfy.py)0
-rw-r--r--src/_cffi_src/openssl/x509name.py (renamed from src/cryptography/hazmat/bindings/openssl/x509name.py)0
-rw-r--r--src/_cffi_src/openssl/x509v3.py (renamed from src/cryptography/hazmat/bindings/openssl/x509v3.py)0
-rw-r--r--src/_cffi_src/utils.py (renamed from src/cryptography/hazmat/bindings/utils.py)80
-rw-r--r--src/cryptography/hazmat/bindings/commoncrypto/binding.py47
-rw-r--r--src/cryptography/hazmat/bindings/openssl/binding.py108
-rw-r--r--src/cryptography/hazmat/primitives/constant_time.py16
-rw-r--r--src/cryptography/hazmat/primitives/kdf/concatkdf.py125
-rw-r--r--src/cryptography/hazmat/primitives/padding.py17
-rw-r--r--tests/hazmat/backends/test_openssl.py8
-rw-r--r--tests/hazmat/bindings/test_commoncrypto.py15
-rw-r--r--tests/hazmat/bindings/test_openssl.py19
-rw-r--r--tests/hazmat/bindings/test_utils.py30
-rw-r--r--tests/hazmat/primitives/test_concatkdf.py251
76 files changed, 838 insertions, 375 deletions
diff --git a/.gitignore b/.gitignore
index 509eba39..8a870e05 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,7 +3,7 @@ _build/
build/
dist/
htmlcov/
-src/cryptography/_Cryptography_cffi_*
+*.so
.tox/
.cache/
.coverage
diff --git a/.travis.yml b/.travis.yml
index 343576fe..76decf62 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -91,10 +91,6 @@ matrix:
- language: generic
os: osx
osx_image: beta-xcode6.3
- env: TOXENV=pypy3
- - language: generic
- os: osx
- osx_image: beta-xcode6.3
env: TOXENV=py26 OPENSSL=0.9.8
- language: generic
os: osx
@@ -115,10 +111,6 @@ matrix:
- language: generic
os: osx
osx_image: beta-xcode6.3
- env: TOXENV=pypy3 OPENSSL=0.9.8
- - language: generic
- os: osx
- osx_image: beta-xcode6.3
env: TOXENV=docs
install:
diff --git a/.travis/install.sh b/.travis/install.sh
index 7c3e9de2..a046a5d8 100755
--- a/.travis/install.sh
+++ b/.travis/install.sh
@@ -35,8 +35,8 @@ if [[ "$(uname -s)" == 'Darwin' ]]; then
;;
pypy)
brew outdated pyenv || brew upgrade pyenv
- pyenv install pypy-2.5.1
- pyenv global pypy-2.5.1
+ pyenv install pypy-2.6.0
+ pyenv global pypy-2.6.0
;;
pypy3)
brew outdated pyenv || brew upgrade pyenv
@@ -51,6 +51,15 @@ if [[ "$(uname -s)" == 'Darwin' ]]; then
pyenv rehash
python -m pip install --user virtualenv
else
+ # temporary pyenv installation to get pypy-2.6 before container infra upgrade
+ if [[ "${TOXENV}" == "pypy" ]]; then
+ git clone https://github.com/yyuu/pyenv.git ~/.pyenv
+ PYENV_ROOT="$HOME/.pyenv"
+ PATH="$PYENV_ROOT/bin:$PATH"
+ eval "$(pyenv init -)"
+ pyenv install pypy-2.6.0
+ pyenv global pypy-2.6.0
+ fi
pip install virtualenv
fi
diff --git a/.travis/run.sh b/.travis/run.sh
index 1efbd60b..17358655 100755
--- a/.travis/run.sh
+++ b/.travis/run.sh
@@ -16,6 +16,13 @@ if [[ "$(uname -s)" == "Darwin" ]]; then
# CommonCrypto when we test against brew OpenSSL
export TOX_FLAGS="--backend=openssl"
fi
+else
+ if [[ "${TOXENV}" == "pypy" ]]; then
+ PYENV_ROOT="$HOME/.pyenv"
+ PATH="$PYENV_ROOT/bin:$PATH"
+ eval "$(pyenv init -)"
+ pyenv global pypy-2.6.0
+ fi
fi
source ~/.venv/bin/activate
tox -- $TOX_FLAGS
diff --git a/AUTHORS.rst b/AUTHORS.rst
index ffa60ac3..7e7b94da 100644
--- a/AUTHORS.rst
+++ b/AUTHORS.rst
@@ -16,7 +16,7 @@ PGP key fingerprints are enclosed in parentheses.
* Stephen Holsapple <sholsapp@gmail.com>
* Terry Chia <terrycwk1994@gmail.com>
* Matthew Iversen <matt@notevencode.com> (2F04 3DCC D6E6 D5AC D262 2E0B C046 E8A8 7452 2973)
-* Mohammed Attia <skeuomorf@gmail.com> (854A F9C5 9FF5 6E38 B17D 9587 2D70 E1ED 5290 D357)
+* Mohammed Attia <skeuomorf@gmail.com>
* Michael Hart <michael.hart1994@gmail.com>
* Mark Adams <mark@markadams.me> (A18A 7DD3 283C CF2A B0CE FE0E C7A0 5E3F C972 098C)
* Gregory Haynes <greg@greghaynes.net> (6FB6 44BF 9FD0 EBA2 1CE9 471F B08F 42F9 0DC6 599F)
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 7e0f8a89..f521c11d 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -6,6 +6,11 @@ Changelog
.. note:: This version is not yet released and is under active development.
+* Switched to the new `cffi`_ ``set_source`` out-of-line API mode for
+ compilation. This results in significantly faster imports and lowered
+ memory consumption. Due to this change we no longer support PyPy releases
+ older than 2.6 nor do we support any released version of PyPy3 (until a
+ version supporting cffi 1.0 comes out).
* Support serialization of certificate signing requests using the
``public_bytes`` method of
:class:`~cryptography.x509.CertificateSigningRequest`.
@@ -15,6 +20,8 @@ Changelog
:class:`~cryptography.hazmat.primitives.twofactor.hotp.HOTP` and
:class:`~cryptography.hazmat.primitives.twofactor.totp.TOTP` for generating
provisioning URIs.
+* Add :class:`~cryptography.hazmat.primitives.kdf.concatkdf.ConcatKDFHash`
+ and :class:`~cryptography.hazmat.primitives.kdf.concatkdf.ConcatKDFHMAC`.
0.9.1 - 2015-06-06
~~~~~~~~~~~~~~~~~~
@@ -442,3 +449,4 @@ Changelog
* Initial release.
.. _`master`: https://github.com/pyca/cryptography/
+.. _`cffi`: https://cffi.readthedocs.org/en/latest/
diff --git a/MANIFEST.in b/MANIFEST.in
index 8dbd0dc2..b05a869c 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -7,8 +7,7 @@ include LICENSE.BSD
include README.rst
recursive-include docs *
-recursive-include src/cryptography/hazmat/primitives/src *.c *.h
-recursive-include src/cryptography/hazmat/bindings/openssl/src *.c *.h
+recursive-include src/_cffi_src *.py *.c *.h
prune docs/_build
recursive-include tests *.py
recursive-exclude vectors *
diff --git a/README.rst b/README.rst
index 4f5c646f..98e8d17e 100644
--- a/README.rst
+++ b/README.rst
@@ -1,7 +1,7 @@
Cryptography
============
-.. image:: https://pypip.in/version/cryptography/badge.svg?style=flat
+.. image:: https://img.shields.io/pypi/v/cryptography.svg
:target: https://pypi.python.org/pypi/cryptography/
:alt: Latest Version
diff --git a/docs/hazmat/primitives/key-derivation-functions.rst b/docs/hazmat/primitives/key-derivation-functions.rst
index 78d40315..35e2dd87 100644
--- a/docs/hazmat/primitives/key-derivation-functions.rst
+++ b/docs/hazmat/primitives/key-derivation-functions.rst
@@ -324,6 +324,189 @@ Different KDFs are suitable for different tasks such as:
``key_material`` generates the same key as the ``expected_key``, and
raises an exception if they do not match.
+.. currentmodule:: cryptography.hazmat.primitives.kdf.concatkdf
+
+.. class:: ConcatKDFHash(algorithm, length, otherinfo, backend)
+
+ .. versionadded:: 1.0
+
+ ConcatKDFHash (Concatenation Key Derivation Function) is defined by the
+ NIST Special Publication `NIST SP 800-56Ar2`_ document, to be used to
+ derive keys for use after a Key Exchange negotiation operation.
+
+ .. warning::
+
+ ConcatKDFHash should not be used for password storage.
+
+ .. doctest::
+
+ >>> import os
+ >>> from cryptography.hazmat.primitives import hashes
+ >>> from cryptography.hazmat.primitives.kdf.concatkdf import ConcatKDFHash
+ >>> from cryptography.hazmat.backends import default_backend
+ >>> backend = default_backend()
+ >>> otherinfo = b"concatkdf-example"
+ >>> ckdf = ConcatKDFHash(
+ ... algorithm=hashes.SHA256(),
+ ... length=256,
+ ... otherinfo=otherinfo,
+ ... backend=backend
+ ... )
+ >>> key = ckdf.derive(b"input key")
+ >>> ckdf = ConcatKDFHash(
+ ... algorithm=hashes.SHA256(),
+ ... length=256,
+ ... otherinfo=otherinfo,
+ ... backend=backend
+ ... )
+ >>> ckdf.verify(b"input key", key)
+
+ :param algorithm: An instance of a
+ :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm`
+ provider
+
+ :param int length: The desired length of the derived key in bytes.
+ Maximum is ``hashlen * (2^32 -1)``.
+
+ :param bytes otherinfo: Application specific context information.
+ If ``None`` is explicitly passed an empty byte string will be used.
+
+ :param backend: A
+ :class:`~cryptography.hazmat.backends.interfaces.HashBackend`
+ provider.
+
+ :raises cryptography.exceptions.UnsupportedAlgorithm: This is raised
+ if the provided ``backend`` does not implement
+ :class:`~cryptography.hazmat.backends.interfaces.HashBackend`
+
+ :raises TypeError: This exception is raised if ``otherinfo`` is not
+ ``bytes``.
+
+ .. method:: derive(key_material)
+
+ :param bytes key_material: The input key material.
+ :return bytes: The derived key.
+ :raises TypeError: This exception is raised if ``key_material`` is
+ not ``bytes``.
+
+ Derives a new key from the input key material.
+
+ .. method:: verify(key_material, expected_key)
+
+ :param bytes key_material: The input key material. This is the same as
+ ``key_material`` in :meth:`derive`.
+ :param bytes expected_key: The expected result of deriving a new key,
+ this is the same as the return value of
+ :meth:`derive`.
+ :raises cryptography.exceptions.InvalidKey: This is raised when the
+ derived key does not match
+ the expected key.
+ :raises cryptography.exceptions.AlreadyFinalized: This is raised when
+ :meth:`derive` or
+ :meth:`verify` is
+ called more than
+ once.
+
+ This checks whether deriving a new key from the supplied
+ ``key_material`` generates the same key as the ``expected_key``, and
+ raises an exception if they do not match.
+
+
+.. class:: ConcatKDFHMAC(algorithm, length, salt, otherinfo, backend)
+
+ .. versionadded:: 1.0
+
+ Similar to ConcatKFDHash but uses an HMAC function instead.
+
+ .. warning::
+
+ ConcatKDFHMAC should not be used for password storage.
+
+ .. doctest::
+
+ >>> import os
+ >>> from cryptography.hazmat.primitives import hashes
+ >>> from cryptography.hazmat.primitives.kdf.concatkdf import ConcatKDFHMAC
+ >>> from cryptography.hazmat.backends import default_backend
+ >>> backend = default_backend()
+ >>> salt = os.urandom(16)
+ >>> otherinfo = b"concatkdf-example"
+ >>> ckdf = ConcatKDFHMAC(
+ ... algorithm=hashes.SHA256(),
+ ... length=256,
+ ... salt=salt,
+ ... otherinfo=otherinfo,
+ ... backend=backend
+ ... )
+ >>> key = ckdf.derive(b"input key")
+ >>> ckdf = ConcatKDFHMAC(
+ ... algorithm=hashes.SHA256(),
+ ... length=256,
+ ... salt=salt,
+ ... otherinfo=otherinfo,
+ ... backend=backend
+ ... )
+ >>> ckdf.verify(b"input key", key)
+
+ :param algorithm: An instance of a
+ :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm`
+ provider
+
+ :param int length: The desired length of the derived key in bytes. Maximum
+ is ``hashlen * (2^32 -1)``.
+
+ :param bytes salt: A salt. Randomizes the KDF's output. Optional, but
+ highly recommended. Ideally as many bits of entropy as the security
+ level of the hash: often that means cryptographically random and as
+ long as the hash output. Does not have to be secret, but may cause
+ stronger security guarantees if secret; If ``None`` is explicitly
+ passed a default salt of ``algorithm.block_size`` null bytes will be
+ used.
+
+ :param bytes otherinfo: Application specific context information.
+ If ``None`` is explicitly passed an empty byte string will be used.
+
+ :param backend: A
+ :class:`~cryptography.hazmat.backends.interfaces.HMACBackend`
+ provider.
+
+ :raises cryptography.exceptions.UnsupportedAlgorithm: This is raised if the
+ provided ``backend`` does not implement
+ :class:`~cryptography.hazmat.backends.interfaces.HMACBackend`
+
+ :raises TypeError: This exception is raised if ``salt`` or ``otherinfo``
+ is not ``bytes``.
+
+ .. method:: derive(key_material)
+
+ :param bytes key_material: The input key material.
+ :return bytes: The derived key.
+ :raises TypeError: This exception is raised if ``key_material`` is not
+ ``bytes``.
+
+ Derives a new key from the input key material.
+
+ .. method:: verify(key_material, expected_key)
+
+ :param bytes key_material: The input key material. This is the same as
+ ``key_material`` in :meth:`derive`.
+ :param bytes expected_key: The expected result of deriving a new key,
+ this is the same as the return value of
+ :meth:`derive`.
+ :raises cryptography.exceptions.InvalidKey: This is raised when the
+ derived key does not match
+ the expected key.
+ :raises cryptography.exceptions.AlreadyFinalized: This is raised when
+ :meth:`derive` or
+ :meth:`verify` is
+ called more than
+ once.
+
+ This checks whether deriving a new key from the supplied
+ ``key_material`` generates the same key as the ``expected_key``, and
+ raises an exception if they do not match.
+
+
Interface
~~~~~~~~~
@@ -372,6 +555,7 @@ Interface
.. _`NIST SP 800-132`: http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf
+.. _`NIST SP 800-56Ar2`: http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar2.pdf
.. _`Password Storage Cheat Sheet`: https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet
.. _`PBKDF2`: https://en.wikipedia.org/wiki/PBKDF2
.. _`scrypt`: https://en.wikipedia.org/wiki/Scrypt
diff --git a/setup.py b/setup.py
index 77f6dcdb..4cd3b51a 100644
--- a/setup.py
+++ b/setup.py
@@ -37,6 +37,7 @@ requirements = [
"six>=1.4.1",
"setuptools"
]
+setup_requirements = []
if sys.version_info < (3, 4):
requirements.append("enum34")
@@ -45,7 +46,8 @@ if sys.version_info < (3, 3):
requirements.append("ipaddress")
if platform.python_implementation() != "PyPy":
- requirements.append("cffi>=0.8")
+ requirements.append("cffi>=1.1.0")
+ setup_requirements.append("cffi>=1.1.0")
# If you add a new dep here you probably need to add it in the tox.ini as well
test_requirements = [
@@ -75,52 +77,6 @@ if cc_is_available():
)
-def get_ext_modules():
- from cryptography.hazmat.bindings.commoncrypto.binding import (
- Binding as CommonCryptoBinding
- )
- from cryptography.hazmat.bindings.openssl.binding import (
- Binding as OpenSSLBinding
- )
- from cryptography.hazmat.primitives import constant_time, padding
-
- ext_modules = [
- OpenSSLBinding.ffi.verifier.get_extension(),
- constant_time._ffi.verifier.get_extension(),
- padding._ffi.verifier.get_extension()
- ]
- if cc_is_available():
- ext_modules.append(CommonCryptoBinding.ffi.verifier.get_extension())
- return ext_modules
-
-
-class CFFIBuild(build):
- """
- This class exists, instead of just providing ``ext_modules=[...]`` directly
- in ``setup()`` because importing cryptography requires we have several
- packages installed first.
-
- By doing the imports here we ensure that packages listed in
- ``setup_requires`` are already installed.
- """
-
- def finalize_options(self):
- self.distribution.ext_modules = get_ext_modules()
- build.finalize_options(self)
-
-
-class CFFIInstall(install):
- """
- As a consequence of CFFIBuild and it's late addition of ext_modules, we
- need the equivalent for the ``install`` command to install into platlib
- install-dir rather than purelib.
- """
-
- def finalize_options(self):
- self.distribution.ext_modules = get_ext_modules()
- install.finalize_options(self)
-
-
class PyTest(test):
def finalize_options(self):
test.finalize_options(self)
@@ -234,19 +190,26 @@ def keywords_with_side_effects(argv):
for i in range(1, len(argv))):
return {
"cmdclass": {
- "build": DummyCFFIBuild,
- "install": DummyCFFIInstall,
+ "build": DummyBuild,
+ "install": DummyInstall,
"test": DummyPyTest,
}
}
else:
+ cffi_modules = [
+ "src/_cffi_src/build_openssl.py:ffi",
+ "src/_cffi_src/build_constant_time.py:ffi",
+ "src/_cffi_src/build_padding.py:ffi",
+ ]
+ if cc_is_available():
+ cffi_modules.append("src/_cffi_src/build_commoncrypto.py:ffi")
+
return {
- "setup_requires": requirements,
+ "setup_requires": setup_requirements,
"cmdclass": {
- "build": CFFIBuild,
- "install": CFFIInstall,
"test": PyTest,
- }
+ },
+ "cffi_modules": cffi_modules
}
@@ -255,7 +218,7 @@ setup_requires_error = ("Requested setup command that needs 'setup_requires' "
"free command or option.")
-class DummyCFFIBuild(build):
+class DummyBuild(build):
"""
This class makes it very obvious when ``keywords_with_side_effects()`` has
incorrectly interpreted the command line arguments to ``setup.py build`` as
@@ -266,7 +229,7 @@ class DummyCFFIBuild(build):
raise RuntimeError(setup_requires_error)
-class DummyCFFIInstall(install):
+class DummyInstall(install):
"""
This class makes it very obvious when ``keywords_with_side_effects()`` has
incorrectly interpreted the command line arguments to ``setup.py install``
@@ -327,7 +290,9 @@ setup(
],
package_dir={"": "src"},
- packages=find_packages(where="src", exclude=["tests", "tests.*"]),
+ packages=find_packages(
+ where="src", exclude=["_cffi_src", "_cffi_src.*", "tests", "tests.*"]
+ ),
include_package_data=True,
install_requires=requirements,
@@ -335,7 +300,7 @@ setup(
# for cffi
zip_safe=False,
- ext_package="cryptography",
+ ext_package="cryptography.hazmat.bindings",
entry_points={
"cryptography.backends": backends,
},
diff --git a/src/_cffi_src/__init__.py b/src/_cffi_src/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/_cffi_src/__init__.py
diff --git a/src/_cffi_src/build_commoncrypto.py b/src/_cffi_src/build_commoncrypto.py
new file mode 100644
index 00000000..1c2692a7
--- /dev/null
+++ b/src/_cffi_src/build_commoncrypto.py
@@ -0,0 +1,29 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import, division, print_function
+
+from _cffi_src.utils import build_ffi_for_binding
+
+
+ffi = build_ffi_for_binding(
+ module_name="_commoncrypto",
+ module_prefix="_cffi_src.commoncrypto.",
+ modules=[
+ "cf",
+ "common_digest",
+ "common_hmac",
+ "common_key_derivation",
+ "common_cryptor",
+ "common_symmetric_key_wrap",
+ "secimport",
+ "secitem",
+ "seckey",
+ "seckeychain",
+ "sectransform",
+ ],
+ extra_link_args=[
+ "-framework", "Security", "-framework", "CoreFoundation"
+ ],
+)
diff --git a/src/_cffi_src/build_constant_time.py b/src/_cffi_src/build_constant_time.py
new file mode 100644
index 00000000..eae0f21a
--- /dev/null
+++ b/src/_cffi_src/build_constant_time.py
@@ -0,0 +1,26 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import, division, print_function
+
+import os
+
+from _cffi_src.utils import build_ffi
+
+
+with open(os.path.join(
+ os.path.dirname(__file__), "hazmat_src/constant_time.h"
+)) as f:
+ types = f.read()
+
+with open(os.path.join(
+ os.path.dirname(__file__), "hazmat_src/constant_time.c"
+)) as f:
+ functions = f.read()
+
+ffi = build_ffi(
+ module_name="_constant_time",
+ cdef_source=types,
+ verify_source=functions
+)
diff --git a/src/_cffi_src/build_openssl.py b/src/_cffi_src/build_openssl.py
new file mode 100644
index 00000000..4c30fe48
--- /dev/null
+++ b/src/_cffi_src/build_openssl.py
@@ -0,0 +1,98 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import, division, print_function
+
+import os
+import sys
+
+from _cffi_src.utils import (
+ build_ffi_for_binding
+)
+
+
+def _get_openssl_libraries(platform):
+ # OpenSSL goes by a different library name on different operating systems.
+ if platform != "win32":
+ # In some circumstances, the order in which these libs are
+ # specified on the linker command-line is significant;
+ # libssl must come before libcrypto
+ # (http://marc.info/?l=openssl-users&m=135361825921871)
+ return ["ssl", "crypto"]
+ else:
+ link_type = os.environ.get("PYCA_WINDOWS_LINK_TYPE", "static")
+ return _get_openssl_windows_libraries(link_type)
+
+
+def _get_openssl_windows_libraries(link_type):
+ if link_type == "dynamic":
+ return ["libeay32", "ssleay32", "advapi32"]
+ elif link_type == "static" or link_type == "":
+ return ["libeay32mt", "ssleay32mt", "advapi32",
+ "crypt32", "gdi32", "user32", "ws2_32"]
+ else:
+ raise ValueError(
+ "PYCA_WINDOWS_LINK_TYPE must be 'static' or 'dynamic'"
+ )
+
+
+_OSX_PRE_INCLUDE = """
+#ifdef __APPLE__
+#include <AvailabilityMacros.h>
+#define __ORIG_DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER \
+ DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
+#undef DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
+#define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
+#endif
+"""
+
+_OSX_POST_INCLUDE = """
+#ifdef __APPLE__
+#undef DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
+#define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER \
+ __ORIG_DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
+#endif
+"""
+
+
+ffi = build_ffi_for_binding(
+ module_name="_openssl",
+ module_prefix="_cffi_src.openssl.",
+ modules=[
+ "aes",
+ "asn1",
+ "bignum",
+ "bio",
+ "cmac",
+ "cms",
+ "conf",
+ "crypto",
+ "dh",
+ "dsa",
+ "ec",
+ "ecdh",
+ "ecdsa",
+ "engine",
+ "err",
+ "evp",
+ "hmac",
+ "nid",
+ "objects",
+ "opensslv",
+ "osrandom_engine",
+ "pem",
+ "pkcs7",
+ "pkcs12",
+ "rand",
+ "rsa",
+ "ssl",
+ "x509",
+ "x509name",
+ "x509v3",
+ "x509_vfy"
+ ],
+ pre_include=_OSX_PRE_INCLUDE,
+ post_include=_OSX_POST_INCLUDE,
+ libraries=_get_openssl_libraries(sys.platform)
+)
diff --git a/src/_cffi_src/build_padding.py b/src/_cffi_src/build_padding.py
new file mode 100644
index 00000000..3eeac2e2
--- /dev/null
+++ b/src/_cffi_src/build_padding.py
@@ -0,0 +1,26 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import, division, print_function
+
+import os
+
+from _cffi_src.utils import build_ffi
+
+
+with open(os.path.join(
+ os.path.dirname(__file__), "hazmat_src/padding.h"
+)) as f:
+ types = f.read()
+
+with open(os.path.join(
+ os.path.dirname(__file__), "hazmat_src/padding.c"
+)) as f:
+ functions = f.read()
+
+ffi = build_ffi(
+ module_name="_padding",
+ cdef_source=types,
+ verify_source=functions
+)
diff --git a/src/_cffi_src/commoncrypto/__init__.py b/src/_cffi_src/commoncrypto/__init__.py
new file mode 100644
index 00000000..4b540884
--- /dev/null
+++ b/src/_cffi_src/commoncrypto/__init__.py
@@ -0,0 +1,5 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import, division, print_function
diff --git a/src/cryptography/hazmat/bindings/commoncrypto/cf.py b/src/_cffi_src/commoncrypto/cf.py
index 77d2d7cc..77d2d7cc 100644
--- a/src/cryptography/hazmat/bindings/commoncrypto/cf.py
+++ b/src/_cffi_src/commoncrypto/cf.py
diff --git a/src/cryptography/hazmat/bindings/commoncrypto/common_cryptor.py b/src/_cffi_src/commoncrypto/common_cryptor.py
index fc6eef91..fc6eef91 100644
--- a/src/cryptography/hazmat/bindings/commoncrypto/common_cryptor.py
+++ b/src/_cffi_src/commoncrypto/common_cryptor.py
diff --git a/src/cryptography/hazmat/bindings/commoncrypto/common_digest.py b/src/_cffi_src/commoncrypto/common_digest.py
index a76fc508..a76fc508 100644
--- a/src/cryptography/hazmat/bindings/commoncrypto/common_digest.py
+++ b/src/_cffi_src/commoncrypto/common_digest.py
diff --git a/src/cryptography/hazmat/bindings/commoncrypto/common_hmac.py b/src/_cffi_src/commoncrypto/common_hmac.py
index fcd0c0f4..fcd0c0f4 100644
--- a/src/cryptography/hazmat/bindings/commoncrypto/common_hmac.py
+++ b/src/_cffi_src/commoncrypto/common_hmac.py
diff --git a/src/cryptography/hazmat/bindings/commoncrypto/common_key_derivation.py b/src/_cffi_src/commoncrypto/common_key_derivation.py
index 19525852..19525852 100644
--- a/src/cryptography/hazmat/bindings/commoncrypto/common_key_derivation.py
+++ b/src/_cffi_src/commoncrypto/common_key_derivation.py
diff --git a/src/cryptography/hazmat/bindings/commoncrypto/common_symmetric_key_wrap.py b/src/_cffi_src/commoncrypto/common_symmetric_key_wrap.py
index ea9e459d..ea9e459d 100644
--- a/src/cryptography/hazmat/bindings/commoncrypto/common_symmetric_key_wrap.py
+++ b/src/_cffi_src/commoncrypto/common_symmetric_key_wrap.py
diff --git a/src/cryptography/hazmat/bindings/commoncrypto/secimport.py b/src/_cffi_src/commoncrypto/secimport.py
index 41a799f9..41a799f9 100644
--- a/src/cryptography/hazmat/bindings/commoncrypto/secimport.py
+++ b/src/_cffi_src/commoncrypto/secimport.py
diff --git a/src/cryptography/hazmat/bindings/commoncrypto/secitem.py b/src/_cffi_src/commoncrypto/secitem.py
index dd255430..dd255430 100644
--- a/src/cryptography/hazmat/bindings/commoncrypto/secitem.py
+++ b/src/_cffi_src/commoncrypto/secitem.py
diff --git a/src/cryptography/hazmat/bindings/commoncrypto/seckey.py b/src/_cffi_src/commoncrypto/seckey.py
index 01d42e6a..01d42e6a 100644
--- a/src/cryptography/hazmat/bindings/commoncrypto/seckey.py
+++ b/src/_cffi_src/commoncrypto/seckey.py
diff --git a/src/cryptography/hazmat/bindings/commoncrypto/seckeychain.py b/src/_cffi_src/commoncrypto/seckeychain.py
index 6a2cb4be..6a2cb4be 100644
--- a/src/cryptography/hazmat/bindings/commoncrypto/seckeychain.py
+++ b/src/_cffi_src/commoncrypto/seckeychain.py
diff --git a/src/cryptography/hazmat/bindings/commoncrypto/sectransform.py b/src/_cffi_src/commoncrypto/sectransform.py
index bed94953..bed94953 100644
--- a/src/cryptography/hazmat/bindings/commoncrypto/sectransform.py
+++ b/src/_cffi_src/commoncrypto/sectransform.py
diff --git a/src/cryptography/hazmat/primitives/src/constant_time.c b/src/_cffi_src/hazmat_src/constant_time.c
index 0a48fe83..0a48fe83 100644
--- a/src/cryptography/hazmat/primitives/src/constant_time.c
+++ b/src/_cffi_src/hazmat_src/constant_time.c
diff --git a/src/cryptography/hazmat/primitives/src/constant_time.h b/src/_cffi_src/hazmat_src/constant_time.h
index 593479f6..593479f6 100644
--- a/src/cryptography/hazmat/primitives/src/constant_time.h
+++ b/src/_cffi_src/hazmat_src/constant_time.h
diff --git a/src/cryptography/hazmat/primitives/src/padding.c b/src/_cffi_src/hazmat_src/padding.c
index 570bad9f..570bad9f 100644
--- a/src/cryptography/hazmat/primitives/src/padding.c
+++ b/src/_cffi_src/hazmat_src/padding.c
diff --git a/src/cryptography/hazmat/primitives/src/padding.h b/src/_cffi_src/hazmat_src/padding.h
index 4d218b1a..4d218b1a 100644
--- a/src/cryptography/hazmat/primitives/src/padding.h
+++ b/src/_cffi_src/hazmat_src/padding.h
diff --git a/src/_cffi_src/openssl/__init__.py b/src/_cffi_src/openssl/__init__.py
new file mode 100644
index 00000000..4b540884
--- /dev/null
+++ b/src/_cffi_src/openssl/__init__.py
@@ -0,0 +1,5 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import, division, print_function
diff --git a/src/cryptography/hazmat/bindings/openssl/aes.py b/src/_cffi_src/openssl/aes.py
index 15da9b62..15da9b62 100644
--- a/src/cryptography/hazmat/bindings/openssl/aes.py
+++ b/src/_cffi_src/openssl/aes.py
diff --git a/src/cryptography/hazmat/bindings/openssl/asn1.py b/src/_cffi_src/openssl/asn1.py
index c18708c5..c18708c5 100644
--- a/src/cryptography/hazmat/bindings/openssl/asn1.py
+++ b/src/_cffi_src/openssl/asn1.py
diff --git a/src/cryptography/hazmat/bindings/openssl/bignum.py b/src/_cffi_src/openssl/bignum.py
index d974e04e..d974e04e 100644
--- a/src/cryptography/hazmat/bindings/openssl/bignum.py
+++ b/src/_cffi_src/openssl/bignum.py
diff --git a/src/cryptography/hazmat/bindings/openssl/bio.py b/src/_cffi_src/openssl/bio.py
index 6cc1bcb2..6cc1bcb2 100644
--- a/src/cryptography/hazmat/bindings/openssl/bio.py
+++ b/src/_cffi_src/openssl/bio.py
diff --git a/src/cryptography/hazmat/bindings/openssl/cmac.py b/src/_cffi_src/openssl/cmac.py
index c01a449f..c01a449f 100644
--- a/src/cryptography/hazmat/bindings/openssl/cmac.py
+++ b/src/_cffi_src/openssl/cmac.py
diff --git a/src/cryptography/hazmat/bindings/openssl/cms.py b/src/_cffi_src/openssl/cms.py
index a43df5d9..a43df5d9 100644
--- a/src/cryptography/hazmat/bindings/openssl/cms.py
+++ b/src/_cffi_src/openssl/cms.py
diff --git a/src/cryptography/hazmat/bindings/openssl/conf.py b/src/_cffi_src/openssl/conf.py
index cab246f0..cab246f0 100644
--- a/src/cryptography/hazmat/bindings/openssl/conf.py
+++ b/src/_cffi_src/openssl/conf.py
diff --git a/src/cryptography/hazmat/bindings/openssl/crypto.py b/src/_cffi_src/openssl/crypto.py
index 641e95a8..641e95a8 100644
--- a/src/cryptography/hazmat/bindings/openssl/crypto.py
+++ b/src/_cffi_src/openssl/crypto.py
diff --git a/src/cryptography/hazmat/bindings/openssl/dh.py b/src/_cffi_src/openssl/dh.py
index b66e7196..b66e7196 100644
--- a/src/cryptography/hazmat/bindings/openssl/dh.py
+++ b/src/_cffi_src/openssl/dh.py
diff --git a/src/cryptography/hazmat/bindings/openssl/dsa.py b/src/_cffi_src/openssl/dsa.py
index 99a685df..99a685df 100644
--- a/src/cryptography/hazmat/bindings/openssl/dsa.py
+++ b/src/_cffi_src/openssl/dsa.py
diff --git a/src/cryptography/hazmat/bindings/openssl/ec.py b/src/_cffi_src/openssl/ec.py
index c5052d36..c5052d36 100644
--- a/src/cryptography/hazmat/bindings/openssl/ec.py
+++ b/src/_cffi_src/openssl/ec.py
diff --git a/src/cryptography/hazmat/bindings/openssl/ecdh.py b/src/_cffi_src/openssl/ecdh.py
index 6c7e010c..6c7e010c 100644
--- a/src/cryptography/hazmat/bindings/openssl/ecdh.py
+++ b/src/_cffi_src/openssl/ecdh.py
diff --git a/src/cryptography/hazmat/bindings/openssl/ecdsa.py b/src/_cffi_src/openssl/ecdsa.py
index db21025c..db21025c 100644
--- a/src/cryptography/hazmat/bindings/openssl/ecdsa.py
+++ b/src/_cffi_src/openssl/ecdsa.py
diff --git a/src/cryptography/hazmat/bindings/openssl/engine.py b/src/_cffi_src/openssl/engine.py
index 3ebfa6c1..3ebfa6c1 100644
--- a/src/cryptography/hazmat/bindings/openssl/engine.py
+++ b/src/_cffi_src/openssl/engine.py
diff --git a/src/cryptography/hazmat/bindings/openssl/err.py b/src/_cffi_src/openssl/err.py
index 0ee19c9e..0ee19c9e 100644
--- a/src/cryptography/hazmat/bindings/openssl/err.py
+++ b/src/_cffi_src/openssl/err.py
diff --git a/src/cryptography/hazmat/bindings/openssl/evp.py b/src/_cffi_src/openssl/evp.py
index 93aa83de..93aa83de 100644
--- a/src/cryptography/hazmat/bindings/openssl/evp.py
+++ b/src/_cffi_src/openssl/evp.py
diff --git a/src/cryptography/hazmat/bindings/openssl/hmac.py b/src/_cffi_src/openssl/hmac.py
index 86bbdfc2..86bbdfc2 100644
--- a/src/cryptography/hazmat/bindings/openssl/hmac.py
+++ b/src/_cffi_src/openssl/hmac.py
diff --git a/src/cryptography/hazmat/bindings/openssl/nid.py b/src/_cffi_src/openssl/nid.py
index c2c0552b..c2c0552b 100644
--- a/src/cryptography/hazmat/bindings/openssl/nid.py
+++ b/src/_cffi_src/openssl/nid.py
diff --git a/src/cryptography/hazmat/bindings/openssl/objects.py b/src/_cffi_src/openssl/objects.py
index 9c480b37..9c480b37 100644
--- a/src/cryptography/hazmat/bindings/openssl/objects.py
+++ b/src/_cffi_src/openssl/objects.py
diff --git a/src/cryptography/hazmat/bindings/openssl/opensslv.py b/src/_cffi_src/openssl/opensslv.py
index e6c5f269..e6c5f269 100644
--- a/src/cryptography/hazmat/bindings/openssl/opensslv.py
+++ b/src/_cffi_src/openssl/opensslv.py
diff --git a/src/cryptography/hazmat/bindings/openssl/osrandom_engine.py b/src/_cffi_src/openssl/osrandom_engine.py
index a8479b07..a8479b07 100644
--- a/src/cryptography/hazmat/bindings/openssl/osrandom_engine.py
+++ b/src/_cffi_src/openssl/osrandom_engine.py
diff --git a/src/cryptography/hazmat/bindings/openssl/pem.py b/src/_cffi_src/openssl/pem.py
index 8ec3fefd..8ec3fefd 100644
--- a/src/cryptography/hazmat/bindings/openssl/pem.py
+++ b/src/_cffi_src/openssl/pem.py
diff --git a/src/cryptography/hazmat/bindings/openssl/pkcs12.py b/src/_cffi_src/openssl/pkcs12.py
index fa7564ac..fa7564ac 100644
--- a/src/cryptography/hazmat/bindings/openssl/pkcs12.py
+++ b/src/_cffi_src/openssl/pkcs12.py
diff --git a/src/cryptography/hazmat/bindings/openssl/pkcs7.py b/src/_cffi_src/openssl/pkcs7.py
index df82afef..df82afef 100644
--- a/src/cryptography/hazmat/bindings/openssl/pkcs7.py
+++ b/src/_cffi_src/openssl/pkcs7.py
diff --git a/src/cryptography/hazmat/bindings/openssl/rand.py b/src/_cffi_src/openssl/rand.py
index 6330482c..6330482c 100644
--- a/src/cryptography/hazmat/bindings/openssl/rand.py
+++ b/src/_cffi_src/openssl/rand.py
diff --git a/src/cryptography/hazmat/bindings/openssl/rsa.py b/src/_cffi_src/openssl/rsa.py
index 8bac7895..8bac7895 100644
--- a/src/cryptography/hazmat/bindings/openssl/rsa.py
+++ b/src/_cffi_src/openssl/rsa.py
diff --git a/src/cryptography/hazmat/bindings/openssl/src/osrandom_engine.c b/src/_cffi_src/openssl/src/osrandom_engine.c
index 27894712..27894712 100644
--- a/src/cryptography/hazmat/bindings/openssl/src/osrandom_engine.c
+++ b/src/_cffi_src/openssl/src/osrandom_engine.c
diff --git a/src/cryptography/hazmat/bindings/openssl/src/osrandom_engine.h b/src/_cffi_src/openssl/src/osrandom_engine.h
index 11a3159e..11a3159e 100644
--- a/src/cryptography/hazmat/bindings/openssl/src/osrandom_engine.h
+++ b/src/_cffi_src/openssl/src/osrandom_engine.h
diff --git a/src/cryptography/hazmat/bindings/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py
index fa0aefc8..fa0aefc8 100644
--- a/src/cryptography/hazmat/bindings/openssl/ssl.py
+++ b/src/_cffi_src/openssl/ssl.py
diff --git a/src/cryptography/hazmat/bindings/openssl/x509.py b/src/_cffi_src/openssl/x509.py
index 534f5b08..534f5b08 100644
--- a/src/cryptography/hazmat/bindings/openssl/x509.py
+++ b/src/_cffi_src/openssl/x509.py
diff --git a/src/cryptography/hazmat/bindings/openssl/x509_vfy.py b/src/_cffi_src/openssl/x509_vfy.py
index 02631409..02631409 100644
--- a/src/cryptography/hazmat/bindings/openssl/x509_vfy.py
+++ b/src/_cffi_src/openssl/x509_vfy.py
diff --git a/src/cryptography/hazmat/bindings/openssl/x509name.py b/src/_cffi_src/openssl/x509name.py
index be5b3a75..be5b3a75 100644
--- a/src/cryptography/hazmat/bindings/openssl/x509name.py
+++ b/src/_cffi_src/openssl/x509name.py
diff --git a/src/cryptography/hazmat/bindings/openssl/x509v3.py b/src/_cffi_src/openssl/x509v3.py
index e9bc461a..e9bc461a 100644
--- a/src/cryptography/hazmat/bindings/openssl/x509v3.py
+++ b/src/_cffi_src/openssl/x509v3.py
diff --git a/src/cryptography/hazmat/bindings/utils.py b/src/_cffi_src/utils.py
index 52c6f8b6..b1ad74d4 100644
--- a/src/cryptography/hazmat/bindings/utils.py
+++ b/src/_cffi_src/utils.py
@@ -4,44 +4,12 @@
from __future__ import absolute_import, division, print_function
-import binascii
import sys
-import threading
from cffi import FFI
-from cffi.verifier import Verifier
-class LazyLibrary(object):
- def __init__(self, ffi):
- self._ffi = ffi
- self._lib = None
- self._lock = threading.Lock()
-
- def __getattr__(self, name):
- if self._lib is None:
- with self._lock:
- if self._lib is None:
- self._lib = self._ffi.verifier.load_library()
-
- return getattr(self._lib, name)
-
-
-def load_library_for_binding(ffi, module_prefix, modules):
- lib = ffi.verifier.load_library()
-
- for name in modules:
- module_name = module_prefix + name
- module = sys.modules[module_name]
- for condition, names in module.CONDITIONAL_NAMES.items():
- if not getattr(lib, condition):
- for name in names:
- delattr(lib, name)
-
- return lib
-
-
-def build_ffi_for_binding(module_prefix, modules, pre_include="",
+def build_ffi_for_binding(module_name, module_prefix, modules, pre_include="",
post_include="", libraries=[], extra_compile_args=[],
extra_link_args=[]):
"""
@@ -64,9 +32,8 @@ def build_ffi_for_binding(module_prefix, modules, pre_include="",
macros = []
customizations = []
for name in modules:
- module_name = module_prefix + name
- __import__(module_name)
- module = sys.modules[module_name]
+ __import__(module_prefix + name)
+ module = sys.modules[module_prefix + name]
types.append(module.TYPES)
macros.append(module.MACROS)
@@ -90,6 +57,7 @@ def build_ffi_for_binding(module_prefix, modules, pre_include="",
customizations
)
ffi = build_ffi(
+ module_name,
cdef_source="\n".join(types + functions + macros),
verify_source=verify_source,
libraries=libraries,
@@ -100,47 +68,15 @@ def build_ffi_for_binding(module_prefix, modules, pre_include="",
return ffi
-def build_ffi(cdef_source, verify_source, libraries=[], extra_compile_args=[],
- extra_link_args=[]):
+def build_ffi(module_name, cdef_source, verify_source, libraries=[],
+ extra_compile_args=[], extra_link_args=[]):
ffi = FFI()
ffi.cdef(cdef_source)
-
- ffi.verifier = Verifier(
- ffi,
+ ffi.set_source(
+ module_name,
verify_source,
- tmpdir='',
- modulename=_create_modulename(cdef_source, verify_source, sys.version),
libraries=libraries,
- ext_package="cryptography",
extra_compile_args=extra_compile_args,
extra_link_args=extra_link_args,
)
-
- ffi.verifier.compile_module = _compile_module
- ffi.verifier._compile_module = _compile_module
-
return ffi
-
-
-def _compile_module(*args, **kwargs):
- raise RuntimeError(
- "Attempted implicit compile of a cffi module. All cffi modules should "
- "be pre-compiled at installation time."
- )
-
-
-def _create_modulename(cdef_sources, source, sys_version):
- """
- cffi creates a modulename internally that incorporates the cffi version.
- This will cause cryptography's wheels to break when the version of cffi
- the user has does not match what was used when building the wheel. To
- resolve this we build our own modulename that uses most of the same code
- from cffi but elides the version key.
- """
- key = '\x00'.join([sys_version[:3], source, cdef_sources])
- key = key.encode('utf-8')
- k1 = hex(binascii.crc32(key[0::2]) & 0xffffffff)
- k1 = k1.lstrip('0x').rstrip('L')
- k2 = hex(binascii.crc32(key[1::2]) & 0xffffffff)
- k2 = k2.lstrip('0').rstrip('L')
- return '_Cryptography_cffi_{0}{1}'.format(k1, k2)
diff --git a/src/cryptography/hazmat/bindings/commoncrypto/binding.py b/src/cryptography/hazmat/bindings/commoncrypto/binding.py
index 54c7603d..1695c041 100644
--- a/src/cryptography/hazmat/bindings/commoncrypto/binding.py
+++ b/src/cryptography/hazmat/bindings/commoncrypto/binding.py
@@ -4,54 +4,15 @@
from __future__ import absolute_import, division, print_function
-import threading
-
-from cryptography.hazmat.bindings.utils import (
- build_ffi_for_binding, load_library_for_binding,
-)
+from cryptography.hazmat.bindings._commoncrypto import ffi, lib
class Binding(object):
"""
CommonCrypto API wrapper.
"""
- _module_prefix = "cryptography.hazmat.bindings.commoncrypto."
- _modules = [
- "cf",
- "common_digest",
- "common_hmac",
- "common_key_derivation",
- "common_cryptor",
- "common_symmetric_key_wrap",
- "secimport",
- "secitem",
- "seckey",
- "seckeychain",
- "sectransform",
- ]
-
- ffi = build_ffi_for_binding(
- module_prefix=_module_prefix,
- modules=_modules,
- extra_link_args=[
- "-framework", "Security", "-framework", "CoreFoundation"
- ],
- )
- lib = None
- _init_lock = threading.Lock()
+ lib = lib
+ ffi = ffi
def __init__(self):
- self._ensure_ffi_initialized()
-
- @classmethod
- def _ensure_ffi_initialized(cls):
- if cls.lib is not None:
- return
-
- with cls._init_lock:
- if cls.lib is None:
- cls.lib = load_library_for_binding(
- cls.ffi,
- module_prefix=cls._module_prefix,
- modules=cls._modules,
- )
+ pass
diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py
index 5ccee974..e0a83972 100644
--- a/src/cryptography/hazmat/bindings/openssl/binding.py
+++ b/src/cryptography/hazmat/bindings/openssl/binding.py
@@ -4,128 +4,34 @@
from __future__ import absolute_import, division, print_function
-import os
-import sys
import threading
-from cryptography.hazmat.bindings.utils import (
- build_ffi_for_binding, load_library_for_binding,
-)
-
-
-_OSX_PRE_INCLUDE = """
-#ifdef __APPLE__
-#include <AvailabilityMacros.h>
-#define __ORIG_DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER \
- DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
-#undef DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
-#define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
-#endif
-"""
-
-_OSX_POST_INCLUDE = """
-#ifdef __APPLE__
-#undef DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
-#define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER \
- __ORIG_DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
-#endif
-"""
-
-
-def _get_libraries(platform):
- # OpenSSL goes by a different library name on different operating systems.
- if platform != "win32":
- # In some circumstances, the order in which these libs are
- # specified on the linker command-line is significant;
- # libssl must come before libcrypto
- # (http://marc.info/?l=openssl-users&m=135361825921871)
- return ["ssl", "crypto"]
- else:
- link_type = os.environ.get("PYCA_WINDOWS_LINK_TYPE", "static")
- return _get_windows_libraries(link_type)
-
-
-def _get_windows_libraries(link_type):
- if link_type == "dynamic":
- return ["libeay32", "ssleay32", "advapi32"]
- elif link_type == "static" or link_type == "":
- return ["libeay32mt", "ssleay32mt", "advapi32",
- "crypt32", "gdi32", "user32", "ws2_32"]
- else:
- raise ValueError(
- "PYCA_WINDOWS_LINK_TYPE must be 'static' or 'dynamic'"
- )
+from cryptography.hazmat.bindings._openssl import ffi, lib
class Binding(object):
"""
OpenSSL API wrapper.
"""
- _module_prefix = "cryptography.hazmat.bindings.openssl."
- _modules = [
- "aes",
- "asn1",
- "bignum",
- "bio",
- "cmac",
- "cms",
- "conf",
- "crypto",
- "dh",
- "dsa",
- "ec",
- "ecdh",
- "ecdsa",
- "engine",
- "err",
- "evp",
- "hmac",
- "nid",
- "objects",
- "opensslv",
- "osrandom_engine",
- "pem",
- "pkcs7",
- "pkcs12",
- "rand",
- "rsa",
- "ssl",
- "x509",
- "x509name",
- "x509v3",
- "x509_vfy"
- ]
-
+ lib = lib
+ ffi = ffi
+ _lib_loaded = False
_locks = None
_lock_cb_handle = None
_init_lock = threading.Lock()
_lock_init_lock = threading.Lock()
- ffi = build_ffi_for_binding(
- module_prefix=_module_prefix,
- modules=_modules,
- pre_include=_OSX_PRE_INCLUDE,
- post_include=_OSX_POST_INCLUDE,
- libraries=_get_libraries(sys.platform)
- )
- lib = None
-
def __init__(self):
self._ensure_ffi_initialized()
@classmethod
def _ensure_ffi_initialized(cls):
- if cls.lib is not None:
+ if cls._lib_loaded:
return
with cls._init_lock:
- if cls.lib is None:
- cls.lib = load_library_for_binding(
- cls.ffi,
- cls._module_prefix,
- cls._modules,
- )
-
+ if not cls._lib_loaded:
+ cls._lib_loaded = True
res = cls.lib.Cryptography_add_osrandom_engine()
assert res != 0
diff --git a/src/cryptography/hazmat/primitives/constant_time.py b/src/cryptography/hazmat/primitives/constant_time.py
index bf85bde1..5a682ca9 100644
--- a/src/cryptography/hazmat/primitives/constant_time.py
+++ b/src/cryptography/hazmat/primitives/constant_time.py
@@ -5,20 +5,8 @@
from __future__ import absolute_import, division, print_function
import hmac
-import os
-from cryptography.hazmat.bindings.utils import LazyLibrary, build_ffi
-
-
-with open(os.path.join(os.path.dirname(__file__), "src/constant_time.h")) as f:
- TYPES = f.read()
-
-with open(os.path.join(os.path.dirname(__file__), "src/constant_time.c")) as f:
- FUNCTIONS = f.read()
-
-
-_ffi = build_ffi(cdef_source=TYPES, verify_source=FUNCTIONS)
-_lib = LazyLibrary(_ffi)
+from cryptography.hazmat.bindings._constant_time import lib
if hasattr(hmac, "compare_digest"):
@@ -33,6 +21,6 @@ else:
if not isinstance(a, bytes) or not isinstance(b, bytes):
raise TypeError("a and b must be bytes.")
- return _lib.Cryptography_constant_time_bytes_eq(
+ return lib.Cryptography_constant_time_bytes_eq(
a, len(a), b, len(b)
) == 1
diff --git a/src/cryptography/hazmat/primitives/kdf/concatkdf.py b/src/cryptography/hazmat/primitives/kdf/concatkdf.py
new file mode 100644
index 00000000..c6399e4f
--- /dev/null
+++ b/src/cryptography/hazmat/primitives/kdf/concatkdf.py
@@ -0,0 +1,125 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import, division, print_function
+
+import struct
+
+from cryptography import utils
+from cryptography.exceptions import (
+ AlreadyFinalized, InvalidKey, UnsupportedAlgorithm, _Reasons
+)
+from cryptography.hazmat.backends.interfaces import HMACBackend
+from cryptography.hazmat.backends.interfaces import HashBackend
+from cryptography.hazmat.primitives import constant_time, hashes, hmac
+from cryptography.hazmat.primitives.kdf import KeyDerivationFunction
+
+
+def _int_to_u32be(n):
+ return struct.pack('>I', n)
+
+
+def _common_args_checks(algorithm, length, otherinfo):
+ max_length = algorithm.digest_size * (2 ** 32 - 1)
+ if length > max_length:
+ raise ValueError(
+ "Can not derive keys larger than {0} bits.".format(
+ max_length
+ ))
+ if not (otherinfo is None or isinstance(otherinfo, bytes)):
+ raise TypeError("otherinfo must be bytes.")
+
+
+def _concatkdf_derive(key_material, length, auxfn, otherinfo):
+ if not isinstance(key_material, bytes):
+ raise TypeError("key_material must be bytes.")
+
+ output = [b""]
+ outlen = 0
+ counter = 1
+
+ while (length > outlen):
+ h = auxfn()
+ h.update(_int_to_u32be(counter))
+ h.update(key_material)
+ h.update(otherinfo)
+ output.append(h.finalize())
+ outlen += len(output[-1])
+ counter += 1
+
+ return b"".join(output)[:length]
+
+
+@utils.register_interface(KeyDerivationFunction)
+class ConcatKDFHash(object):
+ def __init__(self, algorithm, length, otherinfo, backend):
+
+ _common_args_checks(algorithm, length, otherinfo)
+ self._algorithm = algorithm
+ self._length = length
+ self._otherinfo = otherinfo
+ if self._otherinfo is None:
+ self._otherinfo = b""
+
+ if not isinstance(backend, HashBackend):
+ raise UnsupportedAlgorithm(
+ "Backend object does not implement HashBackend.",
+ _Reasons.BACKEND_MISSING_INTERFACE
+ )
+ self._backend = backend
+ self._used = False
+
+ def _hash(self):
+ return hashes.Hash(self._algorithm, self._backend)
+
+ def derive(self, key_material):
+ if self._used:
+ raise AlreadyFinalized
+ self._used = True
+ return _concatkdf_derive(key_material, self._length,
+ self._hash, self._otherinfo)
+
+ def verify(self, key_material, expected_key):
+ if not constant_time.bytes_eq(self.derive(key_material), expected_key):
+ raise InvalidKey
+
+
+@utils.register_interface(KeyDerivationFunction)
+class ConcatKDFHMAC(object):
+ def __init__(self, algorithm, length, salt, otherinfo, backend):
+
+ _common_args_checks(algorithm, length, otherinfo)
+ self._algorithm = algorithm
+ self._length = length
+ self._otherinfo = otherinfo
+ if self._otherinfo is None:
+ self._otherinfo = b""
+
+ if not (salt is None or isinstance(salt, bytes)):
+ raise TypeError("salt must be bytes.")
+ if salt is None:
+ salt = b"\x00" * algorithm.block_size
+ self._salt = salt
+
+ if not isinstance(backend, HMACBackend):
+ raise UnsupportedAlgorithm(
+ "Backend object does not implement HMACBackend.",
+ _Reasons.BACKEND_MISSING_INTERFACE
+ )
+ self._backend = backend
+ self._used = False
+
+ def _hmac(self):
+ return hmac.HMAC(self._salt, self._algorithm, self._backend)
+
+ def derive(self, key_material):
+ if self._used:
+ raise AlreadyFinalized
+ self._used = True
+ return _concatkdf_derive(key_material, self._length,
+ self._hmac, self._otherinfo)
+
+ def verify(self, key_material, expected_key):
+ if not constant_time.bytes_eq(self.derive(key_material), expected_key):
+ raise InvalidKey
diff --git a/src/cryptography/hazmat/primitives/padding.py b/src/cryptography/hazmat/primitives/padding.py
index 6247f7b5..f6491eb7 100644
--- a/src/cryptography/hazmat/primitives/padding.py
+++ b/src/cryptography/hazmat/primitives/padding.py
@@ -6,24 +6,11 @@ from __future__ import absolute_import, division, print_function
import abc
-import os
-
import six
from cryptography import utils
from cryptography.exceptions import AlreadyFinalized
-from cryptography.hazmat.bindings.utils import LazyLibrary, build_ffi
-
-
-with open(os.path.join(os.path.dirname(__file__), "src/padding.h")) as f:
- TYPES = f.read()
-
-with open(os.path.join(os.path.dirname(__file__), "src/padding.c")) as f:
- FUNCTIONS = f.read()
-
-
-_ffi = build_ffi(cdef_source=TYPES, verify_source=FUNCTIONS)
-_lib = LazyLibrary(_ffi)
+from cryptography.hazmat.bindings._padding import lib
@six.add_metaclass(abc.ABCMeta)
@@ -124,7 +111,7 @@ class _PKCS7UnpaddingContext(object):
if len(self._buffer) != self.block_size // 8:
raise ValueError("Invalid padding bytes.")
- valid = _lib.Cryptography_check_pkcs7_padding(
+ valid = lib.Cryptography_check_pkcs7_padding(
self._buffer, self.block_size // 8
)
diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py
index 867c5dd6..b35e7670 100644
--- a/tests/hazmat/backends/test_openssl.py
+++ b/tests/hazmat/backends/test_openssl.py
@@ -482,14 +482,18 @@ class TestOpenSSLSerialisationWithOpenSSL(object):
)
+class DummyLibrary(object):
+ Cryptography_HAS_EC = 0
+
+
class TestOpenSSLEllipticCurve(object):
def test_elliptic_curve_supported(self, monkeypatch):
- monkeypatch.setattr(backend._lib, "Cryptography_HAS_EC", 0)
+ monkeypatch.setattr(backend, "_lib", DummyLibrary())
assert backend.elliptic_curve_supported(None) is False
def test_elliptic_curve_signature_algorithm_supported(self, monkeypatch):
- monkeypatch.setattr(backend._lib, "Cryptography_HAS_EC", 0)
+ monkeypatch.setattr(backend, "_lib", DummyLibrary())
assert backend.elliptic_curve_signature_algorithm_supported(
None, None
diff --git a/tests/hazmat/bindings/test_commoncrypto.py b/tests/hazmat/bindings/test_commoncrypto.py
index a86a1fab..b0a2dc43 100644
--- a/tests/hazmat/bindings/test_commoncrypto.py
+++ b/tests/hazmat/bindings/test_commoncrypto.py
@@ -6,22 +6,21 @@ from __future__ import absolute_import, division, print_function
import pytest
-from cryptography.hazmat.backends import _available_backends
-from cryptography.hazmat.bindings.commoncrypto.binding import Binding
+
+ccbinding = pytest.importorskip(
+ "cryptography.hazmat.bindings.commoncrypto.binding"
+)
-@pytest.mark.skipif("commoncrypto" not in
- [i.name for i in _available_backends()],
- reason="CommonCrypto not available")
class TestCommonCrypto(object):
def test_binding_loads(self):
- binding = Binding()
+ binding = ccbinding.Binding()
assert binding
assert binding.lib
assert binding.ffi
def test_binding_returns_same_lib(self):
- binding = Binding()
- binding2 = Binding()
+ binding = ccbinding.Binding()
+ binding2 = ccbinding.Binding()
assert binding.lib == binding2.lib
assert binding.ffi == binding2.ffi
diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py
index 8cc81cdc..e6d6fc45 100644
--- a/tests/hazmat/bindings/test_openssl.py
+++ b/tests/hazmat/bindings/test_openssl.py
@@ -6,9 +6,7 @@ from __future__ import absolute_import, division, print_function
import pytest
-from cryptography.hazmat.bindings.openssl.binding import (
- Binding, _get_libraries, _get_windows_libraries
-)
+from cryptography.hazmat.bindings.openssl.binding import Binding
class TestOpenSSL(object):
@@ -133,18 +131,3 @@ class TestOpenSSL(object):
expected_options = current_options | b.lib.SSL_OP_ALL
assert resp == expected_options
assert b.lib.SSL_get_mode(ssl) == expected_options
-
- def test_libraries(self, monkeypatch):
- assert _get_libraries("darwin") == ["ssl", "crypto"]
- monkeypatch.setenv('PYCA_WINDOWS_LINK_TYPE', 'static')
- assert "ssleay32mt" in _get_libraries("win32")
-
- def test_windows_static_dynamic_libraries(self):
- assert "ssleay32mt" in _get_windows_libraries("static")
-
- assert "ssleay32mt" in _get_windows_libraries("")
-
- assert "ssleay32" in _get_windows_libraries("dynamic")
-
- with pytest.raises(ValueError):
- _get_windows_libraries("notvalid")
diff --git a/tests/hazmat/bindings/test_utils.py b/tests/hazmat/bindings/test_utils.py
deleted file mode 100644
index 13d5d1cb..00000000
--- a/tests/hazmat/bindings/test_utils.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# This file is dual licensed under the terms of the Apache License, Version
-# 2.0, and the BSD License. See the LICENSE file in the root of this repository
-# for complete details.
-
-from __future__ import absolute_import, division, print_function
-
-import binascii
-import os
-
-import pytest
-
-from cryptography.hazmat.bindings import utils
-
-
-def test_create_modulename():
- cdef_source = "cdef sources go here"
- source = "source code"
- name = utils._create_modulename(cdef_source, source, "2.7")
- assert name == "_Cryptography_cffi_bcba7f4bx4a14b588"
- name = utils._create_modulename(cdef_source, source, "3.2")
- assert name == "_Cryptography_cffi_a7462526x4a14b588"
-
-
-def test_implicit_compile_explodes():
- # This uses a random comment to make sure each test gets its own hash
- random_comment = binascii.hexlify(os.urandom(24))
- ffi = utils.build_ffi("/* %s */" % random_comment, "")
-
- with pytest.raises(RuntimeError):
- ffi.verifier.load_library()
diff --git a/tests/hazmat/primitives/test_concatkdf.py b/tests/hazmat/primitives/test_concatkdf.py
new file mode 100644
index 00000000..27e5460e
--- /dev/null
+++ b/tests/hazmat/primitives/test_concatkdf.py
@@ -0,0 +1,251 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import, division, print_function
+
+import binascii
+
+import pytest
+
+from cryptography.exceptions import (
+ AlreadyFinalized, InvalidKey, _Reasons
+)
+from cryptography.hazmat.backends.interfaces import HMACBackend
+from cryptography.hazmat.backends.interfaces import HashBackend
+from cryptography.hazmat.primitives import hashes
+from cryptography.hazmat.primitives.kdf.concatkdf import ConcatKDFHMAC
+from cryptography.hazmat.primitives.kdf.concatkdf import ConcatKDFHash
+
+from ...utils import raises_unsupported_algorithm
+
+
+@pytest.mark.requires_backend_interface(interface=HashBackend)
+class TestConcatKDFHash(object):
+ def test_length_limit(self, backend):
+ big_length = hashes.SHA256().digest_size * (2 ** 32 - 1) + 1
+
+ with pytest.raises(ValueError):
+ ConcatKDFHash(hashes.SHA256(), big_length, None, backend)
+
+ def test_already_finalized(self, backend):
+ ckdf = ConcatKDFHash(hashes.SHA256(), 16, None, backend)
+
+ ckdf.derive(b"\x01" * 16)
+
+ with pytest.raises(AlreadyFinalized):
+ ckdf.derive(b"\x02" * 16)
+
+ def test_derive(self, backend):
+ prk = binascii.unhexlify(
+ b"52169af5c485dcc2321eb8d26d5efa21fb9b93c98e38412ee2484cf14f0d0d23"
+ )
+
+ okm = binascii.unhexlify(b"1c3bc9e7c4547c5191c0d478cccaed55")
+
+ oinfo = binascii.unhexlify(
+ b"a1b2c3d4e53728157e634612c12d6d5223e204aeea4341565369647bd184bcd2"
+ b"46f72971f292badaa2fe4124612cba"
+ )
+
+ ckdf = ConcatKDFHash(hashes.SHA256(), 16, oinfo, backend)
+
+ assert ckdf.derive(prk) == okm
+
+ def test_verify(self, backend):
+ prk = binascii.unhexlify(
+ b"52169af5c485dcc2321eb8d26d5efa21fb9b93c98e38412ee2484cf14f0d0d23"
+ )
+
+ okm = binascii.unhexlify(b"1c3bc9e7c4547c5191c0d478cccaed55")
+
+ oinfo = binascii.unhexlify(
+ b"a1b2c3d4e53728157e634612c12d6d5223e204aeea4341565369647bd184bcd2"
+ b"46f72971f292badaa2fe4124612cba"
+ )
+
+ ckdf = ConcatKDFHash(hashes.SHA256(), 16, oinfo, backend)
+
+ assert ckdf.verify(prk, okm) is None
+
+ def test_invalid_verify(self, backend):
+ prk = binascii.unhexlify(
+ b"52169af5c485dcc2321eb8d26d5efa21fb9b93c98e38412ee2484cf14f0d0d23"
+ )
+
+ oinfo = binascii.unhexlify(
+ b"a1b2c3d4e53728157e634612c12d6d5223e204aeea4341565369647bd184bcd2"
+ b"46f72971f292badaa2fe4124612cba"
+ )
+
+ ckdf = ConcatKDFHash(hashes.SHA256(), 16, oinfo, backend)
+
+ with pytest.raises(InvalidKey):
+ ckdf.verify(prk, b"wrong key")
+
+ def test_unicode_typeerror(self, backend):
+ with pytest.raises(TypeError):
+ ConcatKDFHash(
+ hashes.SHA256(),
+ 16,
+ otherinfo=u"foo",
+ backend=backend
+ )
+
+ with pytest.raises(TypeError):
+ ckdf = ConcatKDFHash(
+ hashes.SHA256(),
+ 16,
+ otherinfo=None,
+ backend=backend
+ )
+
+ ckdf.derive(u"foo")
+
+ with pytest.raises(TypeError):
+ ckdf = ConcatKDFHash(
+ hashes.SHA256(),
+ 16,
+ otherinfo=None,
+ backend=backend
+ )
+
+ ckdf.verify(u"foo", b"bar")
+
+ with pytest.raises(TypeError):
+ ckdf = ConcatKDFHash(
+ hashes.SHA256(),
+ 16,
+ otherinfo=None,
+ backend=backend
+ )
+
+ ckdf.verify(b"foo", u"bar")
+
+
+@pytest.mark.requires_backend_interface(interface=HMACBackend)
+class TestConcatKDFHMAC(object):
+ def test_length_limit(self, backend):
+ big_length = hashes.SHA256().digest_size * (2 ** 32 - 1) + 1
+
+ with pytest.raises(ValueError):
+ ConcatKDFHMAC(hashes.SHA256(), big_length, None, None, backend)
+
+ def test_already_finalized(self, backend):
+ ckdf = ConcatKDFHMAC(hashes.SHA256(), 16, None, None, backend)
+
+ ckdf.derive(b"\x01" * 16)
+
+ with pytest.raises(AlreadyFinalized):
+ ckdf.derive(b"\x02" * 16)
+
+ def test_derive(self, backend):
+ prk = binascii.unhexlify(
+ b"013951627c1dea63ea2d7702dd24e963eef5faac6b4af7e4"
+ b"b831cde499dff1ce45f6179f741c728aa733583b02409208"
+ b"8f0af7fce1d045edbc5790931e8d5ca79c73"
+ )
+
+ okm = binascii.unhexlify(b"64ce901db10d558661f10b6836a122a7"
+ b"605323ce2f39bf27eaaac8b34cf89f2f")
+
+ oinfo = binascii.unhexlify(
+ b"a1b2c3d4e55e600be5f367e0e8a465f4bf2704db00c9325c"
+ b"9fbd216d12b49160b2ae5157650f43415653696421e68e"
+ )
+
+ ckdf = ConcatKDFHMAC(hashes.SHA512(), 32, None, oinfo, backend)
+
+ assert ckdf.derive(prk) == okm
+
+ def test_verify(self, backend):
+ prk = binascii.unhexlify(
+ b"013951627c1dea63ea2d7702dd24e963eef5faac6b4af7e4"
+ b"b831cde499dff1ce45f6179f741c728aa733583b02409208"
+ b"8f0af7fce1d045edbc5790931e8d5ca79c73"
+ )
+
+ okm = binascii.unhexlify(b"64ce901db10d558661f10b6836a122a7"
+ b"605323ce2f39bf27eaaac8b34cf89f2f")
+
+ oinfo = binascii.unhexlify(
+ b"a1b2c3d4e55e600be5f367e0e8a465f4bf2704db00c9325c"
+ b"9fbd216d12b49160b2ae5157650f43415653696421e68e"
+ )
+
+ ckdf = ConcatKDFHMAC(hashes.SHA512(), 32, None, oinfo, backend)
+
+ assert ckdf.verify(prk, okm) is None
+
+ def test_invalid_verify(self, backend):
+ prk = binascii.unhexlify(
+ b"013951627c1dea63ea2d7702dd24e963eef5faac6b4af7e4"
+ b"b831cde499dff1ce45f6179f741c728aa733583b02409208"
+ b"8f0af7fce1d045edbc5790931e8d5ca79c73"
+ )
+
+ oinfo = binascii.unhexlify(
+ b"a1b2c3d4e55e600be5f367e0e8a465f4bf2704db00c9325c"
+ b"9fbd216d12b49160b2ae5157650f43415653696421e68e"
+ )
+
+ ckdf = ConcatKDFHMAC(hashes.SHA512(), 32, None, oinfo, backend)
+
+ with pytest.raises(InvalidKey):
+ ckdf.verify(prk, b"wrong key")
+
+ def test_unicode_typeerror(self, backend):
+ with pytest.raises(TypeError):
+ ConcatKDFHMAC(
+ hashes.SHA256(),
+ 16, salt=u"foo",
+ otherinfo=None,
+ backend=backend
+ )
+
+ with pytest.raises(TypeError):
+ ConcatKDFHMAC(
+ hashes.SHA256(),
+ 16, salt=None,
+ otherinfo=u"foo",
+ backend=backend
+ )
+
+ with pytest.raises(TypeError):
+ ckdf = ConcatKDFHMAC(
+ hashes.SHA256(),
+ 16, salt=None,
+ otherinfo=None,
+ backend=backend
+ )
+
+ ckdf.derive(u"foo")
+
+ with pytest.raises(TypeError):
+ ckdf = ConcatKDFHMAC(
+ hashes.SHA256(),
+ 16, salt=None,
+ otherinfo=None,
+ backend=backend
+ )
+
+ ckdf.verify(u"foo", b"bar")
+
+ with pytest.raises(TypeError):
+ ckdf = ConcatKDFHMAC(
+ hashes.SHA256(),
+ 16, salt=None,
+ otherinfo=None,
+ backend=backend
+ )
+
+ ckdf.verify(b"foo", u"bar")
+
+
+def test_invalid_backend():
+ pretend_backend = object()
+
+ with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE):
+ ConcatKDFHash(hashes.SHA256(), 16, None, pretend_backend)
+ with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE):
+ ConcatKDFHMAC(hashes.SHA256(), 16, None, None, pretend_backend)