Skip to content

Commit

Permalink
FAPI TEST: rework test certificate creation
Browse files Browse the repository at this point in the history
* A CA script for initializing the CA was added.
* The EK, the EK certificate and the EK fingerprint is now created
  in main-fapi.c
* The creation of the EK certificate was removed from
  fint-log-compiler.sh
* Unneeded helper programs are removed.

Signed-off-by: Juergen Repp <juergen_repp@web.de>
  • Loading branch information
JuergenReppSIT committed Dec 9, 2023
1 parent 35f952e commit a155675
Show file tree
Hide file tree
Showing 16 changed files with 1,109 additions and 1,036 deletions.
34 changes: 1 addition & 33 deletions Makefile-test.am
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ EXTRA_DIST += $(srcdir)/script/int-log-compiler.sh \
$(srcdir)/script/fint-log-compiler.sh \
$(srcdir)/script/int-log-compiler-common.sh \
$(srcdir)/script/ekca/create_ca.sh \
$(srcdir)/script/ekca/init_ca.sh \
$(srcdir)/script/ekca/ek.cnf \
$(srcdir)/script/ekca/intermed-ca.cnf \
$(srcdir)/script/ekca/root-ca.cnf
Expand All @@ -43,39 +44,6 @@ test_helper_tpm_cmd_tcti_dummy_LDFLAGS = $(TESTS_LDFLAGS)
test_helper_tpm_cmd_tcti_dummy_LDADD = $(TESTS_LDADD)
endif #UNIT

if ENABLE_INTEGRATION
check_PROGRAMS += test/helper/tpm_startup
test_helper_tpm_startup_CFLAGS = $(TESTS_CFLAGS) -I$(srcdir)/test/integration
test_helper_tpm_startup_LDFLAGS = $(TESTS_LDFLAGS)
test_helper_tpm_startup_LDADD = $(TESTS_LDADD)

check_PROGRAMS += test/helper/tpm_transientempty
test_helper_tpm_transientempty_CFLAGS = $(TESTS_CFLAGS) -I$(srcdir)/test/integration
test_helper_tpm_transientempty_LDFLAGS = $(TESTS_LDFLAGS)
test_helper_tpm_transientempty_LDADD = $(TESTS_LDADD)

check_PROGRAMS += test/helper/tpm_dumpstate
test_helper_tpm_dumpstate_CFLAGS = $(TESTS_CFLAGS) -I$(srcdir)/test/integration
test_helper_tpm_dumpstate_LDFLAGS = $(TESTS_LDFLAGS)
test_helper_tpm_dumpstate_LDADD = $(TESTS_LDADD)

check_PROGRAMS += test/helper/tpm_getek
test_helper_tpm_getek_CFLAGS = $(TESTS_CFLAGS) -I$(srcdir)/test/integration
test_helper_tpm_getek_LDFLAGS = $(TESTS_LDFLAGS) -lcrypto
test_helper_tpm_getek_LDADD = $(TESTS_LDADD)

check_PROGRAMS += test/helper/tpm_getek_ecc
test_helper_tpm_getek_ecc_CFLAGS = $(TESTS_CFLAGS) -I$(srcdir)/test/integration
test_helper_tpm_getek_ecc_LDFLAGS = $(TESTS_LDFLAGS) -lcrypto
test_helper_tpm_getek_ecc_LDADD = $(TESTS_LDADD)


check_PROGRAMS += test/helper/tpm_writeekcert
test_helper_tpm_writeekcert_CFLAGS = $(TESTS_CFLAGS) -I$(srcdir)/test/integration
test_helper_tpm_writeekcert_LDFLAGS = $(TESTS_LDFLAGS)
test_helper_tpm_writeekcert_LDADD = $(TESTS_LDADD)
endif #ENABLE_INTEGRATION

### Rules to enerate binary test files for FAPI from b64 files.

if FAPI
Expand Down
14 changes: 14 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -966,11 +966,25 @@ install-data-hook: install-dirs
fi

uninstall-local:
-rm -r -f $(top_builddir)/ca
-rm $(DESTDIR)$(udevrulesdir)/$(udevrulesprefix)tpm-udev.rules
cd $(DESTDIR)$(man3dir) && \
[ -L Tss2_TctiLdr_Initialize_Ex.3 ] && \
rm -f Tss2_TctiLdr_Initialize_Ex.3 || true

clean-hook:
-rm -r -f $(top_builddir)/ca

check-hook:
-rm -r -f $(top_builddir)/ca

prepare-check:
if INIT_CA
$(top_srcdir)/script/ekca/init_ca.sh $(top_builddir)
endif

check: prepare-check

EXTRA_DIST += \
doc/doxygen.dox \
doc/coding_standard_c.md \
Expand Down
2 changes: 2 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,8 @@ AS_IF([test "x$enable_self_generated_certificate" = xyes],
[AC_DEFINE([SELF_GENERATED_CERTIFICATE], [1], [Allow usage of self generated root certificate])],
[AS_IF([test "x$integration_tcti" != "xdevice"], [AC_DEFINE([FAPI_TEST_EK_CERT_LESS], [1], [Perform integration tests without EK certificate verification])])])

AM_CONDITIONAL([INIT_CA], [test "x$enable_self_generated_certificate" == xyes])

AS_IF([test "x$enable_integration" = "xyes" && test "x$enable_self_generated_certificate" != "xyes" && test "x$integration_tcti" != "xdevice"],
[AC_MSG_WARN([Running integration tests without EK certificate verification, use --enable-self-generated-certificate for full test coverage])])

Expand Down
130 changes: 130 additions & 0 deletions script/ekca/init_ca.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#!/usr/bin/env bash

#set -x

#set -euf
OS=$(uname)
DATE_FMT_BEFORE=""
DATE_FMT_AFTER=""
SED_CMD=""

if [ "$OS" == "Linux" ]; then
DATE_FMT_BEFORE="+%y%m%d000000Z -u -d -1day"
DATE_FMT_AFTER="+%y%m%d000000Z -u -d +10years+1day"
SED_CMD="sed -i"
elif [ "$OS" == "FreeBSD" ]; then
DATE_FMT_BEFORE="-u -v-1d +%y%m%d000000Z"
DATE_FMT_AFTER="-u -v+10y +%y%m%d000000Z"
SED_CMD="sed -i '' -e"
fi

EKCADIR="$(dirname $(realpath ${0}))/"
CA_DIR="${1-.}/ca"

if test -e $CA_DIR; then
exit
fi
mkdir -p $CA_DIR

pushd "$CA_DIR"

mkdir root-ca
pushd root-ca

mkdir certreqs certs crl newcerts private
touch root-ca.index
echo 00 > root-ca.crlnum
echo 1000 > root-ca.serial
echo "123456" > pass.txt

cp "${EKCADIR}/root-ca.cnf" ./
export OPENSSL_CONF=./root-ca.cnf
ROOT_URL="file:$ROOTCRT"
${SED_CMD} "s|ROOTCRT|$ROOT_URL|g" $OPENSSL_CONF
ROOT_URL="file:$ROOTCRL"
${SED_CMD} "s|ROOTCRL|$ROOT_URL|g" $OPENSSL_CONF
openssl req -new -out root-ca.req.pem -passout file:pass.txt

#
# Create self signed root certificate
#

openssl ca -selfsign \
-in root-ca.req.pem \
-out root-ca.cert.pem \
-extensions root-ca_ext \
-startdate `date ${DATE_FMT_BEFORE}` \
-enddate `date ${DATE_FMT_AFTER}` \
-passin file:pass.txt -batch

openssl x509 -outform der -in root-ca.cert.pem -out root-ca.cert.crt

openssl verify -verbose -CAfile root-ca.cert.pem \
root-ca.cert.pem

openssl ca -gencrl -cert root-ca.cert.pem \
-out root-ca.cert.crl.pem -passin file:pass.txt
openssl crl -in root-ca.cert.crl.pem -outform DER -out root-ca.cert.crl

popd #root-ca

#
# Create intermediate certificate
#
mkdir intermed-ca
pushd intermed-ca

mkdir certreqs certs crl newcerts private
touch intermed-ca.index
echo 00 > intermed-ca.crlnum
echo 2000 > intermed-ca.serial
echo "abcdef" > pass.txt

cp "${EKCADIR}/intermed-ca.cnf" ./
export OPENSSL_CONF=./intermed-ca.cnf

# Adapt CRT URL to current test directory
${SED_CMD} "s|ROOTCRT|$ROOT_URL|g" $OPENSSL_CONF

openssl req -new -out intermed-ca.req.pem -passout file:pass.txt

openssl rsa -inform PEM -in private/intermed-ca.key.pem \
-outform DER -out private/intermed-ca.key.der -passin file:pass.txt

cp intermed-ca.req.pem \
../root-ca/certreqs/

INTERMED_URL="file:$INTERMEDCRT"
${SED_CMD} "s|INTERMEDCRT|$INTERMED_URL|g" $OPENSSL_CONF

pushd ../root-ca
export OPENSSL_CONF=./root-ca.cnf

openssl ca \
-in certreqs/intermed-ca.req.pem \
-out certs/intermed-ca.cert.pem \
-extensions intermed-ca_ext \
-startdate `date ${DATE_FMT_BEFORE}` \
-enddate `date ${DATE_FMT_AFTER}` \
-passin file:pass.txt -batch

openssl x509 -outform der -in certs/intermed-ca.cert.pem \
-out certs/intermed-ca.cert.crt

openssl verify -verbose -CAfile root-ca.cert.pem \
certs/intermed-ca.cert.pem

cp certs/intermed-ca.cert.pem \
../intermed-ca

cp certs/intermed-ca.cert.crt \
../intermed-ca

popd #root-ca

export OPENSSL_CONF=./intermed-ca.cnf
openssl ca -gencrl -cert ../root-ca/certs/intermed-ca.cert.pem \
-out intermed-ca.crl.pem -passin file:pass.txt
openssl crl -in intermed-ca.crl.pem -outform DER -out intermed-ca.crl

popd #intermed-ca
132 changes: 9 additions & 123 deletions script/fint-log-compiler.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,109 +42,8 @@ echo "TPM20TEST_TCTI=${TPM20TEST_TCTI}"

while true; do

if [[ ${TPM20TEST_TCTI} != *device* ]]; then
env TPM20TEST_TCTI="${TPM20TEST_TCTI}" \
TCTI_PCAP_FILE="${TCTI_PCAP_FILE}" \
G_MESSAGES_DEBUG=all ./test/helper/tpm_startup
if [ $? -ne 0 ]; then
echo "TPM_StartUp failed"
ret=99
break
fi
else
env TPM20TEST_TCTI=${TPM20TEST_TCTI} \
TCTI_PCAP_FILE="${TCTI_PCAP_FILE}" \
G_MESSAGES_DEBUG=all ./test/helper/tpm_transientempty
if [ $? -ne 0 ]; then
echo "TPM transient area not empty => skipping"
ret=99
break
fi
fi

# Certificate generation for simulator tests
if [[ ${TPM20TEST_TCTI} != *device* ]]; then
EKPUB_FILE=${TEST_BIN}_ekpub.pem
EKCERT_FILE=${TEST_BIN}_ekcert.crt
EKCERT_PEM_FILE=${TEST_BIN}_ekcert.pem

env TPM20TEST_TCTI="${TPM20TEST_TCTI}" \
TCTI_PCAP_FILE="${TCTI_PCAP_FILE}" \
G_MESSAGES_DEBUG=all ./test/helper/tpm_getek ${EKPUB_FILE}
if [ $? -ne 0 ]; then
echo "TPM_getek failed"
ret=99
break
fi

EKECCPUB_FILE=${TEST_BIN}_ekeccpub.pem
EKECCCERT_FILE=${TEST_BIN}_ekecccert.crt
EKECCCERT_PEM_FILE=${TEST_BIN}_ekecccert.pem

env TPM20TEST_TCTI="${TPM20TEST_TCTI}" \
TCTI_PCAP_FILE="${TCTI_PCAP_FILE}" \
G_MESSAGES_DEBUG=all ./test/helper/tpm_getek_ecc ${EKECCPUB_FILE}
if [ $? -ne 0 ]; then
echo "TPM_getek_ecc failed"
ret=99
break
fi

INTERMEDCA_FILE=${TEST_BIN}_intermedecc-ca
ROOTCA_FILE=${TEST_BIN}_root-ca

SCRIPTDIR="$(dirname $(realpath $0))/"
${SCRIPTDIR}/ekca/create_ca.sh "${EKPUB_FILE}" "${EKECCPUB_FILE}" "${EKCERT_FILE}" \
"${EKECCCERT_FILE}" "${INTERMEDCA_FILE}" "${ROOTCA_FILE}" >${TEST_BIN}_ca.log 2>&1
if [ $? -ne 0 ]; then
echo "ek-cert ca failed"
ret=99
break
fi

# Determine the fingerprint of the RSA EK public.
FINGERPRINT=$(openssl pkey -pubin -inform PEM -in ${EKPUB_FILE} -outform DER | shasum -a 256 | cut -f 1 -d ' ')
export FAPI_TEST_FINGERPRINT=" { \"hashAlg\" : \"sha256\", \"digest\" : \"${FINGERPRINT}\" }"
openssl x509 -inform DER -in ${EKCERT_FILE} -outform PEM -out ${EKCERT_PEM_FILE}
export FAPI_TEST_CERTIFICATE="file:${EKCERT_PEM_FILE}"

# Determine the fingerprint of the RSA EK public.
FINGERPRINT_ECC=$(openssl pkey -pubin -inform PEM -in ${EKECCPUB_FILE} -outform DER | shasum -a 256 | cut -f 1 -d ' ')
export FAPI_TEST_FINGERPRINT_ECC=" { \"hashAlg\" : \"sha256\", \"digest\" : \"${FINGERPRINT_ECC}\" }"
openssl x509 -inform DER -in ${EKECCCERT_FILE} -outform PEM -out ${EKECCCERT_PEM_FILE}
export FAPI_TEST_CERTIFICATE_ECC="file:${EKECCCERT_PEM_FILE}"

cat $EKCERT_FILE | \
env TPM20TEST_TCTI="${TPM20TEST_TCTI}" \
TCTI_PCAP_FILE="${TCTI_PCAP_FILE}" \
G_MESSAGES_DEBUG=all ./test/helper/tpm_writeekcert 1C00002
if [ $? -ne 0 ]; then
echo "TPM_writeekcert failed"
ret=99
break
fi

cat $EKECCCERT_FILE | \
env TPM20TEST_TCTI="${TPM20TEST_TCTI}" \
TCTI_PCAP_FILE="${TCTI_PCAP_FILE}" \
G_MESSAGES_DEBUG=all ./test/helper/tpm_writeekcert 1C0000A
if [ $? -ne 0 ]; then
echo "TPM_writeekcert failed"
ret=99
fi
fi # certificate generation

TPMSTATE_FILE1=${TEST_BIN}_state1
TPMSTATE_FILE2=${TEST_BIN}_state2

env TPM20TEST_TCTI="${TPM20TEST_TCTI}" \
TCTI_PCAP_FILE="${TCTI_PCAP_FILE}" \
G_MESSAGES_DEBUG=all ./test/helper/tpm_dumpstate>${TPMSTATE_FILE1}
if [ $? -ne 0 ]; then
echo "Error during dumpstate"
ret=99
break
fi
INTERMEDCA_FILE=ca/intermed-ca/intermed-ca.cert
ROOTCA_FILE=ca/root-ca/root-ca.cert

echo "Execute the test script"
if [[ ${TPM20TEST_TCTI} == *device* ]]; then
Expand All @@ -154,34 +53,21 @@ if [[ ${TPM20TEST_TCTI} == *device* ]]; then
G_MESSAGES_DEBUG=all ${@: -1}
else
# Run test with generated certificate.

EKECCCERT_PEM_FILE=${TEST_BIN}_ekecccert.pem
export FAPI_TEST_CERTIFICATE_ECC="${EKECCCERT_PEM_FILE}"
EKCERT_PEM_FILE=${TEST_BIN}_ekcert.pem
export FAPI_TEST_CERTIFICATE="${EKCERT_PEM_FILE}"

env TPM20TEST_TCTI="${TPM20TEST_TCTI}" \
TCTI_PCAP_FILE="${TCTI_PCAP_FILE}" \
FAPI_TEST_ROOT_CERT=${ROOTCA_FILE}.pem \
FAPI_TEST_INT_CERT=${INTERMEDCA_FILE}.pem \
G_MESSAGES_DEBUG=all ${@: -1}
fi
ret=$?
echo "Script returned $ret"

#We check the state before a reboot to see if transients and NV were chagned.
env TPM20TEST_TCTI="${TPM20TEST_TCTI}" \
TCTI_PCAP_FILE="${TCTI_PCAP_FILE}" \
G_MESSAGES_DEBUG=all ./test/helper/tpm_dumpstate>${TPMSTATE_FILE2}
if [ $? -ne 0 ]; then
echo "Error during dumpstate"
ret=99
break
fi

if [ "$(cat ${TPMSTATE_FILE1})" != "$(cat ${TPMSTATE_FILE2})" ]; then
echo "TPM changed state during test"
echo "State before ($TPMSTATE_FILE1):"
cat ${TPMSTATE_FILE1}
echo "State after ($TPMSTATE_FILE2):"
cat ${TPMSTATE_FILE2}
ret=1
break
fi

#TODO: Add a tpm-restart/reboot here

break
Expand Down
10 changes: 10 additions & 0 deletions src/tss2-fapi/api/Fapi_Provision.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
#define ECC_EK_TEMPLATE_NV_INDEX 0x01c0000c
#define ECC_SM2_EK_TEMPLATE_NV_INDEX 0x01c0001b

#define FAPI_TEST_ROOT_CERT_FILE "./ca/root-ca/root-ca.cert.pem"
#define FAPI_TEST_INT_CERT_FILE "./ca/intermed-ca/intermed-ca.cert.pem"

/** Error cleanup of provisioning
*
* The profile directory will be deleted.
Expand Down Expand Up @@ -891,6 +894,10 @@ Fapi_Provision_Finish(FAPI_CONTEXT *context)
#ifdef SELF_GENERATED_CERTIFICATE
#pragma message ( "*** Allow self generated certifcate ***" )
root_ca_file = getenv("FAPI_TEST_ROOT_CERT");

if (!root_ca_file && ifapi_io_path_exists(FAPI_TEST_ROOT_CERT_FILE)) {
root_ca_file = FAPI_TEST_ROOT_CERT_FILE;
}
#endif
if (!root_ca_file) {
context->state = PROVISION_EK_CHECK_CERT;
Expand All @@ -917,6 +924,9 @@ Fapi_Provision_Finish(FAPI_CONTEXT *context)
#ifdef SELF_GENERATED_CERTIFICATE
#pragma message ( "*** Allow self generated certifcate ***" )
int_ca_file = getenv("FAPI_TEST_INT_CERT");
if (!int_ca_file && ifapi_io_path_exists(FAPI_TEST_INT_CERT_FILE)) {
int_ca_file = FAPI_TEST_INT_CERT_FILE;
}
#endif
if (!int_ca_file) {
context->state = PROVISION_EK_CHECK_CERT;
Expand Down
Loading

0 comments on commit a155675

Please sign in to comment.