From 0ac86c67ad9d5d229cddb04789592fbc1371caa2 Mon Sep 17 00:00:00 2001 From: Kapil Sharma Date: Tue, 4 Jun 2024 12:26:53 +0530 Subject: [PATCH] repository: handle online key changes (#2650) * repository: Handle online key change situations in do_snapshot() and do_timestamp(): always create a new version if current version is not correctly signed * remove expectedFailure marks from the related tests Signed-off-by: h4l0gen Signed-off-by: Kapil Sharma --- tests/test_repository.py | 2 -- tuf/repository/_repository.py | 26 ++++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/tests/test_repository.py b/tests/test_repository.py index 092df0ec..e1d228dc 100644 --- a/tests/test_repository.py +++ b/tests/test_repository.py @@ -186,7 +186,6 @@ def test_do_snapshot_after_new_targets_delegation(self) -> None: self.assertEqual(2, len(snapshot_versions)) self.assertEqual(2, snapshot_versions[-1].signed.version) - @unittest.expectedFailure # Issue 2438 def test_do_snapshot_after_snapshot_key_change(self) -> None: # change snapshot signing keys with self.repo.edit_root() as root: @@ -228,7 +227,6 @@ def test_do_timestamp_after_snapshot_change(self) -> None: self.assertEqual(2, len(timestamp_versions)) self.assertEqual(2, timestamp_versions[-1].signed.version) - @unittest.expectedFailure # Issue 2438 def test_do_timestamp_after_timestamp_key_change(self) -> None: # change timestamp signing keys with self.repo.edit_root() as root: diff --git a/tuf/repository/_repository.py b/tuf/repository/_repository.py index fc96b8f4..09306b82 100644 --- a/tuf/repository/_repository.py +++ b/tuf/repository/_repository.py @@ -9,6 +9,7 @@ from copy import deepcopy from typing import Dict, Generator, Optional, Tuple +from tuf.api.exceptions import UnsignedMetadataError from tuf.api.metadata import ( Metadata, MetaFile, @@ -188,6 +189,18 @@ def do_snapshot( update_version = force removed: Dict[str, MetaFile] = {} + root = self.root() + snapshot_md = self.open(Snapshot.type) + + try: + root.verify_delegate( + Snapshot.type, + snapshot_md.signed_bytes, + snapshot_md.signatures, + ) + except UnsignedMetadataError: + update_version = True + with self.edit_snapshot() as snapshot: for keyname, new_meta in self.targets_infos.items(): if keyname not in snapshot.meta: @@ -228,6 +241,19 @@ def do_timestamp( """ update_version = force removed = None + + root = self.root() + timestamp_md = self.open(Timestamp.type) + + try: + root.verify_delegate( + Timestamp.type, + timestamp_md.signed_bytes, + timestamp_md.signatures, + ) + except UnsignedMetadataError: + update_version = True + with self.edit_timestamp() as timestamp: if self.snapshot_info.version < timestamp.snapshot_meta.version: raise ValueError("snapshot version rollback")