blob: 0a7bf0623798c0070e1122d220c219f84cebc46d [file] [log] [blame]
# Copyright (c) 2011 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 logging, os, shutil
from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros import pkcs11
class Pkcs11InitFailure(error.TestError):
pass
class platform_Pkcs11InitUnderErrors(test.test):
version = 1
def __delete_if_exists(self, path):
if os.path.exists(path):
os.remove(path)
def __try_manual_init(self, test_desc):
"""Manually request PKCS#11 initialization. And wait for it to finish.
Will raise TestFail exception with |desc| on failure.
Args:
test_desc: string description of test being run.
"""
try:
pkcs11.ensure_initial_state()
pkcs11.init_pkcs11()
if not pkcs11.verify_pkcs11_initialized():
raise error.TestFail('Initialized token failed checks!')
except Exception, e:
logging.error('PKCS#11 initialization failed for test - "%s"',
test_desc)
logging.error('Failure reason: %s', e)
raise error.TestFail('PKCS#11 initialization failed for: %s' %
test_desc)
def __test_erase_everything(self):
shutil.rmtree(pkcs11.USER_TOKEN_DIR, ignore_errors=True)
shutil.rmtree(pkcs11.PKCS11_DIR, ignore_errors=True)
self.__try_manual_init(test_desc='Erase both token and PKCS#11 files')
def __test_erase_token(self):
shutil.rmtree(pkcs11.USER_TOKEN_DIR, ignore_errors=True)
self.__try_manual_init(test_desc='Erase user token in %s' %
pkcs11.USER_TOKEN_DIR)
def __test_erase_pkcs11dir(self):
shutil.rmtree(pkcs11.PKCS11_DIR, ignore_errors=True)
self.__try_manual_init(test_desc='Erase PKCS#11 files in %s' %
pkcs11.PKCS11_DIR)
def __test_broken_symlinks(self):
symlinks_list = ['tpm/chronos', 'tpm/ipsec', 'tpm/root']
for link in symlinks_list:
self.__delete_if_exists(os.path.join(pkcs11.PKCS11_DIR, link))
self.__try_manual_init(test_desc='Broken symlinks in %s' %
pkcs11.PKCS11_DIR)
def __test_missing_token_files(self):
token_file_list = ['NVTOK.DAT', 'TOK_OBJ/OBJ.IDX', 'TOK_OBJ/30000000']
for f in token_file_list:
self.__delete_if_exists(os.path.join(pkcs11.USER_TOKEN_DIR, f))
self.__try_manual_init(test_desc='Missing token files in %s' %
pkcs11.USER_TOKEN_DIR)
def __test_corrupt_token(self):
# Overwrite some user token files with NULL bytes.
token_file_list = ['TOK_OBJ/OBJ.IDX', 'TOK_OBJ/00000000',
'TOK_OBJ/70000000']
for f in token_file_list:
utils.system(
'dd if=/dev/zero of=%s bs=1 count=1000 >/dev/null 2>&1' %
os.path.join(pkcs11.USER_TOKEN_DIR, f))
self.__try_manual_init(test_desc='Corrupt token files in %s' %
pkcs11.USER_TOKEN_DIR)
def __chaps_init_iteration(self):
# Try initializing and using the temporary chaps test token.
pkcs11.load_p11_test_token()
if not pkcs11.verify_p11_test_token():
return False
pkcs11.unload_p11_test_token()
pkcs11.restore_p11_test_token()
return True
def __test_chaps_init(self):
pkcs11.setup_p11_test_token(True)
dbpath = pkcs11.get_p11_test_token_db_path()
# Make sure the test token is functional.
if not self.__chaps_init_iteration():
raise error.TestFail('Token verification failed.')
# Erase the chaps database directory.
shutil.rmtree(dbpath, ignore_errors=True)
if not self.__chaps_init_iteration():
raise error.TestFail('Token verification failed after erasing the '
'database directory.')
# Corrupt each file in the chaps database directory.
for f in os.listdir(dbpath):
utils.system('dd if=/dev/zero of=%s bs=1 count=1000 >/dev/null 2>&1'
% os.path.join(dbpath, f))
if not self.__chaps_init_iteration():
raise error.TestFail('Token verification failed after corrupting '
'the database.')
pkcs11.cleanup_p11_test_token()
def run_once(self):
if pkcs11.is_chaps_enabled():
self.__test_chaps_init()
return
self.__test_erase_everything()
self.__test_erase_token()
self.__test_erase_pkcs11dir()
self.__test_broken_symlinks()
self.__test_missing_token_files()
self.__test_corrupt_token()