| # 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.') |