aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_fernet.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_fernet.py')
-rw-r--r--tests/test_fernet.py79
1 files changed, 77 insertions, 2 deletions
diff --git a/tests/test_fernet.py b/tests/test_fernet.py
index 0b93f017..da2096fb 100644
--- a/tests/test_fernet.py
+++ b/tests/test_fernet.py
@@ -45,7 +45,7 @@ def test_default_backend():
@pytest.mark.requires_backend_interface(interface=HMACBackend)
@pytest.mark.supported(
only_if=lambda backend: backend.cipher_supported(
- algorithms.AES("\x00" * 32), modes.CBC("\x00" * 16)
+ algorithms.AES(b"\x00" * 32), modes.CBC(b"\x00" * 16)
),
skip_message="Does not support AES CBC",
)
@@ -69,6 +69,10 @@ class TestFernet(object):
monkeypatch):
f = Fernet(secret.encode("ascii"), backend=backend)
current_time = calendar.timegm(iso8601.parse_date(now).utctimetuple())
+ payload = f.decrypt_at_time(
+ token.encode("ascii"), ttl=ttl_sec, current_time=current_time,
+ )
+ assert payload == src.encode("ascii")
monkeypatch.setattr(time, "time", lambda: current_time)
payload = f.decrypt(token.encode("ascii"), ttl=ttl_sec)
assert payload == src.encode("ascii")
@@ -77,6 +81,10 @@ class TestFernet(object):
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())
+ with pytest.raises(InvalidToken):
+ f.decrypt_at_time(
+ token.encode("ascii"), ttl=ttl_sec, current_time=current_time,
+ )
monkeypatch.setattr(time, "time", lambda: current_time)
with pytest.raises(InvalidToken):
f.decrypt(token.encode("ascii"), ttl=ttl_sec)
@@ -103,6 +111,17 @@ class TestFernet(object):
with pytest.raises(TypeError):
f.decrypt(u"")
+ def test_timestamp_ignored_no_ttl(self, monkeypatch, backend):
+ f = Fernet(base64.urlsafe_b64encode(b"\x00" * 32), backend=backend)
+ pt = b"encrypt me"
+ token = f.encrypt(pt)
+ ts = "1985-10-26T01:20:01-07:00"
+ current_time = calendar.timegm(iso8601.parse_date(ts).utctimetuple())
+ assert f.decrypt_at_time(
+ token, ttl=None, current_time=current_time) == pt
+ monkeypatch.setattr(time, "time", lambda: current_time)
+ assert f.decrypt(token, ttl=None) == pt
+
@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)
@@ -112,12 +131,20 @@ class TestFernet(object):
with pytest.raises(ValueError):
Fernet(base64.urlsafe_b64encode(b"abc"), backend=backend)
+ def test_extract_timestamp(self, monkeypatch, backend):
+ f = Fernet(base64.urlsafe_b64encode(b"\x00" * 32), backend=backend)
+ current_time = 1526138327
+ token = f.encrypt_at_time(b'encrypt me', current_time)
+ assert f.extract_timestamp(token) == current_time
+ with pytest.raises(InvalidToken):
+ f.extract_timestamp(b"nonsensetoken")
+
@pytest.mark.requires_backend_interface(interface=CipherBackend)
@pytest.mark.requires_backend_interface(interface=HMACBackend)
@pytest.mark.supported(
only_if=lambda backend: backend.cipher_supported(
- algorithms.AES("\x00" * 32), modes.CBC("\x00" * 16)
+ algorithms.AES(b"\x00" * 32), modes.CBC(b"\x00" * 16)
),
skip_message="Does not support AES CBC",
)
@@ -147,3 +174,51 @@ class TestMultiFernet(object):
def test_non_iterable_argument(self, backend):
with pytest.raises(TypeError):
MultiFernet(None)
+
+ def test_rotate(self, backend):
+ f1 = Fernet(base64.urlsafe_b64encode(b"\x00" * 32), backend=backend)
+ f2 = Fernet(base64.urlsafe_b64encode(b"\x01" * 32), backend=backend)
+
+ mf1 = MultiFernet([f1])
+ mf2 = MultiFernet([f2, f1])
+
+ plaintext = b"abc"
+ mf1_ciphertext = mf1.encrypt(plaintext)
+
+ assert mf2.decrypt(mf1_ciphertext) == plaintext
+
+ rotated = mf2.rotate(mf1_ciphertext)
+
+ assert rotated != mf1_ciphertext
+ assert mf2.decrypt(rotated) == plaintext
+
+ with pytest.raises(InvalidToken):
+ mf1.decrypt(rotated)
+
+ def test_rotate_preserves_timestamp(self, backend, monkeypatch):
+ f1 = Fernet(base64.urlsafe_b64encode(b"\x00" * 32), backend=backend)
+ f2 = Fernet(base64.urlsafe_b64encode(b"\x01" * 32), backend=backend)
+
+ mf1 = MultiFernet([f1])
+ mf2 = MultiFernet([f2, f1])
+
+ plaintext = b"abc"
+ original_time = int(time.time()) - 5 * 60
+ mf1_ciphertext = mf1.encrypt_at_time(plaintext, original_time)
+
+ rotated_time, _ = Fernet._get_unverified_token_data(
+ mf2.rotate(mf1_ciphertext)
+ )
+
+ assert int(time.time()) != rotated_time
+ assert original_time == rotated_time
+
+ def test_rotate_decrypt_no_shared_keys(self, backend):
+ f1 = Fernet(base64.urlsafe_b64encode(b"\x00" * 32), backend=backend)
+ f2 = Fernet(base64.urlsafe_b64encode(b"\x01" * 32), backend=backend)
+
+ mf1 = MultiFernet([f1])
+ mf2 = MultiFernet([f2])
+
+ with pytest.raises(InvalidToken):
+ mf2.rotate(mf1.encrypt(b"abc"))