-
Notifications
You must be signed in to change notification settings - Fork 270
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
joshuagl
merged 6 commits into
theupdateframework:develop
from
sechkova:delegations-update
Aug 26, 2020
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
8f396a7
Move _keys_to_keydict() to repository_lib
sechkova f7c9fcb
Update delegations in generate_targets_metadata()
sechkova 8f05420
Load delegated roles 'keyids' and 'threshold'
sechkova 05a7008
Update failing tests for generate_targets_metadata
sechkova b3b0c04
Add test for delegations update
sechkova b6307dd
Fix typo in comment section
sechkova File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -166,7 +166,13 @@ def _generate_and_write_metadata(rolename, metadata_filename, | |
metadata = generate_targets_metadata(targets_directory, | ||
roleinfo['paths'], roleinfo['version'], roleinfo['expires'], | ||
roleinfo['delegations'], consistent_targets, use_existing_fileinfo, | ||
storage_backend) | ||
storage_backend, repository_name) | ||
|
||
# Update roledb with the latest delegations info collected during | ||
# generate_targets_metadata() | ||
tuf.roledb.update_roleinfo(rolename, roleinfo, | ||
repository_name=repository_name) | ||
|
||
|
||
# Before writing 'rolename' to disk, automatically increment its version | ||
# number (if 'increment_version_number' is True) so that the caller does not | ||
|
@@ -1227,6 +1233,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 | ||
|
@@ -1238,43 +1245,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: | ||
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. | ||
|
@@ -1285,6 +1260,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. | ||
|
@@ -1307,7 +1285,8 @@ def generate_root_metadata(version, expiration_date, consistent_snapshot, | |
|
||
def generate_targets_metadata(targets_directory, target_files, version, | ||
expiration_date, delegations=None, write_consistent_targets=False, | ||
use_existing_fileinfo=False, storage_backend=None): | ||
use_existing_fileinfo=False, storage_backend=None, | ||
repository_name='default'): | ||
""" | ||
<Purpose> | ||
Generate the targets metadata object. The targets in 'target_files' must | ||
|
@@ -1360,6 +1339,10 @@ def generate_targets_metadata(targets_directory, target_files, version, | |
An object which implements | ||
securesystemslib.storage.StorageBackendInterface. | ||
|
||
repository_name: | ||
The name of the repository. If not supplied, 'default' repository | ||
is used. | ||
|
||
<Exceptions> | ||
securesystemslib.exceptions.FormatError, if an error occurred trying to | ||
generate the targets metadata object. | ||
|
@@ -1404,6 +1387,23 @@ def generate_targets_metadata(targets_directory, target_files, version, | |
|
||
if delegations is not None: | ||
tuf.formats.DELEGATIONS_SCHEMA.check_match(delegations) | ||
# If targets role has delegations, collect the up-to-date 'keyids' and | ||
# 'threshold' for each role. Update the delegations keys dictionary. | ||
delegations_keys = [] | ||
# Update 'keyids' and 'threshold' for each delegated role | ||
for role in delegations['roles']: | ||
role['keyids'] = tuf.roledb.get_role_keyids(role['name'], | ||
repository_name) | ||
role['threshold'] = tuf.roledb.get_role_threshold(role['name'], | ||
repository_name) | ||
|
||
# Collect all delegations keys for generating the delegations keydict | ||
for keyid in role['keyids']: | ||
key = tuf.keydb.get_key(keyid, repository_name=repository_name) | ||
delegations_keys.append(key) | ||
|
||
_, delegations['keys'] = keys_to_keydict(delegations_keys) | ||
|
||
|
||
# Store the file attributes of targets in 'target_files'. 'filedict', | ||
# conformant to 'tuf.formats.FILEDICT_SCHEMA', is added to the | ||
|
@@ -2253,9 +2253,42 @@ 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: | ||
# be tested by running repository_lib.py as a standalone module: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
# $ python repository_lib.py. | ||
import doctest | ||
doctest.testmod() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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, iskeyids
used anywhere other than the iterator here? Why not just keep forkeyid in tuf.roledb....
?There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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!