1#	$OpenBSD: cert-userkey.sh,v 1.8 2011/05/17 07:13:31 djm Exp $
2#	Placed in the Public Domain.
3
4tid="certified user keys"
5
6# used to disable ECC based tests on platforms without ECC
7ecdsa=""
8if test "x$TEST_SSH_ECC" = "xyes"; then
9	ecdsa=ecdsa
10fi
11
12rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key*
13cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
14
15# Create a CA key
16${SSHKEYGEN} -q -N '' -t rsa  -f $OBJ/user_ca_key ||\
17	fail "ssh-keygen of user_ca_key failed"
18
19# Generate and sign user keys
20for ktype in rsa dsa $ecdsa ; do 
21	verbose "$tid: sign user ${ktype} cert"
22	${SSHKEYGEN} -q -N '' -t ${ktype} \
23	    -f $OBJ/cert_user_key_${ktype} || \
24		fail "ssh-keygen of cert_user_key_${ktype} failed"
25	${SSHKEYGEN} -q -s $OBJ/user_ca_key -I \
26	    "regress user key for $USER" \
27	    -n ${USER},mekmitasdigoat $OBJ/cert_user_key_${ktype} ||
28		fail "couldn't sign cert_user_key_${ktype}"
29	# v00 ecdsa certs do not exist
30	test "${ktype}" = "ecdsa" && continue
31	cp $OBJ/cert_user_key_${ktype} $OBJ/cert_user_key_${ktype}_v00
32	cp $OBJ/cert_user_key_${ktype}.pub $OBJ/cert_user_key_${ktype}_v00.pub
33	${SSHKEYGEN} -q -t v00 -s $OBJ/user_ca_key -I \
34	    "regress user key for $USER" \
35	    -n ${USER},mekmitasdigoat $OBJ/cert_user_key_${ktype}_v00 ||
36		fail "couldn't sign cert_user_key_${ktype}_v00"
37done
38
39# Test explicitly-specified principals
40for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00 ; do 
41	for privsep in yes no ; do
42		_prefix="${ktype} privsep $privsep"
43
44		# Setup for AuthorizedPrincipalsFile
45		rm -f $OBJ/authorized_keys_$USER
46		(
47			cat $OBJ/sshd_proxy_bak
48			echo "UsePrivilegeSeparation $privsep"
49			echo "AuthorizedPrincipalsFile " \
50			    "$OBJ/authorized_principals_%u"
51			echo "TrustedUserCAKeys $OBJ/user_ca_key.pub"
52		) > $OBJ/sshd_proxy
53
54		# Missing authorized_principals
55		verbose "$tid: ${_prefix} missing authorized_principals"
56		rm -f $OBJ/authorized_principals_$USER
57		${SSH} -2i $OBJ/cert_user_key_${ktype} \
58		    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
59		if [ $? -eq 0 ]; then
60			fail "ssh cert connect succeeded unexpectedly"
61		fi
62
63		# Empty authorized_principals
64		verbose "$tid: ${_prefix} empty authorized_principals"
65		echo > $OBJ/authorized_principals_$USER
66		${SSH} -2i $OBJ/cert_user_key_${ktype} \
67		    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
68		if [ $? -eq 0 ]; then
69			fail "ssh cert connect succeeded unexpectedly"
70		fi
71	
72		# Wrong authorized_principals
73		verbose "$tid: ${_prefix} wrong authorized_principals"
74		echo gregorsamsa > $OBJ/authorized_principals_$USER
75		${SSH} -2i $OBJ/cert_user_key_${ktype} \
76		    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
77		if [ $? -eq 0 ]; then
78			fail "ssh cert connect succeeded unexpectedly"
79		fi
80
81		# Correct authorized_principals
82		verbose "$tid: ${_prefix} correct authorized_principals"
83		echo mekmitasdigoat > $OBJ/authorized_principals_$USER
84		${SSH} -2i $OBJ/cert_user_key_${ktype} \
85		    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
86		if [ $? -ne 0 ]; then
87			fail "ssh cert connect failed"
88		fi
89
90		# authorized_principals with bad key option
91		verbose "$tid: ${_prefix} authorized_principals bad key opt"
92		echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_$USER
93		${SSH} -2i $OBJ/cert_user_key_${ktype} \
94		    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
95		if [ $? -eq 0 ]; then
96			fail "ssh cert connect succeeded unexpectedly"
97		fi
98
99		# authorized_principals with command=false
100		verbose "$tid: ${_prefix} authorized_principals command=false"
101		echo 'command="false" mekmitasdigoat' > \
102		    $OBJ/authorized_principals_$USER
103		${SSH} -2i $OBJ/cert_user_key_${ktype} \
104		    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
105		if [ $? -eq 0 ]; then
106			fail "ssh cert connect succeeded unexpectedly"
107		fi
108
109
110		# authorized_principals with command=true
111		verbose "$tid: ${_prefix} authorized_principals command=true"
112		echo 'command="true" mekmitasdigoat' > \
113		    $OBJ/authorized_principals_$USER
114		${SSH} -2i $OBJ/cert_user_key_${ktype} \
115		    -F $OBJ/ssh_proxy somehost false >/dev/null 2>&1
116		if [ $? -ne 0 ]; then
117			fail "ssh cert connect failed"
118		fi
119
120		# Setup for principals= key option
121		rm -f $OBJ/authorized_principals_$USER
122		(
123			cat $OBJ/sshd_proxy_bak
124			echo "UsePrivilegeSeparation $privsep"
125		) > $OBJ/sshd_proxy
126
127		# Wrong principals list
128		verbose "$tid: ${_prefix} wrong principals key option"
129		(
130			echon 'cert-authority,principals="gregorsamsa" '
131			cat $OBJ/user_ca_key.pub
132		) > $OBJ/authorized_keys_$USER
133		${SSH} -2i $OBJ/cert_user_key_${ktype} \
134		    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
135		if [ $? -eq 0 ]; then
136			fail "ssh cert connect succeeded unexpectedly"
137		fi
138
139		# Correct principals list
140		verbose "$tid: ${_prefix} correct principals key option"
141		(
142			echon 'cert-authority,principals="mekmitasdigoat" '
143			cat $OBJ/user_ca_key.pub
144		) > $OBJ/authorized_keys_$USER
145		${SSH} -2i $OBJ/cert_user_key_${ktype} \
146		    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
147		if [ $? -ne 0 ]; then
148			fail "ssh cert connect failed"
149		fi
150	done
151done
152
153basic_tests() {
154	auth=$1
155	if test "x$auth" = "xauthorized_keys" ; then
156		# Add CA to authorized_keys
157		(
158			echon 'cert-authority '
159			cat $OBJ/user_ca_key.pub
160		) > $OBJ/authorized_keys_$USER
161	else
162		echo > $OBJ/authorized_keys_$USER
163		extra_sshd="TrustedUserCAKeys $OBJ/user_ca_key.pub"
164	fi
165	
166	for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00 ; do 
167		for privsep in yes no ; do
168			_prefix="${ktype} privsep $privsep $auth"
169			# Simple connect
170			verbose "$tid: ${_prefix} connect"
171			(
172				cat $OBJ/sshd_proxy_bak
173				echo "UsePrivilegeSeparation $privsep"
174				echo "$extra_sshd"
175			) > $OBJ/sshd_proxy
176	
177			${SSH} -2i $OBJ/cert_user_key_${ktype} \
178			    -F $OBJ/ssh_proxy somehost true
179			if [ $? -ne 0 ]; then
180				fail "ssh cert connect failed"
181			fi
182
183			# Revoked keys
184			verbose "$tid: ${_prefix} revoked key"
185			(
186				cat $OBJ/sshd_proxy_bak
187				echo "UsePrivilegeSeparation $privsep"
188				echo "RevokedKeys $OBJ/cert_user_key_${ktype}.pub"
189				echo "$extra_sshd"
190			) > $OBJ/sshd_proxy
191			${SSH} -2i $OBJ/cert_user_key_${ktype} \
192			    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
193			if [ $? -eq 0 ]; then
194				fail "ssh cert connect succeeded unexpecedly"
195			fi
196		done
197	
198		# Revoked CA
199		verbose "$tid: ${ktype} $auth revoked CA key"
200		(
201			cat $OBJ/sshd_proxy_bak
202			echo "RevokedKeys $OBJ/user_ca_key.pub"
203			echo "$extra_sshd"
204		) > $OBJ/sshd_proxy
205		${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \
206		    somehost true >/dev/null 2>&1
207		if [ $? -eq 0 ]; then
208			fail "ssh cert connect succeeded unexpecedly"
209		fi
210	done
211	
212	verbose "$tid: $auth CA does not authenticate"
213	(
214		cat $OBJ/sshd_proxy_bak
215		echo "$extra_sshd"
216	) > $OBJ/sshd_proxy
217	verbose "$tid: ensure CA key does not authenticate user"
218	${SSH} -2i $OBJ/user_ca_key \
219	    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
220	if [ $? -eq 0 ]; then
221		fail "ssh cert connect with CA key succeeded unexpectedly"
222	fi
223}
224
225basic_tests authorized_keys
226basic_tests TrustedUserCAKeys
227
228test_one() {
229	ident=$1
230	result=$2
231	sign_opts=$3
232	auth_choice=$4
233	auth_opt=$5
234
235	if test "x$auth_choice" = "x" ; then
236		auth_choice="authorized_keys TrustedUserCAKeys"
237	fi
238
239	for auth in $auth_choice ; do
240		for ktype in rsa rsa_v00 ; do
241			case $ktype in
242			*_v00) keyv="-t v00" ;;
243			*) keyv="" ;;
244			esac
245
246			cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy
247			if test "x$auth" = "xauthorized_keys" ; then
248				# Add CA to authorized_keys
249				(
250					echon "cert-authority${auth_opt} "
251					cat $OBJ/user_ca_key.pub
252				) > $OBJ/authorized_keys_$USER
253			else
254				echo > $OBJ/authorized_keys_$USER
255				echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" \
256				    >> $OBJ/sshd_proxy
257				if test "x$auth_opt" != "x" ; then
258					echo $auth_opt >> $OBJ/sshd_proxy
259				fi
260			fi
261			
262			verbose "$tid: $ident auth $auth expect $result $ktype"
263			${SSHKEYGEN} -q -s $OBJ/user_ca_key \
264			    -I "regress user key for $USER" \
265			    $sign_opts $keyv \
266			    $OBJ/cert_user_key_${ktype} ||
267				fail "couldn't sign cert_user_key_${ktype}"
268
269			${SSH} -2i $OBJ/cert_user_key_${ktype} \
270			    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
271			rc=$?
272			if [ "x$result" = "xsuccess" ] ; then
273				if [ $rc -ne 0 ]; then
274					fail "$ident failed unexpectedly"
275				fi
276			else
277				if [ $rc -eq 0 ]; then
278					fail "$ident succeeded unexpectedly"
279				fi
280			fi
281		done
282	done
283}
284
285test_one "correct principal"	success "-n ${USER}"
286test_one "host-certificate"	failure "-n ${USER} -h"
287test_one "wrong principals"	failure "-n foo"
288test_one "cert not yet valid"	failure "-n ${USER} -V20200101:20300101"
289test_one "cert expired"		failure "-n ${USER} -V19800101:19900101"
290test_one "cert valid interval"	success "-n ${USER} -V-1w:+2w"
291test_one "wrong source-address"	failure "-n ${USER} -Osource-address=10.0.0.0/8"
292test_one "force-command"	failure "-n ${USER} -Oforce-command=false"
293
294# Behaviour is different here: TrustedUserCAKeys doesn't allow empty principals
295test_one "empty principals"	success "" authorized_keys
296test_one "empty principals"	failure "" TrustedUserCAKeys
297
298# Check explicitly-specified principals: an empty principals list in the cert
299# should always be refused.
300
301# AuthorizedPrincipalsFile
302rm -f $OBJ/authorized_keys_$USER
303echo mekmitasdigoat > $OBJ/authorized_principals_$USER
304test_one "AuthorizedPrincipalsFile principals" success "-n mekmitasdigoat" \
305    TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u"
306test_one "AuthorizedPrincipalsFile no principals" failure "" \
307    TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u"
308
309# principals= key option
310rm -f $OBJ/authorized_principals_$USER
311test_one "principals key option principals" success "-n mekmitasdigoat" \
312    authorized_keys ',principals="mekmitasdigoat"'
313test_one "principals key option no principals" failure "" \
314    authorized_keys ',principals="mekmitasdigoat"'
315
316# Wrong certificate
317cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy
318for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00 ; do 
319	case $ktype in
320	*_v00) args="-t v00" ;;
321	*) args="" ;;
322	esac
323	# Self-sign
324	${SSHKEYGEN} $args -q -s $OBJ/cert_user_key_${ktype} -I \
325	    "regress user key for $USER" \
326	    -n $USER $OBJ/cert_user_key_${ktype} ||
327		fail "couldn't sign cert_user_key_${ktype}"
328	verbose "$tid: user ${ktype} connect wrong cert"
329	${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \
330	    somehost true >/dev/null 2>&1
331	if [ $? -eq 0 ]; then
332		fail "ssh cert connect $ident succeeded unexpectedly"
333	fi
334done
335
336rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key*
337rm -f $OBJ/authorized_principals_$USER
338
339