1264377Sdes#	$OpenBSD: cert-hostkey.sh,v 1.9 2014/01/26 10:22:10 djm Exp $
2204861Sdes#	Placed in the Public Domain.
3204861Sdes
4204861Sdestid="certified host keys"
5204861Sdes
6204861Sdesrm -f $OBJ/known_hosts-cert $OBJ/host_ca_key* $OBJ/cert_host_key*
7204861Sdescp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
8204861Sdes
9204861SdesHOSTS='localhost-with-alias,127.0.0.1,::1'
10204861Sdes
11204861Sdes# Create a CA key and add it to known hosts
12204861Sdes${SSHKEYGEN} -q -N '' -t rsa  -f $OBJ/host_ca_key ||\
13204861Sdes	fail "ssh-keygen of host_ca_key failed"
14204861Sdes(
15255670Sdes	printf '@cert-authority '
16255670Sdes	printf "$HOSTS "
17204861Sdes	cat $OBJ/host_ca_key.pub
18204861Sdes) > $OBJ/known_hosts-cert
19204861Sdes
20262566SdesPLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'`
21262566Sdes
22262566Sdestype_has_legacy() {
23262566Sdes	case $1 in
24262566Sdes		ed25519*|ecdsa*) return 1 ;;
25262566Sdes	esac
26262566Sdes	return 0
27262566Sdes}
28262566Sdes
29204861Sdes# Generate and sign host keys
30262566Sdesfor ktype in $PLAIN_TYPES ; do 
31204861Sdes	verbose "$tid: sign host ${ktype} cert"
32204861Sdes	# Generate and sign a host key
33204861Sdes	${SSHKEYGEN} -q -N '' -t ${ktype} \
34204861Sdes	    -f $OBJ/cert_host_key_${ktype} || \
35204861Sdes		fail "ssh-keygen of cert_host_key_${ktype} failed"
36204861Sdes	${SSHKEYGEN} -h -q -s $OBJ/host_ca_key \
37204861Sdes	    -I "regress host key for $USER" \
38204861Sdes	    -n $HOSTS $OBJ/cert_host_key_${ktype} ||
39204861Sdes		fail "couldn't sign cert_host_key_${ktype}"
40262566Sdes	type_has_legacy $ktype || continue
41214979Sdes	cp $OBJ/cert_host_key_${ktype} $OBJ/cert_host_key_${ktype}_v00
42214979Sdes	cp $OBJ/cert_host_key_${ktype}.pub $OBJ/cert_host_key_${ktype}_v00.pub
43262566Sdes	verbose "$tid: sign host ${ktype}_v00 cert"
44214979Sdes	${SSHKEYGEN} -t v00 -h -q -s $OBJ/host_ca_key \
45214979Sdes	    -I "regress host key for $USER" \
46214979Sdes	    -n $HOSTS $OBJ/cert_host_key_${ktype}_v00 ||
47214979Sdes		fail "couldn't sign cert_host_key_${ktype}_v00"
48204861Sdesdone
49204861Sdes
50204861Sdes# Basic connect tests
51204861Sdesfor privsep in yes no ; do
52262566Sdes	for ktype in $PLAIN_TYPES rsa_v00 dsa_v00; do 
53204861Sdes		verbose "$tid: host ${ktype} cert connect privsep $privsep"
54204861Sdes		(
55204861Sdes			cat $OBJ/sshd_proxy_bak
56204861Sdes			echo HostKey $OBJ/cert_host_key_${ktype}
57204861Sdes			echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub
58204861Sdes			echo UsePrivilegeSeparation $privsep
59204861Sdes		) > $OBJ/sshd_proxy
60204861Sdes
61204861Sdes		${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
62204861Sdes		    -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
63204861Sdes			-F $OBJ/ssh_proxy somehost true
64204861Sdes		if [ $? -ne 0 ]; then
65204861Sdes			fail "ssh cert connect failed"
66204861Sdes		fi
67204861Sdes	done
68204861Sdesdone
69204861Sdes
70204861Sdes# Revoked certificates with key present
71204861Sdes(
72255670Sdes	printf '@cert-authority '
73255670Sdes	printf "$HOSTS "
74204861Sdes	cat $OBJ/host_ca_key.pub
75262566Sdes	for ktype in $PLAIN_TYPES rsa_v00 dsa_v00; do
76262566Sdes		test -f "$OBJ/cert_host_key_${ktype}.pub" || fatal "no pubkey"
77262566Sdes		printf "@revoked * `cat $OBJ/cert_host_key_${ktype}.pub`\n"
78262566Sdes	done
79204861Sdes) > $OBJ/known_hosts-cert
80204861Sdesfor privsep in yes no ; do
81262566Sdes	for ktype in $PLAIN_TYPES rsa_v00 dsa_v00; do 
82204861Sdes		verbose "$tid: host ${ktype} revoked cert privsep $privsep"
83204861Sdes		(
84204861Sdes			cat $OBJ/sshd_proxy_bak
85204861Sdes			echo HostKey $OBJ/cert_host_key_${ktype}
86204861Sdes			echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub
87204861Sdes			echo UsePrivilegeSeparation $privsep
88204861Sdes		) > $OBJ/sshd_proxy
89204861Sdes
90204861Sdes		${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
91204861Sdes		    -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
92204861Sdes			-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
93204861Sdes		if [ $? -eq 0 ]; then
94204861Sdes			fail "ssh cert connect succeeded unexpectedly"
95204861Sdes		fi
96204861Sdes	done
97204861Sdesdone
98204861Sdes
99204861Sdes# Revoked CA
100204861Sdes(
101255670Sdes	printf '@cert-authority '
102255670Sdes	printf "$HOSTS "
103204861Sdes	cat $OBJ/host_ca_key.pub
104255670Sdes	printf '@revoked '
105255670Sdes	printf "* "
106204861Sdes	cat $OBJ/host_ca_key.pub
107204861Sdes) > $OBJ/known_hosts-cert
108262566Sdesfor ktype in $PLAIN_TYPES rsa_v00 dsa_v00 ; do 
109204861Sdes	verbose "$tid: host ${ktype} revoked cert"
110204861Sdes	(
111204861Sdes		cat $OBJ/sshd_proxy_bak
112204861Sdes		echo HostKey $OBJ/cert_host_key_${ktype}
113204861Sdes		echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub
114204861Sdes	) > $OBJ/sshd_proxy
115204861Sdes	${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
116204861Sdes	    -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
117204861Sdes		-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
118204861Sdes	if [ $? -eq 0 ]; then
119204861Sdes		fail "ssh cert connect succeeded unexpectedly"
120204861Sdes	fi
121204861Sdesdone
122204861Sdes
123204861Sdes# Create a CA key and add it to known hosts
124204861Sdes(
125255670Sdes	printf '@cert-authority '
126255670Sdes	printf "$HOSTS "
127204861Sdes	cat $OBJ/host_ca_key.pub
128204861Sdes) > $OBJ/known_hosts-cert
129204861Sdes
130204861Sdestest_one() {
131204861Sdes	ident=$1
132204861Sdes	result=$2
133204861Sdes	sign_opts=$3
134204861Sdes
135214979Sdes	for kt in rsa rsa_v00 ; do
136214979Sdes		case $kt in
137214979Sdes		*_v00) args="-t v00" ;;
138214979Sdes		*) args="" ;;
139214979Sdes		esac
140204861Sdes
141214979Sdes		verbose "$tid: host cert connect $ident $kt expect $result"
142214979Sdes		${SSHKEYGEN} -q -s $OBJ/host_ca_key \
143214979Sdes		    -I "regress host key for $USER" \
144214979Sdes		    $sign_opts $args \
145214979Sdes		    $OBJ/cert_host_key_${kt} ||
146214979Sdes			fail "couldn't sign cert_host_key_${kt}"
147214979Sdes		(
148214979Sdes			cat $OBJ/sshd_proxy_bak
149214979Sdes			echo HostKey $OBJ/cert_host_key_${kt}
150214979Sdes			echo HostCertificate $OBJ/cert_host_key_${kt}-cert.pub
151214979Sdes		) > $OBJ/sshd_proxy
152214979Sdes	
153214979Sdes		${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
154214979Sdes		    -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
155214979Sdes		    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
156214979Sdes		rc=$?
157214979Sdes		if [ "x$result" = "xsuccess" ] ; then
158214979Sdes			if [ $rc -ne 0 ]; then
159214979Sdes				fail "ssh cert connect $ident failed unexpectedly"
160214979Sdes			fi
161214979Sdes		else
162214979Sdes			if [ $rc -eq 0 ]; then
163214979Sdes				fail "ssh cert connect $ident succeeded unexpectedly"
164214979Sdes			fi
165204861Sdes		fi
166214979Sdes	done
167204861Sdes}
168204861Sdes
169204861Sdestest_one "user-certificate"	failure "-n $HOSTS"
170204861Sdestest_one "empty principals"	success "-h"
171204861Sdestest_one "wrong principals"	failure "-h -n foo"
172204861Sdestest_one "cert not yet valid"	failure "-h -V20200101:20300101"
173204861Sdestest_one "cert expired"		failure "-h -V19800101:19900101"
174204861Sdestest_one "cert valid interval"	success "-h -V-1w:+2w"
175204861Sdestest_one "cert has constraints"	failure "-h -Oforce-command=false"
176204861Sdes
177204861Sdes# Check downgrade of cert to raw key when no CA found
178214979Sdesfor v in v01 v00 ;  do 
179262566Sdes	for ktype in $PLAIN_TYPES ; do 
180262566Sdes		type_has_legacy $ktype || continue
181214979Sdes		rm -f $OBJ/known_hosts-cert $OBJ/cert_host_key*
182214979Sdes		verbose "$tid: host ${ktype} ${v} cert downgrade to raw key"
183214979Sdes		# Generate and sign a host key
184214979Sdes		${SSHKEYGEN} -q -N '' -t ${ktype} \
185214979Sdes		    -f $OBJ/cert_host_key_${ktype} || \
186214979Sdes			fail "ssh-keygen of cert_host_key_${ktype} failed"
187214979Sdes		${SSHKEYGEN} -t ${v} -h -q -s $OBJ/host_ca_key \
188214979Sdes		    -I "regress host key for $USER" \
189214979Sdes		    -n $HOSTS $OBJ/cert_host_key_${ktype} ||
190214979Sdes			fail "couldn't sign cert_host_key_${ktype}"
191214979Sdes		(
192255670Sdes			printf "$HOSTS "
193214979Sdes			cat $OBJ/cert_host_key_${ktype}.pub
194214979Sdes		) > $OBJ/known_hosts-cert
195214979Sdes		(
196214979Sdes			cat $OBJ/sshd_proxy_bak
197214979Sdes			echo HostKey $OBJ/cert_host_key_${ktype}
198214979Sdes			echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub
199214979Sdes		) > $OBJ/sshd_proxy
200214979Sdes		
201214979Sdes		${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
202214979Sdes		    -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
203214979Sdes			-F $OBJ/ssh_proxy somehost true
204214979Sdes		if [ $? -ne 0 ]; then
205214979Sdes			fail "ssh cert connect failed"
206214979Sdes		fi
207214979Sdes	done
208204861Sdesdone
209204861Sdes
210204861Sdes# Wrong certificate
211204861Sdes(
212255670Sdes	printf '@cert-authority '
213255670Sdes	printf "$HOSTS "
214204861Sdes	cat $OBJ/host_ca_key.pub
215204861Sdes) > $OBJ/known_hosts-cert
216214979Sdesfor v in v01 v00 ;  do 
217262566Sdes	for kt in $PLAIN_TYPES ; do 
218262566Sdes		type_has_legacy $kt || continue
219214979Sdes		rm -f $OBJ/cert_host_key*
220214979Sdes		# Self-sign key
221214979Sdes		${SSHKEYGEN} -q -N '' -t ${kt} \
222214979Sdes		    -f $OBJ/cert_host_key_${kt} || \
223214979Sdes			fail "ssh-keygen of cert_host_key_${kt} failed"
224214979Sdes		${SSHKEYGEN} -t ${v} -h -q -s $OBJ/cert_host_key_${kt} \
225214979Sdes		    -I "regress host key for $USER" \
226214979Sdes		    -n $HOSTS $OBJ/cert_host_key_${kt} ||
227214979Sdes			fail "couldn't sign cert_host_key_${kt}"
228214979Sdes		verbose "$tid: host ${kt} connect wrong cert"
229214979Sdes		(
230214979Sdes			cat $OBJ/sshd_proxy_bak
231214979Sdes			echo HostKey $OBJ/cert_host_key_${kt}
232214979Sdes			echo HostCertificate $OBJ/cert_host_key_${kt}-cert.pub
233214979Sdes		) > $OBJ/sshd_proxy
234214979Sdes	
235214979Sdes		${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
236214979Sdes		    -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
237214979Sdes			-F $OBJ/ssh_proxy -q somehost true >/dev/null 2>&1
238214979Sdes		if [ $? -eq 0 ]; then
239214979Sdes			fail "ssh cert connect $ident succeeded unexpectedly"
240214979Sdes		fi
241214979Sdes	done
242204861Sdesdone
243204861Sdes
244204861Sdesrm -f $OBJ/known_hosts-cert $OBJ/host_ca_key* $OBJ/cert_host_key*
245