Merge branch 'master' into commoncrypto-cipher-backend
* master:
expand tox backend example
On OS X at build time compile the CC bindings
fix docs
update docs for name attribute
revert fixture decorator for now, switch to append. no more globals
docs for explicit backend selection and document name attribute of backend
modify backend selection to allow multiple backends via comma delimiter
better name for the variable
don't mutate _ALL_BACKENDS
pass posargs via tox so --backend can be used for tox envs
support --backend as a pytest flag to limit to one backend for testing
diff --git a/cryptography/hazmat/backends/commoncrypto/backend.py b/cryptography/hazmat/backends/commoncrypto/backend.py
index cdce5f4..8b9fe08 100644
--- a/cryptography/hazmat/backends/commoncrypto/backend.py
+++ b/cryptography/hazmat/backends/commoncrypto/backend.py
@@ -90,16 +90,18 @@
def hash_supported(self, algorithm):
try:
self._hash_mapping[algorithm.name]
- return True
except KeyError:
return False
+ else:
+ return True
def hmac_supported(self, algorithm):
try:
self._supported_hmac_algorithms[algorithm.name]
- return True
except KeyError:
return False
+ else:
+ return True
def create_hash_ctx(self, algorithm):
return _HashContext(self, algorithm)
diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py
index 07ee58c..ee82ba7 100644
--- a/cryptography/hazmat/backends/openssl/backend.py
+++ b/cryptography/hazmat/backends/openssl/backend.py
@@ -37,6 +37,7 @@
"""
OpenSSL API binding interfaces.
"""
+ name = "openssl"
def __init__(self):
self._binding = Binding()
diff --git a/cryptography/hazmat/bindings/openssl/dh.py b/cryptography/hazmat/bindings/openssl/dh.py
index edbe0e3..ecc62e9 100644
--- a/cryptography/hazmat/bindings/openssl/dh.py
+++ b/cryptography/hazmat/bindings/openssl/dh.py
@@ -17,10 +17,14 @@
TYPES = """
typedef struct dh_st {
- BIGNUM *p; // prime number (shared)
- BIGNUM *g; // generator of Z_p (shared)
- BIGNUM *priv_key; // private DH value x
- BIGNUM *pub_key; // public DH value g^x
+ // prime number (shared)
+ BIGNUM *p;
+ // generator of Z_p (shared)
+ BIGNUM *g;
+ // private DH value x
+ BIGNUM *priv_key;
+ // public DH value g^x
+ BIGNUM *pub_key;
...;
} DH;
"""
diff --git a/cryptography/hazmat/bindings/openssl/dsa.py b/cryptography/hazmat/bindings/openssl/dsa.py
index 9068e05..609a33b 100644
--- a/cryptography/hazmat/bindings/openssl/dsa.py
+++ b/cryptography/hazmat/bindings/openssl/dsa.py
@@ -17,11 +17,16 @@
TYPES = """
typedef struct dsa_st {
- BIGNUM *p; // prime number (public)
- BIGNUM *q; // 160-bit subprime, q | p-1 (public)
- BIGNUM *g; // generator of subgroup (public)
- BIGNUM *priv_key; // private key x
- BIGNUM *pub_key; // public key y = g^x
+ // prime number (public)
+ BIGNUM *p;
+ // 160-bit subprime, q | p-1 (public)
+ BIGNUM *q;
+ // generator of subgroup (public)
+ BIGNUM *g;
+ // private key x
+ BIGNUM *priv_key;
+ // public key y = g^x
+ BIGNUM *pub_key;
...;
} DSA;
"""
diff --git a/docs/contributing.rst b/docs/contributing.rst
index 8e32c36..4bb1461 100644
--- a/docs/contributing.rst
+++ b/docs/contributing.rst
@@ -250,6 +250,16 @@
You may not have all the required Python versions installed, in which case you
will see one or more ``InterpreterNotFound`` errors.
+
+Explicit Backend Selection
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+While testing you may want to run tests against a subset of the backends that
+cryptography supports. Explicit backend selection can be done via the
+``--backend`` flag. This flag should be passed to ``py.test`` with a comma
+delimited list of backend names. To use it with ``tox`` you must pass it as
+``tox -- --backend=openssl``.
+
Building Documentation
~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/hazmat/backends/openssl.rst b/docs/hazmat/backends/openssl.rst
index 404573a..a1f2d28 100644
--- a/docs/hazmat/backends/openssl.rst
+++ b/docs/hazmat/backends/openssl.rst
@@ -7,7 +7,11 @@
.. data:: cryptography.hazmat.backends.openssl.backend
- This is the exposed API for the OpenSSL backend. It has no public attributes.
+ This is the exposed API for the OpenSSL backend. It has one public attribute.
+
+ .. attribute:: name
+
+ The string name of this backend: ``"openssl"``
Using your own OpenSSL on Linux
-------------------------------
diff --git a/setup.py b/setup.py
index e8bcc11..57a9575 100644
--- a/setup.py
+++ b/setup.py
@@ -43,14 +43,23 @@
"""
def finalize_options(self):
- from cryptography.hazmat.bindings.openssl.binding import Binding
+ 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
self.distribution.ext_modules = [
- Binding().ffi.verifier.get_extension(),
+ OpenSSLBinding().ffi.verifier.get_extension(),
constant_time._ffi.verifier.get_extension(),
padding._ffi.verifier.get_extension()
]
+ if CommonCryptoBinding.is_available():
+ self.distribution.ext_modules.append(
+ CommonCryptoBinding().ffi.verifier.get_extension()
+ )
build.finalize_options(self)
diff --git a/tests/conftest.py b/tests/conftest.py
index 1d9f96e..a9acb54 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -5,12 +5,15 @@
HMACBackend, CipherBackend, HashBackend
)
-from .utils import check_for_iface, check_backend_support
+from .utils import check_for_iface, check_backend_support, select_backends
-@pytest.fixture(params=_ALL_BACKENDS)
-def backend(request):
- return request.param
+def pytest_generate_tests(metafunc):
+ names = metafunc.config.getoption("--backend")
+ selected_backends = select_backends(names, _ALL_BACKENDS)
+
+ if "backend" in metafunc.fixturenames:
+ metafunc.parametrize("backend", selected_backends)
@pytest.mark.trylast
@@ -19,3 +22,10 @@
check_for_iface("cipher", CipherBackend, item)
check_for_iface("hash", HashBackend, item)
check_backend_support(item)
+
+
+def pytest_addoption(parser):
+ parser.addoption(
+ "--backend", action="store", metavar="NAME",
+ help="Only run tests matching the backend NAME."
+ )
diff --git a/tests/test_utils.py b/tests/test_utils.py
index e3e53d6..f852f3a 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -21,7 +21,7 @@
from .utils import (
load_nist_vectors, load_vectors_from_file, load_cryptrec_vectors,
load_openssl_vectors, load_hash_vectors, check_for_iface,
- check_backend_support
+ check_backend_support, select_backends
)
@@ -29,6 +29,48 @@
pass
+def test_select_one_backend():
+ b1 = pretend.stub(name="b1")
+ b2 = pretend.stub(name="b2")
+ b3 = pretend.stub(name="b3")
+ backends = [b1, b2, b3]
+ name = "b2"
+ selected_backends = select_backends(name, backends)
+ assert len(selected_backends) == 1
+ assert selected_backends[0] == b2
+
+
+def test_select_no_backend():
+ b1 = pretend.stub(name="b1")
+ b2 = pretend.stub(name="b2")
+ b3 = pretend.stub(name="b3")
+ backends = [b1, b2, b3]
+ name = "back!"
+ with pytest.raises(ValueError):
+ select_backends(name, backends)
+
+
+def test_select_backends_none():
+ b1 = pretend.stub(name="b1")
+ b2 = pretend.stub(name="b2")
+ b3 = pretend.stub(name="b3")
+ backends = [b1, b2, b3]
+ name = None
+ selected_backends = select_backends(name, backends)
+ assert len(selected_backends) == 3
+
+
+def test_select_two_backends():
+ b1 = pretend.stub(name="b1")
+ b2 = pretend.stub(name="b2")
+ b3 = pretend.stub(name="b3")
+ backends = [b1, b2, b3]
+ name = "b2 ,b1 "
+ selected_backends = select_backends(name, backends)
+ assert len(selected_backends) == 2
+ assert selected_backends == [b1, b2]
+
+
def test_check_for_iface():
item = pretend.stub(keywords=["fake_name"], funcargs={"backend": True})
with pytest.raises(pytest.skip.Exception) as exc_info:
diff --git a/tests/utils.py b/tests/utils.py
index 693a0c8..a243225 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -16,6 +16,25 @@
import pytest
+def select_backends(names, backend_list):
+ if names is None:
+ return backend_list
+ split_names = [x.strip() for x in names.split(',')]
+ # this must be duplicated and then removed to preserve the metadata
+ # pytest associates. Appending backends to a new list doesn't seem to work
+ selected_backends = []
+ for backend in backend_list:
+ if backend.name in split_names:
+ selected_backends.append(backend)
+
+ if len(selected_backends) > 0:
+ return selected_backends
+ else:
+ raise ValueError(
+ "No backend selected. Tried to select: {0}".format(split_names)
+ )
+
+
def check_for_iface(name, iface, item):
if name in item.keywords and "backend" in item.funcargs:
if not isinstance(item.funcargs["backend"], iface):
diff --git a/tox.ini b/tox.ini
index ff5df36..5ff0877 100644
--- a/tox.ini
+++ b/tox.ini
@@ -8,7 +8,7 @@
pretend
pytest
commands =
- coverage run --source=cryptography/,tests/ -m pytest --capture=no --strict
+ coverage run --source=cryptography/,tests/ -m pytest --capture=no --strict {posargs}
coverage report -m
[testenv:docs]
@@ -28,7 +28,7 @@
# Temporarily disable coverage on pypy because of performance problems with
# coverage.py on pypy.
[testenv:pypy]
-commands = py.test --capture=no --strict
+commands = py.test --capture=no --strict {posargs}
[testenv:pep8]
deps = flake8