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