diff --git a/tests/test_keydb.py b/tests/test_keydb.py index b63a3eb5..d9ef148d 100755 --- a/tests/test_keydb.py +++ b/tests/test_keydb.py @@ -365,6 +365,7 @@ def test_create_keydb_from_root_metadata(self): tuf.keydb.clear_keydb() # 'keyid' does not match 'rsakey2'. + # In this case, the key will be added to the keydb keydict[keyid] = rsakey2 # Key with invalid keytype. @@ -372,6 +373,7 @@ def test_create_keydb_from_root_metadata(self): keyid3 = KEYS[2]['keyid'] rsakey3['keytype'] = 'bad_keytype' keydict[keyid3] = rsakey3 + version = 8 expires = '1985-10-21T01:21:00Z' @@ -387,12 +389,20 @@ def test_create_keydb_from_root_metadata(self): self.assertEqual(None, tuf.keydb.create_keydb_from_root_metadata(root_metadata)) - # Ensure only 'keyid2' was added to the keydb database. 'keyid' and + # Ensure only 'keyid2' and 'keyid' were added to the keydb database. # 'keyid3' should not be stored. + self.maxDiff = None self.assertEqual(rsakey2, tuf.keydb.get_key(keyid2)) - self.assertRaises(tuf.exceptions.UnknownKeyError, tuf.keydb.get_key, keyid) + + test_key = rsakey2 + test_key['keyid'] = keyid + self.assertEqual(test_key, tuf.keydb.get_key(keyid)) + self.assertRaises(tuf.exceptions.UnknownKeyError, tuf.keydb.get_key, keyid3) + + # reset values rsakey3['keytype'] = 'rsa' + rsakey2['keyid'] = keyid2 diff --git a/tests/test_updater.py b/tests/test_updater.py index 068c2982..3cf47ac5 100644 --- a/tests/test_updater.py +++ b/tests/test_updater.py @@ -352,7 +352,7 @@ def test_1__rebuild_key_and_role_db(self): # 'targets.json' are also loaded when the repository object is # instantiated. - self.assertEqual(number_of_root_keys * 2 + 2, len(tuf.keydb._keydb_dict[self.repository_name])) + self.assertEqual(number_of_root_keys + 1, len(tuf.keydb._keydb_dict[self.repository_name])) # Test: normal case. self.repository_updater._rebuild_key_and_role_db() @@ -363,7 +363,7 @@ def test_1__rebuild_key_and_role_db(self): # _rebuild_key_and_role_db() will only rebuild the keys and roles specified # in the 'root.json' file, unlike __init__(). Instantiating an updater # object calls both _rebuild_key_and_role_db() and _import_delegations(). - self.assertEqual(number_of_root_keys * 2, len(tuf.keydb._keydb_dict[self.repository_name])) + self.assertEqual(number_of_root_keys, len(tuf.keydb._keydb_dict[self.repository_name])) # Test: properly updated roledb and keydb dicts if the Root role changes. root_metadata = self.repository_updater.metadata['current']['root'] @@ -374,7 +374,7 @@ def test_1__rebuild_key_and_role_db(self): root_roleinfo = tuf.roledb.get_roleinfo('root', self.repository_name) self.assertEqual(root_roleinfo['threshold'], 8) - self.assertEqual(number_of_root_keys * 2 - 2, len(tuf.keydb._keydb_dict[self.repository_name])) + self.assertEqual(number_of_root_keys - 1, len(tuf.keydb._keydb_dict[self.repository_name])) @@ -560,7 +560,7 @@ def test_2__import_delegations(self): # Take into account the number of keyids algorithms supported by default, # which this test condition expects to be two (sha256 and sha512). - self.assertEqual(4 * 2, len(tuf.keydb._keydb_dict[repository_name])) + self.assertEqual(4, len(tuf.keydb._keydb_dict[repository_name])) # Test: pass a role without delegations. self.repository_updater._import_delegations('root') @@ -569,8 +569,8 @@ def test_2__import_delegations(self): # checking the number of elements in the dictionaries. self.assertEqual(len(tuf.roledb._roledb_dict[repository_name]), 4) # Take into account the number of keyid hash algorithms, which this - # test condition expects to be two (for sha256 and sha512). - self.assertEqual(len(tuf.keydb._keydb_dict[repository_name]), 4 * 2) + # test condition expects to be one + self.assertEqual(len(tuf.keydb._keydb_dict[repository_name]), 4) # Test: normal case, first level delegation. self.repository_updater._import_delegations('targets') @@ -578,7 +578,7 @@ def test_2__import_delegations(self): self.assertEqual(len(tuf.roledb._roledb_dict[repository_name]), 5) # The number of root keys (times the number of key hash algorithms) + # delegation's key (+1 for its sha512 keyid). - self.assertEqual(len(tuf.keydb._keydb_dict[repository_name]), 4 * 2 + 2) + self.assertEqual(len(tuf.keydb._keydb_dict[repository_name]), 4 + 1) # Verify that roledb dictionary was added. self.assertTrue('role1' in tuf.roledb._roledb_dict[repository_name]) diff --git a/tuf/client/updater.py b/tuf/client/updater.py index dd292c26..19d518e6 100755 --- a/tuf/client/updater.py +++ b/tuf/client/updater.py @@ -952,18 +952,9 @@ def _import_delegations(self, parent_role): # We specify the keyid to ensure that it's the correct keyid # for the key. try: + key, _ = securesystemslib.keys.format_metadata_to_key(keyinfo, keyid) - # The repo may have used hashing algorithms for the generated keyids - # that doesn't match the client's set of hash algorithms. Make sure - # to only used the repo's selected hashing algorithms. - hash_algorithms = securesystemslib.settings.HASH_ALGORITHMS - securesystemslib.settings.HASH_ALGORITHMS = keyinfo['keyid_hash_algorithms'] - key, keyids = securesystemslib.keys.format_metadata_to_key(keyinfo) - securesystemslib.settings.HASH_ALGORITHMS = hash_algorithms - - for key_id in keyids: - key['keyid'] = key_id - tuf.keydb.add_key(key, keyid=None, repository_name=self.repository_name) + tuf.keydb.add_key(key, repository_name=self.repository_name) except tuf.exceptions.KeyAlreadyExistsError: pass diff --git a/tuf/keydb.py b/tuf/keydb.py index 8011719f..663d9559 100755 --- a/tuf/keydb.py +++ b/tuf/keydb.py @@ -113,30 +113,21 @@ def create_keydb_from_root_metadata(root_metadata, repository_name='default'): # Iterate the keys found in 'root_metadata' by converting them to # 'RSAKEY_SCHEMA' if their type is 'rsa', and then adding them to the - # key database. - for junk, key_metadata in six.iteritems(root_metadata['keys']): + # key database using the provided keyid. + for keyid, key_metadata in six.iteritems(root_metadata['keys']): if key_metadata['keytype'] in _SUPPORTED_KEY_TYPES: # 'key_metadata' is stored in 'KEY_SCHEMA' format. Call # create_from_metadata_format() to get the key in 'RSAKEY_SCHEMA' format, - # which is the format expected by 'add_key()'. Note: The 'keyids' - # returned by format_metadata_to_key() include keyids in addition to the - # default keyid listed in 'key_dict'. The additional keyids are - # generated according to securesystemslib.settings.HASH_ALGORITHMS. + # which is the format expected by 'add_key()'. Note: This call to + # format_metadata_to_key() uses the provided keyid as the default keyid. + # All other keyids returned are ignored. - # The repo may have used hashing algorithms for the generated keyids that - # doesn't match the client's set of hash algorithms. Make sure to only - # used the repo's selected hashing algorithms. - hash_algorithms = securesystemslib.settings.HASH_ALGORITHMS - securesystemslib.settings.HASH_ALGORITHMS = key_metadata['keyid_hash_algorithms'] - key_dict, keyids = securesystemslib.keys.format_metadata_to_key(key_metadata) - securesystemslib.settings.HASH_ALGORITHMS = hash_algorithms + key_dict, _ = securesystemslib.keys.format_metadata_to_key(key_metadata, keyid) + # Make sure to update key_dict['keyid'] to use one of the other valid + # keyids, otherwise add_key() will have no reference to it. try: - for keyid in keyids: - # Make sure to update key_dict['keyid'] to use one of the other valid - # keyids, otherwise add_key() will have no reference to it. - key_dict['keyid'] = keyid - add_key(key_dict, keyid=None, repository_name=repository_name) + add_key(key_dict, repository_name=repository_name) # Although keyid duplicates should *not* occur (unique dict keys), log a # warning and continue. However, 'key_dict' may have already been diff --git a/tuf/repository_lib.py b/tuf/repository_lib.py index fe77ad84..3b986fed 100644 --- a/tuf/repository_lib.py +++ b/tuf/repository_lib.py @@ -642,15 +642,10 @@ def _load_top_level_metadata(repository, top_level_filenames, repository_name): repository_name=repository_name) # Add the keys specified in the delegations field of the Targets role. - for key_metadata in six.itervalues(targets_metadata['delegations']['keys']): + for keyid, key_metadata in six.iteritems(targets_metadata['delegations']['keys']): - # The repo may have used hashing algorithms for the generated keyids - # that doesn't match the client's set of hash algorithms. Make sure - # to only used the repo's selected hashing algorithms. - hash_algorithms = securesystemslib.settings.HASH_ALGORITHMS - securesystemslib.settings.HASH_ALGORITHMS = key_metadata['keyid_hash_algorithms'] - key_object, keyids = securesystemslib.keys.format_metadata_to_key(key_metadata) - securesystemslib.settings.HASH_ALGORITHMS = hash_algorithms + # Use the keyid found in the delegation + key_object, _ = securesystemslib.keys.format_metadata_to_key(key_metadata, keyid) # Add 'key_object' to the list of recognized keys. Keys may be shared, # so do not raise an exception if 'key_object' has already been loaded. @@ -659,10 +654,7 @@ def _load_top_level_metadata(repository, top_level_filenames, repository_name): # repository maintainer should have also been made aware of the duplicate # key when it was added. try: - for keyid in keyids: #pragma: no branch - key_object['keyid'] = keyid - tuf.keydb.add_key(key_object, keyid=None, - repository_name=repository_name) + tuf.keydb.add_key(key_object, keyid=None, repository_name=repository_name) except tuf.exceptions.KeyAlreadyExistsError: pass