swtpm/tests/test_samples_create_tpmca
Stefan Berger 930c7ba16e tests: Allow seccomp override w/ SWTPM_TEST_SECCOMP_OPT env var
The Ubuntu (PPA) build system executes the build on an environment that
has problems with seccomp profiles. It does not allow us to run the test
suite with swtpm applying its seccomp profile since it fails with a
'bad system call' error. To work around this we introduce the env. variable
SWTPM_TEST_SECCOMP_OPT that we can set to "--seccomp action=none" to avoid
having swtpm apply it seccomp profile.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
2020-01-15 15:49:51 -05:00

332 lines
8.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# For the license, see the LICENSE file in the root directory.
if [ "$(id -u)" -ne 0 ]; then
echo "Need to be root to run this test."
exit 77
fi
# tpmtool is not packaged everywhere ...
if [ -z "$(type -P tpmtool)" ]; then
echo "Could not find tpmtool in PATH"
exit 77
fi
ROOT=${abs_top_builddir:-$(dirname "$0")/..}
TESTDIR=${abs_top_testdir:=$(dirname "$0")}
SRCDIR=${abs_top_srcdir:-$(dirname "$0")/..}
SWTPM_SETUP=${ROOT}/src/swtpm_setup/swtpm_setup
SWTPM_CREATE_TPMCA=${SRCDIR}/samples/swtpm-create-tpmca
SWTPM_LOCALCA=${SRCDIR}/samples/swtpm-localca
SWTPM=${ROOT}/src/swtpm/swtpm
SWTPM_IOCTL=${ROOT}/src/swtpm_ioctl/swtpm_ioctl
SWTPM_INTERFACE=socket+socket
SWTPM_SERVER_NAME=localhost
SWTPM_SERVER_PORT=65434
SWTPM_CTRL_PORT=65435
TCSD_LISTEN_PORT=65436
SRK_PASSWORD=srk
OWNER_PASSWORD=owner
workdir=$(mktemp -d)
TCSD_CONF=${workdir}/tcsd.conf
TCSD_SYSTEM_PS_FILE=${workdir}/system_ps_file
TCSD_PIDFILE=${workdir}/tcsd.pid
SWTPM_LOCALCA_DIR=${workdir}/localca
SWTPM_LOCALCA_CONF=${workdir}/localca/swtpm-localca.conf
function cleanup()
{
if [ -n "${TCSD_PID}" ]; then
kill_quiet -15 ${TCSD_PID}
fi
if [ -n "${SWTPM_PID}" ]; then
kill_quiet -9 ${SWTPM_PID}
fi
if [ -n "${BASH_PID}" ]; then
kill_quiet -9 ${BASH_PID}
fi
rm -rf ${workdir}
}
trap "cleanup" SIGTERM EXIT
source ${TESTDIR}/common
case "$(uname -s)" in
Darwin)
CERTTOOL=gnutls-certtool;;
*)
CERTTOOL=certtool;;
esac
PATH=${ROOT}/src/swtpm_bios:${ROOT}/src/swtpm_cert:${PATH}
# run the test with the given owner and SRK passwords
# @param1: owner password; empty means to use well known password
# @param2: SRK password; empty means to use well known password
# @param3: vTPM is a TPM 2.0
function run_test() {
local owner_password="$1"
local srk_password="$2"
local vtpm_is_tpm2=$3
local params certinfo regex regexs fil i skip
rm -rf ${workdir}/*
cat <<_EOF_ > ${workdir}/swtpm_setup.conf
create_certs_tool=${SWTPM_LOCALCA}
create_certs_tool_config=${workdir}/swtpm-localca.conf
create_certs_tool_options=/dev/null
_EOF_
params=""
if [ -n "${owner_password}" ]; then
params="${params} --ownerpass ${owner_password}"
else
params="${params} --owner-well-known"
fi
if [ -n "${srk_password}" ]; then
params="${params} --srkpass ${srk_password}"
else
params="${params} --srk-well-known"
fi
# First setup the TPM and take ownership of it and set SRK password
$SWTPM_SETUP \
--runas root \
--tpm-state ${workdir} \
--logfile ${workdir}/logfile \
--config ${workdir}/swtpm_setup.conf \
--tpm "${SWTPM_EXE} socket ${SWTPM_TEST_SECCOMP_OPT}" \
--swtpm_ioctl ${SWTPM_IOCTL} \
--take-ownership \
${params} \
--tcsd-system-ps-file ${TCSD_SYSTEM_PS_FILE} &>/dev/null
if [ $? -ne 0 ]; then
echo "Error: Could not run $SWTPM_SETUP."
echo "Setup Logfile:"
cat ${workdir}/logfile
exit 1
fi
echo "Successfully took ownership of TPM and set owner and SRK passwords."
run_swtpm ${SWTPM_INTERFACE} \
--flags not-need-init \
--tpmstate dir=${workdir}
swtpm_open_cmddev ${SWTPM_INTERFACE} 100
# Startup the TPM
res="$(swtpm_cmd_tx ${SWTPM_INTERFACE} '\x00\xC1\x00\x00\x00\x0C\x00\x00\x00\x99\x00\x01')"
exp=' 00 c4 00 00 00 0a 00 00 00 00'
if [ "$res" != "$exp" ]; then
echo "Error: Did not get expected result from TPM_Startup(ST_Clear)"
echo "expected: $exp"
echo "received: $res"
exit 1
fi
# Setup the TCSD config file and start TCSD with it
cat <<_EOF_ > ${TCSD_CONF}
port = ${TCSD_LISTEN_PORT}
system_ps_file = ${TCSD_SYSTEM_PS_FILE}
_EOF_
chown tss:tss ${TCSD_CONF}
chmod 0600 ${TCSD_CONF}
bash -c "TCSD_USE_TCP_DEVICE=1 TCSD_TCP_DEVICE_PORT=${SWTPM_SERVER_PORT} tcsd -c ${TCSD_CONF} -e -f &>/dev/null & echo \$! > ${TCSD_PIDFILE}; wait" &
BASH_PID=$!
if wait_for_file ${TCSD_PIDFILE} 3; then
echo "Error: Could not get TCSD's PID file"
exit 1
fi
TCSD_PID=$(cat ${TCSD_PIDFILE})
kill_quiet -0 ${TCSD_PID}
if [ $? -ne 0 ]; then
echo "Error: TCSD with pid ${TCSD_PID} must have terminated"
exit 1
fi
if [ -n "${srk_password}" ]; then
params="--srk-password ${srk_password}"
else
params=""
fi
${SWTPM_CREATE_TPMCA} \
--dir ${SWTPM_LOCALCA_DIR} \
${params} \
--register \
--group tss \
--tss-tcsd-port ${TCSD_LISTEN_PORT} \
--outfile ${SWTPM_LOCALCA_CONF} &>/dev/null
if [ $? -ne 0 ]; then
echo "Error: Could not create TPM CA"
exit 1
fi
for fil in \
swtpm-localca-rootca-cert.pem \
swtpm-localca-rootca-privkey.pem \
swtpm-localca-tpmca-cert.pem \
swtpm-localca-tpmca-pubkey.pem; do
if [ ! -r ${SWTPM_LOCALCA_DIR}/${fil} ]; then
echo "Error: TPM CA tool did not create file ${fil}."
exit 1
fi
done
params=""
if [ -n "${srk_password}" ]; then
params="^parentkey_password ="
fi
for regex in \
"^statedir = " \
"^signingkey = " \
"^issuercert = " \
"^certserial = " \
"^TSS_TCSD_HOSTNAME = " \
"^TSS_TCSD_PORT = " \
${params}; do
if [ -n "${regex}" ] && \
[ -z "$(grep -E "${regex}" ${SWTPM_LOCALCA_CONF})" ]; then
echo "Error: Could not find regex '${line}' in CA config file."
cat ${SWTPM_LOCALCA_CONF}
exit 1
fi
done
params=""
if [ ${vtpm_is_tpm2} -ne 0 ]; then
params="--tpm2"
skip=0
else
skip=7 # header in cert
fi
# make sure we can actually sign with this new certificate
${SWTPM_LOCALCA} \
--type ek \
--ek x=739192d8f1004283957a7b1568d610b41c637ccc114aadcac4908c20456468fa,y=59f63ac06f8011f6fdd1460c6bc8e3e0a2d090d4fc188c7e04870e06795ce8ae \
--dir ${workdir} --vmid test \
${params} \
--tpm-spec-family 2.0 --tpm-spec-revision 146 --tpm-spec-level 00 \
--tpm-model swtpm --tpm-version 20170101 --tpm-manufacturer IBM \
--configfile ${SWTPM_LOCALCA_CONF} \
--optsfile /dev/null
if [ $? -ne 0 ]; then
echo "Error: The CA could not sign with the new certificate"
exit 1
fi
if [ ! -f ${workdir}/ek.cert ]; then
echo "Error: The CA did not produce a certificate"
exit 1
fi
# cert was for example 541 bytes long
if [ $(get_filesize ${workdir}/ek.cert) -lt 500 ]; then
echo "Error: The certificate's size is dubious"
ls -l ${workdir}/ek.cert
exit 1
fi
# Check the contents of the certificate
certinfo=$(dd if=${workdir}/ek.cert bs=1 skip=$skip status=none | \
$CERTTOOL -i --inder)
regexs=('^[[:space:]]+2.23.133.8.1$'
'^[[:space:]]+directoryName:.*(,)?2.23.133.2.3=.*'
'^[[:space:]]+directoryName:.*(,)?2.23.133.2.2=.*'
'^[[:space:]]+directoryName:.*(,)?2.23.133.2.1=.*'
'^[[:space:]]+Certificate Authority \(CA\): FALSE$'
'^[[:space:]]+Unknown extension 2.5.29.9 \(not critical\):$'
'^[[:space:]]+Hexdump: 3019301706056781050210310e300c0c03322e3002010002020092$')
if [ ${vtpm_is_tpm2} -ne 0 ]; then
# TPM 2.0; due to ecc: Key agreement
regexs+=('^[[:space:]]+Key agreement\.$'
'^[[:space:]]+Signature Algorithm: RSA-SHA256$')
else
regexs+=('^[[:space:]]+Key encipherment\.$'
'^[[:space:]]+Signature Algorithm: RSA-SHA1$')
fi
for ((i=0; i < ${#regexs}; i++)); do \
if [ -n "${regexs[$i]}" ] && \
[ -z "$(echo "${certinfo}" | grep -E "${regexs[$i]}")" ]; then
echo "Error: Could not match regex '${regexs[$i]}' with certificate info:"
echo "${certinfo}"
exit 1
fi
done
# Send SIGTERM to TCSD
kill_quiet -15 ${TCSD_PID}
# Shut down TPM
run_swtpm_ioctl ${SWTPM_INTERFACE} -s
if [ $? -ne 0 ]; then
echo "Error: Could not shut down the ${SWTPM_INTERFACE} TPM."
exit 1
fi
if wait_process_gone ${SWTPM_PID} 4; then
echo "Error: ${SWTPM_INTERFACE} TPM should not be running anymore."
exit 1
fi
if wait_process_gone ${SWTPM_PID} 4; then
echo "Error: tcsd should not be running anymore."
exit 1
fi
} # run_test
run_test "${OWNER_PASSWORD}" "${SRK_PASSWORD}" 1
echo "Test 1: OK"
run_test "${OWNER_PASSWORD}" "${SRK_PASSWORD}" 0
echo "Test 2: OK"
run_test "" "${SRK_PASSWORD}" 1
echo "Test 3: OK"
run_test "" "${SRK_PASSWORD}" 0
echo "Test 4: OK"
# Repeat the test with the SRK having the well known password of 20 zero bytes
# We will have to check the help screen of swtpm-create-tpmca for whether
# it supports it, which in turn depends on tpmtool supporting it...
if [ -n "$(${SWTPM_CREATE_TPMCA} --help | grep "use 'well known' password if")" ]; then
run_test "${OWNER_PASSWORD}" "" 1
echo "Test 5: OK"
run_test "${OWNER_PASSWORD}" "" 0
echo "Test 6: OK"
run_test "" "" 1
echo "Test 7: OK"
run_test "" "" 0
echo "Test 8: OK"
else
if [ -n "$(tpmtool --help | grep srk-well-known)" ]; then
echo "Error: tpmtool seems to support --srk-well-known"
exit 1
fi
echo "tpmtool does not seem to support --srk-well-known"
echo "Tests 5..8: SKIP"
fi
exit 0