diff --git a/tests/test_formats.py b/tests/test_formats.py index bb15ee7c..a4390303 100755 --- a/tests/test_formats.py +++ b/tests/test_formats.py @@ -71,9 +71,9 @@ def test_schemas(self): 'SCHEME_SCHEMA': (securesystemslib.formats.SCHEME_SCHEMA, 'rsassa-pss-sha256'), - 'RELPATH_SCHEMA': (securesystemslib.formats.RELPATH_SCHEMA, 'metadata/root/'), + 'RELPATH_SCHEMA': (tuf.formats.RELPATH_SCHEMA, 'metadata/root/'), - 'RELPATHS_SCHEMA': (securesystemslib.formats.RELPATHS_SCHEMA, + 'RELPATHS_SCHEMA': (tuf.formats.RELPATHS_SCHEMA, ['targets/role1/', 'targets/role2/']), 'PATH_SCHEMA': (securesystemslib.formats.PATH_SCHEMA, '/home/someuser/'), @@ -84,16 +84,16 @@ def test_schemas(self): 'URL_SCHEMA': (securesystemslib.formats.URL_SCHEMA, 'https://www.updateframework.com/'), - 'VERSION_SCHEMA': (securesystemslib.formats.VERSION_SCHEMA, + 'VERSION_SCHEMA': (tuf.formats.VERSION_SCHEMA, {'major': 1, 'minor': 0, 'fix': 8}), - 'LENGTH_SCHEMA': (securesystemslib.formats.LENGTH_SCHEMA, 8), + 'LENGTH_SCHEMA': (tuf.formats.LENGTH_SCHEMA, 8), 'NAME_SCHEMA': (securesystemslib.formats.NAME_SCHEMA, 'Marty McFly'), 'BOOLEAN_SCHEMA': (securesystemslib.formats.BOOLEAN_SCHEMA, True), - 'THRESHOLD_SCHEMA': (securesystemslib.formats.THRESHOLD_SCHEMA, 1), + 'THRESHOLD_SCHEMA': (tuf.formats.THRESHOLD_SCHEMA, 1), 'ROLENAME_SCHEMA': (tuf.formats.ROLENAME_SCHEMA, 'Root'), diff --git a/tests/test_repository_lib.py b/tests/test_repository_lib.py index b14346dd..5be7d40e 100755 --- a/tests/test_repository_lib.py +++ b/tests/test_repository_lib.py @@ -417,7 +417,7 @@ def test_get_target_hash(self): '/packages/file2.txt': 'c9c4a5cdd84858dd6a23d98d7e6e6b2aec45034946c16b2200bc317c75415e92' } for filepath, target_hash in six.iteritems(expected_target_hashes): - self.assertTrue(securesystemslib.formats.RELPATH_SCHEMA.matches(filepath)) + self.assertTrue(tuf.formats.RELPATH_SCHEMA.matches(filepath)) self.assertTrue(securesystemslib.formats.HASH_SCHEMA.matches(target_hash)) self.assertEqual(repo_lib.get_target_hash(filepath), target_hash) diff --git a/tests/test_updater.py b/tests/test_updater.py index 6f7f50aa..944623c6 100644 --- a/tests/test_updater.py +++ b/tests/test_updater.py @@ -1556,7 +1556,7 @@ def test_9__get_target_hash(self): '/Jalape\xc3\xb1o': '78bfd5c314680545eb48ecad508aceb861f8d6e680f4fe1b791da45c298cda88' } for filepath, target_hash in six.iteritems(expected_target_hashes): - self.assertTrue(securesystemslib.formats.RELPATH_SCHEMA.matches(filepath)) + self.assertTrue(tuf.formats.RELPATH_SCHEMA.matches(filepath)) self.assertTrue(securesystemslib.formats.HASH_SCHEMA.matches(target_hash)) self.assertEqual(self.repository_updater._get_target_hash(filepath), target_hash) diff --git a/tuf/client/updater.py b/tuf/client/updater.py index e53faee8..1be42ee7 100755 --- a/tuf/client/updater.py +++ b/tuf/client/updater.py @@ -2627,7 +2627,7 @@ def targets_of_role(self, rolename='targets'): # Does 'rolename' have the correct format? # Raise 'securesystemslib.exceptions.FormatError' if there is a mismatch. - securesystemslib.formats.RELPATH_SCHEMA.check_match(rolename) + tuf.formats.RELPATH_SCHEMA.check_match(rolename) # If we've been given a delegated targets role, we don't know how to # validate it without knowing what the delegating role is -- there could @@ -2690,7 +2690,7 @@ def get_one_valid_targetinfo(self, target_filepath): # Does 'target_filepath' have the correct format? # Raise 'securesystemslib.exceptions.FormatError' if there is a mismatch. - securesystemslib.formats.RELPATH_SCHEMA.check_match(target_filepath) + tuf.formats.RELPATH_SCHEMA.check_match(target_filepath) target_filepath = target_filepath.replace('\\', '/') diff --git a/tuf/developer_tool.py b/tuf/developer_tool.py index 65c3c40b..78197ec6 100755 --- a/tuf/developer_tool.py +++ b/tuf/developer_tool.py @@ -694,7 +694,7 @@ def _save_project_configuration(metadata_directory, targets_directory, securesystemslib.formats.PATH_SCHEMA.check_match(metadata_directory) securesystemslib.formats.PATH_SCHEMA.check_match(prefix) securesystemslib.formats.PATH_SCHEMA.check_match(targets_directory) - securesystemslib.formats.RELPATH_SCHEMA.check_match(project_name) + tuf.formats.RELPATH_SCHEMA.check_match(project_name) cfg_file_directory = metadata_directory diff --git a/tuf/download.py b/tuf/download.py index 687e8573..cf7aac06 100755 --- a/tuf/download.py +++ b/tuf/download.py @@ -110,7 +110,7 @@ def safe_download(url, required_length): # Do all of the arguments have the appropriate format? # Raise 'securesystemslib.exceptions.FormatError' if there is a mismatch. securesystemslib.formats.URL_SCHEMA.check_match(url) - securesystemslib.formats.LENGTH_SCHEMA.check_match(required_length) + tuf.formats.LENGTH_SCHEMA.check_match(required_length) return _download_file(url, required_length, STRICT_REQUIRED_LENGTH=True) @@ -161,7 +161,7 @@ def unsafe_download(url, required_length): # Do all of the arguments have the appropriate format? # Raise 'securesystemslib.exceptions.FormatError' if there is a mismatch. securesystemslib.formats.URL_SCHEMA.check_match(url) - securesystemslib.formats.LENGTH_SCHEMA.check_match(required_length) + tuf.formats.LENGTH_SCHEMA.check_match(required_length) return _download_file(url, required_length, STRICT_REQUIRED_LENGTH=False) @@ -216,7 +216,7 @@ def _download_file(url, required_length, STRICT_REQUIRED_LENGTH=True): # Do all of the arguments have the appropriate format? # Raise 'securesystemslib.exceptions.FormatError' if there is a mismatch. securesystemslib.formats.URL_SCHEMA.check_match(url) - securesystemslib.formats.LENGTH_SCHEMA.check_match(required_length) + tuf.formats.LENGTH_SCHEMA.check_match(required_length) # 'url.replace('\\', '/')' is needed for compatibility with Windows-based # systems, because they might use back-slashes in place of forward-slashes. diff --git a/tuf/formats.py b/tuf/formats.py index bcca7ee0..b3e71198 100755 --- a/tuf/formats.py +++ b/tuf/formats.py @@ -95,33 +95,43 @@ # Must be 1, or greater. METADATAVERSION_SCHEMA = SCHEMA.Integer(lo=0) +# A relative file path (e.g., 'metadata/root/'). +RELPATH_SCHEMA = SCHEMA.AnyString() +RELPATHS_SCHEMA = SCHEMA.ListOf(RELPATH_SCHEMA) + VERSIONINFO_SCHEMA = SCHEMA.Object( object_name = 'VERSIONINFO_SCHEMA', version = METADATAVERSION_SCHEMA) -# A dict holding the version or file information for a particular metadata -# role. The dict keys hold the relative file paths, and the dict values the -# corresponding version numbers and/or file information. -FILEINFODICT_SCHEMA = SCHEMA.DictOf( - key_schema = securesystemslib.formats.RELPATH_SCHEMA, - value_schema = SCHEMA.OneOf([VERSIONINFO_SCHEMA, - securesystemslib.formats.FILEINFO_SCHEMA])) - # A string representing a role's name. ROLENAME_SCHEMA = SCHEMA.AnyString() +# A role's threshold value (i.e., the minimum number +# of signatures required to sign a metadata file). +# Must be 1 and greater. +THRESHOLD_SCHEMA = SCHEMA.Integer(lo=1) + +# A hexadecimal value in '23432df87ab..' format. +HEX_SCHEMA = SCHEMA.RegularExpression(r'[a-fA-F0-9]+') + +# A path hash prefix is a hexadecimal string. +PATH_HASH_PREFIX_SCHEMA = HEX_SCHEMA + +# A list of path hash prefixes. +PATH_HASH_PREFIXES_SCHEMA = SCHEMA.ListOf(PATH_HASH_PREFIX_SCHEMA) + # Role object in {'keyids': [keydids..], 'name': 'ABC', 'threshold': 1, # 'paths':[filepaths..]} format. # TODO: This is not a role. In further #660-related PRs, fix it, similar to # the way I did in Uptane's TUF fork. ROLE_SCHEMA = SCHEMA.Object( object_name = 'ROLE_SCHEMA', - name = SCHEMA.Optional(securesystemslib.formats.ROLENAME_SCHEMA), + name = SCHEMA.Optional(ROLENAME_SCHEMA), keyids = securesystemslib.formats.KEYIDS_SCHEMA, - threshold = securesystemslib.formats.THRESHOLD_SCHEMA, + threshold = THRESHOLD_SCHEMA, terminating = SCHEMA.Optional(securesystemslib.formats.BOOLEAN_SCHEMA), - paths = SCHEMA.Optional(securesystemslib.formats.RELPATHS_SCHEMA), - path_hash_prefixes = SCHEMA.Optional(securesystemslib.formats.PATH_HASH_PREFIXES_SCHEMA)) + paths = SCHEMA.Optional(RELPATHS_SCHEMA), + path_hash_prefixes = SCHEMA.Optional(PATH_HASH_PREFIXES_SCHEMA)) # A dict of roles where the dict keys are role names and the dict values holding # the role data/information. @@ -156,17 +166,9 @@ # A string representing a role's name. ROLENAME_SCHEMA = SCHEMA.AnyString() -# A role's threshold value (i.e., the minimum number -# of signatures required to sign a metadata file). -# Must be 1 and greater. -THRESHOLD_SCHEMA = SCHEMA.Integer(lo=1) - # A hexadecimal value in '23432df87ab..' format. HASH_SCHEMA = SCHEMA.RegularExpression(r'[a-fA-F0-9]+') -# A hexadecimal value in '23432df87ab..' format. -HEX_SCHEMA = SCHEMA.RegularExpression(r'[a-fA-F0-9]+') - # A key identifier (e.g., a hexadecimal value identifying an RSA key). KEYID_SCHEMA = HASH_SCHEMA @@ -214,17 +216,6 @@ unknown_sigs = KEYIDS_SCHEMA, untrusted_sigs = KEYIDS_SCHEMA) - -# A relative file path (e.g., 'metadata/root/'). -RELPATH_SCHEMA = SCHEMA.AnyString() -RELPATHS_SCHEMA = SCHEMA.ListOf(RELPATH_SCHEMA) - -# A path hash prefix is a hexadecimal string. -PATH_HASH_PREFIX_SCHEMA = HEX_SCHEMA - -# A list of path hash prefixes. -PATH_HASH_PREFIXES_SCHEMA = SCHEMA.ListOf(PATH_HASH_PREFIX_SCHEMA) - # Role object in {'keyids': [keydids..], 'name': 'ABC', 'threshold': 1, # 'paths':[filepaths..]} format. ROLE_SCHEMA = SCHEMA.Object( @@ -260,6 +251,14 @@ version = SCHEMA.Optional(METADATAVERSION_SCHEMA), custom = SCHEMA.Optional(SCHEMA.Object())) +# A dict holding the version or file information for a particular metadata +# role. The dict keys hold the relative file paths, and the dict values the +# corresponding version numbers and/or file information. +FILEINFODICT_SCHEMA = SCHEMA.DictOf( + key_schema = RELPATH_SCHEMA, + value_schema = SCHEMA.OneOf([VERSIONINFO_SCHEMA, + FILEINFO_SCHEMA])) + # A dict holding the information for a particular target / file. The dict keys # hold the relative file paths, and the dict values the corresponding file # information. @@ -369,7 +368,7 @@ SNAPSHOT_SCHEMA = SCHEMA.Object( object_name = 'SNAPSHOT_SCHEMA', _type = SCHEMA.String('snapshot'), - version = securesystemslib.formats.METADATAVERSION_SCHEMA, + version = METADATAVERSION_SCHEMA, expires = securesystemslib.formats.ISO8601_DATETIME_SCHEMA, spec_version = SPECIFICATION_VERSION_SCHEMA, meta = FILEINFODICT_SCHEMA) @@ -379,9 +378,9 @@ object_name = 'TIMESTAMP_SCHEMA', _type = SCHEMA.String('timestamp'), spec_version = SPECIFICATION_VERSION_SCHEMA, - version = securesystemslib.formats.METADATAVERSION_SCHEMA, + version = METADATAVERSION_SCHEMA, expires = securesystemslib.formats.ISO8601_DATETIME_SCHEMA, - meta = securesystemslib.formats.FILEDICT_SCHEMA) + meta = FILEDICT_SCHEMA) # project.cfg file: stores information about the project in a json dictionary @@ -401,9 +400,9 @@ MIRROR_SCHEMA = SCHEMA.Object( object_name = 'MIRROR_SCHEMA', url_prefix = securesystemslib.formats.URL_SCHEMA, - metadata_path = securesystemslib.formats.RELPATH_SCHEMA, - targets_path = securesystemslib.formats.RELPATH_SCHEMA, - confined_target_dirs = securesystemslib.formats.RELPATHS_SCHEMA, + metadata_path = RELPATH_SCHEMA, + targets_path = RELPATH_SCHEMA, + confined_target_dirs = RELPATHS_SCHEMA, custom = SCHEMA.Optional(SCHEMA.Object())) # A dictionary of mirrors where the dict keys hold the mirror's name and @@ -807,7 +806,7 @@ def make_fileinfo(length, hashes, version=None, custom=None): fileinfo['custom'] = custom # Raise 'securesystemslib.exceptions.FormatError' if the check fails. - securesystemslib.formats.FILEINFO_SCHEMA.check_match(fileinfo) + FILEINFO_SCHEMA.check_match(fileinfo) return fileinfo diff --git a/tuf/mirrors.py b/tuf/mirrors.py index 1b1083b8..6aa5ed27 100755 --- a/tuf/mirrors.py +++ b/tuf/mirrors.py @@ -84,7 +84,7 @@ def get_list_of_mirrors(file_type, file_path, mirrors_dict): """ # Checking if all the arguments have appropriate format. - securesystemslib.formats.RELPATH_SCHEMA.check_match(file_path) + tuf.formats.RELPATH_SCHEMA.check_match(file_path) tuf.formats.MIRRORDICT_SCHEMA.check_match(mirrors_dict) securesystemslib.formats.NAME_SCHEMA.check_match(file_type) diff --git a/tuf/repository_lib.py b/tuf/repository_lib.py index c8bd983c..22f12de7 100755 --- a/tuf/repository_lib.py +++ b/tuf/repository_lib.py @@ -1203,7 +1203,7 @@ def get_target_hash(target_filepath): The hash of 'target_filepath'. """ - securesystemslib.formats.RELPATH_SCHEMA.check_match(target_filepath) + tuf.formats.RELPATH_SCHEMA.check_match(target_filepath) # Calculate the hash of the filepath to determine which bin to find the # target. The client currently assumes the repository uses @@ -1416,7 +1416,7 @@ def generate_targets_metadata(targets_directory, target_files, version, # types, and that all dict keys are properly named. # Raise 'securesystemslib.exceptions.FormatError' if there is a mismatch. securesystemslib.formats.PATH_SCHEMA.check_match(targets_directory) - securesystemslib.formats.PATH_FILEINFO_SCHEMA.check_match(target_files) + tuf.formats.PATH_FILEINFO_SCHEMA.check_match(target_files) tuf.formats.METADATAVERSION_SCHEMA.check_match(version) securesystemslib.formats.ISO8601_DATETIME_SCHEMA.check_match(expiration_date) securesystemslib.formats.BOOLEAN_SCHEMA.check_match(write_consistent_targets) diff --git a/tuf/repository_tool.py b/tuf/repository_tool.py index 0d864c80..a461ab0a 100755 --- a/tuf/repository_tool.py +++ b/tuf/repository_tool.py @@ -1049,7 +1049,7 @@ def version(self): """ A getter method that returns the role's version number, conformant to - 'securesystemslib.formats.VERSION_SCHEMA'. + 'tuf.formats.VERSION_SCHEMA'. None. @@ -1062,7 +1062,7 @@ def version(self): The role's version number, conformant to - 'securesystemslib.formats.VERSION_SCHEMA'. + 'tuf.formats.VERSION_SCHEMA'. """ roleinfo = tuf.roledb.get_roleinfo(self.rolename, self._repository_name) @@ -1094,7 +1094,7 @@ def version(self, version): version: The role's version number, conformant to - 'securesystemslib.formats.VERSION_SCHEMA'. + 'tuf.formats.VERSION_SCHEMA'. securesystemslib.exceptions.FormatError, if the 'version' argument is @@ -1140,7 +1140,7 @@ def threshold(self): The role's threshold value, conformant to - 'securesystemslib.formats.THRESHOLD_SCHEMA'. + 'tuf.formats.THRESHOLD_SCHEMA'. """ roleinfo = tuf.roledb.get_roleinfo(self._rolename, self._repository_name) @@ -1166,7 +1166,7 @@ def threshold(self, threshold): threshold: An integer value that sets the role's threshold value, or the minimum number of signatures needed for metadata to be considered fully - signed. Conformant to 'securesystemslib.formats.THRESHOLD_SCHEMA'. + signed. Conformant to 'tuf.formats.THRESHOLD_SCHEMA'. securesystemslib.exceptions.FormatError, if the 'threshold' argument is @@ -1184,7 +1184,7 @@ def threshold(self, threshold): # Ensure the arguments have the appropriate number of objects and object # types, and that all dict keys are properly named. Raise # 'securesystemslib.exceptions.FormatError' if any are improperly formatted. - securesystemslib.formats.THRESHOLD_SCHEMA.check_match(threshold) + tuf.formats.THRESHOLD_SCHEMA.check_match(threshold) roleinfo = tuf.roledb.get_roleinfo(self._rolename, self._repository_name) roleinfo['previous_threshold'] = roleinfo['threshold'] @@ -1983,7 +1983,7 @@ def add_targets(self, list_of_targets): # Ensure the arguments have the appropriate number of objects and object # types, and that all dict keys are properly named. # Raise 'securesystemslib.exceptions.FormatError' if there is a mismatch. - securesystemslib.formats.RELPATHS_SCHEMA.check_match(list_of_targets) + tuf.formats.RELPATHS_SCHEMA.check_match(list_of_targets) # Update the tuf.roledb entry. targets_directory_length = len(self._targets_directory) @@ -2054,7 +2054,7 @@ def remove_target(self, filepath): # Ensure the arguments have the appropriate number of objects and object # types, and that all dict keys are properly named. Raise # 'securesystemslib.exceptions.FormatError' if there is a mismatch. - securesystemslib.formats.RELPATH_SCHEMA.check_match(filepath) + tuf.formats.RELPATH_SCHEMA.check_match(filepath) # Remove 'relative_filepath', if found, and update this Targets roleinfo. fileinfo = tuf.roledb.get_roleinfo(self.rolename, self._repository_name) @@ -2211,15 +2211,15 @@ def delegate(self, rolename, public_keys, paths, threshold=1, # Raise 'securesystemslib.exceptions.FormatError' if there is a mismatch. tuf.formats.ROLENAME_SCHEMA.check_match(rolename) securesystemslib.formats.ANYKEYLIST_SCHEMA.check_match(public_keys) - securesystemslib.formats.RELPATHS_SCHEMA.check_match(paths) - securesystemslib.formats.THRESHOLD_SCHEMA.check_match(threshold) + tuf.formats.RELPATHS_SCHEMA.check_match(paths) + tuf.formats.THRESHOLD_SCHEMA.check_match(threshold) securesystemslib.formats.BOOLEAN_SCHEMA.check_match(terminating) if list_of_targets is not None: - securesystemslib.formats.RELPATHS_SCHEMA.check_match(list_of_targets) + tuf.formats.RELPATHS_SCHEMA.check_match(list_of_targets) if path_hash_prefixes is not None: - securesystemslib.formats.PATH_HASH_PREFIXES_SCHEMA.check_match(path_hash_prefixes) + tuf.formats.PATH_HASH_PREFIXES_SCHEMA.check_match(path_hash_prefixes) # Keep track of the valid keyids (added to the new Targets object) and # their keydicts (added to this Targets delegations). diff --git a/tuf/sig.py b/tuf/sig.py index 841990ab..5a38a9ce 100755 --- a/tuf/sig.py +++ b/tuf/sig.py @@ -126,7 +126,7 @@ def get_signature_status(signable, role=None, repository_name='default', tuf.formats.ROLENAME_SCHEMA.check_match(role) if threshold is not None: - securesystemslib.formats.THRESHOLD_SCHEMA.check_match(threshold) + tuf.formats.THRESHOLD_SCHEMA.check_match(threshold) if keyids is not None: securesystemslib.formats.KEYIDS_SCHEMA.check_match(keyids)