1#	$OpenBSD: agent-pkcs11.sh,v 1.9 2021/07/25 12:13:03 dtucker Exp $
2#	Placed in the Public Domain.
3
4tid="pkcs11 agent test"
5
6try_token_libs() {
7	for _lib in "$@" ; do
8		if test -f "$_lib" ; then
9			verbose "Using token library $_lib"
10			TEST_SSH_PKCS11="$_lib"
11			return
12		fi
13	done
14	echo "skipped: Unable to find PKCS#11 token library"
15	exit 0
16}
17
18try_token_libs \
19	/usr/local/lib/softhsm/libsofthsm2.so \
20	/usr/lib64/pkcs11/libsofthsm2.so \
21	/usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so
22
23TEST_SSH_PIN=1234
24TEST_SSH_SOPIN=12345678
25if [ "x$TEST_SSH_SSHPKCS11HELPER" != "x" ]; then
26	SSH_PKCS11_HELPER="${TEST_SSH_SSHPKCS11HELPER}"
27	export SSH_PKCS11_HELPER
28fi
29
30test -f "$TEST_SSH_PKCS11" || fatal "$TEST_SSH_PKCS11 does not exist"
31
32# setup environment for softhsm2 token
33DIR=$OBJ/SOFTHSM
34rm -rf $DIR
35TOKEN=$DIR/tokendir
36mkdir -p $TOKEN
37SOFTHSM2_CONF=$DIR/softhsm2.conf
38export SOFTHSM2_CONF
39cat > $SOFTHSM2_CONF << EOF
40# SoftHSM v2 configuration file
41directories.tokendir = ${TOKEN}
42objectstore.backend = file
43# ERROR, WARNING, INFO, DEBUG
44log.level = DEBUG
45# If CKF_REMOVABLE_DEVICE flag should be set
46slots.removable = false
47EOF
48out=$(softhsm2-util --init-token --free --label token-slot-0 --pin "$TEST_SSH_PIN" --so-pin "$TEST_SSH_SOPIN")
49slot=$(echo -- $out | sed 's/.* //')
50
51# prevent ssh-agent from calling ssh-askpass
52SSH_ASKPASS=/usr/bin/true
53export SSH_ASKPASS
54unset DISPLAY
55
56# start command w/o tty, so ssh-add accepts pin from stdin
57notty() {
58	perl -e 'use POSIX; POSIX::setsid();
59	    if (fork) { wait; exit($? >> 8); } else { exec(@ARGV) }' "$@"
60}
61
62trace "generating keys"
63RSA=${DIR}/RSA
64EC=${DIR}/EC
65$OPENSSL_BIN genpkey -algorithm rsa > $RSA
66$OPENSSL_BIN pkcs8 -nocrypt -in $RSA |\
67    softhsm2-util --slot "$slot" --label 01 --id 01 --pin "$TEST_SSH_PIN" --import /dev/stdin
68$OPENSSL_BIN genpkey \
69    -genparam \
70    -algorithm ec \
71    -pkeyopt ec_paramgen_curve:prime256v1 |\
72    $OPENSSL_BIN genpkey \
73    -paramfile /dev/stdin > $EC
74$OPENSSL_BIN pkcs8 -nocrypt -in $EC |\
75    softhsm2-util --slot "$slot" --label 02 --id 02 --pin "$TEST_SSH_PIN" --import /dev/stdin
76
77trace "start agent"
78eval `${SSHAGENT} ${EXTRA_AGENT_ARGS} -s` > /dev/null
79r=$?
80if [ $r -ne 0 ]; then
81	fail "could not start ssh-agent: exit code $r"
82else
83	trace "add pkcs11 key to agent"
84	echo ${TEST_SSH_PIN} | notty ${SSHADD} -s ${TEST_SSH_PKCS11} > /dev/null 2>&1
85	r=$?
86	if [ $r -ne 0 ]; then
87		fail "ssh-add -s failed: exit code $r"
88	fi
89
90	trace "pkcs11 list via agent"
91	${SSHADD} -l > /dev/null 2>&1
92	r=$?
93	if [ $r -ne 0 ]; then
94		fail "ssh-add -l failed: exit code $r"
95	fi
96
97	for k in $RSA $EC; do
98		trace "testing $k"
99		chmod 600 $k
100		ssh-keygen -y -f $k > $k.pub
101		pub=$(cat $k.pub)
102		${SSHADD} -L | grep -q "$pub" || fail "key $k missing in ssh-add -L"
103		${SSHADD} -T $k.pub || fail "ssh-add -T with $k failed"
104
105		# add to authorized keys
106		cat $k.pub > $OBJ/authorized_keys_$USER
107		trace "pkcs11 connect via agent ($k)"
108		${SSH} -F $OBJ/ssh_proxy somehost exit 5
109		r=$?
110		if [ $r -ne 5 ]; then
111			fail "ssh connect failed (exit code $r)"
112		fi
113	done
114
115	trace "remove pkcs11 keys"
116	echo ${TEST_SSH_PIN} | notty ${SSHADD} -e ${TEST_SSH_PKCS11} > /dev/null 2>&1
117	r=$?
118	if [ $r -ne 0 ]; then
119		fail "ssh-add -e failed: exit code $r"
120	fi
121
122	trace "kill agent"
123	${SSHAGENT} -k > /dev/null
124fi
125