aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml5
-rw-r--r--cryptography/bindings/openssl/api.py13
-rw-r--r--cryptography/bindings/openssl/evp.py1
-rw-r--r--cryptography/bindings/openssl/nid.py44
-rw-r--r--cryptography/bindings/openssl/pem.py44
-rw-r--r--cryptography/bindings/openssl/pkcs12.py34
-rw-r--r--cryptography/bindings/openssl/x509.py187
-rw-r--r--cryptography/bindings/openssl/x509v3.py94
-rw-r--r--docs/contributing.rst17
-rw-r--r--docs/index.rst1
-rw-r--r--docs/security.rst12
-rw-r--r--tests/primitives/test_block.py11
-rw-r--r--tests/primitives/utils.py12
-rw-r--r--tests/test_utils.py14
-rw-r--r--tests/utils.py2
-rw-r--r--tox.ini2
16 files changed, 477 insertions, 16 deletions
diff --git a/.travis.yml b/.travis.yml
index defcd77b..1c35b397 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,6 +6,11 @@ env:
- TOX_ENV=py32
- TOX_ENV=py33
- TOX_ENV=pypy
+ - TOX_ENV=py26 CC=clang
+ - TOX_ENV=py27 CC=clang
+ - TOX_ENV=py32 CC=clang
+ - TOX_ENV=py33 CC=clang
+ - TOX_ENV=pypy CC=clang
- TOX_ENV=docs
- TOX_ENV=pep8
diff --git a/cryptography/bindings/openssl/api.py b/cryptography/bindings/openssl/api.py
index cfd4fc47..3c2cf2e2 100644
--- a/cryptography/bindings/openssl/api.py
+++ b/cryptography/bindings/openssl/api.py
@@ -35,12 +35,17 @@ class API(object):
"engine",
"err",
"evp",
+ "nid",
"opensslv",
+ "pem",
"pkcs7",
+ "pkcs12",
"rand",
"rsa",
"ssl",
- "x509name"
+ "x509",
+ "x509name",
+ "x509v3",
]
def __init__(self):
@@ -123,7 +128,8 @@ class API(object):
return ctx
def update_encrypt_context(self, ctx, plaintext):
- buf = self.ffi.new("unsigned char[]", len(plaintext))
+ block_size = self.lib.EVP_CIPHER_CTX_block_size(ctx)
+ buf = self.ffi.new("unsigned char[]", len(plaintext) + block_size - 1)
outlen = self.ffi.new("int *")
res = self.lib.EVP_EncryptUpdate(
ctx, buf, outlen, plaintext, len(plaintext)
@@ -132,8 +138,7 @@ class API(object):
return self.ffi.buffer(buf)[:outlen[0]]
def finalize_encrypt_context(self, ctx):
- cipher = self.lib.EVP_CIPHER_CTX_cipher(ctx)
- block_size = self.lib.EVP_CIPHER_block_size(cipher)
+ block_size = self.lib.EVP_CIPHER_CTX_block_size(ctx)
buf = self.ffi.new("unsigned char[]", block_size)
outlen = self.ffi.new("int *")
res = self.lib.EVP_EncryptFinal_ex(ctx, buf, outlen)
diff --git a/cryptography/bindings/openssl/evp.py b/cryptography/bindings/openssl/evp.py
index 2b7b0f4c..20159906 100644
--- a/cryptography/bindings/openssl/evp.py
+++ b/cryptography/bindings/openssl/evp.py
@@ -76,4 +76,5 @@ int EVP_VerifyFinal(EVP_MD_CTX *, const unsigned char *, unsigned int,
MACROS = """
int EVP_PKEY_assign_RSA(EVP_PKEY *, RSA *);
int EVP_PKEY_assign_DSA(EVP_PKEY *, DSA *);
+int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *);
"""
diff --git a/cryptography/bindings/openssl/nid.py b/cryptography/bindings/openssl/nid.py
new file mode 100644
index 00000000..0f5b0003
--- /dev/null
+++ b/cryptography/bindings/openssl/nid.py
@@ -0,0 +1,44 @@
+# 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.
+
+INCLUDES = ""
+
+TYPES = """
+static const int NID_undef;
+static const int NID_dsa;
+static const int NID_dsaWithSHA;
+static const int NID_dsaWithSHA1;
+static const int NID_md2;
+static const int NID_md4;
+static const int NID_md5;
+static const int NID_mdc2;
+static const int NID_ripemd160;
+static const int NID_sha;
+static const int NID_sha1;
+static const int NID_sha256;
+static const int NID_sha384;
+static const int NID_sha512;
+static const int NID_sha224;
+static const int NID_sha;
+static const int NID_ecdsa_with_SHA1;
+static const int NID_ecdsa_with_SHA224;
+static const int NID_ecdsa_with_SHA256;
+static const int NID_ecdsa_with_SHA384;
+static const int NID_ecdsa_with_SHA512;
+static const int NID_crl_reason;
+static const int NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+"""
+
+FUNCTIONS = ""
+
+MACROS = ""
diff --git a/cryptography/bindings/openssl/pem.py b/cryptography/bindings/openssl/pem.py
new file mode 100644
index 00000000..8c8f736d
--- /dev/null
+++ b/cryptography/bindings/openssl/pem.py
@@ -0,0 +1,44 @@
+# 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.
+
+INCLUDES = """
+#include <openssl/pem.h>
+"""
+
+TYPES = """
+typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata);
+"""
+
+FUNCTIONS = """
+X509 *PEM_read_bio_X509(BIO *, X509 **, pem_password_cb *, void *);
+int PEM_write_bio_X509(BIO *, X509 *);
+
+int PEM_write_bio_PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *,
+ unsigned char *, int, pem_password_cb *, void *);
+
+EVP_PKEY *PEM_read_bio_PrivateKey(BIO *, EVP_PKEY **, pem_password_cb *,
+ void *);
+
+int PEM_write_bio_X509_REQ(BIO *, X509_REQ *);
+
+X509_REQ *PEM_read_bio_X509_REQ(BIO *, X509_REQ **, pem_password_cb *, void *);
+
+X509_CRL *PEM_read_bio_X509_CRL(BIO *, X509_CRL **, pem_password_cb *, void *);
+
+int PEM_write_bio_X509_CRL(BIO *, X509_CRL *);
+
+PKCS7 *PEM_read_bio_PKCS7(BIO *, PKCS7 **, pem_password_cb *, void *);
+DH *PEM_read_bio_DHparams(BIO *, DH **, pem_password_cb *, void *);
+"""
+
+MACROS = ""
diff --git a/cryptography/bindings/openssl/pkcs12.py b/cryptography/bindings/openssl/pkcs12.py
new file mode 100644
index 00000000..5c002b93
--- /dev/null
+++ b/cryptography/bindings/openssl/pkcs12.py
@@ -0,0 +1,34 @@
+# 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.
+
+INCLUDES = """
+#include <openssl/pkcs12.h>
+"""
+
+TYPES = """
+typedef ... PKCS12;
+"""
+
+FUNCTIONS = """
+void PKCS12_free(PKCS12 *);
+
+PKCS12 *d2i_PKCS12_bio(BIO *, PKCS12 **);
+int i2d_PKCS12_bio(BIO *, PKCS12 *);
+"""
+
+MACROS = """
+int PKCS12_parse(PKCS12 *, const char *, EVP_PKEY **, X509 **,
+ struct stack_st_X509 **);
+PKCS12 *PKCS12_create(char *, char *, EVP_PKEY *, X509 *,
+ struct stack_st_X509 *, int, int, int, int, int);
+"""
diff --git a/cryptography/bindings/openssl/x509.py b/cryptography/bindings/openssl/x509.py
new file mode 100644
index 00000000..9a51a6d0
--- /dev/null
+++ b/cryptography/bindings/openssl/x509.py
@@ -0,0 +1,187 @@
+# 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.
+
+INCLUDES = """
+#include <openssl/ssl.h>
+"""
+
+TYPES = """
+typedef struct {
+ ASN1_OBJECT *algorithm;
+ ...;
+} X509_ALGOR;
+
+typedef struct {
+ X509_ALGOR *signature;
+ ...;
+} X509_CINF;
+
+typedef struct {
+ ASN1_OBJECT *object;
+ ASN1_BOOLEAN critical;
+ ASN1_OCTET_STRING *value;
+} X509_EXTENSION;
+
+typedef ... X509_EXTENSIONS;
+
+typedef ... X509_REQ;
+
+typedef ... x509_revoked_st;
+
+typedef struct {
+ ASN1_INTEGER *serialNumber;
+ ASN1_TIME *revocationDate;
+ X509_EXTENSIONS *extensions;
+ int sequence;
+ ...;
+} X509_REVOKED;
+
+typedef struct {
+ struct x509_revoked_st *revoked;
+ ...;
+} X509_CRL_INFO;
+
+typedef struct {
+ X509_CRL_INFO *crl;
+ ...;
+} X509_CRL;
+
+typedef struct {
+ X509_CINF *cert_info;
+ ...;
+} X509;
+
+typedef ... X509_STORE;
+typedef ... NETSCAPE_SPKI;
+"""
+
+FUNCTIONS = """
+X509 *X509_new();
+void X509_free(X509 *);
+X509 *X509_dup(X509 *);
+
+int X509_print_ex(BIO *, X509 *, unsigned long, unsigned long);
+
+int X509_set_version(X509 *, long);
+
+EVP_PKEY *X509_get_pubkey(X509 *);
+int X509_set_pubkey(X509 *, EVP_PKEY *);
+
+unsigned char *X509_alias_get0(X509 *, int *);
+int X509_sign(X509 *, EVP_PKEY *, const EVP_MD *);
+
+int X509_digest(const X509 *, const EVP_MD *, unsigned char *, unsigned int *);
+
+ASN1_TIME *X509_gmtime_adj(ASN1_TIME *, long);
+
+unsigned long X509_subject_name_hash(X509 *);
+
+X509_NAME *X509_get_subject_name(X509 *);
+int X509_set_subject_name(X509 *, X509_NAME *);
+
+X509_NAME *X509_get_issuer_name(X509 *);
+int X509_set_issuer_name(X509 *, X509_NAME *);
+
+int X509_get_ext_count(X509 *);
+int X509_add_ext(X509 *, X509_EXTENSION *, int);
+X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *);
+X509_EXTENSION *X509_get_ext(X509 *, int);
+int X509_EXTENSION_get_critical(X509_EXTENSION *);
+ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *);
+void X509_EXTENSION_free(X509_EXTENSION *);
+
+int X509_REQ_set_version(X509_REQ *, long);
+X509_REQ *X509_REQ_new();
+void X509_REQ_free(X509_REQ *);
+int X509_REQ_set_pubkey(X509_REQ *, EVP_PKEY *);
+int X509_REQ_sign(X509_REQ *, EVP_PKEY *, const EVP_MD *);
+int X509_REQ_verify(X509_REQ *, EVP_PKEY *);
+EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *);
+int X509_REQ_add_extensions(X509_REQ *, X509_EXTENSIONS *);
+int X509_REQ_print_ex(BIO *, X509_REQ *, unsigned long, unsigned long);
+
+int X509V3_EXT_print(BIO *, X509_EXTENSION *, unsigned long, int);
+ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *);
+
+X509_REVOKED *X509_REVOKED_new();
+void X509_REVOKED_free(X509_REVOKED *);
+
+int X509_REVOKED_set_serialNumber(X509_REVOKED *, ASN1_INTEGER *);
+
+int X509_REVOKED_add1_ext_i2d(X509_REVOKED *, int, void *, int, unsigned long);
+
+X509_CRL *d2i_X509_CRL_bio(BIO *, X509_CRL **);
+X509_CRL *X509_CRL_new();
+void X509_CRL_free(X509_CRL *);
+int X509_CRL_add0_revoked(X509_CRL *, X509_REVOKED *);
+int i2d_X509_CRL_bio(BIO *, X509_CRL *);
+int X509_CRL_print(BIO *, X509_CRL *);
+int X509_CRL_set_issuer_name(X509_CRL *, X509_NAME *);
+int X509_CRL_sign(X509_CRL *, EVP_PKEY *, const EVP_MD *);
+
+int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *, EVP_PKEY *);
+int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *, EVP_PKEY *, const EVP_MD *);
+char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *);
+EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *);
+int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *, EVP_PKEY *);
+NETSCAPE_SPKI *NETSCAPE_SPKI_new();
+void NETSCAPE_SPKI_free(NETSCAPE_SPKI *);
+
+/* ASN1 serialization */
+int i2d_X509_bio(BIO *, X509 *);
+X509 *d2i_X509_bio(BIO *, X509 **);
+
+int i2d_X509_REQ_bio(BIO *, X509_REQ *);
+X509_REQ *d2i_X509_REQ_bio(BIO *, X509_REQ **);
+
+int i2d_PrivateKey_bio(BIO *, EVP_PKEY *);
+EVP_PKEY *d2i_PrivateKey_bio(BIO *, EVP_PKEY **);
+
+ASN1_INTEGER *X509_get_serialNumber(X509 *);
+int X509_set_serialNumber(X509 *, ASN1_INTEGER *);
+
+/* X509_STORE */
+X509_STORE *X509_STORE_new();
+void X509_STORE_free(X509_STORE *);
+int X509_STORE_add_cert(X509_STORE *, X509 *);
+"""
+
+MACROS = """
+long X509_get_version(X509 *);
+
+ASN1_TIME *X509_get_notBefore(X509 *);
+ASN1_TIME *X509_get_notAfter(X509 *);
+
+long X509_REQ_get_version(X509_REQ *);
+X509_NAME *X509_REQ_get_subject_name(X509_REQ *);
+
+struct stack_st_X509 *sk_X509_new_null();
+void sk_X509_free(struct stack_st_X509 *);
+int sk_X509_num(struct stack_st_X509 *);
+int sk_X509_push(struct stack_st_X509 *, X509 *);
+X509 *sk_X509_value(struct stack_st_X509 *, int);
+
+X509_EXTENSIONS *sk_X509_EXTENSION_new_null();
+int sk_X509_EXTENSION_num(X509_EXTENSIONS *);
+X509_EXTENSION *sk_X509_EXTENSION_value(X509_EXTENSIONS *, int);
+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);
+
+/* 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 *);
+int X509_CRL_set_nextUpdate(X509_CRL *, const ASN1_TIME *);
+"""
diff --git a/cryptography/bindings/openssl/x509v3.py b/cryptography/bindings/openssl/x509v3.py
new file mode 100644
index 00000000..413bde5f
--- /dev/null
+++ b/cryptography/bindings/openssl/x509v3.py
@@ -0,0 +1,94 @@
+# 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.
+
+INCLUDES = """
+#include <openssl/x509v3.h>
+"""
+
+TYPES = """
+typedef struct {
+ X509 *issuer_cert;
+ X509 *subject_cert;
+ ...;
+} X509V3_CTX;
+
+typedef void * (*X509V3_EXT_D2I)(void *, const unsigned char **, long);
+
+typedef struct {
+ ASN1_ITEM_EXP *it;
+ X509V3_EXT_D2I d2i;
+ ...;
+} X509V3_EXT_METHOD;
+
+static const int GEN_OTHERNAME;
+static const int GEN_EMAIL;
+static const int GEN_X400;
+static const int GEN_DNS;
+static const int GEN_URI;
+static const int GEN_DIRNAME;
+static const int GEN_EDIPARTY;
+static const int GEN_IPADD;
+static const int GEN_RID;
+
+typedef struct {
+ ...;
+} OTHERNAME;
+
+typedef struct {
+ ...;
+} EDIPARTYNAME;
+
+typedef struct {
+ int type;
+ union {
+ char *ptr;
+ OTHERNAME *otherName; /* otherName */
+ ASN1_IA5STRING *rfc822Name;
+ ASN1_IA5STRING *dNSName;
+ ASN1_TYPE *x400Address;
+ X509_NAME *directoryName;
+ EDIPARTYNAME *ediPartyName;
+ ASN1_IA5STRING *uniformResourceIdentifier;
+ ASN1_OCTET_STRING *iPAddress;
+ ASN1_OBJECT *registeredID;
+
+ /* Old names */
+ ASN1_OCTET_STRING *ip; /* iPAddress */
+ X509_NAME *dirn; /* dirn */
+ ASN1_IA5STRING *ia5; /* rfc822Name, dNSName, */
+ /* uniformResourceIdentifier */
+ ASN1_OBJECT *rid; /* registeredID */
+ ASN1_TYPE *other; /* x400Address */
+ } d;
+ ...;
+} GENERAL_NAME;
+
+typedef struct stack_st_GENERAL_NAME GENERAL_NAMES;
+"""
+
+FUNCTIONS = """
+void X509V3_set_ctx(X509V3_CTX *, X509 *, X509 *, X509_REQ *, X509_CRL *, int);
+X509_EXTENSION *X509V3_EXT_nconf(CONF *, X509V3_CTX *, char *, char *);
+int GENERAL_NAME_print(BIO *, GENERAL_NAME *);
+"""
+
+MACROS = """
+void *X509V3_set_ctx_nodb(X509V3_CTX *);
+int sk_GENERAL_NAME_num(struct stack_st_GENERAL_NAME *);
+int sk_GENERAL_NAME_push(struct stack_st_GENERAL_NAME *, GENERAL_NAME *);
+GENERAL_NAME *sk_GENERAL_NAME_value(struct stack_st_GENERAL_NAME *, int);
+
+/* These aren't macros these functions are all const X on openssl > 1.0.x */
+const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *);
+const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int);
+"""
diff --git a/docs/contributing.rst b/docs/contributing.rst
index b125d1af..6a76c705 100644
--- a/docs/contributing.rst
+++ b/docs/contributing.rst
@@ -32,11 +32,8 @@ devastating, ``cryptography`` has a strict code review policy:
The purpose of these policies is to minimize the chances we merge a change
which jeopardizes our users' security.
-We do not yet have a formal security contact. To report security issues in
-``cryptography`` you should email ``alex.gaynor@gmail.com``, messages may be
-encrypted with PGP to key fingerprint
-``E27D 4AA0 1651 72CB C5D2 AF2B 125F 5C67 DFE9 4084`` (this public key is
-available from most commonly-used keyservers).
+If you believe you've identified a security issue in ``cryptography``, please
+follow the directions on the :doc:`security page </security>`.
Code
----
@@ -65,6 +62,16 @@ Don't name parameters:
// Bad
long f(long x);
+...unless they're inside a struct:
+
+.. code-block:: c
+
+ struct my_struct {
+ char *name;
+ int number;
+ ...;
+ };
+
Don't include stray ``void`` parameters:
.. code-block:: c
diff --git a/docs/index.rst b/docs/index.rst
index 5cc455f6..a868a5d6 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -34,4 +34,5 @@ Contents
primitives/index
bindings/index
contributing
+ security
community
diff --git a/docs/security.rst b/docs/security.rst
new file mode 100644
index 00000000..36c8e0f7
--- /dev/null
+++ b/docs/security.rst
@@ -0,0 +1,12 @@
+Security
+========
+
+We take the security of ``cryptography`` seriously. If you believe you've
+identified a security issue in it, please report it to
+``alex.gaynor@gmail.com``. Message may be encrypted with PGP using key
+fingerprint ``E27D 4AA0 1651 72CB C5D2 AF2B 125F 5C67 DFE9 4084`` (this public
+key is available from most commonly-used keyservers).
+
+Once you’ve submitted an issue via email, you should receive an acknowledgment
+within 48 hours, and depending on the action to be taken, you may receive
+further followup emails.
diff --git a/tests/primitives/test_block.py b/tests/primitives/test_block.py
index f4d3f467..9f5905bf 100644
--- a/tests/primitives/test_block.py
+++ b/tests/primitives/test_block.py
@@ -63,3 +63,14 @@ class TestBlockCipher(object):
with pytest.raises(ValueError):
cipher.finalize()
+
+ def test_unaligned_block_encryption(self, api):
+ cipher = BlockCipher(
+ ciphers.AES(binascii.unhexlify(b"0" * 32)),
+ modes.ECB(),
+ api
+ )
+ ct = cipher.encrypt(b"a" * 15)
+ assert ct == b""
+ ct += cipher.encrypt(b"a" * 65)
+ assert len(ct) == 80
diff --git a/tests/primitives/utils.py b/tests/primitives/utils.py
index 8b32700b..a3759b03 100644
--- a/tests/primitives/utils.py
+++ b/tests/primitives/utils.py
@@ -43,7 +43,7 @@ def encrypt_test(api, cipher_factory, mode_factory, params, only_if,
def generate_hash_test(param_loader, path, file_names, hash_cls,
- only_if=lambda api: True, skip_message=None):
+ only_if=None, skip_message=None):
def test_hash(self):
for api in _ALL_APIS:
for file_name in file_names:
@@ -60,7 +60,7 @@ def generate_hash_test(param_loader, path, file_names, hash_cls,
def hash_test(api, hash_cls, params, only_if, skip_message):
- if not only_if(api):
+ if only_if is not None and not only_if(api):
pytest.skip(skip_message)
msg = params[0]
md = params[1]
@@ -70,7 +70,7 @@ def hash_test(api, hash_cls, params, only_if, skip_message):
def generate_base_hash_test(hash_cls, digest_size, block_size,
- only_if=lambda api: True, skip_message=None):
+ only_if=None, skip_message=None):
def test_base_hash(self):
for api in _ALL_APIS:
yield (
@@ -87,7 +87,7 @@ def generate_base_hash_test(hash_cls, digest_size, block_size,
def base_hash_test(api, hash_cls, digest_size, block_size, only_if,
skip_message):
- if not only_if(api):
+ if only_if is not None and not only_if(api):
pytest.skip(skip_message)
m = hash_cls(api=api)
assert m.digest_size == digest_size
@@ -97,7 +97,7 @@ def base_hash_test(api, hash_cls, digest_size, block_size, only_if,
assert m._ctx != m_copy._ctx
-def generate_long_string_hash_test(hash_factory, md, only_if=lambda api: True,
+def generate_long_string_hash_test(hash_factory, md, only_if=None,
skip_message=None):
def test_long_string_hash(self):
for api in _ALL_APIS:
@@ -113,7 +113,7 @@ def generate_long_string_hash_test(hash_factory, md, only_if=lambda api: True,
def long_string_hash_test(api, hash_factory, md, only_if, skip_message):
- if not only_if(api):
+ if only_if is not None and not only_if(api):
pytest.skip(skip_message)
m = hash_factory(api)
m.update(b"a" * 1000000)
diff --git a/tests/test_utils.py b/tests/test_utils.py
index a9bb6a87..3fe9e570 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -269,6 +269,20 @@ def test_load_cryptrec_vectors():
]
+def test_load_cryptrec_vectors_invalid():
+ vector_data = textwrap.dedent("""
+ # Vectors taken from http://info.isl.ntt.co.jp/crypt/eng/camellia/
+ # Download is t_camelia.txt
+
+ # Camellia with 128-bit key
+
+ E No.001 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ """).splitlines()
+
+ with pytest.raises(ValueError):
+ load_cryptrec_vectors(vector_data)
+
+
def test_load_cryptrec_vectors_from_file_encrypt():
test_set = load_cryptrec_vectors_from_file(
"Camellia/NTT/camellia-128-ecb.txt"
diff --git a/tests/utils.py b/tests/utils.py
index 03b780f8..fa7cc68d 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -90,6 +90,8 @@ def load_cryptrec_vectors(vector_data):
"plaintext": pt,
"ciphertext": ct
})
+ else:
+ raise ValueError("Invalid line in file '{}'".format(line))
return cryptrec_list
diff --git a/tox.ini b/tox.ini
index 0a28af15..e72eb58b 100644
--- a/tox.ini
+++ b/tox.ini
@@ -8,7 +8,7 @@ deps =
pretend
commands =
coverage run --source=cryptography/,tests/ -m pytest
- coverage report -m
+ coverage report -m --fail-under 100
[testenv:docs]
deps = sphinx