1#	$OpenBSD: cert-hostkey.sh,v 1.7 2013/05/17 00:37:40 dtucker Exp $
2#	Placed in the Public Domain.
3
4tid="certified host keys"
5
6# used to disable ECC based tests on platforms without ECC
7ecdsa=""
8if test "x$TEST_SSH_ECC" = "xyes"; then
9	ecdsa=ecdsa
10fi
11
12rm -f $OBJ/known_hosts-cert $OBJ/host_ca_key* $OBJ/cert_host_key*
13cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
14
15HOSTS='localhost-with-alias,127.0.0.1,::1'
16
17# Create a CA key and add it to known hosts
18${SSHKEYGEN} -q -N '' -t rsa  -f $OBJ/host_ca_key ||\
19	fail "ssh-keygen of host_ca_key failed"
20(
21	printf '@cert-authority '
22	printf "$HOSTS "
23	cat $OBJ/host_ca_key.pub
24) > $OBJ/known_hosts-cert
25
26# Generate and sign host keys
27for ktype in rsa dsa $ecdsa ; do 
28	verbose "$tid: sign host ${ktype} cert"
29	# Generate and sign a host key
30	${SSHKEYGEN} -q -N '' -t ${ktype} \
31	    -f $OBJ/cert_host_key_${ktype} || \
32		fail "ssh-keygen of cert_host_key_${ktype} failed"
33	${SSHKEYGEN} -h -q -s $OBJ/host_ca_key \
34	    -I "regress host key for $USER" \
35	    -n $HOSTS $OBJ/cert_host_key_${ktype} ||
36		fail "couldn't sign cert_host_key_${ktype}"
37	# v00 ecdsa certs do not exist
38	test "${ktype}" = "ecdsa" && continue
39	cp $OBJ/cert_host_key_${ktype} $OBJ/cert_host_key_${ktype}_v00
40	cp $OBJ/cert_host_key_${ktype}.pub $OBJ/cert_host_key_${ktype}_v00.pub
41	${SSHKEYGEN} -t v00 -h -q -s $OBJ/host_ca_key \
42	    -I "regress host key for $USER" \
43	    -n $HOSTS $OBJ/cert_host_key_${ktype}_v00 ||
44		fail "couldn't sign cert_host_key_${ktype}_v00"
45done
46
47# Basic connect tests
48for privsep in yes no ; do
49	for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00; do 
50		verbose "$tid: host ${ktype} cert connect privsep $privsep"
51		(
52			cat $OBJ/sshd_proxy_bak
53			echo HostKey $OBJ/cert_host_key_${ktype}
54			echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub
55			echo UsePrivilegeSeparation $privsep
56		) > $OBJ/sshd_proxy
57
58		${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
59		    -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
60			-F $OBJ/ssh_proxy somehost true
61		if [ $? -ne 0 ]; then
62			fail "ssh cert connect failed"
63		fi
64	done
65done
66
67# Revoked certificates with key present
68(
69	printf '@cert-authority '
70	printf "$HOSTS "
71	cat $OBJ/host_ca_key.pub
72	printf '@revoked '
73	printf "* "
74	cat $OBJ/cert_host_key_rsa.pub
75	if test "x$TEST_SSH_ECC" = "xyes"; then
76		printf '@revoked '
77		printf "* "
78		cat $OBJ/cert_host_key_ecdsa.pub
79	fi
80	printf '@revoked '
81	printf "* "
82	cat $OBJ/cert_host_key_dsa.pub
83	printf '@revoked '
84	printf "* "
85	cat $OBJ/cert_host_key_rsa_v00.pub
86	printf '@revoked '
87	printf "* "
88	cat $OBJ/cert_host_key_dsa_v00.pub
89) > $OBJ/known_hosts-cert
90for privsep in yes no ; do
91	for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00; do 
92		verbose "$tid: host ${ktype} revoked cert privsep $privsep"
93		(
94			cat $OBJ/sshd_proxy_bak
95			echo HostKey $OBJ/cert_host_key_${ktype}
96			echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub
97			echo UsePrivilegeSeparation $privsep
98		) > $OBJ/sshd_proxy
99
100		${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
101		    -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
102			-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
103		if [ $? -eq 0 ]; then
104			fail "ssh cert connect succeeded unexpectedly"
105		fi
106	done
107done
108
109# Revoked CA
110(
111	printf '@cert-authority '
112	printf "$HOSTS "
113	cat $OBJ/host_ca_key.pub
114	printf '@revoked '
115	printf "* "
116	cat $OBJ/host_ca_key.pub
117) > $OBJ/known_hosts-cert
118for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00 ; do 
119	verbose "$tid: host ${ktype} revoked cert"
120	(
121		cat $OBJ/sshd_proxy_bak
122		echo HostKey $OBJ/cert_host_key_${ktype}
123		echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub
124	) > $OBJ/sshd_proxy
125	${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
126	    -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
127		-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
128	if [ $? -eq 0 ]; then
129		fail "ssh cert connect succeeded unexpectedly"
130	fi
131done
132
133# Create a CA key and add it to known hosts
134(
135	printf '@cert-authority '
136	printf "$HOSTS "
137	cat $OBJ/host_ca_key.pub
138) > $OBJ/known_hosts-cert
139
140test_one() {
141	ident=$1
142	result=$2
143	sign_opts=$3
144
145	for kt in rsa rsa_v00 ; do
146		case $kt in
147		*_v00) args="-t v00" ;;
148		*) args="" ;;
149		esac
150
151		verbose "$tid: host cert connect $ident $kt expect $result"
152		${SSHKEYGEN} -q -s $OBJ/host_ca_key \
153		    -I "regress host key for $USER" \
154		    $sign_opts $args \
155		    $OBJ/cert_host_key_${kt} ||
156			fail "couldn't sign cert_host_key_${kt}"
157		(
158			cat $OBJ/sshd_proxy_bak
159			echo HostKey $OBJ/cert_host_key_${kt}
160			echo HostCertificate $OBJ/cert_host_key_${kt}-cert.pub
161		) > $OBJ/sshd_proxy
162	
163		${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
164		    -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
165		    -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
166		rc=$?
167		if [ "x$result" = "xsuccess" ] ; then
168			if [ $rc -ne 0 ]; then
169				fail "ssh cert connect $ident failed unexpectedly"
170			fi
171		else
172			if [ $rc -eq 0 ]; then
173				fail "ssh cert connect $ident succeeded unexpectedly"
174			fi
175		fi
176	done
177}
178
179test_one "user-certificate"	failure "-n $HOSTS"
180test_one "empty principals"	success "-h"
181test_one "wrong principals"	failure "-h -n foo"
182test_one "cert not yet valid"	failure "-h -V20200101:20300101"
183test_one "cert expired"		failure "-h -V19800101:19900101"
184test_one "cert valid interval"	success "-h -V-1w:+2w"
185test_one "cert has constraints"	failure "-h -Oforce-command=false"
186
187# Check downgrade of cert to raw key when no CA found
188for v in v01 v00 ;  do 
189	for ktype in rsa dsa $ecdsa ; do 
190		# v00 ecdsa certs do not exist.
191		test "${v}${ktype}" = "v00ecdsa" && continue
192		rm -f $OBJ/known_hosts-cert $OBJ/cert_host_key*
193		verbose "$tid: host ${ktype} ${v} cert downgrade to raw key"
194		# Generate and sign a host key
195		${SSHKEYGEN} -q -N '' -t ${ktype} \
196		    -f $OBJ/cert_host_key_${ktype} || \
197			fail "ssh-keygen of cert_host_key_${ktype} failed"
198		${SSHKEYGEN} -t ${v} -h -q -s $OBJ/host_ca_key \
199		    -I "regress host key for $USER" \
200		    -n $HOSTS $OBJ/cert_host_key_${ktype} ||
201			fail "couldn't sign cert_host_key_${ktype}"
202		(
203			printf "$HOSTS "
204			cat $OBJ/cert_host_key_${ktype}.pub
205		) > $OBJ/known_hosts-cert
206		(
207			cat $OBJ/sshd_proxy_bak
208			echo HostKey $OBJ/cert_host_key_${ktype}
209			echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub
210		) > $OBJ/sshd_proxy
211		
212		${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
213		    -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
214			-F $OBJ/ssh_proxy somehost true
215		if [ $? -ne 0 ]; then
216			fail "ssh cert connect failed"
217		fi
218	done
219done
220
221# Wrong certificate
222(
223	printf '@cert-authority '
224	printf "$HOSTS "
225	cat $OBJ/host_ca_key.pub
226) > $OBJ/known_hosts-cert
227for v in v01 v00 ;  do 
228	for kt in rsa dsa $ecdsa ; do 
229		# v00 ecdsa certs do not exist.
230		test "${v}${ktype}" = "v00ecdsa" && continue
231		rm -f $OBJ/cert_host_key*
232		# Self-sign key
233		${SSHKEYGEN} -q -N '' -t ${kt} \
234		    -f $OBJ/cert_host_key_${kt} || \
235			fail "ssh-keygen of cert_host_key_${kt} failed"
236		${SSHKEYGEN} -t ${v} -h -q -s $OBJ/cert_host_key_${kt} \
237		    -I "regress host key for $USER" \
238		    -n $HOSTS $OBJ/cert_host_key_${kt} ||
239			fail "couldn't sign cert_host_key_${kt}"
240		verbose "$tid: host ${kt} connect wrong cert"
241		(
242			cat $OBJ/sshd_proxy_bak
243			echo HostKey $OBJ/cert_host_key_${kt}
244			echo HostCertificate $OBJ/cert_host_key_${kt}-cert.pub
245		) > $OBJ/sshd_proxy
246	
247		${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
248		    -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
249			-F $OBJ/ssh_proxy -q somehost true >/dev/null 2>&1
250		if [ $? -eq 0 ]; then
251			fail "ssh cert connect $ident succeeded unexpectedly"
252		fi
253	done
254done
255
256rm -f $OBJ/known_hosts-cert $OBJ/host_ca_key* $OBJ/cert_host_key*
257