From 814efab2a71a869d362c0b488b6c51bb590f0d23 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 3 Oct 2013 09:24:58 -0700 Subject: Explicitly pass around the API, and run all tests under all available APIs --- cryptography/bindings/__init__.py | 17 +++++++++++++++++ cryptography/primitives/block/base.py | 10 +++++----- tests/conftest.py | 5 +++++ tests/primitives/test_block.py | 20 +++++++++++-------- tests/primitives/test_nist.py | 36 +++++++++++++++++++++-------------- 5 files changed, 61 insertions(+), 27 deletions(-) create mode 100644 tests/conftest.py diff --git a/cryptography/bindings/__init__.py b/cryptography/bindings/__init__.py index e69de29b..b4dc6bf1 100644 --- a/cryptography/bindings/__init__.py +++ b/cryptography/bindings/__init__.py @@ -0,0 +1,17 @@ +# 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 cryptography.bindings.openssl import api + + +default_api = api diff --git a/cryptography/primitives/block/base.py b/cryptography/primitives/block/base.py index b4137fd4..833ebe9b 100644 --- a/cryptography/primitives/block/base.py +++ b/cryptography/primitives/block/base.py @@ -15,8 +15,7 @@ from __future__ import absolute_import, division, print_function from enum import Enum -# TODO: which binding is used should be an option somewhere -from cryptography.bindings.openssl import api +from cryptography.bindings import default_api class _Operation(Enum): @@ -25,10 +24,11 @@ class _Operation(Enum): class BlockCipher(object): - def __init__(self, cipher, mode): + def __init__(self, cipher, mode, api=default_api): super(BlockCipher, self).__init__() self.cipher = cipher self.mode = mode + self._api = api self._ctx = api.create_block_cipher_context(cipher, mode) self._operation = None @@ -48,14 +48,14 @@ class BlockCipher(object): raise ValueError("BlockCipher cannot encrypt when the operation is" " set to %s" % self._operation.name) - return api.update_encrypt_context(self._ctx, plaintext) + return self._api.update_encrypt_context(self._ctx, plaintext) def finalize(self): if self._ctx is None: raise ValueError("BlockCipher was already finalized") if self._operation is _Operation.encrypt: - result = api.finalize_encrypt_context(self._ctx) + result = self._api.finalize_encrypt_context(self._ctx) else: raise ValueError("BlockCipher cannot finalize the unknown " "operation %s" % self._operation.name) diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 00000000..d16be3b6 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,5 @@ +def pytest_generate_tests(metafunc): + from cryptography.bindings.openssl import api + + if "api" in metafunc.fixturenames: + metafunc.parametrize("api", [api]) diff --git a/tests/primitives/test_block.py b/tests/primitives/test_block.py index 774409ca..92fd31a3 100644 --- a/tests/primitives/test_block.py +++ b/tests/primitives/test_block.py @@ -23,17 +23,19 @@ from cryptography.primitives.block.base import _Operation class TestBlockCipher(object): - def test_cipher_name(self): + def test_cipher_name(self, api): cipher = BlockCipher( ciphers.AES(binascii.unhexlify(b"0" * 32)), - modes.CBC(binascii.unhexlify(b"0" * 32)) + modes.CBC(binascii.unhexlify(b"0" * 32)), + api ) assert cipher.name == "AES-128-CBC" - def test_use_after_finalize(self): + def test_use_after_finalize(self, api): cipher = BlockCipher( ciphers.AES(binascii.unhexlify(b"0" * 32)), - modes.CBC(binascii.unhexlify(b"0" * 32)) + modes.CBC(binascii.unhexlify(b"0" * 32)), + api ) cipher.encrypt(b"a" * 16) cipher.finalize() @@ -42,20 +44,22 @@ class TestBlockCipher(object): with pytest.raises(ValueError): cipher.finalize() - def test_encrypt_with_invalid_operation(self): + def test_encrypt_with_invalid_operation(self, api): cipher = BlockCipher( ciphers.AES(binascii.unhexlify(b"0" * 32)), - modes.CBC(binascii.unhexlify(b"0" * 32)) + modes.CBC(binascii.unhexlify(b"0" * 32)), + api ) cipher._operation = _Operation.decrypt with pytest.raises(ValueError): cipher.encrypt(b"b" * 16) - def test_finalize_with_invalid_operation(self): + def test_finalize_with_invalid_operation(self, api): cipher = BlockCipher( ciphers.AES(binascii.unhexlify(b"0" * 32)), - modes.CBC(binascii.unhexlify(b"0" * 32)) + modes.CBC(binascii.unhexlify(b"0" * 32)), + api ) cipher._operation = pretend.stub(name="wat") diff --git a/tests/primitives/test_nist.py b/tests/primitives/test_nist.py index 1e5d2396..261bbd1d 100644 --- a/tests/primitives/test_nist.py +++ b/tests/primitives/test_nist.py @@ -60,10 +60,11 @@ class TestAES_CBC(object): "CBCVarTxt256.rsp", ] ) - def test_KAT(self, key, iv, plaintext, ciphertext): + def test_KAT(self, key, iv, plaintext, ciphertext, api): cipher = BlockCipher( ciphers.AES(binascii.unhexlify(key)), modes.CBC(binascii.unhexlify(iv)), + api ) actual_ciphertext = cipher.encrypt(binascii.unhexlify(plaintext)) actual_ciphertext += cipher.finalize() @@ -78,10 +79,11 @@ class TestAES_CBC(object): "CBCMMT256.rsp", ] ) - def test_MMT(self, key, iv, plaintext, ciphertext): + def test_MMT(self, key, iv, plaintext, ciphertext, api): cipher = BlockCipher( ciphers.AES(binascii.unhexlify(key)), modes.CBC(binascii.unhexlify(iv)), + api ) actual_ciphertext = cipher.encrypt(binascii.unhexlify(plaintext)) actual_ciphertext += cipher.finalize() @@ -107,10 +109,11 @@ class TestAES_ECB(object): "ECBVarTxt256.rsp", ] ) - def test_KAT(self, key, plaintext, ciphertext): + def test_KAT(self, key, plaintext, ciphertext, api): cipher = BlockCipher( ciphers.AES(binascii.unhexlify(key)), - modes.ECB() + modes.ECB(), + api ) actual_ciphertext = cipher.encrypt(binascii.unhexlify(plaintext)) actual_ciphertext += cipher.finalize() @@ -125,10 +128,11 @@ class TestAES_ECB(object): "ECBMMT256.rsp", ] ) - def test_MMT(self, key, plaintext, ciphertext): + def test_MMT(self, key, plaintext, ciphertext, api): cipher = BlockCipher( ciphers.AES(binascii.unhexlify(key)), - modes.ECB() + modes.ECB(), + api ) actual_ciphertext = cipher.encrypt(binascii.unhexlify(plaintext)) actual_ciphertext += cipher.finalize() @@ -154,10 +158,11 @@ class TestAES_OFB(object): "OFBVarTxt256.rsp", ] ) - def test_KAT(self, key, iv, plaintext, ciphertext): + def test_KAT(self, key, iv, plaintext, ciphertext, api): cipher = BlockCipher( ciphers.AES(binascii.unhexlify(key)), - modes.OFB(binascii.unhexlify(iv)) + modes.OFB(binascii.unhexlify(iv)), + api ) actual_ciphertext = cipher.encrypt(binascii.unhexlify(plaintext)) actual_ciphertext += cipher.finalize() @@ -172,10 +177,11 @@ class TestAES_OFB(object): "OFBMMT256.rsp", ] ) - def test_MMT(self, key, iv, plaintext, ciphertext): + def test_MMT(self, key, iv, plaintext, ciphertext, api): cipher = BlockCipher( ciphers.AES(binascii.unhexlify(key)), - modes.OFB(binascii.unhexlify(iv)) + modes.OFB(binascii.unhexlify(iv)), + api ) actual_ciphertext = cipher.encrypt(binascii.unhexlify(plaintext)) actual_ciphertext += cipher.finalize() @@ -201,10 +207,11 @@ class TestAES_CFB(object): "CFB128VarTxt256.rsp", ] ) - def test_KAT(self, key, iv, plaintext, ciphertext): + def test_KAT(self, key, iv, plaintext, ciphertext, api): cipher = BlockCipher( ciphers.AES(binascii.unhexlify(key)), - modes.CFB(binascii.unhexlify(iv)) + modes.CFB(binascii.unhexlify(iv)), + api ) actual_ciphertext = cipher.encrypt(binascii.unhexlify(plaintext)) actual_ciphertext += cipher.finalize() @@ -219,10 +226,11 @@ class TestAES_CFB(object): "CFB128MMT256.rsp", ] ) - def test_MMT(self, key, iv, plaintext, ciphertext): + def test_MMT(self, key, iv, plaintext, ciphertext, api): cipher = BlockCipher( ciphers.AES(binascii.unhexlify(key)), - modes.CFB(binascii.unhexlify(iv)) + modes.CFB(binascii.unhexlify(iv)), + api ) actual_ciphertext = cipher.encrypt(binascii.unhexlify(plaintext)) actual_ciphertext += cipher.finalize() -- cgit v1.2.3 From ff61cd36005297b4cf01302116bb6cda65c67a96 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 3 Oct 2013 09:52:08 -0700 Subject: Run coverage from the outside so it sees everything --- tox.ini | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 4d17ebe8..88e74219 100644 --- a/tox.ini +++ b/tox.ini @@ -3,9 +3,12 @@ envlist = py26,py27,pypy,py32,py33,docs,pep8 [testenv] deps = - pytest-cov + pytest + coverage pretend -commands = py.test --cov=cryptography/ --cov=tests/ +commands = + coverage run --source=cryptography/,tests/ -m pytest + coverage report [testenv:docs] deps = sphinx -- cgit v1.2.3 From 548467c8d90a62d7e7647ae7b8d04cc6291d811e Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 3 Oct 2013 09:53:35 -0700 Subject: Make default_api private --- cryptography/bindings/__init__.py | 2 +- cryptography/primitives/block/base.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cryptography/bindings/__init__.py b/cryptography/bindings/__init__.py index b4dc6bf1..8b165009 100644 --- a/cryptography/bindings/__init__.py +++ b/cryptography/bindings/__init__.py @@ -14,4 +14,4 @@ from cryptography.bindings.openssl import api -default_api = api +_default_api = api diff --git a/cryptography/primitives/block/base.py b/cryptography/primitives/block/base.py index 833ebe9b..197807ea 100644 --- a/cryptography/primitives/block/base.py +++ b/cryptography/primitives/block/base.py @@ -15,7 +15,7 @@ from __future__ import absolute_import, division, print_function from enum import Enum -from cryptography.bindings import default_api +from cryptography.bindings import _default_api class _Operation(Enum): @@ -24,7 +24,7 @@ class _Operation(Enum): class BlockCipher(object): - def __init__(self, cipher, mode, api=default_api): + def __init__(self, cipher, mode, api=_default_api): super(BlockCipher, self).__init__() self.cipher = cipher self.mode = mode -- cgit v1.2.3 From 81a5287984cd31080f7a5a1b249caf626ac8f6bf Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 3 Oct 2013 09:58:45 -0700 Subject: Use a None default so composition is easier --- cryptography/primitives/block/base.py | 6 +++++- tests/primitives/test_block.py | 7 +++++++ tox.ini | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/cryptography/primitives/block/base.py b/cryptography/primitives/block/base.py index 197807ea..b84ca9c4 100644 --- a/cryptography/primitives/block/base.py +++ b/cryptography/primitives/block/base.py @@ -24,8 +24,12 @@ class _Operation(Enum): class BlockCipher(object): - def __init__(self, cipher, mode, api=_default_api): + def __init__(self, cipher, mode, api=None): super(BlockCipher, self).__init__() + + if api is None: + api = _default_api + self.cipher = cipher self.mode = mode self._api = api diff --git a/tests/primitives/test_block.py b/tests/primitives/test_block.py index 92fd31a3..774885fa 100644 --- a/tests/primitives/test_block.py +++ b/tests/primitives/test_block.py @@ -31,6 +31,13 @@ class TestBlockCipher(object): ) assert cipher.name == "AES-128-CBC" + def test_instantiate_without_api(self): + cipher = BlockCipher( + ciphers.AES(binascii.unhexlify(b"0" * 32)), + modes.CBC(binascii.unhexlify(b"0" * 32)) + ) + assert cipher.name == "AES-128-CBC" + def test_use_after_finalize(self, api): cipher = BlockCipher( ciphers.AES(binascii.unhexlify(b"0" * 32)), diff --git a/tox.ini b/tox.ini index 88e74219..0a28af15 100644 --- a/tox.ini +++ b/tox.ini @@ -8,7 +8,7 @@ deps = pretend commands = coverage run --source=cryptography/,tests/ -m pytest - coverage report + coverage report -m [testenv:docs] deps = sphinx -- cgit v1.2.3