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