samples: Add a script to create a TPM 1.2 intermediate CA

This (experimental) script uses GnuTLS tpmtool to create a TPM 1.2
intermediate CA that can sign a vTPM's EK and platform certificates.

Add a man page for this tool.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
Stefan Berger 2018-10-11 09:44:07 -04:00
parent 07c786d1a0
commit 05f4d55f1f
5 changed files with 753 additions and 0 deletions

View File

@ -13,6 +13,7 @@ man8_PODS = \
swtpm_ioctl.pod \
swtpm_setup.pod \
swtpm_setup.conf.pod
swtpm-create-tpmca.pod \
swtpm-localca.pod \
swtpm-localca.options.pod \
swtpm-localca.conf.pod
@ -25,6 +26,7 @@ man8_MANS = \
swtpm_setup.8 \
swtpm_setup.conf.8 \
swtpm_setup.sh.8 \
swtpm-create-tpmca.8 \
swtpm-localca.8 \
swtpm-localca.options.8 \
swtpm-localca.conf.8

View File

@ -0,0 +1,249 @@
.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
. if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{\
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
. \" fudge factors for nroff and troff
.if n \{\
. ds #H 0
. ds #V .8m
. ds #F .3m
. ds #[ \f1
. ds #] \fP
.\}
.if t \{\
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
. ds #V .6m
. ds #F 0
. ds #[ \&
. ds #] \&
.\}
. \" simple accents for nroff and troff
.if n \{\
. ds ' \&
. ds ` \&
. ds ^ \&
. ds , \&
. ds ~ ~
. ds /
.\}
.if t \{\
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
.\}
. \" troff and (daisy-wheel) nroff accents
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
.ds ae a\h'-(\w'a'u*4/10)'e
.ds Ae A\h'-(\w'A'u*4/10)'E
. \" corrections for vroff
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
. \" for low resolution devices (crt and lpr)
.if \n(.H>23 .if \n(.V>19 \
\{\
. ds : e
. ds 8 ss
. ds o a
. ds d- d\h'-1'\(ga
. ds D- D\h'-1'\(hy
. ds th \o'bp'
. ds Th \o'LP'
. ds ae ae
. ds Ae AE
.\}
.rm #[ #] #H #V #F C
.\" ========================================================================
.\"
.IX Title "swtpm-create-tpmca 8"
.TH swtpm-create-tpmca 8 "2018-10-15" "swtpm" ""
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
swtpm\-create\-tpmca
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
\&\fBswtpm-create-tpmca [\s-1OPTIONS\s0]\fR
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
\&\fBswtpm-create-tpmca\fR is a tool to create a \s-1TPM 1.2\s0 based \s-1CA\s0 that
can be used by \fBswtpm-localca\fR to sign \s-1EK\s0 and platform certificates.
The \s-1CA\s0 uses a GnuTLS key to sign certificates. To do this,
GnuTLS talks to the \s-1TPM 1.2\s0 using the \fBtcsd\fR (TrouSerS) daemon.
.PP
Note: This tool is experimental. See the section on known issues below.
.PP
The following options are supported:
.IP "\fB\-\-dir dir\fR" 4
.IX Item "--dir dir"
The directory where the keys will be written to. An existing root \s-1CA\s0 with
the files \fIswtpm\-localca\-rootca\-privkey.pem\fR and
\&\fIswtpm\-localca\-rootca\-cert.pem\fR in this directory will be reused. If
either one of these files does not exist, a new root \s-1CA\s0 will be created.
.IP "\fB\-\-overwrite\fR" 4
.IX Item "--overwrite"
Overwrite the contents of the output directory.
.IP "\fB\-\-register\fR" 4
.IX Item "--register"
Register the key with \s-1TCSD.\s0 For the key to be available for signing,
the same user that created the \s-1TPM CA\s0 has to run the swtpm-localca
later on. If this option is not passed, the private key is written
into a file and can be used by others as well.
.IP "\fB\-\-key\-password s\fR" 4
.IX Item "--key-password s"
The new signing key will get this password.
.Sp
Note: Due to a bug in GnuTLS certtool it may be necessary to use the
same password for the signing key as for the \s-1SRK.\s0
.IP "\fB\-\-srk\-password s\fR" 4
.IX Item "--srk-password s"
The \s-1TPM SRK\s0 password.
.Sp
Note: Since GnuTLS tpmtool does not support the 'well known' password
of 20 zero bytes, the \s-1SRK\s0 password must be set.
.IP "\fB\-\-outfile filename\fR" 4
.IX Item "--outfile filename"
The name of a file where to write the swtpm\-localca.conf configuration
to.
.IP "\fB\-\-owner owner\fR" 4
.IX Item "--owner owner"
The name or uid number of the owner who will own the directory and
outfile file. This option only has an effect if this swtpm-create-tpmca
is run by the root user.
.IP "\fB\-\-group group\fR" 4
.IX Item "--group group"
The name or gid number of the group who will own the directory and
outfile file. This option only has an effect if this swtpm-create-tpmca
is run by the root user.
.IP "\fB\-\-tss\-tcsd\-hostname\fR" 4
.IX Item "--tss-tcsd-hostname"
The hostname where tcsd is running on. The default hostname is 'localhost'.
.IP "\fB\-tss\-tcsd\-port\fR" 4
.IX Item "-tss-tcsd-port"
The \s-1TCP\s0 port on which tcsd is listening for messages. The default port is
30003.
.IP "\fB\-help, \-h, \-?\fR" 4
.IX Item "-help, -h, -?"
Display the help screen and exit.
.SH "EXAMPLE"
.IX Header "EXAMPLE"
The following example creates an intermediate \s-1TPM CA\s0 and writes the keys
into /var/lib/swtpm\-localca and the swtpm-localca configuration to
/etc/swtpm\-localca.conf. It can then be used for signing certificates of
newly created \fBswtpm\fR TPMs.
.PP
.Vb 10
\& #> sudo systemctl start tcsd
\& #> sudo /usr/share/swtpm/swtpm\-create\-tpmca \e
\& \-\-dir /var/lib/swtpm\-localca \e
\& \-\-overwrite \e
\& \-\-outfile /etc/swtpm\-localca.conf \e
\& \-\-srk\-password password \e
\& \-\-key\-password password \e
\& \-\-group tss
\& statedir = /var/lib/swtpm\-localca
\& signingkey = tpmkey:file=/var/lib/swtpm\-localca/swtpm\-localca\-tpmca\-privkey.pem
\& issuercert = /var/lib/swtpm\-localca/swtpm\-localca\-tpmca\-cert.pem
\& certserial = /var/lib/swtpm\-localca/certserial
\& TSS_TCSD_HOSTNAME = localhost
\& TSS_TCSD_PORT = 30003
\& signingkey_password = password
\& parentkey_password = password
.Ve
.SH "KNOWN ISSUES"
.IX Header "KNOWN ISSUES"
The interaction of GnuTLS certtool with the \s-1TPM TCSD\s0 daemon may cause so
many \s-1TPM\s0 (key) authentication failures, that the \s-1TPM\s0 refuses to accept any
more authenticated commands until the \s-1TPM\s0's owner sends it the
TPM_ORD_ResetLockValue command. The reason for this is that certtool first
tries to use 20 zero bytes for the \s-1SRK\s0 password and only then prompts for
and uses the required \s-1SRK\s0 password. The GnuTLS tpmtool does not support 20
zero bytes for the \s-1SRK\s0 password, so forces the usage of a 'real' password.
.PP
The effect of the authentication failues may be that the \s-1TPM CA\s0 cannot sign
certificates since the \s-1TPM\s0 does not accept authenticated commands.
.SH "SEE ALSO"
.IX Header "SEE ALSO"
\&\fBswtpm-localca\fR, \fBswtpm\-localca.conf\fR, \fBtcsd\fR
.SH "REPORTING BUGS"
.IX Header "REPORTING BUGS"
Report bugs to Stefan Berger <stefanb@linux.ibm.com>

View File

@ -0,0 +1,129 @@
=head1 NAME
swtpm-create-tpmca
=head1 SYNOPSIS
B<swtpm-create-tpmca [OPTIONS]>
=head1 DESCRIPTION
B<swtpm-create-tpmca> is a tool to create a TPM 1.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.
Note: This tool is experimental. See the section on known issues below.
The following options are supported:
=over 4
=item B<--dir dir>
The directory where the keys will be written to. An existing root CA with
the files I<swtpm-localca-rootca-privkey.pem> and
I<swtpm-localca-rootca-cert.pem> in this directory will be reused. If
either one of these files does not exist, a new root CA will be created.
=item B<--overwrite>
Overwrite the contents of the output directory.
=item B<--register>
Register the key with TCSD. For the key to be available for signing,
the same user that created the TPM CA has to run the swtpm-localca
later on. If this option is not passed, the private key is written
into a file and can be used by others as well.
=item B<--key-password s>
The new signing key will get this password.
Note: Due to a bug in GnuTLS certtool it may be necessary to use the
same password for the signing key as for the SRK.
=item B<--srk-password s>
The TPM SRK password.
Note: Since GnuTLS tpmtool does not support the 'well known' password
of 20 zero bytes, the SRK password must be set.
=item B<--outfile filename>
The name of a file where to write the swtpm-localca.conf configuration
to.
=item B<--owner owner>
The name or uid number of the owner who will own the directory and
outfile file. This option only has an effect if this swtpm-create-tpmca
is run by the root user.
=item B<--group group>
The name or gid number of the group who will own the directory and
outfile file. This option only has an effect if this swtpm-create-tpmca
is run by the root user.
=item B<--tss-tcsd-hostname>
The hostname where tcsd is running on. The default hostname is 'localhost'.
=item B<-tss-tcsd-port>
The TCP port on which tcsd is listening for messages. The default port is
30003.
=item B<-help, -h, -?>
Display the help screen and exit.
=back
=head1 EXAMPLE
The following example creates an intermediate TPM CA and writes the keys
into /var/lib/swtpm-localca and the swtpm-localca configuration to
/etc/swtpm-localca.conf. It can then be used for signing certificates of
newly created B<swtpm> TPMs.
#> sudo systemctl start tcsd
#> sudo /usr/share/swtpm/swtpm-create-tpmca \
--dir /var/lib/swtpm-localca \
--overwrite \
--outfile /etc/swtpm-localca.conf \
--srk-password password \
--key-password password \
--group tss
statedir = /var/lib/swtpm-localca
signingkey = tpmkey:file=/var/lib/swtpm-localca/swtpm-localca-tpmca-privkey.pem
issuercert = /var/lib/swtpm-localca/swtpm-localca-tpmca-cert.pem
certserial = /var/lib/swtpm-localca/certserial
TSS_TCSD_HOSTNAME = localhost
TSS_TCSD_PORT = 30003
signingkey_password = password
parentkey_password = password
=head1 KNOWN ISSUES
The interaction of GnuTLS certtool with the TPM TCSD daemon may cause so
many TPM (key) authentication failures, that the TPM refuses to accept any
more authenticated commands until the TPM's owner sends it the
TPM_ORD_ResetLockValue command. The reason for this is that certtool first
tries to use 20 zero bytes for the SRK password and only then prompts for
and uses the required SRK password. The GnuTLS tpmtool does not support 20
zero bytes for the SRK password, so forces the usage of a 'real' password.
The effect of the authentication failues may be that the TPM CA cannot sign
certificates since the TPM does not accept authenticated commands.
=head1 SEE ALSO
B<swtpm-localca>, B<swtpm-localca.conf>, B<tcsd>
=head1 REPORTING BUGS
Report bugs to Stefan Berger <stefanb@linux.ibm.com>

View File

@ -8,6 +8,7 @@ samplesconfdir = $(datadir)/@PACKAGE@
samplessysconfdir = $(sysconfdir)
samplesconf_SCRIPTS = \
swtpm-create-tpmca \
swtpm-localca
samplessysconf_DATA = \
@ -21,6 +22,7 @@ install-data-local:
fi
EXTRA_DIST= \
swtpm-create-tpmca \
swtpm-localca \
swtpm-localca.conf \
swtpm-localca.options

371
samples/swtpm-create-tpmca Executable file
View File

@ -0,0 +1,371 @@
#!/usr/bin/env bash
FLAG_OVERWRITE=1
FLAG_REGISTER_KEY=2
TSS_TCSD_HOSTNAME_DEFAULT=localhost
TSS_TCSD_PORT_DEFAULT=30003
logit()
{
if [ -z "$LOGFILE" ]; then
echo "$@" >&1
else
echo "$@" >> $LOGFILE
fi
}
logerr()
{
if [ -z "$LOGFILE" ]; then
echo "Error: $@" >&2
else
echo "Error: $@" >> $LOGFILE
fi
}
# Get the size of a file in bytes
#
# @1: filename
function get_filesize()
{
if [[ "$(uname -s)" =~ (Linux|CYGWIN_NT-) ]]; then
stat -c%s $1
else
# OpenBSD
stat -f%z $1
fi
}
# Use expect for automating the interaction with the tpmtool
#
# @param 1...: parameters to pass to tpmtool command line
#
# TPM_SRK_PASSWORD and TPM_KEY_PASSWORD global variables are used
# for the SRK and key passwords respectively.
run_tpmtool() {
local prg out
prg="spawn tpmtool $@
expect {
\"Enter SRK password:\" {
send \"${TPM_SRK_PASSWORD}\n\"
exp_continue
}
\"Enter key password:\" {
send \"${TPM_KEY_PASSWORD}\n\"
exp_continue
}
\"tpmkey:\" {
send_user \"\n\"
}
eof {
exit
}
}
catch wait result
exit [lindex \$result 3]
"
out=$(expect -c "${prg}")
echo "${out}"
} #run_tpmtool
create_localca_cert() {
local flags=$1
local dir="$2"
local outfile="$3"
local owner="$4"
local cakey=${dir}/swtpm-localca-rootca-privkey.pem
local cacert=${dir}/swtpm-localca-rootca-cert.pem
local tpmkey=${dir}/swtpm-localca-tpmca-privkey.pem
local tpmpubkey=${dir}/swtpm-localca-tpmca-pubkey.pem
local tpmca=${dir}/swtpm-localca-tpmca-cert.pem
local template=${dir}/template
local tpmkeyurl
local msg output
if ! [ -r "${cakey}" ] || ! [ -r ${cacert} ]; then
msg=$(${CERTTOOL} \
--generate-privkey \
--outfile ${cakey} \
2>&1)
[ $? -ne 0 ] && {
logerr "Could not create root-CA key ${cakey}."
logerr "${msg}"
return 1
}
chmod 640 ${cakey}
echo "cn=swtpm-localca-rootca" > ${template}
echo "ca" >> ${template}
echo "cert_signing_key" >> ${template}
echo "expiration_days = 3650" >> ${template}
msd=$(${CERTTOOL} \
--generate-self-signed \
--template ${template} \
--outfile ${cacert} \
--load-privkey ${cakey} \
2>&1)
if [ $? -ne 0 ]; then
logerr "Could not create root CA."
logerr "${msg}"
rm -f ${cakey} ${template}
return 1
fi
else
logit "Reusing existing root CA"
fi
rm -f ${tpmkey} ${tpmpubkey} ${tpmca}
if [ $((flags & FLAG_REGISTER_KEY)) -ne 0 ]; then
msg="$(run_tpmtool --generate-rsa --signing --register)"
if [ $? -ne 0 ]; then
logerr "Could not generate registered signing key with tpmtool"
logerr "${msg}"
return 1
fi
tpmkeyurl=$(echo "${msg}" | sed -n 's/\(tpmkey:uuid=[^;]*\);.*/\1/p')
if [ -z "${tpmkeyurl}" ]; then
logerr "Could not parse tpmkey URL"
logerr "${msg}"
return 1
fi
else
rm -f "${tpmkey}"
msg="$(run_tpmtool --generate-rsa --signing --outfile "${tpmkey}")"
if [ $? -ne 0 ]; 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
logerr "The TPM key file ${tpmkey} was not written properly"
rm -f "${tpmkey}"
return 1
fi
chmod 640 ${tpmkey}
tpmkeyurl=tpmkey:file=${tpmkey}
fi
rm -f "${tpmpubkey}"
msg=$(run_tpmtool --pubkey=${tpmkeyurl} --outfile "${tpmpubkey}")
if [ $? -ne 0 ] || \
[ ! -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
echo "cn=swtpm-localca" > ${template}
echo "ca" >> ${template}
echo "cert_signing_key" >> ${template}
echo "expiration_days = 3650" >> ${template}
msg=$(GNUTLS_PIN=${TPM_SRK_PASSWORD} ${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
logerr "Could not create TPM CA"
logerr "${msg}"
rm -f "${template}"
return 1
fi
output="statedir = ${dir}
signingkey = ${tpmkeyurl}
issuercert = ${tpmca}
certserial = ${dir}/certserial
TSS_TCSD_HOSTNAME = ${TSS_TCSD_HOSTNAME}
TSS_TCSD_PORT = ${TSS_TCSD_PORT}"
if [ -n "${TPM_KEY_PASSWORD}" ]; then
output+="$(echo -e "\nsigningkey_password = ${TPM_KEY_PASSWORD}")"
fi
if [ -n "${TPM_SRK_PASSWORD}" ]; then
output+="$(echo -e "\nparentkey_password = ${TPM_SRK_PASSWORD}")"
fi
if [ -n "${outfile}" ]; then
echo "${output}" > "${outfile}"
chmod 640 "${outfile}"
fi
echo "${output}"
if [ "$(id -u)" -eq 0 ]; then
chown "${owner}":"${group}" ${dir}
pushd ${dir} &>/dev/null
if [ $? -eq 0 ]; then
chown "${owner}":"${group}" *
popd &>/dev/null
fi
if [ -n "${outfile}" ]; then
chown "${owner}":"${group}" "${outfile}"
fi
fi
rm -f ${template}
return 0
} #create_localca_cert
usage() {
cat << _EOF_
Usage: $(basename $1) [options]
THIS SCRIPT IS EXPERIMENTAL
The following options are supported:
--dir directory Directory where to write the CA files into; must not exist
unless --overwrite is passed
--overwrite Overwrite any data in an existing directory; tries to
reuse a root CA if one is found there
--register Create a registered TPM 1.2 key rather than a file that
contains the key
--key-password s Password for the newly created TPM key; required if
--register is not passed
Note: use the same as the --srk-password (bug in certtool)
--srk-password s Password for the TPM's SRK;
Note: the well known password of 20 0x0 is not supported
by tpmtool
--outfile file File to write the configuration to; if not passed it will be
written to stdout only
--owner owner The owner of the directory and the files; only set if this
script is run as root; recommended to be 'tss'
--group group The group owning the directory and the files;
recommended to be 'tss'
--tss-tcsd-hostname hostname
The name of the host where tcsd (TrouSerS daemon) is running
on; default is '${TSS_TCSD_HOSTNAME_DEFAULT}'
--tss-tcsd-port p The TCP port on which tcsd is listening for connections;
default is ${TSS_TCSD_PORT_DEFAULT}
--help, -h, -? Display this help screen and exit
_EOF_
} #usage
main() {
local flags=0
local dir outfile owner group msg
CERTTOOL=certtool
export TSS_TCSD_HOSTNAME=${TSS_TCSD_HOSTNAME_DEFAULT}
export TSS_TCSD_PORT=${TSS_TCSD_PORT_DEFAULT}
while [ $# -ne 0 ]; do
case "$1" in
--dir)
shift
dir="$1"
;;
--overwrite)
flags=$((flags | FLAG_OVERWRITE))
;;
--register)
flags=$((flags | FLAG_REGISTER_KEY))
;;
--srk-password)
shift
TPM_SRK_PASSWORD="$1"
;;
--key-password)
shift
TPM_KEY_PASSWORD="$1"
;;
--outfile)
shift
outfile="$1"
;;
--owner)
shift
owner="$1"
;;
--group)
shift
group="$1"
;;
--tss-tcsd-hostname)
shift
TSS_TCSD_HOSTNAME="$1"
;;
--tss-tcsd-port)
shift
TSS_TCSD_PORT="$2"
;;
--help|-h|-?)
usage "$0"
exit 0
;;
*)
logerr "Unsupported option $1"
exit 1
;;
esac
shift
done
if [ -z "${dir}" ]; then
logerr "Missing --dir option."
return 1
fi
# strip trailing '/' from dir
dir="$(echo "${dir}" | sed -n 's|[/]*$||p')"
if [ -d "${dir}" ] && [ $((flags & FLAG_OVERWRITE)) -eq 0 ]; then
logerr "Refusing to overwrite existing directory ${dir}."
return 1
fi
if [ -z "${TPM_KEY_PASSWORD}" ] && [ $((flags & FLAG_REGISTER_KEY)) -eq 0 ]; then
logerr "Key password is required"
return 1
fi
if [ "$(id -u)" -eq 0 ]; then
if [ -n "${owner}" ]; then
msg="$(id -u "${owner}" 2>&1)"
if [ $? -ne 0 ]; 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
logerr "Group ${group} cannot be used: ${msg}"
return 1
fi
else
group="root"
fi
fi
mkdir -p "${dir}"
if [ $? -ne 0 ]; then
logerr "Could not create directory ${dir}."
return 1
fi
create_localca_cert "${flags}" "${dir}" "${outfile}" "${owner}"
return $?
} #main
main "$@"
exit $?