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