def test_sign_metadata(self): # Test normal case. repository_name = 'test_repository' temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory) metadata_path = os.path.join('repository_data', 'repository', 'metadata') keystore_path = os.path.join('repository_data', 'keystore') root_filename = os.path.join(metadata_path, 'root.json') root_metadata = securesystemslib.util.load_json_file(root_filename)['signed'] targets_filename = os.path.join(metadata_path, 'targets.json') targets_metadata = securesystemslib.util.load_json_file(targets_filename)['signed'] tuf.keydb.create_keydb_from_root_metadata(root_metadata, repository_name) tuf.roledb.create_roledb_from_root_metadata(root_metadata, repository_name) root_keyids = tuf.roledb.get_role_keyids('root', repository_name) targets_keyids = tuf.roledb.get_role_keyids('targets', repository_name) root_private_keypath = os.path.join(keystore_path, 'root_key') root_private_key = repo_lib.import_rsa_privatekey_from_file(root_private_keypath, 'password') # Sign with a valid, but not a threshold, key. targets_public_keypath = os.path.join(keystore_path, 'targets_key.pub') targets_public_key = securesystemslib.interface.\ import_ed25519_publickey_from_file(targets_public_keypath) # sign_metadata() expects the private key 'root_metadata' to be in # 'tuf.keydb'. Remove any public keys that may be loaded before # adding private key, otherwise a 'tuf.KeyAlreadyExists' exception is # raised. tuf.keydb.remove_key(root_private_key['keyid'], repository_name=repository_name) tuf.keydb.add_key(root_private_key, repository_name=repository_name) tuf.keydb.remove_key(targets_public_key['keyid'], repository_name=repository_name) tuf.keydb.add_key(targets_public_key, repository_name=repository_name) # Verify that a valid root signable is generated. root_signable = repo_lib.sign_metadata(root_metadata, root_keyids, root_filename, repository_name) self.assertTrue(tuf.formats.SIGNABLE_SCHEMA.matches(root_signable)) # Test for an unset private key (in this case, target's). repo_lib.sign_metadata(targets_metadata, targets_keyids, targets_filename, repository_name) # Add an invalid keytype to one of the root keys. root_keyid = root_keyids[0] tuf.keydb._keydb_dict[repository_name][root_keyid]['keytype'] = 'bad_keytype' self.assertRaises(securesystemslib.exceptions.Error, repo_lib.sign_metadata, root_metadata, root_keyids, root_filename, repository_name) # Test improperly formatted arguments. self.assertRaises(securesystemslib.exceptions.FormatError, repo_lib.sign_metadata, 3, root_keyids, 'root.json', repository_name) self.assertRaises(securesystemslib.exceptions.FormatError, repo_lib.sign_metadata, root_metadata, 3, 'root.json', repository_name) self.assertRaises(securesystemslib.exceptions.FormatError, repo_lib.sign_metadata, root_metadata, root_keyids, 3, repository_name)
def test_sign_metadata(self): # Test normal case. temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory) metadata_path = os.path.join('repository_data', 'repository', 'metadata') keystore_path = os.path.join('repository_data', 'keystore') root_filename = os.path.join(metadata_path, 'root.json') root_metadata = tuf.util.load_json_file(root_filename)['signed'] tuf.keydb.create_keydb_from_root_metadata(root_metadata) tuf.roledb.create_roledb_from_root_metadata(root_metadata) root_keyids = tuf.roledb.get_role_keyids('root') root_private_keypath = os.path.join(keystore_path, 'root_key') root_private_key = \ repo_lib.import_rsa_privatekey_from_file(root_private_keypath, 'password') # Sign with a valid, but not a threshold, key. targets_private_keypath = os.path.join(keystore_path, 'targets_key') targets_private_key = \ repo_lib.import_rsa_privatekey_from_file(targets_private_keypath, 'password') # sign_metadata() expects the private key 'root_metadata' to be in # 'tuf.keydb'. Remove any public keys that may be loaded before # adding private key, otherwise a 'tuf.KeyAlreadyExists' exception is # raised. tuf.keydb.remove_key(root_private_key['keyid']) tuf.keydb.add_key(root_private_key) tuf.keydb.remove_key(targets_private_key['keyid']) tuf.keydb.add_key(targets_private_key) root_keyids.extend(tuf.roledb.get_role_keyids('targets')) # Add the snapshot's public key (to test whether non-private keys are # ignored by sign_metadata()). root_keyids.extend(tuf.roledb.get_role_keyids('snapshot')) root_signable = repo_lib.sign_metadata(root_metadata, root_keyids, root_filename) self.assertTrue(tuf.formats.SIGNABLE_SCHEMA.matches(root_signable)) # Test improperly formatted arguments. self.assertRaises(tuf.FormatError, repo_lib.sign_metadata, 3, root_keyids, 'root.json') self.assertRaises(tuf.FormatError, repo_lib.sign_metadata, root_metadata, 3, 'root.json') self.assertRaises(tuf.FormatError, repo_lib.sign_metadata, root_metadata, root_keyids, 3)
def test_sign_metadata(self): # Test normal case. temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory) metadata_path = os.path.join("repository_data", "repository", "metadata") keystore_path = os.path.join("repository_data", "keystore") root_filename = os.path.join(metadata_path, "root.json") root_metadata = tuf.util.load_json_file(root_filename)["signed"] tuf.keydb.create_keydb_from_root_metadata(root_metadata) tuf.roledb.create_roledb_from_root_metadata(root_metadata) root_keyids = tuf.roledb.get_role_keyids("root") root_private_keypath = os.path.join(keystore_path, "root_key") root_private_key = repo_lib.import_rsa_privatekey_from_file(root_private_keypath, "password") # Sign with a valid, but not a threshold, key. targets_private_keypath = os.path.join(keystore_path, "targets_key") targets_private_key = repo_lib.import_rsa_privatekey_from_file(targets_private_keypath, "password") # sign_metadata() expects the private key 'root_metadata' to be in # 'tuf.keydb'. Remove any public keys that may be loaded before # adding private key, otherwise a 'tuf.KeyAlreadyExists' exception is # raised. tuf.keydb.remove_key(root_private_key["keyid"]) tuf.keydb.add_key(root_private_key) tuf.keydb.remove_key(targets_private_key["keyid"]) tuf.keydb.add_key(targets_private_key) root_keyids.extend(tuf.roledb.get_role_keyids("targets")) # Add the snapshot's public key (to test whether non-private keys are # ignored by sign_metadata()). root_keyids.extend(tuf.roledb.get_role_keyids("snapshot")) root_signable = repo_lib.sign_metadata(root_metadata, root_keyids, root_filename) self.assertTrue(tuf.formats.SIGNABLE_SCHEMA.matches(root_signable)) # Test improperly formatted arguments. self.assertRaises(tuf.FormatError, repo_lib.sign_metadata, 3, root_keyids, "root.json") self.assertRaises(tuf.FormatError, repo_lib.sign_metadata, root_metadata, 3, "root.json") self.assertRaises(tuf.FormatError, repo_lib.sign_metadata, root_metadata, root_keyids, 3)
def _generate_and_write_metadata(rolename, metadata_filename, write_partial, targets_directory, prefix='', repository_name='default'): """ Non-public function that can generate and write the metadata of the specified 'rolename'. It also increments version numbers if: 1. write_partial==True and the metadata is the first to be written. 2. write_partial=False (i.e., write()), the metadata was not loaded as partially written, and a write_partial is not needed. """ metadata = None # Retrieve the roleinfo of 'rolename' to extract the needed metadata # attributes, such as version number, expiration, etc. roleinfo = roledb.get_roleinfo(rolename, repository_name) metadata = generate_targets_metadata(targets_directory, roleinfo['paths'], roleinfo['version'], roleinfo['expires'], roleinfo['delegations'], False) # Prepend the prefix to the project's filepath to avoid signature errors in # upstream. for element in list(metadata['targets']): junk, relative_target = os.path.split(element) prefixed_path = os.path.join(prefix, relative_target) metadata['targets'][prefixed_path] = metadata['targets'][element] if prefix != '': del (metadata['targets'][element]) signable = repo_lib.sign_metadata(metadata, roleinfo['signing_keyids'], metadata_filename, repository_name) # Check if the version number of 'rolename' may be automatically incremented, # depending on whether if partial metadata is loaded or if the metadata is # written with write() / write_partial(). # Increment the version number if this is the first partial write. if write_partial: temp_signable = repo_lib.sign_metadata(metadata, [], metadata_filename, repository_name) temp_signable['signatures'].extend(roleinfo['signatures']) status = sig.get_signature_status(temp_signable, rolename, repository_name) if len(status['good_sigs']) == 0: metadata['version'] = metadata['version'] + 1 signable = repo_lib.sign_metadata(metadata, roleinfo['signing_keyids'], metadata_filename, repository_name) # non-partial write() else: if sig.verify(signable, rolename, repository_name): metadata['version'] = metadata['version'] + 1 signable = repo_lib.sign_metadata(metadata, roleinfo['signing_keyids'], metadata_filename, repository_name) # Write the metadata to file if contains a threshold of signatures. signable['signatures'].extend(roleinfo['signatures']) if sig.verify(signable, rolename, repository_name) or write_partial: repo_lib._remove_invalid_and_duplicate_signatures( signable, repository_name) storage_backend = sslib_storage.FilesystemBackend() filename = repo_lib.write_metadata_file(signable, metadata_filename, metadata['version'], False, storage_backend) # 'signable' contains an invalid threshold of signatures. else: message = 'Not enough signatures for ' + repr(metadata_filename) raise sslib_exceptions.Error(message, signable) return signable, filename
def _generate_and_write_metadata(rolename, metadata_filename, write_partial, targets_directory, metadata_directory, filenames=None, prefix=''): """ Non-public function that can generate and write the metadata of the specified 'rolename'. It also increments version numbers if: 1. write_partial==True and the metadata is the first to be written. 2. write_partial=False (i.e., write()), the metadata was not loaded as partially written, and a write_partial is not needed. """ metadata = None # Retrieve the roleinfo of 'rolename' to extract the needed metadata # attributes, such as version number, expiration, etc. roleinfo = tuf.roledb.get_roleinfo(rolename) metadata = generate_targets_metadata(targets_directory, roleinfo['paths'], roleinfo['version'], roleinfo['expires'], roleinfo['delegations'], False) # Prepend the prefix to the project's filepath to avoid signature errors in # upstream. target_filepaths = metadata['targets'].items() for element in list(metadata['targets']): junk_path, relative_target = os.path.split(element) prefixed_path = os.path.join(prefix,relative_target) metadata['targets'][prefixed_path] = metadata['targets'][element] if prefix != '': del(metadata['targets'][element]) signable = sign_metadata(metadata, roleinfo['signing_keyids'], metadata_filename) # Check if the version number of 'rolename' may be automatically incremented, # depending on whether if partial metadata is loaded or if the metadata is # written with write() / write_partial(). # Increment the version number if this is the first partial write. if write_partial: temp_signable = sign_metadata(metadata, [], metadata_filename) temp_signable['signatures'].extend(roleinfo['signatures']) status = tuf.sig.get_signature_status(temp_signable, rolename) if len(status['good_sigs']) == 0: metadata['version'] = metadata['version'] + 1 signable = sign_metadata(metadata, roleinfo['signing_keyids'], metadata_filename) # non-partial write() else: if tuf.sig.verify(signable, rolename): #and not roleinfo['partial_loaded']: metadata['version'] = metadata['version'] + 1 signable = sign_metadata(metadata, roleinfo['signing_keyids'], metadata_filename) # Write the metadata to file if contains a threshold of signatures. signable['signatures'].extend(roleinfo['signatures']) if tuf.sig.verify(signable, rolename) or write_partial: _remove_invalid_and_duplicate_signatures(signable) compressions = roleinfo['compressions'] filename = write_metadata_file(signable, metadata_filename, metadata['version'], compressions, False) # 'signable' contains an invalid threshold of signatures. else: message = 'Not enough signatures for ' + repr(metadata_filename) raise tuf.Error(message, signable) return signable, filename