|  | 
|  | 1 | +#!/usr/bin/env bash | 
|  | 2 | + | 
|  | 3 | +# For the license, see the LICENSE file in the root directory. | 
|  | 4 | + | 
|  | 5 | +# This script may not work with softhsm2 2.0.0 but with >= 2.2.0 | 
|  | 6 | + | 
|  | 7 | +if [ -z "$(type -P p11tool)" ]; then | 
|  | 8 | +	echo "Need p11tool from gnutls" | 
|  | 9 | +	exit 77 | 
|  | 10 | +fi | 
|  | 11 | + | 
|  | 12 | +if [ -z "$(type -P softhsm2-util)" ]; then | 
|  | 13 | +	echo "Need softhsm2-util from softhsm2 package" | 
|  | 14 | +	exit 77 | 
|  | 15 | +fi | 
|  | 16 | + | 
|  | 17 | +NAME=model-signing-test | 
|  | 18 | +PIN=${PIN:-1234} | 
|  | 19 | +SO_PIN=${SO_PIN:-1234} | 
|  | 20 | +SOFTHSM_SETUP_CONFIGDIR=${SOFTHSM_SETUP_CONFIGDIR:-~/.config/softhsm2} | 
|  | 21 | +export SOFTHSM2_CONF=${SOFTHSM_SETUP_CONFIGDIR}/softhsm2.conf | 
|  | 22 | + | 
|  | 23 | +UNAME_S="$(uname -s)" | 
|  | 24 | + | 
|  | 25 | +case "${UNAME_S}" in | 
|  | 26 | +Darwin) | 
|  | 27 | +	if ! msg=$(sudo -v -n); then | 
|  | 28 | +		echo "Need password-less sudo rights on OS X to change /etc/gnutls/pkcs11.conf" | 
|  | 29 | +		exit 1 | 
|  | 30 | +	fi | 
|  | 31 | +	;; | 
|  | 32 | +esac | 
|  | 33 | + | 
|  | 34 | +teardown_softhsm() { | 
|  | 35 | +	local configdir=${SOFTHSM_SETUP_CONFIGDIR} | 
|  | 36 | +	local configfile=${SOFTHSM2_CONF} | 
|  | 37 | +	local bakconfigfile=${configfile}.bak | 
|  | 38 | +	local tokendir=${configdir}/tokens | 
|  | 39 | + | 
|  | 40 | +	softhsm2-util --token "${NAME}" --delete-token &>/dev/null | 
|  | 41 | + | 
|  | 42 | +	case "${UNAME_S}" in | 
|  | 43 | +	Darwin*) | 
|  | 44 | +		if [ -f /etc/gnutls/pkcs11.conf.bak ]; then | 
|  | 45 | +			sudo rm -f /etc/gnutls/pkcs11.conf | 
|  | 46 | +			sudo mv /etc/gnutls/pkcs11.conf.bak \ | 
|  | 47 | +			   /etc/gnutls/pkcs11.conf &>/dev/null | 
|  | 48 | +		fi | 
|  | 49 | +		;; | 
|  | 50 | +	esac | 
|  | 51 | + | 
|  | 52 | +	if [ -f "$bakconfigfile" ]; then | 
|  | 53 | +		mv "$bakconfigfile" "$configfile" | 
|  | 54 | +	else | 
|  | 55 | +		rm -f "$configfile" | 
|  | 56 | +	fi | 
|  | 57 | +	if [ -d "$tokendir" ]; then | 
|  | 58 | +		rm -rf "${tokendir}" | 
|  | 59 | +	fi | 
|  | 60 | +	return 0 | 
|  | 61 | +} | 
|  | 62 | + | 
|  | 63 | +setup_softhsm() { | 
|  | 64 | +	local msg tokenuri keyuri | 
|  | 65 | +	local configdir=${SOFTHSM_SETUP_CONFIGDIR} | 
|  | 66 | +	local configfile=${SOFTHSM2_CONF} | 
|  | 67 | +	local bakconfigfile=${configfile}.bak | 
|  | 68 | +	local tokendir=${configdir}/tokens | 
|  | 69 | +	local rc | 
|  | 70 | + | 
|  | 71 | +	case "${UNAME_S}" in | 
|  | 72 | +	Darwin*) | 
|  | 73 | +		if [ -f /etc/gnutls/pkcs11.conf.bak ]; then | 
|  | 74 | +			echo "/etc/gnutls/pkcs11.conf.bak already exists; need to 'teardown' first" | 
|  | 75 | +			return 1 | 
|  | 76 | +		fi | 
|  | 77 | +		sudo mv /etc/gnutls/pkcs11.conf \ | 
|  | 78 | +			/etc/gnutls/pkcs11.conf.bak &>/dev/null | 
|  | 79 | +		if [ "$(id -u)" -eq 0 ]; then | 
|  | 80 | +			SONAME="$(sudo -u nobody brew ls --verbose softhsm | \ | 
|  | 81 | +				  grep -E "\.so$")" | 
|  | 82 | +		else | 
|  | 83 | +			SONAME="$(brew ls --verbose softhsm | \ | 
|  | 84 | +				  grep -E "\.so$")" | 
|  | 85 | +		fi | 
|  | 86 | +		sudo mkdir -p /etc/gnutls &>/dev/null | 
|  | 87 | +		sudo bash -c "echo 'load=${SONAME}' > /etc/gnutls/pkcs11.conf" | 
|  | 88 | +		;; | 
|  | 89 | +	esac | 
|  | 90 | + | 
|  | 91 | +	if ! [ -d "$configdir" ]; then | 
|  | 92 | +		mkdir -p "$configdir" | 
|  | 93 | +	fi | 
|  | 94 | +	mkdir -p "${tokendir}" | 
|  | 95 | + | 
|  | 96 | +	if [ -f "$configfile" ]; then | 
|  | 97 | +		mv "$configfile" "$bakconfigfile" | 
|  | 98 | +	fi | 
|  | 99 | + | 
|  | 100 | +	if ! [ -f "$configfile" ]; then | 
|  | 101 | +		cat <<_EOF_ > "$configfile" | 
|  | 102 | +directories.tokendir = ${tokendir} | 
|  | 103 | +objectstore.backend = file | 
|  | 104 | +log.level = DEBUG | 
|  | 105 | +slots.removable = false | 
|  | 106 | +_EOF_ | 
|  | 107 | +	fi | 
|  | 108 | + | 
|  | 109 | +	if ! msg=$(p11tool --list-tokens 2>&1 | grep "token=${NAME}" | tail -n1); then | 
|  | 110 | +		echo "Could not list existing tokens" | 
|  | 111 | +		echo "$msg" | 
|  | 112 | +	fi | 
|  | 113 | +	tokenuri=$(echo "$msg" | sed -n 's/.*URL: \([[:print:]*]\)/\1/p') | 
|  | 114 | + | 
|  | 115 | +	if [ -z "$tokenuri" ]; then | 
|  | 116 | +		if ! msg=$(softhsm2-util \ | 
|  | 117 | +			   --init-token --pin "${PIN}" --so-pin "${SO_PIN}" \ | 
|  | 118 | +			   --free --label "${NAME}" 2>&1); then | 
|  | 119 | +			echo "Could not initialize token" | 
|  | 120 | +			echo "$msg" | 
|  | 121 | +			return 2 | 
|  | 122 | +		fi | 
|  | 123 | + | 
|  | 124 | +		slot=$(echo "$msg" | \ | 
|  | 125 | +		       sed -n 's/.* reassigned to slot \([0-9]*\)$/\1/p') | 
|  | 126 | +		if [ -z "$slot" ]; then | 
|  | 127 | +			slot=$(softhsm2-util --show-slots | \ | 
|  | 128 | +			       grep -E "^Slot " | head -n1 | | 
|  | 129 | +			       sed -n 's/Slot \([0-9]*\)/\1/p') | 
|  | 130 | +			if [ -z "$slot" ]; then | 
|  | 131 | +				echo "Could not parse slot number from output." | 
|  | 132 | +				echo "$msg" | 
|  | 133 | +				return 3 | 
|  | 134 | +			fi | 
|  | 135 | +		fi | 
|  | 136 | + | 
|  | 137 | +		if ! msg=$(p11tool --list-tokens 2>&1 | \ | 
|  | 138 | +			   grep "token=${NAME}" | tail -n1); then | 
|  | 139 | +			echo "Could not list existing tokens" | 
|  | 140 | +			echo "$msg" | 
|  | 141 | +		fi | 
|  | 142 | +		tokenuri=$(echo "$msg" | sed -n 's/.*URL: \([[:print:]*]\)/\1/p') | 
|  | 143 | +		if [ -z "${tokenuri}" ]; then | 
|  | 144 | +			echo "Could not get tokenuri!" | 
|  | 145 | +			return 4 | 
|  | 146 | +		fi | 
|  | 147 | + | 
|  | 148 | +		# more recent versions of p11tool have --generate-privkey ... | 
|  | 149 | +		if ! msg=$(GNUTLS_PIN=$PIN p11tool \ | 
|  | 150 | +			   --generate-privkey=ecdsa --curve secp384r1 --label mykey --login \ | 
|  | 151 | +			"${tokenuri}" 2>&1); | 
|  | 152 | +		then | 
|  | 153 | +			echo "Could not create secp384r1 key!" | 
|  | 154 | +			echo "$msg" | 
|  | 155 | +			return 5 | 
|  | 156 | +		fi | 
|  | 157 | +	fi | 
|  | 158 | + | 
|  | 159 | +	getkeyuri_softhsm "$slot" | 
|  | 160 | +	rc=$? | 
|  | 161 | +	if [ $rc -ne 0 ]; then | 
|  | 162 | +		teardown_softhsm | 
|  | 163 | +	fi | 
|  | 164 | + | 
|  | 165 | +	return $rc | 
|  | 166 | +} | 
|  | 167 | + | 
|  | 168 | +_getkeyuri_softhsm() { | 
|  | 169 | +	local msg tokenuri keyuri | 
|  | 170 | + | 
|  | 171 | +	if ! msg=$(p11tool --list-tokens 2>&1 | grep "token=${NAME}"); then | 
|  | 172 | +		echo "Could not list existing tokens" | 
|  | 173 | +		echo "$msg" | 
|  | 174 | +		return 5 | 
|  | 175 | +	fi | 
|  | 176 | +	tokenuri=$(echo "$msg" | sed -n 's/.*URL: \([[:print:]*]\)/\1/p') | 
|  | 177 | +	if [ -z "$tokenuri" ]; then | 
|  | 178 | +		echo "Could not get token URL" | 
|  | 179 | +		echo "$msg" | 
|  | 180 | +		return 6 | 
|  | 181 | +	fi | 
|  | 182 | +	if ! msg=$(p11tool --list-all "${tokenuri}" 2>&1); then | 
|  | 183 | +		echo "Could not list object under token $tokenuri" | 
|  | 184 | +		echo "$msg" | 
|  | 185 | +		softhsm2-util --show-slots | 
|  | 186 | +		return 7 | 
|  | 187 | +	fi | 
|  | 188 | + | 
|  | 189 | +	keyuri=$(echo "$msg" | sed -n 's/.*URL: \([[:print:]*]\)/\1/p') | 
|  | 190 | +	if [ -z "$keyuri" ]; then | 
|  | 191 | +		echo "Could not get key URL" | 
|  | 192 | +		echo "$msg" | 
|  | 193 | +		return 8 | 
|  | 194 | +	fi | 
|  | 195 | +	echo "$keyuri" | 
|  | 196 | +	return 0 | 
|  | 197 | +} | 
|  | 198 | + | 
|  | 199 | +getkeyuri_softhsm() { | 
|  | 200 | +	local keyuri rc | 
|  | 201 | + | 
|  | 202 | +	keyuri=$(_getkeyuri_softhsm) | 
|  | 203 | +	rc=$? | 
|  | 204 | +	if [ $rc -ne 0 ]; then | 
|  | 205 | +		return $rc | 
|  | 206 | +	fi | 
|  | 207 | +	echo "keyuri: $keyuri?pin-value=${PIN}&module-name=softhsm2" | 
|  | 208 | +	return 0 | 
|  | 209 | +} | 
|  | 210 | + | 
|  | 211 | +getpubkey_softhsm() { | 
|  | 212 | +	local keyuri rc | 
|  | 213 | + | 
|  | 214 | +	keyuri=$(_getkeyuri_softhsm) | 
|  | 215 | +	rc=$? | 
|  | 216 | +	if [ $rc -ne 0 ]; then | 
|  | 217 | +		return $rc | 
|  | 218 | +	fi | 
|  | 219 | +	GNUTLS_PIN=${PIN} p11tool --export-pubkey "${keyuri}" --login 2>/dev/null | 
|  | 220 | +	return $? | 
|  | 221 | +} | 
|  | 222 | + | 
|  | 223 | +usage() { | 
|  | 224 | +	cat <<_EOF_ | 
|  | 225 | +Usage: $0 [command] | 
|  | 226 | +
 | 
|  | 227 | +Supported commands are: | 
|  | 228 | +
 | 
|  | 229 | +setup      : Setup the user's account for softhsm and create a | 
|  | 230 | +             token and key with a test configuration | 
|  | 231 | +
 | 
|  | 232 | +getkeyuri  : Get the key's URI; may only be called after setup | 
|  | 233 | +
 | 
|  | 234 | +getpubkey  : Get the public key in PEM format; may only be called after setup | 
|  | 235 | +
 | 
|  | 236 | +teardown   : Remove the temporary softhsm test configuration | 
|  | 237 | +
 | 
|  | 238 | +_EOF_ | 
|  | 239 | +} | 
|  | 240 | + | 
|  | 241 | +main() { | 
|  | 242 | +	local ret | 
|  | 243 | + | 
|  | 244 | +	if [ $# -lt 1 ]; then | 
|  | 245 | +		usage "$0" | 
|  | 246 | +		echo -e "Missing command.\n\n" | 
|  | 247 | +		return 1 | 
|  | 248 | +	fi | 
|  | 249 | +	case "$1" in | 
|  | 250 | +	setup) | 
|  | 251 | +		setup_softhsm | 
|  | 252 | +		ret=$? | 
|  | 253 | +		;; | 
|  | 254 | +	getkeyuri) | 
|  | 255 | +		getkeyuri_softhsm | 
|  | 256 | +		ret=$? | 
|  | 257 | +		;; | 
|  | 258 | +	getpubkey) | 
|  | 259 | +		getpubkey_softhsm | 
|  | 260 | +		ret=$? | 
|  | 261 | +		;; | 
|  | 262 | +	teardown) | 
|  | 263 | +		teardown_softhsm | 
|  | 264 | +		ret=$? | 
|  | 265 | +		;; | 
|  | 266 | +	*) | 
|  | 267 | +		echo -e "Unsupported command: $1\n\n" | 
|  | 268 | +		usage "$0" | 
|  | 269 | +		ret=1 | 
|  | 270 | +	esac | 
|  | 271 | +	return $ret | 
|  | 272 | +} | 
|  | 273 | + | 
|  | 274 | +main "$@" | 
|  | 275 | +exit $? | 
0 commit comments