Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update targets delegations in generate_targets_metadata #1074

Merged
merged 6 commits into from Aug 26, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
77 changes: 41 additions & 36 deletions tuf/repository_lib.py
Expand Up @@ -1227,6 +1227,7 @@ def generate_root_metadata(version, expiration_date, consistent_snapshot,
# Conformant to 'ROLEDICT_SCHEMA' and 'KEYDICT_SCHEMA', respectively.
roledict = {}
keydict = {}
keylist = []

# Extract the role, threshold, and keyid information of the top-level roles,
# which Root stores in its metadata. The necessary role metadata is generated
Expand All @@ -1238,43 +1239,11 @@ def generate_root_metadata(version, expiration_date, consistent_snapshot,
raise securesystemslib.exceptions.Error(repr(rolename) + ' not in'
' "tuf.roledb".')

# Keep track of the keys loaded to avoid duplicates.
keyids = []

# Generate keys for the keyids listed by the role being processed.
for keyid in tuf.roledb.get_role_keyids(rolename, repository_name):
# Collect keys from all roles in a list
keyids = tuf.roledb.get_role_keyids(rolename, repository_name)
for keyid in keyids:
Comment on lines -1245 to +1250
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: this change to assigning the return value of roledb.get_role_keyids seems superfluous, is keyids used anywhere other than the iterator here? Why not just keep for keyid in tuf.roledb....?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is used in https://github.com/theupdateframework/tuf/pull/1074/files#diff-9f585d5478a17bd9e0f6cd5f7484ab60L1284

It replaces the keyids list that was used to avoid duplicates which we already decided not necessary somewhere in the discussion above.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, yes I see. Thanks!

key = tuf.keydb.get_key(keyid, repository_name=repository_name)

# If 'key' is an RSA key, it would conform to
# 'securesystemslib.formats.RSAKEY_SCHEMA', and have the form:
# {'keytype': 'rsa',
# 'keyid': keyid,
# 'keyval': {'public': '-----BEGIN RSA PUBLIC KEY----- ...',
# 'private': '-----BEGIN RSA PRIVATE KEY----- ...'}}
keyid = key['keyid']
if keyid not in keydict:

# This appears to be a new keyid. Generate the key for it.
if key['keytype'] in ['rsa', 'ed25519', 'ecdsa-sha2-nistp256']:
keytype = key['keytype']
keyval = key['keyval']
scheme = key['scheme']
keydict[keyid] = \
securesystemslib.keys.format_keyval_to_metadata(keytype,
scheme, keyval, private=False)

# This is not a recognized key. Raise an exception.
else:
raise securesystemslib.exceptions.Error('Unsupported keytype:'
' ' + key['keytype'])

# Do we have a duplicate?
if keyid in keyids:
raise securesystemslib.exceptions.Error('Same keyid listed twice:'
' ' + keyid)

# Add the loaded keyid for the role being processed.
keyids.append(keyid)
keylist.append(key)

# Generate the authentication information Root establishes for each
# top-level role.
Expand All @@ -1285,6 +1254,9 @@ def generate_root_metadata(version, expiration_date, consistent_snapshot,
threshold=role_threshold)
roledict[rolename] = role_metadata

# Create the root metadata 'keys' dictionary
_, keydict = keys_to_keydict(keylist)

# Use generalized build_dict_conforming_to_schema func to produce a dict that
# contains all the appropriate information for this type of metadata,
# checking that the result conforms to the appropriate schema.
Expand Down Expand Up @@ -2253,6 +2225,39 @@ def disable_console_log_messages():



def keys_to_keydict(keys):
"""
<Purpose>
Iterate over a list of keys and return a list of keyids and a dict mapping
keyid to key metadata

<Arguments>
keys:
A list of key objects conforming to
securesystemslib.formats.ANYKEYLIST_SCHEMA.

<Returns>
keyids:
A list of keyids conforming to securesystemslib.formats.KEYID_SCHEMA
keydict:
A dictionary conforming to securesystemslib.formats.KEYDICT_SCHEMA
"""
keyids = []
keydict = {}

for key in keys:
keyid = key['keyid']
key_metadata_format = securesystemslib.keys.format_keyval_to_metadata(
key['keytype'], key['scheme'], key['keyval'])

new_keydict = {keyid: key_metadata_format}
keydict.update(new_keydict)
keyids.append(keyid)
return keyids, keydict




if __name__ == '__main__':
# The interactive sessions of the documentation strings can
# be tested by running repository_tool.py as a standalone module:
Expand Down
28 changes: 2 additions & 26 deletions tuf/repository_tool.py
Expand Up @@ -2377,7 +2377,7 @@ def delegate(self, rolename, public_keys, paths, threshold=1,

# Keep track of the valid keyids (added to the new Targets object) and
# their keydicts (added to this Targets delegations).
keyids, keydict = _keys_to_keydict(public_keys)
keyids, keydict = repo_lib.keys_to_keydict(public_keys)

# Ensure the paths of 'list_of_targets' are located in the repository's
# targets directory.
Expand Down Expand Up @@ -2612,7 +2612,7 @@ def delegate_hashed_bins(self, list_of_targets, keys_of_hashed_bins,
hash_prefix = repo_lib.get_target_hash(target_path)[:prefix_length]
ordered_roles[int(hash_prefix, 16) // bin_size]["target_paths"].append(target_path)

keyids, keydict = _keys_to_keydict(keys_of_hashed_bins)
keyids, keydict = repo_lib.keys_to_keydict(keys_of_hashed_bins)

# A queue of roleinfo's that need to be updated in the roledb
delegated_roleinfos = []
Expand Down Expand Up @@ -2857,30 +2857,6 @@ def _check_path(self, pathname):




def _keys_to_keydict(keys):
"""
Iterate over a list of keys and return a list of keyids and a dict mapping
keyid to key metadata
"""
keyids = []
keydict = {}

for key in keys:
keyid = key['keyid']
key_metadata_format = securesystemslib.keys.format_keyval_to_metadata(
key['keytype'], key['scheme'], key['keyval'])

new_keydict = {keyid: key_metadata_format}
keydict.update(new_keydict)
keyids.append(keyid)

return keyids, keydict





def create_new_repository(repository_directory, repository_name='default',
storage_backend=None, use_timestamp_length=True, use_timestamp_hashes=True,
use_snapshot_length=False, use_snapshot_hashes=False):
Expand Down