2 * Copyright (C) 2004, 2005, 2007, 2009-2015 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
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.
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.
21 * DNSSEC Support Routines.
28 #include <isc/base32.h>
29 #include <isc/buffer.h>
31 #include <isc/entropy.h>
35 #include <isc/string.h>
38 #include <isc/print.h>
41 #include <dns/dbiterator.h>
42 #include <dns/dnssec.h>
43 #include <dns/fixedname.h>
44 #include <dns/keyvalues.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>
58 #include "dnssectool.h"
60 static isc_heap_t *expected_chains, *found_chains;
62 struct nsec3_chain_fixed {
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]; */
73 extern const char *program;
75 typedef struct entropysource entropysource_t;
77 struct entropysource {
78 isc_entropysource_t *source;
80 ISC_LINK(entropysource_t) link;
83 static ISC_LIST(entropysource_t) sources;
84 static fatalcallback_t *fatalcallback = NULL;
87 fatal(const char *format, ...) {
90 fprintf(stderr, "%s: fatal: ", program);
91 va_start(args, format);
92 vfprintf(stderr, format, args);
94 fprintf(stderr, "\n");
95 if (fatalcallback != NULL)
101 setfatalcallback(fatalcallback_t *callback) {
102 fatalcallback = callback;
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));
112 vbprintf(int level, const char *fmt, ...) {
117 fprintf(stderr, "%s: ", program);
118 vfprintf(stderr, fmt, ap);
123 version(const char *name) {
124 fprintf(stderr, "%s %s\n", name, VERSION);
129 type_format(const dns_rdatatype_t type, char *cp, unsigned int size) {
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;
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];
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);
152 setup_logging(isc_mem_t *mctx, isc_log_t **logp) {
154 isc_logdestination_t destination;
155 isc_logconfig_t *logconfig = NULL;
156 isc_log_t *log = NULL;
164 * We want to see warnings about things like out-of-zone
165 * data in the master file even when not verbose.
167 level = ISC_LOG_WARNING;
170 level = ISC_LOG_INFO;
173 level = ISC_LOG_DEBUG(verbose - 2 + 1);
177 RUNTIME_CHECK(isc_log_create(mctx, &log, &logconfig) == ISC_R_SUCCESS);
178 isc_log_setcontext(log);
180 dns_log_setcontext(log);
182 RUNTIME_CHECK(isc_log_settag(logconfig, program) == ISC_R_SUCCESS);
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
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",
198 ISC_LOG_PRINTTAG|ISC_LOG_PRINTLEVEL);
199 check_result(result, "isc_log_createchannel()");
201 RUNTIME_CHECK(isc_log_usechannel(logconfig, "stderr",
202 NULL, NULL) == ISC_R_SUCCESS);
208 cleanup_logging(isc_log_t **logp) {
211 REQUIRE(logp != NULL);
216 isc_log_destroy(&log);
217 isc_log_setcontext(NULL);
218 dns_log_setcontext(NULL);
223 setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx) {
225 isc_entropysource_t *source = NULL;
226 entropysource_t *elt;
227 int usekeyboard = ISC_ENTROPY_KEYBOARDMAYBE;
229 REQUIRE(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);
238 if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) {
239 usekeyboard = ISC_ENTROPY_KEYBOARDYES;
243 result = isc_entropy_usebestsource(*ectx, &source, randomfile,
246 if (result != ISC_R_SUCCESS)
247 fatal("could not initialize entropy source: %s",
248 isc_result_totext(result));
250 if (source != NULL) {
251 elt = isc_mem_get(mctx, sizeof(*elt));
253 fatal("out of memory");
254 elt->source = source;
256 ISC_LINK_INIT(elt, link);
257 ISC_LIST_APPEND(sources, elt, link);
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));
270 isc_entropy_detach(ectx);
274 time_units(isc_stdtime_t offset, char *suffix, const char *str) {
277 return (offset * (365 * 24 * 3600));
281 return (offset * (30 * 24 * 3600));
283 return (offset * 60);
285 fatal("'%s' ambiguous: use 'mi' for minutes "
286 "or 'mo' for months", str);
288 fatal("time value %s is invalid", str);
293 return (offset * (7 * 24 * 3600));
295 return (offset * (24 * 3600));
297 return (offset * 3600);
298 case 'S': case 's': case '\0':
301 fatal("time value %s is invalid", str);
304 return(0); /* silence compiler warning */
307 static inline isc_boolean_t
308 isnone(const char *str) {
309 return (ISC_TF((strcasecmp(str, "none") == 0) ||
310 (strcasecmp(str, "never") == 0)));
314 strtottl(const char *str) {
315 const char *orig = str;
320 return ((dns_ttl_t) 0);
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);
330 strtotime(const char *str, isc_int64_t now, isc_int64_t base,
333 isc_int64_t val, offset;
335 const char *orig = str;
342 return ((isc_stdtime_t) 0);
348 if ((str[0] == '0' || str[0] == '-') && str[1] == '\0')
349 return ((isc_stdtime_t) 0);
352 * We accept times in the following formats:
354 * YYYYMMDD([+-]offset)
355 * YYYYMMDDhhmmss([+-]offset)
358 n = strspn(str, "0123456789");
359 if ((n == 8u || n == 14u) &&
360 (str[n] == '\0' || str[n] == '-' || str[n] == '+'))
364 strlcpy(timestr, str, sizeof(timestr));
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));
374 } else if (strncmp(str, "now", 3) == 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);
385 } else if (str[0] == '-') {
386 offset = strtol(str + 1, &endp, 0);
387 offset = time_units((isc_stdtime_t) offset, endp, orig);
390 fatal("time value %s is invalid", orig);
392 return ((isc_stdtime_t) val);
396 strtoclass(const char *str) {
398 dns_rdataclass_t rdclass;
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);
412 try_dir(const char *dirname) {
417 result = isc_dir_open(&d, dirname);
418 if (result == ISC_R_SUCCESS) {
425 * Check private key version compatibility.
428 check_keyversion(dst_key_t *key, char *keystr) {
430 dst_key_getprivateformat(key, &major, &minor);
431 INSIST(major <= DST_MAJOR_VERSION); /* invalid private key */
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);
444 set_keyversion(dst_key_t *key) {
446 dst_key_getprivateformat(key, &major, &minor);
447 INSIST(major <= DST_MAJOR_VERSION);
449 if (major != DST_MAJOR_VERSION || minor != DST_MINOR_VERSION)
450 dst_key_setprivateformat(key, DST_MAJOR_VERSION,
454 * If the key is from a version older than 1.3, set
455 * set the creation date
457 if (major < 1 || (major == 1 && minor <= 2)) {
459 isc_stdtime_get(&now);
460 dst_key_settime(key, DST_TIME_CREATED, now);
465 key_collision(dst_key_t *dstkey, dns_name_t *name, const char *dir,
466 isc_mem_t *mctx, isc_boolean_t *exact)
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;
479 id = dst_key_id(dstkey);
480 rid = dst_key_rid(dstkey);
481 alg = dst_key_alg(dstkey);
483 ISC_LIST_INIT(matchkeys);
484 result = dns_dnssec_findmatchingkeys(name, dir, mctx, &matchkeys);
485 if (result == ISC_R_NOTFOUND)
488 while (!ISC_LIST_EMPTY(matchkeys) && !conflict) {
489 key = ISC_LIST_HEAD(matchkeys);
490 if (dst_key_alg(key->key) != alg)
493 oldid = dst_key_id(key->key);
494 roldid = dst_key_rid(key->key);
496 if (oldid == rid || roldid == id || id == oldid) {
500 fprintf(stderr, "Key ID %d could "
507 fprintf(stderr, "Key ID %d exists\n",
513 ISC_LIST_UNLINK(matchkeys, key, link);
514 dns_dnsseckey_destroy(mctx, &key);
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);
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)
531 dns_rdataset_t nsset;
534 if (dns_name_equal(name, origin))
537 dns_rdataset_init(&nsset);
538 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_ns,
540 if (dns_rdataset_isassociated(&nsset)) {
543 dns_rdataset_disassociate(&nsset);
546 return (ISC_TF(result == ISC_R_SUCCESS));
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)
553 dns_rdata_dnskey_t key;
554 dns_rdata_rrsig_t sig;
555 dst_key_t *dstkey = NULL;
558 result = dns_rdata_tostruct(sigrdata, &sig, NULL);
559 check_result(result, "dns_rdata_tostruct()");
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,
570 if (result != ISC_R_SUCCESS)
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);
578 result = dns_dnssec_verify(name, rdataset, dstkey, ISC_FALSE,
580 dst_key_free(&dstkey);
581 if (result == ISC_R_SUCCESS)
588 verifynsec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
589 dns_dbnode_t *node, dns_name_t *nextname)
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;
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);
610 result = dns_rdataset_first(&rdataset);
611 check_result(result, "dns_rdataset_first()");
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,
626 /* Check bit map is consistent */
627 result = dns_nsec_buildrdata(db, ver, node, nextname, buffer,
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);
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);
643 dns_rdataset_disassociate(&rdataset);
644 return (ISC_R_SUCCESS);
646 if (dns_rdataset_isassociated(&rdataset))
647 dns_rdataset_disassociate(&rdataset);
648 return (ISC_R_FAILURE);
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)
655 char namebuf[DNS_NAME_FORMATSIZE];
657 dns_rdataset_t sigrdataset;
658 dns_rdatasetiter_t *rdsiter = NULL;
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)
671 dns_rdataset_disassociate(&sigrdataset);
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);
679 if (dns_rdataset_isassociated(&sigrdataset))
680 dns_rdataset_disassociate(&sigrdataset);
681 dns_rdatasetiter_destroy(&rdsiter);
685 chain_compare(void *arg1, void *arg2) {
686 struct nsec3_chain_fixed *e1 = arg1, *e2 = arg2;
690 * Do each element in turn to get a stable sort.
692 if (e1->hash < e2->hash)
694 if (e1->hash > e2->hash)
696 if (e1->iterations < e2->iterations)
698 if (e1->iterations > e2->iterations)
700 if (e1->salt_length < e2->salt_length)
702 if (e1->salt_length > e2->salt_length)
704 if (e1->next_length < e2->next_length)
706 if (e1->next_length > e2->next_length)
708 len = e1->salt_length + 2 * e1->next_length;
709 if (memcmp(e1 + 1, e2 + 1, len) < 0)
715 chain_equal(struct nsec3_chain_fixed *e1, struct nsec3_chain_fixed *e2) {
718 if (e1->hash != e2->hash)
720 if (e1->iterations != e2->iterations)
722 if (e1->salt_length != e2->salt_length)
724 if (e1->next_length != e2->next_length)
726 len = e1->salt_length + 2 * e1->next_length;
727 if (memcmp(e1 + 1, e2 + 1, len) != 0)
733 record_nsec3(const unsigned char *rawhash, const dns_rdata_nsec3_t *nsec3,
734 isc_mem_t *mctx, isc_heap_t *chains)
736 struct nsec3_chain_fixed *element;
741 len = sizeof(*element) + nsec3->next_length * 2 + nsec3->salt_length;
743 element = isc_mem_get(mctx, len);
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);
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)
772 unsigned char cbm[8244];
773 char namebuf[DNS_NAME_FORMATSIZE];
774 dns_rdata_nsec3_t nsec3;
779 * Find matching NSEC3 record.
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)
796 if (result != ISC_R_SUCCESS) {
797 dns_name_format(name, namebuf, sizeof(namebuf));
798 fprintf(stderr, "Missing NSEC3 record for %s\n", namebuf);
803 * Check the type list.
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);
816 result = record_nsec3(rawhash, &nsec3, mctx, expected_chains);
817 check_result(result, "record_nsec3()");
820 * Make sure there is only one NSEC3 record with this set of
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;
842 if (result != ISC_R_NOMORE)
845 result = ISC_R_SUCCESS;
850 innsec3params(dns_rdata_nsec3_t *nsec3, dns_rdataset_t *nsec3paramset) {
851 dns_rdata_nsec3param_t nsec3param;
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;
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)
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)
878 unsigned char owner[NSEC3_MAX_HASH_LENGTH];
879 dns_rdata_nsec3_t nsec3;
880 dns_rdataset_t rdataset;
881 dns_label_t hashlabel;
885 if (nsec3paramset == NULL || !dns_rdataset_isassociated(nsec3paramset))
886 return (ISC_R_SUCCESS);
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);
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)
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))
911 * We only care about NSEC3 records that match a NSEC3PARAM
914 if (!innsec3params(&nsec3, nsec3paramset))
920 result = record_nsec3(owner, &nsec3, mctx, found_chains);
921 check_result(result, "record_nsec3()");
925 dns_rdataset_disassociate(&rdataset);
926 return (ISC_R_SUCCESS);
930 isoptout(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
931 dns_rdata_t *nsec3rdata)
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;
940 dns_dbnode_t *node = NULL;
941 unsigned char rawhash[NSEC3_MAX_HASH_LENGTH];
942 size_t rhsize = sizeof(rawhash);
945 result = dns_rdata_tostruct(nsec3rdata, &nsec3param, NULL);
946 check_result(result, "dns_rdata_tostruct()");
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()");
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)
963 result = dns_rdataset_first(&rdataset);
964 check_result(result, "dns_rdataset_first()");
966 dns_rdataset_current(&rdataset, &rdata);
968 result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
969 if (result != ISC_R_SUCCESS)
972 ret = ISC_TF((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0);
974 if (dns_rdataset_isassociated(&rdataset))
975 dns_rdataset_disassociate(&rdataset);
977 dns_db_detachnode(db, &node);
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)
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;
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;
1000 result = dns_rdata_tostruct(rdata, &nsec3param, NULL);
1001 check_result(result, "dns_rdata_tostruct()");
1003 if (nsec3param.flags != 0)
1004 return (ISC_R_SUCCESS);
1006 if (!dns_nsec3_supportedhash(nsec3param.hash))
1007 return (ISC_R_SUCCESS);
1009 optout = isoptout(db, ver, origin, rdata);
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()");
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
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))))
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",
1037 } else if (result == ISC_R_NOTFOUND &&
1038 delegation && (!empty || optout))
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);
1046 if (dns_rdataset_isassociated(&rdataset))
1047 dns_rdataset_disassociate(&rdataset);
1049 dns_db_detachnode(db, &node);
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)
1060 isc_result_t result;
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;
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)
1073 if (result == ISC_R_NOMORE)
1074 result = ISC_R_SUCCESS;
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)
1084 unsigned char set_algorithms[256];
1085 char namebuf[DNS_NAME_FORMATSIZE];
1088 dns_rdataset_t sigrdataset;
1089 dns_rdatasetiter_t *rdsiter = NULL;
1090 isc_result_t result;
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)
1103 dns_rdataset_disassociate(&sigrdataset);
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);
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;
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);
1133 if ((set_algorithms[sig.algorithm] != 0) ||
1134 (act_algorithms[sig.algorithm] == 0))
1136 if (goodsig(origin, &rdata, name, keyrdataset, rdataset, mctx))
1137 set_algorithms[sig.algorithm] = 1;
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;
1152 dns_rdataset_disassociate(&sigrdataset);
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)
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;
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);
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.
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);
1198 dns_nsec_setbit(types, rdataset.type, 1);
1199 dns_rdataset_disassociate(&rdataset);
1200 result = dns_rdatasetiter_next(rdsiter);
1202 if (result != ISC_R_NOMORE)
1203 fatal("rdataset iteration failed: %s",
1204 isc_result_totext(result));
1205 dns_rdatasetiter_destroy(&rdsiter);
1207 result = ISC_R_SUCCESS;
1209 if (nsecset != NULL && dns_rdataset_isassociated(nsecset))
1210 result = verifynsec(db, ver, name, node, nextname);
1212 if (nsec3paramset != NULL && dns_rdataset_isassociated(nsec3paramset)) {
1213 tresult = verifynsec3s(db, ver, origin, mctx, name,
1214 nsec3paramset, delegation, ISC_FALSE,
1216 if (result == ISC_R_SUCCESS && tresult != ISC_R_SUCCESS)
1222 static isc_boolean_t
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;
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)
1237 check_no_nsec(dns_name_t *name, dns_dbnode_t *node, dns_db_t *db,
1238 dns_dbversion_t *ver)
1240 dns_rdataset_t rdataset;
1241 isc_result_t result;
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);
1252 if (dns_rdataset_isassociated(&rdataset))
1253 dns_rdataset_disassociate(&rdataset);
1256 static isc_boolean_t
1257 newchain(const struct nsec3_chain_fixed *first,
1258 const struct nsec3_chain_fixed *e)
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)
1270 free_element(isc_mem_t *mctx, struct nsec3_chain_fixed *e) {
1273 len = sizeof(*e) + e->salt_length + 2 * e->next_length;
1274 isc_mem_put(mctx, e, len);
1277 static isc_boolean_t
1278 checknext(const struct nsec3_chain_fixed *first,
1279 const struct nsec3_chain_fixed *e)
1282 const unsigned char *d1 = (const unsigned char *)(first + 1);
1283 const unsigned char *d2 = (const unsigned char *)(e + 1);
1287 d1 += first->salt_length + first->next_length;
1288 d2 += e->salt_length;
1290 if (memcmp(d1, d2, first->next_length) == 0)
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);
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),
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);
1316 #define EXPECTEDANDFOUND "Expected and found NSEC3 chains not equal\n"
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;
1324 while ((e = isc_heap_element(expected_chains, 1)) != NULL) {
1325 isc_heap_delete(expected_chains, 1);
1327 f = isc_heap_element(found_chains, 1);
1329 isc_heap_delete(found_chains, 1);
1332 * Check that they match.
1334 if (chain_equal(e, f)) {
1335 free_element(mctx, f);
1338 if (result == ISC_R_SUCCESS)
1339 fprintf(stderr, EXPECTEDANDFOUND);
1340 result = ISC_R_FAILURE;
1342 * Attempt to resync found_chain.
1344 while (f != NULL && !chain_compare(e, f)) {
1345 free_element(mctx, f);
1346 f = isc_heap_element(found_chains, 1);
1348 isc_heap_delete(found_chains, 1);
1349 if (f != NULL && chain_equal(e, f)) {
1350 free_element(mctx, f);
1356 } else if (result == ISC_R_SUCCESS) {
1357 fprintf(stderr, EXPECTEDANDFOUND);
1358 result = ISC_R_FAILURE;
1360 if (first == NULL || newchain(first, e)) {
1362 if (!checknext(prev, first))
1363 result = ISC_R_FAILURE;
1365 free_element(mctx, prev);
1368 free_element(mctx, first);
1372 if (!checknext(prev, e))
1373 result = ISC_R_FAILURE;
1375 free_element(mctx, prev);
1379 if (!checknext(prev, first))
1380 result = ISC_R_FAILURE;
1382 free_element(mctx, prev);
1385 free_element(mctx, first);
1388 if (result == ISC_R_SUCCESS) {
1389 fprintf(stderr, EXPECTEDANDFOUND);
1390 result = ISC_R_FAILURE;
1392 free_element(mctx, f);
1394 f = isc_heap_element(found_chains, 1);
1396 isc_heap_delete(found_chains, 1);
1397 } while (f != NULL);
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)
1407 dns_namereln_t reln;
1409 unsigned int labels, nlabels, i;
1411 isc_result_t result = ISC_R_SUCCESS, tresult;
1413 reln = dns_name_fullcompare(prevname, name, &order, &labels);
1417 nlabels = dns_name_countlabels(name);
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,
1425 if (nsec3paramset != NULL &&
1426 dns_rdataset_isassociated(nsec3paramset)) {
1427 tresult = verifynsec3s(db, ver, origin, mctx,
1428 &suffix, nsec3paramset,
1429 isdelegation, ISC_TRUE,
1431 if (result == ISC_R_SUCCESS &&
1432 tresult != ISC_R_SUCCESS)
1441 * Verify that certain things are sane:
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.
1446 * The DNSKEY record was signed with at least one of the KSKs in this
1449 * The rest of the zone was signed with at least one of the ZSKs
1450 * present in the DNSKEY RRSET.
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)
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;
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];
1483 result = isc_heap_create(mctx, chain_compare, NULL, 1024,
1485 check_result(result, "isc_heap_create()");
1486 result = isc_heap_create(mctx, chain_compare, NULL, 1024,
1488 check_result(result, "isc_heap_create()");
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));
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");
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");
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");
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");
1523 if (!dns_rdataset_isassociated(&keysigs))
1524 fatal("DNSKEY is not signed (keys offline or inactive?)\n");
1526 if (!dns_rdataset_isassociated(&soasigs))
1527 fatal("SOA is not signed (keys offline or inactive?)\n");
1529 if (dns_rdataset_isassociated(&nsecset) &&
1530 !dns_rdataset_isassociated(&nsecsigs))
1531 fatal("NSEC is not signed (keys offline or inactive?)\n");
1533 if (dns_rdataset_isassociated(&nsec3paramset) &&
1534 !dns_rdataset_isassociated(&nsec3paramsigs))
1535 fatal("NSEC3PARAM is not signed (keys offline or inactive?)\n");
1537 if (!dns_rdataset_isassociated(&nsecset) &&
1538 !dns_rdataset_isassociated(&nsec3paramset))
1539 fatal("No valid NSEC/NSEC3 chain for testing\n");
1541 dns_db_detachnode(db, &node);
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));
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).
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");
1564 if ((dnskey.flags & DNS_KEYOWNER_ZONE) == 0)
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,
1571 char namebuf[DNS_NAME_FORMATSIZE];
1575 dns_name_format(origin, 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);
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]++;
1597 if (standby_ksk[dnskey.algorithm] != 255)
1598 standby_ksk[dnskey.algorithm]++;
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]++;
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]++;
1610 if (standby_zsk[dnskey.algorithm] != 255)
1611 standby_zsk[dnskey.algorithm]++;
1613 dns_rdata_freestruct(&dnskey);
1614 dns_rdata_reset(&rdata);
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);
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'.");
1631 fprintf(stderr, "Verifying the zone using the following algorithms:");
1632 for (i = 0; i < 256; i++) {
1634 act_algorithms[i] = (ksk_algorithms[i] != 0 ||
1635 zsk_algorithms[i] != 0) ? 1 : 0;
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);
1643 fprintf(stderr, ".\n");
1645 if (!ignore_kskflag && !keyset_kskonly) {
1646 for (i = 0; i < 256; i++) {
1648 * The counts should both be zero or both be non-zero.
1649 * Mark the algorithm as bad if this is not met.
1651 if ((ksk_algorithms[i] != 0) ==
1652 (zsk_algorithms[i] != 0))
1654 dns_secalg_format(i, algbuf, sizeof(algbuf));
1655 fprintf(stderr, "Missing %s for algorithm %s\n",
1656 (ksk_algorithms[i] != 0)
1658 : "self-signed KSK",
1660 bad_algorithms[i] = 1;
1665 * Check that all the other records were signed by keys that are
1666 * present in the DNSKEY RRSET.
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);
1675 dns_fixedname_init(&fzonecut);
1678 result = dns_db_createiterator(db, DNS_DB_NONSEC3, &dbiter);
1679 check_result(result, "dns_db_createiterator()");
1681 result = dns_dbiterator_first(dbiter);
1682 check_result(result, "dns_dbiterator_first()");
1685 isc_boolean_t isdelegation = ISC_FALSE;
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)
1696 check_result(result, "dns_dbiterator_next()");
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;
1705 result = dns_dbiterator_next(dbiter);
1706 while (result == ISC_R_SUCCESS) {
1707 result = dns_dbiterator_current(dbiter, &nextnode,
1709 check_dns_dbiterator_current(result);
1710 if (!dns_name_issubdomain(nextname, origin) ||
1712 dns_name_issubdomain(nextname, zonecut)))
1714 check_no_nsec(nextname, nextnode, db, ver);
1715 dns_db_detachnode(db, &nextnode);
1716 result = dns_dbiterator_next(dbiter);
1719 if (is_empty(db, ver, nextnode)) {
1720 dns_db_detachnode(db, &nextnode);
1721 result = dns_dbiterator_next(dbiter);
1724 dns_db_detachnode(db, &nextnode);
1727 if (result == ISC_R_NOMORE) {
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,
1737 if (vresult == ISC_R_UNSET)
1738 vresult = ISC_R_SUCCESS;
1739 if (vresult == ISC_R_SUCCESS && result != ISC_R_SUCCESS)
1741 if (prevname != NULL) {
1742 result = verifyemptynodes(db, ver, origin, mctx, name,
1743 prevname, isdelegation,
1746 prevname = dns_fixedname_name(&fprevname);
1747 dns_name_copy(name, prevname, NULL);
1748 if (vresult == ISC_R_SUCCESS && result != ISC_R_SUCCESS)
1750 dns_db_detachnode(db, &node);
1753 dns_dbiterator_destroy(&dbiter);
1755 result = dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbiter);
1756 check_result(result, "dns_db_createiterator()");
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);
1770 dns_dbiterator_destroy(&dbiter);
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);
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)
1783 isc_heap_destroy(&expected_chains);
1784 isc_heap_destroy(&found_chains);
1787 * If we made it this far, we have what we consider a properly signed
1788 * zone. Set the good flag.
1790 for (i = 0; i < 256; i++) {
1791 if (bad_algorithms[i] != 0) {
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);
1801 fprintf(stderr, ".\n");
1802 fatal("DNSSEC completeness test failed.");
1805 if (vresult != ISC_R_SUCCESS)
1806 fatal("DNSSEC completeness test failed (%s).",
1807 dns_result_totext(vresult));
1809 if (goodksk || ignore_kskflag) {
1811 * Print the success summary.
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, "",
1831 keyset_kskonly ? "present" : "stand-by",