blob: e6d80a5ee1b2fff2e06d555b0a15690f4b1cb08c [file] [log] [blame]
# -*- 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
from chromite.lib import cros_test_lib
from chromite.lib import osutils
from chromite.signing.lib import keys
class TestKeyPair(cros_test_lib.TempDirTestCase):
"""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)
self.assertEqual(k1.basename, 'key1')
self.assertEqual(k1.private,
os.path.join(self.tempdir, 'key1' + '.vbprivk'))
self.assertEqual(k1.public,
os.path.join(self.tempdir, 'key1' + '.vbpubk'))
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 testInitWithBasename(self):
"""Test init with basename kwarg."""
k_basename = 'k_base_new'
k_base = keys.KeyPair('k_base', self.tempdir, basename=k_basename)
self.assertEqual(k_base.basename, k_basename)
self.assertEqual(k_base.private,
os.path.join(self.tempdir, k_basename + '.vbprivk'))
self.assertEqual(k_base.public,
os.path.join(self.tempdir, k_basename + '.vbpubk'))
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='.vbprivk2')
self.assertEqual(k_ext.private,
os.path.join(self.tempdir, 'k_ext.vbprivk2'))
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 testCreateKeyblockSimple(self):
k1 = keys.KeyPair('key1', self.tempdir)
kb1 = k1.CreateKeyblock()
self.assertEqual(kb1.keydir, self.tempdir)
self.assertEqual(kb1.name, k1.name)
self.assertEqual(kb1.data_key, k1)
def testCreateKeyblockWithName(self):
k1 = keys.KeyPair('key1', self.tempdir)
kb2 = k1.CreateKeyblock(name='kb2')
self.assertEqual(kb2.name, 'kb2')
def testCreateKeyblockWithBasename(self):
k1 = keys.KeyPair('key1', self.tempdir)
kb1 = k1.CreateKeyblock(basename='bk1_new')
self.assertEqual(kb1.filename,
os.path.join(self.tempdir, 'bk1_new.keyblock'))
def testCreateKeyblockWithDataKey(self):
key4 = keys.KeyPair('key4_data_key', self.tempdir)
kb4 = key4.CreateKeyblock()
self.assertEqual(kb4.name, 'key4')
self.assertEqual(kb4.filename, os.path.join(self.tempdir, 'key4.keyblock'))
class TestKeyblock(cros_test_lib.TempDirTestCase):
"""Test Keyblock class"""
def testInitSimple(self):
kb0 = keys.Keyblock('kb0', keydir=self.tempdir)
self.assertEqual(kb0.name, 'kb0')
self.assertEqual(kb0.keydir, self.tempdir)
self.assertEqual(kb0.filename, os.path.join(self.tempdir, 'kb0.keyblock'))
self.assertEqual(kb0.data_key, None)
def testInitNoKeydir(self):
self.assertRaises(ValueError, keys.Keyblock, 'kb0')
def testInitWithBasename(self):
kb0 = keys.Keyblock('kb0', self.tempdir, basename='kb0_new')
self.assertEqual(kb0.filename,
os.path.join(self.tempdir, 'kb0_new.keyblock'))
def testInitWithKey(self):
key0 = keys.KeyPair('key1', self.tempdir)
kb0 = keys.Keyblock('kb0', data_key=key0)
self.assertEqual(kb0.data_key, key0)
self.assertEqual(kb0.keydir, self.tempdir)
def testExistsEmpty(self):
kb0 = keys.Keyblock('kb0', keydir=self.tempdir)
self.assertFalse(kb0.Exists())
def testExists(self):
kb0 = keys.Keyblock('kb0', self.tempdir)
CreateDummyKeyblock(kb0)
self.assertTrue(kb0.Exists())
class TestKeyset(cros_test_lib.TempDirTestCase):
"""Test Keyset class."""
def _get_keyset(self):
"""Returns keyset with a few keys."""
kc = keys.Keyset()
for key_name in ['key1', 'key2', 'key3', 'key4']:
kc.AddKey(keys.KeyPair(key_name, self.tempdir))
for keyblock_name, key_name in [('kb1', 'key1'),
('kb2', 'key2'),
('kb4', 'key4')]:
kc.AddKeyblock(kc.keys[key_name].CreateKeyblock(name=keyblock_name))
return kc
def testInit(self):
ks = keys.Keyset()
self.assertIsInstance(ks.keys, dict)
self.assertIsInstance(ks.keyblocks, dict)
def testAddKey(self):
ks0 = keys.Keyset()
key0 = keys.KeyPair('key0', self.tempdir)
ks0.AddKey(key0)
self.assertEqual(ks0.keys['key0'], key0)
def testAddKeyWithKeyName(self):
ks0 = keys.Keyset()
key0 = keys.KeyPair('key0', self.tempdir)
ks0.AddKey(key0, key_name='key0_new')
self.assertEqual(ks0.keys['key0_new'], key0)
def testGetKeyMissing(self):
ks0 = self._get_keyset()
self.assertIsNone(ks0.GetKey('foo'))
def testGetKey(self):
ks0 = self._get_keyset()
self.assertEqual(ks0.GetKey('key1'), ks0.keys['key1'])
def testAddKeyblock(self):
ks0 = keys.Keyset()
kb0 = keys.Keyblock('keyblock0', keydir=self.tempdir)
ks0.AddKeyblock(kb0)
self.assertEqual(ks0.keyblocks['keyblock0'], kb0)
def testAddKeyblockWithName(self):
ks0 = keys.Keyset()
kb0 = keys.Keyblock('keyblock0', keydir=self.tempdir)
ks0.AddKeyblock(kb0, kb_name='keyblock0_new')
self.assertEqual(ks0.keyblocks['keyblock0_new'], kb0)
def testGetKeyblockMissing(self):
ks0 = self._get_keyset()
self.assertIsNone(ks0.GetKeyblock('foo'))
def testGetKeyblock(self):
ks0 = self._get_keyset()
self.assertEqual(ks0.GetKeyblock('kb1'), ks0.keyblocks['kb1'])
def testPrune(self):
ks0 = self._get_keyset()
key_keep = ['key1', 'key3']
kb_keep = ['kb1', 'kb4']
for key_name in key_keep:
CreateDummyKeys(ks0.GetKey(key_name))
for kb_name in kb_keep:
CreateDummyKeyblock(ks0.GetKeyblock(kb_name))
ks0.Prune()
for key_name, key in ks0.keys.iteritems():
self.assertTrue(key.Exists(), msg='All keys should exist')
self.assertIn(key_name, key_keep,
msg='Only keys in key_keep should exists')
for keyblock_name, keyblock in ks0.keyblocks.iteritems():
self.assertTrue(keyblock.Exists(), msg='All keyblocks should exist')
self.assertIn(keyblock_name, kb_keep,
msg='Only keyblocks in kb_keep should exist')
def testKeyExistsMissing(self):
ks0 = self._get_keyset()
self.assertFalse(ks0.KeyExists('foo'), msg="'foo' should not exist")
self.assertFalse(ks0.KeyExists('key1'), msg="'foo' should not exist")
def testKeyExistsPublicAndPrivate(self):
ks0 = self._get_keyset()
CreateDummyKeys(ks0.GetKey('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.GetKey('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.GetKey('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('kb1'), msg="'kb1' not created yet")
def testKeyblockExists(self):
ks0 = self._get_keyset()
CreateDummyKeyblock(ks0.GetKeyblock('kb1'))
self.assertTrue(ks0.KeyblockExists('kb1'), msg="'kb1' should exist")
class testKeysetFromDir(cros_test_lib.TempDirTestCase):
"""Test keyeset_from_dir function."""
dev_keys = ['ec_data_key',
'ec_root_key',
'firmware_data_key',
'installer_kernel_data_key',
'kernel_data_key',
'recovery_kernel_data_key',
'root_key']
dev_keyblocks = ['ec',
'firmware',
'installer_kernel',
'kernel',
'recovery_kernel']
dev_loem_keys = ['firmware_data_key.loem1',
'firmware_data_key.loem2',
'firmware_data_key.loem3',
'firmware_data_key.loem4',
'root_key.loem1',
'root_key.loem2',
'root_key.loem3',
'root_key.loem4']
dev_loem_keyblocks = ['firmware.loem1',
'firmware.loem2',
'firmware.loem3',
'firmware.loem4',
'root_key.loem1',
'root_key.loem2',
'root_key.loem3',
'root_key.loem4']
def _create_keyfiles(self, dev_keys, dev_keyblocks=None):
"""Helper to create dummy keyfiles."""
for key_name in dev_keys:
key = keys.KeyPair(key_name, self.tempdir)
CreateDummyPrivateKey(key)
if dev_keyblocks:
kb = key.CreateKeyblock()
if kb.name in dev_keyblocks:
CreateDummyKeyblock(kb)
def testEmpty(self):
ks = keys.KeysetFromDir(self.tempdir)
self.assertIsInstance(ks, keys.Keyset)
def testWithKeypair(self):
self._create_keyfiles(self.dev_keys)
ks = keys.KeysetFromDir(self.tempdir)
for key_name in self.dev_keys:
self.assertTrue(ks.KeyExists(key_name))
self.assertEqual(ks.keyblocks, {}, msg="keyblocks should be empty")
def testCompleteDir(self):
self._create_keyfiles(self.dev_keys, self.dev_keyblocks)
ks = keys.KeysetFromDir(self.tempdir)
for key_name in self.dev_keys:
self.assertTrue(ks.KeyExists(key_name))
for kb_name in self.dev_keyblocks:
self.assertTrue(ks.KeyblockExists(kb_name))
def testLoemDir(self):
self._create_keyfiles(self.dev_loem_keys, self.dev_loem_keyblocks)
ks = keys.KeysetFromDir(self.tempdir)
for key_name in self.dev_loem_keys:
self.assertTrue(ks.KeyExists(key_name))
for kb_name in self.dev_loem_keyblocks:
self.assertTrue(ks.KeyblockExists(kb_name))
def CreateDummyPublic(key):
"""Create empty public key file for testing."""
osutils.Touch(key.public)
def CreateDummyPrivateKey(key):
"""Create empty private key file for testing."""
osutils.Touch(key.private)
def CreateDummyKeys(key):
"""Create empty key files for testing."""
CreateDummyPublic(key)
CreateDummyPrivateKey(key)
def CreateDummyKeyblock(keyblock):
"""Create empty keyblock file for testing."""
osutils.Touch(keyblock.filename)