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)
示例#2
0
  def test_1__sign_and_write_metadata(self):

    # SETUP
    #  Role to test.
    role = 'root'

    #  Create temp directory.
    temp_dir = self.make_temp_directory()

    #  File name.
    filename = os.path.join(temp_dir, role+'.txt')

    #  Role's keyids.
    keyids = self.top_level_role_info[role]['keyids']

    #  Create a temp keystore directory.
    keystore_dir =\
        self.create_temp_keystore_directory(keystore_dicts=True)

    #  Create temp directory for config file.
    config_dir = self.make_temp_directory()

    #  Build config file.
    config_filepath = signerlib.build_config_file(config_dir, 365,
                                                  self.top_level_role_info)

    #  Create role's metadata.
    signable_meta = signerlib.generate_root_metadata(config_filepath)


    # TESTS
    #  Test: normal case.
    signercli._sign_and_write_metadata(signable_meta, keyids, filename)

    #  Verify that the root meta file was created.
    self.assertTrue(os.path.exists(filename))

    Errors = (tuf.Error, tuf.FormatError)

    #  Test: invalid metadata.
    self.assertRaises(Errors, signercli._sign_and_write_metadata,
                      self.random_string(), keyids, filename)

    #  Test: invalid keyids
    invalid_keyids = self.random_string()
    self.assertRaises(Errors, signercli._sign_and_write_metadata,
                      signable_meta, invalid_keyids, filename)

    #  Test: invalid filename
    self.assertRaises(Errors, signercli._sign_and_write_metadata,
                      signable_meta, invalid_keyids, True)
示例#3
0
  def test_2__get_role_config_keyids(self):

    # SETUP
    original_get_password = signercli._get_password
    
    #  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 keystore directory.
    keystore_dir = self.create_temp_keystore_directory()

    #  Patch '_get_password' method.
    self.get_passwords()


    # TESTS
    for role in self.role_list:
      #  Test: normal cases.
      keystore.clear_keystore()
      signercli._get_role_config_keyids(config_filepath, keystore_dir, role)
      
      #  Test: incorrect passwords.
      keystore.clear_keystore()
      role_keyids = self.top_level_role_info[role]['keyids']
      for keyid in role_keyids:
        saved_pw = self.rsa_passwords[keyid]
        self.rsa_passwords[keyid] = self.random_string()
        self.assertRaises(tuf.Error, signercli._get_role_config_keyids,
            config_filepath, keystore_dir, role)

        #    Restore the password.
        self.rsa_passwords[keyid] = saved_pw

    #  Test: non-existing config file path.
    keystore.clear_keystore()
    self.assertRaises(tuf.Error, signercli._get_role_config_keyids,
        self.random_path(), keystore_dir, 'release')

    #  Test: non-existing role.
    keystore.clear_keystore()
    self.assertRaises(tuf.Error, signercli._get_role_config_keyids,
                      config_filepath, keystore_dir, 'no_such_role')

    # RESTORE
    signercli._get_password = original_get_password
示例#4
0
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)
示例#5
0
  def _get_role_info(self, role, directory=None):
    """
    This method generates role's metadata dictionary, it uses previously
    tested signerlib's methods.  Note that at everything maintains the order.
    Nothing that has not been tested previously is used in any of the
    following conditions.

    <Arguments>
      directory:
        Directory of a config file.

    <Returns>
      Tuple (role's metadata(not signed), role's keyids, directory, optional)

    """
    
    # The version number and expiration date for metadata files created.
    version = 8
    expiration_date = '1985-10-26 01:20:00 UTC'


    if not directory:
      # Create a temp directory to hold a config file.
      directory = self.make_temp_directory()

    # Get role's keyids.
    role_keyids = self.top_level_role_info[role]['keyids']


    if role == 'root':
      #  Create config file using previously tested build_config_file().
      config_path = signerlib.build_config_file(directory, 365,
                                                self.top_level_role_info)

      #  Patch keystore's get_key method.
      tuf.repo.keystore.get_key = self.get_keystore_key

      #  Create root metadata.
      root_meta = signerlib.generate_root_metadata(config_path, version)
      return root_meta, role_keyids, directory, config_path

    elif role == 'targets':
      # Generate target files.
      # 'repo_dir' represents repository base.
      # 'target_files' represents a list of relative target paths.
      repo_dir, target_files = \
          self.make_temp_directory_with_data_files(directory=directory)

      #  Patch keystore's get_key method.
      tuf.repo.keystore.get_key = self.get_keystore_key
      
      # Run the 'signerlib.generate_targets_metadata'.  Test its return value.
      # Its return value should correspond to tuf.formats.SIGNABLE_SCHEMA
      targets_meta = signerlib.generate_targets_metadata(repo_dir, target_files,
                                                         version, 
                                                         expiration_date)
      return targets_meta, role_keyids, repo_dir, target_files

    elif role == 'release':
      # Generate 'root.txt' and 'targets.txt' with targets directory in
      # the repository containing files and directories.
      meta_dir = self._create_root_and_targets_meta_files()
      release_meta = signerlib.generate_release_metadata(meta_dir, version,
                                                         expiration_date)
      return release_meta, role_keyids, meta_dir

    elif role == 'timestamp':
      # Generate 'release.txt' which includes creation of 'root.txt',
      # 'targets.txt' and target files.
      junk, release_keyids, meta_dir = self._get_role_info('release')
      signerlib.build_release_file(release_keyids, meta_dir, version,
                                   expiration_date)
      release_filepath = os.path.join(meta_dir, 'release.txt')

      # Generate timestamp metadata.
      timestamp_meta = signerlib.generate_timestamp_metadata(release_filepath,
                                                             version,
                                                             expiration_date)
      return timestamp_meta, role_keyids, meta_dir

    else:
      logger.warning('\nUnrecognized top-level role.')
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
示例#7
0
  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
示例#8
0
  def test_3_make_root_metadata(self):

    # SETUP
    original_get_metadata_directory = signercli._get_metadata_directory
    original_prompt = signercli._prompt
    original_get_password = signercli._get_password
    
    #  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 signercli._get_password().
    self.get_passwords()

    #  Create keystore directory.
    keystore_dir = self.create_temp_keystore_directory()


    # TESTS
    #  Test: normal case.
    signercli.make_root_metadata(keystore_dir)

    #  Verify that the root metadata path was created.
    self.assertTrue(os.path.exists(os.path.join(meta_dir, 'root.txt')))

    #  Test: invalid config path.
    #  Clear keystore's dictionaries.
    keystore.clear_keystore()

    #  Supply a non-existing path to signercli._prompt().
    self.mock_prompt(self.random_path())
    self.assertRaises(tuf.RepositoryError, signercli.make_root_metadata,
                      keystore_dir)

    #  Re-patch signercli._prompt() with valid config path.
    self.mock_prompt(config_filepath)

    #  Test: incorrect 'root' passwords.
    #  Clear keystore's dictionaries.
    keystore.clear_keystore()
    keyids = self.top_level_role_info['root']['keyids']
    for keyid in keyids:
      saved_pw = self.rsa_passwords[keyid]
      self.rsa_passwords[keyid] = self.random_string()
      self.assertRaises(tuf.RepositoryError, signercli.make_root_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
示例#9
0
  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
示例#10
0
  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
示例#11
0
  def test_2__get_all_config_keyids(self):

    # SETUP
    original_get_password = signercli._get_password
    
    #  Create temp directory for config file.
    config_dir = self.make_temp_directory()

    #  Build the config file needed by '_get_all_config_keyids.
    config_filepath = signerlib.build_config_file(config_dir, 365,
                                                  self.top_level_role_info)

    #  Create a temp keystore directory.
    keystore_dir = self.create_temp_keystore_directory()

    #  'sample_keyid' used to test invalid keyid.
    sample_keyid = self.rsa_keyids[0]

    #  Patch signercli._get_password()
    self.get_passwords()


    # TESTS
    #  Test: an incorrect password.
    saved_pw = self.rsa_passwords[sample_keyid]
    self.rsa_passwords[sample_keyid] = self.random_string()
    self.assertRaises(tuf.Error, signercli._get_all_config_keyids,
                      config_filepath, keystore_dir)

    #  Restore the password.
    self.rsa_passwords[sample_keyid] = saved_pw

    #  Test: missing top-level role in the config file.
    #    Clear keystore's dictionaries.
    keystore.clear_keystore()

    #    Remove a role from 'top_level_role_info' which is used to construct
    #    config file.
    targets_holder = self.top_level_role_info['targets']
    del self.top_level_role_info['targets']

    #    Build config file without 'targets' role.
    config_filepath = signerlib.build_config_file(config_dir, 365,
                                                  self.top_level_role_info)
    self.assertRaises(tuf.Error, signercli._get_all_config_keyids,
                      config_filepath, keystore_dir)

    #    Rebuild config file and 'top_level_role_info'.
    self.top_level_role_info['targets'] = targets_holder
    config_filepath = signerlib.build_config_file(config_dir, 365,
                                                  self.top_level_role_info)

    #  Test: non-existing config file path.
    keystore.clear_keystore()
    self.assertRaises(tuf.Error, signercli._get_all_config_keyids,
                      self.random_path(), keystore_dir)

    #  Test: normal case.
    keystore.clear_keystore()
    signercli._get_all_config_keyids(config_filepath, keystore_dir)

    # RESTORE
    signercli._get_password = original_get_password
示例#12
0
  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
示例#13
0
  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 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
示例#15
0
  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
示例#16
0
    def _get_role_info(self, role, directory=None):
        """
    This method generates role's metadata dictionary, it uses previously
    tested signerlib's methods.  Note that at everything maintains the order.
    Nothing that has not been tested previously is used in any of the
    following conditions.

    <Arguments>
      directory:
        Directory of a config file.

    <Returns>
      Tuple (role's metadata(not signed), role's keyids, directory, optional)

    """

        if not directory:
            # Create a temp directory to hold a config file.
            directory = self.make_temp_directory()

        # Get role's keyids.
        role_keyids = self.top_level_role_info[role]["keyids"]

        if role == "root":
            #  Create config file using previously tested build_config_file().
            config_path = signerlib.build_config_file(directory, 365, self.top_level_role_info)

            #  Patch keystore's get_key method.
            tuf.repo.keystore.get_key = self.get_keystore_key

            #  Create root metadata.
            root_meta = signerlib.generate_root_metadata(config_path)
            return root_meta, role_keyids, directory, config_path

        elif role == "targets":
            # Generate target files.
            # 'repo_dir' represents repository base.
            # 'target_files' represents a list of relative target paths.
            repo_dir, target_files = self.make_temp_directory_with_data_files(directory=directory)

            #  Patch keystore's get_key method.
            tuf.repo.keystore.get_key = self.get_keystore_key

            # Run the 'signerlib.generate_targets_metadata'.  Test its return value.
            # Its return value should correspond to tuf.formats.SIGNABLE_SCHEMA
            targets_meta = signerlib.generate_targets_metadata(repo_dir, target_files)
            return targets_meta, role_keyids, repo_dir, target_files

        elif role == "release":
            # Generate 'root.txt' and 'targets.txt' with targets directory in
            # the repository containing files and directories.
            meta_dir = self._create_root_and_targets_meta_files()
            release_meta = signerlib.generate_release_metadata(meta_dir)
            return release_meta, role_keyids, meta_dir

        elif role == "timestamp":
            # Generate 'release.txt' which includes creation of 'root.txt',
            # 'targets.txt' and target files.
            junk, release_keyids, meta_dir = self._get_role_info("release")
            signerlib.build_release_file(release_keyids, meta_dir)
            release_filepath = os.path.join(meta_dir, "release.txt")

            # Generate timestamp metadata.
            timestamp_meta = signerlib.generate_timestamp_metadata(release_filepath)
            return timestamp_meta, role_keyids, meta_dir

        else:
            print "\nUnrecognized top-level role."
示例#17
0
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