blob: 97216967faa1150cf634dd2acd670b21d2371bd4 [file] [log] [blame]
#!/usr/bin/env bash
# For the license, see the LICENSE file in the root directory.
# This script may not work with softhsm2 2.0.0 but with >= 2.2.0
if [ -z "$(type -P p11tool)" ]; then
echo "Need p11tool from gnutls"
exit 77
fi
if [ -z "$(type -P softhsm2-util)" ]; then
echo "Need softhsm2-util from softhsm2 package"
exit 77
fi
NAME=swtpm-test
PIN=${PIN:-1234}
SO_PIN=${SO_PIN:-1234}
SOFTHSM_SETUP_CONFIGDIR=${SOFTHSM_SETUP_CONFIGDIR:-~/.config/softhsm2}
export SOFTHSM2_CONF=${SOFTHSM_SETUP_CONFIGDIR}/softhsm2.conf
UNAME_S="$(uname -s)"
case "${UNAME_S}" in
Darwin)
msg=$(sudo -v -n)
if [ $? -ne 0 ]; then
echo "Need password-less sudo rights on OS X to change /etc/gnutls/pkcs11.conf"
exit 1
fi
;;
esac
teardown_softhsm() {
local configdir=${SOFTHSM_SETUP_CONFIGDIR}
local configfile=${SOFTHSM2_CONF}
local bakconfigfile=${configfile}.bak
local tokendir=${configdir}/tokens
softhsm2-util --token "${NAME}" --delete-token &>/dev/null
case "${UNAME_S}" in
Darwin*)
if [ -f /etc/gnutls/pkcs11.conf.bak ]; then
sudo rm -f /etc/gnutls/pkcs11.conf
sudo mv /etc/gnutls/pkcs11.conf.bak \
/etc/gnutls/pkcs11.conf &>/dev/null
fi
;;
esac
if [ -f "$bakconfigfile" ]; then
mv "$bakconfigfile" "$configfile"
else
rm -f "$configfile"
fi
if [ -d "$tokendir" ]; then
rm -rf "${tokendir}"
fi
return 0
}
setup_softhsm() {
local msg tokenuri keyuri
local configdir=${SOFTHSM_SETUP_CONFIGDIR}
local configfile=${SOFTHSM2_CONF}
local bakconfigfile=${configfile}.bak
local tokendir=${configdir}/tokens
local rc
case "${UNAME_S}" in
Darwin*)
if [ -f /etc/gnutls/pkcs11.conf.bak ]; then
echo "/etc/gnutls/pkcs11.conf.bak already exists; need to 'teardown' first"
return 1
fi
sudo mv /etc/gnutls/pkcs11.conf \
/etc/gnutls/pkcs11.conf.bak &>/dev/null
if [ $(id -u) -eq 0 ]; then
SONAME="$(sudo -u nobody brew ls --verbose softhsm | \
grep -E "\.so$")"
else
SONAME="$(brew ls --verbose softhsm | \
grep -E "\.so$")"
fi
sudo mkdir -p /etc/gnutls &>/dev/null
sudo bash -c "echo "load=${SONAME}" > /etc/gnutls/pkcs11.conf"
;;
esac
if ! [ -d $configdir ]; then
mkdir -p $configdir
fi
mkdir -p ${tokendir}
if [ -f $configfile ]; then
mv "$configfile" "$bakconfigfile"
fi
if ! [ -f $configfile ]; then
cat <<_EOF_ > $configfile
directories.tokendir = ${tokendir}
objectstore.backend = file
log.level = DEBUG
slots.removable = false
_EOF_
fi
msg=$(p11tool --list-tokens 2>&1 | grep "token=${NAME}" | tail -n1)
if [ $? -ne 0 ]; then
echo "Could not list existing tokens"
echo "$msg"
fi
tokenuri=$(echo "$msg" | sed -n 's/.*URL: \([[:print:]*]\)/\1/p')
if [ -z "$tokenuri" ]; then
msg=$(softhsm2-util \
--init-token --pin ${PIN} --so-pin ${SO_PIN} \
--free --label ${NAME} 2>&1)
if [ $? -ne 0 ]; then
echo "Could not initialize token"
echo "$msg"
return 2
fi
slot=$(echo "$msg" | \
sed -n 's/.* reassigned to slot \([0-9]*\)$/\1/p')
if [ -z "$slot" ]; then
slot=$(softhsm2-util --show-slots | \
grep -E "^Slot " | head -n1 |
sed -n 's/Slot \([0-9]*\)/\1/p')
if [ -z "$slot" ]; then
echo "Could not parse slot number from output."
echo "$msg"
return 3
fi
fi
msg=$(p11tool --list-tokens 2>&1 | \
grep "token=${NAME}" | tail -n1)
if [ $? -ne 0 ]; then
echo "Could not list existing tokens"
echo "$msg"
fi
tokenuri=$(echo "$msg" | sed -n 's/.*URL: \([[:print:]*]\)/\1/p')
if [ -z "${tokenuri}" ]; then
echo "Could not get tokenuri!"
return 4
fi
# more recent versions of p11tool have --generate-privkey ...
msg=$(GNUTLS_PIN=$PIN p11tool \
--generate-privkey=rsa --label mykey --login \
"${tokenuri}" 2>&1)
if [ $? -ne 0 ]; then
# ... older versions have --generate-rsa
msg=$(GNUTLS_PIN=$PIN p11tool \
--generate-rsa --label mykey --login \
"${tokenuri}" 2>&1)
if [ $? -ne 0 ]; then
echo "Could not create RSA key!"
echo "$msg"
return 5
fi
fi
fi
getkeyuri_softhsm $slot
rc=$?
if [ $rc -ne 0 ]; then
teardown_softhsm
fi
return $rc
}
_getkeyuri_softhsm() {
local msg tokenuri keyuri
msg=$(p11tool --list-tokens 2>&1 | grep "token=${NAME}")
if [ $? -ne 0 ]; then
echo "Could not list existing tokens"
echo "$msg"
return 5
fi
tokenuri=$(echo "$msg" | sed -n 's/.*URL: \([[:print:]*]\)/\1/p')
if [ -z "$tokenuri" ]; then
echo "Could not get token URL"
echo "$msg"
return 6
fi
msg=$(p11tool --list-all ${tokenuri} 2>&1)
if [ $? -ne 0 ]; then
echo "Could not list object under token $tokenuri"
echo "$msg"
softhsm2-util --show-slots
return 7
fi
keyuri=$(echo "$msg" | sed -n 's/.*URL: \([[:print:]*]\)/\1/p')
if [ -z "$keyuri" ]; then
echo "Could not get key URL"
echo "$msg"
return 8
fi
echo "$keyuri"
return 0
}
getkeyuri_softhsm() {
local keyuri rc
keyuri=$(_getkeyuri_softhsm)
rc=$?
if [ $rc -ne 0 ]; then
return $rc
fi
echo "keyuri: $keyuri?pin-value=${PIN}&module-name=softhsm2"
return 0
}
getpubkey_softhsm() {
local keyuri rc
keyuri=$(_getkeyuri_softhsm)
rc=$?
if [ $rc -ne 0 ]; then
return $rc
fi
GNUTLS_PIN=${PIN} p11tool --export-pubkey "${keyuri}" --login 2>/dev/null
return $?
}
usage() {
cat <<_EOF_
Usage: $0 [command]
Supported commands are:
setup : Setup the user's account for softhsm and create a
token and key with a test configuration
getkeyuri : Get the key's URL; may only be called after setup
getpubkey : Get the public key in PEM format; may only be called after setup
teardown : Remove the temporary softhsm test configuration
_EOF_
}
main() {
local ret
if [ $# -lt 1 ]; then
usage $0
echo -e "Missing command.\n\n"
return 1
fi
case "$1" in
setup)
setup_softhsm
ret=$?
;;
getkeyuri)
getkeyuri_softhsm
ret=$?
;;
getpubkey)
getpubkey_softhsm
ret=$?
;;
teardown)
teardown_softhsm
ret=$?
;;
*)
echo -e "Unsupported command: $1\n\n"
usage $0
ret=1
esac
return $ret
}
main "$@"
exit $?