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