1# Copyright (c) 2014 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import os 6 7from autotest_lib.client.bin import test, utils 8from autotest_lib.client.common_lib import error 9from autotest_lib.client.cros import cryptohome 10 11 12class platform_BootLockbox(test.test): 13 """ Test basic boot-lockbox functionality.""" 14 version = 1 15 16 def initialize(self): 17 test.test.initialize(self) 18 self.data_file = '/tmp/__lockbox_test' 19 open(self.data_file, mode='w').write('test_lockbox_data') 20 21 def cleanup(self): 22 self._remove_file(self.data_file) 23 self._remove_file(self.data_file + '.signature') 24 self._remove_file('/var/lib/boot-lockbox/boot_attributes.pb') 25 self._remove_file('/var/lib/boot-lockbox/boot_attributes.sig') 26 test.test.cleanup(self) 27 28 def _remove_file(self, filename): 29 try: 30 os.remove(filename) 31 except OSError: 32 # Ignore errors 33 pass 34 35 def _ensure_tpm_ready(self): 36 status = cryptohome.get_tpm_status() 37 if not status['Enabled']: 38 raise error.TestNAError('Test NA because there is no TPM.') 39 if not status['Owned']: 40 cryptohome.take_tpm_ownership() 41 status = cryptohome.get_tpm_status() 42 if not status['Ready']: 43 raise error.TestError('Failed to initialize TPM.') 44 45 def _sign_lockbox(self): 46 return utils.system(cryptohome.CRYPTOHOME_CMD + 47 ' --action=sign_lockbox --file=' + self.data_file, 48 ignore_status=True) == 0 49 50 def _verify_lockbox(self): 51 return utils.system(cryptohome.CRYPTOHOME_CMD + 52 ' --action=verify_lockbox --file=' + self.data_file, 53 ignore_status=True) == 0 54 55 def _finalize_lockbox(self): 56 utils.system(cryptohome.CRYPTOHOME_CMD + ' --action=finalize_lockbox') 57 58 def _get_boot_attribute(self): 59 return utils.system(cryptohome.CRYPTOHOME_CMD + 60 ' --action=get_boot_attribute --name=test', 61 ignore_status=True) == 0 62 63 def _set_boot_attribute(self): 64 utils.system(cryptohome.CRYPTOHOME_CMD + 65 ' --action=set_boot_attribute --name=test --value=1234') 66 67 def _flush_and_sign_boot_attributes(self): 68 return utils.system(cryptohome.CRYPTOHOME_CMD + 69 ' --action=flush_and_sign_boot_attributes', 70 ignore_status=True) == 0 71 72 def run_once(self): 73 self._ensure_tpm_ready() 74 if not self._sign_lockbox(): 75 # This will fire if you forget to reboot before running the test! 76 raise error.TestFail('Boot lockbox could not be signed.') 77 78 if cryptohome.get_login_status()['boot_lockbox_finalized']: 79 raise error.TestFail('Boot lockbox is already finalized.') 80 81 if not self._verify_lockbox(): 82 raise error.TestFail('Boot lockbox could not be verified.') 83 84 # Setup a bad signature and make sure it doesn't verify. 85 open(self.data_file, mode='w').write('test_lockbox_data2') 86 if self._verify_lockbox(): 87 raise error.TestFail('Boot lockbox verified bad data.') 88 open(self.data_file, mode='w').write('test_lockbox_data') 89 90 self._set_boot_attribute() 91 92 if self._get_boot_attribute(): 93 raise error.TestFail('Boot attributes already have data.') 94 95 if not self._flush_and_sign_boot_attributes(): 96 raise error.TestFail('Boot attributes could not sign.') 97 98 if not self._get_boot_attribute(): 99 raise error.TestFail('Boot attribute was not available.') 100 101 # Check again to make sure nothing has tricked the finalize check. 102 if cryptohome.get_login_status()['boot_lockbox_finalized']: 103 raise error.TestFail('Boot lockbox prematurely finalized.') 104 105 # Finalize and make sure we can verify but not sign. 106 self._finalize_lockbox() 107 108 if not cryptohome.get_login_status()['boot_lockbox_finalized']: 109 raise error.TestFail('Boot lockbox finalize status did not change ' 110 'after finalization.') 111 112 if self._flush_and_sign_boot_attributes(): 113 raise error.TestFail('Boot attributes signed after finalization.') 114 115 if not self._verify_lockbox(): 116 raise error.TestFail('Boot lockbox could not be verified after ' 117 'finalization.') 118 119 if self._sign_lockbox(): 120 raise error.TestFail('Boot lockbox signed after finalization.') 121