cert-userkey.sh revision 1.5
1#	$OpenBSD: cert-userkey.sh,v 1.5 2010/05/07 11:31:26 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		# Setup for principals= key option
83		rm -f $OBJ/authorized_principals_$USER
84		(
85			cat $OBJ/sshd_proxy_bak
86			echo "UsePrivilegeSeparation $privsep"
87		) > $OBJ/sshd_proxy
88
89		# Wrong principals list
90		verbose "$tid: ${_prefix} wrong principals key option"
91		(
92			echo -n 'cert-authority,principals="gregorsamsa" '
93			cat $OBJ/user_ca_key.pub
94		) > $OBJ/authorized_keys_$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		# Correct principals list
102		verbose "$tid: ${_prefix} correct principals key option"
103		(
104			echo -n 'cert-authority,principals="mekmitasdigoat" '
105			cat $OBJ/user_ca_key.pub
106		) > $OBJ/authorized_keys_$USER
107		${SSH} -2i $OBJ/cert_user_key_${ktype} \
108		    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
109		if [ $? -ne 0 ]; then
110			fail "ssh cert connect failed"
111		fi
112	done
113done
114
115basic_tests() {
116	auth=$1
117	if test "x$auth" = "xauthorized_keys" ; then
118		# Add CA to authorized_keys
119		(
120			echo -n 'cert-authority '
121			cat $OBJ/user_ca_key.pub
122		) > $OBJ/authorized_keys_$USER
123	else
124		echo > $OBJ/authorized_keys_$USER
125		extra_sshd="TrustedUserCAKeys $OBJ/user_ca_key.pub"
126	fi
127	
128	for ktype in rsa dsa rsa_v00 dsa_v00 ; do 
129		for privsep in yes no ; do
130			_prefix="${ktype} privsep $privsep $auth"
131			# Simple connect
132			verbose "$tid: ${_prefix} connect"
133			(
134				cat $OBJ/sshd_proxy_bak
135				echo "UsePrivilegeSeparation $privsep"
136				echo "$extra_sshd"
137			) > $OBJ/sshd_proxy
138	
139			${SSH} -2i $OBJ/cert_user_key_${ktype} \
140			    -F $OBJ/ssh_proxy somehost true
141			if [ $? -ne 0 ]; then
142				fail "ssh cert connect failed"
143			fi
144
145			# Revoked keys
146			verbose "$tid: ${_prefix} revoked key"
147			(
148				cat $OBJ/sshd_proxy_bak
149				echo "UsePrivilegeSeparation $privsep"
150				echo "RevokedKeys $OBJ/cert_user_key_${ktype}.pub"
151				echo "$extra_sshd"
152			) > $OBJ/sshd_proxy
153			${SSH} -2i $OBJ/cert_user_key_${ktype} \
154			    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
155			if [ $? -eq 0 ]; then
156				fail "ssh cert connect succeeded unexpecedly"
157			fi
158		done
159	
160		# Revoked CA
161		verbose "$tid: ${ktype} $auth revoked CA key"
162		(
163			cat $OBJ/sshd_proxy_bak
164			echo "RevokedKeys $OBJ/user_ca_key.pub"
165			echo "$extra_sshd"
166		) > $OBJ/sshd_proxy
167		${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \
168		    somehost true >/dev/null 2>&1
169		if [ $? -eq 0 ]; then
170			fail "ssh cert connect succeeded unexpecedly"
171		fi
172	done
173	
174	verbose "$tid: $auth CA does not authenticate"
175	(
176		cat $OBJ/sshd_proxy_bak
177		echo "$extra_sshd"
178	) > $OBJ/sshd_proxy
179	verbose "$tid: ensure CA key does not authenticate user"
180	${SSH} -2i $OBJ/user_ca_key \
181	    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
182	if [ $? -eq 0 ]; then
183		fail "ssh cert connect with CA key succeeded unexpectedly"
184	fi
185}
186
187basic_tests authorized_keys
188basic_tests TrustedUserCAKeys
189
190test_one() {
191	ident=$1
192	result=$2
193	sign_opts=$3
194	auth_choice=$4
195	auth_opt=$5
196
197	if test "x$auth_choice" = "x" ; then
198		auth_choice="authorized_keys TrustedUserCAKeys"
199	fi
200
201	for auth in $auth_choice ; do
202		for ktype in rsa rsa_v00 ; do
203			cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy
204			if test "x$auth" = "xauthorized_keys" ; then
205				# Add CA to authorized_keys
206				(
207					echo -n "cert-authority${auth_opt} "
208					cat $OBJ/user_ca_key.pub
209				) > $OBJ/authorized_keys_$USER
210			else
211				echo > $OBJ/authorized_keys_$USER
212				echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" \
213				    >> $OBJ/sshd_proxy
214				if test "x$auth_opt" != "x" ; then
215					echo $auth_opt >> $OBJ/sshd_proxy
216				fi
217			fi
218			
219			verbose "$tid: $ident auth $auth expect $result $ktype"
220			${SSHKEYGEN} -q -s $OBJ/user_ca_key \
221			    -I "regress user key for $USER" \
222			    $sign_opts \
223			    $OBJ/cert_user_key_${ktype} ||
224				fail "couldn't sign cert_user_key_${ktype}"
225
226			${SSH} -2i $OBJ/cert_user_key_${ktype} \
227			    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
228			rc=$?
229			if [ "x$result" = "xsuccess" ] ; then
230				if [ $rc -ne 0 ]; then
231					fail "$ident failed unexpectedly"
232				fi
233			else
234				if [ $rc -eq 0 ]; then
235					fail "$ident succeeded unexpectedly"
236				fi
237			fi
238		done
239	done
240}
241
242test_one "correct principal"	success "-n ${USER}"
243test_one "host-certificate"	failure "-n ${USER} -h"
244test_one "wrong principals"	failure "-n foo"
245test_one "cert not yet valid"	failure "-n ${USER} -V20200101:20300101"
246test_one "cert expired"		failure "-n ${USER} -V19800101:19900101"
247test_one "cert valid interval"	success "-n ${USER} -V-1w:+2w"
248test_one "wrong source-address"	failure "-n ${USER} -Osource-address=10.0.0.0/8"
249test_one "force-command"	failure "-n ${USER} -Oforce-command=false"
250
251# Behaviour is different here: TrustedUserCAKeys doesn't allow empty principals
252test_one "empty principals"	success "" authorized_keys
253test_one "empty principals"	failure "" TrustedUserCAKeys
254
255# Check explicitly-specified principals: an empty principals list in the cert
256# should always be refused.
257
258# AuthorizedPrincipalsFile
259rm -f $OBJ/authorized_keys_$USER
260echo mekmitasdigoat > $OBJ/authorized_principals_$USER
261test_one "AuthorizedPrincipalsFile principals" success "-n mekmitasdigoat" \
262    TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u"
263test_one "AuthorizedPrincipalsFile no principals" failure "" \
264    TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u"
265
266# principals= key option
267rm -f $OBJ/authorized_principals_$USER
268test_one "principals key option principals" success "-n mekmitasdigoat" \
269    authorized_keys ',principals="mekmitasdigoat"'
270test_one "principals key option no principals" failure "" \
271    authorized_keys ',principals="mekmitasdigoat"'
272
273# Wrong certificate
274cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy
275for ktype in rsa dsa rsa_v00 dsa_v00 ; do 
276	case $ktype in
277	*_v00) args="-t v00" ;;
278	*) args="" ;;
279	esac
280	# Self-sign
281	${SSHKEYGEN} $args -q -s $OBJ/cert_user_key_${ktype} -I \
282	    "regress user key for $USER" \
283	    -n $USER $OBJ/cert_user_key_${ktype} ||
284		fail "couldn't sign cert_user_key_${ktype}"
285	verbose "$tid: user ${ktype} connect wrong cert"
286	${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \
287	    somehost true >/dev/null 2>&1
288	if [ $? -eq 0 ]; then
289		fail "ssh cert connect $ident succeeded unexpectedly"
290	fi
291done
292
293rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key*
294rm -f $OBJ/authorized_principals_$USER
295
296