xref: /netbsd-src/external/mpl/bind/dist/tests/dns/keytable_test.c (revision bcda20f65a8566e103791ec395f7f499ef322704)
1 /*	$NetBSD: keytable_test.c,v 1.3 2025/01/26 16:25:47 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * SPDX-License-Identifier: MPL-2.0
7  *
8  * This Source Code Form is subject to the terms of the Mozilla Public
9  * License, v. 2.0. If a copy of the MPL was not distributed with this
10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11  *
12  * See the COPYRIGHT file distributed with this work for additional
13  * information regarding copyright ownership.
14  */
15 
16 #include <inttypes.h>
17 #include <sched.h> /* IWYU pragma: keep */
18 #include <setjmp.h>
19 #include <stdarg.h>
20 #include <stdbool.h>
21 #include <stddef.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 
26 #define UNIT_TESTING
27 #include <cmocka.h>
28 
29 #include <isc/base64.h>
30 #include <isc/buffer.h>
31 #include <isc/md.h>
32 #include <isc/util.h>
33 
34 #include <dns/fixedname.h>
35 #include <dns/keytable.h>
36 #include <dns/name.h>
37 #include <dns/nta.h>
38 #include <dns/rdataclass.h>
39 #include <dns/rdatastruct.h>
40 #include <dns/rootns.h>
41 #include <dns/view.h>
42 
43 #include <dst/dst.h>
44 
45 #include <tests/dns.h>
46 
47 static int
48 setup_test(void **state) {
49 	setup_loopmgr(state);
50 
51 	return 0;
52 }
53 
54 static int
55 teardown_test(void **state) {
56 	teardown_loopmgr(state);
57 
58 	return 0;
59 }
60 
61 dns_keytable_t *keytable = NULL;
62 dns_ntatable_t *ntatable = NULL;
63 
64 static const char *keystr1 = "BQEAAAABok+vaUC9neRv8yeT/"
65 			     "FEGgN7svR8s7VBUVSBd8NsAiV8AlaAg "
66 			     "O5FHar3JQd95i/puZos6Vi6at9/"
67 			     "JBbN8qVmO2AuiXxVqfxMKxIcy+LEB "
68 			     "0Vw4NaSJ3N3uaVREso6aTSs98H/"
69 			     "25MjcwLOr7SFfXA7bGhZatLtYY/xu kp6Km5hMfkE=";
70 
71 static const char *keystr2 = "BQEAAAABwuHz9Cem0BJ0JQTO7C/a3McR6hMaufljs1dfG/"
72 			     "inaJpYv7vH "
73 			     "XTrAOm/MeKp+/x6eT4QLru0KoZkvZJnqTI8JyaFTw2OM/"
74 			     "ItBfh/hL2lm "
75 			     "Cft2O7n3MfeqYtvjPnY7dWghYW4sVfH7VVEGm958o9nfi7953"
76 			     "2Qeklxh x8pXWdeAaRU=";
77 
78 static dns_view_t *view = NULL;
79 
80 /*
81  * Test utilities.  In general, these assume input parameters are valid
82  * (checking with assert_int_equal, thus aborting if not) and unlikely run time
83  * errors (such as memory allocation failure) won't happen.  This helps keep
84  * the test code concise.
85  */
86 
87 /*
88  * Utility to convert C-string to dns_name_t.  Return a pointer to
89  * static data, and so is not thread safe.
90  */
91 static dns_name_t *
92 str2name(const char *namestr) {
93 	static dns_fixedname_t fname;
94 	static dns_name_t *name;
95 	static isc_buffer_t namebuf;
96 
97 	name = dns_fixedname_initname(&fname);
98 	isc_buffer_init(&namebuf, UNCONST(namestr), strlen(namestr));
99 	isc_buffer_add(&namebuf, strlen(namestr));
100 	assert_int_equal(
101 		dns_name_fromtext(name, &namebuf, dns_rootname, 0, NULL),
102 		ISC_R_SUCCESS);
103 
104 	return name;
105 }
106 
107 static void
108 create_keystruct(uint16_t flags, uint8_t proto, uint8_t alg, const char *keystr,
109 		 dns_rdata_dnskey_t *keystruct) {
110 	unsigned char keydata[4096];
111 	isc_buffer_t keydatabuf;
112 	isc_region_t r;
113 	const dns_rdataclass_t rdclass = dns_rdataclass_in;
114 
115 	keystruct->common.rdclass = rdclass;
116 	keystruct->common.rdtype = dns_rdatatype_dnskey;
117 	keystruct->mctx = mctx;
118 	ISC_LINK_INIT(&keystruct->common, link);
119 	keystruct->flags = flags;
120 	keystruct->protocol = proto;
121 	keystruct->algorithm = alg;
122 
123 	isc_buffer_init(&keydatabuf, keydata, sizeof(keydata));
124 	assert_int_equal(isc_base64_decodestring(keystr, &keydatabuf),
125 			 ISC_R_SUCCESS);
126 	isc_buffer_usedregion(&keydatabuf, &r);
127 	keystruct->datalen = r.length;
128 	keystruct->data = isc_mem_allocate(mctx, r.length);
129 	memmove(keystruct->data, r.base, r.length);
130 }
131 
132 static void
133 create_dsstruct(dns_name_t *name, uint16_t flags, uint8_t proto, uint8_t alg,
134 		const char *keystr, unsigned char *digest,
135 		dns_rdata_ds_t *dsstruct) {
136 	isc_result_t result;
137 	unsigned char rrdata[4096];
138 	isc_buffer_t rrdatabuf;
139 	dns_rdata_t rdata = DNS_RDATA_INIT;
140 	dns_rdata_dnskey_t dnskey;
141 
142 	/*
143 	 * Populate DNSKEY rdata structure.
144 	 */
145 	create_keystruct(flags, proto, alg, keystr, &dnskey);
146 
147 	/*
148 	 * Convert to wire format.
149 	 */
150 	isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
151 	result = dns_rdata_fromstruct(&rdata, dnskey.common.rdclass,
152 				      dnskey.common.rdtype, &dnskey,
153 				      &rrdatabuf);
154 	assert_int_equal(result, ISC_R_SUCCESS);
155 
156 	/*
157 	 * Build DS rdata struct.
158 	 */
159 	result = dns_ds_fromkeyrdata(name, &rdata, DNS_DSDIGEST_SHA256, digest,
160 				     dsstruct);
161 	assert_int_equal(result, ISC_R_SUCCESS);
162 
163 	dns_rdata_freestruct(&dnskey);
164 }
165 
166 /* Common setup: create a keytable and ntatable to test with a few keys */
167 static void
168 create_tables(void) {
169 	unsigned char digest[ISC_MAX_MD_SIZE];
170 	dns_rdata_ds_t ds;
171 	dns_fixedname_t fn;
172 	dns_name_t *keyname = dns_fixedname_name(&fn);
173 	isc_stdtime_t now = isc_stdtime_now();
174 
175 	assert_int_equal(dns_test_makeview("view", false, false, &view),
176 			 ISC_R_SUCCESS);
177 
178 	dns_keytable_create(view, &keytable);
179 	dns_ntatable_create(view, loopmgr, &ntatable);
180 
181 	/* Add a normal key */
182 	dns_test_namefromstring("example.com.", &fn);
183 	create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
184 	assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds,
185 					  NULL, NULL),
186 			 ISC_R_SUCCESS);
187 
188 	/* Add an initializing managed key */
189 	dns_test_namefromstring("managed.com.", &fn);
190 	create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
191 	assert_int_equal(dns_keytable_add(keytable, true, true, keyname, &ds,
192 					  NULL, NULL),
193 			 ISC_R_SUCCESS);
194 
195 	/* Add a null key */
196 	assert_int_equal(
197 		dns_keytable_marksecure(keytable, str2name("null.example")),
198 		ISC_R_SUCCESS);
199 
200 	/* Add a negative trust anchor, duration 1 hour */
201 	assert_int_equal(dns_ntatable_add(ntatable,
202 					  str2name("insecure.example"), false,
203 					  now, 3600),
204 			 ISC_R_SUCCESS);
205 }
206 
207 static void
208 destroy_tables(void) {
209 	if (ntatable != NULL) {
210 		dns_ntatable_shutdown(ntatable);
211 		dns_ntatable_detach(&ntatable);
212 	}
213 	if (keytable != NULL) {
214 		dns_keytable_detach(&keytable);
215 	}
216 
217 	dns_view_detach(&view);
218 }
219 
220 /* add keys to the keytable */
221 ISC_LOOP_TEST_IMPL(add) {
222 	dns_keynode_t *keynode = NULL;
223 	dns_keynode_t *null_keynode = NULL;
224 	unsigned char digest[ISC_MAX_MD_SIZE];
225 	dns_rdata_ds_t ds;
226 	dns_fixedname_t fn;
227 	dns_name_t *keyname = dns_fixedname_name(&fn);
228 
229 	UNUSED(arg);
230 
231 	create_tables();
232 
233 	/*
234 	 * Getting the keynode for the example.com key should succeed.
235 	 */
236 	assert_int_equal(
237 		dns_keytable_find(keytable, str2name("example.com"), &keynode),
238 		ISC_R_SUCCESS);
239 
240 	/*
241 	 * Try to add the same key.  This should have no effect but
242 	 * report success.
243 	 */
244 	dns_test_namefromstring("example.com.", &fn);
245 	create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
246 	assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds,
247 					  NULL, NULL),
248 			 ISC_R_SUCCESS);
249 	dns_keynode_detach(&keynode);
250 	assert_int_equal(
251 		dns_keytable_find(keytable, str2name("example.com"), &keynode),
252 		ISC_R_SUCCESS);
253 
254 	/* Add another key (different keydata) */
255 	dns_keynode_detach(&keynode);
256 	create_dsstruct(keyname, 257, 3, 5, keystr2, digest, &ds);
257 	assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds,
258 					  NULL, NULL),
259 			 ISC_R_SUCCESS);
260 	assert_int_equal(
261 		dns_keytable_find(keytable, str2name("example.com"), &keynode),
262 		ISC_R_SUCCESS);
263 	dns_keynode_detach(&keynode);
264 
265 	/*
266 	 * Get the keynode for the managed.com key. Ensure the
267 	 * retrieved key is an initializing key, then mark it as trusted using
268 	 * dns_keynode_trust() and ensure the latter works as expected.
269 	 */
270 	assert_int_equal(
271 		dns_keytable_find(keytable, str2name("managed.com"), &keynode),
272 		ISC_R_SUCCESS);
273 	assert_int_equal(dns_keynode_initial(keynode), true);
274 	dns_keynode_trust(keynode);
275 	assert_int_equal(dns_keynode_initial(keynode), false);
276 	dns_keynode_detach(&keynode);
277 
278 	/*
279 	 * Add a different managed key for managed.com, marking it as an
280 	 * initializing key. Since there is already a trusted key at the
281 	 * node, the node should *not* be marked as initializing.
282 	 */
283 	dns_test_namefromstring("managed.com.", &fn);
284 	create_dsstruct(keyname, 257, 3, 5, keystr2, digest, &ds);
285 	assert_int_equal(dns_keytable_add(keytable, true, true, keyname, &ds,
286 					  NULL, NULL),
287 			 ISC_R_SUCCESS);
288 	assert_int_equal(
289 		dns_keytable_find(keytable, str2name("managed.com"), &keynode),
290 		ISC_R_SUCCESS);
291 	assert_int_equal(dns_keynode_initial(keynode), false);
292 	dns_keynode_detach(&keynode);
293 
294 	/*
295 	 * Add the same managed key again, but this time mark it as a
296 	 * non-initializing key.  Ensure the previously added key is upgraded
297 	 * to a non-initializing key and make sure there are still two key
298 	 * nodes for managed.com, both containing non-initializing keys.
299 	 */
300 	assert_int_equal(dns_keytable_add(keytable, true, false, keyname, &ds,
301 					  NULL, NULL),
302 			 ISC_R_SUCCESS);
303 	assert_int_equal(
304 		dns_keytable_find(keytable, str2name("managed.com"), &keynode),
305 		ISC_R_SUCCESS);
306 	assert_int_equal(dns_keynode_initial(keynode), false);
307 	dns_keynode_detach(&keynode);
308 
309 	/*
310 	 * Add a managed key at a new node, two.com, marking it as an
311 	 * initializing key.
312 	 */
313 	dns_test_namefromstring("two.com.", &fn);
314 	create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
315 	assert_int_equal(dns_keytable_add(keytable, true, true, keyname, &ds,
316 					  NULL, NULL),
317 			 ISC_R_SUCCESS);
318 	assert_int_equal(
319 		dns_keytable_find(keytable, str2name("two.com"), &keynode),
320 		ISC_R_SUCCESS);
321 	assert_int_equal(dns_keynode_initial(keynode), true);
322 	dns_keynode_detach(&keynode);
323 
324 	/*
325 	 * Add a different managed key for two.com, marking it as a
326 	 * non-initializing key. Since there is already an iniitalizing
327 	 * trust anchor for two.com and we haven't run dns_keynode_trust(),
328 	 * the initialization status should not change.
329 	 */
330 	create_dsstruct(keyname, 257, 3, 5, keystr2, digest, &ds);
331 	assert_int_equal(dns_keytable_add(keytable, true, false, keyname, &ds,
332 					  NULL, NULL),
333 			 ISC_R_SUCCESS);
334 	assert_int_equal(
335 		dns_keytable_find(keytable, str2name("two.com"), &keynode),
336 		ISC_R_SUCCESS);
337 	assert_int_equal(dns_keynode_initial(keynode), true);
338 	dns_keynode_detach(&keynode);
339 
340 	/*
341 	 * Add a normal key to a name that has a null key.  The null key node
342 	 * will be updated with the normal key.
343 	 */
344 	assert_int_equal(dns_keytable_find(keytable, str2name("null.example"),
345 					   &null_keynode),
346 			 ISC_R_SUCCESS);
347 	dns_test_namefromstring("null.example.", &fn);
348 	create_dsstruct(keyname, 257, 3, 5, keystr2, digest, &ds);
349 	assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds,
350 					  NULL, NULL),
351 			 ISC_R_SUCCESS);
352 	assert_int_equal(
353 		dns_keytable_find(keytable, str2name("null.example"), &keynode),
354 		ISC_R_SUCCESS);
355 	assert_ptr_equal(keynode, null_keynode); /* should be the same node */
356 	dns_keynode_detach(&null_keynode);
357 
358 	/*
359 	 * Try to add a null key to a name that already has a key.  It's
360 	 * effectively no-op, so the same key node is still there.
361 	 * (Note: this and above checks confirm that if a name has a null key
362 	 * that's the only key for the name).
363 	 */
364 	assert_int_equal(
365 		dns_keytable_marksecure(keytable, str2name("null.example")),
366 		ISC_R_SUCCESS);
367 	assert_int_equal(dns_keytable_find(keytable, str2name("null.example"),
368 					   &null_keynode),
369 			 ISC_R_SUCCESS);
370 	assert_ptr_equal(keynode, null_keynode);
371 	dns_keynode_detach(&null_keynode);
372 
373 	dns_keynode_detach(&keynode);
374 	destroy_tables();
375 
376 	isc_loopmgr_shutdown(loopmgr);
377 }
378 
379 /* delete keys from the keytable */
380 ISC_LOOP_TEST_IMPL(delete) {
381 	UNUSED(arg);
382 
383 	create_tables();
384 
385 	/* dns_keytable_delete requires exact match */
386 	assert_int_equal(dns_keytable_delete(keytable, str2name("example.org"),
387 					     NULL, NULL),
388 			 ISC_R_NOTFOUND);
389 	assert_int_equal(dns_keytable_delete(keytable,
390 					     str2name("s.example.com"), NULL,
391 					     NULL),
392 			 ISC_R_NOTFOUND);
393 	assert_int_equal(dns_keytable_delete(keytable, str2name("example.com"),
394 					     NULL, NULL),
395 			 ISC_R_SUCCESS);
396 
397 	/* works also for nodes with a null key */
398 	assert_int_equal(dns_keytable_delete(keytable, str2name("null.example"),
399 					     NULL, NULL),
400 			 ISC_R_SUCCESS);
401 
402 	/* or a negative trust anchor */
403 	assert_int_equal(
404 		dns_ntatable_delete(ntatable, str2name("insecure.example")),
405 		ISC_R_SUCCESS);
406 
407 	destroy_tables();
408 
409 	isc_loopmgr_shutdown(loopmgr);
410 }
411 
412 /* delete key nodes from the keytable */
413 ISC_LOOP_TEST_IMPL(deletekey) {
414 	dns_rdata_dnskey_t dnskey;
415 	dns_fixedname_t fn;
416 	dns_name_t *keyname = dns_fixedname_name(&fn);
417 
418 	UNUSED(arg);
419 
420 	create_tables();
421 
422 	/* key name doesn't match */
423 	dns_test_namefromstring("example.org.", &fn);
424 	create_keystruct(257, 3, 5, keystr1, &dnskey);
425 	assert_int_equal(dns_keytable_deletekey(keytable, keyname, &dnskey),
426 			 ISC_R_NOTFOUND);
427 	dns_rdata_freestruct(&dnskey);
428 
429 	/* subdomain match is the same as no match */
430 	dns_test_namefromstring("sub.example.org.", &fn);
431 	create_keystruct(257, 3, 5, keystr1, &dnskey);
432 	assert_int_equal(dns_keytable_deletekey(keytable, keyname, &dnskey),
433 			 ISC_R_NOTFOUND);
434 	dns_rdata_freestruct(&dnskey);
435 
436 	/* name matches but key doesn't match (resulting in PARTIALMATCH) */
437 	dns_test_namefromstring("example.com.", &fn);
438 	create_keystruct(257, 3, 5, keystr2, &dnskey);
439 	assert_int_equal(dns_keytable_deletekey(keytable, keyname, &dnskey),
440 			 DNS_R_PARTIALMATCH);
441 	dns_rdata_freestruct(&dnskey);
442 
443 	/*
444 	 * exact match: should return SUCCESS on the first try, then
445 	 * PARTIALMATCH on the second (because the name existed but
446 	 * not a matching key).
447 	 */
448 	create_keystruct(257, 3, 5, keystr1, &dnskey);
449 	assert_int_equal(dns_keytable_deletekey(keytable, keyname, &dnskey),
450 			 ISC_R_SUCCESS);
451 	assert_int_equal(dns_keytable_deletekey(keytable, keyname, &dnskey),
452 			 DNS_R_PARTIALMATCH);
453 
454 	/*
455 	 * after deleting the node, any deletekey or delete attempt should
456 	 * result in NOTFOUND.
457 	 */
458 	assert_int_equal(dns_keytable_delete(keytable, keyname, NULL, NULL),
459 			 ISC_R_SUCCESS);
460 	assert_int_equal(dns_keytable_deletekey(keytable, keyname, &dnskey),
461 			 ISC_R_NOTFOUND);
462 	dns_rdata_freestruct(&dnskey);
463 
464 	/*
465 	 * A null key node for a name is not deleted when searched by key;
466 	 * it must be deleted by dns_keytable_delete()
467 	 */
468 	dns_test_namefromstring("null.example.", &fn);
469 	create_keystruct(257, 3, 5, keystr1, &dnskey);
470 	assert_int_equal(dns_keytable_deletekey(keytable, keyname, &dnskey),
471 			 DNS_R_PARTIALMATCH);
472 	assert_int_equal(dns_keytable_delete(keytable, keyname, NULL, NULL),
473 			 ISC_R_SUCCESS);
474 	dns_rdata_freestruct(&dnskey);
475 
476 	destroy_tables();
477 
478 	isc_loopmgr_shutdown(loopmgr);
479 }
480 
481 /* check find-variant operations */
482 ISC_LOOP_TEST_IMPL(find) {
483 	dns_keynode_t *keynode = NULL;
484 	dns_fixedname_t fname;
485 	dns_name_t *name;
486 
487 	UNUSED(arg);
488 
489 	create_tables();
490 
491 	/*
492 	 * dns_keytable_find() requires exact name match.  It matches node
493 	 * that has a null key, too.
494 	 */
495 	assert_int_equal(
496 		dns_keytable_find(keytable, str2name("example.org"), &keynode),
497 		ISC_R_NOTFOUND);
498 	assert_int_equal(dns_keytable_find(keytable,
499 					   str2name("sub.example.com"),
500 					   &keynode),
501 			 ISC_R_NOTFOUND);
502 	assert_int_equal(
503 		dns_keytable_find(keytable, str2name("example.com"), &keynode),
504 		ISC_R_SUCCESS);
505 	dns_keynode_detach(&keynode);
506 	assert_int_equal(
507 		dns_keytable_find(keytable, str2name("null.example"), &keynode),
508 		ISC_R_SUCCESS);
509 	dns_keynode_detach(&keynode);
510 
511 	/*
512 	 * dns_keytable_finddeepestmatch() allows partial match.  Also match
513 	 * nodes with a null key.
514 	 */
515 	name = dns_fixedname_initname(&fname);
516 	assert_int_equal(dns_keytable_finddeepestmatch(
517 				 keytable, str2name("example.com"), name),
518 			 ISC_R_SUCCESS);
519 	assert_true(dns_name_equal(name, str2name("example.com")));
520 	assert_int_equal(dns_keytable_finddeepestmatch(
521 				 keytable, str2name("s.example.com"), name),
522 			 ISC_R_SUCCESS);
523 	assert_true(dns_name_equal(name, str2name("example.com")));
524 	assert_int_equal(dns_keytable_finddeepestmatch(
525 				 keytable, str2name("example.org"), name),
526 			 ISC_R_NOTFOUND);
527 	assert_int_equal(dns_keytable_finddeepestmatch(
528 				 keytable, str2name("null.example"), name),
529 			 ISC_R_SUCCESS);
530 	assert_true(dns_name_equal(name, str2name("null.example")));
531 
532 	destroy_tables();
533 
534 	isc_loopmgr_shutdown(loopmgr);
535 }
536 
537 /* check issecuredomain() */
538 ISC_LOOP_TEST_IMPL(issecuredomain) {
539 	bool issecure;
540 	const char **n;
541 	const char *names[] = { "example.com", "sub.example.com",
542 				"null.example", "sub.null.example", NULL };
543 
544 	UNUSED(arg);
545 	create_tables();
546 
547 	/*
548 	 * Domains that are an exact or partial match of a key name are
549 	 * considered secure.  It's the case even if the key is null
550 	 * (validation will then fail, but that's actually the intended effect
551 	 * of installing a null key).
552 	 */
553 	for (n = names; *n != NULL; n++) {
554 		assert_int_equal(dns_keytable_issecuredomain(keytable,
555 							     str2name(*n), NULL,
556 							     &issecure),
557 				 ISC_R_SUCCESS);
558 		assert_true(issecure);
559 	}
560 
561 	/*
562 	 * If the key table has no entry (not even a null one) for a domain or
563 	 * any of its ancestors, that domain is considered insecure.
564 	 */
565 	assert_int_equal(dns_keytable_issecuredomain(keytable,
566 						     str2name("example.org"),
567 						     NULL, &issecure),
568 			 ISC_R_SUCCESS);
569 	assert_false(issecure);
570 
571 	destroy_tables();
572 
573 	isc_loopmgr_shutdown(loopmgr);
574 }
575 
576 /* check dns_keytable_dump() */
577 ISC_LOOP_TEST_IMPL(dump) {
578 	FILE *f = fopen("/dev/null", "w");
579 
580 	UNUSED(arg);
581 
582 	create_tables();
583 
584 	/*
585 	 * Right now, we only confirm the dump attempt doesn't cause disruption
586 	 * (so we don't check the dump content).
587 	 */
588 	assert_int_equal(dns_keytable_dump(keytable, f), ISC_R_SUCCESS);
589 	fclose(f);
590 
591 	destroy_tables();
592 
593 	isc_loopmgr_shutdown(loopmgr);
594 }
595 
596 /* check negative trust anchors */
597 ISC_LOOP_TEST_IMPL(nta) {
598 	isc_result_t result;
599 	bool issecure, covered;
600 	dns_fixedname_t fn;
601 	dns_name_t *keyname = dns_fixedname_name(&fn);
602 	unsigned char digest[ISC_MAX_MD_SIZE];
603 	dns_rdata_ds_t ds;
604 	dns_view_t *myview = NULL;
605 	isc_stdtime_t now = isc_stdtime_now();
606 
607 	result = dns_test_makeview("view", false, false, &myview);
608 	assert_int_equal(result, ISC_R_SUCCESS);
609 
610 	dns_view_initsecroots(myview);
611 
612 	result = dns_view_getsecroots(myview, &keytable);
613 	assert_int_equal(result, ISC_R_SUCCESS);
614 
615 	dns_view_initntatable(myview, loopmgr);
616 	result = dns_view_getntatable(myview, &ntatable);
617 	assert_int_equal(result, ISC_R_SUCCESS);
618 
619 	dns_test_namefromstring("example.", &fn);
620 	create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
621 	result = dns_keytable_add(keytable, false, false, keyname, &ds, NULL,
622 				  NULL),
623 	assert_int_equal(result, ISC_R_SUCCESS);
624 
625 	result = dns_ntatable_add(ntatable, str2name("insecure.example"), false,
626 				  now, 1);
627 	assert_int_equal(result, ISC_R_SUCCESS);
628 
629 	/* Should be secure */
630 	result = dns_view_issecuredomain(myview,
631 					 str2name("test.secure.example"), now,
632 					 true, &covered, &issecure);
633 	assert_int_equal(result, ISC_R_SUCCESS);
634 	assert_false(covered);
635 	assert_true(issecure);
636 
637 	/* Should not be secure */
638 	result = dns_view_issecuredomain(myview,
639 					 str2name("test.insecure.example"), now,
640 					 true, &covered, &issecure);
641 	assert_int_equal(result, ISC_R_SUCCESS);
642 	assert_true(covered);
643 	assert_false(issecure);
644 
645 	/* NTA covered */
646 	covered = dns_view_ntacovers(myview, now, str2name("insecure.example"),
647 				     dns_rootname);
648 	assert_true(covered);
649 
650 	/* Not NTA covered */
651 	covered = dns_view_ntacovers(myview, now, str2name("secure.example"),
652 				     dns_rootname);
653 	assert_false(covered);
654 
655 	/* As of now + 2, the NTA should be clear */
656 	result = dns_view_issecuredomain(myview,
657 					 str2name("test.insecure.example"),
658 					 now + 2, true, &covered, &issecure);
659 	assert_int_equal(result, ISC_R_SUCCESS);
660 	assert_false(covered);
661 	assert_true(issecure);
662 
663 	/* Now check deletion */
664 	result = dns_view_issecuredomain(myview, str2name("test.new.example"),
665 					 now, true, &covered, &issecure);
666 	assert_int_equal(result, ISC_R_SUCCESS);
667 	assert_false(covered);
668 	assert_true(issecure);
669 
670 	result = dns_ntatable_add(ntatable, str2name("new.example"), false, now,
671 				  3600);
672 	assert_int_equal(result, ISC_R_SUCCESS);
673 
674 	result = dns_view_issecuredomain(myview, str2name("test.new.example"),
675 					 now, true, &covered, &issecure);
676 	assert_int_equal(result, ISC_R_SUCCESS);
677 	assert_true(covered);
678 	assert_false(issecure);
679 
680 	result = dns_ntatable_delete(ntatable, str2name("new.example"));
681 	assert_int_equal(result, ISC_R_SUCCESS);
682 
683 	result = dns_view_issecuredomain(myview, str2name("test.new.example"),
684 					 now, true, &covered, &issecure);
685 	assert_int_equal(result, ISC_R_SUCCESS);
686 	assert_false(covered);
687 	assert_true(issecure);
688 
689 	isc_loopmgr_shutdown(loopmgr);
690 
691 	/* Clean up */
692 	dns_ntatable_detach(&ntatable);
693 	dns_keytable_detach(&keytable);
694 	dns_view_detach(&myview);
695 }
696 
697 ISC_TEST_LIST_START
698 ISC_TEST_ENTRY_CUSTOM(add, setup_test, teardown_test)
699 ISC_TEST_ENTRY_CUSTOM(delete, setup_test, teardown_test)
700 ISC_TEST_ENTRY_CUSTOM(deletekey, setup_test, teardown_test)
701 ISC_TEST_ENTRY_CUSTOM(find, setup_test, teardown_test)
702 ISC_TEST_ENTRY_CUSTOM(issecuredomain, setup_test, teardown_test)
703 ISC_TEST_ENTRY_CUSTOM(dump, setup_test, teardown_test)
704 ISC_TEST_ENTRY_CUSTOM(nta, setup_test, teardown_test)
705 ISC_TEST_LIST_END
706 
707 ISC_TEST_MAIN
708