1295367Sdes#	$OpenBSD: keygen-knownhosts.sh,v 1.3 2015/07/17 03:34:27 djm Exp $
2285031Sdes#	Placed in the Public Domain.
3285031Sdes
4285031Sdestid="ssh-keygen known_hosts"
5285031Sdes
6285031Sdesrm -f $OBJ/kh.*
7285031Sdes
8285031Sdes# Generate some keys for testing (just ed25519 for speed) and make a hosts file.
9285031Sdesfor x in host-a host-b host-c host-d host-e host-f host-a2 host-b2; do
10285031Sdes	${SSHKEYGEN} -qt ed25519 -f $OBJ/kh.$x -C "$x" -N "" || \
11285031Sdes		fatal "ssh-keygen failed"
12285031Sdes	# Add a comment that we expect should be preserved.
13285031Sdes	echo "# $x" >> $OBJ/kh.hosts
14285031Sdes	(
15285031Sdes		case "$x" in
16285031Sdes		host-a|host-b)	printf "$x " ;;
17285031Sdes		host-c)		printf "@cert-authority $x " ;;
18285031Sdes		host-d)		printf "@revoked $x " ;;
19285031Sdes		host-e)		printf "host-e* " ;;
20285031Sdes		host-f)		printf "host-f,host-g,host-h " ;;
21285031Sdes		host-a2)	printf "host-a " ;;
22285031Sdes		host-b2)	printf "host-b " ;;
23285031Sdes		esac
24285031Sdes		cat $OBJ/kh.${x}.pub
25285031Sdes		# Blank line should be preserved.
26285031Sdes		echo "" >> $OBJ/kh.hosts
27285031Sdes	) >> $OBJ/kh.hosts
28285031Sdesdone
29285031Sdes
30285031Sdes# Generate a variant with an invalid line. We'll use this for most tests,
31285031Sdes# because keygen should be able to cope and it should be preserved in any
32285031Sdes# output file.
33285031Sdescat $OBJ/kh.hosts >> $OBJ/kh.invalid
34285031Sdesecho "host-i " >> $OBJ/kh.invalid
35285031Sdes
36285031Sdescp $OBJ/kh.invalid $OBJ/kh.invalid.orig
37285031Sdescp $OBJ/kh.hosts $OBJ/kh.hosts.orig
38285031Sdes
39285031Sdesexpect_key() {
40285031Sdes	_host=$1
41285031Sdes	_hosts=$2
42285031Sdes	_key=$3
43285031Sdes	_line=$4
44285031Sdes	_mark=$5
45285031Sdes	_marker=""
46285031Sdes	test "x$_mark" = "xCA" && _marker="@cert-authority "
47285031Sdes	test "x$_mark" = "xREVOKED" && _marker="@revoked "
48285031Sdes	test "x$_line" != "x" &&
49285031Sdes	    echo "# Host $_host found: line $_line $_mark" >> $OBJ/kh.expect
50285031Sdes	printf "${_marker}$_hosts " >> $OBJ/kh.expect
51285031Sdes	cat $OBJ/kh.${_key}.pub >> $OBJ/kh.expect ||
52285031Sdes	    fatal "${_key}.pub missing"
53285031Sdes}
54285031Sdes
55285031Sdescheck_find() {
56285031Sdes	_host=$1
57285031Sdes	_name=$2
58285031Sdes	_keygenopt=$3
59285031Sdes	${SSHKEYGEN} $_keygenopt -f $OBJ/kh.invalid -F $_host > $OBJ/kh.result
60295367Sdes	if ! diff -w $OBJ/kh.expect $OBJ/kh.result ; then
61285031Sdes		fail "didn't find $_name"
62285031Sdes	fi
63285031Sdes}
64285031Sdes
65285031Sdes# Find key
66285031Sdesrm -f $OBJ/kh.expect
67285031Sdesexpect_key host-a host-a host-a 2
68285031Sdesexpect_key host-a host-a host-a2 20
69285031Sdescheck_find host-a "simple find"
70285031Sdes
71285031Sdes# find CA key
72285031Sdesrm -f $OBJ/kh.expect
73285031Sdesexpect_key host-c host-c host-c 8 CA
74285031Sdescheck_find host-c "find CA key"
75285031Sdes
76285031Sdes# find revoked key
77285031Sdesrm -f $OBJ/kh.expect
78285031Sdesexpect_key host-d host-d host-d 11 REVOKED
79285031Sdescheck_find host-d "find revoked key"
80285031Sdes
81285031Sdes# find key with wildcard
82285031Sdesrm -f $OBJ/kh.expect
83285031Sdesexpect_key host-e.somedomain "host-e*" host-e 14
84285031Sdescheck_find host-e.somedomain "find wildcard key"
85285031Sdes
86285031Sdes# find key among multiple hosts
87285031Sdesrm -f $OBJ/kh.expect
88285031Sdesexpect_key host-h "host-f,host-g,host-h " host-f 17
89285031Sdescheck_find host-h "find multiple hosts"
90285031Sdes
91285031Sdescheck_hashed_find() {
92285031Sdes	_host=$1
93285031Sdes	_name=$2
94285031Sdes	_file=$3
95285031Sdes	test "x$_file" = "x" && _file=$OBJ/kh.invalid
96285031Sdes	${SSHKEYGEN} -f $_file -HF $_host | grep '|1|' | \
97285031Sdes	    sed "s/^[^ ]*/$_host/" > $OBJ/kh.result
98295367Sdes	if ! diff -w $OBJ/kh.expect $OBJ/kh.result ; then
99285031Sdes		fail "didn't find $_name"
100285031Sdes	fi
101285031Sdes}
102285031Sdes
103285031Sdes# Find key and hash
104285031Sdesrm -f $OBJ/kh.expect
105285031Sdesexpect_key host-a host-a host-a
106285031Sdesexpect_key host-a host-a host-a2
107285031Sdescheck_hashed_find host-a "find simple and hash"
108285031Sdes
109285031Sdes# Find CA key and hash
110285031Sdesrm -f $OBJ/kh.expect
111285031Sdesexpect_key host-c host-c host-c "" CA
112285031Sdes# CA key output is not hashed.
113285031Sdescheck_find host-c "find simple and hash" -H
114285031Sdes
115285031Sdes# Find revoked key and hash
116285031Sdesrm -f $OBJ/kh.expect
117285031Sdesexpect_key host-d host-d host-d "" REVOKED
118285031Sdes# Revoked key output is not hashed.
119285031Sdescheck_find host-d "find simple and hash" -H
120285031Sdes
121285031Sdes# find key with wildcard and hash
122285031Sdesrm -f $OBJ/kh.expect
123285031Sdesexpect_key host-e "host-e*" host-e ""
124285031Sdes# Key with wildcard hostname should not be hashed.
125285031Sdescheck_find host-e "find wildcard key" -H
126285031Sdes
127285031Sdes# find key among multiple hosts
128285031Sdesrm -f $OBJ/kh.expect
129285031Sdes# Comma-separated hostnames should be expanded and hashed.
130285031Sdesexpect_key host-f "host-h " host-f
131285031Sdesexpect_key host-g "host-h " host-f
132285031Sdesexpect_key host-h "host-h " host-f
133285031Sdescheck_hashed_find host-h "find multiple hosts"
134285031Sdes
135285031Sdes# Attempt remove key on invalid file.
136285031Sdescp $OBJ/kh.invalid.orig $OBJ/kh.invalid
137285031Sdes${SSHKEYGEN} -qf $OBJ/kh.invalid -R host-a 2>/dev/null
138295367Sdesdiff $OBJ/kh.invalid $OBJ/kh.invalid.orig || fail "remove on invalid succeeded"
139285031Sdes
140285031Sdes# Remove key
141285031Sdescp $OBJ/kh.hosts.orig $OBJ/kh.hosts
142285031Sdes${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-a 2>/dev/null
143285031Sdesgrep -v "^host-a " $OBJ/kh.hosts.orig > $OBJ/kh.expect
144295367Sdesdiff $OBJ/kh.hosts $OBJ/kh.expect || fail "remove simple"
145285031Sdes
146285031Sdes# Remove CA key
147285031Sdescp $OBJ/kh.hosts.orig $OBJ/kh.hosts
148285031Sdes${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-c 2>/dev/null
149285031Sdes# CA key should not be removed.
150295367Sdesdiff $OBJ/kh.hosts $OBJ/kh.hosts.orig || fail "remove CA"
151285031Sdes
152285031Sdes# Remove revoked key
153285031Sdescp $OBJ/kh.hosts.orig $OBJ/kh.hosts
154285031Sdes${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-d 2>/dev/null
155285031Sdes# revoked key should not be removed.
156295367Sdesdiff $OBJ/kh.hosts $OBJ/kh.hosts.orig || fail "remove revoked"
157285031Sdes
158285031Sdes# Remove wildcard
159285031Sdescp $OBJ/kh.hosts.orig $OBJ/kh.hosts
160285031Sdes${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-e.blahblah 2>/dev/null
161285031Sdesgrep -v "^host-e[*] " $OBJ/kh.hosts.orig > $OBJ/kh.expect
162295367Sdesdiff $OBJ/kh.hosts $OBJ/kh.expect || fail "remove wildcard"
163285031Sdes
164285031Sdes# Remove multiple
165285031Sdescp $OBJ/kh.hosts.orig $OBJ/kh.hosts
166285031Sdes${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-h 2>/dev/null
167285031Sdesgrep -v "^host-f," $OBJ/kh.hosts.orig > $OBJ/kh.expect
168295367Sdesdiff $OBJ/kh.hosts $OBJ/kh.expect || fail "remove wildcard"
169285031Sdes
170285031Sdes# Attempt hash on invalid file
171285031Sdescp $OBJ/kh.invalid.orig $OBJ/kh.invalid
172285031Sdes${SSHKEYGEN} -qf $OBJ/kh.invalid -H 2>/dev/null && fail "hash invalid succeeded"
173295367Sdesdiff $OBJ/kh.invalid $OBJ/kh.invalid.orig || fail "invalid file modified"
174285031Sdes
175285031Sdes# Hash valid file
176285031Sdescp $OBJ/kh.hosts.orig $OBJ/kh.hosts
177285031Sdes${SSHKEYGEN} -qf $OBJ/kh.hosts -H 2>/dev/null || fail "hash failed"
178295367Sdesdiff $OBJ/kh.hosts.old $OBJ/kh.hosts.orig || fail "backup differs"
179285031Sdesgrep "^host-[abfgh]" $OBJ/kh.hosts && fail "original hostnames persist"
180285031Sdes
181285031Sdescp $OBJ/kh.hosts $OBJ/kh.hashed.orig
182285031Sdes
183285031Sdes# Test lookup
184285031Sdesrm -f $OBJ/kh.expect
185285031Sdesexpect_key host-a host-a host-a
186285031Sdesexpect_key host-a host-a host-a2
187285031Sdescheck_hashed_find host-a "find simple in hashed" $OBJ/kh.hosts
188285031Sdes
189285031Sdes# Test multiple expanded
190285031Sdesrm -f $OBJ/kh.expect
191285031Sdesexpect_key host-h host-h host-f
192285031Sdescheck_hashed_find host-h "find simple in hashed" $OBJ/kh.hosts
193285031Sdes
194285031Sdes# Test remove
195285031Sdescp $OBJ/kh.hashed.orig $OBJ/kh.hashed
196285031Sdes${SSHKEYGEN} -qf $OBJ/kh.hashed -R host-a 2>/dev/null
197285031Sdes${SSHKEYGEN} -qf $OBJ/kh.hashed -F host-a && fail "found key after hashed remove"
198