def test_4_make_release_metadata(self): # SETUP original_get_metadata_directory = signercli._get_metadata_directory original_prompt = signercli._prompt original_get_password = signercli._get_password # In order to build release metadata file (release.txt), # root and targets metadata files (root.txt, targets.txt) # must exist in the metadata directory. # Create temp directory for config file. config_dir = self.make_temp_directory() # Build a config file. config_filepath = signerlib.build_config_file(config_dir, 365, self.top_level_role_info) # Create a temp repository and metadata directories. repo_dir = self.make_temp_directory() meta_dir = self.make_temp_directory(repo_dir) # Create a directory containing target files. targets_dir, targets_paths = \ self.make_temp_directory_with_data_files(directory=repo_dir) # Patch signercli._get_metadata_directory(). self.mock_get_metadata_directory(directory=meta_dir) # Patch signercli._get_password(). Used in _get_role_config_keyids(). self.get_passwords() # Create keystore directory. keystore_dir = self.create_temp_keystore_directory() # Mock method for signercli._prompt(). self.make_metadata_mock_prompts(targ_dir=targets_dir, conf_path=config_filepath) # TESTS # Test: no root.txt in the metadata dir. signercli.make_targets_metadata(keystore_dir) # Verify that 'tuf.RepositoryError' is raised due to a missing root.txt. keystore.clear_keystore() self.assertTrue(os.path.exists(os.path.join(meta_dir, 'targets.txt'))) self.assertRaises(tuf.RepositoryError, signercli.make_release_metadata, keystore_dir) os.remove(os.path.join(meta_dir,'targets.txt')) keystore.clear_keystore() # Test: no targets.txt in the metadatadir. signercli.make_root_metadata(keystore_dir) keystore.clear_keystore() # Verify that 'tuf.RepositoryError' is raised due to a missing targets.txt. self.assertTrue(os.path.exists(os.path.join(meta_dir, 'root.txt'))) self.assertRaises(tuf.RepositoryError, signercli.make_release_metadata, keystore_dir) os.remove(os.path.join(meta_dir,'root.txt')) keystore.clear_keystore() # Test: normal case. signercli.make_root_metadata(keystore_dir) keystore.clear_keystore() signercli.make_targets_metadata(keystore_dir) keystore.clear_keystore() signercli.make_release_metadata(keystore_dir) keystore.clear_keystore() # Verify if the root, targets and release meta files were created. self.assertTrue(os.path.exists(os.path.join(meta_dir, 'root.txt'))) self.assertTrue(os.path.exists(os.path.join(meta_dir, 'targets.txt'))) self.assertTrue(os.path.exists(os.path.join(meta_dir, 'release.txt'))) # Test: invalid config path. # Supply a non-existing config file path. self.make_metadata_mock_prompts(targ_dir=targets_dir, conf_path=self.random_path()) self.assertRaises(tuf.RepositoryError, signercli.make_release_metadata, keystore_dir) # Restore the config file path. self.make_metadata_mock_prompts(targ_dir=targets_dir, conf_path=config_filepath) # Test: incorrect 'release' passwords. # Clear keystore's dictionaries. keystore.clear_keystore() keyids = self.top_level_role_info['release']['keyids'] for keyid in keyids: saved_pw = self.rsa_passwords[keyid] self.rsa_passwords[keyid] = self.random_string() self.assertRaises(tuf.RepositoryError, signercli.make_release_metadata, keystore_dir) self.rsa_passwords[keyid] = saved_pw # RESTORE signercli._get_password = original_get_password signercli._prompt = original_prompt signercli._get_metadata_directory = original_get_metadata_directory
def test_4_dump_key(self): # SETUP original_get_metadata_directory = signercli._get_metadata_directory original_prompt = signercli._prompt original_get_password = signercli._get_password # Create keystore and repo directories. keystore_dir = self.create_temp_keystore_directory() repo_dir = self.make_temp_directory() # Create temp directory for config file. config_dir = self.make_temp_directory() # Build a config file. config_filepath = signerlib.build_config_file(config_dir, 365, self.top_level_role_info) # Create a temp metadata directory. meta_dir = self.make_temp_directory() # Patch signercli._get_metadata_directory(). self.mock_get_metadata_directory(directory=meta_dir) # Patch signercli._get_password(). self.get_passwords() # Patch signercli._prompt(). self.mock_prompt(config_filepath) signercli.make_root_metadata(keystore_dir) # Create a directory containing target files. targets_dir, targets_paths =\ self.make_temp_directory_with_data_files(directory=repo_dir) # Mock method for signercli._prompt(). self.make_metadata_mock_prompts(targ_dir=targets_dir, conf_path=config_filepath) signercli.make_targets_metadata(keystore_dir) keyid = self.rsa_keyids[0] password = self.rsa_passwords[keyid] show_priv = 'private' # Mock method for signercli._get_password(). def _mock_get_password(msg): return password # Mock method for signercli._prompt(). def _mock_prompt(msg, junk): if msg.startswith('\nEnter the keyid'): return keyid else: return show_priv # Patch signercli._get_password(). signercli._get_password = _mock_get_password # Patch signercli._prompt(). signercli._prompt = _mock_prompt # TESTS # Test: normal case. signercli.dump_key(keystore_dir) # Test: incorrect password. saved_pw = password password = self.random_string() self.assertRaises(tuf.RepositoryError, signercli.dump_key, keystore_dir) # Restore the correct password. password = saved_pw # Test: non-existing keyid. keyid = self.random_string() self.assertRaises(tuf.RepositoryError, signercli.dump_key, keystore_dir) keyid = self.rsa_keyids[0] # RESTORE signercli._get_password = original_get_password signercli._prompt = original_prompt signercli._get_metadata_directory = original_get_metadata_directory
def test_4_change_password(self): # SETUP original_get_metadata_directory = signercli._get_metadata_directory original_prompt = signercli._prompt original_get_password = signercli._get_password # Create keystore and repo directories. keystore_dir = self.create_temp_keystore_directory() repo_dir = self.make_temp_directory() # Create temp directory for config file. config_dir = self.make_temp_directory() # Build a config file. config_filepath = signerlib.build_config_file(config_dir, 365, self.top_level_role_info) # Create a temp metadata directory. meta_dir = self.make_temp_directory() # Patch signercli._get_metadata_directory(). self.mock_get_metadata_directory(directory=meta_dir) # Patch signercli._prompt(). self.mock_prompt(config_filepath) # Patch '_get_password' method. self.get_passwords() signercli.make_root_metadata(keystore_dir) # Create a directory containing target files. targets_dir, targets_paths =\ self.make_temp_directory_with_data_files(directory=repo_dir) # Mock method for signercli._prompt(). self.make_metadata_mock_prompts(targ_dir=targets_dir, conf_path=config_filepath) signercli.make_targets_metadata(keystore_dir) test_keyid = self.rsa_keyids[0] self.mock_prompt(test_keyid) # Specify old password and create a new password. old_password = self.rsa_passwords[test_keyid] new_password = self.random_string() # Mock method for signercli._get_password() def _mock_get_password(msg, confirm=False, old_pw=old_password, new_pw=new_password): if msg.startswith('\nEnter the old password for the keyid: '): return old_pw else: return new_pw # Patch signercli._get_password. signercli._get_password = _mock_get_password # TESTS # Test: normal case. signercli.change_password(keystore_dir) # Verify password change. self.assertEqual(keystore._key_passwords[test_keyid], new_password) # Test: non-existing keyid. keystore.clear_keystore() self.mock_prompt(self.random_string(15)) self.assertRaises(tuf.RepositoryError, signercli.change_password, keystore_dir) # Restore the prompt input to existing keyid. self.mock_prompt(test_keyid) # Test: non-existing old password. keystore.clear_keystore() old_password = self.random_string() self.assertRaises(tuf.RepositoryError, signercli.change_password, keystore_dir) # RESTORE signercli._get_password = original_get_password signercli._prompt = original_prompt signercli._get_metadata_directory = original_get_metadata_directory
def test_4__list_keyids(self): # SETUP original_get_metadata_directory = signercli._get_metadata_directory original_prompt = signercli._prompt original_get_password = signercli._get_password # The 'root.txt' and 'targets.txt' metadata files are # needed for _list_keyids() to determine the roles # associated with each keyid. keystore_dir = self.create_temp_keystore_directory() repo_dir = self.make_temp_directory() # Create temp directory for config file. config_dir = self.make_temp_directory() # Build a config file. config_filepath = signerlib.build_config_file(config_dir, 365, self.top_level_role_info) # Create the metadata directory needed by _list_keyids(). meta_dir = self.make_temp_directory() # Patch signercli._get_metadata_directory(). self.mock_get_metadata_directory(directory=meta_dir) # Patch signercli._prompt(). self.mock_prompt(config_filepath) # Patch signercli._get_password(). self.get_passwords() # Create the root metadata file that will be loaded by _list_keyids() # to extract the keyids for the top-level roles. signercli.make_root_metadata(keystore_dir) # Create a directory containing target files. targets_dir, targets_paths =\ self.make_temp_directory_with_data_files(directory=repo_dir) # Mock method for signercli._prompt(). self.make_metadata_mock_prompts(targ_dir=targets_dir, conf_path=config_filepath) # Create the target metadata file that will be loaded by _list_keyids() # to extract the keyids for all the targets roles. signercli.make_targets_metadata(keystore_dir) # TESTS # Test: normal case. signercli._list_keyids(keystore_dir, meta_dir) # Test: Improperly formatted 'root.txt' file. root_filename = os.path.join(meta_dir, 'root.txt') root_signable = tuf.util.load_json_file(root_filename) saved_roles = root_signable['signed']['roles'] del root_signable['signed']['roles'] tuf.repo.signerlib.write_metadata_file(root_signable, root_filename) self.assertRaises(tuf.RepositoryError, signercli._list_keyids, keystore_dir, meta_dir) # Restore the properly formatted 'root.txt' file. root_signable['signed']['roles'] = saved_roles tuf.repo.signerlib.write_metadata_file(root_signable, root_filename) # Test: Improperly formatted 'targets.txt' file. targets_filename = os.path.join(meta_dir, 'targets.txt') targets_signable = tuf.util.load_json_file(targets_filename) saved_targets = targets_signable['signed']['targets'] del targets_signable['signed']['targets'] tuf.repo.signerlib.write_metadata_file(targets_signable, targets_filename) self.assertRaises(tuf.RepositoryError, signercli._list_keyids, keystore_dir, meta_dir) # Restore the properly formatted 'targets.txt' file. targets_signable['signed']['targets'] = saved_targets tuf.repo.signerlib.write_metadata_file(targets_signable, targets_filename) # RESTORE signercli._get_password = original_get_password signercli._prompt = original_prompt signercli._get_metadata_directory = original_get_metadata_directory
def test_7_make_delegation(self): # SETUP original_get_metadata_directory = signercli._get_metadata_directory original_prompt = signercli._prompt original_get_password = signercli._get_password # Create a temp repository and metadata directories. repo_dir = self.make_temp_directory() meta_dir = self.make_temp_directory(directory=repo_dir) # Create targets directories. targets_dir, targets_paths =\ self.make_temp_directory_with_data_files(directory=repo_dir) delegated_targets_dir = os.path.join(targets_dir,'targets', 'delegated_level1') # Assign parent role and name of the delegated role. parent_role = 'targets' delegated_role = 'delegated_role_1' # Create couple new RSA keys for delegation levels 1 and 2. new_keyid_1 = self.generate_rsakey() new_keyid_2 = self.generate_rsakey() # Create temp directory for config file. config_dir = self.make_temp_directory() # Build a config file. config_filepath = signerlib.build_config_file(config_dir, 365, self.top_level_role_info) # Patch signercli._get_metadata_directory(). self.mock_get_metadata_directory(directory=meta_dir) # Patch signercli._get_password(). Get passwords for parent's keyids. self.get_passwords() # Create keystore directory. keystore_dir = self.create_temp_keystore_directory() # Mock method for signercli._prompt() to generate targets.txt file. self.make_metadata_mock_prompts(targ_dir=targets_dir, conf_path=config_filepath) # List of keyids to be returned by _get_keyids() signing_keyids = [new_keyid_1] # Load keystore. load_keystore = keystore.load_keystore_from_keyfiles # Build the root metadata file (root.txt). signercli.make_root_metadata(keystore_dir) # Build targets metadata file (targets.txt). signercli.make_targets_metadata(keystore_dir) # Clear kestore's dictionaries. keystore.clear_keystore() # Mock method for signercli._prompt(). def _mock_prompt(msg, junk): if msg.startswith('\nThe directory entered'): return delegated_targets_dir elif msg.startswith('\nChoose and enter the parent'): return parent_role elif msg.endswith('\nEnter the delegated role\'s name: '): return delegated_role else: error_msg = ('Prompt: '+'\''+msg+'\''+ ' did not match any predefined mock prompts.') self.fail(error_msg) # Mock method for signercli._get_password(). def _mock_get_password(msg): for keyid in self.rsa_keyids: if msg.endswith('('+keyid+'): '): return self.rsa_passwords[keyid] # Method to patch signercli._get_keyids() def _mock_get_keyids(junk): if signing_keyids: for keyid in signing_keyids: password = self.rsa_passwords[keyid] # Load the keyfile. load_keystore(keystore_dir, [keyid], [password]) return signing_keyids # Patch signercli._prompt(). signercli._prompt = _mock_prompt # Patch signercli._get_password(). signercli._get_password = _mock_get_password # Patch signercli._get_keyids(). signercli._get_keyids = _mock_get_keyids # TESTS # Test: invalid parent role. # Assign a non-existing parent role. parent_role = self.random_string() self.assertRaises(tuf.RepositoryError, signercli.make_delegation, keystore_dir) # Restore parent role. parent_role = 'targets' # Test: invalid password(s) for parent's keyids. keystore.clear_keystore() parent_keyids = self.top_level_role_info[parent_role]['keyids'] for keyid in parent_keyids: saved_pw = self.rsa_passwords[keyid] self.rsa_passwords[keyid] = self.random_string() self.assertRaises(tuf.RepositoryError, signercli.make_delegation, keystore_dir) self.rsa_passwords[keyid] = saved_pw # Test: delegated_keyids == 0. keystore.clear_keystore() # Load 0 keyids (== 0). signing_keyids = [] self.assertRaises(tuf.RepositoryError, signercli.make_delegation, keystore_dir) keystore.clear_keystore() # Restore signing_keyids (== 1). signing_keyids = [new_keyid_1] # Test: normal case 1. # Testing first level delegation. signercli.make_delegation(keystore_dir) # Verify delegated metadata file exists. delegated_meta_file = os.path.join(meta_dir, parent_role, delegated_role+'.txt') self.assertTrue(os.path.exists(delegated_meta_file)) # Test: normal case 2. # Testing second level delegation. keystore.clear_keystore() # Make necessary adjustments for the test. signing_keyids = [new_keyid_2] delegated_targets_dir = os.path.join(delegated_targets_dir, 'delegated_level2') parent_role = os.path.join(parent_role, delegated_role) delegated_role = 'delegated_role_2' signercli.make_delegation(keystore_dir) # Verify delegated metadata file exists. delegated_meta_file = os.path.join(meta_dir, parent_role, delegated_role+'.txt') self.assertTrue(os.path.exists(delegated_meta_file)) # Test: normal case 3. # Testing delegated_keyids > 1. # Ensure make_delegation() sets 'threshold' = 2 for the delegated role. keystore.clear_keystore() # Populate 'signing_keyids' with multiple keys, so the # the delegated metadata is set to a threshold > 1. signing_keyids = [new_keyid_1, new_keyid_2] parent_role = 'targets' delegated_role = 'delegated_role_1' signercli.make_delegation(keystore_dir) # Verify delegated metadata file exists. delegated_meta_file = os.path.join(meta_dir, parent_role, delegated_role+'.txt') self.assertTrue(os.path.exists(delegated_meta_file)) # Verify the threshold value of the delegated metadata file # by inspecting the parent role's 'delegations' field. parent_role_file = os.path.join(meta_dir, parent_role+'.txt') signable = signerlib.read_metadata_file(parent_role_file) delegated_rolename = parent_role+'/'+delegated_role threshold = signable['signed']['delegations']['roles']\ [delegated_rolename]['threshold'] self.assertTrue(threshold == 2) # RESTORE signercli._get_password = original_get_password signercli._prompt = original_prompt signercli._get_metadata_directory = original_get_metadata_directory
def test_6_sign_metadata_file(self): # SETUP original_get_metadata_directory = signercli._get_metadata_directory original_prompt = signercli._prompt original_get_password = signercli._get_password # To test this method, an RSA key will be created with # a password in addition to the existing RSA keys. # Create temp directory for config file. config_dir = self.make_temp_directory() # Build a config file. config_filepath = signerlib.build_config_file(config_dir, 365, self.top_level_role_info) # Create a temp repository and metadata directories. repo_dir = self.make_temp_directory() meta_dir = self.make_temp_directory(repo_dir) # Create a directory containing target files. targets_dir, targets_paths = \ self.make_temp_directory_with_data_files(directory=repo_dir) # Patch signercli._get_metadata_directory(). self.mock_get_metadata_directory(directory=meta_dir) # Patch signercli._get_password(). Used in _get_role_config_keyids(). self.get_passwords() # Create keystore directory. keystore_dir = self.create_temp_keystore_directory() # Mock method for signercli._prompt(). self.make_metadata_mock_prompts(targ_dir=targets_dir, conf_path=config_filepath) # Create metadata files. signercli.make_root_metadata(keystore_dir) keystore.clear_keystore() signercli.make_targets_metadata(keystore_dir) keystore.clear_keystore() signercli.make_release_metadata(keystore_dir) keystore.clear_keystore() signercli.make_timestamp_metadata(keystore_dir) keystore.clear_keystore() # Verify if the root, targets and release meta files were created. root_meta_filepath = os.path.join(meta_dir, 'root.txt') targets_meta_filepath = os.path.join(meta_dir, 'targets.txt') release_meta_filepath = os.path.join(meta_dir, 'release.txt') timestamp_meta_filepath = os.path.join(meta_dir, 'timestamp.txt') self.assertTrue(os.path.exists(root_meta_filepath)) self.assertTrue(os.path.exists(targets_meta_filepath)) self.assertTrue(os.path.exists(release_meta_filepath)) self.assertTrue(os.path.exists(timestamp_meta_filepath)) # Create a new RSA key, indicate metadata filename. new_keyid = self.generate_rsakey() meta_filename = targets_meta_filepath # Create keystore directory. New key is untouched. keystore_dir = self.create_temp_keystore_directory(keystore_dicts=True) # List of keyids to be returned by _get_keyids() signing_keyids = [] # Method to patch signercli._get_keyids() def _mock_get_keyids(junk): return signing_keyids # Method to patch signercli._prompt(). def _mock_prompt(msg, junk): return meta_filename # Patch signercli._get_keyids() signercli._get_keyids = _mock_get_keyids # Patch signercli._prompt(). signercli._prompt = _mock_prompt # TESTS # Test: no loaded keyids. self.assertRaises(tuf.RepositoryError, signercli.sign_metadata_file, keystore_dir) # Load new keyid. signing_keyids = [new_keyid] # Test: normal case. signercli.sign_metadata_file(keystore_dir) # Verify the change. self.assertTrue(os.path.exists(targets_meta_filepath)) # Load targets metadata from the file ('targets.txt'). targets_metadata = tuf.util.load_json_file(targets_meta_filepath) keyid_exists = False for signature in targets_metadata['signatures']: if new_keyid == signature['keyid']: keyid_exists = True break self.assertTrue(keyid_exists) # RESTORE signercli._get_password = original_get_password signercli._prompt = original_prompt signercli._get_metadata_directory = original_get_metadata_directory