예제 #1
0
  def test_sign_metadata(self):
    # Test normal case.
    repository_name = 'test_repository'
    temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory)
    metadata_path = os.path.join('repository_data', 'repository', 'metadata')
    keystore_path = os.path.join('repository_data', 'keystore')
    root_filename = os.path.join(metadata_path, 'root.json')
    root_metadata = securesystemslib.util.load_json_file(root_filename)['signed']
    targets_filename = os.path.join(metadata_path, 'targets.json')
    targets_metadata = securesystemslib.util.load_json_file(targets_filename)['signed']

    tuf.keydb.create_keydb_from_root_metadata(root_metadata, repository_name)
    tuf.roledb.create_roledb_from_root_metadata(root_metadata, repository_name)
    root_keyids = tuf.roledb.get_role_keyids('root', repository_name)
    targets_keyids = tuf.roledb.get_role_keyids('targets', repository_name)

    root_private_keypath = os.path.join(keystore_path, 'root_key')
    root_private_key = repo_lib.import_rsa_privatekey_from_file(root_private_keypath,
        'password')

    # Sign with a valid, but not a threshold, key.
    targets_public_keypath = os.path.join(keystore_path, 'targets_key.pub')
    targets_public_key = securesystemslib.interface.\
        import_ed25519_publickey_from_file(targets_public_keypath)

    # sign_metadata() expects the private key 'root_metadata' to be in
    # 'tuf.keydb'.  Remove any public keys that may be loaded before
    # adding private key, otherwise a 'tuf.KeyAlreadyExists' exception is
    # raised.
    tuf.keydb.remove_key(root_private_key['keyid'],
        repository_name=repository_name)
    tuf.keydb.add_key(root_private_key, repository_name=repository_name)
    tuf.keydb.remove_key(targets_public_key['keyid'], repository_name=repository_name)
    tuf.keydb.add_key(targets_public_key, repository_name=repository_name)

    # Verify that a valid root signable is generated.
    root_signable = repo_lib.sign_metadata(root_metadata, root_keyids,
        root_filename, repository_name)
    self.assertTrue(tuf.formats.SIGNABLE_SCHEMA.matches(root_signable))

    # Test for an unset private key (in this case, target's).
    repo_lib.sign_metadata(targets_metadata, targets_keyids, targets_filename,
        repository_name)

    # Add an invalid keytype to one of the root keys.
    root_keyid = root_keyids[0]
    tuf.keydb._keydb_dict[repository_name][root_keyid]['keytype'] = 'bad_keytype'
    self.assertRaises(securesystemslib.exceptions.Error, repo_lib.sign_metadata,
        root_metadata, root_keyids, root_filename, repository_name)

    # Test improperly formatted arguments.
    self.assertRaises(securesystemslib.exceptions.FormatError,
        repo_lib.sign_metadata, 3, root_keyids, 'root.json', repository_name)
    self.assertRaises(securesystemslib.exceptions.FormatError,
        repo_lib.sign_metadata, root_metadata, 3, 'root.json', repository_name)
    self.assertRaises(securesystemslib.exceptions.FormatError,
        repo_lib.sign_metadata, root_metadata, root_keyids, 3, repository_name)
예제 #2
0
  def test_sign_metadata(self):
    # Test normal case.
    temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory)
    metadata_path = os.path.join('repository_data',
                                 'repository', 'metadata')
    keystore_path = os.path.join('repository_data',
                                 'keystore')
    root_filename = os.path.join(metadata_path, 'root.json')
    root_metadata = tuf.util.load_json_file(root_filename)['signed']
    
    tuf.keydb.create_keydb_from_root_metadata(root_metadata)
    tuf.roledb.create_roledb_from_root_metadata(root_metadata)
    root_keyids = tuf.roledb.get_role_keyids('root')

    root_private_keypath = os.path.join(keystore_path, 'root_key')
    root_private_key = \
      repo_lib.import_rsa_privatekey_from_file(root_private_keypath, 'password')
    
    # Sign with a valid, but not a threshold, key.
    targets_private_keypath = os.path.join(keystore_path, 'targets_key')
    targets_private_key = \
      repo_lib.import_rsa_privatekey_from_file(targets_private_keypath,
                                               'password')

    # sign_metadata() expects the private key 'root_metadata' to be in
    # 'tuf.keydb'.  Remove any public keys that may be loaded before
    # adding private key, otherwise a 'tuf.KeyAlreadyExists' exception is
    # raised.
    tuf.keydb.remove_key(root_private_key['keyid'])
    tuf.keydb.add_key(root_private_key)
    tuf.keydb.remove_key(targets_private_key['keyid'])
    tuf.keydb.add_key(targets_private_key)
   
    root_keyids.extend(tuf.roledb.get_role_keyids('targets'))
    # Add the snapshot's public key (to test whether non-private keys are
    # ignored by sign_metadata()).
    root_keyids.extend(tuf.roledb.get_role_keyids('snapshot'))
    root_signable = repo_lib.sign_metadata(root_metadata, root_keyids,
                                           root_filename) 
    self.assertTrue(tuf.formats.SIGNABLE_SCHEMA.matches(root_signable))


    # Test improperly formatted arguments.
    self.assertRaises(tuf.FormatError, repo_lib.sign_metadata, 3, root_keyids,
                      'root.json')
    self.assertRaises(tuf.FormatError, repo_lib.sign_metadata, root_metadata,
                      3, 'root.json')
    self.assertRaises(tuf.FormatError, repo_lib.sign_metadata, root_metadata,
                      root_keyids, 3)
예제 #3
0
    def test_sign_metadata(self):
        # Test normal case.
        temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory)
        metadata_path = os.path.join("repository_data", "repository", "metadata")
        keystore_path = os.path.join("repository_data", "keystore")
        root_filename = os.path.join(metadata_path, "root.json")
        root_metadata = tuf.util.load_json_file(root_filename)["signed"]

        tuf.keydb.create_keydb_from_root_metadata(root_metadata)
        tuf.roledb.create_roledb_from_root_metadata(root_metadata)
        root_keyids = tuf.roledb.get_role_keyids("root")

        root_private_keypath = os.path.join(keystore_path, "root_key")
        root_private_key = repo_lib.import_rsa_privatekey_from_file(root_private_keypath, "password")

        # Sign with a valid, but not a threshold, key.
        targets_private_keypath = os.path.join(keystore_path, "targets_key")
        targets_private_key = repo_lib.import_rsa_privatekey_from_file(targets_private_keypath, "password")

        # sign_metadata() expects the private key 'root_metadata' to be in
        # 'tuf.keydb'.  Remove any public keys that may be loaded before
        # adding private key, otherwise a 'tuf.KeyAlreadyExists' exception is
        # raised.
        tuf.keydb.remove_key(root_private_key["keyid"])
        tuf.keydb.add_key(root_private_key)
        tuf.keydb.remove_key(targets_private_key["keyid"])
        tuf.keydb.add_key(targets_private_key)

        root_keyids.extend(tuf.roledb.get_role_keyids("targets"))
        # Add the snapshot's public key (to test whether non-private keys are
        # ignored by sign_metadata()).
        root_keyids.extend(tuf.roledb.get_role_keyids("snapshot"))
        root_signable = repo_lib.sign_metadata(root_metadata, root_keyids, root_filename)
        self.assertTrue(tuf.formats.SIGNABLE_SCHEMA.matches(root_signable))

        # Test improperly formatted arguments.
        self.assertRaises(tuf.FormatError, repo_lib.sign_metadata, 3, root_keyids, "root.json")
        self.assertRaises(tuf.FormatError, repo_lib.sign_metadata, root_metadata, 3, "root.json")
        self.assertRaises(tuf.FormatError, repo_lib.sign_metadata, root_metadata, root_keyids, 3)
예제 #4
0
def _generate_and_write_metadata(rolename,
                                 metadata_filename,
                                 write_partial,
                                 targets_directory,
                                 prefix='',
                                 repository_name='default'):
    """
    Non-public function that can generate and write the metadata of the
    specified 'rolename'.  It also increments version numbers if:

    1.  write_partial==True and the metadata is the first to be written.

    2.  write_partial=False (i.e., write()), the metadata was not loaded as
        partially written, and a write_partial is not needed.
  """

    metadata = None

    # Retrieve the roleinfo of 'rolename' to extract the needed metadata
    # attributes, such as version number, expiration, etc.
    roleinfo = roledb.get_roleinfo(rolename, repository_name)

    metadata = generate_targets_metadata(targets_directory, roleinfo['paths'],
                                         roleinfo['version'],
                                         roleinfo['expires'],
                                         roleinfo['delegations'], False)

    # Prepend the prefix to the project's filepath to avoid signature errors in
    # upstream.
    for element in list(metadata['targets']):
        junk, relative_target = os.path.split(element)
        prefixed_path = os.path.join(prefix, relative_target)
        metadata['targets'][prefixed_path] = metadata['targets'][element]
        if prefix != '':
            del (metadata['targets'][element])

    signable = repo_lib.sign_metadata(metadata, roleinfo['signing_keyids'],
                                      metadata_filename, repository_name)

    # Check if the version number of 'rolename' may be automatically incremented,
    # depending on whether if partial metadata is loaded or if the metadata is
    # written with write() / write_partial().
    # Increment the version number if this is the first partial write.
    if write_partial:
        temp_signable = repo_lib.sign_metadata(metadata, [], metadata_filename,
                                               repository_name)
        temp_signable['signatures'].extend(roleinfo['signatures'])
        status = sig.get_signature_status(temp_signable, rolename,
                                          repository_name)
        if len(status['good_sigs']) == 0:
            metadata['version'] = metadata['version'] + 1
            signable = repo_lib.sign_metadata(metadata,
                                              roleinfo['signing_keyids'],
                                              metadata_filename,
                                              repository_name)

    # non-partial write()
    else:
        if sig.verify(signable, rolename, repository_name):
            metadata['version'] = metadata['version'] + 1
            signable = repo_lib.sign_metadata(metadata,
                                              roleinfo['signing_keyids'],
                                              metadata_filename,
                                              repository_name)

    # Write the metadata to file if contains a threshold of signatures.
    signable['signatures'].extend(roleinfo['signatures'])

    if sig.verify(signable, rolename, repository_name) or write_partial:
        repo_lib._remove_invalid_and_duplicate_signatures(
            signable, repository_name)
        storage_backend = sslib_storage.FilesystemBackend()
        filename = repo_lib.write_metadata_file(signable, metadata_filename,
                                                metadata['version'], False,
                                                storage_backend)

    # 'signable' contains an invalid threshold of signatures.
    else:
        message = 'Not enough signatures for ' + repr(metadata_filename)
        raise sslib_exceptions.Error(message, signable)

    return signable, filename
예제 #5
0
def _generate_and_write_metadata(rolename, metadata_filename, write_partial,
                                 targets_directory, metadata_directory,
                                 filenames=None,
                                 prefix=''):
  """
    Non-public function that can generate and write the metadata of the
    specified 'rolename'.  It also increments version numbers if:
    
    1.  write_partial==True and the metadata is the first to be written.
              
    2.  write_partial=False (i.e., write()), the metadata was not loaded as
        partially written, and a write_partial is not needed.
  """

  metadata = None 
  
  # Retrieve the roleinfo of 'rolename' to extract the needed metadata
  # attributes, such as version number, expiration, etc.
  roleinfo = tuf.roledb.get_roleinfo(rolename) 

  metadata = generate_targets_metadata(targets_directory,
                                       roleinfo['paths'],
                                       roleinfo['version'],
                                       roleinfo['expires'],
                                       roleinfo['delegations'],
                                       False) 

  # Prepend the prefix to the project's filepath to avoid signature errors in
  # upstream.
  target_filepaths = metadata['targets'].items()
  for element in list(metadata['targets']):
    junk_path, relative_target = os.path.split(element)
    prefixed_path = os.path.join(prefix,relative_target)
    metadata['targets'][prefixed_path] = metadata['targets'][element]
    if prefix != '':
      del(metadata['targets'][element])

  signable = sign_metadata(metadata, roleinfo['signing_keyids'],
                           metadata_filename)

  # Check if the version number of 'rolename' may be automatically incremented,
  # depending on whether if partial metadata is loaded or if the metadata is
  # written with write() / write_partial(). 
  # Increment the version number if this is the first partial write.
  if write_partial:
    temp_signable = sign_metadata(metadata, [], metadata_filename)
    temp_signable['signatures'].extend(roleinfo['signatures'])
    status = tuf.sig.get_signature_status(temp_signable, rolename)
    if len(status['good_sigs']) == 0:
      metadata['version'] = metadata['version'] + 1
      signable = sign_metadata(metadata, roleinfo['signing_keyids'],
                               metadata_filename)
  
  # non-partial write()
  else:
    if tuf.sig.verify(signable, rolename): #and not roleinfo['partial_loaded']:
      metadata['version'] = metadata['version'] + 1
      signable = sign_metadata(metadata, roleinfo['signing_keyids'],
                               metadata_filename)

  # Write the metadata to file if contains a threshold of signatures. 
  signable['signatures'].extend(roleinfo['signatures']) 
  
  if tuf.sig.verify(signable, rolename) or write_partial:
    _remove_invalid_and_duplicate_signatures(signable)
    compressions = roleinfo['compressions']
    filename = write_metadata_file(signable, metadata_filename,
                                   metadata['version'], compressions,
                                   False)
    
  # 'signable' contains an invalid threshold of signatures. 
  else:
    message = 'Not enough signatures for ' + repr(metadata_filename)
    raise tuf.Error(message, signable)

  return signable, filename