Home | History | Annotate | Download | only in platform_BootLockbox
      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 
      5 import os
      6 
      7 from autotest_lib.client.bin import test, utils
      8 from autotest_lib.client.common_lib import error
      9 from autotest_lib.client.cros import cryptohome
     10 
     11 
     12 class 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