From 0c972717d058dbc214a687f64f2f0e5b83c8b37b Mon Sep 17 00:00:00 2001 From: Joshua Lock Date: Tue, 18 Feb 2020 21:22:39 +0000 Subject: [PATCH 1/8] Remove root from snapshot In PR #40 aginst the specification "root.json" has been removed from the meta dictionary in "snapshot.json". Update generate_snapshot_metadata() to no longer add an entry for root.json to root.json Signed-off-by: Joshua Lock --- tuf/repository_lib.py | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/tuf/repository_lib.py b/tuf/repository_lib.py index 11c5173d..965e9d70 100755 --- a/tuf/repository_lib.py +++ b/tuf/repository_lib.py @@ -121,11 +121,10 @@ def _generate_and_write_metadata(rolename, metadata_filename, elif rolename == 'snapshot': - root_filename = ROOT_FILENAME[:-len(METADATA_EXTENSION)] targets_filename = TARGETS_FILENAME[:-len(METADATA_EXTENSION)] metadata = generate_snapshot_metadata(metadata_directory, - roleinfo['version'], roleinfo['expires'], root_filename, - targets_filename, consistent_snapshot, repository_name) + roleinfo['version'], roleinfo['expires'], targets_filename, + consistent_snapshot, repository_name) _log_warning_if_expires_soon(SNAPSHOT_FILENAME, roleinfo['expires'], @@ -1356,8 +1355,7 @@ def generate_targets_metadata(targets_directory, target_files, version, def generate_snapshot_metadata(metadata_directory, version, expiration_date, - root_filename, targets_filename, consistent_snapshot=False, - repository_name='default'): + targets_filename, consistent_snapshot=False, repository_name='default'): """ Create the snapshot metadata. The minimum metadata must exist (i.e., @@ -1379,10 +1377,6 @@ def generate_snapshot_metadata(metadata_directory, version, expiration_date, The expiration date of the metadata file. Conformant to 'securesystemslib.formats.ISO8601_DATETIME_SCHEMA'. - root_filename: - The filename of the top-level root role. The hash and file size of this - file is listed in the snapshot role. - targets_filename: The filename of the top-level targets role. The hash and file size of this file is listed in the snapshot role. @@ -1417,7 +1411,6 @@ def generate_snapshot_metadata(metadata_directory, version, expiration_date, securesystemslib.formats.PATH_SCHEMA.check_match(metadata_directory) tuf.formats.METADATAVERSION_SCHEMA.check_match(version) securesystemslib.formats.ISO8601_DATETIME_SCHEMA.check_match(expiration_date) - securesystemslib.formats.PATH_SCHEMA.check_match(root_filename) securesystemslib.formats.PATH_SCHEMA.check_match(targets_filename) securesystemslib.formats.BOOLEAN_SCHEMA.check_match(consistent_snapshot) securesystemslib.formats.NAME_SCHEMA.check_match(repository_name) @@ -1427,8 +1420,6 @@ def generate_snapshot_metadata(metadata_directory, version, expiration_date, # Snapshot's 'fileinfodict' shall contain the version number of Root, # Targets, and all delegated roles fo the repository. fileinfodict = {} - fileinfodict[ROOT_FILENAME] = get_metadata_versioninfo(root_filename, - repository_name) fileinfodict[TARGETS_FILENAME] = get_metadata_versioninfo(targets_filename, repository_name) From 8f13fe5added8fcfba91d4964015ed487999e116 Mon Sep 17 00:00:00 2001 From: Joshua Lock Date: Thu, 27 Feb 2020 15:12:51 +0000 Subject: [PATCH 2/8] Update tests for removal of root.json from snapshot.json Signed-off-by: Joshua Lock --- tests/test_repository_lib.py | 17 ++++++----------- tests/test_updater.py | 1 - 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/tests/test_repository_lib.py b/tests/test_repository_lib.py index e80f2954..9d6f9de0 100755 --- a/tests/test_repository_lib.py +++ b/tests/test_repository_lib.py @@ -433,7 +433,6 @@ def test_generate_snapshot_metadata(self): metadata_directory = os.path.join(repository_directory, repo_lib.METADATA_STAGED_DIRECTORY_NAME) targets_directory = os.path.join(repository_directory, repo_lib.TARGETS_DIRECTORY_NAME) - root_filename = os.path.join(metadata_directory, repo_lib.ROOT_FILENAME) targets_filename = os.path.join(metadata_directory, repo_lib.TARGETS_FILENAME) version = 1 @@ -453,12 +452,11 @@ def test_generate_snapshot_metadata(self): with open(invalid_metadata_file, 'w') as file_object: file_object.write('bad extension on metadata file') - root_filename = 'root' targets_filename = 'targets' snapshot_metadata = \ repo_lib.generate_snapshot_metadata(metadata_directory, version, - expiration_date, root_filename, + expiration_date, targets_filename, consistent_snapshot=False) self.assertTrue(tuf.formats.SNAPSHOT_SCHEMA.matches(snapshot_metadata)) @@ -467,22 +465,19 @@ def test_generate_snapshot_metadata(self): # Test improperly formatted arguments. self.assertRaises(securesystemslib.exceptions.FormatError, repo_lib.generate_snapshot_metadata, 3, version, expiration_date, - root_filename, targets_filename, consistent_snapshot=False) + targets_filename, consistent_snapshot=False) self.assertRaises(securesystemslib.exceptions.FormatError, repo_lib.generate_snapshot_metadata, metadata_directory, '3', expiration_date, - root_filename, targets_filename, consistent_snapshot=False) + targets_filename, consistent_snapshot=False) self.assertRaises(securesystemslib.exceptions.FormatError, repo_lib.generate_snapshot_metadata, metadata_directory, version, '3', - root_filename, targets_filename, consistent_snapshot=False) + targets_filename, consistent_snapshot=False) self.assertRaises(securesystemslib.exceptions.FormatError, repo_lib.generate_snapshot_metadata, metadata_directory, version, expiration_date, - 3, targets_filename, consistent_snapshot=False) + 3, consistent_snapshot=False) self.assertRaises(securesystemslib.exceptions.FormatError, repo_lib.generate_snapshot_metadata, metadata_directory, version, expiration_date, - root_filename, 3, consistent_snapshot=False) - self.assertRaises(securesystemslib.exceptions.FormatError, repo_lib.generate_snapshot_metadata, - metadata_directory, version, expiration_date, - root_filename, targets_filename, 3) + targets_filename, 3) diff --git a/tests/test_updater.py b/tests/test_updater.py index 1fa89698..25a193ae 100644 --- a/tests/test_updater.py +++ b/tests/test_updater.py @@ -886,7 +886,6 @@ def test_3__update_metadata_if_changed(self): self.repository_updater._update_metadata('timestamp', DEFAULT_TIMESTAMP_FILELENGTH) self.repository_updater._update_metadata_if_changed('snapshot', 'timestamp') self.repository_updater._update_metadata_if_changed('targets') - self.repository_updater._update_metadata_if_changed('root') targets_path = os.path.join(self.client_metadata_current, 'targets.json') self.assertTrue(os.path.exists(targets_path)) self.assertTrue(self.repository_updater.metadata['current']['targets']) From 8dfee1a106c8e99f2a6cc2afb8f465e1a7750346 Mon Sep 17 00:00:00 2001 From: Joshua Lock Date: Thu, 27 Feb 2020 12:10:31 +0000 Subject: [PATCH 3/8] Update docs/METADATA.md to reflect recent spec change The specification was updated in PR #40 to remove root.json from snapshot.json Signed-off-by: Joshua Lock --- docs/METADATA.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/METADATA.md b/docs/METADATA.md index 8bd6c17c..9f140fe8 100644 --- a/docs/METADATA.md +++ b/docs/METADATA.md @@ -64,7 +64,7 @@ of delegated Targets metadata and [example](https://raw.githubusercontent.com/th Signed by: Snapshot role. -The snapshot.json metadata file lists hashes and sizes of all metadata files other than timestamp.json. This file ensures that clients will see a consistent view of the files on the repository. That is, metadata files (and thus target file) that existed on the repository at different times cannot be combined and presented to clients by an attacker. +The snapshot.json metadata file lists the version, and optionally the file hashes and sizes, of the top-level targets metadata and all delegated targets metadata. This file ensures that clients will see a consistent view of the files on the repository. That is, metadata files (and thus target file) that existed on the repository at different times cannot be combined and presented to clients by an attacker. ​See [example](https://raw.githubusercontent.com/theupdateframework/tuf/develop/tests/repository_data/repository/metadata/snapshot.json) of Snapshot metadata. From 8dafe6018d4dd843bae5d5cc8e16925f72216029 Mon Sep 17 00:00:00 2001 From: Joshua Lock Date: Fri, 28 Feb 2020 10:33:43 +0000 Subject: [PATCH 4/8] Update docstrings and comments for the Updater object The workflow for downloading metadata for top-level roles has changed. Root is now updated and verified by stepping through a chain of trust based on the currently available root metadata. For that reason root.json is no longer needed in snapshot and has been dropped from there per theupdateframework/specification#40 Update docstrings and comments in the Updater object to reflect the correct flow of metadata updates: root (if necessary) -> timestamp -> snapshot -> targets Signed-off-by: Joshua Lock --- tuf/client/updater.py | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/tuf/client/updater.py b/tuf/client/updater.py index 62229421..48397abd 100755 --- a/tuf/client/updater.py +++ b/tuf/client/updater.py @@ -589,7 +589,7 @@ class Updater(object): refresh(): This method downloads, verifies, and loads metadata for the top-level - roles in a specific order (i.e., timestamp -> snapshot -> root -> targets) + roles in a specific order (i.e., root -> timestamp -> snapshot -> targets) The expiration time for downloaded metadata is also verified. The metadata for delegated roles are not refreshed by this method, but by @@ -1002,7 +1002,7 @@ def refresh(self, unsafely_update_root_if_necessary=True): Update the latest copies of the metadata for the top-level roles. The update request process follows a specific order to ensure the metadata files are securely updated: - timestamp -> snapshot -> root (if necessary) -> targets. + root (if necessary) -> timestamp -> snapshot -> targets. Delegated metadata is not refreshed by this method. After this method is called, the use of get_one_valid_targetinfo() will update delegated @@ -1072,10 +1072,8 @@ def refresh(self, unsafely_update_root_if_necessary=True): logger.info('An expired Root metadata was loaded and must be updated.') raise - # TODO: How should the latest root metadata be verified? According to the - # currently trusted root keys? What if all of the currently trusted - # root keys have since been revoked by the latest metadata? Alternatively, - # do we blindly trust the downloaded root metadata here? + # Update the root metadata and verify it by building a chain of trusted root + # keys from the current trusted root metadata file self._update_root_metadata(root_metadata) # Ensure that the role and key information of the top-level roles is the @@ -1093,9 +1091,6 @@ def refresh(self, unsafely_update_root_if_necessary=True): # require strict checks on its required length. self._update_metadata('timestamp', DEFAULT_TIMESTAMP_UPPERLENGTH) - # TODO: After fetching snapshot.json, we should either verify the root - # fileinfo referenced there matches what was fetched earlier in - # _update_root_metadata() or make another attempt to download root.json. self._update_metadata_if_changed('snapshot', referenced_metadata='timestamp') self._update_metadata_if_changed('targets') @@ -1836,21 +1831,23 @@ def _update_metadata_if_changed(self, metadata_role, """ Non-public method that updates the metadata for 'metadata_role' if it has - changed. With the exception of the 'timestamp' role, all the top-level + changed. All top-level roles other than the 'timestamp' and 'root' roles are updated by this method. The 'timestamp' role is always downloaded from a mirror without first checking if it has been updated; it is updated in refresh() by calling _update_metadata('timestamp'). + The 'root' role is always updated first and verified based on the trusted + root metadata file the client already has a copy of; it is updated in + refresh() by calling _update_root_metadata(). This method is also called for delegated role metadata, which are referenced by 'snapshot'. If the metadata needs to be updated but an update cannot be obtained, - this method will delete the file (with the exception of the root - metadata, which never gets removed without a replacement). + this method will delete the file. Due to the way in which metadata files are updated, it is expected that 'referenced_metadata' is not out of date and trusted. The refresh() - method updates the top-level roles in 'timestamp -> snapshot -> - root -> targets' order. For delegated metadata, the parent role is + method updates the top-level roles in 'root -> timestamp -> snapshot -> + targets' order. For delegated metadata, the parent role is updated before the delegated role. Taking into account that 'referenced_metadata' is updated and verified before 'metadata_role', this method determines if 'metadata_role' has changed by checking From a134db0a43ca8d37f7a5dc383f097b3192d20d55 Mon Sep 17 00:00:00 2001 From: Joshua Lock Date: Thu, 27 Feb 2020 15:13:50 +0000 Subject: [PATCH 5/8] Update test repository data generator * Fix the path referenced in the Purpose * Change add_target() calls to pass file paths relative to targets dir Signed-off-by: Joshua Lock --- tests/repository_data/generate.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/repository_data/generate.py b/tests/repository_data/generate.py index de0f0d70..8eb8d8d9 100755 --- a/tests/repository_data/generate.py +++ b/tests/repository_data/generate.py @@ -20,7 +20,7 @@ Provide a set of pre-generated key files and a basic repository that unit tests can use in their test cases. The pre-generated files created by this script should be copied by the unit tests as needed. The original versions - should be preserved. 'tuf/tests/unit/repository_files/' will store the files + should be preserved. 'tuf/tests/repository_data/' will store the files generated. 'generate.py' should not require re-execution if the pre-generated repository files have already been created, unless they need to change in some way. @@ -119,12 +119,12 @@ # about the target (i.e., file permissions in octal format.) octal_file_permissions = oct(os.stat(target1_filepath).st_mode)[4:] file_permissions = {'file_permissions': octal_file_permissions} -repository.targets.add_target(target1_filepath, file_permissions) -repository.targets.add_target(target2_filepath) +repository.targets.add_target(os.path.basename(target1_filepath), file_permissions) +repository.targets.add_target(os.path.basename(target2_filepath)) repository.targets.delegate('role1', [delegation_public], [os.path.basename(target3_filepath)]) -repository.targets('role1').add_target(target3_filepath) +repository.targets('role1').add_target(os.path.basename(target3_filepath)) repository.targets('role1').load_signing_key(delegation_private) repository.targets('role1').delegate('role2', [delegation_public], []) From 4bd9b5ef6b3dc9deb36f747a033a944a8cea32c5 Mon Sep 17 00:00:00 2001 From: Joshua Lock Date: Wed, 4 Mar 2020 10:03:42 +0000 Subject: [PATCH 6/8] Improve determinism of test repository generator One of the created target files has its file permissions encoded in the targets metadata via the custom attribute of the add_target() function. On Linux-based OS the umask value of the environment the script is run in can result in different octal permissions for the created file, i.e. on Fedora the default umask is 0002 (default permissions 664) whereas on Debian/Ubuntu the default umask is 0022 (default permissions 644). Explicitly chown 'file1' to octal permissions 644 so that the generated data has the same custom attributes for targets regardless of which Linux host they are generated on. Signed-off-by: Joshua Lock --- tests/repository_data/generate.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/repository_data/generate.py b/tests/repository_data/generate.py index 8eb8d8d9..fc253c2c 100755 --- a/tests/repository_data/generate.py +++ b/tests/repository_data/generate.py @@ -107,6 +107,11 @@ if not options.dry_run: with open(target1_filepath, 'wt') as file_object: file_object.write('This is an example target file.') + # As we will add this file's permissions to the custom_attribute in the + # target's metadata we need to ensure that the file has the same + # permissions when created by this script regardless of umask value on + # the host system generating the data + os.chmod(target1_filepath, 0o644) with open(target2_filepath, 'wt') as file_object: file_object.write('This is an another example target file.') From 3720b2358e3f263d20d3452080bab9edabd6b573 Mon Sep 17 00:00:00 2001 From: Joshua Lock Date: Thu, 27 Feb 2020 14:55:07 +0000 Subject: [PATCH 7/8] Re-generate repository and client test metadata Re-generate metadata to adopt the change that root.json is no longer listed in snapshot.json ``` # Remove repository and client data cd tests/repository_data && rm -rf repository client # Generate metadata python generate.py # Duplicate metadata files cp -r client/test_repository1 client/test_repository2 # Recover non-signed file git checkout client/map.json ``` Signed-off-by: Joshua Lock --- .../metadata/current/1.root.json | Bin 3396 -> 3396 bytes .../metadata/current/root.json | Bin 3396 -> 3396 bytes .../metadata/current/snapshot.json | Bin 556 -> 515 bytes .../metadata/current/timestamp.json | Bin 557 -> 557 bytes .../metadata/previous/1.root.json | Bin 3396 -> 3396 bytes .../metadata/previous/root.json | Bin 3396 -> 3396 bytes .../metadata/previous/snapshot.json | Bin 556 -> 515 bytes .../metadata/previous/timestamp.json | Bin 557 -> 557 bytes .../metadata/current/1.root.json | Bin 3396 -> 3396 bytes .../metadata/current/root.json | Bin 3396 -> 3396 bytes .../metadata/current/snapshot.json | Bin 556 -> 515 bytes .../metadata/current/timestamp.json | Bin 557 -> 557 bytes .../metadata/previous/1.root.json | Bin 3396 -> 3396 bytes .../metadata/previous/root.json | Bin 3396 -> 3396 bytes .../metadata/previous/snapshot.json | Bin 556 -> 515 bytes .../metadata/previous/timestamp.json | Bin 557 -> 557 bytes .../repository/metadata.staged/1.root.json | Bin 3396 -> 3396 bytes .../repository/metadata.staged/root.json | Bin 3396 -> 3396 bytes .../repository/metadata.staged/snapshot.json | Bin 556 -> 515 bytes .../repository/metadata.staged/timestamp.json | Bin 557 -> 557 bytes .../repository/metadata/1.root.json | Bin 3396 -> 3396 bytes .../repository/metadata/root.json | Bin 3396 -> 3396 bytes .../repository/metadata/snapshot.json | Bin 556 -> 515 bytes .../repository/metadata/timestamp.json | Bin 557 -> 557 bytes 24 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/repository_data/client/test_repository1/metadata/current/1.root.json b/tests/repository_data/client/test_repository1/metadata/current/1.root.json index 9cc9d4dc874447f688eda362a42793572953690f..214d8db01b6ce52ef48cefbbe3d59c65a59b59b1 100644 GIT binary patch delta 786 zcmWlXTMb<~3`IXisx%ae!m;BQ9KQmf1TKYgDTN{!MB}UcD;~9bNlM`(vU03_$M+JN6(0F%;RdE(_Oq>*N7*0R#wakyV z;MyvAPgX@A3_T$htpWVlUL~86ic1U%doLBkW#;otE{KrEOsPE)bx0`$4tWSpkf9l~1$Q9f&y0eT=;`ZX3GCb!x@eOJN` z6P?9uKaw*Spl3`9SWkZ6G_{74+T96t-7f!hMT&;k`u5r&`LY*zA&=gjZ#zrX+d@wru! zB!>H9c2G*7;A%D5RaIg~h`~bRg<~V_7o_rZq zoh~I~XD^OGYv4m(O|RprBIX=4ZY6K-J(i#Jv-;-|cbJd?du3zN6g8MXIIf<%#%gIOm;XQAE4@F+KN#A?^1>$|kR-fJ zCC!LT(zAE%vtH6fly;GnH4nmgh?dKmw7r5VLSJA>wFJ{&GuGj@H=BX4d9zj-^xJ$m zZrjHEnF7qA<6$=lJ7$EL&&j*whK#Q799dm_M)Nk>)E*~h8r|%$dvT{A-g1@5gLqb< z99qtOyyR^AJkrxy3Q3LBMOdRqxT81)t4W#+FRU;cdi3tr9J AJOBUy diff --git a/tests/repository_data/client/test_repository1/metadata/current/root.json b/tests/repository_data/client/test_repository1/metadata/current/root.json index 9cc9d4dc874447f688eda362a42793572953690f..214d8db01b6ce52ef48cefbbe3d59c65a59b59b1 100644 GIT binary patch delta 786 zcmWlXTMb<~3`IXisx%ae!m;BQ9KQmf1TKYgDTN{!MB}UcD;~9bNlM`(vU03_$M+JN6(0F%;RdE(_Oq>*N7*0R#wakyV z;MyvAPgX@A3_T$htpWVlUL~86ic1U%doLBkW#;otE{KrEOsPE)bx0`$4tWSpkf9l~1$Q9f&y0eT=;`ZX3GCb!x@eOJN` z6P?9uKaw*Spl3`9SWkZ6G_{74+T96t-7f!hMT&;k`u5r&`LY*zA&=gjZ#zrX+d@wru! zB!>H9c2G*7;A%D5RaIg~h`~bRg<~V_7o_rZq zoh~I~XD^OGYv4m(O|RprBIX=4ZY6K-J(i#Jv-;-|cbJd?du3zN6g8MXIIf<%#%gIOm;XQAE4@F+KN#A?^1>$|kR-fJ zCC!LT(zAE%vtH6fly;GnH4nmgh?dKmw7r5VLSJA>wFJ{&GuGj@H=BX4d9zj-^xJ$m zZrjHEnF7qA<6$=lJ7$EL&&j*whK#Q799dm_M)Nk>)E*~h8r|%$dvT{A-g1@5gLqb< z99qtOyyR^AJkrxy3Q3LBMOdRqxT81)t4W#+FRU;cdi3tr9J AJOBUy diff --git a/tests/repository_data/client/test_repository1/metadata/current/snapshot.json b/tests/repository_data/client/test_repository1/metadata/current/snapshot.json index af56f045be88d7da8d034628e01bc79c23ac1d54..7c8c091a2ee503c11125d646f88f1cbfdc4b93d9 100644 GIT binary patch delta 143 zcmWN{OA$gb3;@7k<_Svkj}>lhlL){72MoYqgF8Nuf&$p{zK+{*zg)pZ4Yxsd7pe{@ zabc_yL1$8;-IZZ9SI!LHqJunF!_J7I%#BHnR-8Er!V7#ZH7#pFMO)$)Y_l|S4H%db QQ*)00JnhH#{rsHHKUQTae*gdg delta 152 zcmV~$%MHRX3;K?3M$FUP{L*mc1QpKGE3xGNTR}S2|7ZdQ_WBshp{Vsxr!;mGW znQ@bbo!L8SjjS3F#ua!QXIS#}JJ)^NZpU}I9Pj1&2i>MDVgLXD diff --git a/tests/repository_data/client/test_repository1/metadata/current/timestamp.json b/tests/repository_data/client/test_repository1/metadata/current/timestamp.json index 6c8a58d153c40549a4a0f1792e7f10b6c9f6d04d..9a0daf078be4c53de9d4cce01b73920c0daf1a9e 100644 GIT binary patch delta 234 zcmW-bv28;!3`AkTRi-e0okA2Pk<1F&ARS4Ob`hiq(i&dDfdOyfr7}V$h>&ZpdiUun77j?NS$6RKdw=6(j%wQ28dOJa7-CjOz@j-_Le`tGlBOzT hinPSS1T;x)dpfL~pZ{xnkB{TmX?rmMQJLn;6O delta 234 zcmW-ZyG=wv3`MolMpUtSF~Qg~{?P&*klAAo1c(5Uu4n;Q34h4#7&NLq;qe_ z+wtrD6FNl++W@83C~J6PI`~wZeKB?Rs9i9NHt^Axd9V{=_)Ifdy!w#UoYp9wAxbzH ze9y>hIqd%m5@6ljGqP2M)*Ljl9rFA4`UFcbt%(~kV9hAk;3ZQ^b)qObR&y@%$-QIk hxmsmdYWK$5-D%(X{vX?Gy*+=tY!4?QzWf{>{{VfqLyiCd diff --git a/tests/repository_data/client/test_repository1/metadata/previous/1.root.json b/tests/repository_data/client/test_repository1/metadata/previous/1.root.json index 9cc9d4dc874447f688eda362a42793572953690f..214d8db01b6ce52ef48cefbbe3d59c65a59b59b1 100644 GIT binary patch delta 786 zcmWlXTMb<~3`IXisx%ae!m;BQ9KQmf1TKYgDTN{!MB}UcD;~9bNlM`(vU03_$M+JN6(0F%;RdE(_Oq>*N7*0R#wakyV z;MyvAPgX@A3_T$htpWVlUL~86ic1U%doLBkW#;otE{KrEOsPE)bx0`$4tWSpkf9l~1$Q9f&y0eT=;`ZX3GCb!x@eOJN` z6P?9uKaw*Spl3`9SWkZ6G_{74+T96t-7f!hMT&;k`u5r&`LY*zA&=gjZ#zrX+d@wru! zB!>H9c2G*7;A%D5RaIg~h`~bRg<~V_7o_rZq zoh~I~XD^OGYv4m(O|RprBIX=4ZY6K-J(i#Jv-;-|cbJd?du3zN6g8MXIIf<%#%gIOm;XQAE4@F+KN#A?^1>$|kR-fJ zCC!LT(zAE%vtH6fly;GnH4nmgh?dKmw7r5VLSJA>wFJ{&GuGj@H=BX4d9zj-^xJ$m zZrjHEnF7qA<6$=lJ7$EL&&j*whK#Q799dm_M)Nk>)E*~h8r|%$dvT{A-g1@5gLqb< z99qtOyyR^AJkrxy3Q3LBMOdRqxT81)t4W#+FRU;cdi3tr9J AJOBUy diff --git a/tests/repository_data/client/test_repository1/metadata/previous/root.json b/tests/repository_data/client/test_repository1/metadata/previous/root.json index 9cc9d4dc874447f688eda362a42793572953690f..214d8db01b6ce52ef48cefbbe3d59c65a59b59b1 100644 GIT binary patch delta 786 zcmWlXTMb<~3`IXisx%ae!m;BQ9KQmf1TKYgDTN{!MB}UcD;~9bNlM`(vU03_$M+JN6(0F%;RdE(_Oq>*N7*0R#wakyV z;MyvAPgX@A3_T$htpWVlUL~86ic1U%doLBkW#;otE{KrEOsPE)bx0`$4tWSpkf9l~1$Q9f&y0eT=;`ZX3GCb!x@eOJN` z6P?9uKaw*Spl3`9SWkZ6G_{74+T96t-7f!hMT&;k`u5r&`LY*zA&=gjZ#zrX+d@wru! zB!>H9c2G*7;A%D5RaIg~h`~bRg<~V_7o_rZq zoh~I~XD^OGYv4m(O|RprBIX=4ZY6K-J(i#Jv-;-|cbJd?du3zN6g8MXIIf<%#%gIOm;XQAE4@F+KN#A?^1>$|kR-fJ zCC!LT(zAE%vtH6fly;GnH4nmgh?dKmw7r5VLSJA>wFJ{&GuGj@H=BX4d9zj-^xJ$m zZrjHEnF7qA<6$=lJ7$EL&&j*whK#Q799dm_M)Nk>)E*~h8r|%$dvT{A-g1@5gLqb< z99qtOyyR^AJkrxy3Q3LBMOdRqxT81)t4W#+FRU;cdi3tr9J AJOBUy diff --git a/tests/repository_data/client/test_repository1/metadata/previous/snapshot.json b/tests/repository_data/client/test_repository1/metadata/previous/snapshot.json index af56f045be88d7da8d034628e01bc79c23ac1d54..7c8c091a2ee503c11125d646f88f1cbfdc4b93d9 100644 GIT binary patch delta 143 zcmWN{OA$gb3;@7k<_Svkj}>lhlL){72MoYqgF8Nuf&$p{zK+{*zg)pZ4Yxsd7pe{@ zabc_yL1$8;-IZZ9SI!LHqJunF!_J7I%#BHnR-8Er!V7#ZH7#pFMO)$)Y_l|S4H%db QQ*)00JnhH#{rsHHKUQTae*gdg delta 152 zcmV~$%MHRX3;K?3M$FUP{L*mc1QpKGE3xGNTR}S2|7ZdQ_WBshp{Vsxr!;mGW znQ@bbo!L8SjjS3F#ua!QXIS#}JJ)^NZpU}I9Pj1&2i>MDVgLXD diff --git a/tests/repository_data/client/test_repository1/metadata/previous/timestamp.json b/tests/repository_data/client/test_repository1/metadata/previous/timestamp.json index 6c8a58d153c40549a4a0f1792e7f10b6c9f6d04d..9a0daf078be4c53de9d4cce01b73920c0daf1a9e 100644 GIT binary patch delta 234 zcmW-bv28;!3`AkTRi-e0okA2Pk<1F&ARS4Ob`hiq(i&dDfdOyfr7}V$h>&ZpdiUun77j?NS$6RKdw=6(j%wQ28dOJa7-CjOz@j-_Le`tGlBOzT hinPSS1T;x)dpfL~pZ{xnkB{TmX?rmMQJLn;6O delta 234 zcmW-ZyG=wv3`MolMpUtSF~Qg~{?P&*klAAo1c(5Uu4n;Q34h4#7&NLq;qe_ z+wtrD6FNl++W@83C~J6PI`~wZeKB?Rs9i9NHt^Axd9V{=_)Ifdy!w#UoYp9wAxbzH ze9y>hIqd%m5@6ljGqP2M)*Ljl9rFA4`UFcbt%(~kV9hAk;3ZQ^b)qObR&y@%$-QIk hxmsmdYWK$5-D%(X{vX?Gy*+=tY!4?QzWf{>{{VfqLyiCd diff --git a/tests/repository_data/client/test_repository2/metadata/current/1.root.json b/tests/repository_data/client/test_repository2/metadata/current/1.root.json index 9cc9d4dc874447f688eda362a42793572953690f..214d8db01b6ce52ef48cefbbe3d59c65a59b59b1 100644 GIT binary patch delta 786 zcmWlXTMb<~3`IXisx%ae!m;BQ9KQmf1TKYgDTN{!MB}UcD;~9bNlM`(vU03_$M+JN6(0F%;RdE(_Oq>*N7*0R#wakyV z;MyvAPgX@A3_T$htpWVlUL~86ic1U%doLBkW#;otE{KrEOsPE)bx0`$4tWSpkf9l~1$Q9f&y0eT=;`ZX3GCb!x@eOJN` z6P?9uKaw*Spl3`9SWkZ6G_{74+T96t-7f!hMT&;k`u5r&`LY*zA&=gjZ#zrX+d@wru! zB!>H9c2G*7;A%D5RaIg~h`~bRg<~V_7o_rZq zoh~I~XD^OGYv4m(O|RprBIX=4ZY6K-J(i#Jv-;-|cbJd?du3zN6g8MXIIf<%#%gIOm;XQAE4@F+KN#A?^1>$|kR-fJ zCC!LT(zAE%vtH6fly;GnH4nmgh?dKmw7r5VLSJA>wFJ{&GuGj@H=BX4d9zj-^xJ$m zZrjHEnF7qA<6$=lJ7$EL&&j*whK#Q799dm_M)Nk>)E*~h8r|%$dvT{A-g1@5gLqb< z99qtOyyR^AJkrxy3Q3LBMOdRqxT81)t4W#+FRU;cdi3tr9J AJOBUy diff --git a/tests/repository_data/client/test_repository2/metadata/current/root.json b/tests/repository_data/client/test_repository2/metadata/current/root.json index 9cc9d4dc874447f688eda362a42793572953690f..214d8db01b6ce52ef48cefbbe3d59c65a59b59b1 100644 GIT binary patch delta 786 zcmWlXTMb<~3`IXisx%ae!m;BQ9KQmf1TKYgDTN{!MB}UcD;~9bNlM`(vU03_$M+JN6(0F%;RdE(_Oq>*N7*0R#wakyV z;MyvAPgX@A3_T$htpWVlUL~86ic1U%doLBkW#;otE{KrEOsPE)bx0`$4tWSpkf9l~1$Q9f&y0eT=;`ZX3GCb!x@eOJN` z6P?9uKaw*Spl3`9SWkZ6G_{74+T96t-7f!hMT&;k`u5r&`LY*zA&=gjZ#zrX+d@wru! zB!>H9c2G*7;A%D5RaIg~h`~bRg<~V_7o_rZq zoh~I~XD^OGYv4m(O|RprBIX=4ZY6K-J(i#Jv-;-|cbJd?du3zN6g8MXIIf<%#%gIOm;XQAE4@F+KN#A?^1>$|kR-fJ zCC!LT(zAE%vtH6fly;GnH4nmgh?dKmw7r5VLSJA>wFJ{&GuGj@H=BX4d9zj-^xJ$m zZrjHEnF7qA<6$=lJ7$EL&&j*whK#Q799dm_M)Nk>)E*~h8r|%$dvT{A-g1@5gLqb< z99qtOyyR^AJkrxy3Q3LBMOdRqxT81)t4W#+FRU;cdi3tr9J AJOBUy diff --git a/tests/repository_data/client/test_repository2/metadata/current/snapshot.json b/tests/repository_data/client/test_repository2/metadata/current/snapshot.json index af56f045be88d7da8d034628e01bc79c23ac1d54..7c8c091a2ee503c11125d646f88f1cbfdc4b93d9 100644 GIT binary patch delta 143 zcmWN{OA$gb3;@7k<_Svkj}>lhlL){72MoYqgF8Nuf&$p{zK+{*zg)pZ4Yxsd7pe{@ zabc_yL1$8;-IZZ9SI!LHqJunF!_J7I%#BHnR-8Er!V7#ZH7#pFMO)$)Y_l|S4H%db QQ*)00JnhH#{rsHHKUQTae*gdg delta 152 zcmV~$%MHRX3;K?3M$FUP{L*mc1QpKGE3xGNTR}S2|7ZdQ_WBshp{Vsxr!;mGW znQ@bbo!L8SjjS3F#ua!QXIS#}JJ)^NZpU}I9Pj1&2i>MDVgLXD diff --git a/tests/repository_data/client/test_repository2/metadata/current/timestamp.json b/tests/repository_data/client/test_repository2/metadata/current/timestamp.json index 6c8a58d153c40549a4a0f1792e7f10b6c9f6d04d..9a0daf078be4c53de9d4cce01b73920c0daf1a9e 100644 GIT binary patch delta 234 zcmW-bv28;!3`AkTRi-e0okA2Pk<1F&ARS4Ob`hiq(i&dDfdOyfr7}V$h>&ZpdiUun77j?NS$6RKdw=6(j%wQ28dOJa7-CjOz@j-_Le`tGlBOzT hinPSS1T;x)dpfL~pZ{xnkB{TmX?rmMQJLn;6O delta 234 zcmW-ZyG=wv3`MolMpUtSF~Qg~{?P&*klAAo1c(5Uu4n;Q34h4#7&NLq;qe_ z+wtrD6FNl++W@83C~J6PI`~wZeKB?Rs9i9NHt^Axd9V{=_)Ifdy!w#UoYp9wAxbzH ze9y>hIqd%m5@6ljGqP2M)*Ljl9rFA4`UFcbt%(~kV9hAk;3ZQ^b)qObR&y@%$-QIk hxmsmdYWK$5-D%(X{vX?Gy*+=tY!4?QzWf{>{{VfqLyiCd diff --git a/tests/repository_data/client/test_repository2/metadata/previous/1.root.json b/tests/repository_data/client/test_repository2/metadata/previous/1.root.json index 9cc9d4dc874447f688eda362a42793572953690f..214d8db01b6ce52ef48cefbbe3d59c65a59b59b1 100644 GIT binary patch delta 786 zcmWlXTMb<~3`IXisx%ae!m;BQ9KQmf1TKYgDTN{!MB}UcD;~9bNlM`(vU03_$M+JN6(0F%;RdE(_Oq>*N7*0R#wakyV z;MyvAPgX@A3_T$htpWVlUL~86ic1U%doLBkW#;otE{KrEOsPE)bx0`$4tWSpkf9l~1$Q9f&y0eT=;`ZX3GCb!x@eOJN` z6P?9uKaw*Spl3`9SWkZ6G_{74+T96t-7f!hMT&;k`u5r&`LY*zA&=gjZ#zrX+d@wru! zB!>H9c2G*7;A%D5RaIg~h`~bRg<~V_7o_rZq zoh~I~XD^OGYv4m(O|RprBIX=4ZY6K-J(i#Jv-;-|cbJd?du3zN6g8MXIIf<%#%gIOm;XQAE4@F+KN#A?^1>$|kR-fJ zCC!LT(zAE%vtH6fly;GnH4nmgh?dKmw7r5VLSJA>wFJ{&GuGj@H=BX4d9zj-^xJ$m zZrjHEnF7qA<6$=lJ7$EL&&j*whK#Q799dm_M)Nk>)E*~h8r|%$dvT{A-g1@5gLqb< z99qtOyyR^AJkrxy3Q3LBMOdRqxT81)t4W#+FRU;cdi3tr9J AJOBUy diff --git a/tests/repository_data/client/test_repository2/metadata/previous/root.json b/tests/repository_data/client/test_repository2/metadata/previous/root.json index 9cc9d4dc874447f688eda362a42793572953690f..214d8db01b6ce52ef48cefbbe3d59c65a59b59b1 100644 GIT binary patch delta 786 zcmWlXTMb<~3`IXisx%ae!m;BQ9KQmf1TKYgDTN{!MB}UcD;~9bNlM`(vU03_$M+JN6(0F%;RdE(_Oq>*N7*0R#wakyV z;MyvAPgX@A3_T$htpWVlUL~86ic1U%doLBkW#;otE{KrEOsPE)bx0`$4tWSpkf9l~1$Q9f&y0eT=;`ZX3GCb!x@eOJN` z6P?9uKaw*Spl3`9SWkZ6G_{74+T96t-7f!hMT&;k`u5r&`LY*zA&=gjZ#zrX+d@wru! zB!>H9c2G*7;A%D5RaIg~h`~bRg<~V_7o_rZq zoh~I~XD^OGYv4m(O|RprBIX=4ZY6K-J(i#Jv-;-|cbJd?du3zN6g8MXIIf<%#%gIOm;XQAE4@F+KN#A?^1>$|kR-fJ zCC!LT(zAE%vtH6fly;GnH4nmgh?dKmw7r5VLSJA>wFJ{&GuGj@H=BX4d9zj-^xJ$m zZrjHEnF7qA<6$=lJ7$EL&&j*whK#Q799dm_M)Nk>)E*~h8r|%$dvT{A-g1@5gLqb< z99qtOyyR^AJkrxy3Q3LBMOdRqxT81)t4W#+FRU;cdi3tr9J AJOBUy diff --git a/tests/repository_data/client/test_repository2/metadata/previous/snapshot.json b/tests/repository_data/client/test_repository2/metadata/previous/snapshot.json index af56f045be88d7da8d034628e01bc79c23ac1d54..7c8c091a2ee503c11125d646f88f1cbfdc4b93d9 100644 GIT binary patch delta 143 zcmWN{OA$gb3;@7k<_Svkj}>lhlL){72MoYqgF8Nuf&$p{zK+{*zg)pZ4Yxsd7pe{@ zabc_yL1$8;-IZZ9SI!LHqJunF!_J7I%#BHnR-8Er!V7#ZH7#pFMO)$)Y_l|S4H%db QQ*)00JnhH#{rsHHKUQTae*gdg delta 152 zcmV~$%MHRX3;K?3M$FUP{L*mc1QpKGE3xGNTR}S2|7ZdQ_WBshp{Vsxr!;mGW znQ@bbo!L8SjjS3F#ua!QXIS#}JJ)^NZpU}I9Pj1&2i>MDVgLXD diff --git a/tests/repository_data/client/test_repository2/metadata/previous/timestamp.json b/tests/repository_data/client/test_repository2/metadata/previous/timestamp.json index 6c8a58d153c40549a4a0f1792e7f10b6c9f6d04d..9a0daf078be4c53de9d4cce01b73920c0daf1a9e 100644 GIT binary patch delta 234 zcmW-bv28;!3`AkTRi-e0okA2Pk<1F&ARS4Ob`hiq(i&dDfdOyfr7}V$h>&ZpdiUun77j?NS$6RKdw=6(j%wQ28dOJa7-CjOz@j-_Le`tGlBOzT hinPSS1T;x)dpfL~pZ{xnkB{TmX?rmMQJLn;6O delta 234 zcmW-ZyG=wv3`MolMpUtSF~Qg~{?P&*klAAo1c(5Uu4n;Q34h4#7&NLq;qe_ z+wtrD6FNl++W@83C~J6PI`~wZeKB?Rs9i9NHt^Axd9V{=_)Ifdy!w#UoYp9wAxbzH ze9y>hIqd%m5@6ljGqP2M)*Ljl9rFA4`UFcbt%(~kV9hAk;3ZQ^b)qObR&y@%$-QIk hxmsmdYWK$5-D%(X{vX?Gy*+=tY!4?QzWf{>{{VfqLyiCd diff --git a/tests/repository_data/repository/metadata.staged/1.root.json b/tests/repository_data/repository/metadata.staged/1.root.json index 9cc9d4dc874447f688eda362a42793572953690f..214d8db01b6ce52ef48cefbbe3d59c65a59b59b1 100644 GIT binary patch delta 786 zcmWlXTMb<~3`IXisx%ae!m;BQ9KQmf1TKYgDTN{!MB}UcD;~9bNlM`(vU03_$M+JN6(0F%;RdE(_Oq>*N7*0R#wakyV z;MyvAPgX@A3_T$htpWVlUL~86ic1U%doLBkW#;otE{KrEOsPE)bx0`$4tWSpkf9l~1$Q9f&y0eT=;`ZX3GCb!x@eOJN` z6P?9uKaw*Spl3`9SWkZ6G_{74+T96t-7f!hMT&;k`u5r&`LY*zA&=gjZ#zrX+d@wru! zB!>H9c2G*7;A%D5RaIg~h`~bRg<~V_7o_rZq zoh~I~XD^OGYv4m(O|RprBIX=4ZY6K-J(i#Jv-;-|cbJd?du3zN6g8MXIIf<%#%gIOm;XQAE4@F+KN#A?^1>$|kR-fJ zCC!LT(zAE%vtH6fly;GnH4nmgh?dKmw7r5VLSJA>wFJ{&GuGj@H=BX4d9zj-^xJ$m zZrjHEnF7qA<6$=lJ7$EL&&j*whK#Q799dm_M)Nk>)E*~h8r|%$dvT{A-g1@5gLqb< z99qtOyyR^AJkrxy3Q3LBMOdRqxT81)t4W#+FRU;cdi3tr9J AJOBUy diff --git a/tests/repository_data/repository/metadata.staged/root.json b/tests/repository_data/repository/metadata.staged/root.json index 9cc9d4dc874447f688eda362a42793572953690f..214d8db01b6ce52ef48cefbbe3d59c65a59b59b1 100644 GIT binary patch delta 786 zcmWlXTMb<~3`IXisx%ae!m;BQ9KQmf1TKYgDTN{!MB}UcD;~9bNlM`(vU03_$M+JN6(0F%;RdE(_Oq>*N7*0R#wakyV z;MyvAPgX@A3_T$htpWVlUL~86ic1U%doLBkW#;otE{KrEOsPE)bx0`$4tWSpkf9l~1$Q9f&y0eT=;`ZX3GCb!x@eOJN` z6P?9uKaw*Spl3`9SWkZ6G_{74+T96t-7f!hMT&;k`u5r&`LY*zA&=gjZ#zrX+d@wru! zB!>H9c2G*7;A%D5RaIg~h`~bRg<~V_7o_rZq zoh~I~XD^OGYv4m(O|RprBIX=4ZY6K-J(i#Jv-;-|cbJd?du3zN6g8MXIIf<%#%gIOm;XQAE4@F+KN#A?^1>$|kR-fJ zCC!LT(zAE%vtH6fly;GnH4nmgh?dKmw7r5VLSJA>wFJ{&GuGj@H=BX4d9zj-^xJ$m zZrjHEnF7qA<6$=lJ7$EL&&j*whK#Q799dm_M)Nk>)E*~h8r|%$dvT{A-g1@5gLqb< z99qtOyyR^AJkrxy3Q3LBMOdRqxT81)t4W#+FRU;cdi3tr9J AJOBUy diff --git a/tests/repository_data/repository/metadata.staged/snapshot.json b/tests/repository_data/repository/metadata.staged/snapshot.json index af56f045be88d7da8d034628e01bc79c23ac1d54..7c8c091a2ee503c11125d646f88f1cbfdc4b93d9 100644 GIT binary patch delta 143 zcmWN{OA$gb3;@7k<_Svkj}>lhlL){72MoYqgF8Nuf&$p{zK+{*zg)pZ4Yxsd7pe{@ zabc_yL1$8;-IZZ9SI!LHqJunF!_J7I%#BHnR-8Er!V7#ZH7#pFMO)$)Y_l|S4H%db QQ*)00JnhH#{rsHHKUQTae*gdg delta 152 zcmV~$%MHRX3;K?3M$FUP{L*mc1QpKGE3xGNTR}S2|7ZdQ_WBshp{Vsxr!;mGW znQ@bbo!L8SjjS3F#ua!QXIS#}JJ)^NZpU}I9Pj1&2i>MDVgLXD diff --git a/tests/repository_data/repository/metadata.staged/timestamp.json b/tests/repository_data/repository/metadata.staged/timestamp.json index 6c8a58d153c40549a4a0f1792e7f10b6c9f6d04d..9a0daf078be4c53de9d4cce01b73920c0daf1a9e 100644 GIT binary patch delta 234 zcmW-bv28;!3`AkTRi-e0okA2Pk<1F&ARS4Ob`hiq(i&dDfdOyfr7}V$h>&ZpdiUun77j?NS$6RKdw=6(j%wQ28dOJa7-CjOz@j-_Le`tGlBOzT hinPSS1T;x)dpfL~pZ{xnkB{TmX?rmMQJLn;6O delta 234 zcmW-ZyG=wv3`MolMpUtSF~Qg~{?P&*klAAo1c(5Uu4n;Q34h4#7&NLq;qe_ z+wtrD6FNl++W@83C~J6PI`~wZeKB?Rs9i9NHt^Axd9V{=_)Ifdy!w#UoYp9wAxbzH ze9y>hIqd%m5@6ljGqP2M)*Ljl9rFA4`UFcbt%(~kV9hAk;3ZQ^b)qObR&y@%$-QIk hxmsmdYWK$5-D%(X{vX?Gy*+=tY!4?QzWf{>{{VfqLyiCd diff --git a/tests/repository_data/repository/metadata/1.root.json b/tests/repository_data/repository/metadata/1.root.json index 9cc9d4dc874447f688eda362a42793572953690f..214d8db01b6ce52ef48cefbbe3d59c65a59b59b1 100644 GIT binary patch delta 786 zcmWlXTMb<~3`IXisx%ae!m;BQ9KQmf1TKYgDTN{!MB}UcD;~9bNlM`(vU03_$M+JN6(0F%;RdE(_Oq>*N7*0R#wakyV z;MyvAPgX@A3_T$htpWVlUL~86ic1U%doLBkW#;otE{KrEOsPE)bx0`$4tWSpkf9l~1$Q9f&y0eT=;`ZX3GCb!x@eOJN` z6P?9uKaw*Spl3`9SWkZ6G_{74+T96t-7f!hMT&;k`u5r&`LY*zA&=gjZ#zrX+d@wru! zB!>H9c2G*7;A%D5RaIg~h`~bRg<~V_7o_rZq zoh~I~XD^OGYv4m(O|RprBIX=4ZY6K-J(i#Jv-;-|cbJd?du3zN6g8MXIIf<%#%gIOm;XQAE4@F+KN#A?^1>$|kR-fJ zCC!LT(zAE%vtH6fly;GnH4nmgh?dKmw7r5VLSJA>wFJ{&GuGj@H=BX4d9zj-^xJ$m zZrjHEnF7qA<6$=lJ7$EL&&j*whK#Q799dm_M)Nk>)E*~h8r|%$dvT{A-g1@5gLqb< z99qtOyyR^AJkrxy3Q3LBMOdRqxT81)t4W#+FRU;cdi3tr9J AJOBUy diff --git a/tests/repository_data/repository/metadata/root.json b/tests/repository_data/repository/metadata/root.json index 9cc9d4dc874447f688eda362a42793572953690f..214d8db01b6ce52ef48cefbbe3d59c65a59b59b1 100644 GIT binary patch delta 786 zcmWlXTMb<~3`IXisx%ae!m;BQ9KQmf1TKYgDTN{!MB}UcD;~9bNlM`(vU03_$M+JN6(0F%;RdE(_Oq>*N7*0R#wakyV z;MyvAPgX@A3_T$htpWVlUL~86ic1U%doLBkW#;otE{KrEOsPE)bx0`$4tWSpkf9l~1$Q9f&y0eT=;`ZX3GCb!x@eOJN` z6P?9uKaw*Spl3`9SWkZ6G_{74+T96t-7f!hMT&;k`u5r&`LY*zA&=gjZ#zrX+d@wru! zB!>H9c2G*7;A%D5RaIg~h`~bRg<~V_7o_rZq zoh~I~XD^OGYv4m(O|RprBIX=4ZY6K-J(i#Jv-;-|cbJd?du3zN6g8MXIIf<%#%gIOm;XQAE4@F+KN#A?^1>$|kR-fJ zCC!LT(zAE%vtH6fly;GnH4nmgh?dKmw7r5VLSJA>wFJ{&GuGj@H=BX4d9zj-^xJ$m zZrjHEnF7qA<6$=lJ7$EL&&j*whK#Q799dm_M)Nk>)E*~h8r|%$dvT{A-g1@5gLqb< z99qtOyyR^AJkrxy3Q3LBMOdRqxT81)t4W#+FRU;cdi3tr9J AJOBUy diff --git a/tests/repository_data/repository/metadata/snapshot.json b/tests/repository_data/repository/metadata/snapshot.json index af56f045be88d7da8d034628e01bc79c23ac1d54..7c8c091a2ee503c11125d646f88f1cbfdc4b93d9 100644 GIT binary patch delta 143 zcmWN{OA$gb3;@7k<_Svkj}>lhlL){72MoYqgF8Nuf&$p{zK+{*zg)pZ4Yxsd7pe{@ zabc_yL1$8;-IZZ9SI!LHqJunF!_J7I%#BHnR-8Er!V7#ZH7#pFMO)$)Y_l|S4H%db QQ*)00JnhH#{rsHHKUQTae*gdg delta 152 zcmV~$%MHRX3;K?3M$FUP{L*mc1QpKGE3xGNTR}S2|7ZdQ_WBshp{Vsxr!;mGW znQ@bbo!L8SjjS3F#ua!QXIS#}JJ)^NZpU}I9Pj1&2i>MDVgLXD diff --git a/tests/repository_data/repository/metadata/timestamp.json b/tests/repository_data/repository/metadata/timestamp.json index 6c8a58d153c40549a4a0f1792e7f10b6c9f6d04d..9a0daf078be4c53de9d4cce01b73920c0daf1a9e 100644 GIT binary patch delta 234 zcmW-bv28;!3`AkTRi-e0okA2Pk<1F&ARS4Ob`hiq(i&dDfdOyfr7}V$h>&ZpdiUun77j?NS$6RKdw=6(j%wQ28dOJa7-CjOz@j-_Le`tGlBOzT hinPSS1T;x)dpfL~pZ{xnkB{TmX?rmMQJLn;6O delta 234 zcmW-ZyG=wv3`MolMpUtSF~Qg~{?P&*klAAo1c(5Uu4n;Q34h4#7&NLq;qe_ z+wtrD6FNl++W@83C~J6PI`~wZeKB?Rs9i9NHt^Axd9V{=_)Ifdy!w#UoYp9wAxbzH ze9y>hIqd%m5@6ljGqP2M)*Ljl9rFA4`UFcbt%(~kV9hAk;3ZQ^b)qObR&y@%$-QIk hxmsmdYWK$5-D%(X{vX?Gy*+=tY!4?QzWf{>{{VfqLyiCd From 99ba904cbbcf27eb109f5bfdd2a4951fd80735f8 Mon Sep 17 00:00:00 2001 From: Joshua Lock Date: Wed, 11 Mar 2020 12:55:12 +0000 Subject: [PATCH 8/8] Remove redundant code branch in Updater Remove logic for handling of root metadata in _update_metadata_if_changed() as root metadata is no longer fetched with this function, instead _update_root_metadata() serves this purpose. Additionally remove redundant mention of root metadata in a TODO comment. Signed-off-by: Joshua Lock --- tuf/client/updater.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tuf/client/updater.py b/tuf/client/updater.py index 48397abd..17d2394e 100755 --- a/tuf/client/updater.py +++ b/tuf/client/updater.py @@ -1922,9 +1922,9 @@ def _update_metadata_if_changed(self, metadata_role, self._ensure_not_expired(self.metadata['current'][metadata_role], metadata_role) - # TODO: If 'metadata_role' is root or snapshot, we should verify that - # root's hash matches what's in snapshot, and that snapshot hash matches - # what's listed in timestamp.json. + # TODO: If metadata role is snapshot, we should verify that snapshot's + # hash matches what's listed in timestamp.json per step 3.1 of the + # detailed workflows in the specification return @@ -1937,9 +1937,6 @@ def _update_metadata_if_changed(self, metadata_role, if metadata_role == 'snapshot': upperbound_filelength = tuf.settings.DEFAULT_SNAPSHOT_REQUIRED_LENGTH - elif metadata_role == 'root': - upperbound_filelength = DEFAULT_ROOT_UPPERLENGTH - # The metadata is considered Targets (or delegated Targets metadata). else: upperbound_filelength = tuf.settings.DEFAULT_TARGETS_REQUIRED_LENGTH