diff --git a/tests/test_trusted_metadata_set.py b/tests/test_trusted_metadata_set.py index 3560a74ac9..510fae2b1b 100644 --- a/tests/test_trusted_metadata_set.py +++ b/tests/test_trusted_metadata_set.py @@ -198,17 +198,17 @@ def test_root_with_invalid_json(self) -> None: for test_func in [TrustedMetadataSet, self.trusted_set.update_root]: # root is not json with self.assertRaises(exceptions.RepositoryError): - test_func(b"") + test_func(b"") # type: ignore[operator] # root is invalid root = Metadata.from_bytes(self.metadata[Root.type]) root.signed.version += 1 with self.assertRaises(exceptions.UnsignedMetadataError): - test_func(root.to_bytes()) + test_func(root.to_bytes()) # type: ignore[operator] # metadata is of wrong type with self.assertRaises(exceptions.RepositoryError): - test_func(self.metadata[Snapshot.type]) + test_func(self.metadata[Snapshot.type]) # type: ignore[operator] def test_top_level_md_with_invalid_json(self) -> None: top_level_md: List[Tuple[bytes, Callable[[bytes], Signed]]] = [ diff --git a/tuf/ngclient/_internal/trusted_metadata_set.py b/tuf/ngclient/_internal/trusted_metadata_set.py index 9ef47f5c0c..fea8992ecb 100644 --- a/tuf/ngclient/_internal/trusted_metadata_set.py +++ b/tuf/ngclient/_internal/trusted_metadata_set.py @@ -68,7 +68,7 @@ from tuf.api import exceptions from tuf.api.metadata import Root, Signed, Snapshot, Targets, Timestamp -from tuf.ngclient._internal.wrapping import MetadataUnwrapper +from tuf.ngclient._internal.wrapping import MetadataUnwrapper, Unwrapper logger = logging.getLogger(__name__) @@ -82,19 +82,24 @@ class TrustedMetadataSet(abc.Mapping): what is updated. """ - def __init__(self, root_data: bytes): + def __init__(self, root_data: bytes, unwrapper: Optional[Unwrapper] = None): """Initialize ``TrustedMetadataSet`` by loading trusted root metadata. Args: root_data: Trusted root metadata as bytes. Note that this metadata will only be verified by itself: it is the source of trust for all metadata in the ``TrustedMetadataSet`` + unwrapper: Used to unwrap and verify metadata. Default is + MetadataUnwrapper. Raises: RepositoryError: Metadata failed to load or verify. The actual error type and content will contain more details. """ - self._unwrapper = MetadataUnwrapper() + if unwrapper is None: + unwrapper = MetadataUnwrapper() + self._unwrapper = unwrapper + self._trusted_set: Dict[str, Signed] = {} self.reference_time = datetime.datetime.utcnow() diff --git a/tuf/ngclient/config.py b/tuf/ngclient/config.py index 5027994278..4d8ee40a86 100644 --- a/tuf/ngclient/config.py +++ b/tuf/ngclient/config.py @@ -23,7 +23,8 @@ class UpdaterConfig: are used, target download URLs are formed by prefixing the filename with a hash digest of file content by default. This can be overridden by setting ``prefix_targets_with_hash`` to ``False``. - + use_dsse: If true, expect metadata in a DSSE Envelope. Use + traditional Metadata (canonical json) otherwise. """ max_root_rotations: int = 32 @@ -33,3 +34,4 @@ class UpdaterConfig: snapshot_max_length: int = 2000000 # bytes targets_max_length: int = 5000000 # bytes prefix_targets_with_hash: bool = True + use_dsse: bool = False diff --git a/tuf/ngclient/updater.py b/tuf/ngclient/updater.py index 7a2c39993e..5db8519b77 100644 --- a/tuf/ngclient/updater.py +++ b/tuf/ngclient/updater.py @@ -46,7 +46,11 @@ from tuf.api import exceptions from tuf.api.metadata import Root, Snapshot, TargetFile, Targets, Timestamp -from tuf.ngclient._internal import requests_fetcher, trusted_metadata_set +from tuf.ngclient._internal import ( + requests_fetcher, + trusted_metadata_set, + wrapping, +) from tuf.ngclient.config import UpdaterConfig from tuf.ngclient.fetcher import FetcherInterface @@ -94,10 +98,17 @@ def __init__( # Read trusted local root metadata data = self._load_local_metadata(Root.type) - self._trusted_set = trusted_metadata_set.TrustedMetadataSet(data) self._fetcher = fetcher or requests_fetcher.RequestsFetcher() self.config = config or UpdaterConfig() + unwrapper: Optional[wrapping.Unwrapper] = None + if self.config.use_dsse: + unwrapper = wrapping.EnvelopeUnwrapper() + + self._trusted_set = trusted_metadata_set.TrustedMetadataSet( + data, unwrapper + ) + def refresh(self) -> None: """Refresh top-level metadata.