From 43db37c2abc25cbe3fd70fb42996b4ca72abf196 Mon Sep 17 00:00:00 2001 From: dachshund Date: Wed, 7 Aug 2013 02:42:06 -0400 Subject: [PATCH] Improved checking of the "paths" and "path_hash_prefix" attributes. Removed checking whether "path_hash_prefix" is consistent with the delegated paths in the delegator, because now the delegated paths may list directories instead of simply files. --- docs/tuf-spec.txt | 9 +++------ tuf/formats.py | 15 ++++++++++----- tuf/repo/signercli.py | 38 ++++++++++++++++++-------------------- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/docs/tuf-spec.txt b/docs/tuf-spec.txt index c6071a89..06c83001 100644 --- a/docs/tuf-spec.txt +++ b/docs/tuf-spec.txt @@ -565,15 +565,12 @@ "name": ROLE, "keyids" : [ KEYID, ... ] , "threshold" : THRESHOLD, - "paths" : [ PATHPATTERN, ... ], - "path_hash_prefix" : HEX_STRING + ("paths" : [ PATHPATTERN, ... ] | "path_hash_prefix" : HEX_DIGEST) }, ... ] } - In order to discuss target paths, a role must specify either one of the - "paths" or "path_hash_prefix" attribute, each of which we discuss next. In - case the client specifies both attributes, "path_hash_prefix" is to be read - from or written to while "paths" should be ignored. + In order to discuss target paths, a role MUST specify only one of the + "paths" or "path_hash_prefix" attributes, each of which we discuss next. The "paths" list describes paths that the role is trusted to provide. Clients MUST check that a target is in one of the trusted paths of all roles diff --git a/tuf/formats.py b/tuf/formats.py index 43487f42..66426794 100755 --- a/tuf/formats.py +++ b/tuf/formats.py @@ -875,12 +875,17 @@ def make_role_metadata(keyids, threshold, name=None, paths=None, role_meta['name'] = name # According to the specification, the 'paths' and 'path_hash_prefix' must be - # mutually exclusive. In case both are specified, 'paths' is ignored while - # 'path_hash_prefix' is recorded. - if path_hash_prefix is not None: - role_meta['path_hash_prefix'] = path_hash_prefix - elif paths is not None: + # mutually exclusive. However, at the time of writing we do not always ensure + # that this is the case with the schema checks (see #83). Therefore, we must + # do it for ourselves. + + if paths is not None and path_hash_prefix is not None: + raise tuf.FormatError('Both "paths" and "path_hash_prefix" are specified!') + + if paths is not None: role_meta['paths'] = paths + elif path_hash_prefix is not None: + role_meta['path_hash_prefix'] = path_hash_prefix # Does 'role_meta' have the correct type? # This check ensures 'role_meta' conforms to diff --git a/tuf/repo/signercli.py b/tuf/repo/signercli.py index 3b598477..60c0f778 100755 --- a/tuf/repo/signercli.py +++ b/tuf/repo/signercli.py @@ -1146,7 +1146,8 @@ def make_delegation(keystore_directory): # Update the parent role's metadata file. The parent role's delegation # field must be updated with the newly created delegated role. _update_parent_metadata(metadata_directory, delegated_role, delegated_keyids, - delegated_paths, parent_role, parent_keyids) + parent_role, parent_keyids, + delegated_paths=delegated_paths) @@ -1337,39 +1338,36 @@ def _make_delegated_metadata(metadata_directory, delegated_targets, def _update_parent_metadata(metadata_directory, delegated_role, - delegated_keyids, delegated_paths, parent_role, - parent_keyids, path_hash_prefix=None): + delegated_keyids, parent_role, + parent_keyids, delegated_paths=None, + path_hash_prefix=None): """ Update the parent role's metadata file. The delegations field of the metadata file is updated with the key and role information belonging to the newly added delegated role. Finally, the metadata file is signed and written to the metadata directory. - If the optional 'path_hash_prefix' is specified with the required - 'delegated_paths', then 'path_hash_prefix' is checked to be consistent with - 'delegated_paths', and then 'path_hash_prefix', instead of - 'delegated_paths', is written to the parent role metadata file. Otherwise, - 'delegated_paths' is written to the parent role metadata file in - the absense of 'path_hash_prefix'. - """ + # According to the specification, the 'paths' and 'path_hash_prefix' must be + # mutually exclusive. However, at the time of writing we do not always ensure + # that this is the case with the schema checks (see #83). Therefore, we must + # do it for ourselves. + + if delegated_paths is not None and path_hash_prefix is not None: + raise tuf.RepositoryError('Both "paths" and "path_hash_prefix" are ' \ + 'specified!') + + if delegated_paths is None and path_hash_prefix is None: + raise tuf.RepositoryError('Neither "paths" nor`"path_hash_prefix" is ' \ + 'specified!') + # The 'delegated_paths' are relative to 'repository'. # The 'relative_paths' are relative to 'repository/targets'. relative_paths = [] for path in delegated_paths: relative_paths.append(os.path.sep.join(path.split(os.path.sep)[1:])) - if path_hash_prefix: - # Ensure that 'delegated_paths' is consistent with 'path_hash_prefix'. - if not tuf.repo.signerlib.paths_are_consistent_with_hash_prefix( - relative_paths, path_hash_prefix): - raise tuf.RepositoryError('path_hash_prefix '+str(path_hash_prefix)+ - ' is inconsistent with paths: '+ - str(delegated_paths)) - else: - logger.debug('"path_hash_prefix" is unspecified; reading "paths" instead.') - # Extract the metadata from the parent role's file. parent_filename = os.path.join(metadata_directory, parent_role) parent_filename = parent_filename+'.txt'