| #!/usr/bin/env bash |
| |
| # For the license, see the LICENSE file in the root directory. |
| #set -x |
| |
| TOPBUILD=${abs_top_builddir:-$(dirname "$0")/..} |
| TOPSRC=${abs_top_srcdir:-$(dirname "$0")/..} |
| TESTDIR=${abs_top_testdir:-$(dirname "$0")} |
| |
| SWTPM_LOCALCA=${TOPBUILD}/src/swtpm_localca/swtpm_localca |
| |
| workdir="$(mktemp -d)" || exit 1 |
| if [ $? -ne 0 ]; then |
| exit 1 |
| fi |
| |
| # 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 |
| |
| SIGNINGKEY=${workdir}/signingkey.pem |
| ISSUERCERT=${workdir}/issuercert.pem |
| CERTSERIAL=${workdir}/certserial |
| |
| PATH=${TOPBUILD}/src/swtpm_cert:$PATH |
| |
| source ${TESTDIR}/common |
| |
| 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' |
| msg=$(${TESTDIR}/softhsm_setup setup 2>&1) |
| if [ $? -ne 0 ]; 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 |
| msg=$(${CERTTOOL} \ |
| --generate-privkey \ |
| --outfile ${cakey} \ |
| ${passparam} \ |
| 2>&1) |
| if [ $? -ne 0 ]; 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_ |
| |
| msg=$(${CERTTOOL} \ |
| --generate-self-signed \ |
| --template ${template} \ |
| --outfile ${cacert} \ |
| --load-privkey ${cakey} \ |
| 2>&1) |
| if [ $? -ne 0 ]; 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 |
| |
| msg=$(GNUTLS_PIN=${PIN} ${CERTTOOL} \ |
| --load-privkey ${pkcs11uri} \ |
| --pubkey-info \ |
| --outfile ${pubkey}) |
| if [ $? -ne 0 ]; 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_ |
| |
| 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) |
| if [ $? -ne 0 ]; 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) |
| |
| 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} 2>&1) |
| if [ $? -ne 0 ]; 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 [ -z "$(${CERTTOOL} -i \ |
| --inder --infile ${workdir}/ek.cert | \ |
| grep "Key Usage" -A2 | \ |
| grep "$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 |
| |
| GNUTLS_PIN=${PIN} ${CERTTOOL} \ |
| --verify \ |
| --load-ca-certificate ${ISSUERCERT} \ |
| --infile ${workdir}/ek.pem |
| if [ $? -ne 0 ]; then |
| echo "Error: Could not verify certificate chain." |
| exit 1 |
| fi |
| done |
| |
| exit 0 |