1295367Sdes/* 	$OpenBSD: test_iterate.c,v 1.4 2015/03/31 22:59:01 djm Exp $ */
2285031Sdes/*
3285031Sdes * Regress test for hostfile.h hostkeys_foreach()
4285031Sdes *
5285031Sdes * Placed in the public domain
6285031Sdes */
7285031Sdes
8285031Sdes#include "includes.h"
9285031Sdes
10285031Sdes#include <sys/types.h>
11285031Sdes#include <sys/param.h>
12285031Sdes#include <stdio.h>
13285031Sdes#ifdef HAVE_STDINT_H
14285031Sdes#include <stdint.h>
15285031Sdes#endif
16285031Sdes#include <stdlib.h>
17285031Sdes#include <string.h>
18285031Sdes
19285031Sdes#include "../test_helper/test_helper.h"
20285031Sdes
21285031Sdes#include "sshkey.h"
22285031Sdes#include "authfile.h"
23285031Sdes#include "hostfile.h"
24285031Sdes
25285031Sdesstruct expected {
26285031Sdes	const char *key_file;		/* Path for key, NULL for none */
27285031Sdes	int no_parse_status;		/* Expected status w/o key parsing */
28285031Sdes	int no_parse_keytype;		/* Expected keytype w/o key parsing */
29285031Sdes	int match_host_p;		/* Match 'prometheus.example.com' */
30285031Sdes	int match_host_s;		/* Match 'sisyphus.example.com' */
31285031Sdes	int match_ipv4;			/* Match '192.0.2.1' */
32285031Sdes	int match_ipv6;			/* Match '2001:db8::1' */
33285031Sdes	int match_flags;		/* Expected flags from match */
34285031Sdes	struct hostkey_foreach_line l;	/* Expected line contents */
35285031Sdes};
36285031Sdes
37285031Sdesstruct cbctx {
38285031Sdes	const struct expected *expected;
39285031Sdes	size_t nexpected;
40285031Sdes	size_t i;
41285031Sdes	int flags;
42285031Sdes	int match_host_p;
43285031Sdes	int match_host_s;
44285031Sdes	int match_ipv4;
45285031Sdes	int match_ipv6;
46285031Sdes};
47285031Sdes
48285031Sdes/*
49285031Sdes * hostkeys_foreach() iterator callback that verifies the line passed
50285031Sdes * against an array of expected entries.
51285031Sdes */
52285031Sdesstatic int
53285031Sdescheck(struct hostkey_foreach_line *l, void *_ctx)
54285031Sdes{
55285031Sdes	struct cbctx *ctx = (struct cbctx *)_ctx;
56285031Sdes	const struct expected *expected;
57285031Sdes	int parse_key = (ctx->flags & HKF_WANT_PARSE_KEY) != 0;
58285031Sdes	const int matching = (ctx->flags & HKF_WANT_MATCH) != 0;
59285031Sdes	u_int expected_status, expected_match;
60285031Sdes	int expected_keytype;
61285031Sdes
62285031Sdes	test_subtest_info("entry %zu/%zu, file line %ld",
63285031Sdes	    ctx->i + 1, ctx->nexpected, l->linenum);
64285031Sdes
65285031Sdes	for (;;) {
66285031Sdes		ASSERT_SIZE_T_LT(ctx->i, ctx->nexpected);
67285031Sdes		expected = ctx->expected + ctx->i++;
68285031Sdes		/* If we are matching host/IP then skip entries that don't */
69285031Sdes		if (!matching)
70285031Sdes			break;
71285031Sdes		if (ctx->match_host_p && expected->match_host_p)
72285031Sdes			break;
73285031Sdes		if (ctx->match_host_s && expected->match_host_s)
74285031Sdes			break;
75285031Sdes		if (ctx->match_ipv4 && expected->match_ipv4)
76285031Sdes			break;
77285031Sdes		if (ctx->match_ipv6 && expected->match_ipv6)
78285031Sdes			break;
79285031Sdes	}
80285031Sdes	expected_status = (parse_key || expected->no_parse_status < 0) ?
81285031Sdes	    expected->l.status : (u_int)expected->no_parse_status;
82285031Sdes	expected_match = expected->l.match;
83285031Sdes#define UPDATE_MATCH_STATUS(x) do { \
84285031Sdes		if (ctx->x && expected->x) { \
85285031Sdes			expected_match |= expected->x; \
86285031Sdes			if (expected_status == HKF_STATUS_OK) \
87285031Sdes				expected_status = HKF_STATUS_MATCHED; \
88285031Sdes		} \
89285031Sdes	} while (0)
90285031Sdes	expected_keytype = (parse_key || expected->no_parse_keytype < 0) ?
91285031Sdes	    expected->l.keytype : expected->no_parse_keytype;
92285031Sdes
93285031Sdes#ifndef WITH_SSH1
94295367Sdes	if (parse_key && (expected->l.keytype == KEY_RSA1 ||
95295367Sdes	    expected->no_parse_keytype == KEY_RSA1)) {
96285031Sdes		expected_status = HKF_STATUS_INVALID;
97285031Sdes		expected_keytype = KEY_UNSPEC;
98285031Sdes		parse_key = 0;
99285031Sdes	}
100285031Sdes#endif
101285031Sdes#ifndef OPENSSL_HAS_ECC
102285031Sdes	if (expected->l.keytype == KEY_ECDSA ||
103285031Sdes	    expected->no_parse_keytype == KEY_ECDSA) {
104285031Sdes		expected_status = HKF_STATUS_INVALID;
105285031Sdes		expected_keytype = KEY_UNSPEC;
106285031Sdes		parse_key = 0;
107285031Sdes	}
108285031Sdes#endif
109285031Sdes
110285031Sdes	UPDATE_MATCH_STATUS(match_host_p);
111285031Sdes	UPDATE_MATCH_STATUS(match_host_s);
112285031Sdes	UPDATE_MATCH_STATUS(match_ipv4);
113285031Sdes	UPDATE_MATCH_STATUS(match_ipv6);
114285031Sdes
115285031Sdes	ASSERT_PTR_NE(l->path, NULL); /* Don't care about path */
116285031Sdes	ASSERT_LONG_LONG_EQ(l->linenum, expected->l.linenum);
117285031Sdes	ASSERT_U_INT_EQ(l->status, expected_status);
118285031Sdes	ASSERT_U_INT_EQ(l->match, expected_match);
119285031Sdes	/* Not all test entries contain fulltext */
120285031Sdes	if (expected->l.line != NULL)
121285031Sdes		ASSERT_STRING_EQ(l->line, expected->l.line);
122285031Sdes	ASSERT_INT_EQ(l->marker, expected->l.marker);
123285031Sdes	/* XXX we skip hashed hostnames for now; implement checking */
124285031Sdes	if (expected->l.hosts != NULL)
125285031Sdes		ASSERT_STRING_EQ(l->hosts, expected->l.hosts);
126285031Sdes	/* Not all test entries contain raw keys */
127285031Sdes	if (expected->l.rawkey != NULL)
128285031Sdes		ASSERT_STRING_EQ(l->rawkey, expected->l.rawkey);
129285031Sdes	/* XXX synthesise raw key for cases lacking and compare */
130285031Sdes	ASSERT_INT_EQ(l->keytype, expected_keytype);
131285031Sdes	if (parse_key) {
132285031Sdes		if (expected->l.key == NULL)
133285031Sdes			ASSERT_PTR_EQ(l->key, NULL);
134285031Sdes		if (expected->l.key != NULL) {
135285031Sdes			ASSERT_PTR_NE(l->key, NULL);
136285031Sdes			ASSERT_INT_EQ(sshkey_equal(l->key, expected->l.key), 1);
137285031Sdes		}
138285031Sdes	}
139285031Sdes	if (parse_key && !(l->comment == NULL && expected->l.comment == NULL))
140285031Sdes		ASSERT_STRING_EQ(l->comment, expected->l.comment);
141285031Sdes	return 0;
142285031Sdes}
143285031Sdes
144285031Sdes/* Loads public keys for a set of expected results */
145285031Sdesstatic void
146285031Sdesprepare_expected(struct expected *expected, size_t n)
147285031Sdes{
148285031Sdes	size_t i;
149285031Sdes
150285031Sdes	for (i = 0; i < n; i++) {
151285031Sdes		if (expected[i].key_file == NULL)
152285031Sdes			continue;
153285031Sdes#ifndef WITH_SSH1
154285031Sdes		if (expected[i].l.keytype == KEY_RSA1)
155285031Sdes			continue;
156285031Sdes#endif
157285031Sdes#ifndef OPENSSL_HAS_ECC
158285031Sdes		if (expected[i].l.keytype == KEY_ECDSA)
159285031Sdes			continue;
160285031Sdes#endif
161285031Sdes		ASSERT_INT_EQ(sshkey_load_public(
162285031Sdes		    test_data_file(expected[i].key_file), &expected[i].l.key,
163285031Sdes		    NULL), 0);
164285031Sdes	}
165285031Sdes}
166285031Sdes
167285031Sdesstruct expected expected_full[] = {
168285031Sdes	{ NULL, -1, -1, 0, 0, 0, 0, -1, {
169285031Sdes		NULL,				/* path, don't care */
170285031Sdes		1,				/* line number */
171285031Sdes		HKF_STATUS_COMMENT,		/* status */
172285031Sdes		0,				/* match flags */
173285031Sdes		"# Plain host keys, plain host names", /* full line, optional */
174285031Sdes		MRK_NONE,			/* marker (CA / revoked) */
175285031Sdes		NULL,				/* hosts text */
176285031Sdes		NULL,				/* raw key, optional */
177285031Sdes		KEY_UNSPEC,			/* key type */
178285031Sdes		NULL,				/* deserialised key */
179285031Sdes		NULL,				/* comment */
180285031Sdes	} },
181285031Sdes	{ "dsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
182285031Sdes		NULL,
183285031Sdes		2,
184285031Sdes		HKF_STATUS_OK,
185285031Sdes		0,
186285031Sdes		NULL,
187285031Sdes		MRK_NONE,
188285031Sdes		"sisyphus.example.com",
189285031Sdes		NULL,
190285031Sdes		KEY_DSA,
191285031Sdes		NULL,	/* filled at runtime */
192285031Sdes		"DSA #1",
193285031Sdes	} },
194285031Sdes	{ "ecdsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
195285031Sdes		NULL,
196285031Sdes		3,
197285031Sdes		HKF_STATUS_OK,
198285031Sdes		0,
199285031Sdes		NULL,
200285031Sdes		MRK_NONE,
201285031Sdes		"sisyphus.example.com",
202285031Sdes		NULL,
203285031Sdes		KEY_ECDSA,
204285031Sdes		NULL,	/* filled at runtime */
205285031Sdes		"ECDSA #1",
206285031Sdes	} },
207285031Sdes	{ "ed25519_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
208285031Sdes		NULL,
209285031Sdes		4,
210285031Sdes		HKF_STATUS_OK,
211285031Sdes		0,
212285031Sdes		NULL,
213285031Sdes		MRK_NONE,
214285031Sdes		"sisyphus.example.com",
215285031Sdes		NULL,
216285031Sdes		KEY_ED25519,
217285031Sdes		NULL,	/* filled at runtime */
218285031Sdes		"ED25519 #1",
219285031Sdes	} },
220285031Sdes	{ "rsa1_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
221285031Sdes		NULL,
222285031Sdes		5,
223285031Sdes		HKF_STATUS_OK,
224285031Sdes		0,
225285031Sdes		NULL,
226285031Sdes		MRK_NONE,
227285031Sdes		"sisyphus.example.com",
228285031Sdes		NULL,
229285031Sdes		KEY_RSA1,
230285031Sdes		NULL,	/* filled at runtime */
231285031Sdes		"RSA1 #1",
232285031Sdes	} },
233285031Sdes	{ "rsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
234285031Sdes		NULL,
235285031Sdes		6,
236285031Sdes		HKF_STATUS_OK,
237285031Sdes		0,
238285031Sdes		NULL,
239285031Sdes		MRK_NONE,
240285031Sdes		"sisyphus.example.com",
241285031Sdes		NULL,
242285031Sdes		KEY_RSA,
243285031Sdes		NULL,	/* filled at runtime */
244285031Sdes		"RSA #1",
245285031Sdes	} },
246285031Sdes	{ NULL, -1, -1, 0, 0, 0, 0, -1, {
247285031Sdes		NULL,
248285031Sdes		7,
249285031Sdes		HKF_STATUS_COMMENT,
250285031Sdes		0,
251285031Sdes		"",
252285031Sdes		MRK_NONE,
253285031Sdes		NULL,
254285031Sdes		NULL,
255285031Sdes		KEY_UNSPEC,
256285031Sdes		NULL,
257285031Sdes		NULL,
258285031Sdes	} },
259285031Sdes	{ NULL, -1, -1, 0, 0, 0, 0, -1, {
260285031Sdes		NULL,
261285031Sdes		8,
262285031Sdes		HKF_STATUS_COMMENT,
263285031Sdes		0,
264285031Sdes		"# Plain host keys, hostnames + addresses",
265285031Sdes		MRK_NONE,
266285031Sdes		NULL,
267285031Sdes		NULL,
268285031Sdes		KEY_UNSPEC,
269285031Sdes		NULL,
270285031Sdes		NULL,
271285031Sdes	} },
272285031Sdes	{ "dsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
273285031Sdes		NULL,
274285031Sdes		9,
275285031Sdes		HKF_STATUS_OK,
276285031Sdes		0,
277285031Sdes		NULL,
278285031Sdes		MRK_NONE,
279285031Sdes		"prometheus.example.com,192.0.2.1,2001:db8::1",
280285031Sdes		NULL,
281285031Sdes		KEY_DSA,
282285031Sdes		NULL,	/* filled at runtime */
283285031Sdes		"DSA #2",
284285031Sdes	} },
285285031Sdes	{ "ecdsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
286285031Sdes		NULL,
287285031Sdes		10,
288285031Sdes		HKF_STATUS_OK,
289285031Sdes		0,
290285031Sdes		NULL,
291285031Sdes		MRK_NONE,
292285031Sdes		"prometheus.example.com,192.0.2.1,2001:db8::1",
293285031Sdes		NULL,
294285031Sdes		KEY_ECDSA,
295285031Sdes		NULL,	/* filled at runtime */
296285031Sdes		"ECDSA #2",
297285031Sdes	} },
298285031Sdes	{ "ed25519_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
299285031Sdes		NULL,
300285031Sdes		11,
301285031Sdes		HKF_STATUS_OK,
302285031Sdes		0,
303285031Sdes		NULL,
304285031Sdes		MRK_NONE,
305285031Sdes		"prometheus.example.com,192.0.2.1,2001:db8::1",
306285031Sdes		NULL,
307285031Sdes		KEY_ED25519,
308285031Sdes		NULL,	/* filled at runtime */
309285031Sdes		"ED25519 #2",
310285031Sdes	} },
311285031Sdes	{ "rsa1_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
312285031Sdes		NULL,
313285031Sdes		12,
314285031Sdes		HKF_STATUS_OK,
315285031Sdes		0,
316285031Sdes		NULL,
317285031Sdes		MRK_NONE,
318285031Sdes		"prometheus.example.com,192.0.2.1,2001:db8::1",
319285031Sdes		NULL,
320285031Sdes		KEY_RSA1,
321285031Sdes		NULL,	/* filled at runtime */
322285031Sdes		"RSA1 #2",
323285031Sdes	} },
324285031Sdes	{ "rsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
325285031Sdes		NULL,
326285031Sdes		13,
327285031Sdes		HKF_STATUS_OK,
328285031Sdes		0,
329285031Sdes		NULL,
330285031Sdes		MRK_NONE,
331285031Sdes		"prometheus.example.com,192.0.2.1,2001:db8::1",
332285031Sdes		NULL,
333285031Sdes		KEY_RSA,
334285031Sdes		NULL,	/* filled at runtime */
335285031Sdes		"RSA #2",
336285031Sdes	} },
337285031Sdes	{ NULL, -1, -1, 0, 0, 0, 0, -1, {
338285031Sdes		NULL,
339285031Sdes		14,
340285031Sdes		HKF_STATUS_COMMENT,
341285031Sdes		0,
342285031Sdes		"",
343285031Sdes		MRK_NONE,
344285031Sdes		NULL,
345285031Sdes		NULL,
346285031Sdes		KEY_UNSPEC,
347285031Sdes		NULL,
348285031Sdes		NULL,
349285031Sdes	} },
350285031Sdes	{ NULL, -1, -1, 0, 0, 0, 0, -1, {
351285031Sdes		NULL,
352285031Sdes		15,
353285031Sdes		HKF_STATUS_COMMENT,
354285031Sdes		0,
355285031Sdes		"# Some hosts with wildcard names / IPs",
356285031Sdes		MRK_NONE,
357285031Sdes		NULL,
358285031Sdes		NULL,
359285031Sdes		KEY_UNSPEC,
360285031Sdes		NULL,
361285031Sdes		NULL,
362285031Sdes	} },
363285031Sdes	{ "dsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
364285031Sdes		NULL,
365285031Sdes		16,
366285031Sdes		HKF_STATUS_OK,
367285031Sdes		0,
368285031Sdes		NULL,
369285031Sdes		MRK_NONE,
370285031Sdes		"*.example.com,192.0.2.*,2001:*",
371285031Sdes		NULL,
372285031Sdes		KEY_DSA,
373285031Sdes		NULL,	/* filled at runtime */
374285031Sdes		"DSA #3",
375285031Sdes	} },
376285031Sdes	{ "ecdsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
377285031Sdes		NULL,
378285031Sdes		17,
379285031Sdes		HKF_STATUS_OK,
380285031Sdes		0,
381285031Sdes		NULL,
382285031Sdes		MRK_NONE,
383285031Sdes		"*.example.com,192.0.2.*,2001:*",
384285031Sdes		NULL,
385285031Sdes		KEY_ECDSA,
386285031Sdes		NULL,	/* filled at runtime */
387285031Sdes		"ECDSA #3",
388285031Sdes	} },
389285031Sdes	{ "ed25519_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
390285031Sdes		NULL,
391285031Sdes		18,
392285031Sdes		HKF_STATUS_OK,
393285031Sdes		0,
394285031Sdes		NULL,
395285031Sdes		MRK_NONE,
396285031Sdes		"*.example.com,192.0.2.*,2001:*",
397285031Sdes		NULL,
398285031Sdes		KEY_ED25519,
399285031Sdes		NULL,	/* filled at runtime */
400285031Sdes		"ED25519 #3",
401285031Sdes	} },
402285031Sdes	{ "rsa1_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
403285031Sdes		NULL,
404285031Sdes		19,
405285031Sdes		HKF_STATUS_OK,
406285031Sdes		0,
407285031Sdes		NULL,
408285031Sdes		MRK_NONE,
409285031Sdes		"*.example.com,192.0.2.*,2001:*",
410285031Sdes		NULL,
411285031Sdes		KEY_RSA1,
412285031Sdes		NULL,	/* filled at runtime */
413285031Sdes		"RSA1 #3",
414285031Sdes	} },
415285031Sdes	{ "rsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
416285031Sdes		NULL,
417285031Sdes		20,
418285031Sdes		HKF_STATUS_OK,
419285031Sdes		0,
420285031Sdes		NULL,
421285031Sdes		MRK_NONE,
422285031Sdes		"*.example.com,192.0.2.*,2001:*",
423285031Sdes		NULL,
424285031Sdes		KEY_RSA,
425285031Sdes		NULL,	/* filled at runtime */
426285031Sdes		"RSA #3",
427285031Sdes	} },
428285031Sdes	{ NULL, -1, -1, 0, 0, 0, 0, -1, {
429285031Sdes		NULL,
430285031Sdes		21,
431285031Sdes		HKF_STATUS_COMMENT,
432285031Sdes		0,
433285031Sdes		"",
434285031Sdes		MRK_NONE,
435285031Sdes		NULL,
436285031Sdes		NULL,
437285031Sdes		KEY_UNSPEC,
438285031Sdes		NULL,
439285031Sdes		NULL,
440285031Sdes	} },
441285031Sdes	{ NULL, -1, -1, 0, 0, 0, 0, -1, {
442285031Sdes		NULL,
443285031Sdes		22,
444285031Sdes		HKF_STATUS_COMMENT,
445285031Sdes		0,
446285031Sdes		"# Hashed hostname and address entries",
447285031Sdes		MRK_NONE,
448285031Sdes		NULL,
449285031Sdes		NULL,
450285031Sdes		KEY_UNSPEC,
451285031Sdes		NULL,
452285031Sdes		NULL,
453285031Sdes	} },
454285031Sdes	{ "dsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
455285031Sdes		NULL,
456285031Sdes		23,
457285031Sdes		HKF_STATUS_OK,
458285031Sdes		0,
459285031Sdes		NULL,
460285031Sdes		MRK_NONE,
461285031Sdes		NULL,
462285031Sdes		NULL,
463285031Sdes		KEY_DSA,
464285031Sdes		NULL,	/* filled at runtime */
465285031Sdes		"DSA #5",
466285031Sdes	} },
467285031Sdes	{ "ecdsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
468285031Sdes		NULL,
469285031Sdes		24,
470285031Sdes		HKF_STATUS_OK,
471285031Sdes		0,
472285031Sdes		NULL,
473285031Sdes		MRK_NONE,
474285031Sdes		NULL,
475285031Sdes		NULL,
476285031Sdes		KEY_ECDSA,
477285031Sdes		NULL,	/* filled at runtime */
478285031Sdes		"ECDSA #5",
479285031Sdes	} },
480285031Sdes	{ "ed25519_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
481285031Sdes		NULL,
482285031Sdes		25,
483285031Sdes		HKF_STATUS_OK,
484285031Sdes		0,
485285031Sdes		NULL,
486285031Sdes		MRK_NONE,
487285031Sdes		NULL,
488285031Sdes		NULL,
489285031Sdes		KEY_ED25519,
490285031Sdes		NULL,	/* filled at runtime */
491285031Sdes		"ED25519 #5",
492285031Sdes	} },
493285031Sdes	{ "rsa1_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
494285031Sdes		NULL,
495285031Sdes		26,
496285031Sdes		HKF_STATUS_OK,
497285031Sdes		0,
498285031Sdes		NULL,
499285031Sdes		MRK_NONE,
500285031Sdes		NULL,
501285031Sdes		NULL,
502285031Sdes		KEY_RSA1,
503285031Sdes		NULL,	/* filled at runtime */
504285031Sdes		"RSA1 #5",
505285031Sdes	} },
506285031Sdes	{ "rsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
507285031Sdes		NULL,
508285031Sdes		27,
509285031Sdes		HKF_STATUS_OK,
510285031Sdes		0,
511285031Sdes		NULL,
512285031Sdes		MRK_NONE,
513285031Sdes		NULL,
514285031Sdes		NULL,
515285031Sdes		KEY_RSA,
516285031Sdes		NULL,	/* filled at runtime */
517285031Sdes		"RSA #5",
518285031Sdes	} },
519285031Sdes	{ NULL, -1, -1, 0, 0, 0, 0, -1, {
520285031Sdes		NULL,
521285031Sdes		28,
522285031Sdes		HKF_STATUS_COMMENT,
523285031Sdes		0,
524285031Sdes		"",
525285031Sdes		MRK_NONE,
526285031Sdes		NULL,
527285031Sdes		NULL,
528285031Sdes		KEY_UNSPEC,
529285031Sdes		NULL,
530285031Sdes		NULL,
531285031Sdes	} },
532285031Sdes	/*
533285031Sdes	 * The next series have each key listed multiple times, as the
534285031Sdes	 * hostname and addresses in the pre-hashed known_hosts are split
535285031Sdes	 * to separate lines.
536285031Sdes	 */
537285031Sdes	{ "dsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
538285031Sdes		NULL,
539285031Sdes		29,
540285031Sdes		HKF_STATUS_OK,
541285031Sdes		0,
542285031Sdes		NULL,
543285031Sdes		MRK_NONE,
544285031Sdes		NULL,
545285031Sdes		NULL,
546285031Sdes		KEY_DSA,
547285031Sdes		NULL,	/* filled at runtime */
548285031Sdes		"DSA #6",
549285031Sdes	} },
550285031Sdes	{ "dsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
551285031Sdes		NULL,
552285031Sdes		30,
553285031Sdes		HKF_STATUS_OK,
554285031Sdes		0,
555285031Sdes		NULL,
556285031Sdes		MRK_NONE,
557285031Sdes		NULL,
558285031Sdes		NULL,
559285031Sdes		KEY_DSA,
560285031Sdes		NULL,	/* filled at runtime */
561285031Sdes		"DSA #6",
562285031Sdes	} },
563285031Sdes	{ "dsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
564285031Sdes		NULL,
565285031Sdes		31,
566285031Sdes		HKF_STATUS_OK,
567285031Sdes		0,
568285031Sdes		NULL,
569285031Sdes		MRK_NONE,
570285031Sdes		NULL,
571285031Sdes		NULL,
572285031Sdes		KEY_DSA,
573285031Sdes		NULL,	/* filled at runtime */
574285031Sdes		"DSA #6",
575285031Sdes	} },
576285031Sdes	{ "ecdsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
577285031Sdes		NULL,
578285031Sdes		32,
579285031Sdes		HKF_STATUS_OK,
580285031Sdes		0,
581285031Sdes		NULL,
582285031Sdes		MRK_NONE,
583285031Sdes		NULL,
584285031Sdes		NULL,
585285031Sdes		KEY_ECDSA,
586285031Sdes		NULL,	/* filled at runtime */
587285031Sdes		"ECDSA #6",
588285031Sdes	} },
589285031Sdes	{ "ecdsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
590285031Sdes		NULL,
591285031Sdes		33,
592285031Sdes		HKF_STATUS_OK,
593285031Sdes		0,
594285031Sdes		NULL,
595285031Sdes		MRK_NONE,
596285031Sdes		NULL,
597285031Sdes		NULL,
598285031Sdes		KEY_ECDSA,
599285031Sdes		NULL,	/* filled at runtime */
600285031Sdes		"ECDSA #6",
601285031Sdes	} },
602285031Sdes	{ "ecdsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
603285031Sdes		NULL,
604285031Sdes		34,
605285031Sdes		HKF_STATUS_OK,
606285031Sdes		0,
607285031Sdes		NULL,
608285031Sdes		MRK_NONE,
609285031Sdes		NULL,
610285031Sdes		NULL,
611285031Sdes		KEY_ECDSA,
612285031Sdes		NULL,	/* filled at runtime */
613285031Sdes		"ECDSA #6",
614285031Sdes	} },
615285031Sdes	{ "ed25519_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
616285031Sdes		NULL,
617285031Sdes		35,
618285031Sdes		HKF_STATUS_OK,
619285031Sdes		0,
620285031Sdes		NULL,
621285031Sdes		MRK_NONE,
622285031Sdes		NULL,
623285031Sdes		NULL,
624285031Sdes		KEY_ED25519,
625285031Sdes		NULL,	/* filled at runtime */
626285031Sdes		"ED25519 #6",
627285031Sdes	} },
628285031Sdes	{ "ed25519_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
629285031Sdes		NULL,
630285031Sdes		36,
631285031Sdes		HKF_STATUS_OK,
632285031Sdes		0,
633285031Sdes		NULL,
634285031Sdes		MRK_NONE,
635285031Sdes		NULL,
636285031Sdes		NULL,
637285031Sdes		KEY_ED25519,
638285031Sdes		NULL,	/* filled at runtime */
639285031Sdes		"ED25519 #6",
640285031Sdes	} },
641285031Sdes	{ "ed25519_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
642285031Sdes		NULL,
643285031Sdes		37,
644285031Sdes		HKF_STATUS_OK,
645285031Sdes		0,
646285031Sdes		NULL,
647285031Sdes		MRK_NONE,
648285031Sdes		NULL,
649285031Sdes		NULL,
650285031Sdes		KEY_ED25519,
651285031Sdes		NULL,	/* filled at runtime */
652285031Sdes		"ED25519 #6",
653285031Sdes	} },
654285031Sdes	{ "rsa1_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
655285031Sdes		NULL,
656285031Sdes		38,
657285031Sdes		HKF_STATUS_OK,
658285031Sdes		0,
659285031Sdes		NULL,
660285031Sdes		MRK_NONE,
661285031Sdes		NULL,
662285031Sdes		NULL,
663285031Sdes		KEY_RSA1,
664285031Sdes		NULL,	/* filled at runtime */
665285031Sdes		"RSA1 #6",
666285031Sdes	} },
667285031Sdes	{ "rsa1_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
668285031Sdes		NULL,
669285031Sdes		39,
670285031Sdes		HKF_STATUS_OK,
671285031Sdes		0,
672285031Sdes		NULL,
673285031Sdes		MRK_NONE,
674285031Sdes		NULL,
675285031Sdes		NULL,
676285031Sdes		KEY_RSA1,
677285031Sdes		NULL,	/* filled at runtime */
678285031Sdes		"RSA1 #6",
679285031Sdes	} },
680285031Sdes	{ "rsa1_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
681285031Sdes		NULL,
682285031Sdes		40,
683285031Sdes		HKF_STATUS_OK,
684285031Sdes		0,
685285031Sdes		NULL,
686285031Sdes		MRK_NONE,
687285031Sdes		NULL,
688285031Sdes		NULL,
689285031Sdes		KEY_RSA1,
690285031Sdes		NULL,	/* filled at runtime */
691285031Sdes		"RSA1 #6",
692285031Sdes	} },
693285031Sdes	{ "rsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
694285031Sdes		NULL,
695285031Sdes		41,
696285031Sdes		HKF_STATUS_OK,
697285031Sdes		0,
698285031Sdes		NULL,
699285031Sdes		MRK_NONE,
700285031Sdes		NULL,
701285031Sdes		NULL,
702285031Sdes		KEY_RSA,
703285031Sdes		NULL,	/* filled at runtime */
704285031Sdes		"RSA #6",
705285031Sdes	} },
706285031Sdes	{ "rsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
707285031Sdes		NULL,
708285031Sdes		42,
709285031Sdes		HKF_STATUS_OK,
710285031Sdes		0,
711285031Sdes		NULL,
712285031Sdes		MRK_NONE,
713285031Sdes		NULL,
714285031Sdes		NULL,
715285031Sdes		KEY_RSA,
716285031Sdes		NULL,	/* filled at runtime */
717285031Sdes		"RSA #6",
718285031Sdes	} },
719285031Sdes	{ "rsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
720285031Sdes		NULL,
721285031Sdes		43,
722285031Sdes		HKF_STATUS_OK,
723285031Sdes		0,
724285031Sdes		NULL,
725285031Sdes		MRK_NONE,
726285031Sdes		NULL,
727285031Sdes		NULL,
728285031Sdes		KEY_RSA,
729285031Sdes		NULL,	/* filled at runtime */
730285031Sdes		"RSA #6",
731285031Sdes	} },
732285031Sdes	{ NULL, -1, -1, 0, 0, 0, 0, -1, {
733285031Sdes		NULL,
734285031Sdes		44,
735285031Sdes		HKF_STATUS_COMMENT,
736285031Sdes		0,
737285031Sdes		"",
738285031Sdes		MRK_NONE,
739285031Sdes		NULL,
740285031Sdes		NULL,
741285031Sdes		KEY_UNSPEC,
742285031Sdes		NULL,
743285031Sdes		NULL,
744285031Sdes	} },
745285031Sdes	{ NULL, -1, -1, 0, 0, 0, 0, -1, {
746285031Sdes		NULL,
747285031Sdes		45,
748285031Sdes		HKF_STATUS_COMMENT,
749285031Sdes		0,
750285031Sdes		"",
751285031Sdes		MRK_NONE,
752285031Sdes		NULL,
753285031Sdes		NULL,
754285031Sdes		KEY_UNSPEC,
755285031Sdes		NULL,
756285031Sdes		NULL,
757285031Sdes	} },
758285031Sdes	{ NULL, -1, -1, 0, 0, 0, 0, -1, {
759285031Sdes		NULL,
760285031Sdes		46,
761285031Sdes		HKF_STATUS_COMMENT,
762285031Sdes		0,
763285031Sdes		"# Revoked and CA keys",
764285031Sdes		MRK_NONE,
765285031Sdes		NULL,
766285031Sdes		NULL,
767285031Sdes		KEY_UNSPEC,
768285031Sdes		NULL,
769285031Sdes		NULL,
770285031Sdes	} },
771285031Sdes	{ "rsa1_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
772285031Sdes		NULL,
773285031Sdes		47,
774285031Sdes		HKF_STATUS_OK,
775285031Sdes		0,
776285031Sdes		NULL,
777285031Sdes		MRK_REVOKE,
778285031Sdes		"sisyphus.example.com",
779285031Sdes		NULL,
780285031Sdes		KEY_RSA1,
781285031Sdes		NULL,	/* filled at runtime */
782285031Sdes		"RSA1 #4",
783285031Sdes	} },
784285031Sdes	{ "ed25519_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
785285031Sdes		NULL,
786285031Sdes		48,
787285031Sdes		HKF_STATUS_OK,
788285031Sdes		0,
789285031Sdes		NULL,
790285031Sdes		MRK_REVOKE,
791285031Sdes		"sisyphus.example.com",
792285031Sdes		NULL,
793285031Sdes		KEY_ED25519,
794285031Sdes		NULL,	/* filled at runtime */
795285031Sdes		"ED25519 #4",
796285031Sdes	} },
797285031Sdes	{ "ecdsa_4.pub" , -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, {
798285031Sdes		NULL,
799285031Sdes		49,
800285031Sdes		HKF_STATUS_OK,
801285031Sdes		0,
802285031Sdes		NULL,
803285031Sdes		MRK_CA,
804285031Sdes		"prometheus.example.com",
805285031Sdes		NULL,
806285031Sdes		KEY_ECDSA,
807285031Sdes		NULL,	/* filled at runtime */
808285031Sdes		"ECDSA #4",
809285031Sdes	} },
810285031Sdes	{ "dsa_4.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, 0, 0, -1, {
811285031Sdes		NULL,
812285031Sdes		50,
813285031Sdes		HKF_STATUS_OK,
814285031Sdes		0,
815285031Sdes		NULL,
816285031Sdes		MRK_CA,
817285031Sdes		"*.example.com",
818285031Sdes		NULL,
819285031Sdes		KEY_DSA,
820285031Sdes		NULL,	/* filled at runtime */
821285031Sdes		"DSA #4",
822285031Sdes	} },
823285031Sdes	{ NULL, -1, -1, 0, 0, 0, 0, -1, {
824285031Sdes		NULL,
825285031Sdes		51,
826285031Sdes		HKF_STATUS_COMMENT,
827285031Sdes		0,
828285031Sdes		"",
829285031Sdes		MRK_NONE,
830285031Sdes		NULL,
831285031Sdes		NULL,
832285031Sdes		KEY_UNSPEC,
833285031Sdes		NULL,
834285031Sdes		NULL,
835285031Sdes	} },
836285031Sdes	{ NULL, -1, -1, 0, 0, 0, 0, -1, {
837285031Sdes		NULL,
838285031Sdes		52,
839285031Sdes		HKF_STATUS_COMMENT,
840285031Sdes		0,
841285031Sdes		"# Some invalid lines",
842285031Sdes		MRK_NONE,
843285031Sdes		NULL,
844285031Sdes		NULL,
845285031Sdes		KEY_UNSPEC,
846285031Sdes		NULL,
847285031Sdes		NULL,
848285031Sdes	} },
849285031Sdes	{ NULL, -1, -1, 0, 0, 0, 0, -1, {
850285031Sdes		NULL,
851285031Sdes		53,
852285031Sdes		HKF_STATUS_INVALID,
853285031Sdes		0,
854285031Sdes		NULL,
855285031Sdes		MRK_ERROR,
856285031Sdes		NULL,
857285031Sdes		NULL,
858285031Sdes		KEY_UNSPEC,
859285031Sdes		NULL,
860285031Sdes		NULL,
861285031Sdes	} },
862285031Sdes	{ NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
863285031Sdes		NULL,
864285031Sdes		54,
865285031Sdes		HKF_STATUS_INVALID,
866285031Sdes		0,
867285031Sdes		NULL,
868285031Sdes		MRK_NONE,
869285031Sdes		"sisyphus.example.com",
870285031Sdes		NULL,
871285031Sdes		KEY_UNSPEC,
872285031Sdes		NULL,
873285031Sdes		NULL,
874285031Sdes	} },
875285031Sdes	{ NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, {
876285031Sdes		NULL,
877285031Sdes		55,
878285031Sdes		HKF_STATUS_INVALID,
879285031Sdes		0,
880285031Sdes		NULL,
881285031Sdes		MRK_NONE,
882285031Sdes		"prometheus.example.com",
883285031Sdes		NULL,
884285031Sdes		KEY_UNSPEC,
885285031Sdes		NULL,
886285031Sdes		NULL,
887285031Sdes	} },
888285031Sdes	{ NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
889285031Sdes		NULL,
890285031Sdes		56,
891285031Sdes		HKF_STATUS_INVALID,	/* Would be ok if key not parsed */
892285031Sdes		0,
893285031Sdes		NULL,
894285031Sdes		MRK_NONE,
895285031Sdes		"sisyphus.example.com",
896285031Sdes		NULL,
897285031Sdes		KEY_UNSPEC,
898285031Sdes		NULL,
899285031Sdes		NULL,
900285031Sdes	} },
901285031Sdes	{ NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, {
902285031Sdes		NULL,
903285031Sdes		57,
904285031Sdes		HKF_STATUS_INVALID,	/* Would be ok if key not parsed */
905285031Sdes		0,
906285031Sdes		NULL,
907285031Sdes		MRK_NONE,
908285031Sdes		"prometheus.example.com",
909285031Sdes		NULL,
910285031Sdes		KEY_UNSPEC,
911285031Sdes		NULL,
912285031Sdes		NULL,
913285031Sdes	} },
914285031Sdes	{ NULL, HKF_STATUS_OK, KEY_RSA1, 0, HKF_MATCH_HOST, 0, 0, -1, {
915285031Sdes		NULL,
916285031Sdes		58,
917285031Sdes		HKF_STATUS_INVALID,	/* Would be ok if key not parsed */
918285031Sdes		0,
919285031Sdes		NULL,
920285031Sdes		MRK_NONE,
921285031Sdes		"sisyphus.example.com",
922285031Sdes		NULL,
923285031Sdes		KEY_UNSPEC,
924285031Sdes		NULL,
925285031Sdes		NULL,
926285031Sdes	} },
927285031Sdes	{ NULL, HKF_STATUS_OK, KEY_RSA1, HKF_MATCH_HOST, 0, 0, 0, -1, {
928285031Sdes		NULL,
929285031Sdes		59,
930285031Sdes		HKF_STATUS_INVALID,	/* Would be ok if key not parsed */
931285031Sdes		0,
932285031Sdes		NULL,
933285031Sdes		MRK_NONE,
934285031Sdes		"prometheus.example.com",
935285031Sdes		NULL,
936285031Sdes		KEY_UNSPEC,
937285031Sdes		NULL,	/* filled at runtime */
938285031Sdes		NULL,
939285031Sdes	} },
940285031Sdes	{ NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
941285031Sdes		NULL,
942285031Sdes		60,
943285031Sdes		HKF_STATUS_INVALID,
944285031Sdes		0,
945285031Sdes		NULL,
946285031Sdes		MRK_NONE,
947285031Sdes		"sisyphus.example.com",
948285031Sdes		NULL,
949285031Sdes		KEY_UNSPEC,
950285031Sdes		NULL,	/* filled at runtime */
951285031Sdes		NULL,
952285031Sdes	} },
953285031Sdes	{ NULL, HKF_STATUS_OK, KEY_RSA, HKF_MATCH_HOST, 0, 0, 0, -1, {
954285031Sdes		NULL,
955285031Sdes		61,
956285031Sdes		HKF_STATUS_INVALID,	/* Would be ok if key not parsed */
957285031Sdes		0,
958285031Sdes		NULL,
959285031Sdes		MRK_NONE,
960285031Sdes		"prometheus.example.com",
961285031Sdes		NULL,
962285031Sdes		KEY_UNSPEC,
963285031Sdes		NULL,	/* filled at runtime */
964285031Sdes		NULL,
965285031Sdes	} },
966285031Sdes};
967285031Sdes
968285031Sdesvoid test_iterate(void);
969285031Sdes
970285031Sdesvoid
971285031Sdestest_iterate(void)
972285031Sdes{
973285031Sdes	struct cbctx ctx;
974285031Sdes
975285031Sdes	TEST_START("hostkeys_iterate all with key parse");
976285031Sdes	memset(&ctx, 0, sizeof(ctx));
977285031Sdes	ctx.expected = expected_full;
978285031Sdes	ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
979285031Sdes	ctx.flags = HKF_WANT_PARSE_KEY;
980285031Sdes	prepare_expected(expected_full, ctx.nexpected);
981285031Sdes	ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
982285031Sdes	    check, &ctx, NULL, NULL, ctx.flags), 0);
983285031Sdes	TEST_DONE();
984285031Sdes
985285031Sdes	TEST_START("hostkeys_iterate all without key parse");
986285031Sdes	memset(&ctx, 0, sizeof(ctx));
987285031Sdes	ctx.expected = expected_full;
988285031Sdes	ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
989285031Sdes	ctx.flags = 0;
990285031Sdes	prepare_expected(expected_full, ctx.nexpected);
991285031Sdes	ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
992285031Sdes	    check, &ctx, NULL, NULL, ctx.flags), 0);
993285031Sdes	TEST_DONE();
994285031Sdes
995285031Sdes	TEST_START("hostkeys_iterate specify host 1");
996285031Sdes	memset(&ctx, 0, sizeof(ctx));
997285031Sdes	ctx.expected = expected_full;
998285031Sdes	ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
999285031Sdes	ctx.flags = 0;
1000285031Sdes	ctx.match_host_p = 1;
1001285031Sdes	prepare_expected(expected_full, ctx.nexpected);
1002285031Sdes	ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1003285031Sdes	    check, &ctx, "prometheus.example.com", NULL, ctx.flags), 0);
1004285031Sdes	TEST_DONE();
1005285031Sdes
1006285031Sdes	TEST_START("hostkeys_iterate specify host 2");
1007285031Sdes	memset(&ctx, 0, sizeof(ctx));
1008285031Sdes	ctx.expected = expected_full;
1009285031Sdes	ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1010285031Sdes	ctx.flags = 0;
1011285031Sdes	ctx.match_host_s = 1;
1012285031Sdes	prepare_expected(expected_full, ctx.nexpected);
1013285031Sdes	ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1014285031Sdes	    check, &ctx, "sisyphus.example.com", NULL, ctx.flags), 0);
1015285031Sdes	TEST_DONE();
1016285031Sdes
1017285031Sdes	TEST_START("hostkeys_iterate match host 1");
1018285031Sdes	memset(&ctx, 0, sizeof(ctx));
1019285031Sdes	ctx.expected = expected_full;
1020285031Sdes	ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1021285031Sdes	ctx.flags = HKF_WANT_MATCH;
1022285031Sdes	ctx.match_host_p = 1;
1023285031Sdes	prepare_expected(expected_full, ctx.nexpected);
1024285031Sdes	ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1025285031Sdes	    check, &ctx, "prometheus.example.com", NULL, ctx.flags), 0);
1026285031Sdes	TEST_DONE();
1027285031Sdes
1028285031Sdes	TEST_START("hostkeys_iterate match host 2");
1029285031Sdes	memset(&ctx, 0, sizeof(ctx));
1030285031Sdes	ctx.expected = expected_full;
1031285031Sdes	ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1032285031Sdes	ctx.flags = HKF_WANT_MATCH;
1033285031Sdes	ctx.match_host_s = 1;
1034285031Sdes	prepare_expected(expected_full, ctx.nexpected);
1035285031Sdes	ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1036285031Sdes	    check, &ctx, "sisyphus.example.com", NULL, ctx.flags), 0);
1037285031Sdes	TEST_DONE();
1038285031Sdes
1039285031Sdes	TEST_START("hostkeys_iterate specify host missing");
1040285031Sdes	memset(&ctx, 0, sizeof(ctx));
1041285031Sdes	ctx.expected = expected_full;
1042285031Sdes	ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1043285031Sdes	ctx.flags = 0;
1044285031Sdes	prepare_expected(expected_full, ctx.nexpected);
1045285031Sdes	ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1046285031Sdes	    check, &ctx, "actaeon.example.org", NULL, ctx.flags), 0);
1047285031Sdes	TEST_DONE();
1048285031Sdes
1049285031Sdes	TEST_START("hostkeys_iterate match host missing");
1050285031Sdes	memset(&ctx, 0, sizeof(ctx));
1051285031Sdes	ctx.expected = expected_full;
1052285031Sdes	ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1053285031Sdes	ctx.flags = HKF_WANT_MATCH;
1054285031Sdes	prepare_expected(expected_full, ctx.nexpected);
1055285031Sdes	ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1056285031Sdes	    check, &ctx, "actaeon.example.org", NULL, ctx.flags), 0);
1057285031Sdes	TEST_DONE();
1058285031Sdes
1059285031Sdes	TEST_START("hostkeys_iterate specify IPv4");
1060285031Sdes	memset(&ctx, 0, sizeof(ctx));
1061285031Sdes	ctx.expected = expected_full;
1062285031Sdes	ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1063285031Sdes	ctx.flags = 0;
1064285031Sdes	ctx.match_ipv4 = 1;
1065285031Sdes	prepare_expected(expected_full, ctx.nexpected);
1066285031Sdes	ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1067285031Sdes	    check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags), 0);
1068285031Sdes	TEST_DONE();
1069285031Sdes
1070285031Sdes	TEST_START("hostkeys_iterate specify IPv6");
1071285031Sdes	memset(&ctx, 0, sizeof(ctx));
1072285031Sdes	ctx.expected = expected_full;
1073285031Sdes	ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1074285031Sdes	ctx.flags = 0;
1075285031Sdes	ctx.match_ipv6 = 1;
1076285031Sdes	prepare_expected(expected_full, ctx.nexpected);
1077285031Sdes	ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1078285031Sdes	    check, &ctx, "tiresias.example.org", "2001:db8::1", ctx.flags), 0);
1079285031Sdes	TEST_DONE();
1080285031Sdes
1081285031Sdes	TEST_START("hostkeys_iterate match IPv4");
1082285031Sdes	memset(&ctx, 0, sizeof(ctx));
1083285031Sdes	ctx.expected = expected_full;
1084285031Sdes	ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1085285031Sdes	ctx.flags = HKF_WANT_MATCH;
1086285031Sdes	ctx.match_ipv4 = 1;
1087285031Sdes	prepare_expected(expected_full, ctx.nexpected);
1088285031Sdes	ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1089285031Sdes	    check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags), 0);
1090285031Sdes	TEST_DONE();
1091285031Sdes
1092285031Sdes	TEST_START("hostkeys_iterate match IPv6");
1093285031Sdes	memset(&ctx, 0, sizeof(ctx));
1094285031Sdes	ctx.expected = expected_full;
1095285031Sdes	ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1096285031Sdes	ctx.flags = HKF_WANT_MATCH;
1097285031Sdes	ctx.match_ipv6 = 1;
1098285031Sdes	prepare_expected(expected_full, ctx.nexpected);
1099285031Sdes	ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1100285031Sdes	    check, &ctx, "tiresias.example.org", "2001:db8::1", ctx.flags), 0);
1101285031Sdes	TEST_DONE();
1102285031Sdes
1103285031Sdes	TEST_START("hostkeys_iterate specify addr missing");
1104285031Sdes	memset(&ctx, 0, sizeof(ctx));
1105285031Sdes	ctx.expected = expected_full;
1106285031Sdes	ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1107285031Sdes	ctx.flags = 0;
1108285031Sdes	prepare_expected(expected_full, ctx.nexpected);
1109285031Sdes	ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1110285031Sdes	    check, &ctx, "tiresias.example.org", "192.168.0.1", ctx.flags), 0);
1111285031Sdes	TEST_DONE();
1112285031Sdes
1113285031Sdes	TEST_START("hostkeys_iterate match addr missing");
1114285031Sdes	memset(&ctx, 0, sizeof(ctx));
1115285031Sdes	ctx.expected = expected_full;
1116285031Sdes	ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1117285031Sdes	ctx.flags = HKF_WANT_MATCH;
1118285031Sdes	prepare_expected(expected_full, ctx.nexpected);
1119285031Sdes	ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1120285031Sdes	    check, &ctx, "tiresias.example.org", "::1", ctx.flags), 0);
1121285031Sdes	TEST_DONE();
1122285031Sdes
1123285031Sdes	TEST_START("hostkeys_iterate specify host 2 and IPv4");
1124285031Sdes	memset(&ctx, 0, sizeof(ctx));
1125285031Sdes	ctx.expected = expected_full;
1126285031Sdes	ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1127285031Sdes	ctx.flags = 0;
1128285031Sdes	ctx.match_host_s = 1;
1129285031Sdes	ctx.match_ipv4 = 1;
1130285031Sdes	prepare_expected(expected_full, ctx.nexpected);
1131285031Sdes	ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1132285031Sdes	    check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags), 0);
1133285031Sdes	TEST_DONE();
1134285031Sdes
1135285031Sdes	TEST_START("hostkeys_iterate match host 1 and IPv6");
1136285031Sdes	memset(&ctx, 0, sizeof(ctx));
1137285031Sdes	ctx.expected = expected_full;
1138285031Sdes	ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1139285031Sdes	ctx.flags = HKF_WANT_MATCH;
1140285031Sdes	ctx.match_host_p = 1;
1141285031Sdes	ctx.match_ipv6 = 1;
1142285031Sdes	prepare_expected(expected_full, ctx.nexpected);
1143285031Sdes	ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1144285031Sdes	    check, &ctx, "prometheus.example.com", "2001:db8::1", ctx.flags), 0);
1145285031Sdes	TEST_DONE();
1146285031Sdes
1147285031Sdes	TEST_START("hostkeys_iterate specify host 2 and IPv4 w/ key parse");
1148285031Sdes	memset(&ctx, 0, sizeof(ctx));
1149285031Sdes	ctx.expected = expected_full;
1150285031Sdes	ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1151285031Sdes	ctx.flags = HKF_WANT_PARSE_KEY;
1152285031Sdes	ctx.match_host_s = 1;
1153285031Sdes	ctx.match_ipv4 = 1;
1154285031Sdes	prepare_expected(expected_full, ctx.nexpected);
1155285031Sdes	ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1156285031Sdes	    check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags), 0);
1157285031Sdes	TEST_DONE();
1158285031Sdes
1159285031Sdes	TEST_START("hostkeys_iterate match host 1 and IPv6 w/ key parse");
1160285031Sdes	memset(&ctx, 0, sizeof(ctx));
1161285031Sdes	ctx.expected = expected_full;
1162285031Sdes	ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full);
1163285031Sdes	ctx.flags = HKF_WANT_MATCH|HKF_WANT_PARSE_KEY;
1164285031Sdes	ctx.match_host_p = 1;
1165285031Sdes	ctx.match_ipv6 = 1;
1166285031Sdes	prepare_expected(expected_full, ctx.nexpected);
1167285031Sdes	ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"),
1168285031Sdes	    check, &ctx, "prometheus.example.com", "2001:db8::1", ctx.flags), 0);
1169285031Sdes	TEST_DONE();
1170285031Sdes}
1171285031Sdes
1172