def build_server_repository(server_repository_dir, targets_dir): # Make metadata directory inside client and server repository dir. server_metadata_dir = os.path.join(server_repository_dir, 'metadata') os.mkdir(server_metadata_dir) # Make a keystore directory inside server's repository and populate it. keystore_dir = os.path.join(server_repository_dir, 'keystore') os.mkdir(keystore_dir) create_keystore(keystore_dir) # Build config file. config_filepath = signerlib.build_config_file( server_repository_dir, 365, unittest_toolbox.semi_roledict) # Role:keyids dictionary. role_keyids = {} for role in unittest_toolbox.semi_roledict.keys(): role_keyids[role] = unittest_toolbox.semi_roledict[role]['keyids'] # Build root file. signerlib.build_root_file(config_filepath, role_keyids['root'], server_metadata_dir) # Build targets file. signerlib.build_targets_file(targets_dir, role_keyids['targets'], server_metadata_dir) # Build release file. signerlib.build_release_file(role_keyids['release'], server_metadata_dir) # Build timestamp file. signerlib.build_timestamp_file(role_keyids['timestamp'], server_metadata_dir)
def tuf_refresh_repo(root_repo, keyids): """ <Purpose> Update TUF metadata files. Call this method whenever targets files have changed in the 'reg_repo'. """ global version expiration = tuf.formats.format_time(time.time()+86400) reg_repo = os.path.join(root_repo, 'reg_repo') tuf_repo = os.path.join(root_repo, 'tuf_repo') targets_dir = os.path.join(tuf_repo, 'targets') metadata_dir = os.path.join(tuf_repo, 'metadata') for directory in [reg_repo, tuf_repo, targets_dir, metadata_dir]: if not os.path.isdir(directory): msg = ('Directory '+repr(directory)+' does not exist. '+ 'Verify that all directories were setup properly.') raise OSError(msg) shutil.rmtree(targets_dir) shutil.copytree(reg_repo, targets_dir) version = version+1 # Regenerate the 'targets.txt' metadata file. signerlib.build_targets_file([targets_dir], keyids, metadata_dir, version, expiration) # Regenerate the 'release.txt' metadata file. signerlib.build_release_file(keyids, metadata_dir, version, expiration) # Regenerate the 'timestamp.txt' metadata file. signerlib.build_timestamp_file(keyids, metadata_dir, version, expiration)
def tuf_refresh_repo(root_repo, keyids): """ <Purpose> Update TUF metadata files. Call this method whenever targets files have changed in the 'reg_repo'. """ global version expiration = tuf.formats.format_time(time.time() + 86400) reg_repo = os.path.join(root_repo, 'reg_repo') tuf_repo = os.path.join(root_repo, 'tuf_repo') targets_dir = os.path.join(tuf_repo, 'targets') metadata_dir = os.path.join(tuf_repo, 'metadata') for directory in [reg_repo, tuf_repo, targets_dir, metadata_dir]: if not os.path.isdir(directory): msg = ('Directory ' + repr(directory) + ' does not exist. ' + 'Verify that all directories were setup properly.') raise OSError(msg) shutil.rmtree(targets_dir) shutil.copytree(reg_repo, targets_dir) version = version + 1 # Regenerate the 'targets.txt' metadata file. signerlib.build_targets_file([targets_dir], keyids, metadata_dir, version, expiration) # Regenerate the 'release.txt' metadata file. signerlib.build_release_file(keyids, metadata_dir, version, expiration) # Regenerate the 'timestamp.txt' metadata file. signerlib.build_timestamp_file(keyids, metadata_dir, version, expiration)
def test_9_build_timestamp_metadata(self): """ test_9_build_timestamp_file() uses previously tested generate_timestamp_metadata(). """ # SETUP # Create all necessary files and metadata i.e. signed timestamp # metadata, timestamp keyids, 'release.txt', 'root.txt', 'targets.txt', # target files, etc. signed_timestamp_meta, timestamp_info = \ self._get_signed_role_info('timestamp') timestamp_keyids = timestamp_info[1] meta_dir = timestamp_info[2] timestamp_filepath = os.path.join(meta_dir, 'timestamp.txt') # TESTS # Test: normal case. try: signerlib.build_timestamp_file(timestamp_keyids, meta_dir) except Exception, e: raise
def update_timestamp(time_delta, include_compressed_release=True): expiration_date = get_expiration_date(time_delta) timestamp_role_keys = get_keys_for_top_level_role(TIMESTAMP_ROLE_NAME) version_number = signercli._get_metadata_version(TIMESTAMP_ROLE_FILE) # Generate and write the signed timestamp metadata. signerlib.build_timestamp_file(timestamp_role_keys, METADATA_DIRECTORY, version_number, expiration_date, include_compressed_release=include_compressed_release)
def update_timestamp(time_delta, include_compressed_release=True): expiration_date = get_expiration_date(time_delta) timestamp_role_keys = get_keys_for_top_level_role(TIMESTAMP_ROLE_NAME) version_number = signercli._get_metadata_version(TIMESTAMP_ROLE_FILE) # Generate and write the signed timestamp metadata. signerlib.build_timestamp_file( timestamp_role_keys, METADATA_DIRECTORY, version_number, expiration_date, include_compressed_release=include_compressed_release)
def test_9_build_timestamp_file(self): """ test_9_build_timestamp_file() uses previously tested generate_timestamp_metadata(). """ # SETUP original_get_key = tuf.repo.keystore.get_key # Create all necessary files and metadata i.e. signed timestamp # metadata, timestamp keyids, 'release.txt', 'root.txt', 'targets.txt', # target files, etc. signed_timestamp_meta, timestamp_info = self._get_signed_role_info("timestamp") timestamp_keyids = timestamp_info[1] meta_dir = timestamp_info[2] # TESTS # Test: normal case. timestamp_filepath = signerlib.build_timestamp_file(timestamp_keyids, meta_dir) # Check if 'timestamp.txt' file was created in metadata directory. self.assertTrue(os.path.exists(timestamp_filepath)) file_content = tuf.util.load_json_file(timestamp_filepath) self.assertTrue(tuf.formats.SIGNABLE_SCHEMA.matches(file_content)) timestamp_metadata = file_content["signed"] self.assertTrue(tuf.formats.TIMESTAMP_SCHEMA.matches(timestamp_metadata)) # Test: try bogus parameters. self.assertRaises(tuf.Error, signerlib.build_timestamp_file, timestamp_keyids, self.random_path()) self.assertRaises(tuf.FormatError, signerlib.build_timestamp_file, self.random_string(), meta_dir) # RESTORE tuf.repo.keystore.get_key = original_get_key
def test_9_build_timestamp_file(self): """ test_9_build_timestamp_file() uses previously tested generate_timestamp_metadata(). """ # SETUP original_get_key = tuf.repo.keystore.get_key version = 8 expiration_date = '1985-10-26 01:20:00 UTC' # Create all necessary files and metadata i.e. signed timestamp # metadata, timestamp keyids, 'release.txt', 'root.txt', 'targets.txt', # target files, etc. signed_timestamp_meta, timestamp_info = \ self._get_signed_role_info('timestamp') timestamp_keyids = timestamp_info[1] meta_dir = timestamp_info[2] # TESTS # Test: normal case. timestamp_filepath = signerlib.build_timestamp_file( timestamp_keyids, meta_dir, version, expiration_date) # Check if 'timestamp.txt' file was created in metadata directory. self.assertTrue(os.path.exists(timestamp_filepath)) file_content = tuf.util.load_json_file(timestamp_filepath) self.assertTrue(tuf.formats.SIGNABLE_SCHEMA.matches(file_content)) timestamp_metadata = file_content['signed'] self.assertTrue( tuf.formats.TIMESTAMP_SCHEMA.matches(timestamp_metadata)) # Test: try bogus parameters. self.assertRaises(tuf.Error, signerlib.build_timestamp_file, timestamp_keyids, self.random_path(), version, expiration_date) self.assertRaises(tuf.FormatError, signerlib.build_timestamp_file, self.random_string(), meta_dir, version, expiration_date) self.assertRaises(tuf.FormatError, signerlib.build_timestamp_file, timestamp_keyids, meta_dir, self.random_string(), expiration_date) self.assertRaises(tuf.FormatError, signerlib.build_timestamp_file, timestamp_keyids, meta_dir, version, self.random_string()) # RESTORE tuf.repo.keystore.get_key = original_get_key
def build_server_repository(server_repository_dir, targets_dir): # Make metadata directory inside client and server repository dir. server_metadata_dir = os.path.join(server_repository_dir, 'metadata') os.mkdir(server_metadata_dir) # Make a keystore directory inside server's repository and populate it. keystore_dir = os.path.join(server_repository_dir, 'keystore') os.mkdir(keystore_dir) create_keystore(keystore_dir) # Build config file. config_filepath = signerlib.build_config_file(server_repository_dir, 365, unittest_toolbox.semi_roledict) # Role:keyids dictionary. role_keyids = {} for role in unittest_toolbox.semi_roledict.keys(): role_keyids[role] = unittest_toolbox.semi_roledict[role]['keyids'] # Build root file. signerlib.build_root_file(config_filepath, role_keyids['root'], server_metadata_dir) # Build targets file. signerlib.build_targets_file(targets_dir, role_keyids['targets'], server_metadata_dir) # Build release file. signerlib.build_release_file(role_keyids['release'], server_metadata_dir) # Build timestamp file. signerlib.build_timestamp_file(role_keyids['timestamp'], server_metadata_dir)
def init_tuf(root_repo): """ <Purpose> Setup TUF directory structure and populated it with TUF metadata and congfiguration files. """ threshold = 1 global version version = version+1 expiration = tuf.formats.format_time(time.time()+86400) # Setup TUF-repo directory structure. tuf_repo = os.path.join(root_repo, 'tuf_repo') keystore_dir = os.path.join(tuf_repo, 'keystore') metadata_dir = os.path.join(tuf_repo, 'metadata') targets_dir = os.path.join(tuf_repo, 'targets') os.mkdir(tuf_repo) os.mkdir(keystore_dir) os.mkdir(metadata_dir) shutil.copytree(os.path.join(root_repo, 'reg_repo'), targets_dir) # Setting TUF-client directory structure. # 'tuf.client.updater.py' expects the 'current' and 'previous' # directories to exist under client's 'metadata' directory. tuf_client = os.path.join(root_repo, 'tuf_client') tuf_client_metadata_dir = os.path.join(tuf_client, 'metadata') current_dir = os.path.join(tuf_client_metadata_dir, 'current') previous_dir = os.path.join(tuf_client_metadata_dir, 'previous') os.makedirs(tuf_client_metadata_dir) # Generate at least one rsa key. key = signerlib.generate_and_save_rsa_key(keystore_dir, PASSWD) keyids = [key['keyid']] # Set role info. info = {'keyids': [key['keyid']], 'threshold': threshold} # 'role_info' dictionary looks like this: # {role : {'keyids : [keyid1, ...] , 'threshold' : 1}} # In our case 'role_info[keyids]' will only have on entry since only one # is being used. role_info = {} role_list = ['root', 'targets', 'release', 'timestamp'] for role in role_list: role_info[role] = info # At this point there is enough information to create TUF configuration # and metadata files. # Build the configuration file. conf_path = signerlib.build_config_file(metadata_dir, 365, role_info) # Generate the 'root.txt' metadata file. signerlib.build_root_file(conf_path, keyids, metadata_dir, version) # Generate the 'targets.txt' metadata file. signerlib.build_targets_file([targets_dir], keyids, metadata_dir, version, expiration) # Generate the 'release.txt' metadata file. signerlib.build_release_file(keyids, metadata_dir, version, expiration) # Generate the 'timestamp.txt' metadata file. signerlib.build_timestamp_file(keyids, metadata_dir, version, expiration) # Move the metadata to the client's 'current' and 'previous' directories. shutil.copytree(metadata_dir, current_dir) shutil.copytree(metadata_dir, previous_dir) # The repository is now setup! return keyids
def build_server_repository(server_repository_dir, targets_dir): """ <Purpose> 'build_server_repository' builds a complete repository based on target files provided in the 'targets_dir'. Delegated roles are included. """ # Save the originals of the functions patched by this function. # The patched functions will be restored prior to returning. original_get_metadata = signercli._get_metadata_directory original_prompt = signercli._prompt original_get_password = signercli._get_password original_get_keyids = signercli._get_keyids # The expiration date for created metadata, required by the 'signercli.py' # script. The expiration date is set to 259200 seconds ahead of the current # time. Set all the metadata versions numbers to 1. expiration_date = tuf.formats.format_time(time.time() + 259200) expiration_date = expiration_date[0:expiration_date.rfind(' UTC')] version = 1 server_metadata_dir = os.path.join(server_repository_dir, 'metadata') keystore_dir = os.path.join(server_repository_dir, 'keystore') # Remove 'server_metadata_dir' and 'keystore_dir' if they already exist. if os.path.exists(server_metadata_dir): shutil.rmtree(server_metadata_dir) if os.path.exists(keystore_dir): shutil.rmtree(keystore_dir) # Make metadata directory inside server repository dir. os.mkdir(server_metadata_dir) # Make a keystore directory inside server's repository and populate it. os.mkdir(keystore_dir) _create_keystore(keystore_dir) # Build config file. build_config = signerlib.build_config_file top_level_role_info = unittest_toolbox.Modified_TestCase.top_level_role_info config_filepath = build_config(server_repository_dir, 365, top_level_role_info) # BUILD ROLE FILES. # Build root file. signerlib.build_root_file(config_filepath, role_keyids['root'], server_metadata_dir, version) # Build targets file. signerlib.build_targets_file([targets_dir], role_keyids['targets'], server_metadata_dir, version, expiration_date + ' UTC') # MAKE DELEGATIONS. # We will need to patch a few signercli prompts. # Specifically, signercli.make_delegations() asks user input for: # metadata directory, delegated targets directory, parent role, # passwords for parent role's keyids, delegated role's name, and # the keyid to be assigned to the delegated role. Take a look at # signercli's make_delegation() to gain bit more insight in what is # happening. # 'load_key' is a reference to the 'load_keystore_from_keyfiles function'. load_keys = keystore.load_keystore_from_keyfiles # Setup first level delegated role. delegated_level1 = os.path.join(targets_dir, 'delegated_level1') delegated_targets_dir = delegated_level1 parent_role = 'targets' delegated_role_name = 'delegated_role1' signing_keyids = role_keyids['targets/delegated_role1'] # Patching the 'signercli' prompts. # Mock method for signercli._get_metadata_directory(). def _mock_get_metadata_directory(): return server_metadata_dir # Mock method for signercli._prompt(). def _mock_prompt(msg, junk): if msg.startswith('\nThe paths entered'): return delegated_targets_dir elif msg.startswith('\nChoose and enter the parent'): return parent_role elif msg.startswith('\nEnter the delegated role\'s name: '): return delegated_role_name elif msg.startswith('\nCurrent time:'): return expiration_date else: error_msg = ('Prompt: ' + '\'' + msg + '\'' + ' did not match any predefined mock prompts.') sys.exit(error_msg) # Mock method for signercli._get_password(). def _mock_get_password(msg): for keyid in unittest_toolbox.Modified_TestCase.rsa_keyids: if msg.endswith('(' + keyid + '): '): return unittest_toolbox.Modified_TestCase.rsa_passwords[keyid] # Method to patch signercli._get_keyids() def _mock_get_keyids(junk): if signing_keyids: for keyid in signing_keyids: password = unittest_toolbox.Modified_TestCase.rsa_passwords[ keyid] # Load the keyfile. load_keys(keystore_dir, [keyid], [password]) return signing_keyids # Patch signercli._get_metadata_directory(). signercli._get_metadata_directory = _mock_get_metadata_directory # 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 # Clear kestore's dictionaries, by detaching them from unittest_toolbox's # dictionaries. keystore._keystore = {} keystore._derived_keys = {} # Make first level delegation. signercli.make_delegation(keystore_dir) # Setup second level delegated role. delegated_level2 = os.path.join(delegated_level1, 'delegated_level2') delegated_targets_dir = delegated_level2 parent_role = 'targets/delegated_role1' delegated_role_name = 'delegated_role2' signing_keyids = role_keyids['targets/delegated_role1/delegated_role2'] # Clear kestore's dictionaries. keystore.clear_keystore() # Make second level delegation. signercli.make_delegation(keystore_dir) keystore._keystore = unittest_toolbox.Modified_TestCase.rsa_keystore keystore._derived_keys = unittest_toolbox.Modified_TestCase.rsa_passwords # Build release file. signerlib.build_release_file(role_keyids['release'], server_metadata_dir, version, expiration_date + ' UTC') # Build timestamp file. signerlib.build_timestamp_file(role_keyids['timestamp'], server_metadata_dir, version, expiration_date + ' UTC') keystore._keystore = {} keystore._derived_keys = {} # RESTORE signercli._get_metadata_directory = original_get_metadata signercli._prompt = original_prompt signercli._get_password = original_get_password signercli._get_keyids = original_get_keyids
def setUp(self): """ The target delegations tree is fixed as such: targets -> [T1, T2] T1 -> [T3] """ global version version = version+1 expiration = tuf.formats.format_time(time.time()+86400) root_repo, url, server_proc, keyids = util_test_tools.init_repo(tuf=True) # Server side repository. tuf_repo = os.path.join(root_repo, 'tuf_repo') keystore_dir = os.path.join(tuf_repo, 'keystore') metadata_dir = os.path.join(tuf_repo, 'metadata') targets_dir = os.path.join(tuf_repo, 'targets') # We need to provide clients with a way to reach the tuf repository. tuf_repo_relpath = os.path.basename(tuf_repo) tuf_url = url+tuf_repo_relpath # Add files to the server side repository. # target1 = 'targets_dir/[random].txt' # target2 = 'targets_dir/[random].txt' add_target = util_test_tools.add_file_to_repository target1_path = add_target(targets_dir, data='target1') target2_path = add_target(targets_dir, data='target2') # Target paths relative to the 'targets_dir'. # Ex: targetX = 'targets/delegator/delegatee.txt' target1 = os.path.relpath(target1_path, tuf_repo) target2 = os.path.relpath(target2_path, tuf_repo) # Relative to repository's targets directory. target_filepaths = [target1, target2] # Store in self only the variables relevant for tests. self.root_repo = root_repo self.tuf_repo = tuf_repo self.server_proc = server_proc self.target_filepaths = target_filepaths # Targets delegated from A to B. self.delegated_targets = {} # Targets actually signed by B. self.signed_targets = {} self.mirrors = { "mirror1": { "url_prefix": tuf_url, "metadata_path": "metadata", "targets_path": "targets", "confined_target_dirs": [""] } } # Aliases for targets roles. self.T0 = 'targets' self.T1 = 'targets/T1' self.T2 = 'targets/T2' self.T3 = 'targets/T1/T3' # Get tracked and assigned targets, and generate targets metadata. self.make_targets_metadata() assert hasattr(self, 'T0_metadata') assert hasattr(self, 'T1_metadata') assert hasattr(self, 'T2_metadata') assert hasattr(self, 'T3_metadata') # Make delegation directories at the server's repository. metadata_targets_dir = os.path.join(metadata_dir, 'targets') metadata_T1_dir = os.path.join(metadata_targets_dir, 'T1') os.makedirs(metadata_T1_dir) # Delegations metadata paths for the 3 delegated targets roles. T0_path = os.path.join(metadata_dir, 'targets.txt') T1_path = os.path.join(metadata_targets_dir, 'T1.txt') T2_path = os.path.join(metadata_targets_dir, 'T2.txt') T3_path = os.path.join(metadata_T1_dir, 'T3.txt') # Generate RSA keys for the 3 delegatees. key1 = signerlib.generate_and_save_rsa_key(keystore_dir, 'T1') key2 = signerlib.generate_and_save_rsa_key(keystore_dir, 'T2') key3 = signerlib.generate_and_save_rsa_key(keystore_dir, 'T3') # ID for each of the 3 keys. key1_id = key1['keyid'] key2_id = key2['keyid'] key3_id = key3['keyid'] # ID, in a list, for each of the 3 keys. key1_ids = [key1_id] key2_ids = [key2_id] key3_ids = [key3_id] # Public-key JSON for each of the 3 keys. key1_val = tuf.rsa_key.create_in_metadata_format(key1['keyval']) key2_val = tuf.rsa_key.create_in_metadata_format(key2['keyval']) key3_val = tuf.rsa_key.create_in_metadata_format(key3['keyval']) # Create delegation role metadata for each of the 3 delegated targets roles. make_role_metadata = tuf.formats.make_role_metadata T1_targets = self.relpath_from_targets(self.delegated_targets[self.T1]) T1_role = make_role_metadata(key1_ids, 1, name=self.T1, paths=T1_targets) T2_targets = self.relpath_from_targets(self.delegated_targets[self.T2]) T2_role = make_role_metadata(key2_ids, 1, name=self.T2, paths=T2_targets) T3_targets = self.relpath_from_targets(self.delegated_targets[self.T3]) T3_role = make_role_metadata(key3_ids, 1, name=self.T3, paths=T3_targets) # Assign 'delegations' object for 'targets': self.T0_metadata['signed']['delegations'] = { 'keys': {key1_id: key1_val, key2_id: key2_val}, 'roles': [T1_role, T2_role] } # Assign 'delegations' object for 'targets/T1': self.T1_metadata['signed']['delegations'] = { 'keys': {key3_id: key3_val}, 'roles': [T3_role] } sign = signerlib.sign_metadata write = signerlib.write_metadata_file # Sign new metadata objects. T0_signable = sign(self.T0_metadata, keyids, T0_path) T1_signable = sign(self.T1_metadata, key1_ids, T1_path) T2_signable = sign(self.T2_metadata, key2_ids, T2_path) T3_signable = sign(self.T3_metadata, key3_ids, T3_path) # Save new metadata objects. write(T0_signable, T0_path) write(T1_signable, T1_path) write(T2_signable, T2_path) write(T3_signable, T3_path) # Timestamp a new release to reflect latest targets. signerlib.build_release_file(keyids, metadata_dir, version, expiration) signerlib.build_timestamp_file(keyids, metadata_dir, version, expiration) # Unload all keys. keystore.clear_keystore()
def build_server_repository(server_repository_dir, targets_dir): # Make metadata directory inside client and server repository dir. server_metadata_dir = os.path.join(server_repository_dir, 'metadata') os.mkdir(server_metadata_dir) # Make a keystore directory inside server's repository and populate it. keystore_dir = os.path.join(server_repository_dir, 'keystore') os.mkdir(keystore_dir) create_keystore(keystore_dir) # Build config file. build_config = signerlib.build_config_file config_filepath = build_config(server_repository_dir, 365, TestCase_Tools.top_level_role_info) # Role:keyids dictionary. role_keyids = {} for role in TestCase_Tools.semi_roledict.keys(): role_keyids[role] = TestCase_Tools.semi_roledict[role]['keyids'] # BUILD ROLE FILES. # Build root file. signerlib.build_root_file(config_filepath, role_keyids['root'], server_metadata_dir) # Build targets file. signerlib.build_targets_file(targets_dir, role_keyids['targets'], server_metadata_dir) # Build release file. signerlib.build_release_file(role_keyids['release'], server_metadata_dir) # Build timestamp file. signerlib.build_timestamp_file(role_keyids['timestamp'], server_metadata_dir) # MAKE DELEGATIONS. # We will need to patch a few signercli prompts. # Specifically, signercli.make_delegations() asks user input for: # metadata directory, delegated targets directory, parent role, # passwords for parent role's keyids, delegated role's name, and # the keyid to be assigned to the delegated role. Take a look at # signercli's make_delegation() to gain bit more insight in what is # happening. # 'load_key' is a reference to the 'load_keystore_from_keyfiles function'. load_keys = keystore.load_keystore_from_keyfiles # Setup first level delegated role. delegated_level1 = os.path.join(targets_dir, 'delegated_level1') delegated_targets_dir = delegated_level1 parent_role = 'targets' delegated_role_name = 'delegated_role1' signing_keyids = role_keyids['targets/delegated_role1'] # Patching the prompts. # Mock method for signercli._get_metadata_directory(). def _mock_get_metadata_directory(): return server_metadata_dir # Mock method for signercli._prompt(). def _mock_prompt(msg, junk): if msg.startswith('\nNOTE: The 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_name else: error_msg = ('Prompt: '+'\''+msg+'\''+ ' did not match any predefined mock prompts.') sys.exit(error_msg) # Mock method for signercli._get_password(). def _mock_get_password(msg): for keyid in TestCase_Tools.rsa_keyids: if msg.endswith('('+keyid+'): '): return TestCase_Tools.rsa_passwords[keyid] # Method to patch signercli._get_keyids() def _mock_get_keyids(junk): if signing_keyids: for keyid in signing_keyids: password = TestCase_Tools.rsa_passwords[keyid] # Load the keyfile. load_keys(keystore_dir, [keyid], [password]) return signing_keyids # Patch signercli._get_metadata_directory(). signercli._get_metadata_directory = _mock_get_metadata_directory # 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 # Clear kestore's dictionaries, by detaching them from unittest_toolbox's # dictionaries. keystore._keystore = {} keystore._key_passwords = {} # Make first level delegation. signercli.make_delegation(keystore_dir) # Setup first level delegated role. delegated_level2 = os.path.join(delegated_level1, 'delegated_level2') delegated_targets_dir = delegated_level2 parent_role = 'targets/delegated_role1' delegated_role_name = 'delegated_role2' signing_keyids = role_keyids['targets/delegated_role1/delegated_role2'] # Clear kestore's dictionaries. keystore.clear_keystore() # Make second level delegation. signercli.make_delegation(keystore_dir)
def init_tuf(root_repo): """ <Purpose> Setup TUF directory structure and populated it with TUF metadata and congfiguration files. """ threshold = 1 global version version = version + 1 expiration = tuf.formats.format_time(time.time() + 86400) # Setup TUF-repo directory structure. tuf_repo = os.path.join(root_repo, 'tuf_repo') keystore_dir = os.path.join(tuf_repo, 'keystore') metadata_dir = os.path.join(tuf_repo, 'metadata') targets_dir = os.path.join(tuf_repo, 'targets') os.mkdir(tuf_repo) os.mkdir(keystore_dir) os.mkdir(metadata_dir) shutil.copytree(os.path.join(root_repo, 'reg_repo'), targets_dir) # Setting TUF-client directory structure. # 'tuf.client.updater.py' expects the 'current' and 'previous' # directories to exist under client's 'metadata' directory. tuf_client = os.path.join(root_repo, 'tuf_client') tuf_client_metadata_dir = os.path.join(tuf_client, 'metadata') current_dir = os.path.join(tuf_client_metadata_dir, 'current') previous_dir = os.path.join(tuf_client_metadata_dir, 'previous') os.makedirs(tuf_client_metadata_dir) # Generate at least one rsa key. key = signerlib.generate_and_save_rsa_key(keystore_dir, PASSWD) keyids = [key['keyid']] # Set role info. info = {'keyids': [key['keyid']], 'threshold': threshold} # 'role_info' dictionary looks like this: # {role : {'keyids : [keyid1, ...] , 'threshold' : 1}} # In our case 'role_info[keyids]' will only have on entry since only one # is being used. role_info = {} role_list = ['root', 'targets', 'release', 'timestamp'] for role in role_list: role_info[role] = info # At this point there is enough information to create TUF configuration # and metadata files. # Build the configuration file. conf_path = signerlib.build_config_file(metadata_dir, 365, role_info) # Generate the 'root.txt' metadata file. signerlib.build_root_file(conf_path, keyids, metadata_dir, version) # Generate the 'targets.txt' metadata file. signerlib.build_targets_file([targets_dir], keyids, metadata_dir, version, expiration) # Generate the 'release.txt' metadata file. signerlib.build_release_file(keyids, metadata_dir, version, expiration) # Generate the 'timestamp.txt' metadata file. signerlib.build_timestamp_file(keyids, metadata_dir, version, expiration) # Move the metadata to the client's 'current' and 'previous' directories. shutil.copytree(metadata_dir, current_dir) shutil.copytree(metadata_dir, previous_dir) # The repository is now setup! return keyids
def init_tuf(root_repo, url, port): """ <Purpose> Setup TUF directory structure and populated it with TUF metadata and congfiguration files. """ passwd = 'test' threshold = 1 # Setup TUF-repo directory structure. tuf_repo = os.path.join(root_repo, 'tuf_repo') keystore_dir = os.path.join(tuf_repo, 'keystore') metadata_dir = os.path.join(tuf_repo, 'metadata') targets_dir = os.path.join(tuf_repo, 'targets') os.mkdir(tuf_repo) os.mkdir(keystore_dir) os.mkdir(metadata_dir) shutil.copytree(os.path.join(root_repo, 'reg_repo'), targets_dir) # Setting TUF-client directory structure. # 'tuf.client.updater.py' expects the 'current' and 'previous' # directories to exist under client's 'metadata' directory. tuf_client = os.path.join(root_repo, 'tuf_client') tuf_client_metadata_dir = os.path.join(tuf_client, 'metadata') current_dir = os.path.join(tuf_client_metadata_dir, 'current') previous_dir = os.path.join(tuf_client_metadata_dir, 'previous') os.makedirs(tuf_client_metadata_dir) # Generate at least one rsa key. key = signerlib.generate_and_save_rsa_key(keystore_dir, passwd) keyids = [key['keyid']] # Set role info. info = {'keyids': [key['keyid']], 'threshold': threshold} # 'role_info' dictionary looks like this: # {role : {'keyids : [keyid1, ...] , 'threshold' : 1}} # In our case 'role_info[keyids]' will only have on entry since only one # is being used. role_info = {} role_list = ['root', 'targets', 'release', 'timestamp'] for role in role_list: role_info[role] = info # At this point there is enough information to create TUF configuration # and metadata files. # Build the configuration file. conf_path = signerlib.build_config_file(metadata_dir, 365, role_info) # Generate the 'root.txt' metadata file. signerlib.build_root_file(conf_path, keyids, metadata_dir) # Generate the 'targets.txt' metadata file. signerlib.build_targets_file(targets_dir, keyids, metadata_dir) # Generate the 'release.txt' metadata file. signerlib.build_release_file(keyids, metadata_dir) # Generate the 'timestamp.txt' metadata file. signerlib.build_timestamp_file(keyids, metadata_dir) # Move the metadata to the client's 'current' and 'previous' directories. shutil.copytree(metadata_dir, current_dir) shutil.copytree(metadata_dir, previous_dir) # The repository is now setup! # Here is a mirrors dictionary that will allow a client to seek out # places to download the metadata and targets from. tuf_repo_relpath = os.path.basename(tuf_repo) tuf_url = url+tuf_repo_relpath mirrors = {'mirror1': {'url_prefix': tuf_url, 'metadata_path': 'metadata', 'targets_path': 'targets', 'confined_target_dirs': ['']}} # Adjusting configuration file (tuf.conf.py). tuf.conf.repository_directory = tuf_client # In order to implement interposition we need to have a config file with # the following dictionary JSON-serialized. # tuf_url: http://localhost:port/root_repo/tuf_repo/ hostname = 'localhost:9999' interposition_dict = {"configurations": {hostname: {"repository_directory": tuf_client+'/', "repository_mirrors" : {"mirror1": {"url_prefix": tuf_url, "metadata_path": "metadata", "targets_path": "targets", "confined_target_dirs": [ "" ]}}}}} # "target_paths": [ { "(.*\\.html)": "{0}" } ] junk, interpose_json = tempfile.mkstemp(prefix='conf_', dir=root_repo) with open(interpose_json, 'wb') as fileobj: tuf.util.json.dump(interposition_dict, fileobj) tuf.interposition.configure(filename=interpose_json) return keyids
def build_server_repository(server_repository_dir, targets_dir): """ <Purpose> 'build_server_repository' builds a complete repository based on target files provided in the 'targets_dir'. Delegated roles are included. """ # Save the originals of the functions patched by this function. # The patched functions will be restored prior to returning. original_get_metadata = signercli._get_metadata_directory original_prompt = signercli._prompt original_get_password = signercli._get_password original_get_keyids = signercli._get_keyids server_metadata_dir = os.path.join(server_repository_dir, 'metadata') keystore_dir = os.path.join(server_repository_dir, 'keystore') # Remove 'server_metadata_dir' and 'keystore_dir' if they already exist. if os.path.exists(server_metadata_dir): shutil.rmtree(server_metadata_dir) if os.path.exists(keystore_dir): shutil.rmtree(keystore_dir) # Make metadata directory inside server repository dir. os.mkdir(server_metadata_dir) # Make a keystore directory inside server's repository and populate it. os.mkdir(keystore_dir) _create_keystore(keystore_dir) # Build config file. build_config = signerlib.build_config_file top_level_role_info = unittest_toolbox.Modified_TestCase.top_level_role_info config_filepath = build_config(server_repository_dir, 365, top_level_role_info) # BUILD ROLE FILES. # Build root file. signerlib.build_root_file(config_filepath, role_keyids['root'], server_metadata_dir) # Build targets file. signerlib.build_targets_file(targets_dir, role_keyids['targets'], server_metadata_dir) # MAKE DELEGATIONS. # We will need to patch a few signercli prompts. # Specifically, signercli.make_delegations() asks user input for: # metadata directory, delegated targets directory, parent role, # passwords for parent role's keyids, delegated role's name, and # the keyid to be assigned to the delegated role. Take a look at # signercli's make_delegation() to gain bit more insight in what is # happening. # 'load_key' is a reference to the 'load_keystore_from_keyfiles function'. load_keys = keystore.load_keystore_from_keyfiles # Setup first level delegated role. delegated_level1 = os.path.join(targets_dir, 'delegated_level1') delegated_targets_dir = delegated_level1 parent_role = 'targets' delegated_role_name = 'delegated_role1' signing_keyids = role_keyids['targets/delegated_role1'] # Patching the 'signercli' prompts. # Mock method for signercli._get_metadata_directory(). def _mock_get_metadata_directory(): return server_metadata_dir # 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_name else: error_msg = ('Prompt: '+'\''+msg+'\''+ ' did not match any predefined mock prompts.') sys.exit(error_msg) # Mock method for signercli._get_password(). def _mock_get_password(msg): for keyid in unittest_toolbox.Modified_TestCase.rsa_keyids: if msg.endswith('('+keyid+'): '): return unittest_toolbox.Modified_TestCase.rsa_passwords[keyid] # Method to patch signercli._get_keyids() def _mock_get_keyids(junk): if signing_keyids: for keyid in signing_keyids: password = unittest_toolbox.Modified_TestCase.rsa_passwords[keyid] # Load the keyfile. load_keys(keystore_dir, [keyid], [password]) return signing_keyids # Patch signercli._get_metadata_directory(). signercli._get_metadata_directory = _mock_get_metadata_directory # 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 # Clear kestore's dictionaries, by detaching them from unittest_toolbox's # dictionaries. keystore._keystore = {} keystore._key_passwords = {} # Make first level delegation. signercli.make_delegation(keystore_dir) # Setup second level delegated role. delegated_level2 = os.path.join(delegated_level1, 'delegated_level2') delegated_targets_dir = delegated_level2 parent_role = 'targets/delegated_role1' delegated_role_name = 'delegated_role2' signing_keyids = role_keyids['targets/delegated_role1/delegated_role2'] # Clear kestore's dictionaries. keystore.clear_keystore() # Make second level delegation. signercli.make_delegation(keystore_dir) keystore._keystore = unittest_toolbox.Modified_TestCase.rsa_keystore keystore._key_passwords = unittest_toolbox.Modified_TestCase.rsa_passwords # Build release file. signerlib.build_release_file(role_keyids['release'], server_metadata_dir) # Build timestamp file. signerlib.build_timestamp_file(role_keyids['timestamp'], server_metadata_dir) keystore._keystore = {} keystore._key_passwords = {} # RESTORE signercli._get_metadata_directory = original_get_metadata signercli._prompt = original_prompt signercli._get_password = original_get_password signercli._get_keyids = original_get_keyids
def setUp(self): """ The target delegations tree is fixed as such: targets -> [T1, T2] T1 -> [T3] """ global version version = version + 1 expiration = tuf.formats.format_time(time.time() + 86400) root_repo, url, server_proc, keyids = util_test_tools.init_repo( tuf=True) # Server side repository. tuf_repo = os.path.join(root_repo, 'tuf_repo') keystore_dir = os.path.join(tuf_repo, 'keystore') metadata_dir = os.path.join(tuf_repo, 'metadata') targets_dir = os.path.join(tuf_repo, 'targets') # We need to provide clients with a way to reach the tuf repository. tuf_repo_relpath = os.path.basename(tuf_repo) tuf_url = url + tuf_repo_relpath # Add files to the server side repository. # target1 = 'targets_dir/[random].txt' # target2 = 'targets_dir/[random].txt' add_target = util_test_tools.add_file_to_repository target1_path = add_target(targets_dir, data='target1') target2_path = add_target(targets_dir, data='target2') # Target paths relative to the 'targets_dir'. # Ex: targetX = 'targets/delegator/delegatee.txt' target1 = os.path.relpath(target1_path, tuf_repo) target2 = os.path.relpath(target2_path, tuf_repo) # Relative to repository's targets directory. target_filepaths = [target1, target2] # Store in self only the variables relevant for tests. self.root_repo = root_repo self.tuf_repo = tuf_repo self.server_proc = server_proc self.target_filepaths = target_filepaths # Targets delegated from A to B. self.delegated_targets = {} # Targets actually signed by B. self.signed_targets = {} self.mirrors = { "mirror1": { "url_prefix": tuf_url, "metadata_path": "metadata", "targets_path": "targets", "confined_target_dirs": [""] } } # Aliases for targets roles. self.T0 = 'targets' self.T1 = 'targets/T1' self.T2 = 'targets/T2' self.T3 = 'targets/T1/T3' # Get tracked and assigned targets, and generate targets metadata. self.make_targets_metadata() assert hasattr(self, 'T0_metadata') assert hasattr(self, 'T1_metadata') assert hasattr(self, 'T2_metadata') assert hasattr(self, 'T3_metadata') # Make delegation directories at the server's repository. metadata_targets_dir = os.path.join(metadata_dir, 'targets') metadata_T1_dir = os.path.join(metadata_targets_dir, 'T1') os.makedirs(metadata_T1_dir) # Delegations metadata paths for the 3 delegated targets roles. T0_path = os.path.join(metadata_dir, 'targets.txt') T1_path = os.path.join(metadata_targets_dir, 'T1.txt') T2_path = os.path.join(metadata_targets_dir, 'T2.txt') T3_path = os.path.join(metadata_T1_dir, 'T3.txt') # Generate RSA keys for the 3 delegatees. key1 = signerlib.generate_and_save_rsa_key(keystore_dir, 'T1') key2 = signerlib.generate_and_save_rsa_key(keystore_dir, 'T2') key3 = signerlib.generate_and_save_rsa_key(keystore_dir, 'T3') # ID for each of the 3 keys. key1_id = key1['keyid'] key2_id = key2['keyid'] key3_id = key3['keyid'] # ID, in a list, for each of the 3 keys. key1_ids = [key1_id] key2_ids = [key2_id] key3_ids = [key3_id] # Public-key JSON for each of the 3 keys. key1_val = tuf.rsa_key.create_in_metadata_format(key1['keyval']) key2_val = tuf.rsa_key.create_in_metadata_format(key2['keyval']) key3_val = tuf.rsa_key.create_in_metadata_format(key3['keyval']) # Create delegation role metadata for each of the 3 delegated targets roles. make_role_metadata = tuf.formats.make_role_metadata T1_targets = self.relpath_from_targets(self.delegated_targets[self.T1]) T1_role = make_role_metadata(key1_ids, 1, name=self.T1, paths=T1_targets) T2_targets = self.relpath_from_targets(self.delegated_targets[self.T2]) T2_role = make_role_metadata(key2_ids, 1, name=self.T2, paths=T2_targets) T3_targets = self.relpath_from_targets(self.delegated_targets[self.T3]) T3_role = make_role_metadata(key3_ids, 1, name=self.T3, paths=T3_targets) # Assign 'delegations' object for 'targets': self.T0_metadata['signed']['delegations'] = { 'keys': { key1_id: key1_val, key2_id: key2_val }, 'roles': [T1_role, T2_role] } # Assign 'delegations' object for 'targets/T1': self.T1_metadata['signed']['delegations'] = { 'keys': { key3_id: key3_val }, 'roles': [T3_role] } sign = signerlib.sign_metadata write = signerlib.write_metadata_file # Sign new metadata objects. T0_signable = sign(self.T0_metadata, keyids, T0_path) T1_signable = sign(self.T1_metadata, key1_ids, T1_path) T2_signable = sign(self.T2_metadata, key2_ids, T2_path) T3_signable = sign(self.T3_metadata, key3_ids, T3_path) # Save new metadata objects. write(T0_signable, T0_path) write(T1_signable, T1_path) write(T2_signable, T2_path) write(T3_signable, T3_path) # Timestamp a new release to reflect latest targets. signerlib.build_release_file(keyids, metadata_dir, version, expiration) signerlib.build_timestamp_file(keyids, metadata_dir, version, expiration) # Unload all keys. keystore.clear_keystore()