Skip to content

Commit

Permalink
refactor rollback tests (theupdateframework#58)
Browse files Browse the repository at this point in the history
Signed-off-by: Adam Korczynski <[email protected]>
  • Loading branch information
AdamKorcz authored Jul 11, 2024
1 parent fcabe40 commit 54d09eb
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 49 deletions.
14 changes: 14 additions & 0 deletions self_tests/test_repository_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,5 +131,19 @@ def test_add_key_implementation(self):
expected_bytes = meta_dict_to_bytes(json.loads(repo.md_root.to_bytes())["signed"])
self.assertEqual(our_own_bytes, expected_bytes)

def test_downgrade_snapshot(self):
repo = RepositorySimulator()
repo.update_snapshot() # v2
self.assertTrue(repo._version_equals(Snapshot.type, 2))
repo.downgrade_snapshot() # v1
self.assertTrue(repo._version_equals(Snapshot.type, 1))

def test_downgrade_timestamp(self):
repo = RepositorySimulator()
repo.update_timestamp() # v2
self.assertTrue(repo._version_equals(Timestamp.type, 2))
repo.downgrade_timestamp() # v1
self.assertTrue(repo._version_equals(Timestamp.type, 1))

if __name__ == '__main__':
unittest.main()
83 changes: 34 additions & 49 deletions tuf_conformance/test_rollback.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@

def test_new_snapshot_version_rollback(client: ClientRunner,
server: SimulatorServer) -> None:
"""This is an example of a test method:
it should likely be a e.g. a unittest.TestCase"""

name = "test_new_snapshot_version_rollback"

Expand All @@ -21,24 +19,18 @@ def test_new_snapshot_version_rollback(client: ClientRunner,
assert client.init_client(init_data) == 0

# Repository performs legitimate update to snapshot
repo.update_snapshot()
repo.update_snapshot() # v2
assert client.refresh(init_data) == 0

# Sanity check that client saw the snapshot update:
assert client._version_equals(Snapshot.type, 2)

# Repository attempts rollback attack:
repo.downgrade_snapshot()
assert repo._version_equals(Snapshot.type, 1)
repo.downgrade_snapshot() # v1
client.refresh(init_data)

# Check that client resisted rollback attack
assert client._version_equals(Snapshot.type, 2)

def test_new_timestamp_version_rollback(client: ClientRunner,
server: SimulatorServer) -> None:
"""This is an example of a test method:
it should likely be a e.g. a unittest.TestCase"""

name = "test_new_timestamp_version_rollback"

Expand All @@ -49,30 +41,22 @@ def test_new_timestamp_version_rollback(client: ClientRunner,
assert client.init_client(init_data) == 0

# Repository performs legitimate update to snapshot
repo.update_timestamp()
assert repo._version_equals(Timestamp.type, 2)
repo.update_timestamp() # v2
assert client.refresh(init_data) == 0

# Sanity check that client saw the snapshot update:
assert client._version_equals(Timestamp.type, 2)

# Repository attempts rollback attack:
repo.downgrade_timestamp()

# Sanitty check that the repository is attempting a
# rollback attack
assert repo._version_equals(Timestamp.type, 1)
repo.downgrade_timestamp() # v1

client.refresh(init_data)
assert client.refresh(init_data) == 1

# Check that client resisted rollback attack
assert client._version_equals(Timestamp.type, 2)

def test_new_timestamp_snapshot_rollback(client: ClientRunner,
server: SimulatorServer) -> None:
"""This is an example of a test method:
it should likely be a e.g. a unittest.TestCase"""

name = "test_new_timestamp_snapshot_rollback"

# initialize a simulator with repository content we need
Expand All @@ -83,30 +67,28 @@ def test_new_timestamp_snapshot_rollback(client: ClientRunner,
assert client.init_client(init_data) == 0

# Start snapshot version at 2
#repo.snapshot.version = 2
new_snapshot = repo.load_metadata(Snapshot.type)
new_snapshot.signed.version = 2
repo.save_metadata(Snapshot.type, new_snapshot)
repo.update_snapshot() # v2, timestamp = v3

# Repository performs legitimate update to snapshot
repo.update_timestamp()
# Sanity check
assert repo._version_equals(Timestamp.type, 2)
repo.update_timestamp() # v3
assert client.refresh(init_data) == 0

# Repo attempts rollback attack
new_timestamp = repo.load_metadata(Timestamp.type)
new_timestamp.signed.snapshot_meta.version = 1
new_timestamp.signed.version += 1
repo.save_metadata(Timestamp.type, new_timestamp)
# Sanity check
assert repo._version_equals(Timestamp.type, 3)
assert client._version_equals(Timestamp.type, 2)
new_snapshot = repo.load_metadata(Snapshot.type)
new_snapshot.signed.version = 1
repo.save_metadata(Snapshot.type, new_snapshot)
repo.update_timestamp() # v4
assert repo._version_equals(Timestamp.type, 4)
assert client._version_equals(Timestamp.type, 3)

client.refresh(init_data)

# Check that client resisted rollback attack
assert client._version_equals(Timestamp.type, 2)
assert client._version_equals(Timestamp.type, 3)
assert client._version_equals(Snapshot.type, 2)

def test_new_targets_fast_forward_recovery(client: ClientRunner,
server: SimulatorServer) -> None:
Expand All @@ -131,21 +113,23 @@ def test_new_targets_fast_forward_recovery(client: ClientRunner,
new_targets = repo.load_metadata(Targets.type)
new_targets.signed.version = 99999
repo.save_metadata(Targets.type, new_targets)
repo.update_snapshot()
repo.update_snapshot() # v2

client.refresh(init_data)
assert client.refresh(init_data) == 0
assert client._version_equals(Targets.type, 99999)

repo.rotate_keys(Snapshot.type)
repo.bump_root_by_one()
new_targets = repo.load_metadata(Targets.type)
new_targets.signed.version = 1
repo.save_metadata(Targets.type, new_targets)
repo.update_snapshot()
repo.update_snapshot() # v3

client.refresh(init_data)
# TODO: Is it really true that the targets version is 1?
assert repo._version_equals(Snapshot.type, 3)

assert client.refresh(init_data) == 1
assert client._version_equals(Targets.type, 99999)
assert client._version_equals(Snapshot.type, 2)

def test_new_snapshot_fast_forward_recovery(client: ClientRunner,
server: SimulatorServer) -> None:
Expand Down Expand Up @@ -179,14 +163,12 @@ def test_new_snapshot_fast_forward_recovery(client: ClientRunner,
repo.rotate_keys(Timestamp.type)
repo.bump_root_by_one()

#repo.snapshot.version = 1
new_snapshot = repo.load_metadata(Snapshot.type)
new_snapshot.signed.version = 1
repo.save_metadata(Snapshot.type, new_snapshot)
repo.update_timestamp()

client.refresh(init_data)
# TODO: Can this really be true?
assert client.refresh(init_data) == 1
assert client._version_equals(Snapshot.type, 99999)

def test_new_snapshot_version_mismatch(client: ClientRunner,
Expand Down Expand Up @@ -240,17 +222,19 @@ def test_new_timestamp_fast_forward_recovery(client: ClientRunner,
client.refresh(init_data)
assert client._version_equals(Timestamp.type, 99999)

# repository rotates timestamp keys, rolls back timestamp version
# repository rotates timestamp keys,
# rolls back timestamp version
repo.rotate_keys(Timestamp.type)
repo.bump_root_by_one()
#repo.timestamp.version = 1

new_timestamp = repo.load_metadata(Timestamp.type)
new_timestamp.signed.version = 1
repo.save_metadata(Timestamp.type, new_timestamp)

# client refresh the metadata and see the initial timestamp version
client.refresh(init_data)
# repo timestamp version is now 1 which is less
# than the version in the clients metadata.
# The client should not be version 1 after refreshing.
assert client.refresh(init_data) == 1
assert client._version_equals(Timestamp.type, 99999)

def test_snapshot_rollback_with_local_snapshot_hash_mismatch(client: ClientRunner,
Expand All @@ -267,11 +251,12 @@ def test_snapshot_rollback_with_local_snapshot_hash_mismatch(client: ClientRunne
assert client.init_client(init_data) == 0
client.refresh(init_data)
assert client._files_exist([Root.type,
Timestamp.type,
Snapshot.type,
Targets.type])
Timestamp.type,
Snapshot.type,
Targets.type])

# Initialize all metadata and assign targets version higher than 1.
# Initialize all metadata and assign targets
# version higher than 1.
new_targets = repo.load_metadata(Targets.type)
new_targets.signed.version = 2
repo.save_metadata(Targets.type, new_targets)
Expand Down

0 comments on commit 54d09eb

Please sign in to comment.