mirror of
https://github.com/stefanberger/swtpm.git
synced 2026-01-15 13:57:05 +00:00
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>
332 lines
8.4 KiB
Bash
Executable File
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
|