def get_keys_for_targets_role(targets_role_name, create_missing_keys=False): """Given the name of a targets role (targets_role_name) and its list of passwords (targets_role_passwords), return the RSA key IDs for a targets role. Side effect: Load the aforementioned RSA keys into the global TUF keystore.""" # Get the list of passwords for this role. targets_role_passwords = ROLE_NAME_TO_PASSWORDS[targets_role_name] if targets_role_name == 'targets': # Ask root about targets' keys. root_metadata_dict = signerlib.read_metadata_file(ROOT_ROLE_FILE) # TODO: Verify signature on root metadata! signed_root_metadata = root_metadata_dict['signed'] targets_role_keys = signed_root_metadata['roles']['targets']['keyids'] else: # Ask the targets role itself. targets_role_filename = os.path.join( METADATA_DIRECTORY, '{0}.txt'.format(targets_role_name)) # If the targets role exists... if os.path.exists(targets_role_filename): targets_role_metadata_dict = \ signerlib.read_metadata_file(targets_role_filename) # TODO: Verify signature on targets role metadata! targets_role_metadata_signatures = \ targets_role_metadata_dict['signatures'] targets_role_keys = [] # Assume keys are listed in the same order as passwords. for targets_role_metadata_signature in targets_role_metadata_signatures: targets_role_keys.append( targets_role_metadata_signature['keyid']) # Assume that there are as many keys as there are passwords. assert len(targets_role_keys) == len(targets_role_passwords) # Otherwise... else: if create_missing_keys: logger.info('Creating keys for {0}'.format(targets_role_name)) targets_role_keys = generate_rsa_keys(targets_role_passwords) else: raise MissingKeys(targets_role_name) # Decrypt and load the keys of the targets role. loaded_targets_role_keys = \ keystore.load_keystore_from_keyfiles(KEYSTORE_DIRECTORY, targets_role_keys, targets_role_passwords) assert targets_role_keys == loaded_targets_role_keys return targets_role_keys
def get_keys_for_targets_role(targets_role_name, create_missing_keys=False): """Given the name of a targets role (targets_role_name) and its list of passwords (targets_role_passwords), return the RSA key IDs for a targets role. Side effect: Load the aforementioned RSA keys into the global TUF keystore.""" # Get the list of passwords for this role. targets_role_passwords = ROLE_NAME_TO_PASSWORDS[targets_role_name] if targets_role_name == 'targets': # Ask root about targets' keys. root_metadata_dict = signerlib.read_metadata_file(ROOT_ROLE_FILE) # TODO: Verify signature on root metadata! signed_root_metadata = root_metadata_dict['signed'] targets_role_keys = signed_root_metadata['roles']['targets']['keyids'] else: # Ask the targets role itself. targets_role_filename = os.path.join(METADATA_DIRECTORY, '{0}.txt'.format(targets_role_name)) # If the targets role exists... if os.path.exists(targets_role_filename): targets_role_metadata_dict = \ signerlib.read_metadata_file(targets_role_filename) # TODO: Verify signature on targets role metadata! targets_role_metadata_signatures = \ targets_role_metadata_dict['signatures'] targets_role_keys = [] # Assume keys are listed in the same order as passwords. for targets_role_metadata_signature in targets_role_metadata_signatures: targets_role_keys.append(targets_role_metadata_signature['keyid']) # Assume that there are as many keys as there are passwords. assert len(targets_role_keys) == len(targets_role_passwords) # Otherwise... else: if create_missing_keys: logger.info('Creating keys for {0}'.format(targets_role_name)) targets_role_keys = generate_rsa_keys(targets_role_passwords) else: raise MissingKeys(targets_role_name) # Decrypt and load the keys of the targets role. loaded_targets_role_keys = \ keystore.load_keystore_from_keyfiles(KEYSTORE_DIRECTORY, targets_role_keys, targets_role_passwords) assert targets_role_keys == loaded_targets_role_keys return targets_role_keys
def delegate(args): # parse the options options, args = getopt.getopt(args, "", ["keyid=", "keystore=", "repo="]) fuzzy_keys = _get_key_ids(options) parentrole, role, rolekey, paths = args[0], args[1], args[2], args[3:] _keystore = _get_keystore(options) metadir = _get_meta_dir(options) targets_file = _get_meta_filenames(metadir)['targets'] # get the key from the keystore key = signerlib.get_key(_keystore, rolekey) # extract the metadata from the targets file targets_metadata = signerlib.read_metadata_file(targets_file) # extract the delegations structure if it exists delegations = targets_metadata.get('delegations', {}) # update the keys field keys = delegations.get('keys', {}) keys[rolekey] = key.get_meta() delegations['keys'] = keys # update the roles field roles = delegations.get('roles', {}) roles[role] = tuf.formats.make_role_meta([key.get_key_id()], 1, paths) delegations['roles'] = roles # update the larger metadata structure targets_metadata['delegations'] = delegations # and try to write the whole thing meta = tuf.formats.make_signable(targets_metadata) _sign_and_write(meta, fuzzy_keys, targets_file, options)
def get_delegatee_role_from_delegator(delegator_targets_role_name, relative_delegatee_targets_role_name): # Extract metadata from the delegator targets role. delegator_filename = \ os.path.join(METADATA_DIRECTORY, '{0}.txt'.format(delegator_targets_role_name)) delegator_metadata_dict = \ signerlib.read_metadata_file(delegator_filename) # TODO: Verify signature on delegator metadata! delegator_signed_metadata = delegator_metadata_dict['signed'] delegations = delegator_signed_metadata.get('delegations', {}) roles = delegations.get('roles', []) # Find the delegatee, if it exists, in the delegator. absolute_delegatee_targets_role_name = \ '{0}/{1}'.format(delegator_targets_role_name, relative_delegatee_targets_role_name) role_index = \ signerlib.find_delegated_role(roles, absolute_delegatee_targets_role_name) role = None if role_index is None: logger.info('{0} does not know about {1}'.format( delegator_targets_role_name, relative_delegatee_targets_role_name)) else: role = roles[role_index] return role
def sign(args): """ The release.txt file must exist. """ options, args = getopt.getopt(args, "", ["keyid=", "keystore="]) fuzzy_keys = _get_key_ids(options) if len(args) != 1 or len(fuzzy_keys) == 0: usage() filename = args[0] meta = signerlib.read_metadata_file(filename) _sign_and_write(meta, fuzzy_keys, filename, options)
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