From 22e80cb96e034679750a38702aaa55e30da05f69 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 20 Nov 2013 21:27:00 -0600 Subject: GCM support --- tests/hazmat/primitives/test_aes.py | 21 ++++++- tests/hazmat/primitives/test_block.py | 17 +++++- tests/hazmat/primitives/test_utils.py | 25 +++++++- tests/hazmat/primitives/utils.py | 105 +++++++++++++++++++++++++++++++++- 4 files changed, 163 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/hazmat/primitives/test_aes.py b/tests/hazmat/primitives/test_aes.py index d178da7b..f7b0b9a0 100644 --- a/tests/hazmat/primitives/test_aes.py +++ b/tests/hazmat/primitives/test_aes.py @@ -18,7 +18,7 @@ import os from cryptography.hazmat.primitives.ciphers import algorithms, modes -from .utils import generate_encrypt_test +from .utils import generate_encrypt_test, generate_aead_test from ...utils import ( load_nist_vectors, load_openssl_vectors, ) @@ -132,3 +132,22 @@ class TestAES(object): ), skip_message="Does not support AES CTR", ) + + test_GCM = generate_aead_test( + load_nist_vectors, + os.path.join("ciphers", "AES", "GCM"), + [ + "gcmDecrypt128.rsp", + "gcmDecrypt192.rsp", + "gcmDecrypt256.rsp", + "gcmEncryptExtIV128.rsp", + "gcmEncryptExtIV192.rsp", + "gcmEncryptExtIV256.rsp", + ], + lambda key: algorithms.AES(key), + lambda iv, tag: modes.GCM(iv, tag), + only_if=lambda backend: backend.cipher_supported( + algorithms.AES("\x00" * 16), modes.GCM("\x00" * 12) + ), + skip_message="Does not support AES GCM", + ) diff --git a/tests/hazmat/primitives/test_block.py b/tests/hazmat/primitives/test_block.py index f6c44b47..296821a4 100644 --- a/tests/hazmat/primitives/test_block.py +++ b/tests/hazmat/primitives/test_block.py @@ -18,12 +18,16 @@ import binascii import pytest from cryptography import utils -from cryptography.exceptions import UnsupportedAlgorithm, AlreadyFinalized +from cryptography.exceptions import ( + UnsupportedAlgorithm, AlreadyFinalized, +) from cryptography.hazmat.primitives import interfaces from cryptography.hazmat.primitives.ciphers import ( Cipher, algorithms, modes ) +from .utils import generate_aead_use_after_finalize_test + @utils.register_interface(interfaces.CipherAlgorithm) class DummyCipher(object): @@ -120,3 +124,14 @@ class TestCipherContext(object): decryptor.update(b"1") with pytest.raises(ValueError): decryptor.finalize() + + +class TestAEADCipherContext(object): + test_use_after_finalize = generate_aead_use_after_finalize_test( + algorithms.AES, + modes.GCM, + only_if=lambda backend: backend.cipher_supported( + algorithms.AES("\x00" * 16), modes.GCM("\x00" * 12) + ), + skip_message="Does not support AES GCM", + ) diff --git a/tests/hazmat/primitives/test_utils.py b/tests/hazmat/primitives/test_utils.py index cee0b20e..f286e02d 100644 --- a/tests/hazmat/primitives/test_utils.py +++ b/tests/hazmat/primitives/test_utils.py @@ -2,7 +2,8 @@ import pytest from .utils import ( base_hash_test, encrypt_test, hash_test, long_string_hash_test, - base_hmac_test, hmac_test, stream_encryption_test + base_hmac_test, hmac_test, stream_encryption_test, aead_test, + aead_use_after_finalize_test, ) @@ -17,6 +18,28 @@ class TestEncryptTest(object): assert exc_info.value.args[0] == "message!" +class TestAEADTest(object): + def test_skips_if_only_if_returns_false(self): + with pytest.raises(pytest.skip.Exception) as exc_info: + aead_test( + None, None, None, None, + only_if=lambda backend: False, + skip_message="message!" + ) + assert exc_info.value.args[0] == "message!" + + +class TestAEADFinalizeTest(object): + def test_skips_if_only_if_returns_false(self): + with pytest.raises(pytest.skip.Exception) as exc_info: + aead_use_after_finalize_test( + None, None, None, + only_if=lambda backend: False, + skip_message="message!" + ) + assert exc_info.value.args[0] == "message!" + + class TestHashTest(object): def test_skips_if_only_if_returns_false(self): with pytest.raises(pytest.skip.Exception) as exc_info: diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index 6c67ddb3..839ff822 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -4,9 +4,11 @@ import os import pytest from cryptography.hazmat.bindings import _ALL_BACKENDS -from cryptography.hazmat.primitives import hashes -from cryptography.hazmat.primitives import hmac +from cryptography.hazmat.primitives import hashes, hmac from cryptography.hazmat.primitives.ciphers import Cipher +from cryptography.exceptions import ( + AlreadyFinalized, NotFinalized, +) from ...utils import load_vectors_from_file @@ -54,6 +56,72 @@ def encrypt_test(backend, cipher_factory, mode_factory, params, only_if, assert actual_plaintext == binascii.unhexlify(plaintext) +def generate_aead_test(param_loader, path, file_names, cipher_factory, + mode_factory, only_if, skip_message): + def test_aead(self): + for backend in _ALL_BACKENDS: + for file_name in file_names: + for params in load_vectors_from_file( + os.path.join(path, file_name), + param_loader + ): + yield ( + aead_test, + backend, + cipher_factory, + mode_factory, + params, + only_if, + skip_message + ) + return test_aead + + +def aead_test(backend, cipher_factory, mode_factory, params, only_if, + skip_message): + if not only_if(backend): + pytest.skip(skip_message) + if params.get("pt") is not None: + plaintext = params.pop("pt") + ciphertext = params.pop("ct") + aad = params.pop("aad") + if params.get("fail") is True: + cipher = Cipher( + cipher_factory(binascii.unhexlify(params["key"])), + mode_factory(binascii.unhexlify(params["iv"]), + binascii.unhexlify(params["tag"])), + backend + ) + decryptor = cipher.decryptor() + decryptor.add_data(binascii.unhexlify(aad)) + actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext)) + with pytest.raises(AssertionError): + decryptor.finalize() + else: + cipher = Cipher( + cipher_factory(binascii.unhexlify(params["key"])), + mode_factory(binascii.unhexlify(params["iv"]), None), + backend + ) + encryptor = cipher.encryptor() + encryptor.add_data(binascii.unhexlify(aad)) + actual_ciphertext = encryptor.update(binascii.unhexlify(plaintext)) + actual_ciphertext += encryptor.finalize() + tag_len = len(params["tag"]) + assert binascii.hexlify(encryptor.tag)[:tag_len] == params["tag"] + cipher = Cipher( + cipher_factory(binascii.unhexlify(params["key"])), + mode_factory(binascii.unhexlify(params["iv"]), + binascii.unhexlify(params["tag"])), + backend + ) + decryptor = cipher.decryptor() + decryptor.add_data(binascii.unhexlify(aad)) + actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext)) + actual_plaintext += decryptor.finalize() + assert actual_plaintext == binascii.unhexlify(plaintext) + + def generate_stream_encryption_test(param_loader, path, file_names, cipher_factory, only_if=None, skip_message=None): @@ -237,3 +305,36 @@ def base_hmac_test(backend, algorithm, only_if, skip_message): h_copy = h.copy() assert h != h_copy assert h._ctx != h_copy._ctx + + +def generate_aead_use_after_finalize_test(cipher_factory, mode_factory, + only_if, skip_message): + def test_aead_use_after_finalize(self): + for backend in _ALL_BACKENDS: + yield ( + aead_use_after_finalize_test, + backend, + cipher_factory, + mode_factory, + only_if, + skip_message + ) + return test_aead_use_after_finalize + + +def aead_use_after_finalize_test(backend, cipher_factory, mode_factory, + only_if, skip_message): + if not only_if(backend): + pytest.skip(skip_message) + cipher = Cipher( + cipher_factory(binascii.unhexlify(b"0" * 32)), + mode_factory(binascii.unhexlify(b"0" * 24)), + backend + ) + encryptor = cipher.encryptor() + encryptor.update(b"a" * 16) + with pytest.raises(NotFinalized): + encryptor.tag + encryptor.finalize() + with pytest.raises(AlreadyFinalized): + encryptor.add_data(b"b" * 16) -- cgit v1.2.3 From cc9ec987e82d1c4e2d42e6ef41664a090425287c Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 21 Nov 2013 11:21:35 -0600 Subject: rename NotFinalized exception to NotYetFinalized because alex is right ...it does read better that way --- tests/hazmat/primitives/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index 839ff822..98455556 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -7,7 +7,7 @@ from cryptography.hazmat.bindings import _ALL_BACKENDS from cryptography.hazmat.primitives import hashes, hmac from cryptography.hazmat.primitives.ciphers import Cipher from cryptography.exceptions import ( - AlreadyFinalized, NotFinalized, + AlreadyFinalized, NotYetFinalized, ) from ...utils import load_vectors_from_file @@ -333,7 +333,7 @@ def aead_use_after_finalize_test(backend, cipher_factory, mode_factory, ) encryptor = cipher.encryptor() encryptor.update(b"a" * 16) - with pytest.raises(NotFinalized): + with pytest.raises(NotYetFinalized): encryptor.tag encryptor.finalize() with pytest.raises(AlreadyFinalized): -- cgit v1.2.3 From 24316fd1945909ef720ceb0e294752c4d3b6bbb2 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 22 Nov 2013 13:30:46 -0600 Subject: _AEADCipherContext refactor * No longer extends _CipherContext * Remove _tag from _CipherContext * This change duplicates a small amount of code from _CipherContext --- tests/hazmat/primitives/utils.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tests') diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index 98455556..2a99cab9 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -338,3 +338,7 @@ def aead_use_after_finalize_test(backend, cipher_factory, mode_factory, encryptor.finalize() with pytest.raises(AlreadyFinalized): encryptor.add_data(b"b" * 16) + with pytest.raises(AlreadyFinalized): + encryptor.update(b"b" * 16) + with pytest.raises(AlreadyFinalized): + encryptor.finalize() -- cgit v1.2.3 From ce9c611feb4db781fcab5b7bbc68b936816d6a73 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 22 Nov 2013 14:10:59 -0600 Subject: enforce AEAD add_data before update --- tests/hazmat/primitives/test_block.py | 4 ++-- tests/hazmat/primitives/test_utils.py | 4 ++-- tests/hazmat/primitives/utils.py | 18 ++++++++++-------- 3 files changed, 14 insertions(+), 12 deletions(-) (limited to 'tests') diff --git a/tests/hazmat/primitives/test_block.py b/tests/hazmat/primitives/test_block.py index 296821a4..2806efd5 100644 --- a/tests/hazmat/primitives/test_block.py +++ b/tests/hazmat/primitives/test_block.py @@ -26,7 +26,7 @@ from cryptography.hazmat.primitives.ciphers import ( Cipher, algorithms, modes ) -from .utils import generate_aead_use_after_finalize_test +from .utils import generate_aead_exception_test @utils.register_interface(interfaces.CipherAlgorithm) @@ -127,7 +127,7 @@ class TestCipherContext(object): class TestAEADCipherContext(object): - test_use_after_finalize = generate_aead_use_after_finalize_test( + test_aead_exceptions = generate_aead_exception_test( algorithms.AES, modes.GCM, only_if=lambda backend: backend.cipher_supported( diff --git a/tests/hazmat/primitives/test_utils.py b/tests/hazmat/primitives/test_utils.py index f286e02d..ebb8b5c4 100644 --- a/tests/hazmat/primitives/test_utils.py +++ b/tests/hazmat/primitives/test_utils.py @@ -3,7 +3,7 @@ import pytest from .utils import ( base_hash_test, encrypt_test, hash_test, long_string_hash_test, base_hmac_test, hmac_test, stream_encryption_test, aead_test, - aead_use_after_finalize_test, + aead_exception_test, ) @@ -32,7 +32,7 @@ class TestAEADTest(object): class TestAEADFinalizeTest(object): def test_skips_if_only_if_returns_false(self): with pytest.raises(pytest.skip.Exception) as exc_info: - aead_use_after_finalize_test( + aead_exception_test( None, None, None, only_if=lambda backend: False, skip_message="message!" diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index 2a99cab9..8df02e78 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -7,7 +7,7 @@ from cryptography.hazmat.bindings import _ALL_BACKENDS from cryptography.hazmat.primitives import hashes, hmac from cryptography.hazmat.primitives.ciphers import Cipher from cryptography.exceptions import ( - AlreadyFinalized, NotYetFinalized, + AlreadyFinalized, NotYetFinalized, AlreadyUpdated, ) from ...utils import load_vectors_from_file @@ -307,23 +307,23 @@ def base_hmac_test(backend, algorithm, only_if, skip_message): assert h._ctx != h_copy._ctx -def generate_aead_use_after_finalize_test(cipher_factory, mode_factory, - only_if, skip_message): - def test_aead_use_after_finalize(self): +def generate_aead_exception_test(cipher_factory, mode_factory, + only_if, skip_message): + def test_aead_exception(self): for backend in _ALL_BACKENDS: yield ( - aead_use_after_finalize_test, + aead_exception_test, backend, cipher_factory, mode_factory, only_if, skip_message ) - return test_aead_use_after_finalize + return test_aead_exception -def aead_use_after_finalize_test(backend, cipher_factory, mode_factory, - only_if, skip_message): +def aead_exception_test(backend, cipher_factory, mode_factory, + only_if, skip_message): if not only_if(backend): pytest.skip(skip_message) cipher = Cipher( @@ -335,6 +335,8 @@ def aead_use_after_finalize_test(backend, cipher_factory, mode_factory, encryptor.update(b"a" * 16) with pytest.raises(NotYetFinalized): encryptor.tag + with pytest.raises(AlreadyUpdated): + encryptor.add_data(b"b" * 16) encryptor.finalize() with pytest.raises(AlreadyFinalized): encryptor.add_data(b"b" * 16) -- cgit v1.2.3 From a4bfc08b8d2ed312eeb1b0558ac20f285feb8cc2 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 22 Nov 2013 19:57:37 -0600 Subject: invalidtag exception for gcm This exception is probably not safe. It depends on the assumption that if ERR_get_error returns a 0 then it is an AEAD tag error. --- tests/hazmat/primitives/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index 8df02e78..39f5ae82 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -7,7 +7,7 @@ from cryptography.hazmat.bindings import _ALL_BACKENDS from cryptography.hazmat.primitives import hashes, hmac from cryptography.hazmat.primitives.ciphers import Cipher from cryptography.exceptions import ( - AlreadyFinalized, NotYetFinalized, AlreadyUpdated, + AlreadyFinalized, NotYetFinalized, AlreadyUpdated, InvalidTag, ) from ...utils import load_vectors_from_file @@ -95,7 +95,7 @@ def aead_test(backend, cipher_factory, mode_factory, params, only_if, decryptor = cipher.decryptor() decryptor.add_data(binascii.unhexlify(aad)) actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext)) - with pytest.raises(AssertionError): + with pytest.raises(InvalidTag): decryptor.finalize() else: cipher = Cipher( -- cgit v1.2.3 From bc31fb22979df3f034ce286fab20da71be76fe58 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 24 Nov 2013 11:03:53 -0600 Subject: rename add_data to authenticate_additional_data for clarity (hopefully) --- tests/hazmat/primitives/utils.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index 39f5ae82..b6f9e0f5 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -93,7 +93,7 @@ def aead_test(backend, cipher_factory, mode_factory, params, only_if, backend ) decryptor = cipher.decryptor() - decryptor.add_data(binascii.unhexlify(aad)) + decryptor.authenticate_additional_data(binascii.unhexlify(aad)) actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext)) with pytest.raises(InvalidTag): decryptor.finalize() @@ -104,7 +104,7 @@ def aead_test(backend, cipher_factory, mode_factory, params, only_if, backend ) encryptor = cipher.encryptor() - encryptor.add_data(binascii.unhexlify(aad)) + encryptor.authenticate_additional_data(binascii.unhexlify(aad)) actual_ciphertext = encryptor.update(binascii.unhexlify(plaintext)) actual_ciphertext += encryptor.finalize() tag_len = len(params["tag"]) @@ -116,7 +116,7 @@ def aead_test(backend, cipher_factory, mode_factory, params, only_if, backend ) decryptor = cipher.decryptor() - decryptor.add_data(binascii.unhexlify(aad)) + decryptor.authenticate_additional_data(binascii.unhexlify(aad)) actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext)) actual_plaintext += decryptor.finalize() assert actual_plaintext == binascii.unhexlify(plaintext) @@ -336,10 +336,10 @@ def aead_exception_test(backend, cipher_factory, mode_factory, with pytest.raises(NotYetFinalized): encryptor.tag with pytest.raises(AlreadyUpdated): - encryptor.add_data(b"b" * 16) + encryptor.authenticate_additional_data(b"b" * 16) encryptor.finalize() with pytest.raises(AlreadyFinalized): - encryptor.add_data(b"b" * 16) + encryptor.authenticate_additional_data(b"b" * 16) with pytest.raises(AlreadyFinalized): encryptor.update(b"b" * 16) with pytest.raises(AlreadyFinalized): -- cgit v1.2.3 From 0092c205657789e15848c7848eec768720de468f Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 24 Nov 2013 11:39:14 -0600 Subject: raise TypeError if you attempt to get the tag attribute on a decrypt * To support this the _AEADCipherContext in base.py now needs to be aware of whether it is encrypting/decrypting --- tests/hazmat/primitives/utils.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'tests') diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index b6f9e0f5..58b9a917 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -344,3 +344,12 @@ def aead_exception_test(backend, cipher_factory, mode_factory, encryptor.update(b"b" * 16) with pytest.raises(AlreadyFinalized): encryptor.finalize() + cipher = Cipher( + cipher_factory(binascii.unhexlify(b"0" * 32)), + mode_factory(binascii.unhexlify(b"0" * 24), b"0" * 16), + backend + ) + decryptor = cipher.decryptor() + decryptor.update(b"a" * 16) + with pytest.raises(TypeError): + decryptor.tag -- cgit v1.2.3 From 5a40896cbeae2cc2673c86aa18d3953314e760ba Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 29 Nov 2013 17:19:25 -0600 Subject: create AEADEncryptionContext and DecryptionContext --- tests/hazmat/primitives/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index 58b9a917..9aa3a89a 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -351,5 +351,5 @@ def aead_exception_test(backend, cipher_factory, mode_factory, ) decryptor = cipher.decryptor() decryptor.update(b"a" * 16) - with pytest.raises(TypeError): + with pytest.raises(AttributeError): decryptor.tag -- cgit v1.2.3 From 9c3088fe12d844a2007e0eff0eb947af53de7f60 Mon Sep 17 00:00:00 2001 From: Julian Krause Date: Wed, 4 Dec 2013 14:49:50 -0800 Subject: Beginnings of a constant_time module. --- tests/hazmat/primitives/test_constant_time.py | 41 +++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 tests/hazmat/primitives/test_constant_time.py (limited to 'tests') diff --git a/tests/hazmat/primitives/test_constant_time.py b/tests/hazmat/primitives/test_constant_time.py new file mode 100644 index 00000000..dd910dee --- /dev/null +++ b/tests/hazmat/primitives/test_constant_time.py @@ -0,0 +1,41 @@ +# 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 pytest + +import six + +from cryptography.hazmat.primitives import constant_time + + +class TestConstantTimeBytesEq(object): + def test_reject_unicode(self): + with pytest.raises(TypeError): + constant_time.bytes_eq(b"foo", six.u("foo")) + + with pytest.raises(TypeError): + constant_time.bytes_eq(six.u("foo"), b"foo") + + with pytest.raises(TypeError): + constant_time.bytes_eq(six.u("foo"), six.u("foo")) + + def test_compares(self): + assert constant_time.bytes_eq(b"foo", b"foo") is True + + assert constant_time.bytes_eq(b"foo", b"bar") is False + + assert constant_time.bytes_eq(b"foobar", b"foo") is False + + assert constant_time.bytes_eq(b"foo", b"foobar") is False -- cgit v1.2.3 From b91221dd7f27b3dcc09d3ad55645b12da08780cf Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 4 Dec 2013 17:56:40 -0600 Subject: raise ValueErrors when supplying/not supplying tags for GCM --- tests/hazmat/primitives/test_block.py | 12 +++++++++++- tests/hazmat/primitives/test_utils.py | 15 +++++++++++++-- tests/hazmat/primitives/utils.py | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/hazmat/primitives/test_block.py b/tests/hazmat/primitives/test_block.py index 2806efd5..02de3861 100644 --- a/tests/hazmat/primitives/test_block.py +++ b/tests/hazmat/primitives/test_block.py @@ -26,7 +26,9 @@ from cryptography.hazmat.primitives.ciphers import ( Cipher, algorithms, modes ) -from .utils import generate_aead_exception_test +from .utils import ( + generate_aead_exception_test, generate_aead_tag_exception_test +) @utils.register_interface(interfaces.CipherAlgorithm) @@ -135,3 +137,11 @@ class TestAEADCipherContext(object): ), skip_message="Does not support AES GCM", ) + test_aead_tag_exceptions = generate_aead_tag_exception_test( + algorithms.AES, + modes.GCM, + only_if=lambda backend: backend.cipher_supported( + algorithms.AES("\x00" * 16), modes.GCM("\x00" * 12) + ), + skip_message="Does not support AES GCM", + ) diff --git a/tests/hazmat/primitives/test_utils.py b/tests/hazmat/primitives/test_utils.py index ebb8b5c4..c39364c7 100644 --- a/tests/hazmat/primitives/test_utils.py +++ b/tests/hazmat/primitives/test_utils.py @@ -3,7 +3,7 @@ import pytest from .utils import ( base_hash_test, encrypt_test, hash_test, long_string_hash_test, base_hmac_test, hmac_test, stream_encryption_test, aead_test, - aead_exception_test, + aead_exception_test, aead_tag_exception_test, ) @@ -29,7 +29,7 @@ class TestAEADTest(object): assert exc_info.value.args[0] == "message!" -class TestAEADFinalizeTest(object): +class TestAEADExceptionTest(object): def test_skips_if_only_if_returns_false(self): with pytest.raises(pytest.skip.Exception) as exc_info: aead_exception_test( @@ -40,6 +40,17 @@ class TestAEADFinalizeTest(object): assert exc_info.value.args[0] == "message!" +class TestAEADTagExceptionTest(object): + def test_skips_if_only_if_returns_false(self): + with pytest.raises(pytest.skip.Exception) as exc_info: + aead_tag_exception_test( + None, None, None, + only_if=lambda backend: False, + skip_message="message!" + ) + assert exc_info.value.args[0] == "message!" + + class TestHashTest(object): def test_skips_if_only_if_returns_false(self): with pytest.raises(pytest.skip.Exception) as exc_info: diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index 9aa3a89a..705983a0 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -353,3 +353,38 @@ def aead_exception_test(backend, cipher_factory, mode_factory, decryptor.update(b"a" * 16) with pytest.raises(AttributeError): decryptor.tag + + +def generate_aead_tag_exception_test(cipher_factory, mode_factory, + only_if, skip_message): + def test_aead_tag_exception(self): + for backend in _ALL_BACKENDS: + yield ( + aead_tag_exception_test, + backend, + cipher_factory, + mode_factory, + only_if, + skip_message + ) + return test_aead_tag_exception + + +def aead_tag_exception_test(backend, cipher_factory, mode_factory, + only_if, skip_message): + if not only_if(backend): + pytest.skip(skip_message) + cipher = Cipher( + cipher_factory(binascii.unhexlify(b"0" * 32)), + mode_factory(binascii.unhexlify(b"0" * 24)), + backend + ) + with pytest.raises(ValueError): + cipher.decryptor() + cipher = Cipher( + cipher_factory(binascii.unhexlify(b"0" * 32)), + mode_factory(binascii.unhexlify(b"0" * 24), b"0" * 16), + backend + ) + with pytest.raises(ValueError): + cipher.encryptor() -- cgit v1.2.3 From f8796b15a279db82cdefcd00bebfef4cdef8fee8 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 13 Dec 2013 20:28:55 -0800 Subject: Renamed bindings to backends --- tests/conftest.py | 2 +- tests/hazmat/bindings/test_openssl.py | 4 ++-- tests/hazmat/primitives/utils.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/conftest.py b/tests/conftest.py index fab40b14..71662802 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,5 @@ def pytest_generate_tests(metafunc): - from cryptography.hazmat.bindings import _ALL_BACKENDS + from cryptography.hazmat.backends import _ALL_BACKENDS if "backend" in metafunc.fixturenames: metafunc.parametrize("backend", _ALL_BACKENDS) diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py index 1eb6f200..962959b9 100644 --- a/tests/hazmat/bindings/test_openssl.py +++ b/tests/hazmat/bindings/test_openssl.py @@ -15,8 +15,8 @@ import pytest from cryptography import utils from cryptography.exceptions import UnsupportedAlgorithm -from cryptography.hazmat.bindings import default_backend -from cryptography.hazmat.bindings.openssl.backend import backend, Backend +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.backends.openssl.backend import backend, Backend from cryptography.hazmat.primitives import interfaces from cryptography.hazmat.primitives.ciphers import Cipher from cryptography.hazmat.primitives.ciphers.algorithms import AES diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index 705983a0..b06f9b29 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -3,7 +3,7 @@ import os import pytest -from cryptography.hazmat.bindings import _ALL_BACKENDS +from cryptography.hazmat.backends import _ALL_BACKENDS from cryptography.hazmat.primitives import hashes, hmac from cryptography.hazmat.primitives.ciphers import Cipher from cryptography.exceptions import ( -- cgit v1.2.3 From 41e5ab64e9526c1e759034bafb3d75c1492ff54d Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 13 Dec 2013 20:41:49 -0800 Subject: Also rename teh tests --- tests/hazmat/backends/__init__.py | 0 tests/hazmat/backends/test_openssl.py | 97 +++++++++++++++++++++++++++++++++++ tests/hazmat/bindings/__init__.py | 0 tests/hazmat/bindings/test_openssl.py | 97 ----------------------------------- 4 files changed, 97 insertions(+), 97 deletions(-) create mode 100644 tests/hazmat/backends/__init__.py create mode 100644 tests/hazmat/backends/test_openssl.py delete mode 100644 tests/hazmat/bindings/__init__.py delete mode 100644 tests/hazmat/bindings/test_openssl.py (limited to 'tests') diff --git a/tests/hazmat/backends/__init__.py b/tests/hazmat/backends/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py new file mode 100644 index 00000000..962959b9 --- /dev/null +++ b/tests/hazmat/backends/test_openssl.py @@ -0,0 +1,97 @@ +# 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. + +import pytest + +from cryptography import utils +from cryptography.exceptions import UnsupportedAlgorithm +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.backends.openssl.backend import backend, Backend +from cryptography.hazmat.primitives import interfaces +from cryptography.hazmat.primitives.ciphers import Cipher +from cryptography.hazmat.primitives.ciphers.algorithms import AES +from cryptography.hazmat.primitives.ciphers.modes import CBC + + +class DummyMode(object): + pass + + +@utils.register_interface(interfaces.CipherAlgorithm) +class DummyCipher(object): + pass + + +class TestOpenSSL(object): + def test_backend_exists(self): + assert backend + + def test_is_default(self): + assert backend == default_backend() + + def test_openssl_version_text(self): + """ + This test checks the value of OPENSSL_VERSION_TEXT. + + Unfortunately, this define does not appear to have a + formal content definition, so for now we'll test to see + if it starts with OpenSSL as that appears to be true + for every OpenSSL. + """ + assert backend.openssl_version_text().startswith("OpenSSL") + + def test_supports_cipher(self): + assert backend.cipher_supported(None, None) is False + + def test_register_duplicate_cipher_adapter(self): + with pytest.raises(ValueError): + backend.register_cipher_adapter(AES, CBC, None) + + def test_instances_share_ffi(self): + b = Backend() + assert b.ffi is backend.ffi + assert b.lib is backend.lib + + def test_nonexistent_cipher(self): + b = Backend() + b.register_cipher_adapter( + DummyCipher, + DummyMode, + lambda backend, cipher, mode: backend.ffi.NULL + ) + cipher = Cipher( + DummyCipher(), DummyMode(), backend=b, + ) + with pytest.raises(UnsupportedAlgorithm): + cipher.encryptor() + + def test_handle_unknown_error(self): + with pytest.raises(SystemError): + backend._handle_error_code(0, 0, 0) + + with pytest.raises(SystemError): + backend._handle_error_code(backend.lib.ERR_LIB_EVP, 0, 0) + + with pytest.raises(SystemError): + backend._handle_error_code( + backend.lib.ERR_LIB_EVP, + backend.lib.EVP_F_EVP_ENCRYPTFINAL_EX, + 0 + ) + + with pytest.raises(SystemError): + backend._handle_error_code( + backend.lib.ERR_LIB_EVP, + backend.lib.EVP_F_EVP_DECRYPTFINAL_EX, + 0 + ) diff --git a/tests/hazmat/bindings/__init__.py b/tests/hazmat/bindings/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py deleted file mode 100644 index 962959b9..00000000 --- a/tests/hazmat/bindings/test_openssl.py +++ /dev/null @@ -1,97 +0,0 @@ -# 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. - -import pytest - -from cryptography import utils -from cryptography.exceptions import UnsupportedAlgorithm -from cryptography.hazmat.backends import default_backend -from cryptography.hazmat.backends.openssl.backend import backend, Backend -from cryptography.hazmat.primitives import interfaces -from cryptography.hazmat.primitives.ciphers import Cipher -from cryptography.hazmat.primitives.ciphers.algorithms import AES -from cryptography.hazmat.primitives.ciphers.modes import CBC - - -class DummyMode(object): - pass - - -@utils.register_interface(interfaces.CipherAlgorithm) -class DummyCipher(object): - pass - - -class TestOpenSSL(object): - def test_backend_exists(self): - assert backend - - def test_is_default(self): - assert backend == default_backend() - - def test_openssl_version_text(self): - """ - This test checks the value of OPENSSL_VERSION_TEXT. - - Unfortunately, this define does not appear to have a - formal content definition, so for now we'll test to see - if it starts with OpenSSL as that appears to be true - for every OpenSSL. - """ - assert backend.openssl_version_text().startswith("OpenSSL") - - def test_supports_cipher(self): - assert backend.cipher_supported(None, None) is False - - def test_register_duplicate_cipher_adapter(self): - with pytest.raises(ValueError): - backend.register_cipher_adapter(AES, CBC, None) - - def test_instances_share_ffi(self): - b = Backend() - assert b.ffi is backend.ffi - assert b.lib is backend.lib - - def test_nonexistent_cipher(self): - b = Backend() - b.register_cipher_adapter( - DummyCipher, - DummyMode, - lambda backend, cipher, mode: backend.ffi.NULL - ) - cipher = Cipher( - DummyCipher(), DummyMode(), backend=b, - ) - with pytest.raises(UnsupportedAlgorithm): - cipher.encryptor() - - def test_handle_unknown_error(self): - with pytest.raises(SystemError): - backend._handle_error_code(0, 0, 0) - - with pytest.raises(SystemError): - backend._handle_error_code(backend.lib.ERR_LIB_EVP, 0, 0) - - with pytest.raises(SystemError): - backend._handle_error_code( - backend.lib.ERR_LIB_EVP, - backend.lib.EVP_F_EVP_ENCRYPTFINAL_EX, - 0 - ) - - with pytest.raises(SystemError): - backend._handle_error_code( - backend.lib.ERR_LIB_EVP, - backend.lib.EVP_F_EVP_DECRYPTFINAL_EX, - 0 - ) -- cgit v1.2.3