Skip to content

Commit

Permalink
Merge 345a468 into 346b3d6
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanberger committed Feb 22, 2023
2 parents 346b3d6 + 345a468 commit 2a12583
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 60 deletions.
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ selinux-install selinux-uninstall:
endif

syntax-check:
@cd samples && $(MAKE) syntax-check
@cd tests && $(MAKE) syntax-check

.PHONY: selinux-install selinux-uninstall syntax-check
12 changes: 7 additions & 5 deletions man/man8/swtpm-create-tpmca.pod
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ B<swtpm-create-tpmca [OPTIONS]>

=head1 DESCRIPTION

B<swtpm-create-tpmca> is a tool to create a TPM 1.2 based CA that
B<swtpm-create-tpmca> is a tool to create a TPM 1.2 or TPM 2 based CA that
can be used by B<swtpm_localca> to sign EK and platform certificates.
The CA uses a GnuTLS key to sign certificates. To do this,
GnuTLS talks to the TPM 1.2 using the B<tcsd> (TrouSerS) daemon.
The CA uses a GnuTLS key to sign certificates. If a TPM 1.2 is used then
GnuTLS will talk to the TPM 1.2 using the B<tcsd> (TrouSerS) daemon.
If a TPM 2 is used then the Intel pkcs11 driver and its tools (tpm2_ptool)
are also required.

Since the TPM CA's certificate must be signed by a CA, a root certificate authority
will also be created and will sign this certificate. The root CA's
Expand Down Expand Up @@ -138,8 +140,8 @@ Alternatively, if the host's TPM is a TPM 2 and Intel's TPM 2 stack is
installed, we need to start tpm2-abrmd first and can then create the TPM key
and TPM CA certificate:

#> sudo systemctl start tpm2-abrmd
#> tpm2_ptool init
#> sudo systemctl start tpm2-abrmd # may not be required with recent Intel TPM 2 tools
#> sudo tpm2_ptool init
action: Created
id: 1 # this is the --pid parameter below
#> sudo SWTPM_PKCS11_PIN="mypin 123" SWTPM_PKCS11_SO_PIN=123 /usr/share/swtpm/swtpm-create-tpmca \
Expand Down
4 changes: 4 additions & 0 deletions samples/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,7 @@ EXTRA_DIST= \
swtpm-localca.conf \
swtpm-localca.options \
swtpm_setup.conf

.PHONY: syntax-check
syntax-check:
shellcheck swtpm-create-tpmca
112 changes: 57 additions & 55 deletions samples/swtpm-create-tpmca
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ function get_filesize()
# @param 1: The string to escape
function escape_pkcs11_url()
{
echo "$1" | sed 's/;/\\;/g'
echo "${1//;/\\;}"
}

# Use expect for automating the interaction with the tpmtool
Expand All @@ -57,6 +57,12 @@ function escape_pkcs11_url()
run_tpmtool() {
local prg out rc

if [ -z "$(type -P tpmtool)" ]; then
echo "Could not find tpmtool in PATH (${PATH})."
return 1
fi

# shellcheck disable=SC2124,SC2027
prg="spawn tpmtool "$@"
expect {
\"Enter SRK password:\" {
Expand Down Expand Up @@ -100,31 +106,32 @@ create_localca_cert() {
local msg output

if ! [ -r "${cakey}" ] || ! [ -r "${cacert}" ]; then
msg=$("${CERTTOOL}" \
if ! msg=$("${CERTTOOL}" \
--generate-privkey \
${SWTPM_ROOTCA_PASSWORD:+--password "${SWTPM_ROOTCA_PASSWORD}"} \
--outfile "${cakey}" \
2>&1)
[ $? -ne 0 ] && {
2>&1);
then
logerr "Could not create root-CA key ${cakey}."
logerr "${msg}"
return 1
}
fi
chmod 640 "${cakey}"

echo "cn=swtpm-localca-rootca" > "${template}"
echo "ca" >> "${template}"
echo "cert_signing_key" >> "${template}"
echo "expiration_days = 3650" >> "${template}"
{
echo "cn=swtpm-localca-rootca"
echo "ca"
echo "cert_signing_key"
echo "expiration_days = 3650"
} > "${template}"

msg=$(GNUTLS_PIN="${SWTPM_ROOTCA_PASSWORD}" ${CERTTOOL} \
if ! msg=$(GNUTLS_PIN="${SWTPM_ROOTCA_PASSWORD}" ${CERTTOOL} \
--generate-self-signed \
--template "${template}" \
--outfile "${cacert}" \
--load-privkey "${cakey}" \
2>&1)

if [ $? -ne 0 ]; then
2>&1);
then
logerr "Could not create root CA."
logerr "${msg}"
rm -f "${cakey}" "${template}"
Expand All @@ -151,12 +158,12 @@ create_localca_cert() {
logerr "The env. variable SWTPM_PKCS11_SO_PIN must be set to create token ${label}."
return 1
fi
msg=$(tpm2_ptool addtoken \
if ! msg=$(tpm2_ptool addtoken \
--pid "${pid}" \
--sopin "${SWTPM_PKCS11_SO_PIN}" \
--userpin "${userpin}" \
--label "${label}" 2>&1)
if [ $? -ne 0 ]; then
--label "${label}" 2>&1);
then
logerr "Error: Could not create pkcs11 token"
logerr "${msg}"
return 1
Expand All @@ -169,11 +176,11 @@ create_localca_cert() {
logerr "${msg}"
return 1
fi
msg=$(tpm2_ptool config \
if ! msg=$(tpm2_ptool config \
--key tcti \
--value tabrmd \
--label "${label}")
if [ $? -ne 0 ]; then
--label "${label}");
then
logerr "Error: Could not set config value for tcti key"
logerr "${msg}"
return 1
Expand All @@ -183,26 +190,24 @@ create_localca_cert() {
export GNUTLS_PIN="${userpin}"
# GNUTLS_SO_PIN not needed at this point

msg="$(p11tool --login --list-keys "${tokenurl}" 2>&1)"
if [ $? -eq 0 ]; then
if msg="$(p11tool --login --list-keys "${tokenurl}" 2>&1)"; then
tpmkeyurl=$(echo "${msg}" | \
grep ";object=${keylabel}" | \
sed -n "s/.*URL: //p")
fi
if [ -z "${tpmkeyurl}" ]; then
msg=$(tpm2_ptool addkey \
if ! msg=$(tpm2_ptool addkey \
"--label=${label}" \
"--userpin=${userpin}" \
--algorithm=rsa2048 \
"--key-label=${keylabel}" \
--id 1 2>&1)
if [ $? -ne 0 ]; then
--id 1 2>&1);
then
logerr "Error: Could not create create key under pkcs11 token ${token}"
logerr "${msg}"
return 1
fi
msg="$(p11tool --login --list-keys "${tokenurl}" 2>&1)"
if [ $? -ne 0 ]; then
if ! msg="$(p11tool --login --list-keys "${tokenurl}" 2>&1)"; then
logerr "Error: Could not get TPM key URL for ${tokenurl}"
logerr "${msg}"
return 1
Expand All @@ -218,9 +223,8 @@ create_localca_cert() {
fi
rm -f "${tpmpubkey}"

msg=$(p11tool --export-pubkey "${tpmkeyurl}" --login --outfile "${tpmpubkey}" 2>&1)
if [ $? -ne 0 ] || \
[ ! -r "${tpmpubkey}" ] || [ $(get_filesize "${tpmpubkey}") -eq 0 ]; then
if ! msg=$(p11tool --export-pubkey "${tpmkeyurl}" --login --outfile "${tpmpubkey}" 2>&1) || \
[ ! -r "${tpmpubkey}" ] || [ "$(get_filesize "${tpmpubkey}")" -eq 0 ]; then
logerr "Error: Could not get TPM public key"
logerr "${msg}"
rm -f "${tpmkey}" "${tpmpubkey}"
Expand All @@ -237,8 +241,7 @@ create_localca_cert() {
fi

if [ $((flags & FLAG_REGISTER_KEY)) -ne 0 ]; then
msg="$(run_tpmtool --generate-rsa --signing --register ${params})"
if [ $? -ne 0 ]; then
if ! msg="$(run_tpmtool --generate-rsa --signing --register ${params})"; then
logerr "Could not generate registered signing key with tpmtool"
logerr "${msg}"
return 1
Expand All @@ -251,14 +254,14 @@ create_localca_cert() {
fi
else
rm -f "${tpmkey}"
msg="$(run_tpmtool --generate-rsa --signing --outfile \"${tpmkey}\" ${params})"
if [ $? -ne 0 ]; then
# shellcheck disable=SC2086
if ! msg="$(run_tpmtool --generate-rsa --signing --outfile \"${tpmkey}\" ${params})"; then
logerr "Could not create signing key with tpmtool"
logerr "${msg}"
rm -f "${tpmkey}"
return 1
fi
if [ ! -r "${tpmkey}" ] || [ $(get_filesize "${tpmkey}") -eq 0 ]; then
if [ ! -r "${tpmkey}" ] || [ "$(get_filesize "${tpmkey}")" -eq 0 ]; then
logerr "The TPM key file ${tpmkey} was not written properly"
logerr "${msg}"
rm -f "${tpmkey}"
Expand All @@ -269,40 +272,41 @@ create_localca_cert() {
fi

rm -f "${tpmpubkey}"
msg=$(run_tpmtool "--pubkey=${tpmkeyurl}" --outfile \"${tpmpubkey}\" ${params})
if [ $? -ne 0 ] || \
[ ! -r "${tpmpubkey}" ] || [ $(get_filesize "${tpmpubkey}") -eq 0 ]; then
# shellcheck disable=SC2086
if ! msg=$(run_tpmtool "--pubkey=${tpmkeyurl}" --outfile \"${tpmpubkey}\" ${params}) || \
[ ! -r "${tpmpubkey}" ] || [ "$(get_filesize "${tpmpubkey}")" -eq 0 ]; then
logerr "Error: Could not get TPM public key"
logerr "${msg}"
rm -f "${tpmkey}" "${tpmpubkey}"
return 1
fi
fi

echo "cn=swtpm-localca" > "${template}"
echo "ca" >> "${template}"
echo "cert_signing_key" >> "${template}"
echo "expiration_days = 3650" >> "${template}"
{
echo "cn=swtpm-localca"
echo "ca"
echo "cert_signing_key"
echo "expiration_days = 3650"
} > "${template}"

msg=$(${CERTTOOL} \
if ! msg=$(${CERTTOOL} \
--generate-certificate \
--template "${template}" \
--outfile "${tpmca}" \
--load-ca-privkey "${cakey}" \
--load-ca-certificate "${cacert}" \
--load-privkey "${tpmkeyurl}" \
--load-pubkey "${tpmpubkey}" \
2>&1)

if [ $? -ne 0 ]; then
2>&1);
then
logerr "Could not create TPM CA"
logerr "${msg}"
rm -f "${template}"
return 1
fi

output="statedir = ${dir}
signingkey = $(escape_pkcs11_url ${tpmkeyurl})
signingkey = $(escape_pkcs11_url "${tpmkeyurl}")
issuercert = ${tpmca}
certserial = ${dir}/certserial"

Expand All @@ -329,10 +333,9 @@ certserial = ${dir}/certserial"
if [ "$(id -u)" -eq 0 ]; then
chown "${owner}:${group}" "${dir}"

pushd "${dir}" &>/dev/null
if [ $? -eq 0 ]; then
if pushd "${dir}" &>/dev/null; then
chown "${owner}:${group}" ./*
popd &>/dev/null
popd &>/dev/null || return 1
fi

if [ -n "${outfile}" ]; then
Expand Down Expand Up @@ -404,6 +407,8 @@ tpmtool_supports_srk_well_known()
{
local tmp

[ -z "$(type -P tpmtool)" ] && return 1

tmp=$(tpmtool --help | grep "srk-well-known")
[ -z "${tmp}" ] && return 1
return 0
Expand Down Expand Up @@ -512,17 +517,15 @@ main() {

if [ "$(id -u)" -eq 0 ]; then
if [ -n "${owner}" ]; then
msg="$(id -u "${owner}" 2>&1)"
if [ $? -ne 0 ]; then
if ! msg="$(id -u "${owner}" 2>&1)"; then
logerr "User ${owner} cannot be used: ${msg}"
return 1
fi
else
owner="root"
fi
if [ -n "${group}" ]; then
msg="$(id -g "${group}" 2>&1)"
if [ $? -ne 0 ]; then
if ! msg="$(id -g "${group}" 2>&1)"; then
logerr "Group ${group} cannot be used: ${msg}"
return 1
fi
Expand All @@ -531,8 +534,7 @@ main() {
fi
fi

mkdir -p "${dir}"
if [ $? -ne 0 ]; then
if ! mkdir -p "${dir}"; then
logerr "Could not create directory ${dir}."
return 1
fi
Expand Down
1 change: 1 addition & 0 deletions src/swtpm_localca/swtpm_localca.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,7 @@ int main(int argc, char *argv[])
{"allow-signing", no_argument, NULL, 'i'},
{"decryption", no_argument, NULL, 'y'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0},
};
g_autofree gchar *default_options_file = NULL;
g_autofree gchar *default_config_file = NULL;
Expand Down

0 comments on commit 2a12583

Please sign in to comment.