|
@@ -33,26 +33,6 @@ class TestNonceManager:
|
|
|
def commit_nonce_reservation(self, next_unreserved, start_nonce):
|
|
|
pytest.fail("commit_nonce_reservation should never be called on an old repository")
|
|
|
|
|
|
- class MockCipher:
|
|
|
- def __init__(self, iv):
|
|
|
- self.iv_set = False # placeholder, this is never a valid iv
|
|
|
- self.iv = iv
|
|
|
-
|
|
|
- def set_iv(self, iv):
|
|
|
- assert iv is not False
|
|
|
- self.iv_set = iv
|
|
|
- self.iv = iv
|
|
|
-
|
|
|
- def next_iv(self):
|
|
|
- return self.iv
|
|
|
-
|
|
|
- def expect_iv_and_advance(self, expected_iv, advance):
|
|
|
- expected_iv = expected_iv.to_bytes(16, byteorder='big')
|
|
|
- iv_set = self.iv_set
|
|
|
- assert iv_set == expected_iv
|
|
|
- self.iv_set = False
|
|
|
- self.iv = advance.to_bytes(16, byteorder='big')
|
|
|
-
|
|
|
def setUp(self):
|
|
|
self.repository = None
|
|
|
|
|
@@ -67,74 +47,70 @@ class TestNonceManager:
|
|
|
def test_empty_cache_and_old_server(self, monkeypatch):
|
|
|
monkeypatch.setattr(nonces, 'NONCE_SPACE_RESERVATION', 0x20)
|
|
|
|
|
|
- cipher = self.MockCipher(0x2000)
|
|
|
self.repository = self.MockOldRepository()
|
|
|
- manager = NonceManager(self.repository, cipher, 0x2000)
|
|
|
- manager.ensure_reservation(19)
|
|
|
- cipher.expect_iv_and_advance(0x2000, 0x2013)
|
|
|
+ manager = NonceManager(self.repository, 0x2000)
|
|
|
+ next_nonce = manager.ensure_reservation(0x2000, 19)
|
|
|
+ assert next_nonce == 0x2000
|
|
|
|
|
|
assert self.cache_nonce() == "0000000000002033"
|
|
|
|
|
|
def test_empty_cache(self, monkeypatch):
|
|
|
monkeypatch.setattr(nonces, 'NONCE_SPACE_RESERVATION', 0x20)
|
|
|
|
|
|
- cipher = self.MockCipher(0x2000)
|
|
|
self.repository = self.MockRepository()
|
|
|
self.repository.next_free = 0x2000
|
|
|
- manager = NonceManager(self.repository, cipher, 0x2000)
|
|
|
- manager.ensure_reservation(19)
|
|
|
- cipher.expect_iv_and_advance(0x2000, 0x2013)
|
|
|
+ manager = NonceManager(self.repository, 0x2000)
|
|
|
+ next_nonce = manager.ensure_reservation(0x2000, 19)
|
|
|
+ assert next_nonce == 0x2000
|
|
|
|
|
|
assert self.cache_nonce() == "0000000000002033"
|
|
|
|
|
|
def test_empty_nonce(self, monkeypatch):
|
|
|
monkeypatch.setattr(nonces, 'NONCE_SPACE_RESERVATION', 0x20)
|
|
|
|
|
|
- cipher = self.MockCipher(0x2000)
|
|
|
self.repository = self.MockRepository()
|
|
|
self.repository.next_free = None
|
|
|
- manager = NonceManager(self.repository, cipher, 0x2000)
|
|
|
- manager.ensure_reservation(19)
|
|
|
- cipher.expect_iv_and_advance(0x2000, 0x2000 + 19)
|
|
|
+ manager = NonceManager(self.repository, 0x2000)
|
|
|
+ next_nonce = manager.ensure_reservation(0x2000, 19)
|
|
|
+ assert next_nonce == 0x2000
|
|
|
|
|
|
assert self.cache_nonce() == "0000000000002033"
|
|
|
assert self.repository.next_free == 0x2033
|
|
|
|
|
|
# enough space in reservation
|
|
|
- manager.ensure_reservation(13)
|
|
|
- cipher.expect_iv_and_advance(0x2013, 0x2000 + 19 + 13)
|
|
|
+ next_nonce = manager.ensure_reservation(0x2013, 13)
|
|
|
+ assert next_nonce == 0x2013
|
|
|
assert self.cache_nonce() == "0000000000002033"
|
|
|
assert self.repository.next_free == 0x2033
|
|
|
|
|
|
# just barely enough space in reservation
|
|
|
- manager.ensure_reservation(19)
|
|
|
- cipher.expect_iv_and_advance(0x2020, 0x2000 + 19 + 13 + 19)
|
|
|
+ next_nonce = manager.ensure_reservation(0x2020, 19)
|
|
|
+ assert next_nonce == 0x2020
|
|
|
assert self.cache_nonce() == "0000000000002033"
|
|
|
assert self.repository.next_free == 0x2033
|
|
|
|
|
|
# no space in reservation
|
|
|
- manager.ensure_reservation(16)
|
|
|
- cipher.expect_iv_and_advance(0x2033, 0x2000 + 19 + 13 + 19 + 16)
|
|
|
+ next_nonce = manager.ensure_reservation(0x2033, 16)
|
|
|
+ assert next_nonce == 0x2033
|
|
|
assert self.cache_nonce() == "0000000000002063"
|
|
|
assert self.repository.next_free == 0x2063
|
|
|
|
|
|
# spans reservation boundary
|
|
|
- manager.ensure_reservation(64)
|
|
|
- cipher.expect_iv_and_advance(0x2063, 0x2000 + 19 + 13 + 19 + 16 + 64)
|
|
|
+ next_nonce = manager.ensure_reservation(0x2043, 64)
|
|
|
+ assert next_nonce == 0x2063
|
|
|
assert self.cache_nonce() == "00000000000020c3"
|
|
|
assert self.repository.next_free == 0x20c3
|
|
|
|
|
|
def test_sync_nonce(self, monkeypatch):
|
|
|
monkeypatch.setattr(nonces, 'NONCE_SPACE_RESERVATION', 0x20)
|
|
|
|
|
|
- cipher = self.MockCipher(0x2000)
|
|
|
self.repository = self.MockRepository()
|
|
|
self.repository.next_free = 0x2000
|
|
|
self.set_cache_nonce("0000000000002000")
|
|
|
|
|
|
- manager = NonceManager(self.repository, cipher, 0x2000)
|
|
|
- manager.ensure_reservation(19)
|
|
|
- cipher.expect_iv_and_advance(0x2000, 0x2000 + 19)
|
|
|
+ manager = NonceManager(self.repository, 0x2000)
|
|
|
+ next_nonce = manager.ensure_reservation(0x2000, 19)
|
|
|
+ assert next_nonce == 0x2000
|
|
|
|
|
|
assert self.cache_nonce() == "0000000000002033"
|
|
|
assert self.repository.next_free == 0x2033
|
|
@@ -142,14 +118,13 @@ class TestNonceManager:
|
|
|
def test_server_just_upgraded(self, monkeypatch):
|
|
|
monkeypatch.setattr(nonces, 'NONCE_SPACE_RESERVATION', 0x20)
|
|
|
|
|
|
- cipher = self.MockCipher(0x2000)
|
|
|
self.repository = self.MockRepository()
|
|
|
self.repository.next_free = None
|
|
|
self.set_cache_nonce("0000000000002000")
|
|
|
|
|
|
- manager = NonceManager(self.repository, cipher, 0x2000)
|
|
|
- manager.ensure_reservation(19)
|
|
|
- cipher.expect_iv_and_advance(0x2000, 0x2000 + 19)
|
|
|
+ manager = NonceManager(self.repository, 0x2000)
|
|
|
+ next_nonce = manager.ensure_reservation(0x2000, 19)
|
|
|
+ assert next_nonce == 0x2000
|
|
|
|
|
|
assert self.cache_nonce() == "0000000000002033"
|
|
|
assert self.repository.next_free == 0x2033
|
|
@@ -157,13 +132,12 @@ class TestNonceManager:
|
|
|
def test_transaction_abort_no_cache(self, monkeypatch):
|
|
|
monkeypatch.setattr(nonces, 'NONCE_SPACE_RESERVATION', 0x20)
|
|
|
|
|
|
- cipher = self.MockCipher(0x1000)
|
|
|
self.repository = self.MockRepository()
|
|
|
self.repository.next_free = 0x2000
|
|
|
|
|
|
- manager = NonceManager(self.repository, cipher, 0x2000)
|
|
|
- manager.ensure_reservation(19)
|
|
|
- cipher.expect_iv_and_advance(0x2000, 0x2000 + 19)
|
|
|
+ manager = NonceManager(self.repository, 0x2000)
|
|
|
+ next_nonce = manager.ensure_reservation(0x1000, 19)
|
|
|
+ assert next_nonce == 0x2000
|
|
|
|
|
|
assert self.cache_nonce() == "0000000000002033"
|
|
|
assert self.repository.next_free == 0x2033
|
|
@@ -171,27 +145,25 @@ class TestNonceManager:
|
|
|
def test_transaction_abort_old_server(self, monkeypatch):
|
|
|
monkeypatch.setattr(nonces, 'NONCE_SPACE_RESERVATION', 0x20)
|
|
|
|
|
|
- cipher = self.MockCipher(0x1000)
|
|
|
self.repository = self.MockOldRepository()
|
|
|
self.set_cache_nonce("0000000000002000")
|
|
|
|
|
|
- manager = NonceManager(self.repository, cipher, 0x2000)
|
|
|
- manager.ensure_reservation(19)
|
|
|
- cipher.expect_iv_and_advance(0x2000, 0x2000 + 19)
|
|
|
+ manager = NonceManager(self.repository, 0x2000)
|
|
|
+ next_nonce = manager.ensure_reservation(0x1000, 19)
|
|
|
+ assert next_nonce == 0x2000
|
|
|
|
|
|
assert self.cache_nonce() == "0000000000002033"
|
|
|
|
|
|
def test_transaction_abort_on_other_client(self, monkeypatch):
|
|
|
monkeypatch.setattr(nonces, 'NONCE_SPACE_RESERVATION', 0x20)
|
|
|
|
|
|
- cipher = self.MockCipher(0x1000)
|
|
|
self.repository = self.MockRepository()
|
|
|
self.repository.next_free = 0x2000
|
|
|
self.set_cache_nonce("0000000000001000")
|
|
|
|
|
|
- manager = NonceManager(self.repository, cipher, 0x2000)
|
|
|
- manager.ensure_reservation(19)
|
|
|
- cipher.expect_iv_and_advance(0x2000, 0x2000 + 19)
|
|
|
+ manager = NonceManager(self.repository, 0x2000)
|
|
|
+ next_nonce = manager.ensure_reservation(0x1000, 19)
|
|
|
+ assert next_nonce == 0x2000
|
|
|
|
|
|
assert self.cache_nonce() == "0000000000002033"
|
|
|
assert self.repository.next_free == 0x2033
|
|
@@ -199,14 +171,13 @@ class TestNonceManager:
|
|
|
def test_interleaved(self, monkeypatch):
|
|
|
monkeypatch.setattr(nonces, 'NONCE_SPACE_RESERVATION', 0x20)
|
|
|
|
|
|
- cipher = self.MockCipher(0x2000)
|
|
|
self.repository = self.MockRepository()
|
|
|
self.repository.next_free = 0x2000
|
|
|
self.set_cache_nonce("0000000000002000")
|
|
|
|
|
|
- manager = NonceManager(self.repository, cipher, 0x2000)
|
|
|
- manager.ensure_reservation(19)
|
|
|
- cipher.expect_iv_and_advance(0x2000, 0x2000 + 19)
|
|
|
+ manager = NonceManager(self.repository, 0x2000)
|
|
|
+ next_nonce = manager.ensure_reservation(0x2000, 19)
|
|
|
+ assert next_nonce == 0x2000
|
|
|
|
|
|
assert self.cache_nonce() == "0000000000002033"
|
|
|
assert self.repository.next_free == 0x2033
|
|
@@ -215,13 +186,13 @@ class TestNonceManager:
|
|
|
self.repository.next_free = 0x4000
|
|
|
|
|
|
# enough space in reservation
|
|
|
- manager.ensure_reservation(12)
|
|
|
- cipher.expect_iv_and_advance(0x2013, 0x2000 + 19 + 12)
|
|
|
+ next_nonce = manager.ensure_reservation(0x2013, 12)
|
|
|
+ assert next_nonce == 0x2013
|
|
|
assert self.cache_nonce() == "0000000000002033"
|
|
|
assert self.repository.next_free == 0x4000
|
|
|
|
|
|
# spans reservation boundary
|
|
|
- manager.ensure_reservation(21)
|
|
|
- cipher.expect_iv_and_advance(0x4000, 0x4000 + 21)
|
|
|
+ next_nonce = manager.ensure_reservation(0x201f, 21)
|
|
|
+ assert next_nonce == 0x4000
|
|
|
assert self.cache_nonce() == "0000000000004035"
|
|
|
assert self.repository.next_free == 0x4035
|