blob: ac9f55ed88db22c806e9f69c271e7470f83f3d8a [file] [log] [blame]
# Copyright (c) 2014 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.
import os
from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros import cryptohome
class platform_BootLockbox(test.test):
""" Test basic boot-lockbox functionality."""
version = 1
def initialize(self):
test.test.initialize(self)
self.data_file = '/tmp/__lockbox_test'
open(self.data_file, mode='w').write('test_lockbox_data')
def cleanup(self):
self._remove_file(self.data_file)
self._remove_file(self.data_file + '.signature')
self._remove_file('/var/lib/boot-lockbox/boot_attributes.pb')
self._remove_file('/var/lib/boot-lockbox/boot_attributes.sig')
test.test.cleanup(self)
def _remove_file(self, filename):
try:
os.remove(filename)
except OSError:
# Ignore errors
pass
def _ensure_tpm_ready(self):
status = cryptohome.get_tpm_status()
if not status['Enabled']:
raise error.TestNAError('Test NA because there is no TPM.')
if not status['Owned']:
cryptohome.take_tpm_ownership()
status = cryptohome.get_tpm_status()
if not status['Ready']:
raise error.TestError('Failed to initialize TPM.')
def _sign_lockbox(self):
return utils.system(cryptohome.CRYPTOHOME_CMD +
' --action=sign_lockbox --file=' + self.data_file,
ignore_status=True) == 0
def _verify_lockbox(self):
return utils.system(cryptohome.CRYPTOHOME_CMD +
' --action=verify_lockbox --file=' + self.data_file,
ignore_status=True) == 0
def _finalize_lockbox(self):
utils.system(cryptohome.CRYPTOHOME_CMD + ' --action=finalize_lockbox')
def _get_boot_attribute(self):
return utils.system(cryptohome.CRYPTOHOME_CMD +
' --action=get_boot_attribute --name=test',
ignore_status=True) == 0
def _set_boot_attribute(self):
utils.system(cryptohome.CRYPTOHOME_CMD +
' --action=set_boot_attribute --name=test --value=1234')
def _flush_and_sign_boot_attributes(self):
return utils.system(cryptohome.CRYPTOHOME_CMD +
' --action=flush_and_sign_boot_attributes',
ignore_status=True) == 0
def run_once(self):
self._ensure_tpm_ready()
if not self._sign_lockbox():
raise error.TestFail('Boot lockbox could not be signed.')
if cryptohome.get_login_status()['boot_lockbox_finalized']:
raise error.TestFail('Boot lockbox is already finalized.')
if not self._verify_lockbox():
raise error.TestFail('Boot lockbox could not be verified.')
# Setup a bad signature and make sure it doesn't verify.
open(self.data_file, mode='w').write('test_lockbox_data2')
if self._verify_lockbox():
raise error.TestFail('Boot lockbox verified bad data.')
open(self.data_file, mode='w').write('test_lockbox_data')
self._set_boot_attribute()
if self._get_boot_attribute():
raise error.TestFail('Boot attributes already have data.')
if not self._flush_and_sign_boot_attributes():
raise error.TestFail('Boot attributes could not sign.')
if not self._get_boot_attribute():
raise error.TestFail('Boot attribute was not available.')
# Check again to make sure nothing has tricked the finalize check.
if cryptohome.get_login_status()['boot_lockbox_finalized']:
raise error.TestFail('Boot lockbox prematurely finalized.')
# Finalize and make sure we can verify but not sign.
self._finalize_lockbox()
if not cryptohome.get_login_status()['boot_lockbox_finalized']:
raise error.TestFail('Boot lockbox finalize status did not change '
'after finalization.')
if self._flush_and_sign_boot_attributes():
raise error.TestFail('Boot attributes signed after finalization.')
if not self._verify_lockbox():
raise error.TestFail('Boot lockbox could not be verified after '
'finalization.')
if self._sign_lockbox():
raise error.TestFail('Boot lockbox signed after finalization.')