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