From 5a285d6761c4fa2820caf00d23f94e985459e177 Mon Sep 17 00:00:00 2001 From: Sebastien Awwad Date: Mon, 25 Mar 2019 18:10:34 -0400 Subject: [PATCH 1/2] List repos with Director first in demo/test data The director should be updated first, so this might be helpful to readers. Signed-off-by: Sebastien Awwad --- demo/pinned.json | 2 +- demo/pinned_primary_template.json | 2 +- demo/pinned_secondary_template.json | 2 +- tests/test_data/pinned.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/demo/pinned.json b/demo/pinned.json index af8f1c1..fc74c09 100644 --- a/demo/pinned.json +++ b/demo/pinned.json @@ -10,7 +10,7 @@ "delegations": [ { "paths": ["*"], - "repositories": ["imagerepo", "director"] + "repositories": ["director", "imagerepo"] } ] } \ No newline at end of file diff --git a/demo/pinned_primary_template.json b/demo/pinned_primary_template.json index f315207..c0c9e50 100644 --- a/demo/pinned_primary_template.json +++ b/demo/pinned_primary_template.json @@ -10,7 +10,7 @@ "delegations": [ { "paths": ["*"], - "repositories": ["imagerepo", "director"] + "repositories": ["director", "imagerepo"] } ] } \ No newline at end of file diff --git a/demo/pinned_secondary_template.json b/demo/pinned_secondary_template.json index f5ea383..fad641d 100644 --- a/demo/pinned_secondary_template.json +++ b/demo/pinned_secondary_template.json @@ -10,7 +10,7 @@ "delegations": [ { "paths": ["*"], - "repositories": ["imagerepo", "director"] + "repositories": ["director", "imagerepo"] } ] } \ No newline at end of file diff --git a/tests/test_data/pinned.json b/tests/test_data/pinned.json index fc92bc8..4c1d439 100644 --- a/tests/test_data/pinned.json +++ b/tests/test_data/pinned.json @@ -10,7 +10,7 @@ "delegations": [ { "paths": ["*"], - "repositories": ["imagerepo", "director"] + "repositories": ["director", "imagerepo"] } ] } \ No newline at end of file From 18c23b59c7ffe0144fbcd499f463039b3a879748 Mon Sep 17 00:00:00 2001 From: Sebastien Awwad Date: Thu, 28 Mar 2019 12:06:10 -0400 Subject: [PATCH 2/2] Make clients check Director first and also make the primary and secondary top-level metadata refresh procedure identical (for future modularization). This includes a rename in primary.py of refresh_toplevel_metadata_from_repositories to just refresh_toplevel_metadata, which is the same name the function has in secondary.py. While both names are accurate in a sense, the former could be misleading in secondary.py. Signed-off-by: Sebastien Awwad --- tests/test_primary.py | 4 ++-- uptane/clients/primary.py | 31 +++++++++++++++++++++++++------ uptane/clients/secondary.py | 36 +++++++++++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 9 deletions(-) diff --git a/tests/test_primary.py b/tests/test_primary.py index 6a139e4..f7087a9 100644 --- a/tests/test_primary.py +++ b/tests/test_primary.py @@ -708,7 +708,7 @@ def test_25_generate_signed_vehicle_manifest(self): - def test_30_refresh_toplevel_metadata_from_repositories(self): + def test_30_refresh_toplevel_metadata(self): # Check that in the fresh temp directory for this test Primary client, # there aren't any metadata files except root.json yet. @@ -720,7 +720,7 @@ def test_30_refresh_toplevel_metadata_from_repositories(self): sorted(os.listdir(TEST_IMAGE_REPO_METADATA_DIR))) try: - TestPrimary.instance.refresh_toplevel_metadata_from_repositories() + TestPrimary.instance.refresh_toplevel_metadata() except (URLError, tuf.NoWorkingMirrorError) as e: pass else: diff --git a/uptane/clients/primary.py b/uptane/clients/primary.py index d502985..f26c271 100644 --- a/uptane/clients/primary.py +++ b/uptane/clients/primary.py @@ -177,7 +177,7 @@ class Primary(object): # Consider inheriting from Secondary and refactoring. Lower-level methods called by primary_update_cycle() to perform retrieval and validation of metadata and data from central services: - refresh_toplevel_metadata_from_repositories() + refresh_toplevel_metadata() get_target_list_from_director() get_validated_target_info() @@ -332,16 +332,35 @@ def __init__( - def refresh_toplevel_metadata_from_repositories(self): + def refresh_toplevel_metadata(self): """ Refreshes client's metadata for the top-level roles: root, targets, snapshot, and timestamp See tuf.client.updater.Updater.refresh() for details, or the - Uptane Implementation Specification, section 8.3.2 (Full Verification of - Metadata). + Uptane Standard, section 5.4.4.2 (Full Verification). + + # TODO: This function is duplicated in primary.py and secondary.py. It must + # be moved to a general client.py as part of a fix to issue #14 + # (github.com/uptane/uptane/issues/14). + This can raise TUF update exceptions like + - tuf.ExpiredMetadataError: + if after attempts to update the Root metadata succeeded or failed, + whatever currently trusted Root metadata we ended up with was expired. + - tuf.NoWorkingMirrorError: + if we could not obtain and verify all necessary metadata """ - self.updater.refresh() + + # Refresh the Director first, per the Uptane Standard. + self.updater.refresh(repo_name=self.director_repo_name) + + # Now that we've dealt with the Director repository, deal with any and all + # other repositories, presumably Image Repositories. + for repository_name in self.updater.repositories: + if repository_name == self.director_repo_name: + continue + + self.updater.refresh(repo_name=repository_name) @@ -492,7 +511,7 @@ def primary_update_cycle(self): file of type tuf.conf.METADATA_FORMAT. """ log.debug('Refreshing top level metadata from all repositories.') - self.refresh_toplevel_metadata_from_repositories() + self.refresh_toplevel_metadata() # Get the list of targets the director expects us to download and update to. # Note that at this line, this target info is not yet validated with the diff --git a/uptane/clients/secondary.py b/uptane/clients/secondary.py index c5accb0..88ea8fe 100644 --- a/uptane/clients/secondary.py +++ b/uptane/clients/secondary.py @@ -470,6 +470,40 @@ def update_time(self, timeserver_attestation): + def refresh_toplevel_metadata(self): + """ + Refreshes client's metadata for the top-level roles: + root, targets, snapshot, and timestamp + + See tuf.client.updater.Updater.refresh() for details, or the + Uptane Standard, section 5.4.4.2 (Full Verification). + + # TODO: This function is duplicated in primary.py and secondary.py. It must + # be moved to a general client.py as part of a fix to issue #14 + # (github.com/uptane/uptane/issues/14). + This can raise TUF update exceptions like + - tuf.ExpiredMetadataError: + if after attempts to update the Root metadata succeeded or failed, + whatever currently trusted Root metadata we ended up with was expired. + - tuf.NoWorkingMirrorError: + if we could not obtain and verify all necessary metadata + """ + + # Refresh the Director first, per the Uptane Standard. + self.updater.refresh(repo_name=self.director_repo_name) + + # Now that we've dealt with the Director repository, deal with any and all + # other repositories, presumably Image Repositories. + for repository_name in self.updater.repositories: + if repository_name == self.director_repo_name: + continue + + self.updater.refresh(repo_name=repository_name) + + + + + def fully_validate_metadata(self): """ Treats the unvalidated metadata obtained from the Primary (which the @@ -504,7 +538,7 @@ def fully_validate_metadata(self): """ # Refresh the top-level metadata first (all repositories). - self.updater.refresh() + self.refresh_toplevel_metadata() validated_targets_for_this_ecu = []