blob: 4c154a6d5deaafe4f1f24eede7ead4d437080793 [file] [log] [blame]
#!/usr/bin/env bash
# For the license, see the LICENSE file in the root directory.
#set -x
TOPBUILD=${abs_top_builddir:-$(dirname "$0")/..}
TESTDIR=${abs_top_testdir:-$(dirname "$0")}
SWTPM_LOCALCA=${TOPBUILD}/src/swtpm_localca/swtpm_localca
workdir="$(mktemp -d)" || exit 1
# Have softhsm_setup use 'workdir'.
export SOFTHSM_SETUP_CONFIGDIR="${workdir}"
# Since we will be using the pkcs11 module as well via certtool
# we have to set the environment variable to point to its config file.
# This has to be the same as for swtpm_setup sets it.
export SOFTHSM2_CONF="${workdir}"/softhsm2.conf
ek="80" # 2048 bit key must have highest bit set
for ((i = 1; i < 256; i++)); do
ek="${ek}$(printf "%02x" "$i")"
done
ISSUERCERT="${workdir}/issuercert.pem"
CERTSERIAL="${workdir}/certserial"
PATH="${TOPBUILD}/src/swtpm_cert:$PATH"
source "${TESTDIR}/common"
if ${CERTTOOL} --help | grep -q -E "\-\-verify-profile"; then
verify_profile="--verify-profile=medium"
fi
trap "cleanup" SIGTERM EXIT
function cleanup()
{
rm -rf "${workdir}"
"${TESTDIR}/softhsm_setup" teardown
}
skip_test_linked_with_asan "${SWTPM_LOCALCA}"
unset GNUTLS_PIN
export PIN="abcdef"
# Generate the PKCS11 token and key; it uses env. variable 'PIN'
if ! msg=$("${TESTDIR}/softhsm_setup" setup 2>&1); then
echo -e "Could not setup softhsm:\n${msg}"
echo "softhsm needs to be v2.3.0 or greater and pkcs11 correctly configured"
exit 77
fi
pkcs11uri=$(echo "${msg}" | sed -n 's|^keyuri: \(.*\)|\1|p')
# Now we need to create the root CA ...
template="${workdir}/template"
cakey="${workdir}/swtpm-localca-rootca-privkey.pem"
cacert="${workdir}/swtpm-localca-rootca-cert.pem"
# first the private key
if ! msg=$(${CERTTOOL} \
--generate-privkey \
--outfile "${cakey}" \
2>&1); then
echo "Could not create root-CA key ${cakey}."
echo "${msg}"
exit 1
fi
chmod 640 "${cakey}"
# now the self-signed certificate
cat <<_EOF_ > "${template}"
cn=swtpm-localca-rootca
ca
cert_signing_key
expiration_days = 3650
_EOF_
if ! msg=$(${CERTTOOL} \
--generate-self-signed \
--template "${template}" \
--outfile "${cacert}" \
--load-privkey "${cakey}" \
2>&1); then
echo "Could not create root CA."
echo "${msg}"
exit 1
fi
# And now create the intermediate CA with the pkcs11 URI key
pubkey="${workdir}/swtpm-localca-interm-pubkey.pem"
if ! msg=$(GNUTLS_PIN=${PIN} ${CERTTOOL} \
--load-privkey "${pkcs11uri}" \
--pubkey-info \
--outfile "${pubkey}"); then
echo "Could not get public key for pkcs11 uri key ($pkcs11uri}."
echo "${msg}"
exit 1
fi
cat <<_EOF_ > "${template}"
cn=swtpm-localca
ca
cert_signing_key
expiration_days = 3650
_EOF_
if ! msg=$(GNUTLS_PIN=${PIN} ${CERTTOOL} \
--generate-certificate \
--template "${template}" \
--outfile "${ISSUERCERT}" \
--load-ca-privkey "${cakey}" \
--load-ca-certificate "${cacert}" \
--load-privkey "${pkcs11uri}" \
--load-pubkey "${pubkey}" \
2>&1); then
echo "Could not create intermediate CA"
echo "${msg}"
exit 1
fi
echo -n 1 > "${CERTSERIAL}"
# Now we can create the config files
cat <<_EOF_ > "${workdir}/swtpm-localca.conf"
statedir = ${workdir}
signingkey = $(echo "${pkcs11uri}" | sed 's|;|\\;|g')
issuercert = ${ISSUERCERT}
certserial = ${CERTSERIAL}
SWTPM_PKCS11_PIN = ${PIN}
_EOF_
cat <<_EOF_ > "${workdir}/swtpm-localca.options"
--tpm-manufacturer IBM
--tpm-model swtpm-libtpms
--tpm-version 2
--platform-manufacturer Fedora
--platform-version 2.1
--platform-model QEMU
_EOF_
# the following contains the test parameters and
# expected key usage
for testparams in \
"--allow-signing|Digital signature" \
"--allow-signing --decryption|Digital signature,Key encipherment" \
"--decryption|Key encipherment" \
"|Key encipherment";
do
params=$(echo "${testparams}" | cut -d"|" -f1)
usage=$(echo "${testparams}" | cut -d"|" -f2)
if ! msg=$(${SWTPM_LOCALCA} \
--type ek \
--ek "${ek}" \
--dir "${workdir}" \
--vmid test \
--tpm2 \
--configfile "${workdir}/swtpm-localca.conf" \
--optsfile "${workdir}/swtpm-localca.options" \
--tpm-spec-family 2.0 --tpm-spec-revision 146 --tpm-spec-level 0 \
${params:+${params}} 2>&1); then
echo "Error: Test with parameters '$params' failed."
echo "${msg}"
if [[ "${msg}" =~ The\ requested\ PKCS\ #11\ object\ is\ not\ available ]]; then
# could be related to i386 executables on x86_64 host and
# libsofthsm.so only available for x86_64...
exit 77
fi
exit 1
fi
if [ ! -r "${workdir}/ek.cert" ]; then
echo "${msg}"
echo "Error: ${workdir}/ek.cert was not created."
exit 1
fi
OIFS="$IFS"
IFS=","
for u in $usage; do
if ! ${CERTTOOL} -i \
--inder --infile "${workdir}/ek.cert" | \
grep "Key Usage" -A2 | \
grep -q "$u"; then
echo "Error: Could not find key usage $u in key created " \
"with $params."
else
echo "Found '$u'"
fi
done
IFS="$OIFS"
${CERTTOOL} \
-i \
--inder --infile "${workdir}/ek.cert" \
--outfile "${workdir}/ek.pem"
if ! GNUTLS_PIN=${PIN} ${CERTTOOL} \
--verify \
${verify_profile} \
--load-ca-certificate "${ISSUERCERT}" \
--infile "${workdir}/ek.pem"; then
echo "Error: Could not verify certificate chain."
exit 1
fi
done
exit 0