diff options
author | Jean-Paul Calderone <exarkun@twistedmatrix.com> | 2013-12-27 11:09:42 -0500 |
---|---|---|
committer | Jean-Paul Calderone <exarkun@twistedmatrix.com> | 2013-12-27 11:09:42 -0500 |
commit | 08adc00087c8fe128abc2317776de1f974f4eed6 (patch) | |
tree | 9baacf858eb2ab752505cec675ddda118ed2f35d | |
parent | cf99cc77f863a7254d449ecb5f80a35ad7db11ab (diff) | |
parent | b645521e84026633f666aa107816ac2fc5e05cc6 (diff) | |
download | cryptography-08adc00087c8fe128abc2317776de1f974f4eed6.tar.gz cryptography-08adc00087c8fe128abc2317776de1f974f4eed6.tar.bz2 cryptography-08adc00087c8fe128abc2317776de1f974f4eed6.zip |
Merge remote-tracking branch 'origin/master' into some-typedef-fixes
32 files changed, 301 insertions, 47 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 @@ -60,6 +60,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): """ Create a HashContext for calculating a message authentication code. diff --git a/cryptography/hazmat/backends/openssl/asn1.py b/cryptography/hazmat/backends/openssl/asn1.py index 385c5e8c..e285954a 100644 --- a/cryptography/hazmat/backends/openssl/asn1.py +++ b/cryptography/hazmat/backends/openssl/asn1.py @@ -109,7 +109,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_EXP *); +ASN1_ITEM_EXP *ASN1_ITEM_ptr(ASN1_ITEM_EXP *); /* These aren't macros these arguments are all const X on openssl > 1.0.x */ 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/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/evp.py b/cryptography/hazmat/backends/openssl/evp.py index 8cf96b2d..0662b1ef 100644 --- a/cryptography/hazmat/backends/openssl/evp.py +++ b/cryptography/hazmat/backends/openssl/evp.py @@ -103,12 +103,12 @@ 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 long Cryptography_HAS_GCM = 1; #else -const int Cryptography_HAS_GCM = 0; -const int EVP_CTRL_GCM_GET_TAG = -1; -const int EVP_CTRL_GCM_SET_TAG = -1; -const int EVP_CTRL_GCM_SET_IVLEN = -1; +const long Cryptography_HAS_GCM = 0; +const long EVP_CTRL_GCM_GET_TAG = -1; +const long EVP_CTRL_GCM_SET_TAG = -1; +const long EVP_CTRL_GCM_SET_IVLEN = -1; #endif """ 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..f99c2636 100644 --- a/cryptography/hazmat/backends/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py @@ -22,6 +22,16 @@ 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; + +/* 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; @@ -36,6 +46,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; @@ -43,7 +54,6 @@ static const int SSL_OP_NETSCAPE_CHALLENGE_BUG; static const int SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG; static const int SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG; static const int SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER; -static const int SSL_OP_MSIE_SSLV2_RSA_PADDING; static const int SSL_OP_SSLEAY_080_CLIENT_DH_BUG; static const int SSL_OP_TLS_D5_BUG; static const int SSL_OP_TLS_BLOCK_PADDING_BUG; @@ -90,6 +100,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; @@ -132,8 +143,8 @@ 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 (*)()); -void (*SSL_get_info_callback(const SSL *))(); +void SSL_set_info_callback(SSL *ssl, void (*)(const SSL *, int, int)); +void (*SSL_get_info_callback(const SSL *))(const SSL *, int, int); SSL *SSL_new(SSL_CTX *); void SSL_free(SSL *); int SSL_set_fd(SSL *, int); @@ -195,7 +206,7 @@ long SSL_get_options(SSL *); int SSL_want_read(const SSL *); int SSL_want_write(const SSL *); -int SSL_total_renegotiations(const SSL *); +int SSL_total_renegotiations(SSL *); long SSL_CTX_set_options(SSL_CTX *, long); long SSL_CTX_get_options(SSL_CTX *); @@ -243,24 +254,38 @@ void SSL_CTX_set_tlsext_servername_callback( CUSTOMIZATIONS = """ #ifdef OPENSSL_NO_SSL2 -static const int Cryptography_HAS_SSL2 = 0; +static const long 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_HAS_SSL2 = 1; +static const long Cryptography_HAS_SSL2 = 1; #endif #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME -static const int Cryptography_HAS_TLSEXT_HOSTNAME = 1; +static const long Cryptography_HAS_TLSEXT_HOSTNAME = 1; #else -static const int Cryptography_HAS_TLSEXT_HOSTNAME = 0; +static const long 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)( SSL_CTX *, int (*)(const SSL *, int *, void *)) = NULL; #endif + +#ifdef SSL_MODE_RELEASE_BUFFERS +static const long Cryptography_HAS_RELEASE_BUFFERS = 1; +#else +static const long Cryptography_HAS_RELEASE_BUFFERS = 0; +const long SSL_MODE_RELEASE_BUFFERS = 0; +#endif + +#ifdef SSL_OP_NO_COMPRESSION +static const long Cryptography_HAS_OP_NO_COMPRESSION = 1; +#else +static const long Cryptography_HAS_OP_NO_COMPRESSION = 0; +const long SSL_OP_NO_COMPRESSION = 0; +#endif """ CONDITIONAL_NAMES = { @@ -274,5 +299,14 @@ CONDITIONAL_NAMES = { "SSL_set_tlsext_host_name", "SSL_get_servername", "SSL_CTX_set_tlsext_servername_callback", - ] + ], + + "Cryptography_HAS_RELEASE_BUFFERS": [ + "SSL_MODE_RELEASE_BUFFERS", + ], + + "Cryptography_HAS_OP_NO_COMPRESSION": [ + "SSL_OP_NO_COMPRESSION", + ], + } diff --git a/cryptography/hazmat/backends/openssl/x509.py b/cryptography/hazmat/backends/openssl/x509.py index dd7815fa..5cba476e 100644 --- a/cryptography/hazmat/backends/openssl/x509.py +++ b/cryptography/hazmat/backends/openssl/x509.py @@ -47,7 +47,7 @@ typedef struct { } X509_REVOKED; typedef struct { - struct x509_revoked_st *revoked; + struct stack_st_X509_REVOKED *revoked; ...; } X509_CRL_INFO; @@ -178,8 +178,8 @@ int sk_X509_EXTENSION_push(X509_EXTENSIONS *, X509_EXTENSION *); void sk_X509_EXTENSION_delete(X509_EXTENSIONS *, int); void sk_X509_EXTENSION_free(X509_EXTENSIONS *); -int sk_X509_REVOKED_num(struct x509_revoked_st *); -X509_REVOKED *sk_X509_REVOKED_value(struct x509_revoked_st *, int); +int sk_X509_REVOKED_num(struct stack_st_X509_REVOKED *); +X509_REVOKED *sk_X509_REVOKED_value(struct stack_st_X509_REVOKED *, int); /* These aren't macros these arguments are all const X on openssl > 1.0.x */ int X509_CRL_set_lastUpdate(X509_CRL *, const ASN1_TIME *); diff --git a/docs/api-stability.rst b/docs/api-stability.rst new file mode 100644 index 00000000..e87cc140 --- /dev/null +++ b/docs/api-stability.rst @@ -0,0 +1,51 @@ +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 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. + +Security +~~~~~~~~ + +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 +----------- + +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. 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/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/interfaces.rst b/docs/hazmat/backends/interfaces.rst index b524943d..5b6cd64d 100644 --- a/docs/hazmat/backends/interfaces.rst +++ b/docs/hazmat/backends/interfaces.rst @@ -126,6 +126,17 @@ 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 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. 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 @@ -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..e059b630 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 .utils import check_for_iface + + 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): + check_for_iface("hmac", HMACBackend, item) + check_for_iface("cipher", CipherBackend, item) + check_for_iface("hash", HashBackend, item) diff --git a/tests/hazmat/primitives/test_3des.py b/tests/hazmat/primitives/test_3des.py index 0db56f47..439ca258 100644 --- a/tests/hazmat/primitives/test_3des.py +++ b/tests/hazmat/primitives/test_3des.py @@ -20,12 +20,15 @@ from __future__ import absolute_import, division, print_function import binascii import os +import pytest + from cryptography.hazmat.primitives.ciphers import algorithms, modes 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, @@ -39,6 +42,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,9 +60,14 @@ 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", ) +@pytest.mark.cipher class TestTripleDES_OFB(object): test_KAT = generate_encrypt_test( load_nist_vectors, @@ -69,6 +81,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,9 +99,14 @@ 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", ) +@pytest.mark.cipher class TestTripleDES_CFB(object): test_KAT = generate_encrypt_test( load_nist_vectors, @@ -99,6 +120,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 +138,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..e9ef3853 100644 --- a/tests/hazmat/primitives/test_aes.py +++ b/tests/hazmat/primitives/test_aes.py @@ -16,6 +16,8 @@ from __future__ import absolute_import, division, print_function import binascii import os +import pytest + from cryptography.hazmat.primitives.ciphers import algorithms, modes from .utils import generate_encrypt_test, generate_aead_test @@ -24,6 +26,7 @@ from ...utils import ( ) +@pytest.mark.cipher class TestAES(object): test_CBC = generate_encrypt_test( load_nist_vectors, @@ -47,6 +50,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 +78,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 +106,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 +134,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( diff --git a/tests/hazmat/primitives/test_arc4.py b/tests/hazmat/primitives/test_arc4.py index a9ef2bbe..f2e2452c 100644 --- a/tests/hazmat/primitives/test_arc4.py +++ b/tests/hazmat/primitives/test_arc4.py @@ -16,12 +16,15 @@ from __future__ import absolute_import, division, print_function import binascii import os +import pytest + from cryptography.hazmat.primitives.ciphers import algorithms 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..79ceabe7 100644 --- a/tests/hazmat/primitives/test_blowfish.py +++ b/tests/hazmat/primitives/test_blowfish.py @@ -16,12 +16,15 @@ from __future__ import absolute_import, division, print_function import binascii import os +import pytest + from cryptography.hazmat.primitives.ciphers import algorithms, modes 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..c376220e 100644 --- a/tests/hazmat/primitives/test_camellia.py +++ b/tests/hazmat/primitives/test_camellia.py @@ -16,6 +16,8 @@ from __future__ import absolute_import, division, print_function import binascii import os +import pytest + from cryptography.hazmat.primitives.ciphers import algorithms, modes from .utils import generate_encrypt_test @@ -24,6 +26,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..a4789c65 100644 --- a/tests/hazmat/primitives/test_cast5.py +++ b/tests/hazmat/primitives/test_cast5.py @@ -16,12 +16,15 @@ from __future__ import absolute_import, division, print_function import binascii import os +import pytest + from cryptography.hazmat.primitives.ciphers import algorithms, modes 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..d9febea9 100644 --- a/tests/hazmat/primitives/test_hash_vectors.py +++ b/tests/hazmat/primitives/test_hash_vectors.py @@ -15,12 +15,15 @@ from __future__ import absolute_import, division, print_function import os +import pytest + from cryptography.hazmat.primitives import hashes 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 +38,7 @@ class TestSHA1(object): ) +@pytest.mark.hash class TestSHA224(object): test_SHA224 = generate_hash_test( load_hash_vectors, @@ -49,6 +53,7 @@ class TestSHA224(object): ) +@pytest.mark.hash class TestSHA256(object): test_SHA256 = generate_hash_test( load_hash_vectors, @@ -63,6 +68,7 @@ class TestSHA256(object): ) +@pytest.mark.hash class TestSHA384(object): test_SHA384 = generate_hash_test( load_hash_vectors, @@ -77,6 +83,7 @@ class TestSHA384(object): ) +@pytest.mark.hash class TestSHA512(object): test_SHA512 = generate_hash_test( load_hash_vectors, @@ -91,6 +98,7 @@ class TestSHA512(object): ) +@pytest.mark.hash class TestRIPEMD160(object): test_RIPEMD160 = generate_hash_test( load_hash_vectors, @@ -111,6 +119,7 @@ class TestRIPEMD160(object): ) +@pytest.mark.hash class TestWhirlpool(object): test_whirlpool = generate_hash_test( load_hash_vectors, @@ -133,6 +142,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 124c4377..6d8cc27b 100644 --- a/tests/hazmat/primitives/test_hmac.py +++ b/tests/hazmat/primitives/test_hmac.py @@ -31,10 +31,11 @@ class UnsupportedDummyHash(object): name = "unsupported-dummy-hash" +@pytest.mark.hmac 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..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, @@ -27,11 +30,12 @@ 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", ) +@pytest.mark.hmac class TestHMAC_SHA1(object): test_hmac_sha1 = generate_hmac_test( load_hash_vectors, @@ -40,11 +44,12 @@ 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", ) +@pytest.mark.hmac class TestHMAC_SHA224(object): test_hmac_sha224 = generate_hmac_test( load_hash_vectors, @@ -53,11 +58,12 @@ 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", ) +@pytest.mark.hmac class TestHMAC_SHA256(object): test_hmac_sha256 = generate_hmac_test( load_hash_vectors, @@ -66,11 +72,12 @@ 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", ) +@pytest.mark.hmac class TestHMAC_SHA384(object): test_hmac_sha384 = generate_hmac_test( load_hash_vectors, @@ -79,11 +86,12 @@ 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", ) +@pytest.mark.hmac class TestHMAC_SHA512(object): test_hmac_sha512 = generate_hmac_test( load_hash_vectors, @@ -92,11 +100,12 @@ 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", ) +@pytest.mark.hmac class TestHMAC_RIPEMD160(object): test_hmac_ripemd160 = generate_hmac_test( load_hash_vectors, @@ -105,6 +114,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", ) 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) 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): @@ -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 |