# -*- coding: utf-8 -*-
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

""""ChromeOS key unittests"""

from __future__ import print_function

import os
import textwrap

from chromite.lib import cros_test_lib
from chromite.lib import osutils
from chromite.lib import partial_mock
from chromite.signing.lib import keys


MOCK_SHA1SUM = 'e2c1c92d7d7aa7dfed5e8375edd30b7ae52b7450'

# pylint: disable=protected-access

def MockVbutilKey(rc, sha1sum=MOCK_SHA1SUM):
  """Adds vbutil_key mocks to |rc|"""

  cmd_output = textwrap.dedent('''
    Public Key file:   firmware_data_key.vbpubk
    Algorithm:         7 RSA4096 SHA256
    Key Version:       1
    Key sha1sum:       ''' + sha1sum)

  rc.AddCmdResult(partial_mock.ListRegex('vbutil_key --unpack .*'),
                  output=cmd_output)


class KeysetMock(keys.Keyset):
  """Mock Keyset that mimics common loem key directory."""
  KEYS = ('ec_data_key',
          'ec_root_key',
          'key_ec_efs',
          'firmware_data_key',
          'installer_kernel_data_key',
          'kernel_data_key',
          'kernel_subkey',
          'recovery_kernel_data_key',
          'recovery_key',
          'root_key')

  KEYS_WITH_BUILDTARGET_ALIASES = keys.Keyset._per_buildtarget_key_names

  BUILDTARGET_ALIASES = ('loem1', 'loem2', 'loem3', 'loem4')

  BUILDTARGET_NAMES = ('ACME', 'SHINRA', 'WILE', 'COYOTE')

  def __init__(self, key_dir, has_loem_ini=True):
    """Create a Keyset with buildtarget-specific keys, and populate it."""

    # This will create the Keyset without buildtarget-specific keys, since that
    # is determined by having loem.ini, and the directory does not exist yet,
    # let alone loem.ini.
    # We do not actually create files for the KeyPairs, since the tests care.
    super(KeysetMock, self).__init__(key_dir)

    osutils.SafeMakedirs(key_dir)
    self.has_loem_ini = has_loem_ini

    # By default, we have buildtarget-specific keys.  If not, don't create them.
    if not has_loem_ini:
      self.KEYS_WITH_BUILDTARGET_ALIASES = ()
      self.BUILDTARGET_ALIASES = ()
      self.BUILDTARGET_NAMES = ()

    # Create KeyPairs as appropriate for the Keyset we are mocking.
    for key_name in KeysetMock.KEYS:
      if key_name not in self.KEYS_WITH_BUILDTARGET_ALIASES:
        self.AddKey(keys.KeyPair(key_name, key_dir))

    for name in self.KEYS_WITH_BUILDTARGET_ALIASES:
      for buildtarget in self.BUILDTARGET_ALIASES:
        key = keys.KeyPair("%s.%s" % (name, buildtarget), key_dir)
        self.AddBuildtargetKey(name, buildtarget, key)

    for alias, buildtarget in zip(
        self.BUILDTARGET_NAMES, self.BUILDTARGET_ALIASES):
      self.buildtarget_map[alias] = buildtarget
      self.buildtarget_map[buildtarget] = buildtarget
    self.WriteIniFile()

  # TODO(lamontjones): This may eventually make sense to move into
  # keys.Keyset(), if it ever becomes the thing that creates a keyset directory.
  # Today, we only read the keyset from the directory, we do not update it.
  def WriteIniFile(self):
    """Writes alias to file"""
    if not self.has_loem_ini:
      return
    lines = ['[loem]']
    lines += ['%d = %s' % (i, name)
              for i, name in enumerate(self.BUILDTARGET_NAMES, 1)]
    contents = '\n'.join(lines) + '\n'
    osutils.WriteFile(os.path.join(self.key_dir, 'loem.ini'), contents)

  def CreateDummyKeys(self):
    """Creates dummy keys from stored keys."""
    for key in self.keys.values():
      CreateDummyKeys(key)
    for loem in self._buildtarget_keys.values():
      for key in loem.values():
        CreateDummyKeys(key)


class TestKeyPair(cros_test_lib.RunCommandTempDirTestCase):
  """Test KeyPair class."""

  def testInitSimple(self):
    """Test init with minimal arguments."""
    k1 = keys.KeyPair('key1', self.tempdir)
    self.assertEqual(k1.name, 'key1')
    self.assertEqual(k1.version, 1)
    self.assertEqual(k1.keydir, self.tempdir)

  def testRejectsEmptyName(self):
    with self.assertRaises(ValueError):
      keys.KeyPair('', self.tempdir)

  def testRejectsNameWithSlash(self):
    with self.assertRaises(ValueError):
      keys.KeyPair('/foo', self.tempdir)
    with self.assertRaises(ValueError):
      keys.KeyPair('foo/bar', self.tempdir)

  def testRejectsLeadingDot(self):
    with self.assertRaises(ValueError):
      keys.KeyPair('.foo', self.tempdir)

  def testCoercesVersionToInt(self):
    k1 = keys.KeyPair('key1', self.tempdir, version='1')
    self.assertEqual(k1.name, 'key1')
    self.assertEqual(k1.version, 1)
    self.assertEqual(k1.keydir, self.tempdir)

  def testAssertsValueErrorOnNonNumericVersion(self):
    with self.assertRaises(ValueError):
      keys.KeyPair('key1', self.tempdir, version='blah')

  def testAssertsValueErrorOnEmptyStringVersion(self):
    with self.assertRaises(ValueError):
      keys.KeyPair('key1', self.tempdir, version='')

  def testPrivateKey(self):
    k1 = keys.KeyPair('key1', self.tempdir)
    self.assertEqual(k1.private,
                     os.path.join(self.tempdir, 'key1' + '.vbprivk'))

  def testPublicKey(self):
    k1 = keys.KeyPair('key1', self.tempdir)
    self.assertEqual(k1.public,
                     os.path.join(self.tempdir, 'key1' + '.vbpubk'))

  def testKeyblock(self):
    k1 = keys.KeyPair('key1', self.tempdir)
    self.assertEqual(k1.keyblock,
                     os.path.join(self.tempdir, 'key1' + '.keyblock'))

  def testKeyblockWithSuffix(self):
    k1 = keys.KeyPair('key1_data_key', self.tempdir)
    self.assertEqual(k1.keyblock,
                     os.path.join(self.tempdir, 'key1' + '.keyblock'))

  def testInitWithVersion(self):
    """Test init with version kwarg."""
    k_ver = keys.KeyPair('k_ver', self.tempdir, version=2)
    self.assertEqual(k_ver.version, 2)

  def testInitWithPubExt(self):
    """Test init with pub_ext kwarg."""
    k_ext = keys.KeyPair('k_ext', self.tempdir, pub_ext='.vbpubk2')
    self.assertEqual(k_ext.public,
                     os.path.join(self.tempdir, 'k_ext.vbpubk2'))

  def testInitWithPrivExt(self):
    """Test init with priv_ext kwarg."""
    k_ext = keys.KeyPair('k_ext', self.tempdir, priv_ext='.vbprik2')
    self.assertEqual(k_ext.private,
                     os.path.join(self.tempdir, 'k_ext.vbprik2'))
    self.assertEqual(k_ext.public,
                     os.path.join(self.tempdir, 'k_ext.vbpubk2'))

  def testRejectsInvalidPubExt(self):
    """Test init with bad pub_ext argument."""
    with self.assertRaises(ValueError):
      keys.KeyPair('foo', self.tempdir, pub_ext='.bar')

  def testRejectsInvalidPrivExt(self):
    """Test init with bad priv_ext argument."""
    with self.assertRaises(ValueError):
      keys.KeyPair('foo', self.tempdir, priv_ext='.bar')

  def testSetsPubExtCorrectly(self):
    """Test init sets pub_ext correctly based on priv_ext argument."""
    k1 = keys.KeyPair('k1', self.tempdir, priv_ext='.vbprivk')
    k2 = keys.KeyPair('k2', self.tempdir, priv_ext='.vbprik2')
    self.assertEqual(k1._pub_ext, '.vbpubk')
    self.assertEqual(k2._pub_ext, '.vbpubk2')
    self.assertEqual(k1.public, '%s/k1.vbpubk' % self.tempdir)
    self.assertEqual(k2.public, '%s/k2.vbpubk2' % self.tempdir)

  def testCmpSame(self):
    k1 = keys.KeyPair('key1', self.tempdir)
    k2 = keys.KeyPair('key1', self.tempdir)
    self.assertEqual(k1, k1)
    self.assertEqual(k1, k2)

  def testCmpDiff(self):
    k1 = keys.KeyPair('key1', self.tempdir)
    k2 = keys.KeyPair('key2', self.tempdir)
    self.assertNotEqual(k1, k2)

  def testParsePrivateKeyFilenameReturnsValues(self):
    """Make sure that we return the correct name/ext."""
    v1 = keys.KeyPair.ParsePrivateKeyFilename('foo.vbprivk')
    self.assertEqual('foo', v1.group('name'))
    self.assertEqual('.vbprivk', v1.group('ext'))
    v2 = keys.KeyPair.ParsePrivateKeyFilename('bar.vbprik2')
    self.assertEqual('bar', v2.group('name'))
    self.assertEqual('.vbprik2', v2.group('ext'))

  def testParsePrivateKeyFilenameReturnsNone(self):
    """Non-private key filenames return None"""
    self.assertEqual(None, keys.KeyPair.ParsePrivateKeyFilename('foo.vbpubk'))

  def testParsePrivateKeyFilenameStripsDir(self):
    """Leading directories in the path are ignored."""
    name = keys.KeyPair.ParsePrivateKeyFilename(
        '/path/to/foo.vbprivk').group('name')
    self.assertEqual('foo', name)

  def testExistsEmpty(self):
    self.assertFalse(keys.KeyPair('key1', self.tempdir).Exists())

  def testExistEmptyRequirePublic(self):
    k1 = keys.KeyPair('key1', self.tempdir)
    self.assertFalse(k1.Exists(require_public=True))

  def testExistEmptyRequirePrivate(self):
    k1 = keys.KeyPair('key1', self.tempdir)
    self.assertFalse(k1.Exists(require_private=True))

  def testExistEmptyRequirePublicRequirePrivate(self):
    k1 = keys.KeyPair('key1', self.tempdir)
    self.assertFalse(k1.Exists(require_private=True, require_public=True))

  def testExistWithPublicKey(self):
    k1 = keys.KeyPair('key1', self.tempdir)

    CreateDummyPublic(k1)
    self.assertTrue(k1.Exists())
    self.assertTrue(k1.Exists(require_public=True))
    self.assertFalse(k1.Exists(require_private=True))

  def testExistsWithPrivateKey(self):
    k1 = keys.KeyPair('key1', self.tempdir)

    CreateDummyPrivateKey(k1)
    self.assertTrue(k1.Exists())
    self.assertTrue(k1.Exists(require_private=True))
    self.assertFalse(k1.Exists(require_public=True))

  def testExistsWithBothKeys(self):
    """Exists() works correctly when private/public are both required."""
    k1 = keys.KeyPair('key1', self.tempdir)

    CreateDummyPrivateKey(k1)
    CreateDummyPublic(k1)
    self.assertTrue(k1.Exists())
    self.assertTrue(k1.Exists(require_private=True))
    self.assertTrue(k1.Exists(require_public=True))
    self.assertTrue(k1.Exists(
        require_private=True, require_public=True))

  def testKeyblockExistsMissing(self):
    k1 = keys.KeyPair('key1', self.tempdir)
    self.assertFalse(k1.KeyblockExists())

  def testKeyblockExists(self):
    k1 = keys.KeyPair('key1', self.tempdir)
    CreateDummyKeyblock(k1)
    self.assertTrue(k1.KeyblockExists())

  def testGetSha1sumEmpty(self):
    """"Test GetSha1sum with bad cmd output."""
    k1 = keys.KeyPair('key1', self.tempdir)

    with self.assertRaises(keys.SignerKeyError):
      k1.GetSHA1sum()

  def testGetSha1sumMockCmd(self):
    """Test GetSha1sum with mock cmd output."""
    MockVbutilKey(self.rc)
    k1 = keys.KeyPair('firmware_data_key', self.tempdir)

    k1sum = k1.GetSHA1sum()
    self.assertEqual(k1sum, MOCK_SHA1SUM)
    self.assertCommandCalled(['vbutil_key', '--unpack', k1.public],
                             error_code_ok=True)


class TestKeyVersions(cros_test_lib.TempDirTestCase):
  """Test KeyVersions class."""

  # used for several tests
  expected = {
      'firmware_key_version': 2,
      'firmware_version': 3,
      'kernel_key_version': 4,
      'kernel_version': 5,
      'random': 6,
  }

  def _CreateVersionsFile(self, values):
    kv_path = os.path.join(self.tempdir, 'key.versions')
    lines = ['%s=%d' % (k, v) for k, v in values.items()]
    contents = '\n'.join(lines) + '\n'
    osutils.WriteFile(kv_path, contents)
    return kv_path

  def testInitReturnsDefaultButDoesNotCreateFile(self):
    kv_path = os.path.join(self.tempdir, 'key.versions')
    kv = keys.KeyVersions(kv_path)
    self.assertFalse(os.path.exists(kv_path))
    expected = {
        'firmware_key_version': 1,
        'firmware_version': 1,
        'kernel_key_version': 1,
        'kernel_version': 1,
    }
    self.assertEqual(False, kv.saved)
    self.assertDictEqual(expected, kv._versions)

  def testInitReadsFile(self):
    kv_path = self._CreateVersionsFile(self.expected)
    kv = keys.KeyVersions(kv_path)
    self.assertDictEqual(self.expected, kv._versions)
    self.assertEqual(True, kv.saved)

  def testInitErrorOnBadFileContents(self):
    kv_path = self._CreateVersionsFile({})
    osutils.WriteFile(kv_path, 'firmware_version=bogus\n')
    with self.assertRaises(ValueError):
      keys.KeyVersions(kv_path)

  def testKeyNameTransformsName(self):
    kv_path = self._CreateVersionsFile({})
    kv = keys.KeyVersions(kv_path)
    self.assertEqual('firmware_version', kv._KeyName('firmware_data_key'))
    self.assertEqual('firmware_version', kv._KeyName('firmware_data_key.loem1'))
    self.assertEqual('firmware_version', kv._KeyName('firmware_version'))

  def testKeyNameIsIdempotent(self):
    kv_path = self._CreateVersionsFile({})
    kv = keys.KeyVersions(kv_path)
    self.assertEqual('B_version', kv._KeyName(kv._KeyName('B_data_key')))
    self.assertEqual('B_version', kv._KeyName(kv._KeyName('B_data_key.loem1')))
    self.assertEqual('B_version', kv._KeyName(kv._KeyName('B_version')))

  def testGetReturnsValue(self):
    kv_path = self._CreateVersionsFile(self.expected)
    kv = keys.KeyVersions(kv_path)
    self.assertEqual(
        self.expected['firmware_version'], kv.Get('firmware_data_key'))

  def testGetReturnsOneForUnknown(self):
    kv_path = self._CreateVersionsFile(self.expected)
    kv = keys.KeyVersions(kv_path)
    self.assertEqual(1, kv.Get('invalid'))

  def testSetSetsValue(self):
    kv_path = self._CreateVersionsFile({})
    kv = keys.KeyVersions(kv_path)
    kv.Set('firmware_data_key', 10)
    self.assertEqual(10, kv._versions['firmware_version'])

  def testSetMarksDirty(self):
    kv_path = self._CreateVersionsFile({})
    kv = keys.KeyVersions(kv_path)
    self.assertEqual(True, kv.saved)
    kv.Set('firmware_data_key', 10)
    self.assertEqual(10, kv._versions['firmware_version'])
    self.assertEqual(False, kv.saved)

  def testSetDoesNotSave(self):
    kv_path = self._CreateVersionsFile(self.expected)
    kv = keys.KeyVersions(kv_path)
    kv.Set('firmware_data_key', 10)
    kv2 = keys.KeyVersions(kv_path)
    self.assertEqual(
        self.expected['firmware_version'], kv2._versions['firmware_version'])

  def testIncrementIncrementsAndMarksDirty(self):
    kv_path = self._CreateVersionsFile({'firmware_version': 30})
    kv = keys.KeyVersions(kv_path)
    kv.Increment('firmware_data_key')
    self.assertEqual(31, kv._versions['firmware_version'])
    self.assertEqual(False, kv.saved)

  def testIncrementRaisesOnOverflow(self):
    kv_path = self._CreateVersionsFile({'firmware_version': 0xffff})
    kv = keys.KeyVersions(kv_path)
    with self.assertRaises(keys.VersionOverflowError):
      kv.Increment('firmware_data_key')
    self.assertEqual(0xffff, kv._versions['firmware_version'])

  def testIncrementDoesNotSave(self):
    kv_path = self._CreateVersionsFile(self.expected)
    kv = keys.KeyVersions(kv_path)
    kv.Increment('firmware_data_key')
    kv2 = keys.KeyVersions(kv_path)
    self.assertEqual(
        self.expected['firmware_version'], kv2._versions['firmware_version'])

  def testSaveSaves(self):
    kv_path = self._CreateVersionsFile(self.expected)
    kv = keys.KeyVersions(kv_path)
    kv.Increment('firmware_data_key')
    kv.Set('new', 37)
    kv.Save()
    self.assertEqual(True, kv.saved)
    kv2 = keys.KeyVersions(kv_path)
    self.assertDictEqual(kv._versions, kv2._versions)


class TestKeyset(cros_test_lib.TempDirTestCase):
  """Test Keyset class."""

  def _get_keyset(self, has_loem_ini=True):
    """Returns keyset with a few keys."""
    kc = KeysetMock(self.tempdir, has_loem_ini=has_loem_ini)

    # Add a few more keys for this build.
    for key_name in ['key1', 'key2', 'key3', 'key4']:
      kc.AddKey(keys.KeyPair(key_name, self.tempdir))

    return kc

  def testInit(self):
    ks = keys.Keyset()
    self.assertIsInstance(ks.keys, dict)
    self.assertIsInstance(ks._buildtarget_keys, dict)
    self.assertIsInstance(ks.buildtarget_map, dict)

  def testInitWithEmptyDir(self):
    """Call Keyset() with an uncreated directory."""
    ks = keys.Keyset(self.tempdir)
    self.assertIsInstance(ks, keys.Keyset)
    self.assertIsInstance(ks._buildtarget_keys, dict)
    self.assertIsInstance(ks.buildtarget_map, dict)

  def testInitWithPopulatedDirectory(self):
    """Keyset() loads a populated keyset directory correctly."""
    ks0 = KeysetMock(self.tempdir)
    ks0.CreateDummyKeys()

    ks1 = keys.Keyset(self.tempdir)

    self.assertDictEqual(ks0.keys, ks1.keys, msg='Incorrect keys')

    self.assertDictEqual(ks0._buildtarget_keys, ks1._buildtarget_keys,
                         msg='Incorrect buildtarget_keys')

    self.assertDictEqual(ks0.buildtarget_map, ks1.buildtarget_map,
                         msg='Incorrect key aliases')

    self.assertEqual(ks0, ks1)

  def testEqSame(self):
    kc1 = self._get_keyset()
    kc2 = self._get_keyset()
    self.assertEqual(kc1, kc2)

  def testEqDiffrent(self):
    kc1 = self._get_keyset()
    kc2 = self._get_keyset()

    kc2 = self._get_keyset()
    kc2.AddKey(keys.KeyPair('Foo', self.tempdir))

    self.assertFalse(kc1 == kc2)

  def testAddKey(self):
    ks0 = keys.Keyset()
    key0 = keys.KeyPair('key0', self.tempdir)
    ks0.AddKey(key0)
    self.assertEqual(ks0.keys['key0'], key0)

  def testAddBuildtargetKey(self):
    k9 = keys.KeyPair('root_key.loem9', self.tempdir)
    ks0 = self._get_keyset()
    ks0.AddBuildtargetKey('root_key', 'loem9', k9)

    self.assertEqual(ks0._buildtarget_keys['loem9']['root_key'], k9)

  def testGetBuildtargetKeysWithLoemIni(self):
    ks0 = self._get_keyset()
    expected_keys = ks0.GetBuildtargetKeys('root_key')
    expected = {k: ks0._buildtarget_keys[k]['root_key']
                for k in ks0._buildtarget_keys.keys()}
    self.assertDictEqual(expected, expected_keys)

  def testGetBuildtargetKeysWithoutLoemIni(self):
    ks0 = self._get_keyset(has_loem_ini=False)
    expected_keys = ks0.GetBuildtargetKeys('root_key')
    self.assertDictEqual({'root_key': ks0.keys['root_key']}, expected_keys)

  def testGetBuildKeysetMissmatch(self):
    ks0 = self._get_keyset()

    with self.assertRaises(keys.SignerBuildtargetKeyMissingError):
      ks0.GetBuildKeyset('foo')

  def testGetBuildKeyset(self):
    ks0 = self._get_keyset()
    ks1 = ks0.GetBuildKeyset('ACME')

    expected_keys = {name: k for name, k in ks0.keys.items()}
    for name, k in ks0._buildtarget_keys[
        ks0.buildtarget_map['ACME']].items():
      expected_keys[k.name] = k
      k1 = k.Copy()
      k1.name = name
      expected_keys[name] = k1
    actual_keys = {name: k for name, k in ks1.keys.items()}
    self.assertEqual(expected_keys, actual_keys)
    self.assertEqual(ks1._buildtarget_keys, {})

  def testGetBuildKeysetWithAliasSucceeds(self):
    ks0 = self._get_keyset()
    ks1 = ks0.GetBuildKeyset('loem3')
    self.assertEqual(ks0._buildtarget_keys['loem3']['root_key'],
                     ks1.keys['root_key.loem3'])
    self.assertEqual('root_key', ks1.keys['root_key'].name)
    # The rest of the fields should be equal.
    ks1.keys['root_key'].name = 'root_key.loem3'
    self.assertEqual(ks0._buildtarget_keys['loem3']['root_key'],
                     ks1.keys['root_key'])

  def testGetBuildKeysetWithMissingName(self):
    ks0 = self._get_keyset()
    with self.assertRaises(keys.SignerBuildtargetKeyMissingError):
      ks0.GetBuildKeyset('loem99')

  def testPrune(self):
    ks0 = self._get_keyset()
    key_keep = set(['key1', 'key3'])

    for key_name in key_keep:
      CreateDummyKeys(ks0.keys[key_name])

    ks0.Prune()
    # Only our keepers should have survived.
    self.assertEqual(key_keep, set([k.name for k in ks0.keys.values()]))
    for key_name, key in ks0.keys.items():
      self.assertTrue(key.Exists(), msg='All keys should exist')
      self.assertIn(key_name, key_keep,
                    msg='Only keys in key_keep should exists')

  def testKeyExistsMissing(self):
    ks0 = self._get_keyset()

    self.assertFalse(ks0.KeyExists('foo'), msg="'foo' should not exist")
    self.assertFalse(ks0.KeyExists('key1'), msg="'key1' should not exist")

  def testKeyExistsPublicAndPrivate(self):
    ks0 = self._get_keyset()
    CreateDummyKeys(ks0.keys['key1'])
    self.assertTrue(ks0.KeyExists('key1'), msg="key1 should exist")
    self.assertTrue(ks0.KeyExists('key1', require_public=True),
                    msg="key1 public key should exist")
    self.assertTrue(ks0.KeyExists('key1', require_private=True),
                    msg="key1 private key should exist")
    self.assertTrue(ks0.KeyExists('key1',
                                  require_public=True,
                                  require_private=True),
                    msg="key1 keys should exist")

  def testKeyExistsPrivate(self):
    ks0 = self._get_keyset()
    CreateDummyPrivateKey(ks0.keys['key2'])
    self.assertTrue(ks0.KeyExists('key2'),
                    msg="should pass with only private key")
    self.assertTrue(ks0.KeyExists('key2', require_private=True),
                    msg="Should exist with only private key")
    self.assertFalse(ks0.KeyExists('key2', require_public=True),
                     msg="Shouldn't pass with only private key")

  def testKeyExistsPublic(self):
    ks0 = self._get_keyset()
    CreateDummyPublic(ks0.keys['key3'])
    self.assertTrue(ks0.KeyExists('key3'),
                    msg="should pass with only public key")
    self.assertTrue(ks0.KeyExists('key3', require_public=True),
                    msg="Should exist with only public key")
    self.assertFalse(ks0.KeyExists('key3', require_private=True),
                     msg="Shouldn't pass with only public key")

  def testKeyblockExistsMissing(self):
    ks0 = self._get_keyset()
    self.assertFalse(ks0.KeyExists('foo'), msg="'foo' should not exist")
    self.assertFalse(ks0.KeyExists('key1'), msg="'key1' not created yet")

  def testKeyblockExists(self):
    ks0 = self._get_keyset()
    CreateDummyKeyblock(ks0.keys['key1'])
    self.assertTrue(ks0.KeyblockExists('key1'), msg="'key1' should exist")


def CreateDummyPublic(key):
  """Create empty public key file for given key."""
  osutils.Touch(key.public, makedirs=True)


def CreateDummyPrivateKey(key):
  """Create empty private key for given key."""
  osutils.Touch(key.private, makedirs=True)


def CreateDummyKeyblock(key):
  """Create empty keyblock file for given key."""
  osutils.Touch(key.keyblock, makedirs=True)


def CreateDummyKeys(key):
  """Create empty key files for given key (or buildtarget_keys if exist)."""
  CreateDummyPublic(key)
  CreateDummyPrivateKey(key)
  CreateDummyKeyblock(key)
