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