1 /*	$NetBSD: dnssectool.c,v 1.9 2015/07/08 17:28:55 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2004, 2005, 2007, 2009-2015  Internet Systems Consortium, Inc. ("ISC")
5  * Copyright (C) 2000, 2001, 2003  Internet Software Consortium.
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /*! \file */
21 
22 /*%
23  * DNSSEC Support Routines.
24  */
25 
26 #include <config.h>
27 
28 #include <stdlib.h>
29 
30 #include <isc/base32.h>
31 #include <isc/buffer.h>
32 #include <isc/dir.h>
33 #include <isc/entropy.h>
34 #include <isc/heap.h>
35 #include <isc/list.h>
36 #include <isc/mem.h>
37 #include <isc/string.h>
38 #include <isc/time.h>
39 #include <isc/util.h>
40 #include <isc/print.h>
41 
42 #include <dns/db.h>
43 #include <dns/dbiterator.h>
44 #include <dns/dnssec.h>
45 #include <dns/fixedname.h>
46 #include <dns/keyvalues.h>
47 #include <dns/log.h>
48 #include <dns/name.h>
49 #include <dns/nsec.h>
50 #include <dns/nsec3.h>
51 #include <dns/rdatastruct.h>
52 #include <dns/rdataclass.h>
53 #include <dns/rdataset.h>
54 #include <dns/rdatasetiter.h>
55 #include <dns/rdatatype.h>
56 #include <dns/result.h>
57 #include <dns/secalg.h>
58 #include <dns/time.h>
59 
60 #include "dnssectool.h"
61 
62 static isc_heap_t *expected_chains, *found_chains;
63 
64 struct nsec3_chain_fixed {
65 	isc_uint8_t	hash;
66 	isc_uint8_t	salt_length;
67 	isc_uint8_t	next_length;
68 	isc_uint16_t	iterations;
69 	/* unsigned char salt[0]; */
70 	/* unsigned char owner[0]; */
71 	/* unsigned char next[0]; */
72 };
73 
74 extern int verbose;
75 extern const char *program;
76 
77 typedef struct entropysource entropysource_t;
78 
79 struct entropysource {
80 	isc_entropysource_t *source;
81 	isc_mem_t *mctx;
82 	ISC_LINK(entropysource_t) link;
83 };
84 
85 static ISC_LIST(entropysource_t) sources;
86 static fatalcallback_t *fatalcallback = NULL;
87 
88 void
fatal(const char * format,...)89 fatal(const char *format, ...) {
90 	va_list args;
91 
92 	fprintf(stderr, "%s: fatal: ", program);
93 	va_start(args, format);
94 	vfprintf(stderr, format, args);
95 	va_end(args);
96 	fprintf(stderr, "\n");
97 	if (fatalcallback != NULL)
98 		(*fatalcallback)();
99 	exit(1);
100 }
101 
102 void
setfatalcallback(fatalcallback_t * callback)103 setfatalcallback(fatalcallback_t *callback) {
104 	fatalcallback = callback;
105 }
106 
107 void
check_result(isc_result_t result,const char * message)108 check_result(isc_result_t result, const char *message) {
109 	if (result != ISC_R_SUCCESS)
110 		fatal("%s: %s", message, isc_result_totext(result));
111 }
112 
113 void
vbprintf(int level,const char * fmt,...)114 vbprintf(int level, const char *fmt, ...) {
115 	va_list ap;
116 	if (level > verbose)
117 		return;
118 	va_start(ap, fmt);
119 	fprintf(stderr, "%s: ", program);
120 	vfprintf(stderr, fmt, ap);
121 	va_end(ap);
122 }
123 
124 void
version(const char * name)125 version(const char *name) {
126 	fprintf(stderr, "%s %s\n", name, VERSION);
127 	exit(0);
128 }
129 
130 void
type_format(const dns_rdatatype_t type,char * cp,unsigned int size)131 type_format(const dns_rdatatype_t type, char *cp, unsigned int size) {
132 	isc_buffer_t b;
133 	isc_region_t r;
134 	isc_result_t result;
135 
136 	isc_buffer_init(&b, cp, size - 1);
137 	result = dns_rdatatype_totext(type, &b);
138 	check_result(result, "dns_rdatatype_totext()");
139 	isc_buffer_usedregion(&b, &r);
140 	r.base[r.length] = 0;
141 }
142 
143 void
sig_format(dns_rdata_rrsig_t * sig,char * cp,unsigned int size)144 sig_format(dns_rdata_rrsig_t *sig, char *cp, unsigned int size) {
145 	char namestr[DNS_NAME_FORMATSIZE];
146 	char algstr[DNS_NAME_FORMATSIZE];
147 
148 	dns_name_format(&sig->signer, namestr, sizeof(namestr));
149 	dns_secalg_format(sig->algorithm, algstr, sizeof(algstr));
150 	snprintf(cp, size, "%s/%s/%d", namestr, algstr, sig->keyid);
151 }
152 
153 void
setup_logging(isc_mem_t * mctx,isc_log_t ** logp)154 setup_logging(isc_mem_t *mctx, isc_log_t **logp) {
155 	isc_result_t result;
156 	isc_logdestination_t destination;
157 	isc_logconfig_t *logconfig = NULL;
158 	isc_log_t *log = NULL;
159 	int level;
160 
161 	if (verbose < 0)
162 		verbose = 0;
163 	switch (verbose) {
164 	case 0:
165 		/*
166 		 * We want to see warnings about things like out-of-zone
167 		 * data in the master file even when not verbose.
168 		 */
169 		level = ISC_LOG_WARNING;
170 		break;
171 	case 1:
172 		level = ISC_LOG_INFO;
173 		break;
174 	default:
175 		level = ISC_LOG_DEBUG(verbose - 2 + 1);
176 		break;
177 	}
178 
179 	RUNTIME_CHECK(isc_log_create(mctx, &log, &logconfig) == ISC_R_SUCCESS);
180 	isc_log_setcontext(log);
181 	dns_log_init(log);
182 	dns_log_setcontext(log);
183 
184 	RUNTIME_CHECK(isc_log_settag(logconfig, program) == ISC_R_SUCCESS);
185 
186 	/*
187 	 * Set up a channel similar to default_stderr except:
188 	 *  - the logging level is passed in
189 	 *  - the program name and logging level are printed
190 	 *  - no time stamp is printed
191 	 */
192 	destination.file.stream = stderr;
193 	destination.file.name = NULL;
194 	destination.file.versions = ISC_LOG_ROLLNEVER;
195 	destination.file.maximum_size = 0;
196 	result = isc_log_createchannel(logconfig, "stderr",
197 				       ISC_LOG_TOFILEDESC,
198 				       level,
199 				       &destination,
200 				       ISC_LOG_PRINTTAG|ISC_LOG_PRINTLEVEL);
201 	check_result(result, "isc_log_createchannel()");
202 
203 	RUNTIME_CHECK(isc_log_usechannel(logconfig, "stderr",
204 					 NULL, NULL) == ISC_R_SUCCESS);
205 
206 	*logp = log;
207 }
208 
209 void
cleanup_logging(isc_log_t ** logp)210 cleanup_logging(isc_log_t **logp) {
211 	isc_log_t *log;
212 
213 	REQUIRE(logp != NULL);
214 
215 	log = *logp;
216 	if (log == NULL)
217 		return;
218 	isc_log_destroy(&log);
219 	isc_log_setcontext(NULL);
220 	dns_log_setcontext(NULL);
221 	logp = NULL;
222 }
223 
224 void
setup_entropy(isc_mem_t * mctx,const char * randomfile,isc_entropy_t ** ectx)225 setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx) {
226 	isc_result_t result;
227 	isc_entropysource_t *source = NULL;
228 	entropysource_t *elt;
229 	int usekeyboard = ISC_ENTROPY_KEYBOARDMAYBE;
230 
231 	REQUIRE(ectx != NULL);
232 
233 	if (*ectx == NULL) {
234 		result = isc_entropy_create(mctx, ectx);
235 		if (result != ISC_R_SUCCESS)
236 			fatal("could not create entropy object");
237 		ISC_LIST_INIT(sources);
238 	}
239 
240 	if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) {
241 		usekeyboard = ISC_ENTROPY_KEYBOARDYES;
242 		randomfile = NULL;
243 	}
244 
245 	result = isc_entropy_usebestsource(*ectx, &source, randomfile,
246 					   usekeyboard);
247 
248 	if (result != ISC_R_SUCCESS)
249 		fatal("could not initialize entropy source: %s",
250 		      isc_result_totext(result));
251 
252 	if (source != NULL) {
253 		elt = isc_mem_get(mctx, sizeof(*elt));
254 		if (elt == NULL)
255 			fatal("out of memory");
256 		elt->source = source;
257 		elt->mctx = mctx;
258 		ISC_LINK_INIT(elt, link);
259 		ISC_LIST_APPEND(sources, elt, link);
260 	}
261 }
262 
263 void
cleanup_entropy(isc_entropy_t ** ectx)264 cleanup_entropy(isc_entropy_t **ectx) {
265 	entropysource_t *source;
266 	while (!ISC_LIST_EMPTY(sources)) {
267 		source = ISC_LIST_HEAD(sources);
268 		ISC_LIST_UNLINK(sources, source, link);
269 		isc_entropy_destroysource(&source->source);
270 		isc_mem_put(source->mctx, source, sizeof(*source));
271 	}
272 	isc_entropy_detach(ectx);
273 }
274 
275 static isc_stdtime_t
time_units(isc_stdtime_t offset,char * suffix,const char * str)276 time_units(isc_stdtime_t offset, char *suffix, const char *str) {
277 	switch (suffix[0]) {
278 	    case 'Y': case 'y':
279 		return (offset * (365 * 24 * 3600));
280 	    case 'M': case 'm':
281 		switch (suffix[1]) {
282 		    case 'O': case 'o':
283 			return (offset * (30 * 24 * 3600));
284 		    case 'I': case 'i':
285 			return (offset * 60);
286 		    case '\0':
287 			fatal("'%s' ambiguous: use 'mi' for minutes "
288 			      "or 'mo' for months", str);
289 		    default:
290 			fatal("time value %s is invalid", str);
291 		}
292 		/* NOTREACHED */
293 		break;
294 	    case 'W': case 'w':
295 		return (offset * (7 * 24 * 3600));
296 	    case 'D': case 'd':
297 		return (offset * (24 * 3600));
298 	    case 'H': case 'h':
299 		return (offset * 3600);
300 	    case 'S': case 's': case '\0':
301 		return (offset);
302 	    default:
303 		fatal("time value %s is invalid", str);
304 	}
305 	/* NOTREACHED */
306 	return(0); /* silence compiler warning */
307 }
308 
309 static inline isc_boolean_t
isnone(const char * str)310 isnone(const char *str) {
311 	return (ISC_TF((strcasecmp(str, "none") == 0) ||
312 		       (strcasecmp(str, "never") == 0)));
313 }
314 
315 dns_ttl_t
strtottl(const char * str)316 strtottl(const char *str) {
317 	const char *orig = str;
318 	dns_ttl_t ttl;
319 	char *endp;
320 
321 	if (isnone(str))
322 		return ((dns_ttl_t) 0);
323 
324 	ttl = strtol(str, &endp, 0);
325 	if (ttl == 0 && endp == str)
326 		fatal("TTL must be numeric");
327 	ttl = time_units(ttl, endp, orig);
328 	return (ttl);
329 }
330 
331 isc_stdtime_t
strtotime(const char * str,isc_int64_t now,isc_int64_t base,isc_boolean_t * setp)332 strtotime(const char *str, isc_int64_t now, isc_int64_t base,
333 	  isc_boolean_t *setp)
334 {
335 	isc_int64_t val, offset;
336 	isc_result_t result;
337 	const char *orig = str;
338 	char *endp;
339 	size_t n;
340 
341 	if (isnone(str)) {
342 		if (setp != NULL)
343 			*setp = ISC_FALSE;
344 		return ((isc_stdtime_t) 0);
345 	}
346 
347 	if (setp != NULL)
348 		*setp = ISC_TRUE;
349 
350 	if ((str[0] == '0' || str[0] == '-') && str[1] == '\0')
351 		return ((isc_stdtime_t) 0);
352 
353 	/*
354 	 * We accept times in the following formats:
355 	 *   now([+-]offset)
356 	 *   YYYYMMDD([+-]offset)
357 	 *   YYYYMMDDhhmmss([+-]offset)
358 	 *   [+-]offset
359 	 */
360 	n = strspn(str, "0123456789");
361 	if ((n == 8u || n == 14u) &&
362 	    (str[n] == '\0' || str[n] == '-' || str[n] == '+'))
363 	{
364 		char timestr[15];
365 
366 		strlcpy(timestr, str, sizeof(timestr));
367 		timestr[n] = 0;
368 		if (n == 8u)
369 			strlcat(timestr, "000000", sizeof(timestr));
370 		result = dns_time64_fromtext(timestr, &val);
371 		if (result != ISC_R_SUCCESS)
372 			fatal("time value %s is invalid: %s", orig,
373 			      isc_result_totext(result));
374 		base = val;
375 		str += n;
376 	} else if (strncmp(str, "now", 3) == 0) {
377 		base = now;
378 		str += 3;
379 	}
380 
381 	if (str[0] == '\0')
382 		return ((isc_stdtime_t) base);
383 	else if (str[0] == '+') {
384 		offset = strtol(str + 1, &endp, 0);
385 		offset = time_units((isc_stdtime_t) offset, endp, orig);
386 		val = base + offset;
387 	} else if (str[0] == '-') {
388 		offset = strtol(str + 1, &endp, 0);
389 		offset = time_units((isc_stdtime_t) offset, endp, orig);
390 		val = base - offset;
391 	} else
392 		fatal("time value %s is invalid", orig);
393 
394 	return ((isc_stdtime_t) val);
395 }
396 
397 dns_rdataclass_t
strtoclass(const char * str)398 strtoclass(const char *str) {
399 	isc_textregion_t r;
400 	dns_rdataclass_t rdclass;
401 	isc_result_t ret;
402 
403 	if (str == NULL)
404 		return dns_rdataclass_in;
405 	DE_CONST(str, r.base);
406 	r.length = strlen(str);
407 	ret = dns_rdataclass_fromtext(&rdclass, &r);
408 	if (ret != ISC_R_SUCCESS)
409 		fatal("unknown class %s", str);
410 	return (rdclass);
411 }
412 
413 isc_result_t
try_dir(const char * dirname)414 try_dir(const char *dirname) {
415 	isc_result_t result;
416 	isc_dir_t d;
417 
418 	isc_dir_init(&d);
419 	result = isc_dir_open(&d, dirname);
420 	if (result == ISC_R_SUCCESS) {
421 		isc_dir_close(&d);
422 	}
423 	return (result);
424 }
425 
426 /*
427  * Check private key version compatibility.
428  */
429 void
check_keyversion(dst_key_t * key,char * keystr)430 check_keyversion(dst_key_t *key, char *keystr) {
431 	int major, minor;
432 	dst_key_getprivateformat(key, &major, &minor);
433 	INSIST(major <= DST_MAJOR_VERSION); /* invalid private key */
434 
435 	if (major < DST_MAJOR_VERSION || minor < DST_MINOR_VERSION)
436 		fatal("Key %s has incompatible format version %d.%d, "
437 		      "use -f to force upgrade to new version.",
438 		      keystr, major, minor);
439 	if (minor > DST_MINOR_VERSION)
440 		fatal("Key %s has incompatible format version %d.%d, "
441 		      "use -f to force downgrade to current version.",
442 		      keystr, major, minor);
443 }
444 
445 void
set_keyversion(dst_key_t * key)446 set_keyversion(dst_key_t *key) {
447 	int major, minor;
448 	dst_key_getprivateformat(key, &major, &minor);
449 	INSIST(major <= DST_MAJOR_VERSION);
450 
451 	if (major != DST_MAJOR_VERSION || minor != DST_MINOR_VERSION)
452 		dst_key_setprivateformat(key, DST_MAJOR_VERSION,
453 					 DST_MINOR_VERSION);
454 
455 	/*
456 	 * If the key is from a version older than 1.3, set
457 	 * set the creation date
458 	 */
459 	if (major < 1 || (major == 1 && minor <= 2)) {
460 		isc_stdtime_t now;
461 		isc_stdtime_get(&now);
462 		dst_key_settime(key, DST_TIME_CREATED, now);
463 	}
464 }
465 
466 isc_boolean_t
key_collision(dst_key_t * dstkey,dns_name_t * name,const char * dir,isc_mem_t * mctx,isc_boolean_t * exact)467 key_collision(dst_key_t *dstkey, dns_name_t *name, const char *dir,
468 	      isc_mem_t *mctx, isc_boolean_t *exact)
469 {
470 	isc_result_t result;
471 	isc_boolean_t conflict = ISC_FALSE;
472 	dns_dnsseckeylist_t matchkeys;
473 	dns_dnsseckey_t *key = NULL;
474 	isc_uint16_t id, oldid;
475 	isc_uint32_t rid, roldid;
476 	dns_secalg_t alg;
477 
478 	if (exact != NULL)
479 		*exact = ISC_FALSE;
480 
481 	id = dst_key_id(dstkey);
482 	rid = dst_key_rid(dstkey);
483 	alg = dst_key_alg(dstkey);
484 
485 	ISC_LIST_INIT(matchkeys);
486 	result = dns_dnssec_findmatchingkeys(name, dir, mctx, &matchkeys);
487 	if (result == ISC_R_NOTFOUND)
488 		return (ISC_FALSE);
489 
490 	while (!ISC_LIST_EMPTY(matchkeys) && !conflict) {
491 		key = ISC_LIST_HEAD(matchkeys);
492 		if (dst_key_alg(key->key) != alg)
493 			goto next;
494 
495 		oldid = dst_key_id(key->key);
496 		roldid = dst_key_rid(key->key);
497 
498 		if (oldid == rid || roldid == id || id == oldid) {
499 			conflict = ISC_TRUE;
500 			if (id != oldid) {
501 				if (verbose > 1)
502 					fprintf(stderr, "Key ID %d could "
503 						"collide with %d\n",
504 						id, oldid);
505 			} else {
506 				if (exact != NULL)
507 					*exact = ISC_TRUE;
508 				if (verbose > 1)
509 					fprintf(stderr, "Key ID %d exists\n",
510 						id);
511 			}
512 		}
513 
514  next:
515 		ISC_LIST_UNLINK(matchkeys, key, link);
516 		dns_dnsseckey_destroy(mctx, &key);
517 	}
518 
519 	/* Finish freeing the list */
520 	while (!ISC_LIST_EMPTY(matchkeys)) {
521 		key = ISC_LIST_HEAD(matchkeys);
522 		ISC_LIST_UNLINK(matchkeys, key, link);
523 		dns_dnsseckey_destroy(mctx, &key);
524 	}
525 
526 	return (conflict);
527 }
528 
529 isc_boolean_t
is_delegation(dns_db_t * db,dns_dbversion_t * ver,dns_name_t * origin,dns_name_t * name,dns_dbnode_t * node,isc_uint32_t * ttlp)530 is_delegation(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
531 	      dns_name_t *name, dns_dbnode_t *node, isc_uint32_t *ttlp)
532 {
533 	dns_rdataset_t nsset;
534 	isc_result_t result;
535 
536 	if (dns_name_equal(name, origin))
537 		return (ISC_FALSE);
538 
539 	dns_rdataset_init(&nsset);
540 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_ns,
541 				     0, 0, &nsset, NULL);
542 	if (dns_rdataset_isassociated(&nsset)) {
543 		if (ttlp != NULL)
544 			*ttlp = nsset.ttl;
545 		dns_rdataset_disassociate(&nsset);
546 	}
547 
548 	return (ISC_TF(result == ISC_R_SUCCESS));
549 }
550 
551 static isc_boolean_t
goodsig(dns_name_t * origin,dns_rdata_t * sigrdata,dns_name_t * name,dns_rdataset_t * keyrdataset,dns_rdataset_t * rdataset,isc_mem_t * mctx)552 goodsig(dns_name_t *origin, dns_rdata_t *sigrdata, dns_name_t *name,
553 	dns_rdataset_t *keyrdataset, dns_rdataset_t *rdataset, isc_mem_t *mctx)
554 {
555 	dns_rdata_dnskey_t key;
556 	dns_rdata_rrsig_t sig;
557 	dst_key_t *dstkey = NULL;
558 	isc_result_t result;
559 
560 	result = dns_rdata_tostruct(sigrdata, &sig, NULL);
561 	check_result(result, "dns_rdata_tostruct()");
562 
563 	for (result = dns_rdataset_first(keyrdataset);
564 	     result == ISC_R_SUCCESS;
565 	     result = dns_rdataset_next(keyrdataset)) {
566 		dns_rdata_t rdata = DNS_RDATA_INIT;
567 		dns_rdataset_current(keyrdataset, &rdata);
568 		result = dns_rdata_tostruct(&rdata, &key, NULL);
569 		check_result(result, "dns_rdata_tostruct()");
570 		result = dns_dnssec_keyfromrdata(origin, &rdata, mctx,
571 						 &dstkey);
572 		if (result != ISC_R_SUCCESS)
573 			return (ISC_FALSE);
574 		if (sig.algorithm != key.algorithm ||
575 		    sig.keyid != dst_key_id(dstkey) ||
576 		    !dns_name_equal(&sig.signer, origin)) {
577 			dst_key_free(&dstkey);
578 			continue;
579 		}
580 		result = dns_dnssec_verify(name, rdataset, dstkey, ISC_FALSE,
581 					   mctx, sigrdata);
582 		dst_key_free(&dstkey);
583 		if (result == ISC_R_SUCCESS)
584 			return(ISC_TRUE);
585 	}
586 	return (ISC_FALSE);
587 }
588 
589 static isc_result_t
verifynsec(dns_db_t * db,dns_dbversion_t * ver,dns_name_t * name,dns_dbnode_t * node,dns_name_t * nextname)590 verifynsec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
591 	   dns_dbnode_t *node, dns_name_t *nextname)
592 {
593 	unsigned char buffer[DNS_NSEC_BUFFERSIZE];
594 	char namebuf[DNS_NAME_FORMATSIZE];
595 	char nextbuf[DNS_NAME_FORMATSIZE];
596 	char found[DNS_NAME_FORMATSIZE];
597 	dns_rdataset_t rdataset;
598 	dns_rdata_t rdata = DNS_RDATA_INIT;
599 	dns_rdata_t tmprdata = DNS_RDATA_INIT;
600 	dns_rdata_nsec_t nsec;
601 	isc_result_t result;
602 
603 	dns_rdataset_init(&rdataset);
604 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
605 				     0, 0, &rdataset, NULL);
606 	if (result != ISC_R_SUCCESS) {
607 		dns_name_format(name, namebuf, sizeof(namebuf));
608 		fprintf(stderr, "Missing NSEC record for %s\n", namebuf);
609 		goto failure;
610 	}
611 
612 	result = dns_rdataset_first(&rdataset);
613 	check_result(result, "dns_rdataset_first()");
614 
615 	dns_rdataset_current(&rdataset, &rdata);
616 	result = dns_rdata_tostruct(&rdata, &nsec, NULL);
617 	check_result(result, "dns_rdata_tostruct()");
618 	/* Check bit next name is consistent */
619 	if (!dns_name_equal(&nsec.next, nextname)) {
620 		dns_name_format(name, namebuf, sizeof(namebuf));
621 		dns_name_format(nextname, nextbuf, sizeof(nextbuf));
622 		dns_name_format(&nsec.next, found, sizeof(found));
623 		fprintf(stderr, "Bad NSEC record for %s, next name "
624 				"mismatch (expected:%s, found:%s)\n", namebuf,
625 				nextbuf, found);
626 		goto failure;
627 	}
628 	/* Check bit map is consistent */
629 	result = dns_nsec_buildrdata(db, ver, node, nextname, buffer,
630 				     &tmprdata);
631 	check_result(result, "dns_nsec_buildrdata()");
632 	if (dns_rdata_compare(&rdata, &tmprdata) != 0) {
633 		dns_name_format(name, namebuf, sizeof(namebuf));
634 		fprintf(stderr, "Bad NSEC record for %s, bit map "
635 				"mismatch\n", namebuf);
636 		goto failure;
637 	}
638 	result = dns_rdataset_next(&rdataset);
639 	if (result != ISC_R_NOMORE) {
640 		dns_name_format(name, namebuf, sizeof(namebuf));
641 		fprintf(stderr, "Multipe NSEC records for %s\n", namebuf);
642 		goto failure;
643 
644 	}
645 	dns_rdataset_disassociate(&rdataset);
646 	return (ISC_R_SUCCESS);
647  failure:
648 	if (dns_rdataset_isassociated(&rdataset))
649 		dns_rdataset_disassociate(&rdataset);
650 	return (ISC_R_FAILURE);
651 }
652 
653 static void
check_no_rrsig(dns_db_t * db,dns_dbversion_t * ver,dns_rdataset_t * rdataset,dns_name_t * name,dns_dbnode_t * node)654 check_no_rrsig(dns_db_t *db, dns_dbversion_t *ver, dns_rdataset_t *rdataset,
655 	       dns_name_t *name, dns_dbnode_t *node)
656 {
657 	char namebuf[DNS_NAME_FORMATSIZE];
658 	char typebuf[80];
659 	dns_rdataset_t sigrdataset;
660 	dns_rdatasetiter_t *rdsiter = NULL;
661 	isc_result_t result;
662 
663 	dns_rdataset_init(&sigrdataset);
664 	result = dns_db_allrdatasets(db, node, ver, 0, &rdsiter);
665 	check_result(result, "dns_db_allrdatasets()");
666 	for (result = dns_rdatasetiter_first(rdsiter);
667 	     result == ISC_R_SUCCESS;
668 	     result = dns_rdatasetiter_next(rdsiter)) {
669 		dns_rdatasetiter_current(rdsiter, &sigrdataset);
670 		if (sigrdataset.type == dns_rdatatype_rrsig &&
671 		    sigrdataset.covers == rdataset->type)
672 			break;
673 		dns_rdataset_disassociate(&sigrdataset);
674 	}
675 	if (result == ISC_R_SUCCESS) {
676 		dns_name_format(name, namebuf, sizeof(namebuf));
677 		type_format(rdataset->type, typebuf, sizeof(typebuf));
678 		fprintf(stderr, "Warning: Found unexpected signatures for "
679 			"%s/%s\n", namebuf, typebuf);
680 	}
681 	if (dns_rdataset_isassociated(&sigrdataset))
682 		dns_rdataset_disassociate(&sigrdataset);
683 	dns_rdatasetiter_destroy(&rdsiter);
684 }
685 
686 static isc_boolean_t
chain_compare(void * arg1,void * arg2)687 chain_compare(void *arg1, void *arg2) {
688 	struct nsec3_chain_fixed *e1 = arg1, *e2 = arg2;
689 	size_t len;
690 
691 	/*
692 	 * Do each element in turn to get a stable sort.
693 	 */
694 	if (e1->hash < e2->hash)
695 		return (ISC_TRUE);
696 	if (e1->hash > e2->hash)
697 		return (ISC_FALSE);
698 	if (e1->iterations < e2->iterations)
699 		return (ISC_TRUE);
700 	if (e1->iterations > e2->iterations)
701 		return (ISC_FALSE);
702 	if (e1->salt_length < e2->salt_length)
703 		return (ISC_TRUE);
704 	if (e1->salt_length > e2->salt_length)
705 		return (ISC_FALSE);
706 	if (e1->next_length < e2->next_length)
707 		return (ISC_TRUE);
708 	if (e1->next_length > e2->next_length)
709 		return (ISC_FALSE);
710 	len = e1->salt_length + 2 * e1->next_length;
711 	if (memcmp(e1 + 1, e2 + 1, len) < 0)
712 		return (ISC_TRUE);
713 	return (ISC_FALSE);
714 }
715 
716 static isc_boolean_t
chain_equal(struct nsec3_chain_fixed * e1,struct nsec3_chain_fixed * e2)717 chain_equal(struct nsec3_chain_fixed *e1, struct nsec3_chain_fixed *e2) {
718 	size_t len;
719 
720 	if (e1->hash != e2->hash)
721 		return (ISC_FALSE);
722 	if (e1->iterations != e2->iterations)
723 		return (ISC_FALSE);
724 	if (e1->salt_length != e2->salt_length)
725 		return (ISC_FALSE);
726 	if (e1->next_length != e2->next_length)
727 		return (ISC_FALSE);
728 	len = e1->salt_length + 2 * e1->next_length;
729 	if (memcmp(e1 + 1, e2 + 1, len) != 0)
730 		return (ISC_FALSE);
731 	return (ISC_TRUE);
732 }
733 
734 static isc_result_t
record_nsec3(const unsigned char * rawhash,const dns_rdata_nsec3_t * nsec3,isc_mem_t * mctx,isc_heap_t * chains)735 record_nsec3(const unsigned char *rawhash, const dns_rdata_nsec3_t *nsec3,
736 	     isc_mem_t *mctx, isc_heap_t *chains)
737 {
738 	struct nsec3_chain_fixed *element;
739 	size_t len;
740 	unsigned char *cp;
741 	isc_result_t result;
742 
743 	len = sizeof(*element) + nsec3->next_length * 2 + nsec3->salt_length;
744 
745 	element = isc_mem_get(mctx, len);
746 	if (element == NULL)
747 		return (ISC_R_NOMEMORY);
748 	memset(element, 0, len);
749 	element->hash = nsec3->hash;
750 	element->salt_length = nsec3->salt_length;
751 	element->next_length = nsec3->next_length;
752 	element->iterations = nsec3->iterations;
753 	cp = (unsigned char *)(element + 1);
754 	memmove(cp, nsec3->salt, nsec3->salt_length);
755 	cp += nsec3->salt_length;
756 	memmove(cp, rawhash, nsec3->next_length);
757 	cp += nsec3->next_length;
758 	memmove(cp, nsec3->next, nsec3->next_length);
759 	result = isc_heap_insert(chains, element);
760 	if (result != ISC_R_SUCCESS) {
761 		fprintf(stderr, "isc_heap_insert failed: %s\n",
762 			isc_result_totext(result));
763 		isc_mem_put(mctx, element, len);
764 	}
765 	return (result);
766 }
767 
768 static isc_result_t
match_nsec3(dns_name_t * name,isc_mem_t * mctx,dns_rdata_nsec3param_t * nsec3param,dns_rdataset_t * rdataset,unsigned char types[8192],unsigned int maxtype,unsigned char * rawhash,size_t rhsize)769 match_nsec3(dns_name_t *name, isc_mem_t *mctx,
770 	    dns_rdata_nsec3param_t *nsec3param, dns_rdataset_t *rdataset,
771 	    unsigned char types[8192], unsigned int maxtype,
772 	    unsigned char *rawhash, size_t rhsize)
773 {
774 	unsigned char cbm[8244];
775 	char namebuf[DNS_NAME_FORMATSIZE];
776 	dns_rdata_nsec3_t nsec3;
777 	isc_result_t result;
778 	unsigned int len;
779 
780 	/*
781 	 * Find matching NSEC3 record.
782 	 */
783 	for (result = dns_rdataset_first(rdataset);
784 	     result == ISC_R_SUCCESS;
785 	     result = dns_rdataset_next(rdataset)) {
786 		dns_rdata_t rdata = DNS_RDATA_INIT;
787 		dns_rdataset_current(rdataset, &rdata);
788 		result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
789 		check_result(result, "dns_rdata_tostruct()");
790 		if (nsec3.hash == nsec3param->hash &&
791 		    nsec3.next_length == rhsize &&
792 		    nsec3.iterations == nsec3param->iterations &&
793 		    nsec3.salt_length == nsec3param->salt_length &&
794 		    memcmp(nsec3.salt, nsec3param->salt,
795 			   nsec3param->salt_length) == 0)
796 			break;
797 	}
798 	if (result != ISC_R_SUCCESS) {
799 		dns_name_format(name, namebuf, sizeof(namebuf));
800 		fprintf(stderr, "Missing NSEC3 record for %s\n", namebuf);
801 		return (result);
802 	}
803 
804 	/*
805 	 * Check the type list.
806 	 */
807 	len = dns_nsec_compressbitmap(cbm, types, maxtype);
808 	if (nsec3.len != len || memcmp(cbm, nsec3.typebits, len) != 0) {
809 		dns_name_format(name, namebuf, sizeof(namebuf));
810 		fprintf(stderr, "Bad NSEC3 record for %s, bit map "
811 				"mismatch\n", namebuf);
812 		return (ISC_R_FAILURE);
813 	}
814 
815 	/*
816 	 * Record chain.
817 	 */
818 	result = record_nsec3(rawhash, &nsec3, mctx, expected_chains);
819 	check_result(result, "record_nsec3()");
820 
821 	/*
822 	 * Make sure there is only one NSEC3 record with this set of
823 	 * parameters.
824 	 */
825 	for (result = dns_rdataset_next(rdataset);
826 	     result == ISC_R_SUCCESS;
827 	     result = dns_rdataset_next(rdataset)) {
828 		dns_rdata_t rdata = DNS_RDATA_INIT;
829 		dns_rdataset_current(rdataset, &rdata);
830 		result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
831 		check_result(result, "dns_rdata_tostruct()");
832 		if (nsec3.hash == nsec3param->hash &&
833 		    nsec3.iterations == nsec3param->iterations &&
834 		    nsec3.salt_length == nsec3param->salt_length &&
835 		    memcmp(nsec3.salt, nsec3param->salt,
836 			   nsec3.salt_length) == 0) {
837 			dns_name_format(name, namebuf, sizeof(namebuf));
838 			fprintf(stderr, "Multiple NSEC3 records with the "
839 				"same parameter set for %s", namebuf);
840 			result = DNS_R_DUPLICATE;
841 			break;
842 		}
843 	}
844 	if (result != ISC_R_NOMORE)
845 		return (result);
846 
847 	result = ISC_R_SUCCESS;
848 	return (result);
849 }
850 
851 static isc_boolean_t
innsec3params(dns_rdata_nsec3_t * nsec3,dns_rdataset_t * nsec3paramset)852 innsec3params(dns_rdata_nsec3_t *nsec3, dns_rdataset_t *nsec3paramset) {
853 	dns_rdata_nsec3param_t nsec3param;
854 	isc_result_t result;
855 
856 	for (result = dns_rdataset_first(nsec3paramset);
857 	     result == ISC_R_SUCCESS;
858 	     result = dns_rdataset_next(nsec3paramset)) {
859 		dns_rdata_t rdata = DNS_RDATA_INIT;
860 
861 		dns_rdataset_current(nsec3paramset, &rdata);
862 		result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
863 		check_result(result, "dns_rdata_tostruct()");
864 		if (nsec3param.flags == 0 &&
865 		    nsec3param.hash == nsec3->hash &&
866 		    nsec3param.iterations == nsec3->iterations &&
867 		    nsec3param.salt_length == nsec3->salt_length &&
868 		    memcmp(nsec3param.salt, nsec3->salt,
869 			   nsec3->salt_length) == 0)
870 			return (ISC_TRUE);
871 	}
872 	return (ISC_FALSE);
873 }
874 
875 static isc_result_t
record_found(dns_db_t * db,dns_dbversion_t * ver,isc_mem_t * mctx,dns_name_t * name,dns_dbnode_t * node,dns_rdataset_t * nsec3paramset)876 record_found(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx,
877 	     dns_name_t *name, dns_dbnode_t *node,
878 	     dns_rdataset_t *nsec3paramset)
879 {
880 	unsigned char owner[NSEC3_MAX_HASH_LENGTH];
881 	dns_rdata_nsec3_t nsec3;
882 	dns_rdataset_t rdataset;
883 	dns_label_t hashlabel;
884 	isc_buffer_t b;
885 	isc_result_t result;
886 
887 	if (nsec3paramset == NULL || !dns_rdataset_isassociated(nsec3paramset))
888 		return (ISC_R_SUCCESS);
889 
890 	dns_rdataset_init(&rdataset);
891 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
892 				     0, 0, &rdataset, NULL);
893 	if (result != ISC_R_SUCCESS)
894 		return (ISC_R_SUCCESS);
895 
896 	dns_name_getlabel(name, 0, &hashlabel);
897 	isc_region_consume(&hashlabel, 1);
898 	isc_buffer_init(&b, owner, sizeof(owner));
899 	result = isc_base32hex_decoderegion(&hashlabel, &b);
900 	if (result != ISC_R_SUCCESS)
901 		goto cleanup;
902 
903 	for (result = dns_rdataset_first(&rdataset);
904 	     result == ISC_R_SUCCESS;
905 	     result = dns_rdataset_next(&rdataset)) {
906 		dns_rdata_t rdata = DNS_RDATA_INIT;
907 		dns_rdataset_current(&rdataset, &rdata);
908 		result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
909 		check_result(result, "dns_rdata_tostruct()");
910 		if (nsec3.next_length != isc_buffer_usedlength(&b))
911 			continue;
912 		/*
913 		 * We only care about NSEC3 records that match a NSEC3PARAM
914 		 * record.
915 		 */
916 		if (!innsec3params(&nsec3, nsec3paramset))
917 			continue;
918 
919 		/*
920 		 * Record chain.
921 		 */
922 		result = record_nsec3(owner, &nsec3, mctx, found_chains);
923 		check_result(result, "record_nsec3()");
924 	}
925 
926  cleanup:
927 	dns_rdataset_disassociate(&rdataset);
928 	return (ISC_R_SUCCESS);
929 }
930 
931 static isc_boolean_t
isoptout(dns_db_t * db,dns_dbversion_t * ver,dns_name_t * origin,dns_rdata_t * nsec3rdata)932 isoptout(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
933 	 dns_rdata_t *nsec3rdata)
934 {
935 	dns_rdataset_t rdataset;
936 	dns_rdata_t rdata = DNS_RDATA_INIT;
937 	dns_rdata_nsec3_t nsec3;
938 	dns_rdata_nsec3param_t nsec3param;
939 	dns_fixedname_t fixed;
940 	dns_name_t *hashname;
941 	isc_result_t result;
942 	dns_dbnode_t *node = NULL;
943 	unsigned char rawhash[NSEC3_MAX_HASH_LENGTH];
944 	size_t rhsize = sizeof(rawhash);
945 	isc_boolean_t ret;
946 
947 	result = dns_rdata_tostruct(nsec3rdata, &nsec3param, NULL);
948 	check_result(result, "dns_rdata_tostruct()");
949 
950 	dns_fixedname_init(&fixed);
951 	result = dns_nsec3_hashname(&fixed, rawhash, &rhsize, origin, origin,
952 				    nsec3param.hash, nsec3param.iterations,
953 				    nsec3param.salt, nsec3param.salt_length);
954 	check_result(result, "dns_nsec3_hashname()");
955 
956 	dns_rdataset_init(&rdataset);
957 	hashname = dns_fixedname_name(&fixed);
958 	result = dns_db_findnsec3node(db, hashname, ISC_FALSE, &node);
959 	if (result == ISC_R_SUCCESS)
960 		result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
961 					     0, 0, &rdataset, NULL);
962 	if (result != ISC_R_SUCCESS)
963 		return (ISC_FALSE);
964 
965 	result = dns_rdataset_first(&rdataset);
966 	check_result(result, "dns_rdataset_first()");
967 
968 	dns_rdataset_current(&rdataset, &rdata);
969 
970 	result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
971 	if (result != ISC_R_SUCCESS)
972 		ret = ISC_FALSE;
973 	else
974 		ret = ISC_TF((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0);
975 
976 	if (dns_rdataset_isassociated(&rdataset))
977 		dns_rdataset_disassociate(&rdataset);
978 	if (node != NULL)
979 		dns_db_detachnode(db, &node);
980 
981 	return (ret);
982 }
983 
984 static isc_result_t
verifynsec3(dns_db_t * db,dns_dbversion_t * ver,dns_name_t * origin,isc_mem_t * mctx,dns_name_t * name,dns_rdata_t * rdata,isc_boolean_t delegation,isc_boolean_t empty,unsigned char types[8192],unsigned int maxtype)985 verifynsec3(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
986 	    isc_mem_t *mctx, dns_name_t *name, dns_rdata_t *rdata,
987 	    isc_boolean_t delegation, isc_boolean_t empty,
988 	    unsigned char types[8192], unsigned int maxtype)
989 {
990 	char namebuf[DNS_NAME_FORMATSIZE];
991 	char hashbuf[DNS_NAME_FORMATSIZE];
992 	dns_rdataset_t rdataset;
993 	dns_rdata_nsec3param_t nsec3param;
994 	dns_fixedname_t fixed;
995 	dns_name_t *hashname;
996 	isc_result_t result;
997 	dns_dbnode_t *node = NULL;
998 	unsigned char rawhash[NSEC3_MAX_HASH_LENGTH];
999 	size_t rhsize = sizeof(rawhash);
1000 	isc_boolean_t optout;
1001 
1002 	result = dns_rdata_tostruct(rdata, &nsec3param, NULL);
1003 	check_result(result, "dns_rdata_tostruct()");
1004 
1005 	if (nsec3param.flags != 0)
1006 		return (ISC_R_SUCCESS);
1007 
1008 	if (!dns_nsec3_supportedhash(nsec3param.hash))
1009 		return (ISC_R_SUCCESS);
1010 
1011 	optout = isoptout(db, ver, origin, rdata);
1012 
1013 	dns_fixedname_init(&fixed);
1014 	result = dns_nsec3_hashname(&fixed, rawhash, &rhsize, name, origin,
1015 				    nsec3param.hash, nsec3param.iterations,
1016 				    nsec3param.salt, nsec3param.salt_length);
1017 	check_result(result, "dns_nsec3_hashname()");
1018 
1019 	/*
1020 	 * We don't use dns_db_find() here as it works with the choosen
1021 	 * nsec3 chain and we may also be called with uncommitted data
1022 	 * from dnssec-signzone so the secure status of the zone may not
1023 	 * be up to date.
1024 	 */
1025 	dns_rdataset_init(&rdataset);
1026 	hashname = dns_fixedname_name(&fixed);
1027 	result = dns_db_findnsec3node(db, hashname, ISC_FALSE, &node);
1028 	if (result == ISC_R_SUCCESS)
1029 		result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
1030 					     0, 0, &rdataset, NULL);
1031 	if (result != ISC_R_SUCCESS &&
1032 	    (!delegation || (empty && !optout) ||
1033 	     (!empty && dns_nsec_isset(types, dns_rdatatype_ds))))
1034 	{
1035 		dns_name_format(name, namebuf, sizeof(namebuf));
1036 		dns_name_format(hashname, hashbuf, sizeof(hashbuf));
1037 		fprintf(stderr, "Missing NSEC3 record for %s (%s)\n",
1038 			namebuf, hashbuf);
1039 	} else if (result == ISC_R_NOTFOUND &&
1040 		   delegation && (!empty || optout))
1041 	{
1042 		result = ISC_R_SUCCESS;
1043 	} else if (result == ISC_R_SUCCESS) {
1044 		result = match_nsec3(name, mctx, &nsec3param, &rdataset,
1045 				     types, maxtype, rawhash, rhsize);
1046 	}
1047 
1048 	if (dns_rdataset_isassociated(&rdataset))
1049 		dns_rdataset_disassociate(&rdataset);
1050 	if (node != NULL)
1051 		dns_db_detachnode(db, &node);
1052 
1053 	return (result);
1054 }
1055 
1056 static isc_result_t
verifynsec3s(dns_db_t * db,dns_dbversion_t * ver,dns_name_t * origin,isc_mem_t * mctx,dns_name_t * name,dns_rdataset_t * nsec3paramset,isc_boolean_t delegation,isc_boolean_t empty,unsigned char types[8192],unsigned int maxtype)1057 verifynsec3s(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
1058 	     isc_mem_t *mctx, dns_name_t *name, dns_rdataset_t *nsec3paramset,
1059 	     isc_boolean_t delegation, isc_boolean_t empty,
1060 	     unsigned char types[8192], unsigned int maxtype)
1061 {
1062 	isc_result_t result;
1063 
1064 	for (result = dns_rdataset_first(nsec3paramset);
1065 	     result == ISC_R_SUCCESS;
1066 	     result = dns_rdataset_next(nsec3paramset)) {
1067 		dns_rdata_t rdata = DNS_RDATA_INIT;
1068 
1069 		dns_rdataset_current(nsec3paramset, &rdata);
1070 		result = verifynsec3(db, ver, origin, mctx, name, &rdata,
1071 				     delegation, empty, types, maxtype);
1072 		if (result != ISC_R_SUCCESS)
1073 			break;
1074 	}
1075 	if (result == ISC_R_NOMORE)
1076 		result = ISC_R_SUCCESS;
1077 	return (result);
1078 }
1079 
1080 static void
verifyset(dns_db_t * db,dns_dbversion_t * ver,dns_name_t * origin,isc_mem_t * mctx,dns_rdataset_t * rdataset,dns_name_t * name,dns_dbnode_t * node,dns_rdataset_t * keyrdataset,unsigned char * act_algorithms,unsigned char * bad_algorithms)1081 verifyset(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
1082 	  isc_mem_t *mctx, dns_rdataset_t *rdataset, dns_name_t *name,
1083 	  dns_dbnode_t *node, dns_rdataset_t *keyrdataset,
1084 	  unsigned char *act_algorithms, unsigned char *bad_algorithms)
1085 {
1086 	unsigned char set_algorithms[256];
1087 	char namebuf[DNS_NAME_FORMATSIZE];
1088 	char algbuf[80];
1089 	char typebuf[80];
1090 	dns_rdataset_t sigrdataset;
1091 	dns_rdatasetiter_t *rdsiter = NULL;
1092 	isc_result_t result;
1093 	int i;
1094 
1095 	dns_rdataset_init(&sigrdataset);
1096 	result = dns_db_allrdatasets(db, node, ver, 0, &rdsiter);
1097 	check_result(result, "dns_db_allrdatasets()");
1098 	for (result = dns_rdatasetiter_first(rdsiter);
1099 	     result == ISC_R_SUCCESS;
1100 	     result = dns_rdatasetiter_next(rdsiter)) {
1101 		dns_rdatasetiter_current(rdsiter, &sigrdataset);
1102 		if (sigrdataset.type == dns_rdatatype_rrsig &&
1103 		    sigrdataset.covers == rdataset->type)
1104 			break;
1105 		dns_rdataset_disassociate(&sigrdataset);
1106 	}
1107 	if (result != ISC_R_SUCCESS) {
1108 		dns_name_format(name, namebuf, sizeof(namebuf));
1109 		type_format(rdataset->type, typebuf, sizeof(typebuf));
1110 		fprintf(stderr, "No signatures for %s/%s\n", namebuf, typebuf);
1111 		for (i = 0; i < 256; i++)
1112 			if (act_algorithms[i] != 0)
1113 				bad_algorithms[i] = 1;
1114 		dns_rdatasetiter_destroy(&rdsiter);
1115 		return;
1116 	}
1117 
1118 	memset(set_algorithms, 0, sizeof(set_algorithms));
1119 	for (result = dns_rdataset_first(&sigrdataset);
1120 	     result == ISC_R_SUCCESS;
1121 	     result = dns_rdataset_next(&sigrdataset)) {
1122 		dns_rdata_t rdata = DNS_RDATA_INIT;
1123 		dns_rdata_rrsig_t sig;
1124 
1125 		dns_rdataset_current(&sigrdataset, &rdata);
1126 		result = dns_rdata_tostruct(&rdata, &sig, NULL);
1127 		check_result(result, "dns_rdata_tostruct()");
1128 		if (rdataset->ttl != sig.originalttl) {
1129 			dns_name_format(name, namebuf, sizeof(namebuf));
1130 			type_format(rdataset->type, typebuf, sizeof(typebuf));
1131 			fprintf(stderr, "TTL mismatch for %s %s keytag %u\n",
1132 				namebuf, typebuf, sig.keyid);
1133 			continue;
1134 		}
1135 		if ((set_algorithms[sig.algorithm] != 0) ||
1136 		    (act_algorithms[sig.algorithm] == 0))
1137 			continue;
1138 		if (goodsig(origin, &rdata, name, keyrdataset, rdataset, mctx))
1139 			set_algorithms[sig.algorithm] = 1;
1140 	}
1141 	dns_rdatasetiter_destroy(&rdsiter);
1142 	if (memcmp(set_algorithms, act_algorithms, sizeof(set_algorithms))) {
1143 		dns_name_format(name, namebuf, sizeof(namebuf));
1144 		type_format(rdataset->type, typebuf, sizeof(typebuf));
1145 		for (i = 0; i < 256; i++)
1146 			if ((act_algorithms[i] != 0) &&
1147 			    (set_algorithms[i] == 0)) {
1148 				dns_secalg_format(i, algbuf, sizeof(algbuf));
1149 				fprintf(stderr, "No correct %s signature for "
1150 					"%s %s\n", algbuf, namebuf, typebuf);
1151 				bad_algorithms[i] = 1;
1152 			}
1153 	}
1154 	dns_rdataset_disassociate(&sigrdataset);
1155 }
1156 
1157 static isc_result_t
verifynode(dns_db_t * db,dns_dbversion_t * ver,dns_name_t * origin,isc_mem_t * mctx,dns_name_t * name,dns_dbnode_t * node,isc_boolean_t delegation,dns_rdataset_t * keyrdataset,unsigned char * act_algorithms,unsigned char * bad_algorithms,dns_rdataset_t * nsecset,dns_rdataset_t * nsec3paramset,dns_name_t * nextname)1158 verifynode(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
1159 	   isc_mem_t *mctx, dns_name_t *name, dns_dbnode_t *node,
1160 	   isc_boolean_t delegation, dns_rdataset_t *keyrdataset,
1161 	   unsigned char *act_algorithms, unsigned char *bad_algorithms,
1162 	   dns_rdataset_t *nsecset, dns_rdataset_t *nsec3paramset,
1163 	   dns_name_t *nextname)
1164 {
1165 	unsigned char types[8192];
1166 	unsigned int maxtype = 0;
1167 	dns_rdataset_t rdataset; dns_rdatasetiter_t *rdsiter = NULL;
1168 	isc_result_t result, tresult;
1169 
1170 	memset(types, 0, sizeof(types));
1171 	result = dns_db_allrdatasets(db, node, ver, 0, &rdsiter);
1172 	check_result(result, "dns_db_allrdatasets()");
1173 	result = dns_rdatasetiter_first(rdsiter);
1174 	dns_rdataset_init(&rdataset);
1175 	while (result == ISC_R_SUCCESS) {
1176 		dns_rdatasetiter_current(rdsiter, &rdataset);
1177 		/*
1178 		 * If we are not at a delegation then everything should be
1179 		 * signed.  If we are at a delegation then only the DS set
1180 		 * is signed.  The NS set is not signed at a delegation but
1181 		 * its existance is recorded in the bit map.  Anything else
1182 		 * other than NSEC and DS is not signed at a delegation.
1183 		 */
1184 		if (rdataset.type != dns_rdatatype_rrsig &&
1185 		    rdataset.type != dns_rdatatype_dnskey &&
1186 		    (!delegation || rdataset.type == dns_rdatatype_ds ||
1187 		     rdataset.type == dns_rdatatype_nsec)) {
1188 			verifyset(db, ver, origin, mctx, &rdataset,
1189 				  name, node, keyrdataset,
1190 				  act_algorithms, bad_algorithms);
1191 			dns_nsec_setbit(types, rdataset.type, 1);
1192 			if (rdataset.type > maxtype)
1193 				maxtype = rdataset.type;
1194 		} else if (rdataset.type != dns_rdatatype_rrsig &&
1195 			   rdataset.type != dns_rdatatype_dnskey) {
1196 			if (rdataset.type == dns_rdatatype_ns)
1197 				dns_nsec_setbit(types, rdataset.type, 1);
1198 			check_no_rrsig(db, ver, &rdataset, name, node);
1199 		} else
1200 			dns_nsec_setbit(types, rdataset.type, 1);
1201 		dns_rdataset_disassociate(&rdataset);
1202 		result = dns_rdatasetiter_next(rdsiter);
1203 	}
1204 	if (result != ISC_R_NOMORE)
1205 		fatal("rdataset iteration failed: %s",
1206 		      isc_result_totext(result));
1207 	dns_rdatasetiter_destroy(&rdsiter);
1208 
1209 	result = ISC_R_SUCCESS;
1210 
1211 	if (nsecset != NULL && dns_rdataset_isassociated(nsecset))
1212 		result = verifynsec(db, ver, name, node, nextname);
1213 
1214 	if (nsec3paramset != NULL && dns_rdataset_isassociated(nsec3paramset)) {
1215 		tresult = verifynsec3s(db, ver, origin, mctx, name,
1216 				       nsec3paramset, delegation, ISC_FALSE,
1217 				       types, maxtype);
1218 		if (result == ISC_R_SUCCESS && tresult != ISC_R_SUCCESS)
1219 			result = tresult;
1220 	}
1221 	return (result);
1222 }
1223 
1224 static isc_boolean_t
is_empty(dns_db_t * db,dns_dbversion_t * ver,dns_dbnode_t * node)1225 is_empty(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node) {
1226 	dns_rdatasetiter_t *rdsiter = NULL;
1227 	isc_result_t result;
1228 
1229 	result = dns_db_allrdatasets(db, node, ver, 0, &rdsiter);
1230 	check_result(result, "dns_db_allrdatasets()");
1231 	result = dns_rdatasetiter_first(rdsiter);
1232 	dns_rdatasetiter_destroy(&rdsiter);
1233 	if (result == ISC_R_NOMORE)
1234 		return (ISC_TRUE);
1235 	return (ISC_FALSE);
1236 }
1237 
1238 static void
check_no_nsec(dns_name_t * name,dns_dbnode_t * node,dns_db_t * db,dns_dbversion_t * ver)1239 check_no_nsec(dns_name_t *name, dns_dbnode_t *node, dns_db_t *db,
1240 	      dns_dbversion_t *ver)
1241 {
1242 	dns_rdataset_t rdataset;
1243 	isc_result_t result;
1244 
1245 	dns_rdataset_init(&rdataset);
1246 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
1247 				     0, 0, &rdataset, NULL);
1248 	if (result != ISC_R_NOTFOUND) {
1249 		char namebuf[DNS_NAME_FORMATSIZE];
1250 		dns_name_format(name, namebuf, sizeof(namebuf));
1251 		fatal("unexpected NSEC RRset at %s\n", namebuf);
1252 	}
1253 
1254 	if (dns_rdataset_isassociated(&rdataset))
1255 		dns_rdataset_disassociate(&rdataset);
1256 }
1257 
1258 static isc_boolean_t
newchain(const struct nsec3_chain_fixed * first,const struct nsec3_chain_fixed * e)1259 newchain(const struct nsec3_chain_fixed *first,
1260 	 const struct nsec3_chain_fixed *e)
1261 {
1262 	if (first->hash != e->hash ||
1263 	    first->iterations != e->iterations ||
1264 	    first->salt_length != e->salt_length ||
1265 	    first->next_length != e->next_length ||
1266 	    memcmp(first + 1, e + 1, first->salt_length) != 0)
1267 		return (ISC_TRUE);
1268 	return (ISC_FALSE);
1269 }
1270 
1271 static void
free_element(isc_mem_t * mctx,struct nsec3_chain_fixed * e)1272 free_element(isc_mem_t *mctx, struct nsec3_chain_fixed *e) {
1273 	size_t len;
1274 
1275 	len = sizeof(*e) + e->salt_length + 2 * e->next_length;
1276 	isc_mem_put(mctx, e, len);
1277 }
1278 
1279 static isc_boolean_t
checknext(const struct nsec3_chain_fixed * first,const struct nsec3_chain_fixed * e)1280 checknext(const struct nsec3_chain_fixed *first,
1281 	  const struct nsec3_chain_fixed *e)
1282 {
1283 	char buf[512];
1284 	const unsigned char *d1 = (const unsigned char *)(first + 1);
1285 	const unsigned char *d2 = (const unsigned char *)(e + 1);
1286 	isc_buffer_t b;
1287 	isc_region_t sr;
1288 
1289 	d1 += first->salt_length + first->next_length;
1290 	d2 += e->salt_length;
1291 
1292 	if (memcmp(d1, d2, first->next_length) == 0)
1293 		return (ISC_TRUE);
1294 
1295 	DE_CONST(d1 - first->next_length, sr.base);
1296 	sr.length = first->next_length;
1297 	isc_buffer_init(&b, buf, sizeof(buf));
1298 	isc_base32hex_totext(&sr, 1, "", &b);
1299 	fprintf(stderr, "Break in NSEC3 chain at: %.*s\n",
1300 		(int) isc_buffer_usedlength(&b), buf);
1301 
1302 	DE_CONST(d1, sr.base);
1303 	sr.length = first->next_length;
1304 	isc_buffer_init(&b, buf, sizeof(buf));
1305 	isc_base32hex_totext(&sr, 1, "", &b);
1306 	fprintf(stderr, "Expected: %.*s\n", (int) isc_buffer_usedlength(&b),
1307 		buf);
1308 
1309 	DE_CONST(d2, sr.base);
1310 	sr.length = first->next_length;
1311 	isc_buffer_init(&b, buf, sizeof(buf));
1312 	isc_base32hex_totext(&sr, 1, "", &b);
1313 	fprintf(stderr, "Found: %.*s\n", (int) isc_buffer_usedlength(&b), buf);
1314 
1315 	return (ISC_FALSE);
1316 }
1317 
1318 #define EXPECTEDANDFOUND "Expected and found NSEC3 chains not equal\n"
1319 
1320 static isc_result_t
verify_nsec3_chains(isc_mem_t * mctx)1321 verify_nsec3_chains(isc_mem_t *mctx) {
1322 	isc_result_t result = ISC_R_SUCCESS;
1323 	struct nsec3_chain_fixed *e, *f = NULL;
1324 	struct nsec3_chain_fixed *first = NULL, *prev = NULL;
1325 
1326 	while ((e = isc_heap_element(expected_chains, 1)) != NULL) {
1327 		isc_heap_delete(expected_chains, 1);
1328 		if (f == NULL)
1329 			f = isc_heap_element(found_chains, 1);
1330 		if (f != NULL) {
1331 			isc_heap_delete(found_chains, 1);
1332 
1333 			/*
1334 			 * Check that they match.
1335 			 */
1336 			if (chain_equal(e, f)) {
1337 				free_element(mctx, f);
1338 				f = NULL;
1339 			} else {
1340 				if (result == ISC_R_SUCCESS)
1341 					fprintf(stderr, EXPECTEDANDFOUND);
1342 				result = ISC_R_FAILURE;
1343 				/*
1344 				 * Attempt to resync found_chain.
1345 				 */
1346 				while (f != NULL && !chain_compare(e, f)) {
1347 					free_element(mctx, f);
1348 					f = isc_heap_element(found_chains, 1);
1349 					if (f != NULL)
1350 						isc_heap_delete(found_chains, 1);
1351 					if (f != NULL && chain_equal(e, f)) {
1352 						free_element(mctx, f);
1353 						f = NULL;
1354 						break;
1355 					}
1356 				}
1357 			}
1358 		} else if (result == ISC_R_SUCCESS) {
1359 			fprintf(stderr, EXPECTEDANDFOUND);
1360 			result = ISC_R_FAILURE;
1361 		}
1362 		if (first == NULL || newchain(first, e)) {
1363 			if (prev != NULL) {
1364 				if (!checknext(prev, first))
1365 					result = ISC_R_FAILURE;
1366 				if (prev != first)
1367 					free_element(mctx, prev);
1368 			}
1369 			if (first != NULL)
1370 				free_element(mctx, first);
1371 			prev = first = e;
1372 			continue;
1373 		}
1374 		if (!checknext(prev, e))
1375 			result = ISC_R_FAILURE;
1376 		if (prev != first)
1377 			free_element(mctx, prev);
1378 		prev = e;
1379 	}
1380 	if (prev != NULL) {
1381 		if (!checknext(prev, first))
1382 			result = ISC_R_FAILURE;
1383 		if (prev != first)
1384 			free_element(mctx, prev);
1385 	}
1386 	if (first != NULL)
1387 		free_element(mctx, first);
1388 	do {
1389 		if (f != NULL) {
1390 			if (result == ISC_R_SUCCESS) {
1391 				fprintf(stderr, EXPECTEDANDFOUND);
1392 				result = ISC_R_FAILURE;
1393 			}
1394 			free_element(mctx, f);
1395 		}
1396 		f = isc_heap_element(found_chains, 1);
1397 		if (f != NULL)
1398 			isc_heap_delete(found_chains, 1);
1399 	} while (f != NULL);
1400 
1401 	return (result);
1402 }
1403 
1404 static isc_result_t
verifyemptynodes(dns_db_t * db,dns_dbversion_t * ver,dns_name_t * origin,isc_mem_t * mctx,dns_name_t * name,dns_name_t * prevname,isc_boolean_t isdelegation,dns_rdataset_t * nsec3paramset)1405 verifyemptynodes(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
1406 		 isc_mem_t *mctx, dns_name_t *name, dns_name_t *prevname,
1407 		 isc_boolean_t isdelegation, dns_rdataset_t *nsec3paramset)
1408 {
1409 	dns_namereln_t reln;
1410 	int order;
1411 	unsigned int labels, nlabels, i;
1412 	dns_name_t suffix;
1413 	isc_result_t result = ISC_R_SUCCESS, tresult;
1414 
1415 	reln = dns_name_fullcompare(prevname, name, &order, &labels);
1416 	if (order >= 0)
1417 		return (result);
1418 
1419 	nlabels = dns_name_countlabels(name);
1420 
1421 	if (reln == dns_namereln_commonancestor ||
1422 	    reln == dns_namereln_contains) {
1423 		dns_name_init(&suffix, NULL);
1424 		for (i = labels + 1; i < nlabels; i++) {
1425 			dns_name_getlabelsequence(name, nlabels - i, i,
1426 						  &suffix);
1427 			if (nsec3paramset != NULL &&
1428 			     dns_rdataset_isassociated(nsec3paramset)) {
1429 				tresult = verifynsec3s(db, ver, origin, mctx,
1430 						       &suffix, nsec3paramset,
1431 						       isdelegation, ISC_TRUE,
1432 						       NULL, 0);
1433 				if (result == ISC_R_SUCCESS &&
1434 				    tresult != ISC_R_SUCCESS)
1435 					result = tresult;
1436 			}
1437 		}
1438 	}
1439 	return (result);
1440 }
1441 
1442 /*%
1443  * Verify that certain things are sane:
1444  *
1445  *   The apex has a DNSKEY record with at least one KSK, and at least
1446  *   one ZSK if the -x flag was not used.
1447  *
1448  *   The DNSKEY record was signed with at least one of the KSKs in this
1449  *   set.
1450  *
1451  *   The rest of the zone was signed with at least one of the ZSKs
1452  *   present in the DNSKEY RRSET.
1453  */
1454 void
verifyzone(dns_db_t * db,dns_dbversion_t * ver,dns_name_t * origin,isc_mem_t * mctx,isc_boolean_t ignore_kskflag,isc_boolean_t keyset_kskonly)1455 verifyzone(dns_db_t *db, dns_dbversion_t *ver,
1456 	   dns_name_t *origin, isc_mem_t *mctx,
1457 	   isc_boolean_t ignore_kskflag, isc_boolean_t keyset_kskonly)
1458 {
1459 	char algbuf[80];
1460 	dns_dbiterator_t *dbiter = NULL;
1461 	dns_dbnode_t *node = NULL, *nextnode = NULL;
1462 	dns_fixedname_t fname, fnextname, fprevname, fzonecut;
1463 	dns_name_t *name, *nextname, *prevname, *zonecut;
1464 	dns_rdata_dnskey_t dnskey;
1465 	dns_rdata_t rdata = DNS_RDATA_INIT;
1466 	dns_rdataset_t keyset, soaset;
1467 	dns_rdataset_t keysigs, soasigs;
1468 	dns_rdataset_t nsecset, nsecsigs;
1469 	dns_rdataset_t nsec3paramset, nsec3paramsigs;
1470 	int i;
1471 	isc_boolean_t done = ISC_FALSE;
1472 	isc_boolean_t first = ISC_TRUE;
1473 	isc_boolean_t goodksk = ISC_FALSE;
1474 	isc_boolean_t goodzsk = ISC_FALSE;
1475 	isc_result_t result, vresult = ISC_R_UNSET;
1476 	unsigned char revoked_ksk[256];
1477 	unsigned char revoked_zsk[256];
1478 	unsigned char standby_ksk[256];
1479 	unsigned char standby_zsk[256];
1480 	unsigned char ksk_algorithms[256];
1481 	unsigned char zsk_algorithms[256];
1482 	unsigned char bad_algorithms[256];
1483 	unsigned char act_algorithms[256];
1484 
1485 	result = isc_heap_create(mctx, chain_compare, NULL, 1024,
1486 				 &expected_chains);
1487 	check_result(result, "isc_heap_create()");
1488 	result = isc_heap_create(mctx, chain_compare, NULL, 1024,
1489 				 &found_chains);
1490 	check_result(result, "isc_heap_create()");
1491 
1492 	result = dns_db_findnode(db, origin, ISC_FALSE, &node);
1493 	if (result != ISC_R_SUCCESS)
1494 		fatal("failed to find the zone's origin: %s",
1495 		      isc_result_totext(result));
1496 
1497 	dns_rdataset_init(&keyset);
1498 	dns_rdataset_init(&keysigs);
1499 	dns_rdataset_init(&soaset);
1500 	dns_rdataset_init(&soasigs);
1501 	dns_rdataset_init(&nsecset);
1502 	dns_rdataset_init(&nsecsigs);
1503 	dns_rdataset_init(&nsec3paramset);
1504 	dns_rdataset_init(&nsec3paramsigs);
1505 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
1506 				     0, 0, &keyset, &keysigs);
1507 	if (result != ISC_R_SUCCESS)
1508 		fatal("Zone contains no DNSSEC keys\n");
1509 
1510 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
1511 				     0, 0, &soaset, &soasigs);
1512 	if (result != ISC_R_SUCCESS)
1513 		fatal("Zone contains no SOA record\n");
1514 
1515 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
1516 				     0, 0, &nsecset, &nsecsigs);
1517 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
1518 		fatal("NSEC lookup failed\n");
1519 
1520 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
1521 				     0, 0, &nsec3paramset, &nsec3paramsigs);
1522 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
1523 		fatal("NSEC3PARAM lookup failed\n");
1524 
1525 	if (!dns_rdataset_isassociated(&keysigs))
1526 		fatal("DNSKEY is not signed (keys offline or inactive?)\n");
1527 
1528 	if (!dns_rdataset_isassociated(&soasigs))
1529 		fatal("SOA is not signed (keys offline or inactive?)\n");
1530 
1531 	if (dns_rdataset_isassociated(&nsecset) &&
1532 	    !dns_rdataset_isassociated(&nsecsigs))
1533 		fatal("NSEC is not signed (keys offline or inactive?)\n");
1534 
1535 	if (dns_rdataset_isassociated(&nsec3paramset) &&
1536 	    !dns_rdataset_isassociated(&nsec3paramsigs))
1537 		fatal("NSEC3PARAM is not signed (keys offline or inactive?)\n");
1538 
1539 	if (!dns_rdataset_isassociated(&nsecset) &&
1540 	    !dns_rdataset_isassociated(&nsec3paramset))
1541 		fatal("No valid NSEC/NSEC3 chain for testing\n");
1542 
1543 	dns_db_detachnode(db, &node);
1544 
1545 	memset(revoked_ksk, 0, sizeof(revoked_ksk));
1546 	memset(revoked_zsk, 0, sizeof(revoked_zsk));
1547 	memset(standby_ksk, 0, sizeof(standby_ksk));
1548 	memset(standby_zsk, 0, sizeof(standby_zsk));
1549 	memset(ksk_algorithms, 0, sizeof(ksk_algorithms));
1550 	memset(zsk_algorithms, 0, sizeof(zsk_algorithms));
1551 	memset(bad_algorithms, 0, sizeof(bad_algorithms));
1552 	memset(act_algorithms, 0, sizeof(act_algorithms));
1553 
1554 	/*
1555 	 * Check that the DNSKEY RR has at least one self signing KSK
1556 	 * and one ZSK per algorithm in it (or, if -x was used, one
1557 	 * self-signing KSK).
1558 	 */
1559 	for (result = dns_rdataset_first(&keyset);
1560 	     result == ISC_R_SUCCESS;
1561 	     result = dns_rdataset_next(&keyset)) {
1562 		dns_rdataset_current(&keyset, &rdata);
1563 		result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
1564 		check_result(result, "dns_rdata_tostruct");
1565 
1566 		if ((dnskey.flags & DNS_KEYOWNER_ZONE) == 0)
1567 			;
1568 		else if ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0) {
1569 			if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 &&
1570 			    !dns_dnssec_selfsigns(&rdata, origin, &keyset,
1571 						  &keysigs, ISC_FALSE,
1572 						  mctx)) {
1573 				char namebuf[DNS_NAME_FORMATSIZE];
1574 				char buffer[1024];
1575 				isc_buffer_t buf;
1576 
1577 				dns_name_format(origin, namebuf,
1578 						sizeof(namebuf));
1579 				isc_buffer_init(&buf, buffer, sizeof(buffer));
1580 				result = dns_rdata_totext(&rdata, NULL, &buf);
1581 				check_result(result, "dns_rdata_totext");
1582 				fatal("revoked KSK is not self signed:\n"
1583 				      "%s DNSKEY %.*s", namebuf,
1584 				      (int)isc_buffer_usedlength(&buf), buffer);
1585 			}
1586 			if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 &&
1587 			     revoked_ksk[dnskey.algorithm] != 255)
1588 				revoked_ksk[dnskey.algorithm]++;
1589 			else if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0 &&
1590 				 revoked_zsk[dnskey.algorithm] != 255)
1591 				revoked_zsk[dnskey.algorithm]++;
1592 		} else if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0) {
1593 			if (dns_dnssec_selfsigns(&rdata, origin, &keyset,
1594 						 &keysigs, ISC_FALSE, mctx)) {
1595 				if (ksk_algorithms[dnskey.algorithm] != 255)
1596 					ksk_algorithms[dnskey.algorithm]++;
1597 				goodksk = ISC_TRUE;
1598 			} else {
1599 				if (standby_ksk[dnskey.algorithm] != 255)
1600 					standby_ksk[dnskey.algorithm]++;
1601 			}
1602 		} else if (dns_dnssec_selfsigns(&rdata, origin, &keyset,
1603 						&keysigs, ISC_FALSE, mctx)) {
1604 			if (zsk_algorithms[dnskey.algorithm] != 255)
1605 				zsk_algorithms[dnskey.algorithm]++;
1606 			goodzsk = ISC_TRUE;
1607 		} else if (dns_dnssec_signs(&rdata, origin, &soaset,
1608 					    &soasigs, ISC_FALSE, mctx)) {
1609 			if (zsk_algorithms[dnskey.algorithm] != 255)
1610 				zsk_algorithms[dnskey.algorithm]++;
1611 		} else {
1612 			if (standby_zsk[dnskey.algorithm] != 255)
1613 				standby_zsk[dnskey.algorithm]++;
1614 		}
1615 		dns_rdata_freestruct(&dnskey);
1616 		dns_rdata_reset(&rdata);
1617 	}
1618 	dns_rdataset_disassociate(&keysigs);
1619 	dns_rdataset_disassociate(&soaset);
1620 	dns_rdataset_disassociate(&soasigs);
1621 	if (dns_rdataset_isassociated(&nsecsigs))
1622 		dns_rdataset_disassociate(&nsecsigs);
1623 	if (dns_rdataset_isassociated(&nsec3paramsigs))
1624 		dns_rdataset_disassociate(&nsec3paramsigs);
1625 
1626 	if (ignore_kskflag ) {
1627 		if (!goodksk && !goodzsk)
1628 			fatal("No self-signed DNSKEY found.");
1629 	} else if (!goodksk)
1630 		fatal("No self-signed KSK DNSKEY found.  Supply an active\n"
1631 		      "key with the KSK flag set, or use '-P'.");
1632 
1633 	fprintf(stderr, "Verifying the zone using the following algorithms:");
1634 	for (i = 0; i < 256; i++) {
1635 		if (ignore_kskflag)
1636 			act_algorithms[i] = (ksk_algorithms[i] != 0 ||
1637 					     zsk_algorithms[i] != 0) ? 1 : 0;
1638 		else
1639 			act_algorithms[i] = ksk_algorithms[i] != 0 ? 1 : 0;
1640 		if (act_algorithms[i] != 0) {
1641 			dns_secalg_format(i, algbuf, sizeof(algbuf));
1642 			fprintf(stderr, " %s", algbuf);
1643 		}
1644 	}
1645 	fprintf(stderr, ".\n");
1646 
1647 	if (!ignore_kskflag && !keyset_kskonly) {
1648 		for (i = 0; i < 256; i++) {
1649 			/*
1650 			 * The counts should both be zero or both be non-zero.
1651 			 * Mark the algorithm as bad if this is not met.
1652 			 */
1653 			if ((ksk_algorithms[i] != 0) ==
1654 			    (zsk_algorithms[i] != 0))
1655 				continue;
1656 			dns_secalg_format(i, algbuf, sizeof(algbuf));
1657 			fprintf(stderr, "Missing %s for algorithm %s\n",
1658 				(ksk_algorithms[i] != 0)
1659 				   ? "ZSK"
1660 				   : "self-signed KSK",
1661 				algbuf);
1662 			bad_algorithms[i] = 1;
1663 		}
1664 	}
1665 
1666 	/*
1667 	 * Check that all the other records were signed by keys that are
1668 	 * present in the DNSKEY RRSET.
1669 	 */
1670 
1671 	dns_fixedname_init(&fname);
1672 	name = dns_fixedname_name(&fname);
1673 	dns_fixedname_init(&fnextname);
1674 	nextname = dns_fixedname_name(&fnextname);
1675 	dns_fixedname_init(&fprevname);
1676 	prevname = NULL;
1677 	dns_fixedname_init(&fzonecut);
1678 	zonecut = NULL;
1679 
1680 	result = dns_db_createiterator(db, DNS_DB_NONSEC3, &dbiter);
1681 	check_result(result, "dns_db_createiterator()");
1682 
1683 	result = dns_dbiterator_first(dbiter);
1684 	check_result(result, "dns_dbiterator_first()");
1685 
1686 	while (!done) {
1687 		isc_boolean_t isdelegation = ISC_FALSE;
1688 
1689 		result = dns_dbiterator_current(dbiter, &node, name);
1690 		check_dns_dbiterator_current(result);
1691 		if (!dns_name_issubdomain(name, origin)) {
1692 			check_no_nsec(name, node, db, ver);
1693 			dns_db_detachnode(db, &node);
1694 			result = dns_dbiterator_next(dbiter);
1695 			if (result == ISC_R_NOMORE)
1696 				done = ISC_TRUE;
1697 			else
1698 				check_result(result, "dns_dbiterator_next()");
1699 			continue;
1700 		}
1701 		if (is_delegation(db, ver, origin, name, node, NULL)) {
1702 			zonecut = dns_fixedname_name(&fzonecut);
1703 			dns_name_copy(name, zonecut, NULL);
1704 			isdelegation = ISC_TRUE;
1705 		}
1706 		nextnode = NULL;
1707 		result = dns_dbiterator_next(dbiter);
1708 		while (result == ISC_R_SUCCESS) {
1709 			result = dns_dbiterator_current(dbiter, &nextnode,
1710 							nextname);
1711 			check_dns_dbiterator_current(result);
1712 			if (!dns_name_issubdomain(nextname, origin) ||
1713 			    (zonecut != NULL &&
1714 			     dns_name_issubdomain(nextname, zonecut)))
1715 			{
1716 				check_no_nsec(nextname, nextnode, db, ver);
1717 				dns_db_detachnode(db, &nextnode);
1718 				result = dns_dbiterator_next(dbiter);
1719 				continue;
1720 			}
1721 			if (is_empty(db, ver, nextnode)) {
1722 				dns_db_detachnode(db, &nextnode);
1723 				result = dns_dbiterator_next(dbiter);
1724 				continue;
1725 			}
1726 			dns_db_detachnode(db, &nextnode);
1727 			break;
1728 		}
1729 		if (result == ISC_R_NOMORE) {
1730 			done = ISC_TRUE;
1731 			nextname = origin;
1732 		} else if (result != ISC_R_SUCCESS)
1733 			fatal("iterating through the database failed: %s",
1734 			      isc_result_totext(result));
1735 		result = verifynode(db, ver, origin, mctx, name, node,
1736 				    isdelegation, &keyset, act_algorithms,
1737 				    bad_algorithms, &nsecset, &nsec3paramset,
1738 				    nextname);
1739 		if (vresult == ISC_R_UNSET)
1740 			vresult = ISC_R_SUCCESS;
1741 		if (vresult == ISC_R_SUCCESS && result != ISC_R_SUCCESS)
1742 			vresult = result;
1743 		if (prevname != NULL) {
1744 			result = verifyemptynodes(db, ver, origin, mctx, name,
1745 						  prevname, isdelegation,
1746 						  &nsec3paramset);
1747 		} else
1748 			prevname = dns_fixedname_name(&fprevname);
1749 		dns_name_copy(name, prevname, NULL);
1750 		if (vresult == ISC_R_SUCCESS && result != ISC_R_SUCCESS)
1751 			vresult = result;
1752 		dns_db_detachnode(db, &node);
1753 	}
1754 
1755 	dns_dbiterator_destroy(&dbiter);
1756 
1757 	result = dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbiter);
1758 	check_result(result, "dns_db_createiterator()");
1759 
1760 	for (result = dns_dbiterator_first(dbiter);
1761 	     result == ISC_R_SUCCESS;
1762 	     result = dns_dbiterator_next(dbiter) ) {
1763 		result = dns_dbiterator_current(dbiter, &node, name);
1764 		check_dns_dbiterator_current(result);
1765 		result = verifynode(db, ver, origin, mctx, name, node,
1766 				    ISC_FALSE, &keyset, act_algorithms,
1767 				    bad_algorithms, NULL, NULL, NULL);
1768 		check_result(result, "verifynode");
1769 		record_found(db, ver, mctx, name, node, &nsec3paramset);
1770 		dns_db_detachnode(db, &node);
1771 	}
1772 	dns_dbiterator_destroy(&dbiter);
1773 
1774 	dns_rdataset_disassociate(&keyset);
1775 	if (dns_rdataset_isassociated(&nsecset))
1776 		dns_rdataset_disassociate(&nsecset);
1777 	if (dns_rdataset_isassociated(&nsec3paramset))
1778 		dns_rdataset_disassociate(&nsec3paramset);
1779 
1780 	result = verify_nsec3_chains(mctx);
1781 	if (vresult == ISC_R_UNSET)
1782 		vresult = ISC_R_SUCCESS;
1783 	if (result != ISC_R_SUCCESS && vresult == ISC_R_SUCCESS)
1784 		vresult = result;
1785 	isc_heap_destroy(&expected_chains);
1786 	isc_heap_destroy(&found_chains);
1787 
1788 	/*
1789 	 * If we made it this far, we have what we consider a properly signed
1790 	 * zone.  Set the good flag.
1791 	 */
1792 	for (i = 0; i < 256; i++) {
1793 		if (bad_algorithms[i] != 0) {
1794 			if (first)
1795 				fprintf(stderr, "The zone is not fully signed "
1796 					"for the following algorithms:");
1797 			dns_secalg_format(i, algbuf, sizeof(algbuf));
1798 			fprintf(stderr, " %s", algbuf);
1799 			first = ISC_FALSE;
1800 		}
1801 	}
1802 	if (!first) {
1803 		fprintf(stderr, ".\n");
1804 		fatal("DNSSEC completeness test failed.");
1805 	}
1806 
1807 	if (vresult != ISC_R_SUCCESS)
1808 		fatal("DNSSEC completeness test failed (%s).",
1809 		      dns_result_totext(vresult));
1810 
1811 	if (goodksk || ignore_kskflag) {
1812 		/*
1813 		 * Print the success summary.
1814 		 */
1815 		fprintf(stderr, "Zone fully signed:\n");
1816 		for (i = 0; i < 256; i++) {
1817 			if ((ksk_algorithms[i] != 0) ||
1818 			    (standby_ksk[i] != 0) ||
1819 			    (revoked_zsk[i] != 0) ||
1820 			    (zsk_algorithms[i] != 0) ||
1821 			    (standby_zsk[i] != 0) ||
1822 			    (revoked_zsk[i] != 0)) {
1823 				dns_secalg_format(i, algbuf, sizeof(algbuf));
1824 				fprintf(stderr, "Algorithm: %s: KSKs: "
1825 					"%u active, %u stand-by, %u revoked\n",
1826 					algbuf, ksk_algorithms[i],
1827 					standby_ksk[i], revoked_ksk[i]);
1828 				fprintf(stderr, "%*sZSKs: "
1829 					"%u active, %u %s, %u revoked\n",
1830 					(int) strlen(algbuf) + 13, "",
1831 					zsk_algorithms[i],
1832 					standby_zsk[i],
1833 					keyset_kskonly ? "present" : "stand-by",
1834 					revoked_zsk[i]);
1835 			}
1836 		}
1837 	}
1838 }
1839