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