aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/conftest.py9
-rw-r--r--tests/hazmat/backends/test_openssl.py21
-rw-r--r--tests/hazmat/bindings/test_commoncrypto.py32
-rw-r--r--tests/hazmat/bindings/test_openssl.py3
-rw-r--r--tests/hazmat/primitives/test_block.py37
-rw-r--r--tests/hazmat/primitives/test_cast5.py41
-rw-r--r--tests/hazmat/primitives/test_ciphers.py15
-rw-r--r--tests/hazmat/primitives/test_hash_vectors.py16
-rw-r--r--tests/hazmat/primitives/test_hashes.py16
-rw-r--r--tests/hazmat/primitives/test_hmac.py2
-rw-r--r--tests/hazmat/primitives/test_hmac_vectors.py14
-rw-r--r--tests/test_fernet.py150
-rw-r--r--tests/test_utils.py2
-rw-r--r--tests/utils.py4
-rw-r--r--tests/vectors/fernet/generate.json9
-rw-r--r--tests/vectors/fernet/invalid.json58
-rw-r--r--tests/vectors/fernet/verify.json9
17 files changed, 352 insertions, 86 deletions
diff --git a/tests/conftest.py b/tests/conftest.py
index 0ddc3338..1d9f96ed 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,5 +1,6 @@
import pytest
+from cryptography.hazmat.backends import _ALL_BACKENDS
from cryptography.hazmat.backends.interfaces import (
HMACBackend, CipherBackend, HashBackend
)
@@ -7,11 +8,9 @@ from cryptography.hazmat.backends.interfaces import (
from .utils import check_for_iface, check_backend_support
-def pytest_generate_tests(metafunc):
- from cryptography.hazmat.backends import _ALL_BACKENDS
-
- if "backend" in metafunc.fixturenames:
- metafunc.parametrize("backend", _ALL_BACKENDS)
+@pytest.fixture(params=_ALL_BACKENDS)
+def backend(request):
+ return request.param
@pytest.mark.trylast
diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py
index b7d999b8..51eb408f 100644
--- a/tests/hazmat/backends/test_openssl.py
+++ b/tests/hazmat/backends/test_openssl.py
@@ -119,6 +119,9 @@ def unregister_dummy_engine():
class DummyMode(object):
name = "dummy-mode"
+ def validate_for_algorithm(self, algorithm):
+ pass
+
@utils.register_interface(interfaces.CipherAlgorithm)
class DummyCipher(object):
@@ -185,6 +188,24 @@ class TestOpenSSL(object):
0
)
+ def test_ssl_ciphers_registered(self):
+ meth = backend._lib.TLSv1_method()
+ ctx = backend._lib.SSL_CTX_new(meth)
+ assert ctx != backend._ffi.NULL
+ backend._lib.SSL_CTX_free(ctx)
+
+ def test_evp_ciphers_registered(self):
+ cipher = backend._lib.EVP_get_cipherbyname(b"aes-256-cbc")
+ assert cipher != backend._ffi.NULL
+
+ def test_error_strings_loaded(self):
+ # returns a value in a static buffer
+ err = backend._lib.ERR_error_string(101183626, backend._ffi.NULL)
+ assert backend._ffi.string(err) == (
+ b"error:0607F08A:digital envelope routines:EVP_EncryptFinal_ex:"
+ b"data not multiple of block length"
+ )
+
# This test is not in the next class because to check if it's really
# default we don't want to run the setup_method before it
def test_osrandom_engine_is_default(self):
diff --git a/tests/hazmat/bindings/test_commoncrypto.py b/tests/hazmat/bindings/test_commoncrypto.py
new file mode 100644
index 00000000..db3d1b74
--- /dev/null
+++ b/tests/hazmat/bindings/test_commoncrypto.py
@@ -0,0 +1,32 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import pytest
+
+from cryptography.hazmat.bindings.commoncrypto.binding import Binding
+
+
+@pytest.mark.skipif(not Binding.is_available(),
+ reason="CommonCrypto not available")
+class TestCommonCrypto(object):
+ def test_binding_loads(self):
+ binding = Binding()
+ assert binding
+ assert binding.lib
+ assert binding.ffi
+
+ def test_binding_returns_same_lib(self):
+ binding = Binding()
+ binding2 = Binding()
+ assert binding.lib == binding2.lib
+ assert binding.ffi == binding2.ffi
diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py
index 31f736ab..d1e85058 100644
--- a/tests/hazmat/bindings/test_openssl.py
+++ b/tests/hazmat/bindings/test_openssl.py
@@ -20,3 +20,6 @@ class TestOpenSSL(object):
assert binding
assert binding.lib
assert binding.ffi
+
+ def test_is_available(self):
+ assert Binding.is_available() is True
diff --git a/tests/hazmat/primitives/test_block.py b/tests/hazmat/primitives/test_block.py
index 30cf1d60..f758ffaa 100644
--- a/tests/hazmat/primitives/test_block.py
+++ b/tests/hazmat/primitives/test_block.py
@@ -35,6 +35,9 @@ from .utils import (
class DummyMode(object):
name = "dummy-mode"
+ def validate_for_algorithm(self, algorithm):
+ pass
+
@utils.register_interface(interfaces.CipherAlgorithm)
class DummyCipher(object):
@@ -152,3 +155,37 @@ class TestAEADCipherContext(object):
algorithms.AES,
modes.GCM,
)
+
+
+class TestModeValidation(object):
+ def test_cbc(self, backend):
+ with pytest.raises(ValueError):
+ Cipher(
+ algorithms.AES(b"\x00" * 16),
+ modes.CBC(b"abc"),
+ backend,
+ )
+
+ def test_ofb(self, backend):
+ with pytest.raises(ValueError):
+ Cipher(
+ algorithms.AES(b"\x00" * 16),
+ modes.OFB(b"abc"),
+ backend,
+ )
+
+ def test_cfb(self, backend):
+ with pytest.raises(ValueError):
+ Cipher(
+ algorithms.AES(b"\x00" * 16),
+ modes.CFB(b"abc"),
+ backend,
+ )
+
+ def test_ctr(self, backend):
+ with pytest.raises(ValueError):
+ Cipher(
+ algorithms.AES(b"\x00" * 16),
+ modes.CTR(b"abc"),
+ backend,
+ )
diff --git a/tests/hazmat/primitives/test_cast5.py b/tests/hazmat/primitives/test_cast5.py
deleted file mode 100644
index d65a86b2..00000000
--- a/tests/hazmat/primitives/test_cast5.py
+++ /dev/null
@@ -1,41 +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 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.supported(
- only_if=lambda backend: backend.cipher_supported(
- algorithms.CAST5("\x00" * 16), modes.ECB()
- ),
- skip_message="Does not support CAST5 ECB",
-)
-@pytest.mark.cipher
-class TestCAST5(object):
- test_ECB = generate_encrypt_test(
- load_nist_vectors,
- os.path.join("ciphers", "CAST5"),
- ["cast5-ecb.txt"],
- lambda key, **kwargs: algorithms.CAST5(binascii.unhexlify((key))),
- lambda **kwargs: modes.ECB(),
- )
diff --git a/tests/hazmat/primitives/test_ciphers.py b/tests/hazmat/primitives/test_ciphers.py
index 653f7ce6..6a7b2f93 100644
--- a/tests/hazmat/primitives/test_ciphers.py
+++ b/tests/hazmat/primitives/test_ciphers.py
@@ -18,7 +18,7 @@ import binascii
import pytest
from cryptography.hazmat.primitives.ciphers.algorithms import (
- AES, Camellia, TripleDES, Blowfish, CAST5, ARC4
+ AES, Camellia, TripleDES, Blowfish, ARC4
)
@@ -80,19 +80,6 @@ class TestBlowfish(object):
Blowfish(binascii.unhexlify(b"0" * 6))
-class TestCAST5(object):
- @pytest.mark.parametrize(("key", "keysize"), [
- (b"0" * (keysize // 4), keysize) for keysize in range(40, 129, 8)
- ])
- def test_key_size(self, key, keysize):
- cipher = CAST5(binascii.unhexlify(key))
- assert cipher.key_size == keysize
-
- def test_invalid_key_size(self):
- with pytest.raises(ValueError):
- CAST5(binascii.unhexlify(b"0" * 34))
-
-
class TestARC4(object):
@pytest.mark.parametrize(("key", "keysize"), [
(b"0" * 10, 40),
diff --git a/tests/hazmat/primitives/test_hash_vectors.py b/tests/hazmat/primitives/test_hash_vectors.py
index 13ffc3fd..ca97fc11 100644
--- a/tests/hazmat/primitives/test_hash_vectors.py
+++ b/tests/hazmat/primitives/test_hash_vectors.py
@@ -24,7 +24,7 @@ from ...utils import load_hash_vectors
@pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.SHA1),
+ only_if=lambda backend: backend.hash_supported(hashes.SHA1()),
skip_message="Does not support SHA1",
)
@pytest.mark.hash
@@ -41,7 +41,7 @@ class TestSHA1(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.SHA224),
+ only_if=lambda backend: backend.hash_supported(hashes.SHA224()),
skip_message="Does not support SHA224",
)
@pytest.mark.hash
@@ -58,7 +58,7 @@ class TestSHA224(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.SHA256),
+ only_if=lambda backend: backend.hash_supported(hashes.SHA256()),
skip_message="Does not support SHA256",
)
@pytest.mark.hash
@@ -75,7 +75,7 @@ class TestSHA256(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.SHA384),
+ only_if=lambda backend: backend.hash_supported(hashes.SHA384()),
skip_message="Does not support SHA384",
)
@pytest.mark.hash
@@ -92,7 +92,7 @@ class TestSHA384(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.SHA512),
+ only_if=lambda backend: backend.hash_supported(hashes.SHA512()),
skip_message="Does not support SHA512",
)
@pytest.mark.hash
@@ -109,7 +109,7 @@ class TestSHA512(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.RIPEMD160),
+ only_if=lambda backend: backend.hash_supported(hashes.RIPEMD160()),
skip_message="Does not support RIPEMD160",
)
@pytest.mark.hash
@@ -130,7 +130,7 @@ class TestRIPEMD160(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.Whirlpool),
+ only_if=lambda backend: backend.hash_supported(hashes.Whirlpool()),
skip_message="Does not support Whirlpool",
)
@pytest.mark.hash
@@ -153,7 +153,7 @@ class TestWhirlpool(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.MD5),
+ only_if=lambda backend: backend.hash_supported(hashes.MD5()),
skip_message="Does not support MD5",
)
@pytest.mark.hash
diff --git a/tests/hazmat/primitives/test_hashes.py b/tests/hazmat/primitives/test_hashes.py
index c907ef61..9ca2feee 100644
--- a/tests/hazmat/primitives/test_hashes.py
+++ b/tests/hazmat/primitives/test_hashes.py
@@ -70,7 +70,7 @@ class TestHashContext(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.SHA1),
+ only_if=lambda backend: backend.hash_supported(hashes.SHA1()),
skip_message="Does not support SHA1",
)
@pytest.mark.hash
@@ -83,7 +83,7 @@ class TestSHA1(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.SHA224),
+ only_if=lambda backend: backend.hash_supported(hashes.SHA224()),
skip_message="Does not support SHA224",
)
@pytest.mark.hash
@@ -96,7 +96,7 @@ class TestSHA224(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.SHA256),
+ only_if=lambda backend: backend.hash_supported(hashes.SHA256()),
skip_message="Does not support SHA256",
)
@pytest.mark.hash
@@ -109,7 +109,7 @@ class TestSHA256(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.SHA384),
+ only_if=lambda backend: backend.hash_supported(hashes.SHA384()),
skip_message="Does not support SHA384",
)
@pytest.mark.hash
@@ -122,7 +122,7 @@ class TestSHA384(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.SHA512),
+ only_if=lambda backend: backend.hash_supported(hashes.SHA512()),
skip_message="Does not support SHA512",
)
@pytest.mark.hash
@@ -135,7 +135,7 @@ class TestSHA512(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.RIPEMD160),
+ only_if=lambda backend: backend.hash_supported(hashes.RIPEMD160()),
skip_message="Does not support RIPEMD160",
)
@pytest.mark.hash
@@ -148,7 +148,7 @@ class TestRIPEMD160(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.Whirlpool),
+ only_if=lambda backend: backend.hash_supported(hashes.Whirlpool()),
skip_message="Does not support Whirlpool",
)
@pytest.mark.hash
@@ -161,7 +161,7 @@ class TestWhirlpool(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.MD5),
+ only_if=lambda backend: backend.hash_supported(hashes.MD5()),
skip_message="Does not support MD5",
)
@pytest.mark.hash
diff --git a/tests/hazmat/primitives/test_hmac.py b/tests/hazmat/primitives/test_hmac.py
index 04913af6..dd9cdaab 100644
--- a/tests/hazmat/primitives/test_hmac.py
+++ b/tests/hazmat/primitives/test_hmac.py
@@ -34,7 +34,7 @@ class UnsupportedDummyHash(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hmac_supported(hashes.MD5),
+ only_if=lambda backend: backend.hmac_supported(hashes.MD5()),
skip_message="Does not support MD5",
)
@pytest.mark.hmac
diff --git a/tests/hazmat/primitives/test_hmac_vectors.py b/tests/hazmat/primitives/test_hmac_vectors.py
index c5644459..0792080b 100644
--- a/tests/hazmat/primitives/test_hmac_vectors.py
+++ b/tests/hazmat/primitives/test_hmac_vectors.py
@@ -22,7 +22,7 @@ from ...utils import load_hash_vectors
@pytest.mark.supported(
- only_if=lambda backend: backend.hmac_supported(hashes.MD5),
+ only_if=lambda backend: backend.hmac_supported(hashes.MD5()),
skip_message="Does not support MD5",
)
@pytest.mark.hmac
@@ -38,7 +38,7 @@ class TestHMAC_MD5(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hmac_supported(hashes.SHA1),
+ only_if=lambda backend: backend.hmac_supported(hashes.SHA1()),
skip_message="Does not support SHA1",
)
@pytest.mark.hmac
@@ -54,7 +54,7 @@ class TestHMAC_SHA1(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hmac_supported(hashes.SHA224),
+ only_if=lambda backend: backend.hmac_supported(hashes.SHA224()),
skip_message="Does not support SHA224",
)
@pytest.mark.hmac
@@ -70,7 +70,7 @@ class TestHMAC_SHA224(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hmac_supported(hashes.SHA256),
+ only_if=lambda backend: backend.hmac_supported(hashes.SHA256()),
skip_message="Does not support SHA256",
)
@pytest.mark.hmac
@@ -86,7 +86,7 @@ class TestHMAC_SHA256(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hmac_supported(hashes.SHA384),
+ only_if=lambda backend: backend.hmac_supported(hashes.SHA384()),
skip_message="Does not support SHA384",
)
@pytest.mark.hmac
@@ -102,7 +102,7 @@ class TestHMAC_SHA384(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hmac_supported(hashes.SHA512),
+ only_if=lambda backend: backend.hmac_supported(hashes.SHA512()),
skip_message="Does not support SHA512",
)
@pytest.mark.hmac
@@ -118,7 +118,7 @@ class TestHMAC_SHA512(object):
@pytest.mark.supported(
- only_if=lambda backend: backend.hmac_supported(hashes.RIPEMD160),
+ only_if=lambda backend: backend.hmac_supported(hashes.RIPEMD160()),
skip_message="Does not support RIPEMD160",
)
@pytest.mark.hmac
diff --git a/tests/test_fernet.py b/tests/test_fernet.py
new file mode 100644
index 00000000..bd4d90a5
--- /dev/null
+++ b/tests/test_fernet.py
@@ -0,0 +1,150 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import base64
+import calendar
+import json
+import os
+import time
+
+import iso8601
+
+import pytest
+
+import six
+
+from cryptography.fernet import Fernet, InvalidToken
+from cryptography.hazmat.backends import default_backend
+from cryptography.hazmat.primitives.ciphers import algorithms, modes
+
+
+def json_parametrize(keys, fname):
+ path = os.path.join(os.path.dirname(__file__), "vectors", "fernet", fname)
+ with open(path) as f:
+ data = json.load(f)
+ return pytest.mark.parametrize(keys, [
+ tuple([entry[k] for k in keys])
+ for entry in data
+ ])
+
+
+@pytest.mark.cipher
+class TestFernet(object):
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.cipher_supported(
+ algorithms.AES("\x00" * 32), modes.CBC("\x00" * 16)
+ ),
+ skip_message="Does not support AES CBC",
+ )
+ @json_parametrize(
+ ("secret", "now", "iv", "src", "token"), "generate.json",
+ )
+ def test_generate(self, secret, now, iv, src, token, backend):
+ f = Fernet(secret.encode("ascii"), backend=backend)
+ actual_token = f._encrypt_from_parts(
+ src.encode("ascii"),
+ calendar.timegm(iso8601.parse_date(now).utctimetuple()),
+ b"".join(map(six.int2byte, iv))
+ )
+ assert actual_token == token.encode("ascii")
+
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.cipher_supported(
+ algorithms.AES("\x00" * 32), modes.CBC("\x00" * 16)
+ ),
+ skip_message="Does not support AES CBC",
+ )
+ @json_parametrize(
+ ("secret", "now", "src", "ttl_sec", "token"), "verify.json",
+ )
+ def test_verify(self, secret, now, src, ttl_sec, token, backend,
+ monkeypatch):
+ f = Fernet(secret.encode("ascii"), backend=backend)
+ current_time = calendar.timegm(iso8601.parse_date(now).utctimetuple())
+ monkeypatch.setattr(time, "time", lambda: current_time)
+ payload = f.decrypt(token.encode("ascii"), ttl=ttl_sec)
+ assert payload == src.encode("ascii")
+
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.cipher_supported(
+ algorithms.AES("\x00" * 32), modes.CBC("\x00" * 16)
+ ),
+ skip_message="Does not support AES CBC",
+ )
+ @json_parametrize(("secret", "token", "now", "ttl_sec"), "invalid.json")
+ def test_invalid(self, secret, token, now, ttl_sec, backend, monkeypatch):
+ f = Fernet(secret.encode("ascii"), backend=backend)
+ current_time = calendar.timegm(iso8601.parse_date(now).utctimetuple())
+ monkeypatch.setattr(time, "time", lambda: current_time)
+ with pytest.raises(InvalidToken):
+ f.decrypt(token.encode("ascii"), ttl=ttl_sec)
+
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.cipher_supported(
+ algorithms.AES("\x00" * 32), modes.CBC("\x00" * 16)
+ ),
+ skip_message="Does not support AES CBC",
+ )
+ def test_invalid_start_byte(self, backend):
+ f = Fernet(Fernet.generate_key(), backend=backend)
+ with pytest.raises(InvalidToken):
+ f.decrypt(base64.urlsafe_b64encode(b"\x81"))
+
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.cipher_supported(
+ algorithms.AES("\x00" * 32), modes.CBC("\x00" * 16)
+ ),
+ skip_message="Does not support AES CBC",
+ )
+ def test_timestamp_too_short(self, backend):
+ f = Fernet(Fernet.generate_key(), backend=backend)
+ with pytest.raises(InvalidToken):
+ f.decrypt(base64.urlsafe_b64encode(b"\x80abc"))
+
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.cipher_supported(
+ algorithms.AES("\x00" * 32), modes.CBC("\x00" * 16)
+ ),
+ skip_message="Does not support AES CBC",
+ )
+ def test_unicode(self, backend):
+ f = Fernet(base64.urlsafe_b64encode(b"\x00" * 32), backend=backend)
+ with pytest.raises(TypeError):
+ f.encrypt(six.u(""))
+ with pytest.raises(TypeError):
+ f.decrypt(six.u(""))
+
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.cipher_supported(
+ algorithms.AES("\x00" * 32), modes.CBC("\x00" * 16)
+ ),
+ skip_message="Does not support AES CBC",
+ )
+ @pytest.mark.parametrize("message", [b"", b"Abc!", b"\x00\xFF\x00\x80"])
+ def test_roundtrips(self, message, backend):
+ f = Fernet(Fernet.generate_key(), backend=backend)
+ assert f.decrypt(f.encrypt(message)) == message
+
+ def test_default_backend(self):
+ f = Fernet(Fernet.generate_key())
+ assert f._backend is default_backend()
+
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.cipher_supported(
+ algorithms.AES("\x00" * 32), modes.CBC("\x00" * 16)
+ ),
+ skip_message="Does not support AES CBC",
+ )
+ def test_bad_key(self, backend):
+ with pytest.raises(ValueError):
+ Fernet(base64.urlsafe_b64encode(b"abc"), backend=backend)
diff --git a/tests/test_utils.py b/tests/test_utils.py
index c640367e..e3e53d63 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -50,7 +50,7 @@ def test_check_backend_support_skip():
funcargs={"backend": True})
with pytest.raises(pytest.skip.Exception) as exc_info:
check_backend_support(item)
- assert exc_info.value.args[0] == "Nope"
+ assert exc_info.value.args[0] == "Nope (True)"
def test_check_backend_support_no_skip():
diff --git a/tests/utils.py b/tests/utils.py
index beb2ca5d..693a0c8f 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -28,7 +28,9 @@ def check_backend_support(item):
supported = item.keywords.get("supported")
if supported and "backend" in item.funcargs:
if not supported.kwargs["only_if"](item.funcargs["backend"]):
- pytest.skip(supported.kwargs["skip_message"])
+ pytest.skip("{0} ({1})".format(
+ supported.kwargs["skip_message"], item.funcargs["backend"]
+ ))
elif supported:
raise ValueError("This mark is only available on methods that take a "
"backend")
diff --git a/tests/vectors/fernet/generate.json b/tests/vectors/fernet/generate.json
new file mode 100644
index 00000000..d1f3e083
--- /dev/null
+++ b/tests/vectors/fernet/generate.json
@@ -0,0 +1,9 @@
+[
+ {
+ "token": "gAAAAAAdwJ6wAAECAwQFBgcICQoLDA0ODy021cpGVWKZ_eEwCGM4BLLF_5CV9dOPmrhuVUPgJobwOz7JcbmrR64jVmpU4IwqDA==",
+ "now": "1985-10-26T01:20:00-07:00",
+ "iv": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
+ "src": "hello",
+ "secret": "cw_0x689RpI-jtRR7oE8h_eQsKImvJapLeSbXpwF4e4="
+ }
+]
diff --git a/tests/vectors/fernet/invalid.json b/tests/vectors/fernet/invalid.json
new file mode 100644
index 00000000..d80e7b4a
--- /dev/null
+++ b/tests/vectors/fernet/invalid.json
@@ -0,0 +1,58 @@
+[
+ {
+ "desc": "incorrect mac",
+ "token": "gAAAAAAdwJ6xAAECAwQFBgcICQoLDA0OD3HkMATM5lFqGaerZ-fWPAl1-szkFVzXTuGb4hR8AKtwcaX1YdykQUFBQUFBQUFBQQ==",
+ "now": "1985-10-26T01:20:01-07:00",
+ "ttl_sec": 60,
+ "secret": "cw_0x689RpI-jtRR7oE8h_eQsKImvJapLeSbXpwF4e4="
+ },
+ {
+ "desc": "too short",
+ "token": "gAAAAAAdwJ6xAAECAwQFBgcICQoLDA0OD3HkMATM5lFqGaerZ-fWPA==",
+ "now": "1985-10-26T01:20:01-07:00",
+ "ttl_sec": 60,
+ "secret": "cw_0x689RpI-jtRR7oE8h_eQsKImvJapLeSbXpwF4e4="
+ },
+ {
+ "desc": "invalid base64",
+ "token": "%%%%%%%%%%%%%AECAwQFBgcICQoLDA0OD3HkMATM5lFqGaerZ-fWPAl1-szkFVzXTuGb4hR8AKtwcaX1YdykRtfsH-p1YsUD2Q==",
+ "now": "1985-10-26T01:20:01-07:00",
+ "ttl_sec": 60,
+ "secret": "cw_0x689RpI-jtRR7oE8h_eQsKImvJapLeSbXpwF4e4="
+ },
+ {
+ "desc": "payload size not multiple of block size",
+ "token": "gAAAAAAdwJ6xAAECAwQFBgcICQoLDA0OD3HkMATM5lFqGaerZ-fWPOm73QeoCk9uGib28Xe5vz6oxq5nmxbx_v7mrfyudzUm",
+ "now": "1985-10-26T01:20:01-07:00",
+ "ttl_sec": 60,
+ "secret": "cw_0x689RpI-jtRR7oE8h_eQsKImvJapLeSbXpwF4e4="
+ },
+ {
+ "desc": "payload padding error",
+ "token": "gAAAAAAdwJ6xAAECAwQFBgcICQoLDA0ODz4LEpdELGQAad7aNEHbf-JkLPIpuiYRLQ3RtXatOYREu2FWke6CnJNYIbkuKNqOhw==",
+ "now": "1985-10-26T01:20:01-07:00",
+ "ttl_sec": 60,
+ "secret": "cw_0x689RpI-jtRR7oE8h_eQsKImvJapLeSbXpwF4e4="
+ },
+ {
+ "desc": "far-future TS (unacceptable clock skew)",
+ "token": "gAAAAAAdwStRAAECAwQFBgcICQoLDA0OD3HkMATM5lFqGaerZ-fWPAnja1xKYyhd-Y6mSkTOyTGJmw2Xc2a6kBd-iX9b_qXQcw==",
+ "now": "1985-10-26T01:20:01-07:00",
+ "ttl_sec": 60,
+ "secret": "cw_0x689RpI-jtRR7oE8h_eQsKImvJapLeSbXpwF4e4="
+ },
+ {
+ "desc": "expired TTL",
+ "token": "gAAAAAAdwJ6xAAECAwQFBgcICQoLDA0OD3HkMATM5lFqGaerZ-fWPAl1-szkFVzXTuGb4hR8AKtwcaX1YdykRtfsH-p1YsUD2Q==",
+ "now": "1985-10-26T01:21:31-07:00",
+ "ttl_sec": 60,
+ "secret": "cw_0x689RpI-jtRR7oE8h_eQsKImvJapLeSbXpwF4e4="
+ },
+ {
+ "desc": "incorrect IV (causes padding error)",
+ "token": "gAAAAAAdwJ6xBQECAwQFBgcICQoLDA0OD3HkMATM5lFqGaerZ-fWPAkLhFLHpGtDBRLRTZeUfWgHSv49TF2AUEZ1TIvcZjK1zQ==",
+ "now": "1985-10-26T01:20:01-07:00",
+ "ttl_sec": 60,
+ "secret": "cw_0x689RpI-jtRR7oE8h_eQsKImvJapLeSbXpwF4e4="
+ }
+]
diff --git a/tests/vectors/fernet/verify.json b/tests/vectors/fernet/verify.json
new file mode 100644
index 00000000..08c480f5
--- /dev/null
+++ b/tests/vectors/fernet/verify.json
@@ -0,0 +1,9 @@
+[
+ {
+ "token": "gAAAAAAdwJ6wAAECAwQFBgcICQoLDA0ODy021cpGVWKZ_eEwCGM4BLLF_5CV9dOPmrhuVUPgJobwOz7JcbmrR64jVmpU4IwqDA==",
+ "now": "1985-10-26T01:20:01-07:00",
+ "ttl_sec": 60,
+ "src": "hello",
+ "secret": "cw_0x689RpI-jtRR7oE8h_eQsKImvJapLeSbXpwF4e4="
+ }
+]