| #!/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) |
| if ! msg=$(sudo -v -n); 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 |
| |
| if ! msg=$(p11tool --list-tokens 2>&1 | grep "token=${NAME}" | tail -n1); then |
| echo "Could not list existing tokens" |
| echo "$msg" |
| fi |
| tokenuri=$(echo "$msg" | sed -n 's/.*URL: \([[:print:]*]\)/\1/p') |
| |
| if [ -z "$tokenuri" ]; then |
| if ! msg=$(softhsm2-util \ |
| --init-token --pin "${PIN}" --so-pin "${SO_PIN}" \ |
| --free --label "${NAME}" 2>&1); 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 |
| |
| if ! msg=$(p11tool --list-tokens 2>&1 | \ |
| grep "token=${NAME}" | tail -n1); 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 ... |
| if ! msg=$(GNUTLS_PIN=$PIN p11tool \ |
| --generate-privkey=rsa --bits 2048 --label mykey --login \ |
| "${tokenuri}" 2>&1); then |
| # ... older versions have --generate-rsa |
| if ! msg=$(GNUTLS_PIN=$PIN p11tool \ |
| --generate-rsa --bits 2048 --label mykey --login \ |
| "${tokenuri}" 2>&1); 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 |
| |
| if ! msg=$(p11tool --list-tokens 2>&1 | grep "token=${NAME}"); 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 |
| if ! msg=$(p11tool --list-all "${tokenuri}" 2>&1); 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 URI; 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 $? |