Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sample: Fix some issues related to swtpm-create-tpmca tool #789

Merged
merged 4 commits into from
Feb 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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