From ba2c8cf84f05153b26a93c304f1e9d991663655c Mon Sep 17 00:00:00 2001 From: Emile Baez Date: Wed, 5 Apr 2023 19:40:48 -0400 Subject: [PATCH 1/3] addition of offline flag to TUF updater offline flag is manually set to true. Tries to catch exceptions on updater refresh. pip requirements are modified to get TUF repo from demo version. --- install/requirements.txt | 7 ++++--- sigstore/_internal/tuf.py | 10 ++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/install/requirements.txt b/install/requirements.txt index 907ecc0b5..5029e7d06 100644 --- a/install/requirements.txt +++ b/install/requirements.txt @@ -370,10 +370,11 @@ six==1.16.0 \ --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 # via python-dateutil -tuf==2.1.0 \ - --hash=sha256:ab22d1143d4d8aa20c94d243de27eedc8cd517e251ddaf4a88c10952358a13ea \ - --hash=sha256:dbfe18fbdeba6d76144931db88b76e473fa40c431b60d25b455a9adbb07c2397 +# tuf==2.1.0 \ +# --hash=sha256:ab22d1143d4d8aa20c94d243de27eedc8cd517e251ddaf4a88c10952358a13ea \ +# --hash=sha256:dbfe18fbdeba6d76144931db88b76e473fa40c431b60d25b455a9adbb07c2397 # via sigstore +git+https://github.com/emboman13/python-tuf-lazy-refresh/tree/offline.git typing-extensions==4.5.0 \ --hash=sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb \ --hash=sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4 diff --git a/sigstore/_internal/tuf.py b/sigstore/_internal/tuf.py index eeafccad3..b910cfd98 100644 --- a/sigstore/_internal/tuf.py +++ b/sigstore/_internal/tuf.py @@ -115,6 +115,8 @@ def __init__(self, url: str) -> None: """ self._repo_url = url self._metadata_dir, self._targets_dir = _get_dirs(url) + # change to get from args + self.offline = True rsrc_prefix: str if self._repo_url == DEFAULT_TUF_URL: @@ -174,12 +176,15 @@ def _updater(self) -> Updater: target_base_url=parse.urljoin(f"{self._repo_url}/", "targets/"), target_dir=str(self._targets_dir), fetcher=_get_fetcher(), + offline=self.offline ) # NOTE: we would like to avoid refresh if the toplevel metadata is valid. # https://github.com/theupdateframework/python-tuf/issues/2225 try: updater.refresh() + except TUFExceptions.ExpiredMetadataError as exp_e: + raise TUFError("Local metadata is not available and you are in offline mode") from exp_e except Exception as e: raise TUFError("Failed to refresh TUF metadata") from e @@ -191,14 +196,19 @@ def _get_trusted_root(self) -> TrustedRoot: if root_info is None: raise TUFError("Unsupported TUF configuration: no trusted root") path = self._updater().find_cached_target(root_info) + # might have to change something here if path is None: try: path = self._updater().download_target(root_info) + except TUFExceptions.ExpiredMetadataError as exp_e: + raise NameError("Local metadata is not available and you are in offline mode") from exp_e except ( TUFExceptions.DownloadError, TUFExceptions.RepositoryError, ) as e: raise TUFError("Failed to download trusted key bundle") from e + + logger.debug("Found trusted root") return TrustedRoot().from_json(Path(path).read_bytes()) From 70786481ea5c58625b601cc14c35a4b158a1c295 Mon Sep 17 00:00:00 2001 From: Emile Baez Date: Thu, 6 Apr 2023 15:50:48 -0400 Subject: [PATCH 2/3] offline flag hardcoded for testing purposes. tuf.py creates config with offline flag. requirements file edited so that tuf is not downloaded, requires pip install on our forked version. needs formal tests. --- sigstore/_internal/tuf.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sigstore/_internal/tuf.py b/sigstore/_internal/tuf.py index b910cfd98..f6f94dd8e 100644 --- a/sigstore/_internal/tuf.py +++ b/sigstore/_internal/tuf.py @@ -34,7 +34,7 @@ TrustedRoot, ) from tuf.api import exceptions as TUFExceptions -from tuf.ngclient import RequestsFetcher, Updater +from tuf.ngclient import RequestsFetcher, Updater, config from sigstore._utils import read_embedded from sigstore.errors import MetadataError, RootError, TUFError @@ -170,13 +170,17 @@ def staging(cls) -> TrustUpdater: @lru_cache() def _updater(self) -> Updater: """Initialize and update the toplevel TUF metadata""" + if self.offline: + configClass = config.UpdaterConfig(offline=True) + else: + configClass = config.UpdaterConfig() updater = Updater( metadata_dir=str(self._metadata_dir), metadata_base_url=self._repo_url, target_base_url=parse.urljoin(f"{self._repo_url}/", "targets/"), target_dir=str(self._targets_dir), fetcher=_get_fetcher(), - offline=self.offline + config=configClass ) # NOTE: we would like to avoid refresh if the toplevel metadata is valid. From 70b71b0952a1133421823c3b1dc74ae423853a13 Mon Sep 17 00:00:00 2001 From: Emile Baez Date: Thu, 6 Apr 2023 16:06:29 -0400 Subject: [PATCH 3/3] linted and signed? Signed-off-by: Emile Baez --- sigstore/_internal/tuf.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sigstore/_internal/tuf.py b/sigstore/_internal/tuf.py index f6f94dd8e..463070bdd 100644 --- a/sigstore/_internal/tuf.py +++ b/sigstore/_internal/tuf.py @@ -180,7 +180,7 @@ def _updater(self) -> Updater: target_base_url=parse.urljoin(f"{self._repo_url}/", "targets/"), target_dir=str(self._targets_dir), fetcher=_get_fetcher(), - config=configClass + config=configClass, ) # NOTE: we would like to avoid refresh if the toplevel metadata is valid. @@ -188,7 +188,9 @@ def _updater(self) -> Updater: try: updater.refresh() except TUFExceptions.ExpiredMetadataError as exp_e: - raise TUFError("Local metadata is not available and you are in offline mode") from exp_e + raise TUFError( + "Local metadata is not available and you are in offline mode" + ) from exp_e except Exception as e: raise TUFError("Failed to refresh TUF metadata") from e @@ -205,14 +207,14 @@ def _get_trusted_root(self) -> TrustedRoot: try: path = self._updater().download_target(root_info) except TUFExceptions.ExpiredMetadataError as exp_e: - raise NameError("Local metadata is not available and you are in offline mode") from exp_e + raise NameError( + "Local metadata is not available and you are in offline mode" + ) from exp_e except ( TUFExceptions.DownloadError, TUFExceptions.RepositoryError, ) as e: raise TUFError("Failed to download trusted key bundle") from e - - logger.debug("Found trusted root") return TrustedRoot().from_json(Path(path).read_bytes())