Skip to content

Commit 01acaa4

Browse files
author
Lukas Pühringer
authored
Merge pull request #2024 from MVrachev/timestamp-eq-version
ngclient: pick old timestamp if new.version is equal
2 parents 46eb5a0 + 5fd3ddc commit 01acaa4

File tree

5 files changed

+54
-1
lines changed

5 files changed

+54
-1
lines changed

tests/test_trusted_metadata_set.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,25 @@ def version_modifier(timestamp: Timestamp) -> None:
274274
with self.assertRaises(exceptions.BadVersionNumberError):
275275
self.trusted_set.update_timestamp(self.metadata[Timestamp.type])
276276

277+
def test_update_timestamp_with_same_timestamp(self) -> None:
278+
# Test that timestamp is NOT updated if:
279+
# new_timestamp.version == trusted_timestamp.version
280+
self.trusted_set.update_timestamp(self.metadata[Timestamp.type])
281+
initial_timestamp = self.trusted_set.timestamp
282+
283+
# Update timestamp with the same version.
284+
with self.assertRaises(exceptions.EqualVersionNumberError):
285+
self.trusted_set.update_timestamp((self.metadata[Timestamp.type]))
286+
287+
# Every object has a unique id() if they are equal, this means timestamp
288+
# was not updated.
289+
self.assertEqual(id(initial_timestamp), id(self.trusted_set.timestamp))
290+
277291
def test_update_timestamp_snapshot_ver_below_current(self) -> None:
278292
def bump_snapshot_version(timestamp: Timestamp) -> None:
279293
timestamp.snapshot_meta.version = 2
294+
# The timestamp version must be increased to initiate a update.
295+
timestamp.version += 1
280296

281297
# set current known snapshot.json version to 2
282298
timestamp = self.modify_metadata(Timestamp.type, bump_snapshot_version)
@@ -382,6 +398,8 @@ def snapshot_expired_modifier(snapshot: Snapshot) -> None:
382398
def test_update_snapshot_successful_rollback_checks(self) -> None:
383399
def meta_version_bump(timestamp: Timestamp) -> None:
384400
timestamp.snapshot_meta.version += 1
401+
# The timestamp version must be increased to initiate a update.
402+
timestamp.version += 1
385403

386404
def version_bump(snapshot: Snapshot) -> None:
387405
snapshot.version += 1

tests/test_updater_top_level_update.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,27 @@ def test_max_metadata_lengths(self) -> None:
804804
updater = self._init_updater()
805805
updater.refresh()
806806

807+
def test_timestamp_eq_versions_check(self) -> None:
808+
# Test that a modified timestamp with different content, but the same
809+
# version doesn't replace the valid locally stored one.
810+
811+
# Make a successful update of valid metadata which stores it in cache
812+
self._run_refresh()
813+
initial_timestamp_meta_ver = self.sim.timestamp.snapshot_meta.version
814+
815+
# Change timestamp without bumping its version in order to test if a new
816+
# timestamp with the same version will be persisted.
817+
self.sim.timestamp.snapshot_meta.version = 100
818+
self._run_refresh()
819+
820+
# If the local timestamp md file has the same snapshot_meta.version as
821+
# the initial one, then the new modified timestamp has not been stored.
822+
timestamp_path = os.path.join(self.metadata_dir, "timestamp.json")
823+
timestamp: Metadata[Timestamp] = Metadata.from_file(timestamp_path)
824+
self.assertEqual(
825+
initial_timestamp_meta_ver, timestamp.signed.snapshot_meta.version
826+
)
827+
807828

808829
if __name__ == "__main__":
809830
if "--dump" in sys.argv:

tuf/api/exceptions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ class BadVersionNumberError(RepositoryError):
2929
"""An error for metadata that contains an invalid version number."""
3030

3131

32+
class EqualVersionNumberError(BadVersionNumberError):
33+
"""An error for metadata containing a previously verified version number."""
34+
35+
3236
class ExpiredMetadataError(RepositoryError):
3337
"""Indicate that a TUF Metadata file has expired."""
3438

tuf/ngclient/_internal/trusted_metadata_set.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,10 @@ def update_timestamp(self, data: bytes) -> Metadata[Timestamp]:
226226
f"New timestamp version {new_timestamp.signed.version} must"
227227
f" be >= {self.timestamp.signed.version}"
228228
)
229+
# Keep using old timestamp if versions are equal.
230+
if new_timestamp.signed.version == self.timestamp.signed.version:
231+
raise exceptions.EqualVersionNumberError()
232+
229233
# Prevent rolling back snapshot version
230234
snapshot_meta = self.timestamp.signed.snapshot_meta
231235
new_snapshot_meta = new_timestamp.signed.snapshot_meta

tuf/ngclient/updater.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,13 @@ def _load_timestamp(self) -> None:
336336
data = self._download_metadata(
337337
Timestamp.type, self.config.timestamp_max_length
338338
)
339-
self._trusted_set.update_timestamp(data)
339+
try:
340+
self._trusted_set.update_timestamp(data)
341+
except exceptions.EqualVersionNumberError:
342+
# If the new timestamp version is the same as current, discard the
343+
# new timestamp. This is normal and it shouldn't raise any error.
344+
return
345+
340346
self._persist_metadata(Timestamp.type, data)
341347

342348
def _load_snapshot(self) -> None:

0 commit comments

Comments
 (0)