cert-userkey.sh revision 261320
1265236Sken#	$OpenBSD: cert-userkey.sh,v 1.12 2013/12/06 13:52:46 markus Exp $
2283661Sslm#	Placed in the Public Domain.
3299263Sslm
4265236Skentid="certified user keys"
5265236Sken
6265236Skenrm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key*
7265236Skencp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
8265236Sken
9265236SkenPLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'`
10265236Sken
11265236Skentype_has_legacy() {
12265236Sken	case $1 in
13265236Sken		ed25519*|ecdsa*) return 1 ;;
14265236Sken	esac
15265236Sken	return 0
16265236Sken}
17265236Sken
18265236Sken# Create a CA key
19265236Sken${SSHKEYGEN} -q -N '' -t rsa  -f $OBJ/user_ca_key ||\
20265236Sken	fail "ssh-keygen of user_ca_key failed"
21265236Sken
22265236Sken# Generate and sign user keys
23265236Skenfor ktype in $PLAIN_TYPES ; do 
24265236Sken	verbose "$tid: sign user ${ktype} cert"
25265236Sken	${SSHKEYGEN} -q -N '' -t ${ktype} \
26265236Sken	    -f $OBJ/cert_user_key_${ktype} || \
27265236Sken		fail "ssh-keygen of cert_user_key_${ktype} failed"
28265236Sken	${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \
29265236Sken	    -z $$ -n ${USER},mekmitasdigoat $OBJ/cert_user_key_${ktype} ||
30283661Sslm		fail "couldn't sign cert_user_key_${ktype}"
31265236Sken	type_has_legacy $ktype || continue
32265236Sken	cp $OBJ/cert_user_key_${ktype} $OBJ/cert_user_key_${ktype}_v00
33265236Sken	cp $OBJ/cert_user_key_${ktype}.pub $OBJ/cert_user_key_${ktype}_v00.pub
34265236Sken	verbose "$tid: sign host ${ktype}_v00 cert"
35265236Sken	${SSHKEYGEN} -q -t v00 -s $OBJ/user_ca_key -I \
36283661Sslm	    "regress user key for $USER" \
37299263Sslm	    -n ${USER},mekmitasdigoat $OBJ/cert_user_key_${ktype}_v00 ||
38299263Sslm		fatal "couldn't sign cert_user_key_${ktype}_v00"
39265236Skendone
40265236Sken
41265236Sken# Test explicitly-specified principals
42265236Skenfor ktype in $PLAIN_TYPES rsa_v00 dsa_v00 ; do 
43265236Sken	for privsep in yes no ; do
44265236Sken		_prefix="${ktype} privsep $privsep"
45299263Sslm
46265236Sken		# Setup for AuthorizedPrincipalsFile
47265236Sken		rm -f $OBJ/authorized_keys_$USER
48265236Sken		(
49265236Sken			cat $OBJ/sshd_proxy_bak
50265236Sken			echo "UsePrivilegeSeparation $privsep"
51265236Sken			echo "AuthorizedPrincipalsFile " \
52265236Sken			    "$OBJ/authorized_principals_%u"
53265236Sken			echo "TrustedUserCAKeys $OBJ/user_ca_key.pub"
54265236Sken		) > $OBJ/sshd_proxy
55265236Sken
56265236Sken		# Missing authorized_principals
57265236Sken		verbose "$tid: ${_prefix} missing authorized_principals"
58265236Sken		rm -f $OBJ/authorized_principals_$USER
59265236Sken		${SSH} -2i $OBJ/cert_user_key_${ktype} \
60265236Sken		    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
61265236Sken		if [ $? -eq 0 ]; then
62265236Sken			fail "ssh cert connect succeeded unexpectedly"
63265236Sken		fi
64265236Sken
65265236Sken		# Empty authorized_principals
66265236Sken		verbose "$tid: ${_prefix} empty authorized_principals"
67265236Sken		echo > $OBJ/authorized_principals_$USER
68265236Sken		${SSH} -2i $OBJ/cert_user_key_${ktype} \
69265236Sken		    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
70265236Sken		if [ $? -eq 0 ]; then
71265236Sken			fail "ssh cert connect succeeded unexpectedly"
72265236Sken		fi
73265236Sken	
74265236Sken		# Wrong authorized_principals
75265236Sken		verbose "$tid: ${_prefix} wrong authorized_principals"
76265236Sken		echo gregorsamsa > $OBJ/authorized_principals_$USER
77265236Sken		${SSH} -2i $OBJ/cert_user_key_${ktype} \
78265236Sken		    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
79265236Sken		if [ $? -eq 0 ]; then
80265236Sken			fail "ssh cert connect succeeded unexpectedly"
81265236Sken		fi
82265236Sken
83265236Sken		# Correct authorized_principals
84265236Sken		verbose "$tid: ${_prefix} correct authorized_principals"
85265236Sken		echo mekmitasdigoat > $OBJ/authorized_principals_$USER
86265236Sken		${SSH} -2i $OBJ/cert_user_key_${ktype} \
87265236Sken		    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
88265236Sken		if [ $? -ne 0 ]; then
89265236Sken			fail "ssh cert connect failed"
90265236Sken		fi
91265236Sken
92265236Sken		# authorized_principals with bad key option
93265236Sken		verbose "$tid: ${_prefix} authorized_principals bad key opt"
94265236Sken		echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_$USER
95265236Sken		${SSH} -2i $OBJ/cert_user_key_${ktype} \
96265236Sken		    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
97265236Sken		if [ $? -eq 0 ]; then
98265236Sken			fail "ssh cert connect succeeded unexpectedly"
99265236Sken		fi
100265236Sken
101265236Sken		# authorized_principals with command=false
102265236Sken		verbose "$tid: ${_prefix} authorized_principals command=false"
103265236Sken		echo 'command="false" mekmitasdigoat' > \
104265236Sken		    $OBJ/authorized_principals_$USER
105265236Sken		${SSH} -2i $OBJ/cert_user_key_${ktype} \
106265236Sken		    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
107265236Sken		if [ $? -eq 0 ]; then
108265236Sken			fail "ssh cert connect succeeded unexpectedly"
109265236Sken		fi
110265236Sken
111265236Sken
112265236Sken		# authorized_principals with command=true
113265236Sken		verbose "$tid: ${_prefix} authorized_principals command=true"
114265236Sken		echo 'command="true" mekmitasdigoat' > \
115265236Sken		    $OBJ/authorized_principals_$USER
116265236Sken		${SSH} -2i $OBJ/cert_user_key_${ktype} \
117265236Sken		    -F $OBJ/ssh_proxy somehost false >/dev/null 2>&1
118265236Sken		if [ $? -ne 0 ]; then
119265236Sken			fail "ssh cert connect failed"
120265236Sken		fi
121265236Sken
122265236Sken		# Setup for principals= key option
123265236Sken		rm -f $OBJ/authorized_principals_$USER
124265236Sken		(
125265236Sken			cat $OBJ/sshd_proxy_bak
126265236Sken			echo "UsePrivilegeSeparation $privsep"
127265236Sken		) > $OBJ/sshd_proxy
128265236Sken
129265236Sken		# Wrong principals list
130265236Sken		verbose "$tid: ${_prefix} wrong principals key option"
131265236Sken		(
132265236Sken			printf 'cert-authority,principals="gregorsamsa" '
133265236Sken			cat $OBJ/user_ca_key.pub
134265236Sken		) > $OBJ/authorized_keys_$USER
135265236Sken		${SSH} -2i $OBJ/cert_user_key_${ktype} \
136265236Sken		    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
137265236Sken		if [ $? -eq 0 ]; then
138265236Sken			fail "ssh cert connect succeeded unexpectedly"
139265236Sken		fi
140265236Sken
141265236Sken		# Correct principals list
142265236Sken		verbose "$tid: ${_prefix} correct principals key option"
143265236Sken		(
144265236Sken			printf 'cert-authority,principals="mekmitasdigoat" '
145265236Sken			cat $OBJ/user_ca_key.pub
146265236Sken		) > $OBJ/authorized_keys_$USER
147265236Sken		${SSH} -2i $OBJ/cert_user_key_${ktype} \
148265236Sken		    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
149265236Sken		if [ $? -ne 0 ]; then
150265236Sken			fail "ssh cert connect failed"
151265236Sken		fi
152265236Sken	done
153265236Skendone
154265236Sken
155265236Skenbasic_tests() {
156265236Sken	auth=$1
157265236Sken	if test "x$auth" = "xauthorized_keys" ; then
158265236Sken		# Add CA to authorized_keys
159265236Sken		(
160265236Sken			printf 'cert-authority '
161265236Sken			cat $OBJ/user_ca_key.pub
162265236Sken		) > $OBJ/authorized_keys_$USER
163265236Sken	else
164265236Sken		echo > $OBJ/authorized_keys_$USER
165265236Sken		extra_sshd="TrustedUserCAKeys $OBJ/user_ca_key.pub"
166265236Sken	fi
167265236Sken	
168265236Sken	for ktype in $PLAIN_TYPES rsa_v00 dsa_v00 ; do 
169265236Sken		for privsep in yes no ; do
170265236Sken			_prefix="${ktype} privsep $privsep $auth"
171265236Sken			# Simple connect
172299263Sslm			verbose "$tid: ${_prefix} connect"
173299263Sslm			(
174299263Sslm				cat $OBJ/sshd_proxy_bak
175299263Sslm				echo "UsePrivilegeSeparation $privsep"
176299263Sslm				echo "$extra_sshd"
177299263Sslm			) > $OBJ/sshd_proxy
178299263Sslm	
179299263Sslm			${SSH} -2i $OBJ/cert_user_key_${ktype} \
180299263Sslm			    -F $OBJ/ssh_proxy somehost true
181299263Sslm			if [ $? -ne 0 ]; then
182299263Sslm				fail "ssh cert connect failed"
183265236Sken			fi
184265236Sken
185265236Sken			# Revoked keys
186265236Sken			verbose "$tid: ${_prefix} revoked key"
187265236Sken			(
188265236Sken				cat $OBJ/sshd_proxy_bak
189265236Sken				echo "UsePrivilegeSeparation $privsep"
190265236Sken				echo "RevokedKeys $OBJ/cert_user_key_revoked"
191265236Sken				echo "$extra_sshd"
192265236Sken			) > $OBJ/sshd_proxy
193265236Sken			cp $OBJ/cert_user_key_${ktype}.pub \
194265236Sken			    $OBJ/cert_user_key_revoked
195265236Sken			${SSH} -2i $OBJ/cert_user_key_${ktype} \
196265236Sken			    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
197265236Sken			if [ $? -eq 0 ]; then
198265236Sken				fail "ssh cert connect succeeded unexpecedly"
199265236Sken			fi
200265236Sken			verbose "$tid: ${_prefix} revoked via KRL"
201265236Sken			rm $OBJ/cert_user_key_revoked
202265236Sken			${SSHKEYGEN} -kqf $OBJ/cert_user_key_revoked \
203265236Sken			    $OBJ/cert_user_key_${ktype}.pub
204265236Sken			${SSH} -2i $OBJ/cert_user_key_${ktype} \
205265236Sken			    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
206265236Sken			if [ $? -eq 0 ]; then
207265236Sken				fail "ssh cert connect succeeded unexpecedly"
208265236Sken			fi
209265236Sken			verbose "$tid: ${_prefix} empty KRL"
210265236Sken			${SSHKEYGEN} -kqf $OBJ/cert_user_key_revoked
211265236Sken			${SSH} -2i $OBJ/cert_user_key_${ktype} \
212265236Sken			    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
213265236Sken			if [ $? -ne 0 ]; then
214265236Sken				fail "ssh cert connect failed"
215299263Sslm			fi
216299263Sslm		done
217265236Sken	
218265236Sken		# Revoked CA
219265236Sken		verbose "$tid: ${ktype} $auth revoked CA key"
220265236Sken		(
221265236Sken			cat $OBJ/sshd_proxy_bak
222265236Sken			echo "RevokedKeys $OBJ/user_ca_key.pub"
223265236Sken			echo "$extra_sshd"
224265236Sken		) > $OBJ/sshd_proxy
225265236Sken		${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \
226265236Sken		    somehost true >/dev/null 2>&1
227265236Sken		if [ $? -eq 0 ]; then
228265236Sken			fail "ssh cert connect succeeded unexpecedly"
229265236Sken		fi
230265236Sken	done
231265236Sken	
232265236Sken	verbose "$tid: $auth CA does not authenticate"
233265236Sken	(
234265236Sken		cat $OBJ/sshd_proxy_bak
235265236Sken		echo "$extra_sshd"
236265236Sken	) > $OBJ/sshd_proxy
237265236Sken	verbose "$tid: ensure CA key does not authenticate user"
238265236Sken	${SSH} -2i $OBJ/user_ca_key \
239265236Sken	    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
240265236Sken	if [ $? -eq 0 ]; then
241265236Sken		fail "ssh cert connect with CA key succeeded unexpectedly"
242265236Sken	fi
243265236Sken}
244265236Sken
245265236Skenbasic_tests authorized_keys
246265236Skenbasic_tests TrustedUserCAKeys
247265236Sken
248265236Skentest_one() {
249265236Sken	ident=$1
250265236Sken	result=$2
251265236Sken	sign_opts=$3
252265236Sken	auth_choice=$4
253265236Sken	auth_opt=$5
254265236Sken
255265236Sken	if test "x$auth_choice" = "x" ; then
256265236Sken		auth_choice="authorized_keys TrustedUserCAKeys"
257265236Sken	fi
258265236Sken
259265236Sken	for auth in $auth_choice ; do
260265236Sken		for ktype in rsa rsa_v00 ; do
261265236Sken			case $ktype in
262265236Sken			*_v00) keyv="-t v00" ;;
263265236Sken			*) keyv="" ;;
264265236Sken			esac
265265236Sken
266265236Sken			cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy
267265236Sken			if test "x$auth" = "xauthorized_keys" ; then
268265236Sken				# Add CA to authorized_keys
269265236Sken				(
270265236Sken					printf "cert-authority${auth_opt} "
271265236Sken					cat $OBJ/user_ca_key.pub
272265236Sken				) > $OBJ/authorized_keys_$USER
273265236Sken			else
274265236Sken				echo > $OBJ/authorized_keys_$USER
275265236Sken				echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" \
276265236Sken				    >> $OBJ/sshd_proxy
277265236Sken				if test "x$auth_opt" != "x" ; then
278265236Sken					echo $auth_opt >> $OBJ/sshd_proxy
279265236Sken				fi
280265236Sken			fi
281265236Sken			
282265236Sken			verbose "$tid: $ident auth $auth expect $result $ktype"
283265236Sken			${SSHKEYGEN} -q -s $OBJ/user_ca_key \
284265236Sken			    -I "regress user key for $USER" \
285265236Sken			    $sign_opts $keyv \
286265236Sken			    $OBJ/cert_user_key_${ktype} ||
287265236Sken				fail "couldn't sign cert_user_key_${ktype}"
288265236Sken
289265236Sken			${SSH} -2i $OBJ/cert_user_key_${ktype} \
290265236Sken			    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
291265236Sken			rc=$?
292265236Sken			if [ "x$result" = "xsuccess" ] ; then
293265236Sken				if [ $rc -ne 0 ]; then
294265236Sken					fail "$ident failed unexpectedly"
295265236Sken				fi
296265236Sken			else
297265236Sken				if [ $rc -eq 0 ]; then
298265236Sken					fail "$ident succeeded unexpectedly"
299265236Sken				fi
300265236Sken			fi
301265236Sken		done
302265236Sken	done
303265236Sken}
304265236Sken
305265236Skentest_one "correct principal"	success "-n ${USER}"
306265236Skentest_one "host-certificate"	failure "-n ${USER} -h"
307265236Skentest_one "wrong principals"	failure "-n foo"
308265236Skentest_one "cert not yet valid"	failure "-n ${USER} -V20200101:20300101"
309265236Skentest_one "cert expired"		failure "-n ${USER} -V19800101:19900101"
310265236Skentest_one "cert valid interval"	success "-n ${USER} -V-1w:+2w"
311265236Skentest_one "wrong source-address"	failure "-n ${USER} -Osource-address=10.0.0.0/8"
312265236Skentest_one "force-command"	failure "-n ${USER} -Oforce-command=false"
313265236Sken
314265236Sken# Behaviour is different here: TrustedUserCAKeys doesn't allow empty principals
315265236Skentest_one "empty principals"	success "" authorized_keys
316265236Skentest_one "empty principals"	failure "" TrustedUserCAKeys
317265236Sken
318265236Sken# Check explicitly-specified principals: an empty principals list in the cert
319265236Sken# should always be refused.
320265236Sken
321265236Sken# AuthorizedPrincipalsFile
322265236Skenrm -f $OBJ/authorized_keys_$USER
323265236Skenecho mekmitasdigoat > $OBJ/authorized_principals_$USER
324265236Skentest_one "AuthorizedPrincipalsFile principals" success "-n mekmitasdigoat" \
325265236Sken    TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u"
326265236Skentest_one "AuthorizedPrincipalsFile no principals" failure "" \
327265236Sken    TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u"
328265236Sken
329265236Sken# principals= key option
330265236Skenrm -f $OBJ/authorized_principals_$USER
331265236Skentest_one "principals key option principals" success "-n mekmitasdigoat" \
332265236Sken    authorized_keys ',principals="mekmitasdigoat"'
333265236Skentest_one "principals key option no principals" failure "" \
334265236Sken    authorized_keys ',principals="mekmitasdigoat"'
335265236Sken
336265236Sken# Wrong certificate
337265236Skencat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy
338265236Skenfor ktype in $PLAIN_TYPES rsa_v00 dsa_v00 ; do 
339265236Sken	case $ktype in
340265236Sken	*_v00) args="-t v00" ;;
341265236Sken	*) args="" ;;
342265236Sken	esac
343265236Sken	# Self-sign
344299263Sslm	${SSHKEYGEN} $args -q -s $OBJ/cert_user_key_${ktype} -I \
345299263Sslm	    "regress user key for $USER" \
346299263Sslm	    -n $USER $OBJ/cert_user_key_${ktype} ||
347299263Sslm		fail "couldn't sign cert_user_key_${ktype}"
348299263Sslm	verbose "$tid: user ${ktype} connect wrong cert"
349299263Sslm	${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \
350265236Sken	    somehost true >/dev/null 2>&1
351265236Sken	if [ $? -eq 0 ]; then
352265236Sken		fail "ssh cert connect $ident succeeded unexpectedly"
353265236Sken	fi
354265236Skendone
355265236Sken
356265236Skenrm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key*
357265236Skenrm -f $OBJ/authorized_principals_$USER
358265236Sken
359265236Sken