aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Paul Calderone <exarkun@twistedmatrix.com>2013-12-27 11:09:42 -0500
committerJean-Paul Calderone <exarkun@twistedmatrix.com>2013-12-27 11:09:42 -0500
commit08adc00087c8fe128abc2317776de1f974f4eed6 (patch)
tree9baacf858eb2ab752505cec675ddda118ed2f35d
parentcf99cc77f863a7254d449ecb5f80a35ad7db11ab (diff)
parentb645521e84026633f666aa107816ac2fc5e05cc6 (diff)
downloadcryptography-08adc00087c8fe128abc2317776de1f974f4eed6.tar.gz
cryptography-08adc00087c8fe128abc2317776de1f974f4eed6.tar.bz2
cryptography-08adc00087c8fe128abc2317776de1f974f4eed6.zip
Merge remote-tracking branch 'origin/master' into some-typedef-fixes
-rw-r--r--cryptography/hazmat/backends/interfaces.py7
-rw-r--r--cryptography/hazmat/backends/openssl/asn1.py2
-rw-r--r--cryptography/hazmat/backends/openssl/backend.py3
-rw-r--r--cryptography/hazmat/backends/openssl/crypto.py6
-rw-r--r--cryptography/hazmat/backends/openssl/evp.py10
-rw-r--r--cryptography/hazmat/backends/openssl/opensslv.py1
-rw-r--r--cryptography/hazmat/backends/openssl/rand.py1
-rw-r--r--cryptography/hazmat/backends/openssl/ssl.py52
-rw-r--r--cryptography/hazmat/backends/openssl/x509.py6
-rw-r--r--docs/api-stability.rst51
-rw-r--r--docs/contributing.rst1
-rw-r--r--docs/hazmat/backends/index.rst24
-rw-r--r--docs/hazmat/backends/interfaces.rst11
-rw-r--r--docs/hazmat/backends/openssl.rst4
-rw-r--r--docs/index.rst1
-rw-r--r--pytest.ini4
-rw-r--r--tests/conftest.py16
-rw-r--r--tests/hazmat/primitives/test_3des.py29
-rw-r--r--tests/hazmat/primitives/test_aes.py19
-rw-r--r--tests/hazmat/primitives/test_arc4.py3
-rw-r--r--tests/hazmat/primitives/test_block.py3
-rw-r--r--tests/hazmat/primitives/test_blowfish.py3
-rw-r--r--tests/hazmat/primitives/test_camellia.py3
-rw-r--r--tests/hazmat/primitives/test_cast5.py3
-rw-r--r--tests/hazmat/primitives/test_hash_vectors.py10
-rw-r--r--tests/hazmat/primitives/test_hashes.py9
-rw-r--r--tests/hazmat/primitives/test_hmac.py3
-rw-r--r--tests/hazmat/primitives/test_hmac_vectors.py23
-rw-r--r--tests/hazmat/primitives/utils.py3
-rw-r--r--tests/test_utils.py21
-rw-r--r--tests/utils.py12
-rw-r--r--tox.ini4
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
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..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):
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