From e5c5eec8cc5b0a4a1faa47013c0b90d01483b125 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 13 Dec 2013 08:10:20 -0800 Subject: Clean up test generation to not use generators anymore and use parametrization --- tests/hazmat/primitives/utils.py | 541 +++++++++++++++------------------------ 1 file changed, 209 insertions(+), 332 deletions(-) diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index 705983a0..7f67ad40 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -3,7 +3,6 @@ import os import pytest -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 ( @@ -13,378 +12,256 @@ from cryptography.exceptions import ( from ...utils import load_vectors_from_file +def _load_all_params(path, file_names, param_loader): + all_params = [] + for file_name in file_names: + all_params.extend( + load_vectors_from_file(os.path.join(path, file_name), param_loader) + ) + return all_params + + def generate_encrypt_test(param_loader, path, file_names, cipher_factory, mode_factory, only_if=lambda backend: True, skip_message=None): - def test_encryption(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 ( - encrypt_test, - backend, - cipher_factory, - mode_factory, - params, - only_if, - skip_message - ) - return test_encryption - + all_params = _load_all_params(path, file_names, param_loader) + + @pytest.mark.parametrize("params", all_params) + def test_encryption(self, backend, params): + if not only_if(backend): + pytest.skip(skip_message) + plaintext = params.pop("plaintext") + ciphertext = params.pop("ciphertext") + cipher = Cipher( + cipher_factory(**params), + mode_factory(**params), + backend=backend + ) + encryptor = cipher.encryptor() + actual_ciphertext = encryptor.update(binascii.unhexlify(plaintext)) + actual_ciphertext += encryptor.finalize() + assert actual_ciphertext == binascii.unhexlify(ciphertext) + decryptor = cipher.decryptor() + actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext)) + actual_plaintext += decryptor.finalize() + assert actual_plaintext == binascii.unhexlify(plaintext) -def encrypt_test(backend, cipher_factory, mode_factory, params, only_if, - skip_message): - if not only_if(backend): - pytest.skip(skip_message) - plaintext = params.pop("plaintext") - ciphertext = params.pop("ciphertext") - cipher = Cipher( - cipher_factory(**params), - mode_factory(**params), - backend=backend - ) - encryptor = cipher.encryptor() - actual_ciphertext = encryptor.update(binascii.unhexlify(plaintext)) - actual_ciphertext += encryptor.finalize() - assert actual_ciphertext == binascii.unhexlify(ciphertext) - decryptor = cipher.decryptor() - actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext)) - actual_plaintext += decryptor.finalize() - assert actual_plaintext == binascii.unhexlify(plaintext) + return test_encryption 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 - ) + all_params = _load_all_params(path, file_names, param_loader) + + @pytest.mark.parametrize("params", all_params) + def test_aead(self, backend, params): + 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.authenticate_additional_data(binascii.unhexlify(aad)) + actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext)) + with pytest.raises(InvalidTag): + decryptor.finalize() + else: + cipher = Cipher( + cipher_factory(binascii.unhexlify(params["key"])), + mode_factory(binascii.unhexlify(params["iv"]), None), + backend + ) + encryptor = cipher.encryptor() + encryptor.authenticate_additional_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.authenticate_additional_data(binascii.unhexlify(aad)) + actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext)) + actual_plaintext += decryptor.finalize() + assert actual_plaintext == binascii.unhexlify(plaintext) + 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.authenticate_additional_data(binascii.unhexlify(aad)) - actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext)) - with pytest.raises(InvalidTag): - decryptor.finalize() - else: - cipher = Cipher( - cipher_factory(binascii.unhexlify(params["key"])), - mode_factory(binascii.unhexlify(params["iv"]), None), - backend - ) +def generate_stream_encryption_test(param_loader, path, file_names, + cipher_factory, only_if=None, + skip_message=None): + all_params = _load_all_params(path, file_names, param_loader) + + @pytest.mark.parametrize("params", all_params) + def test_stream_encryption(self, backend, params): + if not only_if(backend): + pytest.skip(skip_message) + plaintext = params.pop("plaintext") + ciphertext = params.pop("ciphertext") + offset = params.pop("offset") + cipher = Cipher(cipher_factory(**params), None, backend=backend) encryptor = cipher.encryptor() - encryptor.authenticate_additional_data(binascii.unhexlify(aad)) + # throw away offset bytes + encryptor.update(b"\x00" * int(offset)) 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 - ) + assert actual_ciphertext == binascii.unhexlify(ciphertext) decryptor = cipher.decryptor() - decryptor.authenticate_additional_data(binascii.unhexlify(aad)) + decryptor.update(b"\x00" * int(offset)) 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): - def test_stream_encryption(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 ( - stream_encryption_test, - backend, - cipher_factory, - params, - only_if, - skip_message - ) return test_stream_encryption -def stream_encryption_test(backend, cipher_factory, params, only_if, - skip_message): - if not only_if(backend): - pytest.skip(skip_message) - plaintext = params.pop("plaintext") - ciphertext = params.pop("ciphertext") - offset = params.pop("offset") - cipher = Cipher(cipher_factory(**params), None, backend=backend) - encryptor = cipher.encryptor() - # throw away offset bytes - encryptor.update(b"\x00" * int(offset)) - actual_ciphertext = encryptor.update(binascii.unhexlify(plaintext)) - actual_ciphertext += encryptor.finalize() - assert actual_ciphertext == binascii.unhexlify(ciphertext) - decryptor = cipher.decryptor() - decryptor.update(b"\x00" * int(offset)) - actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext)) - actual_plaintext += decryptor.finalize() - assert actual_plaintext == binascii.unhexlify(plaintext) - - -def generate_hash_test(param_loader, path, file_names, hash_cls, - only_if=None, skip_message=None): - def test_hash(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 ( - hash_test, - backend, - hash_cls, - params, - only_if, - skip_message - ) - return test_hash +def generate_hash_test(param_loader, path, file_names, algorithm, only_if=None, + skip_message=None): + all_params = _load_all_params(path, file_names, param_loader) + @pytest.mark.parametrize("params", all_params) + def test_hash(self, backend, params): + if only_if is not None and not only_if(backend): + pytest.skip(skip_message) + msg, md = params + m = hashes.Hash(algorithm, backend=backend) + m.update(binascii.unhexlify(msg)) + expected_md = md.replace(" ", "").lower().encode("ascii") + assert m.finalize() == binascii.unhexlify(expected_md) -def hash_test(backend, algorithm, params, only_if, skip_message): - if only_if is not None and not only_if(backend): - pytest.skip(skip_message) - msg = params[0] - md = params[1] - m = hashes.Hash(algorithm, backend=backend) - m.update(binascii.unhexlify(msg)) - expected_md = md.replace(" ", "").lower().encode("ascii") - assert m.finalize() == binascii.unhexlify(expected_md) - - -def generate_base_hash_test(algorithm, digest_size, block_size, - only_if=None, skip_message=None): - def test_base_hash(self): - for backend in _ALL_BACKENDS: - yield ( - base_hash_test, - backend, - algorithm, - digest_size, - block_size, - only_if, - skip_message, - ) - return test_base_hash + return test_hash -def base_hash_test(backend, algorithm, digest_size, block_size, only_if, - skip_message): - if only_if is not None and not only_if(backend): - pytest.skip(skip_message) +def generate_base_hash_test(algorithm, digest_size, block_size, only_if=None, + skip_message=None): + def test_base_hash(self, backend): + if only_if is not None and not only_if(backend): + pytest.skip(skip_message) - m = hashes.Hash(algorithm, backend=backend) - assert m.algorithm.digest_size == digest_size - assert m.algorithm.block_size == block_size - m_copy = m.copy() - assert m != m_copy - assert m._ctx != m_copy._ctx + m = hashes.Hash(algorithm, backend=backend) + assert m.algorithm.digest_size == digest_size + assert m.algorithm.block_size == block_size + m_copy = m.copy() + assert m != m_copy + assert m._ctx != m_copy._ctx - m.update(b"abc") - copy = m.copy() - copy.update(b"123") - m.update(b"123") - assert copy.finalize() == m.finalize() + m.update(b"abc") + copy = m.copy() + copy.update(b"123") + m.update(b"123") + assert copy.finalize() == m.finalize() + + return test_base_hash -def generate_long_string_hash_test(hash_factory, md, only_if=None, +def generate_long_string_hash_test(algorithm, md, only_if=None, skip_message=None): - def test_long_string_hash(self): - for backend in _ALL_BACKENDS: - yield( - long_string_hash_test, - backend, - hash_factory, - md, - only_if, - skip_message - ) + def test_long_string_hash(self, backend): + if only_if is not None and not only_if(backend): + pytest.skip(skip_message) + m = hashes.Hash(algorithm, backend=backend) + m.update(b"a" * 1000000) + assert m.finalize() == binascii.unhexlify(md.lower().encode("ascii")) + return test_long_string_hash -def long_string_hash_test(backend, algorithm, md, only_if, skip_message): - if only_if is not None and not only_if(backend): - pytest.skip(skip_message) - m = hashes.Hash(algorithm, backend=backend) - m.update(b"a" * 1000000) - assert m.finalize() == binascii.unhexlify(md.lower().encode("ascii")) - - -def generate_hmac_test(param_loader, path, file_names, algorithm, - only_if=None, skip_message=None): - def test_hmac(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 ( - hmac_test, - backend, - algorithm, - params, - only_if, - skip_message - ) +def generate_hmac_test(param_loader, path, file_names, algorithm, only_if=None, + skip_message=None): + all_params = _load_all_params(path, file_names, param_loader) + + @pytest.mark.parametrize("params", all_params) + def test_hmac(self, backend, params): + if only_if is not None and not only_if(backend): + pytest.skip(skip_message) + msg, md, key = params + h = hmac.HMAC(binascii.unhexlify(key), algorithm, backend=backend) + h.update(binascii.unhexlify(msg)) + assert h.finalize() == binascii.unhexlify(md.encode("ascii")) + return test_hmac -def hmac_test(backend, algorithm, params, only_if, skip_message): - if only_if is not None and not only_if(backend): - pytest.skip(skip_message) - msg = params[0] - md = params[1] - key = params[2] - h = hmac.HMAC(binascii.unhexlify(key), algorithm, backend=backend) - h.update(binascii.unhexlify(msg)) - assert h.finalize() == binascii.unhexlify(md.encode("ascii")) - - -def generate_base_hmac_test(hash_cls, only_if=None, skip_message=None): - def test_base_hmac(self): - for backend in _ALL_BACKENDS: - yield ( - base_hmac_test, - backend, - hash_cls, - only_if, - skip_message, - ) +def generate_base_hmac_test(algorithm, only_if=None, skip_message=None): + def test_base_hmac(self, backend): + if only_if is not None and not only_if(backend): + pytest.skip(skip_message) + key = b"ab" + h = hmac.HMAC(binascii.unhexlify(key), algorithm, backend=backend) + h_copy = h.copy() + assert h != h_copy + assert h._ctx != h_copy._ctx + return test_base_hmac -def base_hmac_test(backend, algorithm, only_if, skip_message): - if only_if is not None and not only_if(backend): - pytest.skip(skip_message) - key = b"ab" - h = hmac.HMAC(binascii.unhexlify(key), algorithm, backend=backend) - h_copy = h.copy() - assert h != h_copy - assert h._ctx != h_copy._ctx - - -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_exception_test, - backend, - cipher_factory, - mode_factory, - only_if, - skip_message - ) - return test_aead_exception +def generate_aead_exception_test(cipher_factory, mode_factory, only_if, + skip_message): + def test_aead_exception(self, backend): + 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(NotYetFinalized): + encryptor.tag + with pytest.raises(AlreadyUpdated): + encryptor.authenticate_additional_data(b"b" * 16) + encryptor.finalize() + with pytest.raises(AlreadyFinalized): + encryptor.authenticate_additional_data(b"b" * 16) + with pytest.raises(AlreadyFinalized): + 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(AttributeError): + decryptor.tag + return test_aead_exception -def aead_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 - ) - encryptor = cipher.encryptor() - encryptor.update(b"a" * 16) - with pytest.raises(NotYetFinalized): - encryptor.tag - with pytest.raises(AlreadyUpdated): - encryptor.authenticate_additional_data(b"b" * 16) - encryptor.finalize() - with pytest.raises(AlreadyFinalized): - encryptor.authenticate_additional_data(b"b" * 16) - with pytest.raises(AlreadyFinalized): - 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(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 generate_aead_tag_exception_test(cipher_factory, mode_factory, only_if, + skip_message): + def test_aead_tag_exception(self, backend): + 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() -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() + return test_aead_tag_exception -- cgit v1.2.3 From 21919e218ae485e52da3f66e8373e79230e61a4c Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 13 Dec 2013 08:56:32 -0800 Subject: Make this less invasive --- tests/hazmat/primitives/utils.py | 457 ++++++++++++++++++++++++--------------- 1 file changed, 280 insertions(+), 177 deletions(-) diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index 7f67ad40..cfc885b0 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -3,6 +3,7 @@ import os import pytest +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 ( @@ -20,7 +21,6 @@ def _load_all_params(path, file_names, param_loader): ) return all_params - def generate_encrypt_test(param_loader, path, file_names, cipher_factory, mode_factory, only_if=lambda backend: True, skip_message=None): @@ -28,240 +28,343 @@ def generate_encrypt_test(param_loader, path, file_names, cipher_factory, @pytest.mark.parametrize("params", all_params) def test_encryption(self, backend, params): - if not only_if(backend): - pytest.skip(skip_message) - plaintext = params.pop("plaintext") - ciphertext = params.pop("ciphertext") - cipher = Cipher( - cipher_factory(**params), - mode_factory(**params), - backend=backend + encrypt_test( + backend, + cipher_factory, + mode_factory, + params, + only_if, + skip_message ) - encryptor = cipher.encryptor() - actual_ciphertext = encryptor.update(binascii.unhexlify(plaintext)) - actual_ciphertext += encryptor.finalize() - assert actual_ciphertext == binascii.unhexlify(ciphertext) - decryptor = cipher.decryptor() - actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext)) - actual_plaintext += decryptor.finalize() - assert actual_plaintext == binascii.unhexlify(plaintext) return test_encryption +def encrypt_test(backend, cipher_factory, mode_factory, params, only_if, + skip_message): + if not only_if(backend): + pytest.skip(skip_message) + plaintext = params.pop("plaintext") + ciphertext = params.pop("ciphertext") + cipher = Cipher( + cipher_factory(**params), + mode_factory(**params), + backend=backend + ) + encryptor = cipher.encryptor() + actual_ciphertext = encryptor.update(binascii.unhexlify(plaintext)) + actual_ciphertext += encryptor.finalize() + assert actual_ciphertext == binascii.unhexlify(ciphertext) + decryptor = cipher.decryptor() + actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext)) + actual_plaintext += decryptor.finalize() + assert actual_plaintext == binascii.unhexlify(plaintext) + + def generate_aead_test(param_loader, path, file_names, cipher_factory, mode_factory, only_if, skip_message): all_params = _load_all_params(path, file_names, param_loader) @pytest.mark.parametrize("params", all_params) def test_aead(self, backend, params): - 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.authenticate_additional_data(binascii.unhexlify(aad)) - actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext)) - with pytest.raises(InvalidTag): - decryptor.finalize() - else: - cipher = Cipher( - cipher_factory(binascii.unhexlify(params["key"])), - mode_factory(binascii.unhexlify(params["iv"]), None), - backend - ) - encryptor = cipher.encryptor() - encryptor.authenticate_additional_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.authenticate_additional_data(binascii.unhexlify(aad)) - actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext)) - actual_plaintext += decryptor.finalize() - assert actual_plaintext == binascii.unhexlify(plaintext) + aead_test( + backend, + cipher_factory, + mode_factory, + params, + only_if, + skip_message + ) return test_aead -def generate_stream_encryption_test(param_loader, path, file_names, - cipher_factory, only_if=None, - skip_message=None): - all_params = _load_all_params(path, file_names, param_loader) - - @pytest.mark.parametrize("params", all_params) - def test_stream_encryption(self, backend, params): - if not only_if(backend): - pytest.skip(skip_message) - plaintext = params.pop("plaintext") - ciphertext = params.pop("ciphertext") - offset = params.pop("offset") - cipher = Cipher(cipher_factory(**params), None, backend=backend) +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.authenticate_additional_data(binascii.unhexlify(aad)) + actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext)) + with pytest.raises(InvalidTag): + decryptor.finalize() + else: + cipher = Cipher( + cipher_factory(binascii.unhexlify(params["key"])), + mode_factory(binascii.unhexlify(params["iv"]), None), + backend + ) encryptor = cipher.encryptor() - # throw away offset bytes - encryptor.update(b"\x00" * int(offset)) + encryptor.authenticate_additional_data(binascii.unhexlify(aad)) actual_ciphertext = encryptor.update(binascii.unhexlify(plaintext)) actual_ciphertext += encryptor.finalize() - assert actual_ciphertext == binascii.unhexlify(ciphertext) + 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.update(b"\x00" * int(offset)) + decryptor.authenticate_additional_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): + all_params = _load_all_params(path, file_names, param_loader) + + @pytest.mark.parametrize("params", all_params) + def test_stream_encryption(self, backend, params): + stream_encryption_test( + backend, + cipher_factory, + params, + only_if, + skip_message + ) return test_stream_encryption -def generate_hash_test(param_loader, path, file_names, algorithm, only_if=None, - skip_message=None): +def stream_encryption_test(backend, cipher_factory, params, only_if, + skip_message): + if not only_if(backend): + pytest.skip(skip_message) + plaintext = params.pop("plaintext") + ciphertext = params.pop("ciphertext") + offset = params.pop("offset") + cipher = Cipher(cipher_factory(**params), None, backend=backend) + encryptor = cipher.encryptor() + # throw away offset bytes + encryptor.update(b"\x00" * int(offset)) + actual_ciphertext = encryptor.update(binascii.unhexlify(plaintext)) + actual_ciphertext += encryptor.finalize() + assert actual_ciphertext == binascii.unhexlify(ciphertext) + decryptor = cipher.decryptor() + decryptor.update(b"\x00" * int(offset)) + actual_plaintext = decryptor.update(binascii.unhexlify(ciphertext)) + actual_plaintext += decryptor.finalize() + assert actual_plaintext == binascii.unhexlify(plaintext) + + +def generate_hash_test(param_loader, path, file_names, hash_cls, + only_if=None, skip_message=None): all_params = _load_all_params(path, file_names, param_loader) @pytest.mark.parametrize("params", all_params) def test_hash(self, backend, params): - if only_if is not None and not only_if(backend): - pytest.skip(skip_message) - msg, md = params - m = hashes.Hash(algorithm, backend=backend) - m.update(binascii.unhexlify(msg)) - expected_md = md.replace(" ", "").lower().encode("ascii") - assert m.finalize() == binascii.unhexlify(expected_md) - + hash_test( + backend, + hash_cls, + params, + only_if, + skip_message + ) return test_hash -def generate_base_hash_test(algorithm, digest_size, block_size, only_if=None, - skip_message=None): - def test_base_hash(self, backend): - if only_if is not None and not only_if(backend): - pytest.skip(skip_message) - - m = hashes.Hash(algorithm, backend=backend) - assert m.algorithm.digest_size == digest_size - assert m.algorithm.block_size == block_size - m_copy = m.copy() - assert m != m_copy - assert m._ctx != m_copy._ctx - - m.update(b"abc") - copy = m.copy() - copy.update(b"123") - m.update(b"123") - assert copy.finalize() == m.finalize() +def hash_test(backend, algorithm, params, only_if, skip_message): + if only_if is not None and not only_if(backend): + pytest.skip(skip_message) + msg = params[0] + md = params[1] + m = hashes.Hash(algorithm, backend=backend) + m.update(binascii.unhexlify(msg)) + expected_md = md.replace(" ", "").lower().encode("ascii") + assert m.finalize() == binascii.unhexlify(expected_md) + +def generate_base_hash_test(algorithm, digest_size, block_size, + only_if=None, skip_message=None): + def test_base_hash(self, backend): + base_hash_test( + backend, + algorithm, + digest_size, + block_size, + only_if, + skip_message, + ) return test_base_hash -def generate_long_string_hash_test(algorithm, md, only_if=None, +def base_hash_test(backend, algorithm, digest_size, block_size, only_if, + skip_message): + if only_if is not None and not only_if(backend): + pytest.skip(skip_message) + + m = hashes.Hash(algorithm, backend=backend) + assert m.algorithm.digest_size == digest_size + assert m.algorithm.block_size == block_size + m_copy = m.copy() + assert m != m_copy + assert m._ctx != m_copy._ctx + + m.update(b"abc") + copy = m.copy() + copy.update(b"123") + m.update(b"123") + assert copy.finalize() == m.finalize() + + +def generate_long_string_hash_test(hash_factory, md, only_if=None, skip_message=None): def test_long_string_hash(self, backend): - if only_if is not None and not only_if(backend): - pytest.skip(skip_message) - m = hashes.Hash(algorithm, backend=backend) - m.update(b"a" * 1000000) - assert m.finalize() == binascii.unhexlify(md.lower().encode("ascii")) - + long_string_hash_test( + backend, + hash_factory, + md, + only_if, + skip_message + ) return test_long_string_hash -def generate_hmac_test(param_loader, path, file_names, algorithm, only_if=None, - skip_message=None): +def long_string_hash_test(backend, algorithm, md, only_if, skip_message): + if only_if is not None and not only_if(backend): + pytest.skip(skip_message) + m = hashes.Hash(algorithm, backend=backend) + m.update(b"a" * 1000000) + assert m.finalize() == binascii.unhexlify(md.lower().encode("ascii")) + + +def generate_hmac_test(param_loader, path, file_names, algorithm, + only_if=None, skip_message=None): all_params = _load_all_params(path, file_names, param_loader) @pytest.mark.parametrize("params", all_params) def test_hmac(self, backend, params): - if only_if is not None and not only_if(backend): - pytest.skip(skip_message) - msg, md, key = params - h = hmac.HMAC(binascii.unhexlify(key), algorithm, backend=backend) - h.update(binascii.unhexlify(msg)) - assert h.finalize() == binascii.unhexlify(md.encode("ascii")) - + hmac_test( + backend, + algorithm, + params, + only_if, + skip_message + ) return test_hmac -def generate_base_hmac_test(algorithm, only_if=None, skip_message=None): - def test_base_hmac(self, backend): - if only_if is not None and not only_if(backend): - pytest.skip(skip_message) - key = b"ab" - h = hmac.HMAC(binascii.unhexlify(key), algorithm, backend=backend) - h_copy = h.copy() - assert h != h_copy - assert h._ctx != h_copy._ctx +def hmac_test(backend, algorithm, params, only_if, skip_message): + if only_if is not None and not only_if(backend): + pytest.skip(skip_message) + msg = params[0] + md = params[1] + key = params[2] + h = hmac.HMAC(binascii.unhexlify(key), algorithm, backend=backend) + h.update(binascii.unhexlify(msg)) + assert h.finalize() == binascii.unhexlify(md.encode("ascii")) + +def generate_base_hmac_test(hash_cls, only_if=None, skip_message=None): + def test_base_hmac(self, backend): + base_hmac_test( + backend, + hash_cls, + only_if, + skip_message, + ) return test_base_hmac -def generate_aead_exception_test(cipher_factory, mode_factory, only_if, - skip_message): +def base_hmac_test(backend, algorithm, only_if, skip_message): + if only_if is not None and not only_if(backend): + pytest.skip(skip_message) + key = b"ab" + h = hmac.HMAC(binascii.unhexlify(key), algorithm, backend=backend) + h_copy = h.copy() + assert h != h_copy + assert h._ctx != h_copy._ctx + + +def generate_aead_exception_test(cipher_factory, mode_factory, + only_if, skip_message): def test_aead_exception(self, backend): - 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(NotYetFinalized): - encryptor.tag - with pytest.raises(AlreadyUpdated): - encryptor.authenticate_additional_data(b"b" * 16) - encryptor.finalize() - with pytest.raises(AlreadyFinalized): - encryptor.authenticate_additional_data(b"b" * 16) - with pytest.raises(AlreadyFinalized): - 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 + aead_exception_test( + backend, + cipher_factory, + mode_factory, + only_if, + skip_message ) - decryptor = cipher.decryptor() - decryptor.update(b"a" * 16) - with pytest.raises(AttributeError): - decryptor.tag - return test_aead_exception -def generate_aead_tag_exception_test(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( + 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(NotYetFinalized): + encryptor.tag + with pytest.raises(AlreadyUpdated): + encryptor.authenticate_additional_data(b"b" * 16) + encryptor.finalize() + with pytest.raises(AlreadyFinalized): + encryptor.authenticate_additional_data(b"b" * 16) + with pytest.raises(AlreadyFinalized): + 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(AttributeError): + decryptor.tag + + +def generate_aead_tag_exception_test(cipher_factory, mode_factory, + only_if, skip_message): def test_aead_tag_exception(self, backend): - 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 + aead_tag_exception_test( + backend, + cipher_factory, + mode_factory, + only_if, + skip_message ) - 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() - 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 4eec0bb4e1d79f107f40b3856f2c9ec76c3eef88 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 13 Dec 2013 09:12:19 -0800 Subject: pep8 --- tests/hazmat/primitives/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index cfc885b0..758e755c 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -3,7 +3,6 @@ import os import pytest -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 ( @@ -21,6 +20,7 @@ def _load_all_params(path, file_names, param_loader): ) return all_params + def generate_encrypt_test(param_loader, path, file_names, cipher_factory, mode_factory, only_if=lambda backend: True, skip_message=None): -- cgit v1.2.3 From 668d4803571876c1cf803b33495ddcf4433a4d83 Mon Sep 17 00:00:00 2001 From: David Reid Date: Tue, 17 Dec 2013 11:53:43 -0800 Subject: BlockCipherAlgorithm because we should document block_size and ARC4 shouldn't need block_size = 1. --- cryptography/hazmat/backends/openssl/backend.py | 11 ++++++++--- cryptography/hazmat/primitives/ciphers/algorithms.py | 6 +++++- cryptography/hazmat/primitives/interfaces.py | 8 ++++++++ docs/hazmat/primitives/interfaces.rst | 11 +++++++++++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index bd092bec..588a4273 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -276,6 +276,11 @@ class _CipherContext(object): self._operation = operation self._tag = None + if isinstance(self._cipher, interfaces.BlockCipherAlgorithm): + self._block_size = self._cipher.block_size + else: + self._block_size = 1 + ctx = self._backend.lib.EVP_CIPHER_CTX_new() ctx = self._backend.ffi.gc(ctx, self._backend.lib.EVP_CIPHER_CTX_free) @@ -341,7 +346,7 @@ class _CipherContext(object): def update(self, data): buf = self._backend.ffi.new("unsigned char[]", - len(data) + self._cipher.block_size - 1) + len(data) + self._block_size - 1) outlen = self._backend.ffi.new("int *") res = self._backend.lib.EVP_CipherUpdate(self._ctx, buf, outlen, data, len(data)) @@ -349,7 +354,7 @@ class _CipherContext(object): return self._backend.ffi.buffer(buf)[:outlen[0]] def finalize(self): - buf = self._backend.ffi.new("unsigned char[]", self._cipher.block_size) + buf = self._backend.ffi.new("unsigned char[]", self._block_size) outlen = self._backend.ffi.new("int *") res = self._backend.lib.EVP_CipherFinal_ex(self._ctx, buf, outlen) if res == 0: @@ -357,7 +362,7 @@ class _CipherContext(object): if (isinstance(self._mode, GCM) and self._operation == self._ENCRYPT): - block_byte_size = self._cipher.block_size // 8 + block_byte_size = self._block_size // 8 tag_buf = self._backend.ffi.new("unsigned char[]", block_byte_size) res = self._backend.lib.EVP_CIPHER_CTX_ctrl( self._ctx, self._backend.lib.Cryptography_EVP_CTRL_GCM_GET_TAG, diff --git a/cryptography/hazmat/primitives/ciphers/algorithms.py b/cryptography/hazmat/primitives/ciphers/algorithms.py index a206b273..a5cfce92 100644 --- a/cryptography/hazmat/primitives/ciphers/algorithms.py +++ b/cryptography/hazmat/primitives/ciphers/algorithms.py @@ -26,6 +26,7 @@ def _verify_key_size(algorithm, key): return key +@utils.register_interface(interfaces.BlockCipherAlgorithm) @utils.register_interface(interfaces.CipherAlgorithm) class AES(object): name = "AES" @@ -40,6 +41,7 @@ class AES(object): return len(self.key) * 8 +@utils.register_interface(interfaces.BlockCipherAlgorithm) @utils.register_interface(interfaces.CipherAlgorithm) class Camellia(object): name = "camellia" @@ -54,6 +56,7 @@ class Camellia(object): return len(self.key) * 8 +@utils.register_interface(interfaces.BlockCipherAlgorithm) @utils.register_interface(interfaces.CipherAlgorithm) class TripleDES(object): name = "3DES" @@ -72,6 +75,7 @@ class TripleDES(object): return len(self.key) * 8 +@utils.register_interface(interfaces.BlockCipherAlgorithm) @utils.register_interface(interfaces.CipherAlgorithm) class Blowfish(object): name = "Blowfish" @@ -86,6 +90,7 @@ class Blowfish(object): return len(self.key) * 8 +@utils.register_interface(interfaces.BlockCipherAlgorithm) @utils.register_interface(interfaces.CipherAlgorithm) class CAST5(object): name = "CAST5" @@ -103,7 +108,6 @@ class CAST5(object): @utils.register_interface(interfaces.CipherAlgorithm) class ARC4(object): name = "RC4" - block_size = 1 key_sizes = frozenset([40, 56, 64, 80, 128, 192, 256]) def __init__(self, key): diff --git a/cryptography/hazmat/primitives/interfaces.py b/cryptography/hazmat/primitives/interfaces.py index e3f4f586..2a1a21b8 100644 --- a/cryptography/hazmat/primitives/interfaces.py +++ b/cryptography/hazmat/primitives/interfaces.py @@ -32,6 +32,14 @@ class CipherAlgorithm(six.with_metaclass(abc.ABCMeta)): """ +class BlockCipherAlgorithm(six.with_metaclass(abc.ABCMeta)): + @abc.abstractproperty + def block_size(self): + """ + The size of a block as an integer in bits. (e.g. 64, 128) + """ + + class Mode(six.with_metaclass(abc.ABCMeta)): @abc.abstractproperty def name(self): diff --git a/docs/hazmat/primitives/interfaces.rst b/docs/hazmat/primitives/interfaces.rst index 11cff51a..361b723e 100644 --- a/docs/hazmat/primitives/interfaces.rst +++ b/docs/hazmat/primitives/interfaces.rst @@ -36,6 +36,17 @@ Symmetric Ciphers The number of bits in the key being used. +.. class:: BlockCipherAlgorithm + + A block cipher algorithm. + + .. attribute:: block_size + + :type: int + + The number of bits in a block. + + Cipher Modes ------------ -- cgit v1.2.3 From ccfa8894432831126095f4d7a3691c2add25d873 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 18 Dec 2013 14:54:05 -0800 Subject: Removed usage of stdbool for Windows which doesn't have C99 --- cryptography/hazmat/primitives/constant_time.py | 11 +++++------ cryptography/hazmat/primitives/padding.py | 6 ++---- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/cryptography/hazmat/primitives/constant_time.py b/cryptography/hazmat/primitives/constant_time.py index a8351504..6502803e 100644 --- a/cryptography/hazmat/primitives/constant_time.py +++ b/cryptography/hazmat/primitives/constant_time.py @@ -20,17 +20,16 @@ import six _ffi = cffi.FFI() _ffi.cdef(""" -bool Cryptography_constant_time_bytes_eq(uint8_t *, size_t, uint8_t *, size_t); +uint8_t Cryptography_constant_time_bytes_eq(uint8_t *, size_t, uint8_t *, + size_t); """) _lib = _ffi.verify(""" -#include - -bool Cryptography_constant_time_bytes_eq(uint8_t *a, size_t len_a, uint8_t *b, - size_t len_b) { +uint8_t Cryptography_constant_time_bytes_eq(uint8_t *a, size_t len_a, + uint8_t *b, size_t len_b) { size_t i = 0; uint8_t mismatch = 0; if (len_a != len_b) { - return false; + return 0; } for (i = 0; i < len_a; i++) { mismatch |= a[i] ^ b[i]; diff --git a/cryptography/hazmat/primitives/padding.py b/cryptography/hazmat/primitives/padding.py index cfa90db9..97298277 100644 --- a/cryptography/hazmat/primitives/padding.py +++ b/cryptography/hazmat/primitives/padding.py @@ -21,11 +21,9 @@ from cryptography.hazmat.primitives import interfaces _ffi = cffi.FFI() _ffi.cdef(""" -bool Cryptography_check_pkcs7_padding(const uint8_t *, uint8_t); +uint8_t Cryptography_check_pkcs7_padding(const uint8_t *, uint8_t); """) _lib = _ffi.verify(""" -#include - /* Returns the value of the input with the most-significant-bit copied to all of the bits. */ static uint8_t Cryptography_DUPLICATE_MSB_TO_ALL(uint8_t a) { @@ -39,7 +37,7 @@ static uint8_t Cryptography_constant_time_lt(uint8_t a, uint8_t b) { return Cryptography_DUPLICATE_MSB_TO_ALL(a); } -bool Cryptography_check_pkcs7_padding(const uint8_t *data, uint8_t block_len) { +uint8_t Cryptography_check_pkcs7_padding(const uint8_t *data, uint8_t block_len) { uint8_t i; uint8_t pad_size = data[block_len - 1]; uint8_t mismatch = 0; -- cgit v1.2.3 From 41e604dceeb0290b43a348c10789e65af0cc60f7 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 18 Dec 2013 16:26:27 -0800 Subject: flake8 fix --- cryptography/hazmat/primitives/padding.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cryptography/hazmat/primitives/padding.py b/cryptography/hazmat/primitives/padding.py index 97298277..e517dee0 100644 --- a/cryptography/hazmat/primitives/padding.py +++ b/cryptography/hazmat/primitives/padding.py @@ -37,7 +37,8 @@ static uint8_t Cryptography_constant_time_lt(uint8_t a, uint8_t b) { return Cryptography_DUPLICATE_MSB_TO_ALL(a); } -uint8_t Cryptography_check_pkcs7_padding(const uint8_t *data, uint8_t block_len) { +uint8_t Cryptography_check_pkcs7_padding(const uint8_t *data, + uint8_t block_len) { uint8_t i; uint8_t pad_size = data[block_len - 1]; uint8_t mismatch = 0; -- cgit v1.2.3 From 99fdc809e5ee05785d31af7da37dbed2326c8e5b Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 19 Dec 2013 13:31:03 -0800 Subject: Attempt to handle the fact that based on defines ASN1_ITEM_EXP might be something else --- cryptography/hazmat/backends/openssl/asn1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/asn1.py b/cryptography/hazmat/backends/openssl/asn1.py index 719a523c..c752e682 100644 --- a/cryptography/hazmat/backends/openssl/asn1.py +++ b/cryptography/hazmat/backends/openssl/asn1.py @@ -41,7 +41,7 @@ typedef ... ASN1_VALUE; typedef struct { ...; } ASN1_TIME; -typedef const ASN1_ITEM ASN1_ITEM_EXP; +typedef ... ASN1_ITEM_EXP; typedef ... ASN1_UTCTIME; @@ -102,7 +102,7 @@ ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **, const unsigned char **, long, MACROS = """ ASN1_TIME *M_ASN1_TIME_dup(void *); -ASN1_ITEM *ASN1_ITEM_ptr(ASN1_ITEM *); +ASN1_ITEM *ASN1_ITEM_ptr(ASN1_ITEM_EXP *); /* These aren't macros these arguments are all const X on openssl > 1.0.x */ -- cgit v1.2.3 From 67539c09123de7e76440ce5867613ade2a74b075 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 19 Dec 2013 15:25:17 -0800 Subject: Clean up some docstrings --- cryptography/hazmat/primitives/interfaces.py | 30 +++++++++++++++------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/cryptography/hazmat/primitives/interfaces.py b/cryptography/hazmat/primitives/interfaces.py index 2a1a21b8..61ecda9a 100644 --- a/cryptography/hazmat/primitives/interfaces.py +++ b/cryptography/hazmat/primitives/interfaces.py @@ -22,13 +22,13 @@ class CipherAlgorithm(six.with_metaclass(abc.ABCMeta)): @abc.abstractproperty def name(self): """ - A string naming this mode. (e.g. AES, Camellia) + A string naming this mode (e.g. "AES", "Camellia"). """ @abc.abstractproperty def key_size(self): """ - The size of the key being used as an integer in bits. (e.g. 128, 256) + The size of the key being used as an integer in bits (e.g. 128, 256). """ @@ -36,7 +36,7 @@ class BlockCipherAlgorithm(six.with_metaclass(abc.ABCMeta)): @abc.abstractproperty def block_size(self): """ - The size of a block as an integer in bits. (e.g. 64, 128) + The size of a block as an integer in bits (e.g. 64, 128). """ @@ -44,7 +44,7 @@ class Mode(six.with_metaclass(abc.ABCMeta)): @abc.abstractproperty def name(self): """ - A string naming this mode. (e.g. ECB, CBC) + A string naming this mode (e.g. ECB, CBC). """ @@ -76,13 +76,14 @@ class CipherContext(six.with_metaclass(abc.ABCMeta)): @abc.abstractmethod def update(self, data): """ - update takes bytes and return bytes + Processes the provided bytes through the cipher and returns the results + as bytes. """ @abc.abstractmethod def finalize(self): """ - finalize return bytes + Returns the results of processing the final block as bytes. """ @@ -90,7 +91,7 @@ class AEADCipherContext(six.with_metaclass(abc.ABCMeta)): @abc.abstractmethod def authenticate_additional_data(self, data): """ - authenticate_additional_data takes bytes and returns nothing. + Authenticates the provided bytes. """ @@ -98,7 +99,8 @@ class AEADEncryptionContext(six.with_metaclass(abc.ABCMeta)): @abc.abstractproperty def tag(self): """ - Returns tag bytes after finalizing encryption. + Returns tag bytes. This is only available after encryption is + finalized. """ @@ -106,13 +108,13 @@ class PaddingContext(six.with_metaclass(abc.ABCMeta)): @abc.abstractmethod def update(self, data): """ - update takes bytes and return bytes + Pads the provided bytes and returns any available data as bytes. """ @abc.abstractmethod def finalize(self): """ - finalize return bytes + Finalize the padding, returns bytes. """ @@ -120,7 +122,7 @@ class HashAlgorithm(six.with_metaclass(abc.ABCMeta)): @abc.abstractproperty def name(self): """ - A string naming this algorithm. (e.g. sha256, md5) + A string naming this algorithm (e.g. sha256, md5). """ @abc.abstractproperty @@ -146,17 +148,17 @@ class HashContext(six.with_metaclass(abc.ABCMeta)): @abc.abstractmethod def update(self, data): """ - hash data as bytes + Processes the provided bytes through the hash. """ @abc.abstractmethod def finalize(self): """ - finalize this copy of the hash and return the digest as bytes. + Finalizes the hash context and returns the hash digest as bytes. """ @abc.abstractmethod def copy(self): """ - return a HashContext that is a copy of the current context. + Return a HashContext that is a copy of the current context. """ -- cgit v1.2.3 From 764b54a5b1b3e8d6f5d7c2b72a5fdf00b0d805b3 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 19 Dec 2013 17:22:20 -0800 Subject: Make these examples consistent --- cryptography/hazmat/primitives/interfaces.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cryptography/hazmat/primitives/interfaces.py b/cryptography/hazmat/primitives/interfaces.py index 61ecda9a..e87c9ca9 100644 --- a/cryptography/hazmat/primitives/interfaces.py +++ b/cryptography/hazmat/primitives/interfaces.py @@ -44,7 +44,7 @@ class Mode(six.with_metaclass(abc.ABCMeta)): @abc.abstractproperty def name(self): """ - A string naming this mode (e.g. ECB, CBC). + A string naming this mode (e.g. "ECB", "CBC"). """ @@ -122,7 +122,7 @@ class HashAlgorithm(six.with_metaclass(abc.ABCMeta)): @abc.abstractproperty def name(self): """ - A string naming this algorithm (e.g. sha256, md5). + A string naming this algorithm (e.g. "sha256", "md5"). """ @abc.abstractproperty -- cgit v1.2.3 From b87f7b55d8322358c9dfa73d29d744c14c44237b Mon Sep 17 00:00:00 2001 From: cyli Date: Sat, 19 Oct 2013 21:25:41 -0700 Subject: Initial basic bindings for ssl --- cryptography/hazmat/backends/openssl/ssl.py | 74 +++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index 04611309..e1dccf4c 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -48,6 +48,7 @@ static const int SSL_OP_PKCS1_CHECK_1; static const int SSL_OP_PKCS1_CHECK_2; static const int SSL_OP_NETSCAPE_CA_DN_BUG; static const int SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG; +static const int SSL_OP_NO_COMPRESSION; static const int SSL_OP_NO_QUERY_MTU; static const int SSL_OP_COOKIE_EXCHANGE; static const int SSL_OP_NO_TICKET; @@ -84,6 +85,7 @@ static const int SSL_CB_CONNECT_LOOP; static const int SSL_CB_CONNECT_EXIT; static const int SSL_CB_HANDSHAKE_START; static const int SSL_CB_HANDSHAKE_DONE; +static const int SSL_MODE_RELEASE_BUFFERS; static const int SSL_MODE_ENABLE_PARTIAL_WRITE; static const int SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER; static const int SSL_MODE_AUTO_RETRY; @@ -112,13 +114,38 @@ typedef struct { } SSL; static const int TLSEXT_NAMETYPE_host_name; + +typedef int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx); +typedef void info_callback(const SSL *ssl, int where, int ret); +typedef int tlsext_servername_callback(const SSL *ssl, int *alert, void *arg); """ FUNCTIONS = """ -void SSL_load_error_strings(); - +void *OPENSSL_malloc(int); +void OPENSSL_free(void *); int SSL_library_init(); +/* methods */ + +const SSL_METHOD *SSLv3_method(); +const SSL_METHOD *SSLv3_server_method(); +const SSL_METHOD *SSLv3_client_method(); +const SSL_METHOD *TLSv1_method(); +const SSL_METHOD *TLSv1_server_method(); +const SSL_METHOD *TLSv1_client_method(); +const SSL_METHOD *SSLv23_method(); +const SSL_METHOD *SSLv23_server_method(); +const SSL_METHOD *SSLv23_client_method(); + +/* SSLv2 support is compiled out of some versions of OpenSSL. These will + * get special support when we generate the bindings so that if they are + * available they will be wrapped, but if they are not they won't cause + * problems (like link errors). + */ +SSL_METHOD *SSLv2_method(); +SSL_METHOD *SSLv2_server_method(); +SSL_METHOD *SSLv2_client_method(); + /* SSL */ SSL_CTX *SSL_set_SSL_CTX(SSL *, SSL_CTX *); SSL_SESSION *SSL_get1_session(SSL *); @@ -126,6 +153,14 @@ int SSL_set_session(SSL *, SSL_SESSION *); int SSL_get_verify_mode(const SSL *); void SSL_set_verify_depth(SSL *, int); int SSL_get_verify_depth(const SSL *); +int (*SSL_get_verify_callback(const SSL *))(int, X509_STORE_CTX *); +long SSL_set_mode(SSL *, long); +long SSL_get_mode(SSL *); +long SSL_set_options(SSL *, long); +long SSL_clear_options(SSL *, long); +long SSL_get_options(SSL *); +void SSL_set_info_callback(SSL *, void (*callback)()); +void (*SSL_get_info_callback(const SSL *))(); SSL *SSL_new(SSL_CTX *); void SSL_free(SSL *); int SSL_set_fd(SSL *, int); @@ -138,20 +173,43 @@ int SSL_pending(const SSL *); int SSL_write(SSL *, const void *, int); int SSL_read(SSL *, void *, int); X509 *SSL_get_peer_certificate(const SSL *); +struct stack_st_X509 *SSL_get_peer_cert_chain(const SSL *); +int SSL_want_read(const SSL *); +int SSL_want_write(const SSL *); +int SSL_total_renegotiations(const SSL *); int SSL_get_error(const SSL *, int); int SSL_do_handshake(SSL *); int SSL_shutdown(SSL *); +void SSL_set_shutdown(SSL *, int); +int SSL_get_shutdown(const SSL *); +struct stack_st_SSL_CIPHER *SSL_get_ciphers(const SSL *); const char *SSL_get_cipher_list(const SSL *, int); +struct stack_st_X509_NAME *SSL_get_client_CA_list(const SSL *); /* context */ +SSL_CTX *SSL_CTX_new(SSL_METHOD *); void SSL_CTX_free(SSL_CTX *); long SSL_CTX_set_timeout(SSL_CTX *, long); +long SSL_CTX_get_timeout(SSL_CTX *); int SSL_CTX_set_default_verify_paths(SSL_CTX *); +void SSL_CTX_set_verify(SSL_CTX *, int, verify_callback); void SSL_CTX_set_verify_depth(SSL_CTX *, int); +int (*SSL_CTX_get_verify_callback(const SSL_CTX *))(int, X509_STORE_CTX *); +void SSL_CTX_set_info_callback(SSL_CTX *, info_callback); +void (*SSL_CTX_get_info_callback(const SSL_CTX *))(); +long SSL_CTX_set_options(SSL_CTX *, long); +long SSL_CTX_clear_options(SSL_CTX *, long); +long SSL_CTX_get_options(SSL_CTX *); +long SSL_CTX_set_mode(SSL_CTX *, long); +long SSL_CTX_get_mode(SSL_CTX *); +long SSL_CTX_set_session_cache_mode(SSL_CTX *, long); +long SSL_CTX_get_session_cache_mode(SSL_CTX *); int SSL_CTX_get_verify_mode(const SSL_CTX *); int SSL_CTX_get_verify_depth(const SSL_CTX *); int SSL_CTX_set_cipher_list(SSL_CTX *, const char *); int SSL_CTX_load_verify_locations(SSL_CTX *, const char *, const char *); +long SSL_CTX_set_tmp_dh(SSL_CTX *, DH *); +long SSL_CTX_add_extra_chain_cert(SSL_CTX *, X509 *); void SSL_CTX_set_default_passwd_cb(SSL_CTX *, pem_password_cb *); void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *, void *); int SSL_CTX_use_certificate(SSL_CTX *, X509 *); @@ -159,9 +217,11 @@ int SSL_CTX_use_certificate_file(SSL_CTX *, const char *, int); int SSL_CTX_use_certificate_chain_file(SSL_CTX *, const char *); int SSL_CTX_use_PrivateKey(SSL_CTX *, EVP_PKEY *); int SSL_CTX_use_PrivateKey_file(SSL_CTX *, const char *, int); +struct stack_st_X509_NAME *SSL_CTX_get_client_CA_list(const SSL_CTX *); void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *); X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *); int SSL_CTX_add_client_CA(SSL_CTX *, X509 *); +void SSL_CTX_set_client_CA_list(SSL_CTX *, struct stack_st_X509_NAME *); /* X509_STORE_CTX */ int X509_STORE_CTX_get_error(X509_STORE_CTX *); @@ -173,7 +233,7 @@ X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *); void SSL_SESSION_free(SSL_SESSION *); """ -MACROS = MACROS = """ +MACROS = """ long SSL_set_mode(SSL *, long); long SSL_get_mode(SSL *); @@ -210,6 +270,14 @@ const SSL_METHOD *SSLv23_client_method(); /*- These aren't macros these arguments are all const X on openssl > 1.0.x -*/ SSL_CTX *SSL_CTX_new(const SSL_METHOD *); long SSL_CTX_get_timeout(const SSL_CTX *); + +/* SNI APIs were introduced in OpenSSL 1.0.0. To continue to support + * earlier versions some special handling of these is necessary. + */ +void SSL_set_tlsext_host_name(SSL *, char *); +const char *SSL_get_servername(const SSL *, const int); +void SSL_CTX_set_tlsext_servername_callback(SSL_CTX *, + tlsext_servername_callback); """ CUSTOMIZATIONS = """ -- cgit v1.2.3 From eb373f5b2c4b81a9a90504468a6d39c9b50e7fd6 Mon Sep 17 00:00:00 2001 From: cyli Date: Sat, 19 Oct 2013 21:36:23 -0700 Subject: Delete some repeated functions, and move the OPENSSL_malloc definition to crypto bindings, since it seems to be in crypto.h --- cryptography/hazmat/backends/openssl/crypto.py | 2 ++ cryptography/hazmat/backends/openssl/ssl.py | 4 ---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/crypto.py b/cryptography/hazmat/backends/openssl/crypto.py index 773d9b14..2f1dfe11 100644 --- a/cryptography/hazmat/backends/openssl/crypto.py +++ b/cryptography/hazmat/backends/openssl/crypto.py @@ -34,6 +34,8 @@ void CRYPTO_malloc_debug_init(); #define CRYPTO_MEM_CHECK_OFF ... #define CRYPTO_MEM_CHECK_ENABLE ... #define CRYPTO_MEM_CHECK_DISABLE ... + +#define OPENSSL_malloc ... """ CUSTOMIZATIONS = """ diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index e1dccf4c..b42407ad 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -121,12 +121,10 @@ typedef int tlsext_servername_callback(const SSL *ssl, int *alert, void *arg); """ FUNCTIONS = """ -void *OPENSSL_malloc(int); void OPENSSL_free(void *); int SSL_library_init(); /* methods */ - const SSL_METHOD *SSLv3_method(); const SSL_METHOD *SSLv3_server_method(); const SSL_METHOD *SSLv3_client_method(); @@ -180,8 +178,6 @@ int SSL_total_renegotiations(const SSL *); int SSL_get_error(const SSL *, int); int SSL_do_handshake(SSL *); int SSL_shutdown(SSL *); -void SSL_set_shutdown(SSL *, int); -int SSL_get_shutdown(const SSL *); struct stack_st_SSL_CIPHER *SSL_get_ciphers(const SSL *); const char *SSL_get_cipher_list(const SSL *, int); struct stack_st_X509_NAME *SSL_get_client_CA_list(const SSL *); -- cgit v1.2.3 From 3a61d720d0d622d1a8c019db4fe5c512ccdf7c3e Mon Sep 17 00:00:00 2001 From: cyli Date: Sat, 19 Oct 2013 23:09:30 -0700 Subject: Move a few macros to macros --- cryptography/hazmat/backends/openssl/ssl.py | 48 +++++++++++++++++------------ 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index b42407ad..3a100f18 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -135,15 +135,6 @@ const SSL_METHOD *SSLv23_method(); const SSL_METHOD *SSLv23_server_method(); const SSL_METHOD *SSLv23_client_method(); -/* SSLv2 support is compiled out of some versions of OpenSSL. These will - * get special support when we generate the bindings so that if they are - * available they will be wrapped, but if they are not they won't cause - * problems (like link errors). - */ -SSL_METHOD *SSLv2_method(); -SSL_METHOD *SSLv2_server_method(); -SSL_METHOD *SSLv2_client_method(); - /* SSL */ SSL_CTX *SSL_set_SSL_CTX(SSL *, SSL_CTX *); SSL_SESSION *SSL_get1_session(SSL *); @@ -152,11 +143,6 @@ int SSL_get_verify_mode(const SSL *); void SSL_set_verify_depth(SSL *, int); int SSL_get_verify_depth(const SSL *); int (*SSL_get_verify_callback(const SSL *))(int, X509_STORE_CTX *); -long SSL_set_mode(SSL *, long); -long SSL_get_mode(SSL *); -long SSL_set_options(SSL *, long); -long SSL_clear_options(SSL *, long); -long SSL_get_options(SSL *); void SSL_set_info_callback(SSL *, void (*callback)()); void (*SSL_get_info_callback(const SSL *))(); SSL *SSL_new(SSL_CTX *); @@ -172,9 +158,6 @@ int SSL_write(SSL *, const void *, int); int SSL_read(SSL *, void *, int); X509 *SSL_get_peer_certificate(const SSL *); struct stack_st_X509 *SSL_get_peer_cert_chain(const SSL *); -int SSL_want_read(const SSL *); -int SSL_want_write(const SSL *); -int SSL_total_renegotiations(const SSL *); int SSL_get_error(const SSL *, int); int SSL_do_handshake(SSL *); int SSL_shutdown(SSL *); @@ -183,10 +166,8 @@ const char *SSL_get_cipher_list(const SSL *, int); struct stack_st_X509_NAME *SSL_get_client_CA_list(const SSL *); /* context */ -SSL_CTX *SSL_CTX_new(SSL_METHOD *); void SSL_CTX_free(SSL_CTX *); long SSL_CTX_set_timeout(SSL_CTX *, long); -long SSL_CTX_get_timeout(SSL_CTX *); int SSL_CTX_set_default_verify_paths(SSL_CTX *); void SSL_CTX_set_verify(SSL_CTX *, int, verify_callback); void SSL_CTX_set_verify_depth(SSL_CTX *, int); @@ -276,5 +257,34 @@ void SSL_CTX_set_tlsext_servername_callback(SSL_CTX *, tlsext_servername_callback); """ +MACROS = """ +long SSL_set_mode(SSL *, long); +long SSL_get_mode(SSL *); + +long SSL_set_options(SSL *, long); +long SSL_clear_options(SSL *, long); +long SSL_get_options(SSL *); + +int SSL_want_read(const SSL *); +int SSL_want_write(const SSL *); + +int SSL_total_renegotiations(const SSL *); + +/*- These aren't macros these functions are all const X on openssl > 1.0.x -*/ + +/* SSLv2 support is compiled out of some versions of OpenSSL. These will + * get special support when we generate the bindings so that if they are + * available they will be wrapped, but if they are not they won't cause + * problems (like link errors). + */ +const SSL_METHOD *SSLv2_method(); +const SSL_METHOD *SSLv2_server_method(); +const SSL_METHOD *SSLv2_client_method(); + +/*- These aren't macros these arguments are all const X on openssl > 1.0.x -*/ +SSL_CTX *SSL_CTX_new(const SSL_METHOD *); +long SSL_CTX_get_timeout(const SSL_CTX *); +""" + CUSTOMIZATIONS = """ """ -- cgit v1.2.3 From 02209c6045d8a5702f30c7401dfe6755208edef1 Mon Sep 17 00:00:00 2001 From: cyli Date: Sat, 19 Oct 2013 23:19:10 -0700 Subject: Unfortunate hack to make replacing some callback signature in the function definitions work --- cryptography/hazmat/backends/openssl/ssl.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index 3a100f18..dee5edc5 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -13,6 +13,14 @@ INCLUDES = """ #include + +/* This is a gross hack - if it is not here, as well as in the TYPES section, + * because it is needed to replace some function signatures in the FUNCTIONS + * section, and may be needed by PyOpenSSL + */ +typedef int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx); +typedef void info_callback(const SSL *ssl, int where, int ret); +typedef int tlsext_servername_callback(const SSL *ssl, int *alert, void *arg); """ TYPES = """ -- cgit v1.2.3 From 272987868860db0d82a3765c7af767cbf12b4397 Mon Sep 17 00:00:00 2001 From: cyli Date: Sun, 20 Oct 2013 17:15:07 -0700 Subject: Move some methods to macros that have become const between versions --- cryptography/hazmat/backends/openssl/ssl.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index dee5edc5..20b69b11 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -132,17 +132,6 @@ FUNCTIONS = """ void OPENSSL_free(void *); int SSL_library_init(); -/* methods */ -const SSL_METHOD *SSLv3_method(); -const SSL_METHOD *SSLv3_server_method(); -const SSL_METHOD *SSLv3_client_method(); -const SSL_METHOD *TLSv1_method(); -const SSL_METHOD *TLSv1_server_method(); -const SSL_METHOD *TLSv1_client_method(); -const SSL_METHOD *SSLv23_method(); -const SSL_METHOD *SSLv23_server_method(); -const SSL_METHOD *SSLv23_client_method(); - /* SSL */ SSL_CTX *SSL_set_SSL_CTX(SSL *, SSL_CTX *); SSL_SESSION *SSL_get1_session(SSL *); @@ -289,6 +278,17 @@ const SSL_METHOD *SSLv2_method(); const SSL_METHOD *SSLv2_server_method(); const SSL_METHOD *SSLv2_client_method(); +/* methods */ +const SSL_METHOD *SSLv3_method(); +const SSL_METHOD *SSLv3_server_method(); +const SSL_METHOD *SSLv3_client_method(); +const SSL_METHOD *TLSv1_method(); +const SSL_METHOD *TLSv1_server_method(); +const SSL_METHOD *TLSv1_client_method(); +const SSL_METHOD *SSLv23_method(); +const SSL_METHOD *SSLv23_server_method(); +const SSL_METHOD *SSLv23_client_method(); + /*- These aren't macros these arguments are all const X on openssl > 1.0.x -*/ SSL_CTX *SSL_CTX_new(const SSL_METHOD *); long SSL_CTX_get_timeout(const SSL_CTX *); -- cgit v1.2.3 From 76db2227819f19d1094aa569725356f0d0f02e8a Mon Sep 17 00:00:00 2001 From: cyli Date: Sun, 20 Oct 2013 17:17:34 -0700 Subject: Fix broken function definition --- cryptography/hazmat/backends/openssl/ssl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index 20b69b11..5a235f85 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -170,7 +170,7 @@ void SSL_CTX_set_verify(SSL_CTX *, int, verify_callback); void SSL_CTX_set_verify_depth(SSL_CTX *, int); int (*SSL_CTX_get_verify_callback(const SSL_CTX *))(int, X509_STORE_CTX *); void SSL_CTX_set_info_callback(SSL_CTX *, info_callback); -void (*SSL_CTX_get_info_callback(const SSL_CTX *))(); +void (*SSL_CTX_get_info_callback(SSL_CTX *))(const SSL *, int, int); long SSL_CTX_set_options(SSL_CTX *, long); long SSL_CTX_clear_options(SSL_CTX *, long); long SSL_CTX_get_options(SSL_CTX *); -- cgit v1.2.3 From e105635d5e4bff08688760b5b1692520cd439446 Mon Sep 17 00:00:00 2001 From: cyli Date: Sun, 20 Oct 2013 18:08:55 -0700 Subject: Move OPENSSL_free to crypto.py as per @alex --- cryptography/hazmat/backends/openssl/crypto.py | 2 ++ cryptography/hazmat/backends/openssl/ssl.py | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cryptography/hazmat/backends/openssl/crypto.py b/cryptography/hazmat/backends/openssl/crypto.py index 2f1dfe11..c4300ee0 100644 --- a/cryptography/hazmat/backends/openssl/crypto.py +++ b/cryptography/hazmat/backends/openssl/crypto.py @@ -24,6 +24,8 @@ int CRYPTO_mem_ctrl(int); int CRYPTO_is_mem_check_on(); void CRYPTO_mem_leaks(struct bio_st *); void CRYPTO_cleanup_all_ex_data(); + +void OPENSSL_free(void *); """ MACROS = """ diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index 5a235f85..46463eaa 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -129,7 +129,6 @@ typedef int tlsext_servername_callback(const SSL *ssl, int *alert, void *arg); """ FUNCTIONS = """ -void OPENSSL_free(void *); int SSL_library_init(); /* SSL */ -- cgit v1.2.3 From 6796ddd83f157fe394f433fdbc3582759f03c1c1 Mon Sep 17 00:00:00 2001 From: cyli Date: Sun, 20 Oct 2013 18:09:58 -0700 Subject: Remove typedef'd callbacks and just include the callback definitions in the larger function definitions --- cryptography/hazmat/backends/openssl/ssl.py | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index 46463eaa..cf221c92 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -13,14 +13,6 @@ INCLUDES = """ #include - -/* This is a gross hack - if it is not here, as well as in the TYPES section, - * because it is needed to replace some function signatures in the FUNCTIONS - * section, and may be needed by PyOpenSSL - */ -typedef int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx); -typedef void info_callback(const SSL *ssl, int where, int ret); -typedef int tlsext_servername_callback(const SSL *ssl, int *alert, void *arg); """ TYPES = """ @@ -122,10 +114,6 @@ typedef struct { } SSL; static const int TLSEXT_NAMETYPE_host_name; - -typedef int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx); -typedef void info_callback(const SSL *ssl, int where, int ret); -typedef int tlsext_servername_callback(const SSL *ssl, int *alert, void *arg); """ FUNCTIONS = """ @@ -165,10 +153,10 @@ struct stack_st_X509_NAME *SSL_get_client_CA_list(const SSL *); void SSL_CTX_free(SSL_CTX *); long SSL_CTX_set_timeout(SSL_CTX *, long); int SSL_CTX_set_default_verify_paths(SSL_CTX *); -void SSL_CTX_set_verify(SSL_CTX *, int, verify_callback); +void SSL_CTX_set_verify(SSL_CTX *, int, int (*callback)(int, X509_STORE_CTX *)); void SSL_CTX_set_verify_depth(SSL_CTX *, int); int (*SSL_CTX_get_verify_callback(const SSL_CTX *))(int, X509_STORE_CTX *); -void SSL_CTX_set_info_callback(SSL_CTX *, info_callback); +void SSL_CTX_set_info_callback(SSL_CTX *, void (*cb)(const SSL *, int, int)); void (*SSL_CTX_get_info_callback(SSL_CTX *))(const SSL *, int, int); long SSL_CTX_set_options(SSL_CTX *, long); long SSL_CTX_clear_options(SSL_CTX *, long); @@ -249,8 +237,9 @@ long SSL_CTX_get_timeout(const SSL_CTX *); */ void SSL_set_tlsext_host_name(SSL *, char *); const char *SSL_get_servername(const SSL *, const int); -void SSL_CTX_set_tlsext_servername_callback(SSL_CTX *, - tlsext_servername_callback); +void SSL_CTX_set_tlsext_servername_callback( + SSL_CTX *, + int (*cb)(const SSL *, int *, void *)); """ MACROS = """ -- cgit v1.2.3 From 2df36e58f72aff9e86956f2c9a4d9dc4cd53c4ae Mon Sep 17 00:00:00 2001 From: cyli Date: Sun, 20 Oct 2013 18:13:37 -0700 Subject: Move more macros to the macro section --- cryptography/hazmat/backends/openssl/ssl.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index cf221c92..b2cc865e 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -158,19 +158,10 @@ void SSL_CTX_set_verify_depth(SSL_CTX *, int); int (*SSL_CTX_get_verify_callback(const SSL_CTX *))(int, X509_STORE_CTX *); void SSL_CTX_set_info_callback(SSL_CTX *, void (*cb)(const SSL *, int, int)); void (*SSL_CTX_get_info_callback(SSL_CTX *))(const SSL *, int, int); -long SSL_CTX_set_options(SSL_CTX *, long); -long SSL_CTX_clear_options(SSL_CTX *, long); -long SSL_CTX_get_options(SSL_CTX *); -long SSL_CTX_set_mode(SSL_CTX *, long); -long SSL_CTX_get_mode(SSL_CTX *); -long SSL_CTX_set_session_cache_mode(SSL_CTX *, long); -long SSL_CTX_get_session_cache_mode(SSL_CTX *); int SSL_CTX_get_verify_mode(const SSL_CTX *); int SSL_CTX_get_verify_depth(const SSL_CTX *); int SSL_CTX_set_cipher_list(SSL_CTX *, const char *); int SSL_CTX_load_verify_locations(SSL_CTX *, const char *, const char *); -long SSL_CTX_set_tmp_dh(SSL_CTX *, DH *); -long SSL_CTX_add_extra_chain_cert(SSL_CTX *, X509 *); void SSL_CTX_set_default_passwd_cb(SSL_CTX *, pem_password_cb *); void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *, void *); int SSL_CTX_use_certificate(SSL_CTX *, X509 *); @@ -255,6 +246,16 @@ int SSL_want_write(const SSL *); int SSL_total_renegotiations(const SSL *); +long SSL_CTX_set_options(SSL_CTX *, long); +long SSL_CTX_clear_options(SSL_CTX *, long); +long SSL_CTX_get_options(SSL_CTX *); +long SSL_CTX_set_mode(SSL_CTX *, long); +long SSL_CTX_get_mode(SSL_CTX *); +long SSL_CTX_set_session_cache_mode(SSL_CTX *, long); +long SSL_CTX_get_session_cache_mode(SSL_CTX *); +long SSL_CTX_set_tmp_dh(SSL_CTX *, DH *); +long SSL_CTX_add_extra_chain_cert(SSL_CTX *, X509 *); + /*- These aren't macros these functions are all const X on openssl > 1.0.x -*/ /* SSLv2 support is compiled out of some versions of OpenSSL. These will -- cgit v1.2.3 From db7a91138a4883de00917d862e69fe4414dac7b7 Mon Sep 17 00:00:00 2001 From: cyli Date: Sun, 20 Oct 2013 18:15:47 -0700 Subject: Undo accidentaly removal a function after rebase --- cryptography/hazmat/backends/openssl/ssl.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index b2cc865e..1d22ded8 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -117,6 +117,7 @@ static const int TLSEXT_NAMETYPE_host_name; """ FUNCTIONS = """ +void SSL_load_error_strings(); int SSL_library_init(); /* SSL */ -- cgit v1.2.3 From e0562502d3006c9bc4968e76f02274ec7ed80582 Mon Sep 17 00:00:00 2001 From: cyli Date: Sun, 10 Nov 2013 18:08:14 -0800 Subject: Put customizations back in after rebase --- cryptography/hazmat/backends/openssl/ssl.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index 1d22ded8..d91c89a6 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -16,6 +16,12 @@ INCLUDES = """ """ TYPES = """ +/* Internally invented symbol to tell us if SSLv2 is supported */ +static const int PYOPENSSL_NO_SSL2; + +/* Internally invented symbol to tell us if SNI is supported */ +static const int PYOPENSSL_TLSEXT_HOSTNAME; + static const int SSL_FILETYPE_PEM; static const int SSL_FILETYPE_ASN1; static const int SSL_ERROR_NONE; @@ -285,4 +291,23 @@ long SSL_CTX_get_timeout(const SSL_CTX *); """ CUSTOMIZATIONS = """ +#ifdef OPENSSL_NO_SSL2 +static const int PYOPENSSL_NO_SSL2 = 1; +SSL_METHOD* (*SSLv2_method)() = NULL; +SSL_METHOD* (*SSLv2_client_method)() = NULL; +SSL_METHOD* (*SSLv2_server_method)() = NULL; +#else +static const int PYOPENSSL_NO_SSL2 = 0; +#endif + +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME +static const int PYOPENSSL_TLSEXT_HOSTNAME = 1; +#else +static const int PYOPENSSL_TLSEXT_HOSTNAME = 0; +void (*SSL_set_tlsext_host_name)(SSL *, char *) = NULL; +const char* (*SSL_get_servername)(const SSL *, const int) = NULL; +void (*SSL_CTX_set_tlsext_servername_callback)( + SSL_CTX *, + int (*cb)(const SSL *, int *, void *)) = NULL; +#endif """ -- cgit v1.2.3 From bef5768d9e691c094f19bc4e611367d2e7b8b573 Mon Sep 17 00:00:00 2001 From: cyli Date: Sun, 10 Nov 2013 18:09:45 -0800 Subject: Move some SNI APIs to macros --- cryptography/hazmat/backends/openssl/ssl.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index d91c89a6..09d342b8 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -233,11 +233,7 @@ long SSL_CTX_get_timeout(const SSL_CTX *); /* SNI APIs were introduced in OpenSSL 1.0.0. To continue to support * earlier versions some special handling of these is necessary. */ -void SSL_set_tlsext_host_name(SSL *, char *); const char *SSL_get_servername(const SSL *, const int); -void SSL_CTX_set_tlsext_servername_callback( - SSL_CTX *, - int (*cb)(const SSL *, int *, void *)); """ MACROS = """ @@ -288,6 +284,14 @@ const SSL_METHOD *SSLv23_client_method(); /*- These aren't macros these arguments are all const X on openssl > 1.0.x -*/ SSL_CTX *SSL_CTX_new(const SSL_METHOD *); long SSL_CTX_get_timeout(const SSL_CTX *); + +/* SNI APIs were introduced in OpenSSL 1.0.0. To continue to support + * earlier versions some special handling of these is necessary. + */ +void SSL_set_tlsext_host_name(SSL *, char *); +void SSL_CTX_set_tlsext_servername_callback( + SSL_CTX *, + int (*cb)(const SSL *, int *, void *)); """ CUSTOMIZATIONS = """ -- cgit v1.2.3 From 1c6110923d12b877390dcaa2ca07080261fca38d Mon Sep 17 00:00:00 2001 From: cyli Date: Mon, 11 Nov 2013 09:47:28 -0800 Subject: Remove some functions that are dependent upon the stacksafe macro STACK_OF --- cryptography/hazmat/backends/openssl/ssl.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index 09d342b8..3de2e1e0 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -148,13 +148,10 @@ int SSL_pending(const SSL *); int SSL_write(SSL *, const void *, int); int SSL_read(SSL *, void *, int); X509 *SSL_get_peer_certificate(const SSL *); -struct stack_st_X509 *SSL_get_peer_cert_chain(const SSL *); int SSL_get_error(const SSL *, int); int SSL_do_handshake(SSL *); int SSL_shutdown(SSL *); -struct stack_st_SSL_CIPHER *SSL_get_ciphers(const SSL *); const char *SSL_get_cipher_list(const SSL *, int); -struct stack_st_X509_NAME *SSL_get_client_CA_list(const SSL *); /* context */ void SSL_CTX_free(SSL_CTX *); @@ -176,11 +173,9 @@ int SSL_CTX_use_certificate_file(SSL_CTX *, const char *, int); int SSL_CTX_use_certificate_chain_file(SSL_CTX *, const char *); int SSL_CTX_use_PrivateKey(SSL_CTX *, EVP_PKEY *); int SSL_CTX_use_PrivateKey_file(SSL_CTX *, const char *, int); -struct stack_st_X509_NAME *SSL_CTX_get_client_CA_list(const SSL_CTX *); void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *); X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *); int SSL_CTX_add_client_CA(SSL_CTX *, X509 *); -void SSL_CTX_set_client_CA_list(SSL_CTX *, struct stack_st_X509_NAME *); /* X509_STORE_CTX */ int X509_STORE_CTX_get_error(X509_STORE_CTX *); -- cgit v1.2.3 From 9f2182543e782cde17c1b46908d4c8e8ff01b8fc Mon Sep 17 00:00:00 2001 From: cyli Date: Mon, 11 Nov 2013 16:11:29 -0800 Subject: Remove OPENSSL_malloc, which was causing errors, and remove the two vars that were problematic in 0.9.8 --- cryptography/hazmat/backends/openssl/crypto.py | 2 -- cryptography/hazmat/backends/openssl/ssl.py | 2 -- 2 files changed, 4 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/crypto.py b/cryptography/hazmat/backends/openssl/crypto.py index c4300ee0..11e5f2f5 100644 --- a/cryptography/hazmat/backends/openssl/crypto.py +++ b/cryptography/hazmat/backends/openssl/crypto.py @@ -36,8 +36,6 @@ void CRYPTO_malloc_debug_init(); #define CRYPTO_MEM_CHECK_OFF ... #define CRYPTO_MEM_CHECK_ENABLE ... #define CRYPTO_MEM_CHECK_DISABLE ... - -#define OPENSSL_malloc ... """ CUSTOMIZATIONS = """ diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index 3de2e1e0..a3a718bf 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -54,7 +54,6 @@ static const int SSL_OP_PKCS1_CHECK_1; static const int SSL_OP_PKCS1_CHECK_2; static const int SSL_OP_NETSCAPE_CA_DN_BUG; static const int SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG; -static const int SSL_OP_NO_COMPRESSION; static const int SSL_OP_NO_QUERY_MTU; static const int SSL_OP_COOKIE_EXCHANGE; static const int SSL_OP_NO_TICKET; @@ -91,7 +90,6 @@ static const int SSL_CB_CONNECT_LOOP; static const int SSL_CB_CONNECT_EXIT; static const int SSL_CB_HANDSHAKE_START; static const int SSL_CB_HANDSHAKE_DONE; -static const int SSL_MODE_RELEASE_BUFFERS; static const int SSL_MODE_ENABLE_PARTIAL_WRITE; static const int SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER; static const int SSL_MODE_AUTO_RETRY; -- cgit v1.2.3 From c24597b261249567afee2802c5eda5cd9141a141 Mon Sep 17 00:00:00 2001 From: cyli Date: Sun, 17 Nov 2013 18:05:09 -0800 Subject: Fixes after rebasing --- cryptography/hazmat/backends/openssl/ssl.py | 44 ----------------------------- 1 file changed, 44 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index a3a718bf..15269bd5 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -189,50 +189,6 @@ MACROS = """ long SSL_set_mode(SSL *, long); long SSL_get_mode(SSL *); -long SSL_set_options(SSL *, long); -long SSL_get_options(SSL *); - -int SSL_want_read(const SSL *); -int SSL_want_write(const SSL *); - -int SSL_total_renegotiations(const SSL *); - -long SSL_CTX_set_options(SSL_CTX *, long); -long SSL_CTX_get_options(SSL_CTX *); -long SSL_CTX_set_mode(SSL_CTX *, long); -long SSL_CTX_get_mode(SSL_CTX *); -long SSL_CTX_set_session_cache_mode(SSL_CTX *, long); -long SSL_CTX_get_session_cache_mode(SSL_CTX *); -long SSL_CTX_set_tmp_dh(SSL_CTX *, DH *); -long SSL_CTX_add_extra_chain_cert(SSL_CTX *, X509 *); - -/*- These aren't macros these functions are all const X on openssl > 1.0.x -*/ - -/* methods */ -const SSL_METHOD *SSLv3_method(); -const SSL_METHOD *SSLv3_server_method(); -const SSL_METHOD *SSLv3_client_method(); -const SSL_METHOD *TLSv1_method(); -const SSL_METHOD *TLSv1_server_method(); -const SSL_METHOD *TLSv1_client_method(); -const SSL_METHOD *SSLv23_method(); -const SSL_METHOD *SSLv23_server_method(); -const SSL_METHOD *SSLv23_client_method(); - -/*- These aren't macros these arguments are all const X on openssl > 1.0.x -*/ -SSL_CTX *SSL_CTX_new(const SSL_METHOD *); -long SSL_CTX_get_timeout(const SSL_CTX *); - -/* SNI APIs were introduced in OpenSSL 1.0.0. To continue to support - * earlier versions some special handling of these is necessary. - */ -const char *SSL_get_servername(const SSL *, const int); -""" - -MACROS = """ -long SSL_set_mode(SSL *, long); -long SSL_get_mode(SSL *); - long SSL_set_options(SSL *, long); long SSL_clear_options(SSL *, long); long SSL_get_options(SSL *); -- cgit v1.2.3 From 6238b0a46255440e322b4403cd37330d1616c7ff Mon Sep 17 00:00:00 2001 From: cyli Date: Sat, 14 Dec 2013 22:32:42 -0800 Subject: Rename PYOPENSSL_ to CRYPTOGRAPHY_ --- cryptography/hazmat/backends/openssl/ssl.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index 15269bd5..89b2c5ae 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -17,10 +17,10 @@ INCLUDES = """ TYPES = """ /* Internally invented symbol to tell us if SSLv2 is supported */ -static const int PYOPENSSL_NO_SSL2; +static const int CRYPTOGRAPHY_NO_SSL2; /* Internally invented symbol to tell us if SNI is supported */ -static const int PYOPENSSL_TLSEXT_HOSTNAME; +static const int CRYPTOGRAPHY_TLSEXT_HOSTNAME; static const int SSL_FILETYPE_PEM; static const int SSL_FILETYPE_ASN1; @@ -245,18 +245,18 @@ void SSL_CTX_set_tlsext_servername_callback( CUSTOMIZATIONS = """ #ifdef OPENSSL_NO_SSL2 -static const int PYOPENSSL_NO_SSL2 = 1; +static const int CRYPTOGRAPHY_NO_SSL2 = 1; SSL_METHOD* (*SSLv2_method)() = NULL; SSL_METHOD* (*SSLv2_client_method)() = NULL; SSL_METHOD* (*SSLv2_server_method)() = NULL; #else -static const int PYOPENSSL_NO_SSL2 = 0; +static const int CRYPTOGRAPHY_NO_SSL2 = 0; #endif #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME -static const int PYOPENSSL_TLSEXT_HOSTNAME = 1; +static const int CRYPTOGRAPHY_TLSEXT_HOSTNAME = 1; #else -static const int PYOPENSSL_TLSEXT_HOSTNAME = 0; +static const int CRYPTOGRAPHY_TLSEXT_HOSTNAME = 0; void (*SSL_set_tlsext_host_name)(SSL *, char *) = NULL; const char* (*SSL_get_servername)(const SSL *, const int) = NULL; void (*SSL_CTX_set_tlsext_servername_callback)( -- cgit v1.2.3 From 4ba8ea6c962d0c4277b7c46c401a93db708e0378 Mon Sep 17 00:00:00 2001 From: cyli Date: Sun, 15 Dec 2013 21:02:52 -0800 Subject: Oops, change to Cryptography_, not CRYPTOPGRAPHY_ (screaming). Also remove SSL_clear_options which is not in 0.9.8. --- cryptography/hazmat/backends/openssl/ssl.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index 89b2c5ae..7e7de5ce 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -17,10 +17,10 @@ INCLUDES = """ TYPES = """ /* Internally invented symbol to tell us if SSLv2 is supported */ -static const int CRYPTOGRAPHY_NO_SSL2; +static const int Cryptography_NO_SSL2; /* Internally invented symbol to tell us if SNI is supported */ -static const int CRYPTOGRAPHY_TLSEXT_HOSTNAME; +static const int Cryptography_TLSEXT_HOSTNAME; static const int SSL_FILETYPE_PEM; static const int SSL_FILETYPE_ASN1; @@ -190,7 +190,6 @@ long SSL_set_mode(SSL *, long); long SSL_get_mode(SSL *); long SSL_set_options(SSL *, long); -long SSL_clear_options(SSL *, long); long SSL_get_options(SSL *); int SSL_want_read(const SSL *); @@ -245,18 +244,18 @@ void SSL_CTX_set_tlsext_servername_callback( CUSTOMIZATIONS = """ #ifdef OPENSSL_NO_SSL2 -static const int CRYPTOGRAPHY_NO_SSL2 = 1; +static const int Cryptography_NO_SSL2 = 1; SSL_METHOD* (*SSLv2_method)() = NULL; SSL_METHOD* (*SSLv2_client_method)() = NULL; SSL_METHOD* (*SSLv2_server_method)() = NULL; #else -static const int CRYPTOGRAPHY_NO_SSL2 = 0; +static const int Cryptography_NO_SSL2 = 0; #endif #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME -static const int CRYPTOGRAPHY_TLSEXT_HOSTNAME = 1; +static const int Cryptography_TLSEXT_HOSTNAME = 1; #else -static const int CRYPTOGRAPHY_TLSEXT_HOSTNAME = 0; +static const int Cryptography_TLSEXT_HOSTNAME = 0; void (*SSL_set_tlsext_host_name)(SSL *, char *) = NULL; const char* (*SSL_get_servername)(const SSL *, const int) = NULL; void (*SSL_CTX_set_tlsext_servername_callback)( -- cgit v1.2.3 From a620b7dfc15cf945a589e9d472b01db6f48a50a5 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 20 Dec 2013 22:59:02 -0600 Subject: don't modify params on parametrized tests multiple backends receive the same params dicts, but we were modifying them using pop. --- tests/hazmat/primitives/test_3des.py | 42 ++++++++++++++++++-------------- tests/hazmat/primitives/test_aes.py | 20 +++++++-------- tests/hazmat/primitives/test_arc4.py | 2 +- tests/hazmat/primitives/test_blowfish.py | 24 ++++++++++++------ tests/hazmat/primitives/test_camellia.py | 24 ++++++++++++------ tests/hazmat/primitives/test_cast5.py | 4 +-- tests/hazmat/primitives/utils.py | 16 ++++++------ 7 files changed, 77 insertions(+), 55 deletions(-) diff --git a/tests/hazmat/primitives/test_3des.py b/tests/hazmat/primitives/test_3des.py index 69ec9c9a..35745310 100644 --- a/tests/hazmat/primitives/test_3des.py +++ b/tests/hazmat/primitives/test_3des.py @@ -37,8 +37,10 @@ class TestTripleDES_CBC(object): "TCBCvarkey.rsp", "TCBCvartext.rsp", ], - lambda keys, iv: algorithms.TripleDES(binascii.unhexlify(keys)), - lambda keys, iv: modes.CBC(binascii.unhexlify(iv)), + lambda **kwargs: algorithms.TripleDES( + binascii.unhexlify(kwargs["keys"]) + ), + lambda **kwargs: modes.CBC(binascii.unhexlify(kwargs["iv"])), ) test_MMT = generate_encrypt_test( @@ -49,10 +51,10 @@ class TestTripleDES_CBC(object): "TCBCMMT2.rsp", "TCBCMMT3.rsp", ], - lambda key1, key2, key3, iv: ( - algorithms.TripleDES(binascii.unhexlify(key1 + key2 + key3)) - ), - lambda key1, key2, key3, iv: modes.CBC(binascii.unhexlify(iv)), + lambda **kwargs: algorithms.TripleDES(binascii.unhexlify( + kwargs["key1"] + kwargs["key2"] + kwargs["key3"] + )), + lambda **kwargs: modes.CBC(binascii.unhexlify(kwargs["iv"])), ) @@ -67,8 +69,10 @@ class TestTripleDES_OFB(object): "TOFBvartext.rsp", "TOFBinvperm.rsp", ], - lambda keys, iv: algorithms.TripleDES(binascii.unhexlify(keys)), - lambda keys, iv: modes.OFB(binascii.unhexlify(iv)), + lambda **kwargs: algorithms.TripleDES( + binascii.unhexlify(kwargs["keys"]) + ), + lambda **kwargs: modes.OFB(binascii.unhexlify(kwargs["iv"])), ) test_MMT = generate_encrypt_test( @@ -79,10 +83,10 @@ class TestTripleDES_OFB(object): "TOFBMMT2.rsp", "TOFBMMT3.rsp", ], - lambda key1, key2, key3, iv: ( - algorithms.TripleDES(binascii.unhexlify(key1 + key2 + key3)) - ), - lambda key1, key2, key3, iv: modes.OFB(binascii.unhexlify(iv)), + lambda **kwargs: algorithms.TripleDES(binascii.unhexlify( + kwargs["key1"] + kwargs["key2"] + kwargs["key3"] + )), + lambda **kwargs: modes.OFB(binascii.unhexlify(kwargs["iv"])), ) @@ -97,8 +101,10 @@ class TestTripleDES_CFB(object): "TCFB64varkey.rsp", "TCFB64vartext.rsp", ], - lambda keys, iv: algorithms.TripleDES(binascii.unhexlify(keys)), - lambda keys, iv: modes.CFB(binascii.unhexlify(iv)), + lambda **kwargs: algorithms.TripleDES( + binascii.unhexlify(kwargs["keys"]) + ), + lambda **kwargs: modes.CFB(binascii.unhexlify(kwargs["iv"])), ) test_MMT = generate_encrypt_test( @@ -109,8 +115,8 @@ class TestTripleDES_CFB(object): "TCFB64MMT2.rsp", "TCFB64MMT3.rsp", ], - lambda key1, key2, key3, iv: ( - algorithms.TripleDES(binascii.unhexlify(key1 + key2 + key3)) - ), - lambda key1, key2, key3, iv: modes.CFB(binascii.unhexlify(iv)), + lambda **kwargs: algorithms.TripleDES(binascii.unhexlify( + kwargs["key1"] + kwargs["key2"] + kwargs["key3"] + )), + lambda **kwargs: modes.CFB(binascii.unhexlify(kwargs["iv"])), ) diff --git a/tests/hazmat/primitives/test_aes.py b/tests/hazmat/primitives/test_aes.py index f7b0b9a0..d706cbd8 100644 --- a/tests/hazmat/primitives/test_aes.py +++ b/tests/hazmat/primitives/test_aes.py @@ -45,8 +45,8 @@ class TestAES(object): "CBCMMT192.rsp", "CBCMMT256.rsp", ], - lambda key, iv: algorithms.AES(binascii.unhexlify(key)), - lambda key, iv: modes.CBC(binascii.unhexlify(iv)), + lambda **kwargs: algorithms.AES(binascii.unhexlify(kwargs["key"])), + lambda **kwargs: modes.CBC(binascii.unhexlify(kwargs["iv"])), ) test_ECB = generate_encrypt_test( @@ -69,8 +69,8 @@ class TestAES(object): "ECBMMT192.rsp", "ECBMMT256.rsp", ], - lambda key: algorithms.AES(binascii.unhexlify(key)), - lambda key: modes.ECB(), + lambda **kwargs: algorithms.AES(binascii.unhexlify(kwargs["key"])), + lambda **kwargs: modes.ECB(), ) test_OFB = generate_encrypt_test( @@ -93,8 +93,8 @@ class TestAES(object): "OFBMMT192.rsp", "OFBMMT256.rsp", ], - lambda key, iv: algorithms.AES(binascii.unhexlify(key)), - lambda key, iv: modes.OFB(binascii.unhexlify(iv)), + lambda **kwargs: algorithms.AES(binascii.unhexlify(kwargs["key"])), + lambda **kwargs: modes.OFB(binascii.unhexlify(kwargs["iv"])), ) test_CFB = generate_encrypt_test( @@ -117,16 +117,16 @@ class TestAES(object): "CFB128MMT192.rsp", "CFB128MMT256.rsp", ], - lambda key, iv: algorithms.AES(binascii.unhexlify(key)), - lambda key, iv: modes.CFB(binascii.unhexlify(iv)), + lambda **kwargs: algorithms.AES(binascii.unhexlify(kwargs["key"])), + lambda **kwargs: modes.CFB(binascii.unhexlify(kwargs["iv"])), ) test_CTR = generate_encrypt_test( load_openssl_vectors, os.path.join("ciphers", "AES", "CTR"), ["aes-128-ctr.txt", "aes-192-ctr.txt", "aes-256-ctr.txt"], - lambda key, iv: algorithms.AES(binascii.unhexlify(key)), - lambda key, iv: modes.CTR(binascii.unhexlify(iv)), + lambda **kwargs: algorithms.AES(binascii.unhexlify(kwargs["key"])), + lambda **kwargs: modes.CTR(binascii.unhexlify(kwargs["iv"])), only_if=lambda backend: backend.cipher_supported( algorithms.AES("\x00" * 16), modes.CTR("\x00" * 16) ), diff --git a/tests/hazmat/primitives/test_arc4.py b/tests/hazmat/primitives/test_arc4.py index d233bec2..7ce93061 100644 --- a/tests/hazmat/primitives/test_arc4.py +++ b/tests/hazmat/primitives/test_arc4.py @@ -35,7 +35,7 @@ class TestARC4(object): "rfc-6229-192.txt", "rfc-6229-256.txt", ], - lambda key: algorithms.ARC4(binascii.unhexlify((key))), + lambda **kwargs: algorithms.ARC4(binascii.unhexlify((kwargs["key"]))), only_if=lambda backend: backend.cipher_supported( algorithms.ARC4("\x00" * 16), None ), diff --git a/tests/hazmat/primitives/test_blowfish.py b/tests/hazmat/primitives/test_blowfish.py index d5fbed6f..3e0e9025 100644 --- a/tests/hazmat/primitives/test_blowfish.py +++ b/tests/hazmat/primitives/test_blowfish.py @@ -27,8 +27,10 @@ class TestBlowfish(object): load_nist_vectors, os.path.join("ciphers", "Blowfish"), ["bf-ecb.txt"], - lambda key: algorithms.Blowfish(binascii.unhexlify(key)), - lambda key: modes.ECB(), + lambda **kwargs: algorithms.Blowfish( + binascii.unhexlify(kwargs["key"]) + ), + lambda **kwargs: modes.ECB(), only_if=lambda backend: backend.cipher_supported( algorithms.Blowfish("\x00" * 56), modes.ECB() ), @@ -39,8 +41,10 @@ class TestBlowfish(object): load_nist_vectors, os.path.join("ciphers", "Blowfish"), ["bf-cbc.txt"], - lambda key, iv: algorithms.Blowfish(binascii.unhexlify(key)), - lambda key, iv: modes.CBC(binascii.unhexlify(iv)), + lambda **kwargs: algorithms.Blowfish( + binascii.unhexlify(kwargs["key"]) + ), + lambda **kwargs: modes.CBC(binascii.unhexlify(kwargs["iv"])), only_if=lambda backend: backend.cipher_supported( algorithms.Blowfish("\x00" * 56), modes.CBC("\x00" * 8) ), @@ -51,8 +55,10 @@ class TestBlowfish(object): load_nist_vectors, os.path.join("ciphers", "Blowfish"), ["bf-ofb.txt"], - lambda key, iv: algorithms.Blowfish(binascii.unhexlify(key)), - lambda key, iv: modes.OFB(binascii.unhexlify(iv)), + lambda **kwargs: algorithms.Blowfish( + binascii.unhexlify(kwargs["key"]) + ), + lambda **kwargs: modes.OFB(binascii.unhexlify(kwargs["iv"])), only_if=lambda backend: backend.cipher_supported( algorithms.Blowfish("\x00" * 56), modes.OFB("\x00" * 8) ), @@ -63,8 +69,10 @@ class TestBlowfish(object): load_nist_vectors, os.path.join("ciphers", "Blowfish"), ["bf-cfb.txt"], - lambda key, iv: algorithms.Blowfish(binascii.unhexlify(key)), - lambda key, iv: modes.CFB(binascii.unhexlify(iv)), + lambda **kwargs: algorithms.Blowfish( + binascii.unhexlify(kwargs["key"]) + ), + lambda **kwargs: modes.CFB(binascii.unhexlify(kwargs["iv"])), only_if=lambda backend: backend.cipher_supported( algorithms.Blowfish("\x00" * 56), modes.CFB("\x00" * 8) ), diff --git a/tests/hazmat/primitives/test_camellia.py b/tests/hazmat/primitives/test_camellia.py index a2c935d9..e11d590a 100644 --- a/tests/hazmat/primitives/test_camellia.py +++ b/tests/hazmat/primitives/test_camellia.py @@ -33,8 +33,10 @@ class TestCamellia(object): "camellia-192-ecb.txt", "camellia-256-ecb.txt" ], - lambda key: algorithms.Camellia(binascii.unhexlify((key))), - lambda key: modes.ECB(), + lambda **kwargs: algorithms.Camellia( + binascii.unhexlify((kwargs["key"])) + ), + lambda **kwargs: modes.ECB(), only_if=lambda backend: backend.cipher_supported( algorithms.Camellia("\x00" * 16), modes.ECB() ), @@ -45,8 +47,10 @@ class TestCamellia(object): load_openssl_vectors, os.path.join("ciphers", "Camellia"), ["camellia-cbc.txt"], - lambda key, iv: algorithms.Camellia(binascii.unhexlify(key)), - lambda key, iv: modes.CBC(binascii.unhexlify(iv)), + lambda **kwargs: algorithms.Camellia( + binascii.unhexlify((kwargs["key"])) + ), + lambda **kwargs: modes.CBC(binascii.unhexlify(kwargs["iv"])), only_if=lambda backend: backend.cipher_supported( algorithms.Camellia("\x00" * 16), modes.CBC("\x00" * 16) ), @@ -57,8 +61,10 @@ class TestCamellia(object): load_openssl_vectors, os.path.join("ciphers", "Camellia"), ["camellia-ofb.txt"], - lambda key, iv: algorithms.Camellia(binascii.unhexlify(key)), - lambda key, iv: modes.OFB(binascii.unhexlify(iv)), + lambda **kwargs: algorithms.Camellia( + binascii.unhexlify((kwargs["key"])) + ), + lambda **kwargs: modes.OFB(binascii.unhexlify(kwargs["iv"])), only_if=lambda backend: backend.cipher_supported( algorithms.Camellia("\x00" * 16), modes.OFB("\x00" * 16) ), @@ -69,8 +75,10 @@ class TestCamellia(object): load_openssl_vectors, os.path.join("ciphers", "Camellia"), ["camellia-cfb.txt"], - lambda key, iv: algorithms.Camellia(binascii.unhexlify(key)), - lambda key, iv: modes.CFB(binascii.unhexlify(iv)), + lambda **kwargs: algorithms.Camellia( + binascii.unhexlify((kwargs["key"])) + ), + lambda **kwargs: modes.CFB(binascii.unhexlify(kwargs["iv"])), only_if=lambda backend: backend.cipher_supported( algorithms.Camellia("\x00" * 16), modes.CFB("\x00" * 16) ), diff --git a/tests/hazmat/primitives/test_cast5.py b/tests/hazmat/primitives/test_cast5.py index a283dafc..10c6ef39 100644 --- a/tests/hazmat/primitives/test_cast5.py +++ b/tests/hazmat/primitives/test_cast5.py @@ -27,8 +27,8 @@ class TestCAST5(object): load_nist_vectors, os.path.join("ciphers", "CAST5"), ["cast5-ecb.txt"], - lambda key: algorithms.CAST5(binascii.unhexlify((key))), - lambda key: modes.ECB(), + lambda **kwargs: algorithms.CAST5(binascii.unhexlify((kwargs["key"]))), + lambda **kwargs: modes.ECB(), only_if=lambda backend: backend.cipher_supported( algorithms.CAST5("\x00" * 16), modes.ECB() ), diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index 758e755c..227a4055 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -44,8 +44,8 @@ def encrypt_test(backend, cipher_factory, mode_factory, params, only_if, skip_message): if not only_if(backend): pytest.skip(skip_message) - plaintext = params.pop("plaintext") - ciphertext = params.pop("ciphertext") + plaintext = params["plaintext"] + ciphertext = params["ciphertext"] cipher = Cipher( cipher_factory(**params), mode_factory(**params), @@ -84,9 +84,9 @@ def aead_test(backend, cipher_factory, mode_factory, params, only_if, 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") + plaintext = params["pt"] + ciphertext = params["ct"] + aad = params["aad"] if params.get("fail") is True: cipher = Cipher( cipher_factory(binascii.unhexlify(params["key"])), @@ -145,9 +145,9 @@ def stream_encryption_test(backend, cipher_factory, params, only_if, skip_message): if not only_if(backend): pytest.skip(skip_message) - plaintext = params.pop("plaintext") - ciphertext = params.pop("ciphertext") - offset = params.pop("offset") + plaintext = params["plaintext"] + ciphertext = params["ciphertext"] + offset = params["offset"] cipher = Cipher(cipher_factory(**params), None, backend=backend) encryptor = cipher.encryptor() # throw away offset bytes -- cgit v1.2.3 From 687d0f849fd88eeaa6fe8968091a9d79b7f96901 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 21 Dec 2013 10:53:50 -0600 Subject: use both kwargs and named args in lambdas for clarity --- tests/hazmat/primitives/test_3des.py | 42 ++++++++++++++------------------ tests/hazmat/primitives/test_aes.py | 18 +++++++------- tests/hazmat/primitives/test_arc4.py | 2 +- tests/hazmat/primitives/test_blowfish.py | 22 ++++++----------- tests/hazmat/primitives/test_camellia.py | 22 ++++++----------- tests/hazmat/primitives/test_cast5.py | 2 +- 6 files changed, 43 insertions(+), 65 deletions(-) diff --git a/tests/hazmat/primitives/test_3des.py b/tests/hazmat/primitives/test_3des.py index 35745310..0db56f47 100644 --- a/tests/hazmat/primitives/test_3des.py +++ b/tests/hazmat/primitives/test_3des.py @@ -37,10 +37,8 @@ class TestTripleDES_CBC(object): "TCBCvarkey.rsp", "TCBCvartext.rsp", ], - lambda **kwargs: algorithms.TripleDES( - binascii.unhexlify(kwargs["keys"]) - ), - lambda **kwargs: modes.CBC(binascii.unhexlify(kwargs["iv"])), + lambda keys, **kwargs: algorithms.TripleDES(binascii.unhexlify(keys)), + lambda iv, **kwargs: modes.CBC(binascii.unhexlify(iv)), ) test_MMT = generate_encrypt_test( @@ -51,10 +49,10 @@ class TestTripleDES_CBC(object): "TCBCMMT2.rsp", "TCBCMMT3.rsp", ], - lambda **kwargs: algorithms.TripleDES(binascii.unhexlify( - kwargs["key1"] + kwargs["key2"] + kwargs["key3"] - )), - lambda **kwargs: modes.CBC(binascii.unhexlify(kwargs["iv"])), + lambda key1, key2, key3, **kwargs: algorithms.TripleDES( + binascii.unhexlify(key1 + key2 + key3) + ), + lambda iv, **kwargs: modes.CBC(binascii.unhexlify(iv)), ) @@ -69,10 +67,8 @@ class TestTripleDES_OFB(object): "TOFBvartext.rsp", "TOFBinvperm.rsp", ], - lambda **kwargs: algorithms.TripleDES( - binascii.unhexlify(kwargs["keys"]) - ), - lambda **kwargs: modes.OFB(binascii.unhexlify(kwargs["iv"])), + lambda keys, **kwargs: algorithms.TripleDES(binascii.unhexlify(keys)), + lambda iv, **kwargs: modes.OFB(binascii.unhexlify(iv)), ) test_MMT = generate_encrypt_test( @@ -83,10 +79,10 @@ class TestTripleDES_OFB(object): "TOFBMMT2.rsp", "TOFBMMT3.rsp", ], - lambda **kwargs: algorithms.TripleDES(binascii.unhexlify( - kwargs["key1"] + kwargs["key2"] + kwargs["key3"] - )), - lambda **kwargs: modes.OFB(binascii.unhexlify(kwargs["iv"])), + lambda key1, key2, key3, **kwargs: algorithms.TripleDES( + binascii.unhexlify(key1 + key2 + key3) + ), + lambda iv, **kwargs: modes.OFB(binascii.unhexlify(iv)), ) @@ -101,10 +97,8 @@ class TestTripleDES_CFB(object): "TCFB64varkey.rsp", "TCFB64vartext.rsp", ], - lambda **kwargs: algorithms.TripleDES( - binascii.unhexlify(kwargs["keys"]) - ), - lambda **kwargs: modes.CFB(binascii.unhexlify(kwargs["iv"])), + lambda keys, **kwargs: algorithms.TripleDES(binascii.unhexlify(keys)), + lambda iv, **kwargs: modes.CFB(binascii.unhexlify(iv)), ) test_MMT = generate_encrypt_test( @@ -115,8 +109,8 @@ class TestTripleDES_CFB(object): "TCFB64MMT2.rsp", "TCFB64MMT3.rsp", ], - lambda **kwargs: algorithms.TripleDES(binascii.unhexlify( - kwargs["key1"] + kwargs["key2"] + kwargs["key3"] - )), - lambda **kwargs: modes.CFB(binascii.unhexlify(kwargs["iv"])), + lambda key1, key2, key3, **kwargs: algorithms.TripleDES( + binascii.unhexlify(key1 + key2 + key3) + ), + lambda iv, **kwargs: modes.CFB(binascii.unhexlify(iv)), ) diff --git a/tests/hazmat/primitives/test_aes.py b/tests/hazmat/primitives/test_aes.py index d706cbd8..9e5a3cb5 100644 --- a/tests/hazmat/primitives/test_aes.py +++ b/tests/hazmat/primitives/test_aes.py @@ -45,8 +45,8 @@ class TestAES(object): "CBCMMT192.rsp", "CBCMMT256.rsp", ], - lambda **kwargs: algorithms.AES(binascii.unhexlify(kwargs["key"])), - lambda **kwargs: modes.CBC(binascii.unhexlify(kwargs["iv"])), + lambda key, **kwargs: algorithms.AES(binascii.unhexlify(key)), + lambda iv, **kwargs: modes.CBC(binascii.unhexlify(iv)), ) test_ECB = generate_encrypt_test( @@ -69,7 +69,7 @@ class TestAES(object): "ECBMMT192.rsp", "ECBMMT256.rsp", ], - lambda **kwargs: algorithms.AES(binascii.unhexlify(kwargs["key"])), + lambda key, **kwargs: algorithms.AES(binascii.unhexlify(key)), lambda **kwargs: modes.ECB(), ) @@ -93,8 +93,8 @@ class TestAES(object): "OFBMMT192.rsp", "OFBMMT256.rsp", ], - lambda **kwargs: algorithms.AES(binascii.unhexlify(kwargs["key"])), - lambda **kwargs: modes.OFB(binascii.unhexlify(kwargs["iv"])), + lambda key, **kwargs: algorithms.AES(binascii.unhexlify(key)), + lambda iv, **kwargs: modes.OFB(binascii.unhexlify(iv)), ) test_CFB = generate_encrypt_test( @@ -117,16 +117,16 @@ class TestAES(object): "CFB128MMT192.rsp", "CFB128MMT256.rsp", ], - lambda **kwargs: algorithms.AES(binascii.unhexlify(kwargs["key"])), - lambda **kwargs: modes.CFB(binascii.unhexlify(kwargs["iv"])), + lambda key, **kwargs: algorithms.AES(binascii.unhexlify(key)), + lambda iv, **kwargs: modes.CFB(binascii.unhexlify(iv)), ) test_CTR = generate_encrypt_test( load_openssl_vectors, os.path.join("ciphers", "AES", "CTR"), ["aes-128-ctr.txt", "aes-192-ctr.txt", "aes-256-ctr.txt"], - lambda **kwargs: algorithms.AES(binascii.unhexlify(kwargs["key"])), - lambda **kwargs: modes.CTR(binascii.unhexlify(kwargs["iv"])), + lambda key, **kwargs: algorithms.AES(binascii.unhexlify(key)), + lambda iv, **kwargs: modes.CTR(binascii.unhexlify(iv)), only_if=lambda backend: backend.cipher_supported( algorithms.AES("\x00" * 16), modes.CTR("\x00" * 16) ), diff --git a/tests/hazmat/primitives/test_arc4.py b/tests/hazmat/primitives/test_arc4.py index 7ce93061..a9ef2bbe 100644 --- a/tests/hazmat/primitives/test_arc4.py +++ b/tests/hazmat/primitives/test_arc4.py @@ -35,7 +35,7 @@ class TestARC4(object): "rfc-6229-192.txt", "rfc-6229-256.txt", ], - lambda **kwargs: algorithms.ARC4(binascii.unhexlify((kwargs["key"]))), + lambda key, **kwargs: algorithms.ARC4(binascii.unhexlify(key)), only_if=lambda backend: backend.cipher_supported( algorithms.ARC4("\x00" * 16), None ), diff --git a/tests/hazmat/primitives/test_blowfish.py b/tests/hazmat/primitives/test_blowfish.py index 3e0e9025..065855d7 100644 --- a/tests/hazmat/primitives/test_blowfish.py +++ b/tests/hazmat/primitives/test_blowfish.py @@ -27,9 +27,7 @@ class TestBlowfish(object): load_nist_vectors, os.path.join("ciphers", "Blowfish"), ["bf-ecb.txt"], - lambda **kwargs: algorithms.Blowfish( - binascii.unhexlify(kwargs["key"]) - ), + lambda key, **kwargs: algorithms.Blowfish(binascii.unhexlify(key)), lambda **kwargs: modes.ECB(), only_if=lambda backend: backend.cipher_supported( algorithms.Blowfish("\x00" * 56), modes.ECB() @@ -41,10 +39,8 @@ class TestBlowfish(object): load_nist_vectors, os.path.join("ciphers", "Blowfish"), ["bf-cbc.txt"], - lambda **kwargs: algorithms.Blowfish( - binascii.unhexlify(kwargs["key"]) - ), - lambda **kwargs: modes.CBC(binascii.unhexlify(kwargs["iv"])), + lambda key, **kwargs: algorithms.Blowfish(binascii.unhexlify(key)), + lambda iv, **kwargs: modes.CBC(binascii.unhexlify(iv)), only_if=lambda backend: backend.cipher_supported( algorithms.Blowfish("\x00" * 56), modes.CBC("\x00" * 8) ), @@ -55,10 +51,8 @@ class TestBlowfish(object): load_nist_vectors, os.path.join("ciphers", "Blowfish"), ["bf-ofb.txt"], - lambda **kwargs: algorithms.Blowfish( - binascii.unhexlify(kwargs["key"]) - ), - lambda **kwargs: modes.OFB(binascii.unhexlify(kwargs["iv"])), + lambda key, **kwargs: algorithms.Blowfish(binascii.unhexlify(key)), + lambda iv, **kwargs: modes.OFB(binascii.unhexlify(iv)), only_if=lambda backend: backend.cipher_supported( algorithms.Blowfish("\x00" * 56), modes.OFB("\x00" * 8) ), @@ -69,10 +63,8 @@ class TestBlowfish(object): load_nist_vectors, os.path.join("ciphers", "Blowfish"), ["bf-cfb.txt"], - lambda **kwargs: algorithms.Blowfish( - binascii.unhexlify(kwargs["key"]) - ), - lambda **kwargs: modes.CFB(binascii.unhexlify(kwargs["iv"])), + lambda key, **kwargs: algorithms.Blowfish(binascii.unhexlify(key)), + lambda iv, **kwargs: modes.CFB(binascii.unhexlify(iv)), only_if=lambda backend: backend.cipher_supported( algorithms.Blowfish("\x00" * 56), modes.CFB("\x00" * 8) ), diff --git a/tests/hazmat/primitives/test_camellia.py b/tests/hazmat/primitives/test_camellia.py index e11d590a..6e5fe682 100644 --- a/tests/hazmat/primitives/test_camellia.py +++ b/tests/hazmat/primitives/test_camellia.py @@ -33,9 +33,7 @@ class TestCamellia(object): "camellia-192-ecb.txt", "camellia-256-ecb.txt" ], - lambda **kwargs: algorithms.Camellia( - binascii.unhexlify((kwargs["key"])) - ), + lambda key, **kwargs: algorithms.Camellia(binascii.unhexlify(key)), lambda **kwargs: modes.ECB(), only_if=lambda backend: backend.cipher_supported( algorithms.Camellia("\x00" * 16), modes.ECB() @@ -47,10 +45,8 @@ class TestCamellia(object): load_openssl_vectors, os.path.join("ciphers", "Camellia"), ["camellia-cbc.txt"], - lambda **kwargs: algorithms.Camellia( - binascii.unhexlify((kwargs["key"])) - ), - lambda **kwargs: modes.CBC(binascii.unhexlify(kwargs["iv"])), + lambda key, **kwargs: algorithms.Camellia(binascii.unhexlify(key)), + lambda iv, **kwargs: modes.CBC(binascii.unhexlify(iv)), only_if=lambda backend: backend.cipher_supported( algorithms.Camellia("\x00" * 16), modes.CBC("\x00" * 16) ), @@ -61,10 +57,8 @@ class TestCamellia(object): load_openssl_vectors, os.path.join("ciphers", "Camellia"), ["camellia-ofb.txt"], - lambda **kwargs: algorithms.Camellia( - binascii.unhexlify((kwargs["key"])) - ), - lambda **kwargs: modes.OFB(binascii.unhexlify(kwargs["iv"])), + lambda key, **kwargs: algorithms.Camellia(binascii.unhexlify(key)), + lambda iv, **kwargs: modes.OFB(binascii.unhexlify(iv)), only_if=lambda backend: backend.cipher_supported( algorithms.Camellia("\x00" * 16), modes.OFB("\x00" * 16) ), @@ -75,10 +69,8 @@ class TestCamellia(object): load_openssl_vectors, os.path.join("ciphers", "Camellia"), ["camellia-cfb.txt"], - lambda **kwargs: algorithms.Camellia( - binascii.unhexlify((kwargs["key"])) - ), - lambda **kwargs: modes.CFB(binascii.unhexlify(kwargs["iv"])), + lambda key, **kwargs: algorithms.Camellia(binascii.unhexlify(key)), + lambda iv, **kwargs: modes.CFB(binascii.unhexlify(iv)), only_if=lambda backend: backend.cipher_supported( algorithms.Camellia("\x00" * 16), modes.CFB("\x00" * 16) ), diff --git a/tests/hazmat/primitives/test_cast5.py b/tests/hazmat/primitives/test_cast5.py index 10c6ef39..406f9b55 100644 --- a/tests/hazmat/primitives/test_cast5.py +++ b/tests/hazmat/primitives/test_cast5.py @@ -27,7 +27,7 @@ class TestCAST5(object): load_nist_vectors, os.path.join("ciphers", "CAST5"), ["cast5-ecb.txt"], - lambda **kwargs: algorithms.CAST5(binascii.unhexlify((kwargs["key"]))), + lambda key, **kwargs: algorithms.CAST5(binascii.unhexlify((key))), lambda **kwargs: modes.ECB(), only_if=lambda backend: backend.cipher_supported( algorithms.CAST5("\x00" * 16), modes.ECB() -- cgit v1.2.3 From 1b1327cfe537b9e7bdc271239d1025c2479239c3 Mon Sep 17 00:00:00 2001 From: Alex Stapleton Date: Sat, 21 Dec 2013 15:16:57 +0000 Subject: Raise UnsupportedAlgorithm when initing Hash() Instead of just an AssertionError. --- cryptography/hazmat/backends/openssl/backend.py | 6 +++++- docs/hazmat/primitives/cryptographic-hashes.rst | 3 +++ tests/hazmat/primitives/test_hashes.py | 14 ++++++++++++-- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index 588a4273..5b7cb3de 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -400,7 +400,11 @@ class _HashContext(object): self._backend.lib.EVP_MD_CTX_destroy) evp_md = self._backend.lib.EVP_get_digestbyname( algorithm.name.encode("ascii")) - assert evp_md != self._backend.ffi.NULL + if evp_md == self._backend.ffi.NULL: + raise UnsupportedAlgorithm( + "{0} is not a supported hash on this backend".format( + algorithm.name) + ) res = self._backend.lib.EVP_DigestInit_ex(ctx, evp_md, self._backend.ffi.NULL) assert res != 0 diff --git a/docs/hazmat/primitives/cryptographic-hashes.rst b/docs/hazmat/primitives/cryptographic-hashes.rst index 90ca198a..38347378 100644 --- a/docs/hazmat/primitives/cryptographic-hashes.rst +++ b/docs/hazmat/primitives/cryptographic-hashes.rst @@ -28,6 +28,9 @@ Message Digests >>> digest.finalize() 'l\xa1=R\xcap\xc8\x83\xe0\xf0\xbb\x10\x1eBZ\x89\xe8bM\xe5\x1d\xb2\xd29%\x93\xafj\x84\x11\x80\x90' + If the backend doesn't support the requested ``algorithm`` an + :class:`~cryptography.exceptions.UnsupportedAlgorithm` will be raised. + Keep in mind that attacks against cryptographic hashes only get stronger with time, and that often algorithms that were once thought to be strong, become broken. Because of this it's important to include a plan for diff --git a/tests/hazmat/primitives/test_hashes.py b/tests/hazmat/primitives/test_hashes.py index ff42e8f4..72bc3e27 100644 --- a/tests/hazmat/primitives/test_hashes.py +++ b/tests/hazmat/primitives/test_hashes.py @@ -19,12 +19,18 @@ import pytest import six -from cryptography.exceptions import AlreadyFinalized -from cryptography.hazmat.primitives import hashes +from cryptography import utils +from cryptography.exceptions import AlreadyFinalized, UnsupportedAlgorithm +from cryptography.hazmat.primitives import hashes, interfaces from .utils import generate_base_hash_test +@utils.register_interface(interfaces.HashAlgorithm) +class UnsupportedDummyHash(object): + name = "unsupported-dummy-hash" + + class TestHashContext(object): def test_hash_reject_unicode(self, backend): m = hashes.Hash(hashes.SHA1(), backend=backend) @@ -57,6 +63,10 @@ class TestHashContext(object): with pytest.raises(AlreadyFinalized): h.finalize() + def test_unsupported_hash(self, backend): + with pytest.raises(UnsupportedAlgorithm): + hashes.Hash(UnsupportedDummyHash(), backend) + class TestSHA1(object): test_SHA1 = generate_base_hash_test( -- cgit v1.2.3 From 447d64fb69e19c0059e3ba18ef3b1317a716a7c4 Mon Sep 17 00:00:00 2001 From: Alex Stapleton Date: Sat, 21 Dec 2013 21:26:55 +0000 Subject: Raise UnsupportedAlgorithm when initing HMACs --- cryptography/hazmat/backends/openssl/backend.py | 6 +++++- docs/hazmat/primitives/hmac.rst | 2 ++ tests/hazmat/primitives/test_hmac.py | 14 ++++++++++++-- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index 588a4273..94826874 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -442,7 +442,11 @@ class _HMACContext(object): ctx = self._backend.ffi.gc(ctx, self._backend.lib.HMAC_CTX_cleanup) evp_md = self._backend.lib.EVP_get_digestbyname( algorithm.name.encode('ascii')) - assert evp_md != self._backend.ffi.NULL + if evp_md == self._backend.ffi.NULL: + raise UnsupportedAlgorithm( + "{0} is not a supported hash on this backend".format( + algorithm.name) + ) res = self._backend.lib.Cryptography_HMAC_Init_ex( ctx, key, len(key), evp_md, self._backend.ffi.NULL ) diff --git a/docs/hazmat/primitives/hmac.rst b/docs/hazmat/primitives/hmac.rst index 0c0d0220..0547b7d2 100644 --- a/docs/hazmat/primitives/hmac.rst +++ b/docs/hazmat/primitives/hmac.rst @@ -34,6 +34,8 @@ message. >>> h.finalize() '#F\xdaI\x8b"e\xc4\xf1\xbb\x9a\x8fc\xff\xf5\xdex.\xbc\xcd/+\x8a\x86\x1d\x84\'\xc3\xa6\x1d\xd8J' + If the backend doesn't support the requested ``algorithm`` an + :class:`~cryptography.exceptions.UnsupportedAlgorithm` will be raised. :param key: Secret key as ``bytes``. :param algorithm: A diff --git a/tests/hazmat/primitives/test_hmac.py b/tests/hazmat/primitives/test_hmac.py index 992bcb1a..124c4377 100644 --- a/tests/hazmat/primitives/test_hmac.py +++ b/tests/hazmat/primitives/test_hmac.py @@ -19,12 +19,18 @@ import pytest import six -from cryptography.exceptions import AlreadyFinalized -from cryptography.hazmat.primitives import hashes, hmac +from cryptography import utils +from cryptography.exceptions import AlreadyFinalized, UnsupportedAlgorithm +from cryptography.hazmat.primitives import hashes, hmac, interfaces from .utils import generate_base_hmac_test +@utils.register_interface(interfaces.HashAlgorithm) +class UnsupportedDummyHash(object): + name = "unsupported-dummy-hash" + + class TestHMAC(object): test_copy = generate_base_hmac_test( hashes.MD5(), @@ -63,3 +69,7 @@ class TestHMAC(object): with pytest.raises(AlreadyFinalized): h.finalize() + + def test_unsupported_hash(self, backend): + with pytest.raises(UnsupportedAlgorithm): + hmac.HMAC(b"key", UnsupportedDummyHash(), backend) -- cgit v1.2.3 From f7b4ede584f5612546a07eb085eb5672629dcb96 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 21 Dec 2013 17:25:19 -0600 Subject: restrict gcm tags to a minimum of 4 bytes in length --- cryptography/hazmat/backends/openssl/backend.py | 6 +++--- tests/hazmat/primitives/utils.py | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index 5b7cb3de..559ace7e 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -319,9 +319,9 @@ class _CipherContext(object): ) assert res != 0 if operation == self._DECRYPT: - if not mode.tag: - raise ValueError("Authentication tag must be supplied " - "when decrypting") + if not mode.tag or len(mode.tag) < 4: + raise ValueError("Authentication tag must be provided " + "and >= 4 bytes when decrypting") res = self._backend.lib.EVP_CIPHER_CTX_ctrl( ctx, self._backend.lib.Cryptography_EVP_CTRL_GCM_SET_TAG, len(mode.tag), mode.tag diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index 227a4055..b00d3184 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -359,6 +359,13 @@ def aead_tag_exception_test(backend, cipher_factory, mode_factory, 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"000"), + backend + ) with pytest.raises(ValueError): cipher.decryptor() cipher = Cipher( -- cgit v1.2.3 From ca73504e62e2c55a7235f94c78cb8ee4d3718590 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 21 Dec 2013 17:31:48 -0600 Subject: add note regarding not truncating tags --- docs/hazmat/primitives/symmetric-encryption.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index f4d0457a..8ed64c7c 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -352,6 +352,11 @@ Modes Do not reuse an ``initialization_vector`` with a given ``key``. + .. note:: + + Do not truncate the GCM authentication tag unless absolutely necessary. + If you must truncate the minimum allowable length is 4 bytes. + :param bytes tag: The tag bytes to verify during decryption. When encrypting this must be None. -- cgit v1.2.3 From a7fbf07a3e96133b40df05ac5be159bbf6f1fc91 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 21 Dec 2013 18:12:25 -0600 Subject: doc updates --- cryptography/hazmat/backends/openssl/backend.py | 2 +- docs/hazmat/primitives/symmetric-encryption.rst | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index 559ace7e..9697a4a6 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -321,7 +321,7 @@ class _CipherContext(object): if operation == self._DECRYPT: if not mode.tag or len(mode.tag) < 4: raise ValueError("Authentication tag must be provided " - "and >= 4 bytes when decrypting") + "and 4 bytes or longer when decrypting") res = self._backend.lib.EVP_CIPHER_CTX_ctrl( ctx, self._backend.lib.Cryptography_EVP_CTRL_GCM_SET_TAG, len(mode.tag), mode.tag diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index 8ed64c7c..85d7d5b1 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -354,8 +354,10 @@ Modes .. note:: - Do not truncate the GCM authentication tag unless absolutely necessary. - If you must truncate the minimum allowable length is 4 bytes. + `NIST SP-800-38D`_ recommends that GCM tags be 128, 120, 122, 104, or + 96-bits in length. Tags are shortened by truncating bytes. Longer tags + provide better security margins. If you must shorten the tag the minimum + allowed length is 4 bytes (32 bits). :param bytes tag: The tag bytes to verify during decryption. When encrypting this must be None. @@ -395,3 +397,4 @@ Insecure Modes .. _`described by Colin Percival`: http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html .. _`recommends 96-bit IV length`: http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf +.. _`NIST SP-800-38D`: http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf -- cgit v1.2.3 From fc73e2d04315e21011869fbd925df9e7a99d21ae Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 21 Dec 2013 18:41:38 -0600 Subject: prose updates for GCM tag --- cryptography/hazmat/backends/openssl/backend.py | 4 ++-- docs/hazmat/primitives/symmetric-encryption.rst | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index 9697a4a6..b0ea96ea 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -320,8 +320,8 @@ class _CipherContext(object): assert res != 0 if operation == self._DECRYPT: if not mode.tag or len(mode.tag) < 4: - raise ValueError("Authentication tag must be provided " - "and 4 bytes or longer when decrypting") + raise ValueError("Authentication tag must be provided and " + "be 4 bytes or longer when decrypting") res = self._backend.lib.EVP_CIPHER_CTX_ctrl( ctx, self._backend.lib.Cryptography_EVP_CTRL_GCM_SET_TAG, len(mode.tag), mode.tag diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index 85d7d5b1..f009bb78 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -354,10 +354,12 @@ Modes .. note:: - `NIST SP-800-38D`_ recommends that GCM tags be 128, 120, 122, 104, or - 96-bits in length. Tags are shortened by truncating bytes. Longer tags - provide better security margins. If you must shorten the tag the minimum - allowed length is 4 bytes (32 bits). + Cryptography will emit a 128-bit tag when finalizing encryption. + You can shorten a tag by truncating it to the desired length, but this + is **not recommended** as it lowers the security margins of the + authentication (`NIST SP-800-38D`_ recommends 96-bit or greater). + If you must shorten the tag the minimum allowed length is 4 bytes + (32 bit). :param bytes tag: The tag bytes to verify during decryption. When encrypting this must be None. -- cgit v1.2.3 From 048d6cb43a0757f3b4cca385e788d30173ebcb17 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 21 Dec 2013 18:53:19 -0600 Subject: a few more doc changes to gcm tag info --- docs/hazmat/primitives/symmetric-encryption.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index f009bb78..6e3c1024 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -357,9 +357,10 @@ Modes Cryptography will emit a 128-bit tag when finalizing encryption. You can shorten a tag by truncating it to the desired length, but this is **not recommended** as it lowers the security margins of the - authentication (`NIST SP-800-38D`_ recommends 96-bit or greater). + authentication (`NIST SP-800-38D`_ recommends 96-bits or greater). If you must shorten the tag the minimum allowed length is 4 bytes - (32 bit). + (32-bits). Applications **must** verify the tag is the expected length + to guarantee the expected security margin. :param bytes tag: The tag bytes to verify during decryption. When encrypting this must be None. -- cgit v1.2.3 From 15cf6b995624e938209e611f3953dd8dbb7a57b8 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 21 Dec 2013 19:22:39 -0800 Subject: A handful of cleanups and rewordings to the docs --- docs/contributing.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/contributing.rst b/docs/contributing.rst index cb9c7283..f176393f 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -53,11 +53,10 @@ API Considerations Most projects' APIs are designed with a philosophy of "make easy things easy, and make hard things possible". One of the perils of writing cryptographic code -is that code that is secure looks just like code that isn't, and produces -results that are also difficult to distinguish. As a result ``cryptography`` -has, as a design philosophy: "make it hard to do insecure things". Here are a -few strategies for API design which should be both followed, and should inspire -other API choices: +is that secure code looks just like insecure code, and it's results are almost +always indistinguishable. As a result ``cryptography`` has, as a design +philosophy: "make it hard to do insecure things". Here are a few strategies for +API design which should be both followed, and should inspire other API choices: If it is incorrect to ignore the result of a method, it should raise an exception, and not return a boolean ``True``/``False`` flag. For example, a @@ -163,7 +162,7 @@ as much as possible. To that end: * When documenting a generic interface, use a strong algorithm in examples. (e.g. when showing a hashing example, don't use - :class:`cryptography.hazmat.primitives.hashes.MD5`) + :class:`~cryptography.hazmat.primitives.hashes.MD5`) * When giving prescriptive advice, always provide references and supporting material. * When there is real disagreement between cryptographic experts, represent both @@ -206,7 +205,7 @@ automatically, so all you have to do is: $ py.test ... - 4294 passed in 15.24 seconds + 62746 passed in 220.43 seconds This runs the tests with the default Python interpreter. @@ -244,7 +243,8 @@ Use `tox`_ to build the documentation. For example: docs: commands succeeded congratulations :) -The HTML documentation index can now be found at ``docs/_build/html/index.html`` +The HTML documentation index can now be found at +``docs/_build/html/index.html``. .. _`GitHub`: https://github.com/pyca/cryptography -- cgit v1.2.3 From 6955ea32cdfbc8719c5f4ae9c55c989787553a97 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 21 Dec 2013 19:26:19 -0800 Subject: Recommend that recipes include a version --- docs/contributing.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/contributing.rst b/docs/contributing.rst index cb9c7283..cec067ca 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -77,6 +77,10 @@ whether the signature was valid. if not is_valid: raise InvalidSignature +Every recipe should include a version or algorithmic marker of some sort in its +output in order to allow transparent upgrading of the algorithms in use, as +the algorithms or parameters needed to achieve a given security margin evolve. + APIs at the :doc:`/hazmat/primitives/index` layer should always take an explicit backend, APIs at the recipes layer should automatically use the :func:`~cryptography.hazmat.backends.default_backend`, but optionally allow -- cgit v1.2.3 From 95243f5b34f6cdfc16fb95669efbe2a61ac81179 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 21 Dec 2013 19:37:24 -0800 Subject: English, how does it work? --- docs/contributing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing.rst b/docs/contributing.rst index f176393f..b1702df8 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -53,7 +53,7 @@ API Considerations Most projects' APIs are designed with a philosophy of "make easy things easy, and make hard things possible". One of the perils of writing cryptographic code -is that secure code looks just like insecure code, and it's results are almost +is that secure code looks just like insecure code, and its results are almost always indistinguishable. As a result ``cryptography`` has, as a design philosophy: "make it hard to do insecure things". Here are a few strategies for API design which should be both followed, and should inspire other API choices: -- cgit v1.2.3 From 35cb3659bcf97eea22ce1ad14b7fc3d0913d2be2 Mon Sep 17 00:00:00 2001 From: Alex Stapleton Date: Sat, 21 Dec 2013 16:29:45 +0000 Subject: UnsupportedAlgorithm error messages for Ciphers --- cryptography/hazmat/backends/openssl/backend.py | 12 ++++++++++-- docs/hazmat/primitives/symmetric-encryption.rst | 2 +- tests/hazmat/backends/test_openssl.py | 12 +++++++----- tests/hazmat/primitives/test_block.py | 12 +++++++++--- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index 588a4273..714823e9 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -288,11 +288,19 @@ class _CipherContext(object): try: adapter = registry[type(cipher), type(mode)] except KeyError: - raise UnsupportedAlgorithm + raise UnsupportedAlgorithm( + "cipher {0} in {1} mode is not supported " + "by this backend".format( + cipher.name, mode.name if mode else mode) + ) evp_cipher = adapter(self._backend, cipher, mode) if evp_cipher == self._backend.ffi.NULL: - raise UnsupportedAlgorithm + raise UnsupportedAlgorithm( + "cipher {0} in {1} mode is not supported " + "by this backend".format( + cipher.name, mode.name if mode else mode) + ) if isinstance(mode, interfaces.ModeWithInitializationVector): iv_nonce = mode.initialization_vector diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index f4d0457a..dfadd895 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -61,7 +61,7 @@ an "encrypt-then-MAC" formulation as `described by Colin Percival`_. provider. If the backend doesn't support the requested combination of ``cipher`` - and ``mode`` an :class:`cryptography.exceptions.UnsupportedAlgorithm` + and ``mode`` an :class:`~cryptography.exceptions.UnsupportedAlgorithm` will be raised. .. method:: decryptor() diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index 962959b9..543a05fe 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -23,13 +23,14 @@ from cryptography.hazmat.primitives.ciphers.algorithms import AES from cryptography.hazmat.primitives.ciphers.modes import CBC +@utils.register_interface(interfaces.Mode) class DummyMode(object): - pass + name = "dummy-mode" @utils.register_interface(interfaces.CipherAlgorithm) class DummyCipher(object): - pass + name = "dummy-cipher" class TestOpenSSL(object): @@ -62,15 +63,16 @@ class TestOpenSSL(object): assert b.ffi is backend.ffi assert b.lib is backend.lib - def test_nonexistent_cipher(self): + @pytest.mark.parametrize("mode", [DummyMode(), None]) + def test_nonexistent_cipher(self, mode): b = Backend() b.register_cipher_adapter( DummyCipher, - DummyMode, + type(mode), lambda backend, cipher, mode: backend.ffi.NULL ) cipher = Cipher( - DummyCipher(), DummyMode(), backend=b, + DummyCipher(), mode, backend=b, ) with pytest.raises(UnsupportedAlgorithm): cipher.encryptor() diff --git a/tests/hazmat/primitives/test_block.py b/tests/hazmat/primitives/test_block.py index 02de3861..573f5633 100644 --- a/tests/hazmat/primitives/test_block.py +++ b/tests/hazmat/primitives/test_block.py @@ -31,9 +31,14 @@ from .utils import ( ) +@utils.register_interface(interfaces.Mode) +class DummyMode(object): + name = "dummy-mode" + + @utils.register_interface(interfaces.CipherAlgorithm) class DummyCipher(object): - pass + name = "dummy-cipher" class TestCipher(object): @@ -101,9 +106,10 @@ class TestCipherContext(object): assert pt == b"a" * 80 decryptor.finalize() - def test_nonexistent_cipher(self, backend): + @pytest.mark.parametrize("mode", [DummyMode(), None]) + def test_nonexistent_cipher(self, backend, mode): cipher = Cipher( - DummyCipher(), object(), backend + DummyCipher(), mode, backend ) with pytest.raises(UnsupportedAlgorithm): cipher.encryptor() -- cgit v1.2.3 From b32c90c00975c95ae6c00d232b39e8eff6339243 Mon Sep 17 00:00:00 2001 From: cyli Date: Sun, 22 Dec 2013 15:51:50 -0800 Subject: Change the Cryptography-specific variable names --- cryptography/hazmat/backends/openssl/ssl.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index 7e7de5ce..76bb8363 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -17,10 +17,10 @@ INCLUDES = """ TYPES = """ /* Internally invented symbol to tell us if SSLv2 is supported */ -static const int Cryptography_NO_SSL2; +static const int Cryptography_HAS_SSL2; /* Internally invented symbol to tell us if SNI is supported */ -static const int Cryptography_TLSEXT_HOSTNAME; +static const int Cryptography_HAS_TLSEXT_HOSTNAME; static const int SSL_FILETYPE_PEM; static const int SSL_FILETYPE_ASN1; @@ -244,18 +244,18 @@ void SSL_CTX_set_tlsext_servername_callback( CUSTOMIZATIONS = """ #ifdef OPENSSL_NO_SSL2 -static const int Cryptography_NO_SSL2 = 1; +static const int Cryptography_HAS_SSL2 = 0; SSL_METHOD* (*SSLv2_method)() = NULL; SSL_METHOD* (*SSLv2_client_method)() = NULL; SSL_METHOD* (*SSLv2_server_method)() = NULL; #else -static const int Cryptography_NO_SSL2 = 0; +static const int Cryptography_HAS_SSL2 = 1; #endif #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME -static const int Cryptography_TLSEXT_HOSTNAME = 1; +static const int Cryptography_HAS_TLSEXT_HOSTNAME = 1; #else -static const int Cryptography_TLSEXT_HOSTNAME = 0; +static const int Cryptography_HAS_TLSEXT_HOSTNAME = 0; void (*SSL_set_tlsext_host_name)(SSL *, char *) = NULL; const char* (*SSL_get_servername)(const SSL *, const int) = NULL; void (*SSL_CTX_set_tlsext_servername_callback)( -- cgit v1.2.3 From 6fd76ba7a5f7810757f4c2c5f0b07cf947dd2315 Mon Sep 17 00:00:00 2001 From: cyli Date: Sun, 22 Dec 2013 16:26:44 -0800 Subject: Remove some extra parameters in function declarations --- cryptography/hazmat/backends/openssl/ssl.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index 76bb8363..e478f65e 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -132,7 +132,7 @@ int SSL_get_verify_mode(const SSL *); void SSL_set_verify_depth(SSL *, int); int SSL_get_verify_depth(const SSL *); int (*SSL_get_verify_callback(const SSL *))(int, X509_STORE_CTX *); -void SSL_set_info_callback(SSL *, void (*callback)()); +void SSL_set_info_callback(SSL *, void (*)()); void (*SSL_get_info_callback(const SSL *))(); SSL *SSL_new(SSL_CTX *); void SSL_free(SSL *); @@ -155,10 +155,10 @@ const char *SSL_get_cipher_list(const SSL *, int); void SSL_CTX_free(SSL_CTX *); long SSL_CTX_set_timeout(SSL_CTX *, long); int SSL_CTX_set_default_verify_paths(SSL_CTX *); -void SSL_CTX_set_verify(SSL_CTX *, int, int (*callback)(int, X509_STORE_CTX *)); +void SSL_CTX_set_verify(SSL_CTX *, int, int (*)(int, X509_STORE_CTX *)); void SSL_CTX_set_verify_depth(SSL_CTX *, int); int (*SSL_CTX_get_verify_callback(const SSL_CTX *))(int, X509_STORE_CTX *); -void SSL_CTX_set_info_callback(SSL_CTX *, void (*cb)(const SSL *, int, int)); +void SSL_CTX_set_info_callback(SSL_CTX *, void (*)(const SSL *, int, int)); void (*SSL_CTX_get_info_callback(SSL_CTX *))(const SSL *, int, int); int SSL_CTX_get_verify_mode(const SSL_CTX *); int SSL_CTX_get_verify_depth(const SSL_CTX *); @@ -239,7 +239,7 @@ long SSL_CTX_get_timeout(const SSL_CTX *); void SSL_set_tlsext_host_name(SSL *, char *); void SSL_CTX_set_tlsext_servername_callback( SSL_CTX *, - int (*cb)(const SSL *, int *, void *)); + int (*)(const SSL *, int *, void *)); """ CUSTOMIZATIONS = """ @@ -260,6 +260,6 @@ void (*SSL_set_tlsext_host_name)(SSL *, char *) = NULL; const char* (*SSL_get_servername)(const SSL *, const int) = NULL; void (*SSL_CTX_set_tlsext_servername_callback)( SSL_CTX *, - int (*cb)(const SSL *, int *, void *)) = NULL; + int (*)(const SSL *, int *, void *)) = NULL; #endif """ -- cgit v1.2.3 From f8540eb4b2366a64711d058896a8be91e2410fd4 Mon Sep 17 00:00:00 2001 From: cyli Date: Sun, 22 Dec 2013 17:15:05 -0800 Subject: Remove SSL_CTX_clear_options, since it doesn't seem to be in openssl 0.9.8 --- cryptography/hazmat/backends/openssl/ssl.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index e478f65e..4fc20ebc 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -198,7 +198,6 @@ int SSL_want_write(const SSL *); int SSL_total_renegotiations(const SSL *); long SSL_CTX_set_options(SSL_CTX *, long); -long SSL_CTX_clear_options(SSL_CTX *, long); long SSL_CTX_get_options(SSL_CTX *); long SSL_CTX_set_mode(SSL_CTX *, long); long SSL_CTX_get_mode(SSL_CTX *); -- cgit v1.2.3 From 7dc4a127e2fe5ec07ba94e96de00a6b2f65f4371 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 23 Dec 2013 07:53:34 -0800 Subject: Remove names from the backend that don't actually exist --- cryptography/hazmat/backends/openssl/asn1.py | 2 ++ cryptography/hazmat/backends/openssl/backend.py | 8 ++++++++ cryptography/hazmat/backends/openssl/bignum.py | 2 ++ cryptography/hazmat/backends/openssl/bio.py | 2 ++ cryptography/hazmat/backends/openssl/conf.py | 2 ++ cryptography/hazmat/backends/openssl/crypto.py | 2 ++ cryptography/hazmat/backends/openssl/dh.py | 2 ++ cryptography/hazmat/backends/openssl/dsa.py | 2 ++ cryptography/hazmat/backends/openssl/engine.py | 2 ++ cryptography/hazmat/backends/openssl/err.py | 2 ++ cryptography/hazmat/backends/openssl/evp.py | 10 ++++++++++ cryptography/hazmat/backends/openssl/hmac.py | 2 ++ cryptography/hazmat/backends/openssl/nid.py | 2 ++ cryptography/hazmat/backends/openssl/opensslv.py | 2 ++ cryptography/hazmat/backends/openssl/pem.py | 2 ++ cryptography/hazmat/backends/openssl/pkcs12.py | 2 ++ cryptography/hazmat/backends/openssl/pkcs7.py | 2 ++ cryptography/hazmat/backends/openssl/rand.py | 2 ++ cryptography/hazmat/backends/openssl/rsa.py | 2 ++ cryptography/hazmat/backends/openssl/ssl.py | 12 ++++++++++++ cryptography/hazmat/backends/openssl/x509.py | 2 ++ cryptography/hazmat/backends/openssl/x509name.py | 2 ++ cryptography/hazmat/backends/openssl/x509v3.py | 2 ++ 23 files changed, 70 insertions(+) diff --git a/cryptography/hazmat/backends/openssl/asn1.py b/cryptography/hazmat/backends/openssl/asn1.py index c752e682..b56932fa 100644 --- a/cryptography/hazmat/backends/openssl/asn1.py +++ b/cryptography/hazmat/backends/openssl/asn1.py @@ -122,3 +122,5 @@ BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *, BIGNUM *); CUSTOMIZATIONS = """ """ + +CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index 080cb5f1..5d6b5bcc 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -141,6 +141,14 @@ class Backend(object): libraries=["crypto", "ssl"], ) + for name in cls._modules: + module_name = "cryptography.hazmat.backends.openssl." + name + __import__(module_name) + module = sys.modules[module_name] + for name, condition in module.CONDITIONAL_NAMES.items(): + if not getattr(lib, condition): + delattr(lib, name) + cls.ffi = ffi cls.lib = lib cls.lib.OpenSSL_add_all_algorithms() diff --git a/cryptography/hazmat/backends/openssl/bignum.py b/cryptography/hazmat/backends/openssl/bignum.py index 1b0fe5ab..68d0c3a2 100644 --- a/cryptography/hazmat/backends/openssl/bignum.py +++ b/cryptography/hazmat/backends/openssl/bignum.py @@ -38,3 +38,5 @@ MACROS = """ CUSTOMIZATIONS = """ """ + +CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/backends/openssl/bio.py b/cryptography/hazmat/backends/openssl/bio.py index c23dd0d8..d164804f 100644 --- a/cryptography/hazmat/backends/openssl/bio.py +++ b/cryptography/hazmat/backends/openssl/bio.py @@ -171,3 +171,5 @@ long BIO_set_buffer_read_data(BIO *, void *, long); CUSTOMIZATIONS = """ """ + +CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/backends/openssl/conf.py b/cryptography/hazmat/backends/openssl/conf.py index 4846252c..6d818cf1 100644 --- a/cryptography/hazmat/backends/openssl/conf.py +++ b/cryptography/hazmat/backends/openssl/conf.py @@ -27,3 +27,5 @@ MACROS = """ CUSTOMIZATIONS = """ """ + +CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/backends/openssl/crypto.py b/cryptography/hazmat/backends/openssl/crypto.py index 11e5f2f5..8d88c16e 100644 --- a/cryptography/hazmat/backends/openssl/crypto.py +++ b/cryptography/hazmat/backends/openssl/crypto.py @@ -40,3 +40,5 @@ void CRYPTO_malloc_debug_init(); CUSTOMIZATIONS = """ """ + +CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/backends/openssl/dh.py b/cryptography/hazmat/backends/openssl/dh.py index b8fbf368..56fa8b46 100644 --- a/cryptography/hazmat/backends/openssl/dh.py +++ b/cryptography/hazmat/backends/openssl/dh.py @@ -29,3 +29,5 @@ MACROS = """ CUSTOMIZATIONS = """ """ + +CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/backends/openssl/dsa.py b/cryptography/hazmat/backends/openssl/dsa.py index e6c369a6..3b77d7ae 100644 --- a/cryptography/hazmat/backends/openssl/dsa.py +++ b/cryptography/hazmat/backends/openssl/dsa.py @@ -31,3 +31,5 @@ MACROS = """ CUSTOMIZATIONS = """ """ + +CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/backends/openssl/engine.py b/cryptography/hazmat/backends/openssl/engine.py index 1f377665..cc214f84 100644 --- a/cryptography/hazmat/backends/openssl/engine.py +++ b/cryptography/hazmat/backends/openssl/engine.py @@ -63,3 +63,5 @@ MACROS = """ CUSTOMIZATIONS = """ """ + +CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/backends/openssl/err.py b/cryptography/hazmat/backends/openssl/err.py index f31c2405..2fb8bbe1 100644 --- a/cryptography/hazmat/backends/openssl/err.py +++ b/cryptography/hazmat/backends/openssl/err.py @@ -74,3 +74,5 @@ int ERR_FATAL_ERROR(unsigned long); CUSTOMIZATIONS = """ """ + +CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/backends/openssl/evp.py b/cryptography/hazmat/backends/openssl/evp.py index 8cb44610..fa35c6ac 100644 --- a/cryptography/hazmat/backends/openssl/evp.py +++ b/cryptography/hazmat/backends/openssl/evp.py @@ -35,6 +35,8 @@ static const int EVP_PKEY_DSA; static const int Cryptography_EVP_CTRL_GCM_SET_IVLEN; static const int Cryptography_EVP_CTRL_GCM_GET_TAG; static const int Cryptography_EVP_CTRL_GCM_SET_TAG; + +static const int Cryptography_HAS_GCM; """ FUNCTIONS = """ @@ -101,12 +103,20 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *, int, int, void *); CUSTOMIZATIONS = """ #ifdef EVP_CTRL_GCM_SET_TAG +const int Cryptography_HAS_GCM = 1; const int Cryptography_EVP_CTRL_GCM_GET_TAG = EVP_CTRL_GCM_GET_TAG; const int Cryptography_EVP_CTRL_GCM_SET_TAG = EVP_CTRL_GCM_SET_TAG; const int Cryptography_EVP_CTRL_GCM_SET_IVLEN = EVP_CTRL_GCM_SET_IVLEN; #else +const int Cryptography_HAS_GCM = 0; const int Cryptography_EVP_CTRL_GCM_GET_TAG = -1; const int Cryptography_EVP_CTRL_GCM_SET_TAG = -1; const int Cryptography_EVP_CTRL_GCM_SET_IVLEN = -1; #endif """ + +CONDITIONAL_NAMES = { + "Cryptography_EVP_CTRL_GCM_GET_TAG": "Cryptography_HAS_GCM", + "Cryptography_EVP_CTRL_GCM_SET_TAG": "Cryptography_HAS_GCM", + "Cryptography_EVP_CTRL_GCM_SET_IVLEN": "Cryptography_HAS_GCM", +} diff --git a/cryptography/hazmat/backends/openssl/hmac.py b/cryptography/hazmat/backends/openssl/hmac.py index 10e67141..5f9e0945 100644 --- a/cryptography/hazmat/backends/openssl/hmac.py +++ b/cryptography/hazmat/backends/openssl/hmac.py @@ -88,3 +88,5 @@ int Cryptography_HMAC_CTX_copy(HMAC_CTX *dst_ctx, HMAC_CTX *src_ctx) { #endif } """ + +CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/backends/openssl/nid.py b/cryptography/hazmat/backends/openssl/nid.py index 9816dde4..111f82f9 100644 --- a/cryptography/hazmat/backends/openssl/nid.py +++ b/cryptography/hazmat/backends/openssl/nid.py @@ -47,3 +47,5 @@ MACROS = """ CUSTOMIZATIONS = """ """ + +CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/backends/openssl/opensslv.py b/cryptography/hazmat/backends/openssl/opensslv.py index d463776c..37bbd2a7 100644 --- a/cryptography/hazmat/backends/openssl/opensslv.py +++ b/cryptography/hazmat/backends/openssl/opensslv.py @@ -27,3 +27,5 @@ MACROS = """ CUSTOMIZATIONS = """ """ + +CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/backends/openssl/pem.py b/cryptography/hazmat/backends/openssl/pem.py index cef7839f..ee5552c5 100644 --- a/cryptography/hazmat/backends/openssl/pem.py +++ b/cryptography/hazmat/backends/openssl/pem.py @@ -55,3 +55,5 @@ MACROS = """ CUSTOMIZATIONS = """ """ + +CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/backends/openssl/pkcs12.py b/cryptography/hazmat/backends/openssl/pkcs12.py index d91d100f..b3ecd0aa 100644 --- a/cryptography/hazmat/backends/openssl/pkcs12.py +++ b/cryptography/hazmat/backends/openssl/pkcs12.py @@ -35,3 +35,5 @@ PKCS12 *PKCS12_create(char *, char *, EVP_PKEY *, X509 *, CUSTOMIZATIONS = """ """ + +CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/backends/openssl/pkcs7.py b/cryptography/hazmat/backends/openssl/pkcs7.py index 60ea3c52..43f9540b 100644 --- a/cryptography/hazmat/backends/openssl/pkcs7.py +++ b/cryptography/hazmat/backends/openssl/pkcs7.py @@ -35,3 +35,5 @@ int PKCS7_type_is_data(PKCS7 *); CUSTOMIZATIONS = """ """ + +CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/backends/openssl/rand.py b/cryptography/hazmat/backends/openssl/rand.py index 848ee05a..ddd0a3d8 100644 --- a/cryptography/hazmat/backends/openssl/rand.py +++ b/cryptography/hazmat/backends/openssl/rand.py @@ -38,3 +38,5 @@ MACROS = """ CUSTOMIZATIONS = """ """ + +CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/backends/openssl/rsa.py b/cryptography/hazmat/backends/openssl/rsa.py index ad0d37b4..e3a24d0f 100644 --- a/cryptography/hazmat/backends/openssl/rsa.py +++ b/cryptography/hazmat/backends/openssl/rsa.py @@ -57,3 +57,5 @@ MACROS = """ CUSTOMIZATIONS = """ """ + +CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index 4fc20ebc..45dc97bd 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -262,3 +262,15 @@ void (*SSL_CTX_set_tlsext_servername_callback)( int (*)(const SSL *, int *, void *)) = NULL; #endif """ + +CONDITIONAL_NAMES = { + "SSLv2_method": "Cryptography_HAS_SSL2", + "SSLv2_client_method": "Cryptography_HAS_SSL2", + "SSLv2_server_method": "Cryptography_HAS_SSL2", + + "SSL_set_tlsext_host_name": "Cryptography_HAS_TLSEXT_HOSTNAME", + "SSL_get_servername": "Cryptography_HAS_TLSEXT_HOSTNAME", + "SSL_CTX_set_tlsext_servername_callback": ( + "Cryptography_HAS_TLSEXT_HOSTNAME" + ), +} diff --git a/cryptography/hazmat/backends/openssl/x509.py b/cryptography/hazmat/backends/openssl/x509.py index b2ee672e..dd7815fa 100644 --- a/cryptography/hazmat/backends/openssl/x509.py +++ b/cryptography/hazmat/backends/openssl/x509.py @@ -188,3 +188,5 @@ int X509_CRL_set_nextUpdate(X509_CRL *, const ASN1_TIME *); CUSTOMIZATIONS = """ """ + +CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/backends/openssl/x509name.py b/cryptography/hazmat/backends/openssl/x509name.py index 896f0ae4..4be39b53 100644 --- a/cryptography/hazmat/backends/openssl/x509name.py +++ b/cryptography/hazmat/backends/openssl/x509name.py @@ -49,3 +49,5 @@ void sk_X509_NAME_free(struct stack_st_X509_NAME *); CUSTOMIZATIONS = """ """ + +CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/backends/openssl/x509v3.py b/cryptography/hazmat/backends/openssl/x509v3.py index bc26236c..6d2d2361 100644 --- a/cryptography/hazmat/backends/openssl/x509v3.py +++ b/cryptography/hazmat/backends/openssl/x509v3.py @@ -95,3 +95,5 @@ const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int); CUSTOMIZATIONS = """ """ + +CONDITIONAL_NAMES = {} -- cgit v1.2.3 From 7938206b7a7416f5a1a7abd7b652302ee2125a91 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 23 Dec 2013 08:02:38 -0800 Subject: Reduce duplication --- cryptography/hazmat/backends/openssl/backend.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index 5d6b5bcc..67a3e698 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -57,6 +57,7 @@ class Backend(object): """ OpenSSL API wrapper. """ + _module_prefix = "cryptography.hazmat.backends.openssl." _modules = [ "asn1", "bignum", @@ -102,7 +103,7 @@ class Backend(object): macros = [] customizations = [] for name in cls._modules: - module_name = "cryptography.hazmat.backends.openssl." + name + module_name = cls._module_prefix + name __import__(module_name) module = sys.modules[module_name] @@ -142,7 +143,7 @@ class Backend(object): ) for name in cls._modules: - module_name = "cryptography.hazmat.backends.openssl." + name + module_name = cls._module_prefix + name __import__(module_name) module = sys.modules[module_name] for name, condition in module.CONDITIONAL_NAMES.items(): -- cgit v1.2.3 From 3e52645f14dc3f015f354fb1c545259a4d882bc7 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 23 Dec 2013 08:02:49 -0800 Subject: Invert these dics for more readability --- cryptography/hazmat/backends/openssl/backend.py | 5 +++-- cryptography/hazmat/backends/openssl/evp.py | 8 +++++--- cryptography/hazmat/backends/openssl/ssl.py | 18 ++++++++++-------- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index 67a3e698..6cc8275d 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -146,9 +146,10 @@ class Backend(object): module_name = cls._module_prefix + name __import__(module_name) module = sys.modules[module_name] - for name, condition in module.CONDITIONAL_NAMES.items(): + for condition, names in module.CONDITIONAL_NAMES.items(): if not getattr(lib, condition): - delattr(lib, name) + for name in names: + delattr(lib, name) cls.ffi = ffi cls.lib = lib diff --git a/cryptography/hazmat/backends/openssl/evp.py b/cryptography/hazmat/backends/openssl/evp.py index fa35c6ac..7e50a6b3 100644 --- a/cryptography/hazmat/backends/openssl/evp.py +++ b/cryptography/hazmat/backends/openssl/evp.py @@ -116,7 +116,9 @@ const int Cryptography_EVP_CTRL_GCM_SET_IVLEN = -1; """ CONDITIONAL_NAMES = { - "Cryptography_EVP_CTRL_GCM_GET_TAG": "Cryptography_HAS_GCM", - "Cryptography_EVP_CTRL_GCM_SET_TAG": "Cryptography_HAS_GCM", - "Cryptography_EVP_CTRL_GCM_SET_IVLEN": "Cryptography_HAS_GCM", + "Cryptography_HAS_GCM": [ + "Cryptography_EVP_CTRL_GCM_GET_TAG", + "Cryptography_EVP_CTRL_GCM_SET_TAG", + "Cryptography_EVP_CTRL_GCM_SET_IVLEN", + ] } diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index 45dc97bd..bf1ffcc6 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -264,13 +264,15 @@ void (*SSL_CTX_set_tlsext_servername_callback)( """ CONDITIONAL_NAMES = { - "SSLv2_method": "Cryptography_HAS_SSL2", - "SSLv2_client_method": "Cryptography_HAS_SSL2", - "SSLv2_server_method": "Cryptography_HAS_SSL2", + "Cryptography_HAS_SSL2": [ + "SSLv2_method", + "SSLv2_client_method", + "SSLv2_server_method", + ], - "SSL_set_tlsext_host_name": "Cryptography_HAS_TLSEXT_HOSTNAME", - "SSL_get_servername": "Cryptography_HAS_TLSEXT_HOSTNAME", - "SSL_CTX_set_tlsext_servername_callback": ( - "Cryptography_HAS_TLSEXT_HOSTNAME" - ), + "Cryptography_HAS_TLSEXT_HOSTNAME": [ + "SSL_set_tlsext_host_name", + "SSL_get_servername", + "SSL_CTX_set_tlsext_servername_callback", + ] } -- cgit v1.2.3 From af09025900863a2a196eb67b1ec844a8626caa0c Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Mon, 23 Dec 2013 08:22:03 -0500 Subject: bind a few more assorted random simple things --- cryptography/hazmat/backends/openssl/crypto.py | 6 ++++++ cryptography/hazmat/backends/openssl/opensslv.py | 1 + cryptography/hazmat/backends/openssl/rand.py | 1 + cryptography/hazmat/backends/openssl/ssl.py | 2 ++ 4 files changed, 10 insertions(+) diff --git a/cryptography/hazmat/backends/openssl/crypto.py b/cryptography/hazmat/backends/openssl/crypto.py index 8d88c16e..71d32c52 100644 --- a/cryptography/hazmat/backends/openssl/crypto.py +++ b/cryptography/hazmat/backends/openssl/crypto.py @@ -16,6 +16,11 @@ INCLUDES = """ """ TYPES = """ +static const int SSLEAY_VERSION; +static const int SSLEAY_CFLAGS; +static const int SSLEAY_PLATFORM; +static const int SSLEAY_DIR; +static const int SSLEAY_BUILT_ON; """ FUNCTIONS = """ @@ -32,6 +37,7 @@ MACROS = """ void CRYPTO_add(int *, int, int); void CRYPTO_malloc_init(); void CRYPTO_malloc_debug_init(); + #define CRYPTO_MEM_CHECK_ON ... #define CRYPTO_MEM_CHECK_OFF ... #define CRYPTO_MEM_CHECK_ENABLE ... diff --git a/cryptography/hazmat/backends/openssl/opensslv.py b/cryptography/hazmat/backends/openssl/opensslv.py index 37bbd2a7..4e110327 100644 --- a/cryptography/hazmat/backends/openssl/opensslv.py +++ b/cryptography/hazmat/backends/openssl/opensslv.py @@ -16,6 +16,7 @@ INCLUDES = """ """ TYPES = """ +static const int OPENSSL_VERSION_NUMBER; static char *const OPENSSL_VERSION_TEXT; """ diff --git a/cryptography/hazmat/backends/openssl/rand.py b/cryptography/hazmat/backends/openssl/rand.py index ddd0a3d8..5ac36cac 100644 --- a/cryptography/hazmat/backends/openssl/rand.py +++ b/cryptography/hazmat/backends/openssl/rand.py @@ -19,6 +19,7 @@ TYPES = """ """ FUNCTIONS = """ +void ERR_load_RAND_strings(); void RAND_seed(const void *, int); void RAND_add(const void *, int, double); int RAND_status(); diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index bf1ffcc6..168d5429 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -36,6 +36,7 @@ static const int SSL_RECEIVED_SHUTDOWN; static const int SSL_OP_NO_SSLv2; static const int SSL_OP_NO_SSLv3; static const int SSL_OP_NO_TLSv1; +static const int SSL_OP_NO_COMPRESSION; static const int SSL_OP_SINGLE_DH_USE; static const int SSL_OP_EPHEMERAL_RSA; static const int SSL_OP_MICROSOFT_SESS_ID_BUG; @@ -93,6 +94,7 @@ static const int SSL_CB_HANDSHAKE_DONE; static const int SSL_MODE_ENABLE_PARTIAL_WRITE; static const int SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER; static const int SSL_MODE_AUTO_RETRY; +static const int SSL_MODE_RELEASE_BUFFERS; static const int SSL3_RANDOM_SIZE; typedef ... X509_STORE_CTX; static const int X509_V_OK; -- cgit v1.2.3 From 21a37548b5c1cd2df9f2e3e7131e4ae3d72c333a Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Mon, 23 Dec 2013 11:13:34 -0500 Subject: Try making SSL_MODE_RELEASE_BUFFERS conditional on whether the underlying OpenSSL library has this flag --- cryptography/hazmat/backends/openssl/ssl.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index 168d5429..3af0074e 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -94,7 +94,6 @@ static const int SSL_CB_HANDSHAKE_DONE; static const int SSL_MODE_ENABLE_PARTIAL_WRITE; static const int SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER; static const int SSL_MODE_AUTO_RETRY; -static const int SSL_MODE_RELEASE_BUFFERS; static const int SSL3_RANDOM_SIZE; typedef ... X509_STORE_CTX; static const int X509_V_OK; @@ -263,6 +262,13 @@ void (*SSL_CTX_set_tlsext_servername_callback)( SSL_CTX *, int (*)(const SSL *, int *, void *)) = NULL; #endif + +#ifdef SSL_MODE_RELEASE_BUFFERS +static const int Cryptography_HAS_RELEASE_BUFFERS = 1; +#else +static const int Cryptography_HAS_RELEASE_BUFFERS = 0; +const int SSL_MODE_RELEASE_BUFFERS = 0; +#endif """ CONDITIONAL_NAMES = { @@ -276,5 +282,10 @@ CONDITIONAL_NAMES = { "SSL_set_tlsext_host_name", "SSL_get_servername", "SSL_CTX_set_tlsext_servername_callback", - ] + ], + + "Cryptography_HAS_RELEASE_BUFFERS": [ + "SSL_MODE_RELEASE_BUFFERS", + ], + } -- cgit v1.2.3 From ab51df1d664fafe1426748e38ddb125cf31d4052 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Mon, 23 Dec 2013 11:16:12 -0500 Subject: Finish that conditional support --- cryptography/hazmat/backends/openssl/ssl.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index 3af0074e..a1acde38 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -22,6 +22,11 @@ static const int Cryptography_HAS_SSL2; /* Internally invented symbol to tell us if SNI is supported */ static const int Cryptography_HAS_TLSEXT_HOSTNAME; +/* Internally invented symbol to tell us if SSL_MODE_RELEASE_BUFFERS is + * supported + */ +static const int Cryptography_HAS_RELEASE_BUFFERS; + static const int SSL_FILETYPE_PEM; static const int SSL_FILETYPE_ASN1; static const int SSL_ERROR_NONE; @@ -91,6 +96,7 @@ static const int SSL_CB_CONNECT_LOOP; static const int SSL_CB_CONNECT_EXIT; static const int SSL_CB_HANDSHAKE_START; static const int SSL_CB_HANDSHAKE_DONE; +static const int SSL_MODE_RELEASE_BUFFERS; static const int SSL_MODE_ENABLE_PARTIAL_WRITE; static const int SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER; static const int SSL_MODE_AUTO_RETRY; -- cgit v1.2.3 From 2ca30db7b8608af3e9994f6b324d9311ca437b78 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 23 Dec 2013 08:21:34 -0800 Subject: This name is alreayd known to be imported --- cryptography/hazmat/backends/openssl/backend.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index 6cc8275d..9cd07ea5 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -144,7 +144,6 @@ class Backend(object): for name in cls._modules: module_name = cls._module_prefix + name - __import__(module_name) module = sys.modules[module_name] for condition, names in module.CONDITIONAL_NAMES.items(): if not getattr(lib, condition): -- cgit v1.2.3 From 834342bea3990d166b9c63620a133d18ae5c9339 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 23 Dec 2013 08:25:24 -0800 Subject: A docstring --- cryptography/hazmat/backends/openssl/backend.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index 9cd07ea5..3e47afa1 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -56,6 +56,20 @@ _OSX_POST_INCLUDE = """ class Backend(object): """ OpenSSL API wrapper. + + Modules listed in the ``_modules`` listed should have the following + attributes: + + * ``INCLUDES``: A string containg C includes. + * ``TYPES``: A string containing C declarations for types. + * ``FUNCTIONS``: A string containing C declarations for functions. + * ``MACROS``: A string containing C declarations for any macros. + * ``CUSTOMIZATIONS``: A string containing arbitrary top-level C code, this + can be used to do things like test for a define and provide an + alternate implementation based on that. + * ``CONDITIONAL_NAMES``: A dict mapping strings of condition names from the + library to a list of names which will not be present without the + condition. """ _module_prefix = "cryptography.hazmat.backends.openssl." _modules = [ -- cgit v1.2.3 From f1ca56c42a9cb6fc1e83f6c28ae941d0f0044fb9 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 23 Dec 2013 09:54:03 -0800 Subject: Make the naming of things in the OpenSSL backend more consistent --- cryptography/hazmat/backends/openssl/backend.py | 6 +++--- cryptography/hazmat/backends/openssl/evp.py | 15 ++++++--------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index 3e47afa1..f11ddf22 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -345,7 +345,7 @@ class _CipherContext(object): assert res != 0 if isinstance(mode, GCM): res = self._backend.lib.EVP_CIPHER_CTX_ctrl( - ctx, self._backend.lib.Cryptography_EVP_CTRL_GCM_SET_IVLEN, + ctx, self._backend.lib.EVP_CTRL_GCM_SET_IVLEN, len(iv_nonce), self._backend.ffi.NULL ) assert res != 0 @@ -354,7 +354,7 @@ class _CipherContext(object): raise ValueError("Authentication tag must be provided and " "be 4 bytes or longer when decrypting") res = self._backend.lib.EVP_CIPHER_CTX_ctrl( - ctx, self._backend.lib.Cryptography_EVP_CTRL_GCM_SET_TAG, + ctx, self._backend.lib.EVP_CTRL_GCM_SET_TAG, len(mode.tag), mode.tag ) assert res != 0 @@ -396,7 +396,7 @@ class _CipherContext(object): block_byte_size = self._block_size // 8 tag_buf = self._backend.ffi.new("unsigned char[]", block_byte_size) res = self._backend.lib.EVP_CIPHER_CTX_ctrl( - self._ctx, self._backend.lib.Cryptography_EVP_CTRL_GCM_GET_TAG, + self._ctx, self._backend.lib.EVP_CTRL_GCM_GET_TAG, block_byte_size, tag_buf ) assert res != 0 diff --git a/cryptography/hazmat/backends/openssl/evp.py b/cryptography/hazmat/backends/openssl/evp.py index 7e50a6b3..e7b61b72 100644 --- a/cryptography/hazmat/backends/openssl/evp.py +++ b/cryptography/hazmat/backends/openssl/evp.py @@ -32,9 +32,9 @@ typedef struct evp_pkey_st { } EVP_PKEY; static const int EVP_PKEY_RSA; static const int EVP_PKEY_DSA; -static const int Cryptography_EVP_CTRL_GCM_SET_IVLEN; -static const int Cryptography_EVP_CTRL_GCM_GET_TAG; -static const int Cryptography_EVP_CTRL_GCM_SET_TAG; +static const int EVP_CTRL_GCM_SET_IVLEN; +static const int EVP_CTRL_GCM_GET_TAG; +static const int EVP_CTRL_GCM_SET_TAG; static const int Cryptography_HAS_GCM; """ @@ -104,9 +104,6 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *, int, int, void *); CUSTOMIZATIONS = """ #ifdef EVP_CTRL_GCM_SET_TAG const int Cryptography_HAS_GCM = 1; -const int Cryptography_EVP_CTRL_GCM_GET_TAG = EVP_CTRL_GCM_GET_TAG; -const int Cryptography_EVP_CTRL_GCM_SET_TAG = EVP_CTRL_GCM_SET_TAG; -const int Cryptography_EVP_CTRL_GCM_SET_IVLEN = EVP_CTRL_GCM_SET_IVLEN; #else const int Cryptography_HAS_GCM = 0; const int Cryptography_EVP_CTRL_GCM_GET_TAG = -1; @@ -117,8 +114,8 @@ const int Cryptography_EVP_CTRL_GCM_SET_IVLEN = -1; CONDITIONAL_NAMES = { "Cryptography_HAS_GCM": [ - "Cryptography_EVP_CTRL_GCM_GET_TAG", - "Cryptography_EVP_CTRL_GCM_SET_TAG", - "Cryptography_EVP_CTRL_GCM_SET_IVLEN", + "EVP_CTRL_GCM_GET_TAG", + "EVP_CTRL_GCM_SET_TAG", + "EVP_CTRL_GCM_SET_IVLEN", ] } -- cgit v1.2.3 From 0245a9a1070b4d0834cd84aad6292238cf74cb81 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 23 Dec 2013 09:57:07 -0800 Subject: Fix --- cryptography/hazmat/backends/openssl/evp.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/evp.py b/cryptography/hazmat/backends/openssl/evp.py index e7b61b72..8cf96b2d 100644 --- a/cryptography/hazmat/backends/openssl/evp.py +++ b/cryptography/hazmat/backends/openssl/evp.py @@ -106,9 +106,9 @@ CUSTOMIZATIONS = """ const int Cryptography_HAS_GCM = 1; #else const int Cryptography_HAS_GCM = 0; -const int Cryptography_EVP_CTRL_GCM_GET_TAG = -1; -const int Cryptography_EVP_CTRL_GCM_SET_TAG = -1; -const int Cryptography_EVP_CTRL_GCM_SET_IVLEN = -1; +const int EVP_CTRL_GCM_GET_TAG = -1; +const int EVP_CTRL_GCM_SET_TAG = -1; +const int EVP_CTRL_GCM_SET_IVLEN = -1; #endif """ -- cgit v1.2.3 From 22af23ebbbee831f8d9874ebf9080b4b5ed545b7 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Mon, 23 Dec 2013 15:00:02 -0500 Subject: Also make SSL_OP_NO_COMPRESSION optional --- cryptography/hazmat/backends/openssl/ssl.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index a1acde38..3fd0bf23 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -27,6 +27,11 @@ static const int Cryptography_HAS_TLSEXT_HOSTNAME; */ static const int Cryptography_HAS_RELEASE_BUFFERS; +/* Internally invented symbol to tell us if SSL_OP_NO_COMPRESSION is + * supported + */ +static const int Cryptography_HAS_OP_NO_COMPRESSION; + static const int SSL_FILETYPE_PEM; static const int SSL_FILETYPE_ASN1; static const int SSL_ERROR_NONE; @@ -275,6 +280,13 @@ static const int Cryptography_HAS_RELEASE_BUFFERS = 1; static const int Cryptography_HAS_RELEASE_BUFFERS = 0; const int SSL_MODE_RELEASE_BUFFERS = 0; #endif + +#ifdef SSL_OP_NO_COMPRESSION +static const int Cryptography_HAS_OP_NO_COMPRESSION = 1; +#else +static const int Cryptography_HAS_OP_NO_COMPRESSION = 0; +const int SSL_OP_NO_COMPRESSION = 0; +#endif """ CONDITIONAL_NAMES = { @@ -294,4 +306,8 @@ CONDITIONAL_NAMES = { "SSL_MODE_RELEASE_BUFFERS", ], + "Cryptography_HAS_OP_NO_COMPRESSION": [ + "SSL_OP_NO_COMPRESSION", + ], + } -- cgit v1.2.3 From 90ae866e0a83ef92ce2b2e7c58ccb86e79f3bee8 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 23 Dec 2013 17:21:00 -0600 Subject: add hmac_supported method to backend. Previously we were implicitly assuming that if a hash was supported then its hmac equivalent was as well. --- cryptography/hazmat/backends/openssl/backend.py | 3 +++ docs/hazmat/backends/interfaces.rst | 15 +++++++++++++-- tests/hazmat/primitives/test_hmac.py | 2 +- tests/hazmat/primitives/test_hmac_vectors.py | 14 +++++++------- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index f11ddf22..7b67fb0b 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -184,6 +184,9 @@ class Backend(object): digest = self.lib.EVP_get_digestbyname(algorithm.name.encode("ascii")) return digest != self.ffi.NULL + def hmac_supported(self, algorithm): + return self.hash_supported(algorithm) + def create_hash_ctx(self, algorithm): return _HashContext(self, algorithm) diff --git a/docs/hazmat/backends/interfaces.rst b/docs/hazmat/backends/interfaces.rst index b524943d..45fbaf09 100644 --- a/docs/hazmat/backends/interfaces.rst +++ b/docs/hazmat/backends/interfaces.rst @@ -126,12 +126,23 @@ A specific ``backend`` may provide one or more of these interfaces. A backend with methods for using cryptographic hash functions as message authentication codes. + .. method:: hmac_supported(algorithm) + + Check if the specified ``algorithm`` is supported by this backend. + + :param algorithm: An instance of a + :class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm` + provider. + + :returns: ``True`` if the specified ``algorithm`` is supported for HMAC + by this backend, otherwise ``False``. + .. method:: create_hmac_ctx(algorithm) Create a :class:`~cryptogrpahy.hazmat.primitives.interfaces.HashContext` that - uses the specified ``algorithm`` to calculate a hash-based message - authentication code. + uses the specified ``algorithm`` to calculate a hash-based message + authentication code. :param algorithm: An instance of a :class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm` diff --git a/tests/hazmat/primitives/test_hmac.py b/tests/hazmat/primitives/test_hmac.py index 124c4377..1e776c98 100644 --- a/tests/hazmat/primitives/test_hmac.py +++ b/tests/hazmat/primitives/test_hmac.py @@ -34,7 +34,7 @@ class UnsupportedDummyHash(object): class TestHMAC(object): test_copy = generate_base_hmac_test( hashes.MD5(), - only_if=lambda backend: backend.hash_supported(hashes.MD5), + only_if=lambda backend: backend.hmac_supported(hashes.MD5), skip_message="Does not support MD5", ) diff --git a/tests/hazmat/primitives/test_hmac_vectors.py b/tests/hazmat/primitives/test_hmac_vectors.py index 7d0f156a..f884d850 100644 --- a/tests/hazmat/primitives/test_hmac_vectors.py +++ b/tests/hazmat/primitives/test_hmac_vectors.py @@ -27,7 +27,7 @@ class TestHMAC_MD5(object): "rfc-2202-md5.txt", ], hashes.MD5(), - only_if=lambda backend: backend.hash_supported(hashes.MD5), + only_if=lambda backend: backend.hmac_supported(hashes.MD5), skip_message="Does not support MD5", ) @@ -40,7 +40,7 @@ class TestHMAC_SHA1(object): "rfc-2202-sha1.txt", ], hashes.SHA1(), - only_if=lambda backend: backend.hash_supported(hashes.SHA1), + only_if=lambda backend: backend.hmac_supported(hashes.SHA1), skip_message="Does not support SHA1", ) @@ -53,7 +53,7 @@ class TestHMAC_SHA224(object): "rfc-4231-sha224.txt", ], hashes.SHA224(), - only_if=lambda backend: backend.hash_supported(hashes.SHA224), + only_if=lambda backend: backend.hmac_supported(hashes.SHA224), skip_message="Does not support SHA224", ) @@ -66,7 +66,7 @@ class TestHMAC_SHA256(object): "rfc-4231-sha256.txt", ], hashes.SHA256(), - only_if=lambda backend: backend.hash_supported(hashes.SHA256), + only_if=lambda backend: backend.hmac_supported(hashes.SHA256), skip_message="Does not support SHA256", ) @@ -79,7 +79,7 @@ class TestHMAC_SHA384(object): "rfc-4231-sha384.txt", ], hashes.SHA384(), - only_if=lambda backend: backend.hash_supported(hashes.SHA384), + only_if=lambda backend: backend.hmac_supported(hashes.SHA384), skip_message="Does not support SHA384", ) @@ -92,7 +92,7 @@ class TestHMAC_SHA512(object): "rfc-4231-sha512.txt", ], hashes.SHA512(), - only_if=lambda backend: backend.hash_supported(hashes.SHA512), + only_if=lambda backend: backend.hmac_supported(hashes.SHA512), skip_message="Does not support SHA512", ) @@ -105,6 +105,6 @@ class TestHMAC_RIPEMD160(object): "rfc-2286-ripemd160.txt", ], hashes.RIPEMD160(), - only_if=lambda backend: backend.hash_supported(hashes.RIPEMD160), + only_if=lambda backend: backend.hmac_supported(hashes.RIPEMD160), skip_message="Does not support RIPEMD160", ) -- cgit v1.2.3 From 4f776c495cfef4dd29023cb7bb035612d1e53916 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 23 Dec 2013 17:25:54 -0600 Subject: fix erroneous indent and add abstractmethod to HMACBackend --- cryptography/hazmat/backends/interfaces.py | 7 +++++++ docs/hazmat/backends/interfaces.rst | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/cryptography/hazmat/backends/interfaces.py b/cryptography/hazmat/backends/interfaces.py index 912476bb..9a570968 100644 --- a/cryptography/hazmat/backends/interfaces.py +++ b/cryptography/hazmat/backends/interfaces.py @@ -59,6 +59,13 @@ class HashBackend(six.with_metaclass(abc.ABCMeta)): class HMACBackend(six.with_metaclass(abc.ABCMeta)): + @abc.abstractmethod + def hmac_supported(self, algorithm): + """ + Return True if the hash algorithm is supported for HMAC by this + backend. + """ + @abc.abstractmethod def create_hmac_ctx(self, key, algorithm): """ diff --git a/docs/hazmat/backends/interfaces.rst b/docs/hazmat/backends/interfaces.rst index 45fbaf09..5b6cd64d 100644 --- a/docs/hazmat/backends/interfaces.rst +++ b/docs/hazmat/backends/interfaces.rst @@ -141,8 +141,8 @@ A specific ``backend`` may provide one or more of these interfaces. Create a :class:`~cryptogrpahy.hazmat.primitives.interfaces.HashContext` that - uses the specified ``algorithm`` to calculate a hash-based message - authentication code. + uses the specified ``algorithm`` to calculate a hash-based message + authentication code. :param algorithm: An instance of a :class:`~cryptography.hazmat.primitives.interfaces.HashAlgorithm` -- cgit v1.2.3 From 93a0b2f1f7ec9fcc2c0f5327f4f88378ae19561e Mon Sep 17 00:00:00 2001 From: David Reid Date: Mon, 23 Dec 2013 15:56:21 -0800 Subject: Run py.test with catpure=no for more faster. --- tox.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 39fe024f..61143112 100644 --- a/tox.ini +++ b/tox.ini @@ -7,7 +7,7 @@ deps = coverage pretend commands = - coverage run --source=cryptography/,tests/ -m pytest --strict + coverage run --source=cryptography/,tests/ -m pytest --capture=no --strict coverage report -m [testenv:docs] @@ -24,7 +24,7 @@ commands = # Temporarily disable coverage on pypy because of performance problems with # coverage.py on pypy. [testenv:pypy] -commands = py.test +commands = py.test --capture=no [testenv:pep8] deps = flake8 -- cgit v1.2.3 From c80c68da793a255c552e0131ebc07ba2cf911570 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 23 Dec 2013 19:38:08 -0600 Subject: add more skip check lambdas --- tests/hazmat/primitives/test_3des.py | 24 ++++++++++++++++++++++++ tests/hazmat/primitives/test_aes.py | 16 ++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/tests/hazmat/primitives/test_3des.py b/tests/hazmat/primitives/test_3des.py index 0db56f47..4e380dee 100644 --- a/tests/hazmat/primitives/test_3des.py +++ b/tests/hazmat/primitives/test_3des.py @@ -39,6 +39,10 @@ class TestTripleDES_CBC(object): ], lambda keys, **kwargs: algorithms.TripleDES(binascii.unhexlify(keys)), lambda iv, **kwargs: modes.CBC(binascii.unhexlify(iv)), + only_if=lambda backend: backend.cipher_supported( + algorithms.TripleDES("\x00" * 8), modes.CBC("\x00" * 8) + ), + skip_message="Does not support TripleDES CBC", ) test_MMT = generate_encrypt_test( @@ -53,6 +57,10 @@ class TestTripleDES_CBC(object): binascii.unhexlify(key1 + key2 + key3) ), lambda iv, **kwargs: modes.CBC(binascii.unhexlify(iv)), + only_if=lambda backend: backend.cipher_supported( + algorithms.TripleDES("\x00" * 8), modes.CBC("\x00" * 8) + ), + skip_message="Does not support TripleDES CBC", ) @@ -69,6 +77,10 @@ class TestTripleDES_OFB(object): ], lambda keys, **kwargs: algorithms.TripleDES(binascii.unhexlify(keys)), lambda iv, **kwargs: modes.OFB(binascii.unhexlify(iv)), + only_if=lambda backend: backend.cipher_supported( + algorithms.TripleDES("\x00" * 8), modes.OFB("\x00" * 8) + ), + skip_message="Does not support TripleDES OFB", ) test_MMT = generate_encrypt_test( @@ -83,6 +95,10 @@ class TestTripleDES_OFB(object): binascii.unhexlify(key1 + key2 + key3) ), lambda iv, **kwargs: modes.OFB(binascii.unhexlify(iv)), + only_if=lambda backend: backend.cipher_supported( + algorithms.TripleDES("\x00" * 8), modes.OFB("\x00" * 8) + ), + skip_message="Does not support TripleDES OFB", ) @@ -99,6 +115,10 @@ class TestTripleDES_CFB(object): ], lambda keys, **kwargs: algorithms.TripleDES(binascii.unhexlify(keys)), lambda iv, **kwargs: modes.CFB(binascii.unhexlify(iv)), + only_if=lambda backend: backend.cipher_supported( + algorithms.TripleDES("\x00" * 8), modes.CFB("\x00" * 8) + ), + skip_message="Does not support TripleDES CFB", ) test_MMT = generate_encrypt_test( @@ -113,4 +133,8 @@ class TestTripleDES_CFB(object): binascii.unhexlify(key1 + key2 + key3) ), lambda iv, **kwargs: modes.CFB(binascii.unhexlify(iv)), + only_if=lambda backend: backend.cipher_supported( + algorithms.TripleDES("\x00" * 8), modes.CFB("\x00" * 8) + ), + skip_message="Does not support TripleDES CFB", ) diff --git a/tests/hazmat/primitives/test_aes.py b/tests/hazmat/primitives/test_aes.py index 9e5a3cb5..241772e6 100644 --- a/tests/hazmat/primitives/test_aes.py +++ b/tests/hazmat/primitives/test_aes.py @@ -47,6 +47,10 @@ class TestAES(object): ], lambda key, **kwargs: algorithms.AES(binascii.unhexlify(key)), lambda iv, **kwargs: modes.CBC(binascii.unhexlify(iv)), + only_if=lambda backend: backend.cipher_supported( + algorithms.AES("\x00" * 16), modes.CBC("\x00" * 16) + ), + skip_message="Does not support AES CBC", ) test_ECB = generate_encrypt_test( @@ -71,6 +75,10 @@ class TestAES(object): ], lambda key, **kwargs: algorithms.AES(binascii.unhexlify(key)), lambda **kwargs: modes.ECB(), + only_if=lambda backend: backend.cipher_supported( + algorithms.AES("\x00" * 16), modes.ECB() + ), + skip_message="Does not support AES ECB", ) test_OFB = generate_encrypt_test( @@ -95,6 +103,10 @@ class TestAES(object): ], lambda key, **kwargs: algorithms.AES(binascii.unhexlify(key)), lambda iv, **kwargs: modes.OFB(binascii.unhexlify(iv)), + only_if=lambda backend: backend.cipher_supported( + algorithms.AES("\x00" * 16), modes.OFB("\x00" * 16) + ), + skip_message="Does not support AES OFB", ) test_CFB = generate_encrypt_test( @@ -119,6 +131,10 @@ class TestAES(object): ], lambda key, **kwargs: algorithms.AES(binascii.unhexlify(key)), lambda iv, **kwargs: modes.CFB(binascii.unhexlify(iv)), + only_if=lambda backend: backend.cipher_supported( + algorithms.AES("\x00" * 16), modes.CFB("\x00" * 16) + ), + skip_message="Does not support AES CFB", ) test_CTR = generate_encrypt_test( -- cgit v1.2.3 From 1a9bbf24301a9b0dc76ede1128d74ca629075888 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 24 Dec 2013 10:59:50 -0800 Subject: Document our API stability policy. Fixes #312 --- docs/contributing.rst | 1 - docs/index.rst | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing.rst b/docs/contributing.rst index 744f2098..620e1b6a 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -136,7 +136,6 @@ Include a space after commas between parameters: // Bad long f(int,char *) - Documentation ------------- diff --git a/docs/index.rst b/docs/index.rst index 381063df..70558bda 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -75,4 +75,5 @@ The ``cryptography`` open source project contributing security + api-stability community -- cgit v1.2.3 From f5415c859d4e413e9ac8b1862157babdcbda88ec Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 24 Dec 2013 11:00:15 -0800 Subject: Forgotten file --- docs/api-stability.rst | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 docs/api-stability.rst diff --git a/docs/api-stability.rst b/docs/api-stability.rst new file mode 100644 index 00000000..6497a687 --- /dev/null +++ b/docs/api-stability.rst @@ -0,0 +1,48 @@ +API Stability +============= + +From its first release, ``cryptography`` will have a strong API stability +policy. + +What does this policy cover? +---------------------------- + +This policy includes any API or behavior which is documented in this +documentation. + +What does "stable" mean? +------------------------ + +* Public APIs will not be removed or renamed without providing a compatibility + alias. +* The behavior of existing APIs will not change. + +What doesn't this policy cover? +------------------------------- + +* We may add new features, things like the result of ``dir(obj))`` or the + contents of ``obj.__dict__`` may change. +* Objects are not guarnteed to be pickleable, and pickled objects from one + version of ``cryptography`` may not be loadable in future versions. + +Security +~~~~~~~~ + +In the event a security vulnerability, or hardening necessitates it, we will +break backwards compatibility in order to address an issue. + +Deprecation +----------- + +From time to time we will want to change the behavior of an API or remove it +entirely. In that case, here's how the process will work: + +* In ``cryptography X.Y`` the feature exists. +* In ``cryptography X.Y+1`` using that feature will emit a + ``PendingDeprecationWarning``. +* In ``cryptography X.Y+2`` using that feature will emit a + ``DeprecationWarning``. +* In ``cryptography X.Y+3`` the feature will be removed or changed. + +In short, code which runs without warnings will always continue to work for a +period of two releases. -- cgit v1.2.3 From 6cf1e697a8024c779b9b86d29f300a3bfed30cfe Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 24 Dec 2013 11:02:54 -0800 Subject: Note abotu development versions --- docs/api-stability.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/api-stability.rst b/docs/api-stability.rst index 6497a687..40608ac5 100644 --- a/docs/api-stability.rst +++ b/docs/api-stability.rst @@ -24,6 +24,8 @@ What doesn't this policy cover? contents of ``obj.__dict__`` may change. * Objects are not guarnteed to be pickleable, and pickled objects from one version of ``cryptography`` may not be loadable in future versions. +* Development versions of ``cryptography``. Before a feature is in a release, + it is not covered by this policy and may change. Security ~~~~~~~~ -- cgit v1.2.3 From d43134ae57a1bb91bfa47a53176a88789728d686 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 24 Dec 2013 11:03:16 -0800 Subject: Typo --- docs/api-stability.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-stability.rst b/docs/api-stability.rst index 40608ac5..a457306f 100644 --- a/docs/api-stability.rst +++ b/docs/api-stability.rst @@ -22,7 +22,7 @@ What doesn't this policy cover? * We may add new features, things like the result of ``dir(obj))`` or the contents of ``obj.__dict__`` may change. -* Objects are not guarnteed to be pickleable, and pickled objects from one +* Objects are not guaranteed to be pickleable, and pickled objects from one version of ``cryptography`` may not be loadable in future versions. * Development versions of ``cryptography``. Before a feature is in a release, it is not covered by this policy and may change. -- cgit v1.2.3 From 1c9e57bbc64d5023ec9d35f162b0a071a39b0a48 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 24 Dec 2013 12:47:45 -0800 Subject: Rephrase --- docs/api-stability.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/api-stability.rst b/docs/api-stability.rst index a457306f..e87cc140 100644 --- a/docs/api-stability.rst +++ b/docs/api-stability.rst @@ -30,8 +30,9 @@ What doesn't this policy cover? Security ~~~~~~~~ -In the event a security vulnerability, or hardening necessitates it, we will -break backwards compatibility in order to address an issue. +One exception to our API stability policy is for security. We will violate this +policy as necessary in order to resolve a security issue or harden +``cryptography`` against a possible attack. Deprecation ----------- -- cgit v1.2.3 From 8f42fe4e86267c4dee696707ac08371a1aa2531a Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 24 Dec 2013 13:15:52 -0800 Subject: Slightly reorganize and cleanuip the backend docs --- docs/hazmat/backends/index.rst | 24 ++++++++++++------------ docs/hazmat/backends/openssl.rst | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/hazmat/backends/index.rst b/docs/hazmat/backends/index.rst index a89cf0d5..06951281 100644 --- a/docs/hazmat/backends/index.rst +++ b/docs/hazmat/backends/index.rst @@ -1,17 +1,10 @@ .. hazmat:: -Bindings +Backends ======== -.. toctree:: - :maxdepth: 1 - - openssl - interfaces - - -Getting a Backend Provider -~~~~~~~~~~~~~~~~~~~~~~~~~~ +Getting a Backend +----------------- .. currentmodule:: cryptography.hazmat.backends @@ -19,8 +12,7 @@ Getting a Backend Provider the widest number of supported cryptographic algorithms as well as supporting platform specific implementations. -You can get the default backend by calling -:func:`~default_backend`. +You can get the default backend by calling :func:`~default_backend`. The default backend will change over time as we implement new backends and the libraries we use in those backends changes. @@ -32,3 +24,11 @@ the libraries we use in those backends changes. :class:`~interfaces.CipherBackend`, :class:`~interfaces.HashBackend`, and :class:`~interfaces.HMACBackend`. +Individual Backends +------------------- + +.. toctree:: + :maxdepth: 1 + + openssl + interfaces diff --git a/docs/hazmat/backends/openssl.rst b/docs/hazmat/backends/openssl.rst index 12fbff04..5e51c75e 100644 --- a/docs/hazmat/backends/openssl.rst +++ b/docs/hazmat/backends/openssl.rst @@ -1,7 +1,7 @@ .. hazmat:: -OpenSSL -======= +OpenSSL Backend +=============== These are `CFFI`_ bindings to the `OpenSSL`_ C library. -- cgit v1.2.3 From 2a36dd1b9f68f34f2545e519f8eac00b8b40c59d Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 24 Dec 2013 13:44:45 -0800 Subject: Cover a missed branch --- tests/hazmat/primitives/utils.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index b00d3184..e0184777 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -22,8 +22,7 @@ def _load_all_params(path, file_names, param_loader): def generate_encrypt_test(param_loader, path, file_names, cipher_factory, - mode_factory, only_if=lambda backend: True, - skip_message=None): + mode_factory, only_if, skip_message=None): all_params = _load_all_params(path, file_names, param_loader) @pytest.mark.parametrize("params", all_params) -- cgit v1.2.3 From 7e4bc6d87741e8469ffcd00dc8004875ec9a95fe Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 24 Dec 2013 22:23:53 -0600 Subject: add test marks for various backend functionality --- pytest.ini | 4 ++++ tests/conftest.py | 16 ++++++++++++++++ tests/skip_check.py | 22 ++++++++++++++++++++++ tests/test_skip_check.py | 31 +++++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+) create mode 100644 tests/skip_check.py create mode 100644 tests/test_skip_check.py diff --git a/pytest.ini b/pytest.ini index 723735ac..1aeb23fc 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,2 +1,6 @@ [pytest] addopts = -r s +markers = + hmac: this test requires a backend providing HMACBackend + cipher: this test requires a backend providing CipherBackend + hash: this test requires a backend providing HashBackend diff --git a/tests/conftest.py b/tests/conftest.py index 71662802..91ba988f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,21 @@ +import pytest + +from cryptography.hazmat.backends.interfaces import ( + HMACBackend, CipherBackend, HashBackend +) + +from .skip_check import skip_check + + def pytest_generate_tests(metafunc): from cryptography.hazmat.backends import _ALL_BACKENDS if "backend" in metafunc.fixturenames: metafunc.parametrize("backend", _ALL_BACKENDS) + + +@pytest.mark.trylast +def pytest_runtest_setup(item): + skip_check('hmac', HMACBackend, item) + skip_check('cipher', CipherBackend, item) + skip_check('hash', HashBackend, item) diff --git a/tests/skip_check.py b/tests/skip_check.py new file mode 100644 index 00000000..4d454d73 --- /dev/null +++ b/tests/skip_check.py @@ -0,0 +1,22 @@ +# 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 + + +def skip_check(name, iface, item): + if name in item.keywords and item.funcargs.get('backend') is not None: + if not isinstance(item.funcargs['backend'], iface): + pytest.skip("Backend does not support {}".format(name)) diff --git a/tests/test_skip_check.py b/tests/test_skip_check.py new file mode 100644 index 00000000..3b303aca --- /dev/null +++ b/tests/test_skip_check.py @@ -0,0 +1,31 @@ +# 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 pretend + +import pytest + +from .skip_check import skip_check + + +class FakeInterface(object): + pass + + +def test_skip_check(): + item = pretend.stub(keywords=["fake_name"], funcargs={"backend": True}) + with pytest.raises(pytest.skip.Exception) as exc_info: + skip_check("fake_name", FakeInterface, item) + assert exc_info.value.args[0] == "Backend does not support fake_name" -- cgit v1.2.3 From 0cbcfa67fc7c1e13764f4b662fc238a372507af8 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 24 Dec 2013 22:29:12 -0600 Subject: whoops, python 2.6 compatible format string --- tests/skip_check.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/skip_check.py b/tests/skip_check.py index 4d454d73..454a3c5f 100644 --- a/tests/skip_check.py +++ b/tests/skip_check.py @@ -19,4 +19,4 @@ import pytest def skip_check(name, iface, item): if name in item.keywords and item.funcargs.get('backend') is not None: if not isinstance(item.funcargs['backend'], iface): - pytest.skip("Backend does not support {}".format(name)) + pytest.skip("Backend does not support {0}".format(name)) -- cgit v1.2.3 From 4f2b1031c3c155b9af3817126b9ac508cbf849a3 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 24 Dec 2013 22:24:31 -0600 Subject: add all the markers to the tests --- tests/hazmat/primitives/test_3des.py | 4 ++++ tests/hazmat/primitives/test_aes.py | 2 ++ tests/hazmat/primitives/test_arc4.py | 2 ++ tests/hazmat/primitives/test_block.py | 3 +++ tests/hazmat/primitives/test_blowfish.py | 2 ++ tests/hazmat/primitives/test_camellia.py | 2 ++ tests/hazmat/primitives/test_cast5.py | 2 ++ tests/hazmat/primitives/test_hash_vectors.py | 9 +++++++++ tests/hazmat/primitives/test_hashes.py | 9 +++++++++ tests/hazmat/primitives/test_hmac.py | 1 + tests/hazmat/primitives/test_hmac_vectors.py | 9 +++++++++ 11 files changed, 45 insertions(+) diff --git a/tests/hazmat/primitives/test_3des.py b/tests/hazmat/primitives/test_3des.py index 4e380dee..4c43898c 100644 --- a/tests/hazmat/primitives/test_3des.py +++ b/tests/hazmat/primitives/test_3des.py @@ -19,6 +19,7 @@ from __future__ import absolute_import, division, print_function import binascii import os +import pytest from cryptography.hazmat.primitives.ciphers import algorithms, modes @@ -26,6 +27,7 @@ from .utils import generate_encrypt_test from ...utils import load_nist_vectors +@pytest.mark.cipher class TestTripleDES_CBC(object): test_KAT = generate_encrypt_test( load_nist_vectors, @@ -64,6 +66,7 @@ class TestTripleDES_CBC(object): ) +@pytest.mark.cipher class TestTripleDES_OFB(object): test_KAT = generate_encrypt_test( load_nist_vectors, @@ -102,6 +105,7 @@ class TestTripleDES_OFB(object): ) +@pytest.mark.cipher class TestTripleDES_CFB(object): test_KAT = generate_encrypt_test( load_nist_vectors, diff --git a/tests/hazmat/primitives/test_aes.py b/tests/hazmat/primitives/test_aes.py index 241772e6..5b706842 100644 --- a/tests/hazmat/primitives/test_aes.py +++ b/tests/hazmat/primitives/test_aes.py @@ -15,6 +15,7 @@ from __future__ import absolute_import, division, print_function import binascii import os +import pytest from cryptography.hazmat.primitives.ciphers import algorithms, modes @@ -24,6 +25,7 @@ from ...utils import ( ) +@pytest.mark.cipher class TestAES(object): test_CBC = generate_encrypt_test( load_nist_vectors, diff --git a/tests/hazmat/primitives/test_arc4.py b/tests/hazmat/primitives/test_arc4.py index a9ef2bbe..d506a8a1 100644 --- a/tests/hazmat/primitives/test_arc4.py +++ b/tests/hazmat/primitives/test_arc4.py @@ -15,6 +15,7 @@ from __future__ import absolute_import, division, print_function import binascii import os +import pytest from cryptography.hazmat.primitives.ciphers import algorithms @@ -22,6 +23,7 @@ from .utils import generate_stream_encryption_test from ...utils import load_nist_vectors +@pytest.mark.cipher class TestARC4(object): test_rfc = generate_stream_encryption_test( load_nist_vectors, diff --git a/tests/hazmat/primitives/test_block.py b/tests/hazmat/primitives/test_block.py index 573f5633..22a7c02f 100644 --- a/tests/hazmat/primitives/test_block.py +++ b/tests/hazmat/primitives/test_block.py @@ -41,6 +41,7 @@ class DummyCipher(object): name = "dummy-cipher" +@pytest.mark.cipher class TestCipher(object): def test_creates_encryptor(self, backend): cipher = Cipher( @@ -64,6 +65,7 @@ class TestCipher(object): Cipher(algorithm, mode=None, backend=backend) +@pytest.mark.cipher class TestCipherContext(object): def test_use_after_finalize(self, backend): cipher = Cipher( @@ -134,6 +136,7 @@ class TestCipherContext(object): decryptor.finalize() +@pytest.mark.cipher class TestAEADCipherContext(object): test_aead_exceptions = generate_aead_exception_test( algorithms.AES, diff --git a/tests/hazmat/primitives/test_blowfish.py b/tests/hazmat/primitives/test_blowfish.py index 065855d7..2d5dc521 100644 --- a/tests/hazmat/primitives/test_blowfish.py +++ b/tests/hazmat/primitives/test_blowfish.py @@ -15,6 +15,7 @@ from __future__ import absolute_import, division, print_function import binascii import os +import pytest from cryptography.hazmat.primitives.ciphers import algorithms, modes @@ -22,6 +23,7 @@ from .utils import generate_encrypt_test from ...utils import load_nist_vectors +@pytest.mark.cipher class TestBlowfish(object): test_ECB = generate_encrypt_test( load_nist_vectors, diff --git a/tests/hazmat/primitives/test_camellia.py b/tests/hazmat/primitives/test_camellia.py index 6e5fe682..0b6c37fb 100644 --- a/tests/hazmat/primitives/test_camellia.py +++ b/tests/hazmat/primitives/test_camellia.py @@ -15,6 +15,7 @@ from __future__ import absolute_import, division, print_function import binascii import os +import pytest from cryptography.hazmat.primitives.ciphers import algorithms, modes @@ -24,6 +25,7 @@ from ...utils import ( ) +@pytest.mark.cipher class TestCamellia(object): test_ECB = generate_encrypt_test( load_cryptrec_vectors, diff --git a/tests/hazmat/primitives/test_cast5.py b/tests/hazmat/primitives/test_cast5.py index 406f9b55..2ebc040b 100644 --- a/tests/hazmat/primitives/test_cast5.py +++ b/tests/hazmat/primitives/test_cast5.py @@ -15,6 +15,7 @@ from __future__ import absolute_import, division, print_function import binascii import os +import pytest from cryptography.hazmat.primitives.ciphers import algorithms, modes @@ -22,6 +23,7 @@ from .utils import generate_encrypt_test from ...utils import load_nist_vectors +@pytest.mark.cipher class TestCAST5(object): test_ECB = generate_encrypt_test( load_nist_vectors, diff --git a/tests/hazmat/primitives/test_hash_vectors.py b/tests/hazmat/primitives/test_hash_vectors.py index a8655812..5c9e9bed 100644 --- a/tests/hazmat/primitives/test_hash_vectors.py +++ b/tests/hazmat/primitives/test_hash_vectors.py @@ -14,6 +14,7 @@ from __future__ import absolute_import, division, print_function import os +import pytest from cryptography.hazmat.primitives import hashes @@ -21,6 +22,7 @@ from .utils import generate_hash_test, generate_long_string_hash_test from ...utils import load_hash_vectors +@pytest.mark.hash class TestSHA1(object): test_SHA1 = generate_hash_test( load_hash_vectors, @@ -35,6 +37,7 @@ class TestSHA1(object): ) +@pytest.mark.hash class TestSHA224(object): test_SHA224 = generate_hash_test( load_hash_vectors, @@ -49,6 +52,7 @@ class TestSHA224(object): ) +@pytest.mark.hash class TestSHA256(object): test_SHA256 = generate_hash_test( load_hash_vectors, @@ -63,6 +67,7 @@ class TestSHA256(object): ) +@pytest.mark.hash class TestSHA384(object): test_SHA384 = generate_hash_test( load_hash_vectors, @@ -77,6 +82,7 @@ class TestSHA384(object): ) +@pytest.mark.hash class TestSHA512(object): test_SHA512 = generate_hash_test( load_hash_vectors, @@ -91,6 +97,7 @@ class TestSHA512(object): ) +@pytest.mark.hash class TestRIPEMD160(object): test_RIPEMD160 = generate_hash_test( load_hash_vectors, @@ -111,6 +118,7 @@ class TestRIPEMD160(object): ) +@pytest.mark.hash class TestWhirlpool(object): test_whirlpool = generate_hash_test( load_hash_vectors, @@ -133,6 +141,7 @@ class TestWhirlpool(object): ) +@pytest.mark.hash class TestMD5(object): test_md5 = generate_hash_test( load_hash_vectors, diff --git a/tests/hazmat/primitives/test_hashes.py b/tests/hazmat/primitives/test_hashes.py index 72bc3e27..45faaab2 100644 --- a/tests/hazmat/primitives/test_hashes.py +++ b/tests/hazmat/primitives/test_hashes.py @@ -31,6 +31,7 @@ class UnsupportedDummyHash(object): name = "unsupported-dummy-hash" +@pytest.mark.hash class TestHashContext(object): def test_hash_reject_unicode(self, backend): m = hashes.Hash(hashes.SHA1(), backend=backend) @@ -68,6 +69,7 @@ class TestHashContext(object): hashes.Hash(UnsupportedDummyHash(), backend) +@pytest.mark.hash class TestSHA1(object): test_SHA1 = generate_base_hash_test( hashes.SHA1(), @@ -78,6 +80,7 @@ class TestSHA1(object): ) +@pytest.mark.hash class TestSHA224(object): test_SHA224 = generate_base_hash_test( hashes.SHA224(), @@ -88,6 +91,7 @@ class TestSHA224(object): ) +@pytest.mark.hash class TestSHA256(object): test_SHA256 = generate_base_hash_test( hashes.SHA256(), @@ -98,6 +102,7 @@ class TestSHA256(object): ) +@pytest.mark.hash class TestSHA384(object): test_SHA384 = generate_base_hash_test( hashes.SHA384(), @@ -108,6 +113,7 @@ class TestSHA384(object): ) +@pytest.mark.hash class TestSHA512(object): test_SHA512 = generate_base_hash_test( hashes.SHA512(), @@ -118,6 +124,7 @@ class TestSHA512(object): ) +@pytest.mark.hash class TestRIPEMD160(object): test_RIPEMD160 = generate_base_hash_test( hashes.RIPEMD160(), @@ -128,6 +135,7 @@ class TestRIPEMD160(object): ) +@pytest.mark.hash class TestWhirlpool(object): test_Whirlpool = generate_base_hash_test( hashes.Whirlpool(), @@ -138,6 +146,7 @@ class TestWhirlpool(object): ) +@pytest.mark.hash class TestMD5(object): test_MD5 = generate_base_hash_test( hashes.MD5(), diff --git a/tests/hazmat/primitives/test_hmac.py b/tests/hazmat/primitives/test_hmac.py index 1e776c98..6d8cc27b 100644 --- a/tests/hazmat/primitives/test_hmac.py +++ b/tests/hazmat/primitives/test_hmac.py @@ -31,6 +31,7 @@ class UnsupportedDummyHash(object): name = "unsupported-dummy-hash" +@pytest.mark.hmac class TestHMAC(object): test_copy = generate_base_hmac_test( hashes.MD5(), diff --git a/tests/hazmat/primitives/test_hmac_vectors.py b/tests/hazmat/primitives/test_hmac_vectors.py index f884d850..9bc06a2e 100644 --- a/tests/hazmat/primitives/test_hmac_vectors.py +++ b/tests/hazmat/primitives/test_hmac_vectors.py @@ -13,12 +13,15 @@ from __future__ import absolute_import, division, print_function +import pytest + from cryptography.hazmat.primitives import hashes from .utils import generate_hmac_test from ...utils import load_hash_vectors +@pytest.mark.hmac class TestHMAC_MD5(object): test_hmac_md5 = generate_hmac_test( load_hash_vectors, @@ -32,6 +35,7 @@ class TestHMAC_MD5(object): ) +@pytest.mark.hmac class TestHMAC_SHA1(object): test_hmac_sha1 = generate_hmac_test( load_hash_vectors, @@ -45,6 +49,7 @@ class TestHMAC_SHA1(object): ) +@pytest.mark.hmac class TestHMAC_SHA224(object): test_hmac_sha224 = generate_hmac_test( load_hash_vectors, @@ -58,6 +63,7 @@ class TestHMAC_SHA224(object): ) +@pytest.mark.hmac class TestHMAC_SHA256(object): test_hmac_sha256 = generate_hmac_test( load_hash_vectors, @@ -71,6 +77,7 @@ class TestHMAC_SHA256(object): ) +@pytest.mark.hmac class TestHMAC_SHA384(object): test_hmac_sha384 = generate_hmac_test( load_hash_vectors, @@ -84,6 +91,7 @@ class TestHMAC_SHA384(object): ) +@pytest.mark.hmac class TestHMAC_SHA512(object): test_hmac_sha512 = generate_hmac_test( load_hash_vectors, @@ -97,6 +105,7 @@ class TestHMAC_SHA512(object): ) +@pytest.mark.hmac class TestHMAC_RIPEMD160(object): test_hmac_ripemd160 = generate_hmac_test( load_hash_vectors, -- cgit v1.2.3 From 5a09c6e9545373cece95f87ed28579f05959fced Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 24 Dec 2013 21:03:23 -0800 Subject: Include teh name of the backend in the error message --- tests/skip_check.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/skip_check.py b/tests/skip_check.py index 454a3c5f..42a152ea 100644 --- a/tests/skip_check.py +++ b/tests/skip_check.py @@ -17,6 +17,8 @@ import pytest def skip_check(name, iface, item): - if name in item.keywords and item.funcargs.get('backend') is not None: - if not isinstance(item.funcargs['backend'], iface): - pytest.skip("Backend does not support {0}".format(name)) + if name in item.keywords and "backend" in item.funcargs: + if not isinstance(item.funcargs["backend"], iface): + pytest.skip("{0} backend does not support {1}".format( + item.funcargs["backend"], name + )) -- cgit v1.2.3 From 6198da1fcce93d7efb89995d0a10d9170ee8f230 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 24 Dec 2013 21:03:43 -0800 Subject: Update test --- tests/test_skip_check.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_skip_check.py b/tests/test_skip_check.py index 3b303aca..73a6e563 100644 --- a/tests/test_skip_check.py +++ b/tests/test_skip_check.py @@ -28,4 +28,4 @@ def test_skip_check(): item = pretend.stub(keywords=["fake_name"], funcargs={"backend": True}) with pytest.raises(pytest.skip.Exception) as exc_info: skip_check("fake_name", FakeInterface, item) - assert exc_info.value.args[0] == "Backend does not support fake_name" + assert exc_info.value.args[0] == "True backend does not support fake_name" -- cgit v1.2.3 From 8d85b058d28d37f1f505292f7cc6311092dd4f39 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 24 Dec 2013 23:50:59 -0600 Subject: correct import style --- tests/hazmat/primitives/test_3des.py | 1 + tests/hazmat/primitives/test_aes.py | 1 + tests/hazmat/primitives/test_arc4.py | 1 + tests/hazmat/primitives/test_blowfish.py | 1 + tests/hazmat/primitives/test_camellia.py | 1 + tests/hazmat/primitives/test_cast5.py | 1 + tests/hazmat/primitives/test_hash_vectors.py | 1 + 7 files changed, 7 insertions(+) diff --git a/tests/hazmat/primitives/test_3des.py b/tests/hazmat/primitives/test_3des.py index 4c43898c..439ca258 100644 --- a/tests/hazmat/primitives/test_3des.py +++ b/tests/hazmat/primitives/test_3des.py @@ -19,6 +19,7 @@ from __future__ import absolute_import, division, print_function import binascii import os + import pytest from cryptography.hazmat.primitives.ciphers import algorithms, modes diff --git a/tests/hazmat/primitives/test_aes.py b/tests/hazmat/primitives/test_aes.py index 5b706842..e9ef3853 100644 --- a/tests/hazmat/primitives/test_aes.py +++ b/tests/hazmat/primitives/test_aes.py @@ -15,6 +15,7 @@ from __future__ import absolute_import, division, print_function import binascii import os + import pytest from cryptography.hazmat.primitives.ciphers import algorithms, modes diff --git a/tests/hazmat/primitives/test_arc4.py b/tests/hazmat/primitives/test_arc4.py index d506a8a1..f2e2452c 100644 --- a/tests/hazmat/primitives/test_arc4.py +++ b/tests/hazmat/primitives/test_arc4.py @@ -15,6 +15,7 @@ from __future__ import absolute_import, division, print_function import binascii import os + import pytest from cryptography.hazmat.primitives.ciphers import algorithms diff --git a/tests/hazmat/primitives/test_blowfish.py b/tests/hazmat/primitives/test_blowfish.py index 2d5dc521..79ceabe7 100644 --- a/tests/hazmat/primitives/test_blowfish.py +++ b/tests/hazmat/primitives/test_blowfish.py @@ -15,6 +15,7 @@ from __future__ import absolute_import, division, print_function import binascii import os + import pytest from cryptography.hazmat.primitives.ciphers import algorithms, modes diff --git a/tests/hazmat/primitives/test_camellia.py b/tests/hazmat/primitives/test_camellia.py index 0b6c37fb..c376220e 100644 --- a/tests/hazmat/primitives/test_camellia.py +++ b/tests/hazmat/primitives/test_camellia.py @@ -15,6 +15,7 @@ from __future__ import absolute_import, division, print_function import binascii import os + import pytest from cryptography.hazmat.primitives.ciphers import algorithms, modes diff --git a/tests/hazmat/primitives/test_cast5.py b/tests/hazmat/primitives/test_cast5.py index 2ebc040b..a4789c65 100644 --- a/tests/hazmat/primitives/test_cast5.py +++ b/tests/hazmat/primitives/test_cast5.py @@ -15,6 +15,7 @@ from __future__ import absolute_import, division, print_function import binascii import os + import pytest from cryptography.hazmat.primitives.ciphers import algorithms, modes diff --git a/tests/hazmat/primitives/test_hash_vectors.py b/tests/hazmat/primitives/test_hash_vectors.py index 5c9e9bed..d9febea9 100644 --- a/tests/hazmat/primitives/test_hash_vectors.py +++ b/tests/hazmat/primitives/test_hash_vectors.py @@ -14,6 +14,7 @@ from __future__ import absolute_import, division, print_function import os + import pytest from cryptography.hazmat.primitives import hashes -- cgit v1.2.3 From 2b3f94271209883aab4181ac5401c699c5c60b75 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 24 Dec 2013 21:55:24 -0800 Subject: Move stuff around and coverage --- tests/conftest.py | 8 ++++---- tests/skip_check.py | 24 ------------------------ tests/test_skip_check.py | 31 ------------------------------- tests/test_utils.py | 21 ++++++++++++++++++++- tests/utils.py | 12 +++++++++++- 5 files changed, 35 insertions(+), 61 deletions(-) delete mode 100644 tests/skip_check.py delete mode 100644 tests/test_skip_check.py diff --git a/tests/conftest.py b/tests/conftest.py index 91ba988f..e059b630 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,7 +4,7 @@ from cryptography.hazmat.backends.interfaces import ( HMACBackend, CipherBackend, HashBackend ) -from .skip_check import skip_check +from .utils import check_for_iface def pytest_generate_tests(metafunc): @@ -16,6 +16,6 @@ def pytest_generate_tests(metafunc): @pytest.mark.trylast def pytest_runtest_setup(item): - skip_check('hmac', HMACBackend, item) - skip_check('cipher', CipherBackend, item) - skip_check('hash', HashBackend, item) + check_for_iface("hmac", HMACBackend, item) + check_for_iface("cipher", CipherBackend, item) + check_for_iface("hash", HashBackend, item) diff --git a/tests/skip_check.py b/tests/skip_check.py deleted file mode 100644 index 42a152ea..00000000 --- a/tests/skip_check.py +++ /dev/null @@ -1,24 +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. - -from __future__ import absolute_import, division, print_function - -import pytest - - -def skip_check(name, iface, item): - if name in item.keywords and "backend" in item.funcargs: - if not isinstance(item.funcargs["backend"], iface): - pytest.skip("{0} backend does not support {1}".format( - item.funcargs["backend"], name - )) diff --git a/tests/test_skip_check.py b/tests/test_skip_check.py deleted file mode 100644 index 73a6e563..00000000 --- a/tests/test_skip_check.py +++ /dev/null @@ -1,31 +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. - -from __future__ import absolute_import, division, print_function - -import pretend - -import pytest - -from .skip_check import skip_check - - -class FakeInterface(object): - pass - - -def test_skip_check(): - item = pretend.stub(keywords=["fake_name"], funcargs={"backend": True}) - with pytest.raises(pytest.skip.Exception) as exc_info: - skip_check("fake_name", FakeInterface, item) - assert exc_info.value.args[0] == "True backend does not support fake_name" diff --git a/tests/test_utils.py b/tests/test_utils.py index 5c58fd76..a65091ff 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -14,14 +14,33 @@ import os import textwrap +import pretend + import pytest from .utils import ( load_nist_vectors, load_vectors_from_file, load_cryptrec_vectors, - load_openssl_vectors, load_hash_vectors, + load_openssl_vectors, load_hash_vectors, check_for_iface ) +class FakeInterface(object): + pass + + +def test_check_for_iface(): + item = pretend.stub(keywords=["fake_name"], funcargs={"backend": True}) + with pytest.raises(pytest.skip.Exception) as exc_info: + check_for_iface("fake_name", FakeInterface, item) + assert exc_info.value.args[0] == "True backend does not support fake_name" + + item = pretend.stub( + keywords=["fake_name"], + funcargs={"backend": FakeInterface()} + ) + check_for_iface("fake_name", FakeInterface, item) + + def test_load_nist_vectors(): vector_data = textwrap.dedent(""" # CAVS 11.1 diff --git a/tests/utils.py b/tests/utils.py index 94f97d59..82021a5f 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -11,7 +11,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os.path +import os + +import pytest + + +def check_for_iface(name, iface, item): + if name in item.keywords and "backend" in item.funcargs: + if not isinstance(item.funcargs["backend"], iface): + pytest.skip("{0} backend does not support {1}".format( + item.funcargs["backend"], name + )) def load_vectors_from_file(filename, loader): -- cgit v1.2.3