2 * Copyright (C) 2006, 2008-2014 Internet Systems Consortium, Inc. ("ISC")
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
21 #include <isc/base32.h>
22 #include <isc/buffer.h>
24 #include <isc/iterated_hash.h>
26 #include <isc/string.h>
33 #include <dns/compress.h>
34 #include <dns/dbiterator.h>
36 #include <dns/fixedname.h>
38 #include <dns/nsec3.h>
39 #include <dns/rdata.h>
40 #include <dns/rdatalist.h>
41 #include <dns/rdataset.h>
42 #include <dns/rdatasetiter.h>
43 #include <dns/rdatastruct.h>
44 #include <dns/result.h>
46 #define CHECK(x) do { \
48 if (result != ISC_R_SUCCESS) \
52 #define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0)
53 #define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0)
54 #define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0)
55 #define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
58 dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
59 dns_dbnode_t *node, unsigned int hashalg,
60 unsigned int flags, unsigned int iterations,
61 const unsigned char *salt, size_t salt_length,
62 const unsigned char *nexthash, size_t hash_length,
63 unsigned char *buffer, dns_rdata_t *rdata)
66 dns_rdataset_t rdataset;
70 isc_boolean_t found_ns;
71 isc_boolean_t need_rrsig;
73 unsigned char *nsec_bits, *bm;
74 unsigned int max_type;
75 dns_rdatasetiter_t *rdsiter;
78 REQUIRE(salt_length < 256U);
79 REQUIRE(hash_length < 256U);
80 REQUIRE(flags <= 0xffU);
81 REQUIRE(hashalg <= 0xffU);
82 REQUIRE(iterations <= 0xffffU);
86 REQUIRE(hash_length == ISC_SHA1_DIGESTLENGTH);
90 memset(buffer, 0, DNS_NSEC3_BUFFERSIZE);
97 *p++ = iterations >> 8;
100 *p++ = (unsigned char)salt_length;
101 memmove(p, salt, salt_length);
104 *p++ = (unsigned char)hash_length;
105 memmove(p, nexthash, hash_length);
108 r.length = (unsigned int)(p - buffer);
112 * Use the end of the space for a raw bitmap leaving enough
113 * space for the window identifiers and length octets.
115 bm = r.base + r.length + 512;
116 nsec_bits = r.base + r.length;
119 goto collapse_bitmap;
120 dns_rdataset_init(&rdataset);
122 result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
123 if (result != ISC_R_SUCCESS)
125 found = found_ns = need_rrsig = ISC_FALSE;
126 for (result = dns_rdatasetiter_first(rdsiter);
127 result == ISC_R_SUCCESS;
128 result = dns_rdatasetiter_next(rdsiter))
130 dns_rdatasetiter_current(rdsiter, &rdataset);
131 if (rdataset.type != dns_rdatatype_nsec &&
132 rdataset.type != dns_rdatatype_nsec3 &&
133 rdataset.type != dns_rdatatype_rrsig) {
134 if (rdataset.type > max_type)
135 max_type = rdataset.type;
136 dns_nsec_setbit(bm, rdataset.type, 1);
138 * Work out if we need to set the RRSIG bit for
139 * this node. We set the RRSIG bit if either of
140 * the following conditions are met:
141 * 1) We have a SOA or DS then we need to set
142 * the RRSIG bit as both always will be signed.
143 * 2) We set the RRSIG bit if we don't have
144 * a NS record but do have other data.
146 if (rdataset.type == dns_rdatatype_soa ||
147 rdataset.type == dns_rdatatype_ds)
148 need_rrsig = ISC_TRUE;
149 else if (rdataset.type == dns_rdatatype_ns)
154 dns_rdataset_disassociate(&rdataset);
156 if ((found && !found_ns) || need_rrsig) {
157 if (dns_rdatatype_rrsig > max_type)
158 max_type = dns_rdatatype_rrsig;
159 dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1);
163 * At zone cuts, deny the existence of glue in the parent zone.
165 if (dns_nsec_isset(bm, dns_rdatatype_ns) &&
166 ! dns_nsec_isset(bm, dns_rdatatype_soa)) {
167 for (i = 0; i <= max_type; i++) {
168 if (dns_nsec_isset(bm, i) &&
169 ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i))
170 dns_nsec_setbit(bm, i, 0);
174 dns_rdatasetiter_destroy(&rdsiter);
175 if (result != ISC_R_NOMORE)
179 nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type);
180 r.length = (unsigned int)(nsec_bits - r.base);
181 INSIST(r.length <= DNS_NSEC3_BUFFERSIZE);
182 dns_rdata_fromregion(rdata, dns_db_class(db), dns_rdatatype_nsec3, &r);
184 return (ISC_R_SUCCESS);
188 dns_nsec3_typepresent(dns_rdata_t *rdata, dns_rdatatype_t type) {
189 dns_rdata_nsec3_t nsec3;
191 isc_boolean_t present;
192 unsigned int i, len, window;
194 REQUIRE(rdata != NULL);
195 REQUIRE(rdata->type == dns_rdatatype_nsec3);
197 /* This should never fail */
198 result = dns_rdata_tostruct(rdata, &nsec3, NULL);
199 INSIST(result == ISC_R_SUCCESS);
202 for (i = 0; i < nsec3.len; i += len) {
203 INSIST(i + 2 <= nsec3.len);
204 window = nsec3.typebits[i];
205 len = nsec3.typebits[i + 1];
206 INSIST(len > 0 && len <= 32);
208 INSIST(i + len <= nsec3.len);
209 if (window * 256 > type)
211 if ((window + 1) * 256 <= type)
213 if (type < (window * 256) + len * 8)
214 present = ISC_TF(dns_nsec_isset(&nsec3.typebits[i],
218 dns_rdata_freestruct(&nsec3);
223 dns_nsec3_hashname(dns_fixedname_t *result,
224 unsigned char rethash[NSEC3_MAX_HASH_LENGTH],
225 size_t *hash_length, dns_name_t *name, dns_name_t *origin,
226 dns_hash_t hashalg, unsigned int iterations,
227 const unsigned char *salt, size_t saltlength)
229 unsigned char hash[NSEC3_MAX_HASH_LENGTH];
230 unsigned char nametext[DNS_NAME_FORMATSIZE];
231 dns_fixedname_t fixed;
232 dns_name_t *downcased;
233 isc_buffer_t namebuffer;
240 memset(rethash, 0, NSEC3_MAX_HASH_LENGTH);
242 dns_fixedname_init(&fixed);
243 downcased = dns_fixedname_name(&fixed);
244 dns_name_downcase(name, downcased, NULL);
246 /* hash the node name */
247 len = isc_iterated_hash(rethash, hashalg, iterations,
248 salt, (int)saltlength,
249 downcased->ndata, downcased->length);
251 return (DNS_R_BADALG);
253 if (hash_length != NULL)
256 /* convert the hash to base32hex */
257 region.base = rethash;
258 region.length = (unsigned int)len;
259 isc_buffer_init(&namebuffer, nametext, sizeof nametext);
260 isc_base32hex_totext(®ion, 1, "", &namebuffer);
262 /* convert the hex to a domain name */
263 dns_fixedname_init(result);
264 return (dns_name_fromtext(dns_fixedname_name(result), &namebuffer,
269 dns_nsec3_hashlength(dns_hash_t hash) {
272 case dns_hash_sha1: return(ISC_SHA1_DIGESTLENGTH);
278 dns_nsec3_supportedhash(dns_hash_t hash) {
280 case dns_hash_sha1: return (ISC_TRUE);
286 * Update a single RR in version 'ver' of 'db' and log the
290 * \li '*tuple' == NULL. Either the tuple is freed, or its
291 * ownership has been transferred to the diff.
294 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
297 dns_diff_t temp_diff;
301 * Create a singleton diff.
303 dns_diff_init(diff->mctx, &temp_diff);
304 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
307 * Apply it to the database.
309 result = dns_diff_apply(&temp_diff, db, ver);
310 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
311 if (result != ISC_R_SUCCESS) {
312 dns_difftuple_free(tuple);
317 * Merge it into the current pending journal entry.
319 dns_diff_appendminimal(diff, tuple);
322 * Do not clear temp_diff.
324 return (ISC_R_SUCCESS);
328 * Set '*exists' to true iff the given name exists, to false otherwise.
331 name_exists(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
332 isc_boolean_t *exists)
335 dns_dbnode_t *node = NULL;
336 dns_rdatasetiter_t *iter = NULL;
338 result = dns_db_findnode(db, name, ISC_FALSE, &node);
339 if (result == ISC_R_NOTFOUND) {
341 return (ISC_R_SUCCESS);
343 if (result != ISC_R_SUCCESS)
346 result = dns_db_allrdatasets(db, node, version,
347 (isc_stdtime_t) 0, &iter);
348 if (result != ISC_R_SUCCESS)
351 result = dns_rdatasetiter_first(iter);
352 if (result == ISC_R_SUCCESS) {
354 } else if (result == ISC_R_NOMORE) {
356 result = ISC_R_SUCCESS;
359 dns_rdatasetiter_destroy(&iter);
362 dns_db_detachnode(db, &node);
367 match_nsec3param(const dns_rdata_nsec3_t *nsec3,
368 const dns_rdata_nsec3param_t *nsec3param)
370 if (nsec3->hash == nsec3param->hash &&
371 nsec3->iterations == nsec3param->iterations &&
372 nsec3->salt_length == nsec3param->salt_length &&
373 !memcmp(nsec3->salt, nsec3param->salt, nsec3->salt_length))
379 * Delete NSEC3 records at "name" which match "param", recording the
383 delete(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
384 const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff)
386 dns_dbnode_t *node = NULL ;
387 dns_difftuple_t *tuple = NULL;
388 dns_rdata_nsec3_t nsec3;
389 dns_rdataset_t rdataset;
392 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
393 if (result == ISC_R_NOTFOUND)
394 return (ISC_R_SUCCESS);
395 if (result != ISC_R_SUCCESS)
398 dns_rdataset_init(&rdataset);
399 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, 0,
400 (isc_stdtime_t) 0, &rdataset, NULL);
402 if (result == ISC_R_NOTFOUND) {
403 result = ISC_R_SUCCESS;
406 if (result != ISC_R_SUCCESS)
409 for (result = dns_rdataset_first(&rdataset);
410 result == ISC_R_SUCCESS;
411 result = dns_rdataset_next(&rdataset))
413 dns_rdata_t rdata = DNS_RDATA_INIT;
414 dns_rdataset_current(&rdataset, &rdata);
415 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
417 if (!match_nsec3param(&nsec3, nsec3param))
420 result = dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, name,
421 rdataset.ttl, &rdata, &tuple);
422 if (result != ISC_R_SUCCESS)
424 result = do_one_tuple(&tuple, db, version, diff);
425 if (result != ISC_R_SUCCESS)
428 if (result != ISC_R_NOMORE)
430 result = ISC_R_SUCCESS;
433 dns_rdataset_disassociate(&rdataset);
435 dns_db_detachnode(db, &node);
441 better_param(dns_rdataset_t *nsec3paramset, dns_rdata_t *param) {
442 dns_rdataset_t rdataset;
445 if (REMOVE(param->data[1]))
448 dns_rdataset_init(&rdataset);
449 dns_rdataset_clone(nsec3paramset, &rdataset);
450 for (result = dns_rdataset_first(&rdataset);
451 result == ISC_R_SUCCESS;
452 result = dns_rdataset_next(&rdataset)) {
453 dns_rdata_t rdata = DNS_RDATA_INIT;
454 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
456 if (rdataset.type != dns_rdatatype_nsec3param) {
457 dns_rdata_t tmprdata = DNS_RDATA_INIT;
458 dns_rdataset_current(&rdataset, &tmprdata);
459 if (!dns_nsec3param_fromprivate(&tmprdata, &rdata,
463 dns_rdataset_current(&rdataset, &rdata);
465 if (rdata.length != param->length)
467 if (rdata.data[0] != param->data[0] ||
468 REMOVE(rdata.data[1]) ||
469 rdata.data[2] != param->data[2] ||
470 rdata.data[3] != param->data[3] ||
471 rdata.data[4] != param->data[4] ||
472 memcmp(&rdata.data[5], ¶m->data[5], param->data[4]))
474 if (CREATE(rdata.data[1]) && !CREATE(param->data[1])) {
475 dns_rdataset_disassociate(&rdataset);
479 dns_rdataset_disassociate(&rdataset);
484 find_nsec3(dns_rdata_nsec3_t *nsec3, dns_rdataset_t *rdataset,
485 const dns_rdata_nsec3param_t *nsec3param)
488 for (result = dns_rdataset_first(rdataset);
489 result == ISC_R_SUCCESS;
490 result = dns_rdataset_next(rdataset)) {
491 dns_rdata_t rdata = DNS_RDATA_INIT;
493 dns_rdataset_current(rdataset, &rdata);
494 CHECK(dns_rdata_tostruct(&rdata, nsec3, NULL));
495 dns_rdata_reset(&rdata);
496 if (match_nsec3param(nsec3, nsec3param))
504 dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version,
505 dns_name_t *name, const dns_rdata_nsec3param_t *nsec3param,
506 dns_ttl_t nsecttl, isc_boolean_t unsecure, dns_diff_t *diff)
508 dns_dbiterator_t *dbit = NULL;
509 dns_dbnode_t *node = NULL;
510 dns_dbnode_t *newnode = NULL;
511 dns_difftuple_t *tuple = NULL;
512 dns_fixedname_t fixed;
513 dns_fixedname_t fprev;
515 dns_name_t *hashname;
519 dns_rdata_nsec3_t nsec3;
520 dns_rdata_t rdata = DNS_RDATA_INIT;
521 dns_rdataset_t rdataset;
523 isc_boolean_t exists = ISC_FALSE;
524 isc_boolean_t maybe_remove_unsecure = ISC_FALSE;
528 unsigned char *old_next;
530 unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
531 unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
532 unsigned int iterations;
535 unsigned int old_length;
536 unsigned int salt_length;
538 dns_fixedname_init(&fixed);
539 hashname = dns_fixedname_name(&fixed);
540 dns_fixedname_init(&fprev);
541 prev = dns_fixedname_name(&fprev);
543 dns_rdataset_init(&rdataset);
545 origin = dns_db_origin(db);
550 hash = nsec3param->hash;
551 iterations = nsec3param->iterations;
552 salt_length = nsec3param->salt_length;
553 salt = nsec3param->salt;
556 * Default flags for a new chain.
558 flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
561 * If this is the first NSEC3 in the chain nexthash will
562 * remain pointing to itself.
564 next_length = sizeof(nexthash);
565 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
566 name, origin, hash, iterations,
570 * Create the node if it doesn't exist and hold
571 * a reference to it until we have added the NSEC3.
573 CHECK(dns_db_findnsec3node(db, hashname, ISC_TRUE, &newnode));
576 * Seek the iterator to the 'newnode'.
578 CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
579 CHECK(dns_dbiterator_seek(dbit, hashname));
580 CHECK(dns_dbiterator_pause(dbit));
581 result = dns_db_findrdataset(db, newnode, version, dns_rdatatype_nsec3,
582 0, (isc_stdtime_t) 0, &rdataset, NULL);
584 * If we updating a existing NSEC3 then find its
587 if (result == ISC_R_SUCCESS) {
588 result = find_nsec3(&nsec3, &rdataset, nsec3param);
589 if (result == ISC_R_SUCCESS) {
590 if (!CREATE(nsec3param->flags))
592 next_length = nsec3.next_length;
593 INSIST(next_length <= sizeof(nexthash));
594 memmove(nexthash, nsec3.next, next_length);
595 dns_rdataset_disassociate(&rdataset);
597 * If the NSEC3 is not for a unsecure delegation then
598 * we are just updating it. If it is for a unsecure
599 * delegation then we need find out if we need to
600 * remove the NSEC3 record or not by examining the
601 * previous NSEC3 record.
605 else if (CREATE(nsec3param->flags) && OPTOUT(flags)) {
606 result = dns_nsec3_delnsec3(db, version, name,
610 maybe_remove_unsecure = ISC_TRUE;
612 dns_rdataset_disassociate(&rdataset);
613 if (result != ISC_R_NOMORE)
619 * Find the previous NSEC3 (if any) and update it if required.
623 result = dns_dbiterator_prev(dbit);
624 if (result == ISC_R_NOMORE) {
626 CHECK(dns_dbiterator_last(dbit));
628 CHECK(dns_dbiterator_current(dbit, &node, prev));
629 CHECK(dns_dbiterator_pause(dbit));
630 result = dns_db_findrdataset(db, node, version,
631 dns_rdatatype_nsec3, 0,
632 (isc_stdtime_t) 0, &rdataset,
634 dns_db_detachnode(db, &node);
635 if (result != ISC_R_SUCCESS)
638 result = find_nsec3(&nsec3, &rdataset, nsec3param);
639 if (result == ISC_R_NOMORE) {
640 dns_rdataset_disassociate(&rdataset);
643 if (result != ISC_R_SUCCESS)
646 if (maybe_remove_unsecure) {
647 dns_rdataset_disassociate(&rdataset);
649 * If we have OPTOUT set in the previous NSEC3 record
650 * we actually need to delete the NSEC3 record.
651 * Otherwise we just need to replace the NSEC3 record.
653 if (OPTOUT(nsec3.flags)) {
654 result = dns_nsec3_delnsec3(db, version, name,
661 * Is this is a unsecure delegation we are adding?
662 * If so no change is required.
664 if (OPTOUT(nsec3.flags) && unsecure) {
665 dns_rdataset_disassociate(&rdataset);
670 old_next = nsec3.next;
671 old_length = nsec3.next_length;
674 * Delete the old previous NSEC3.
676 CHECK(delete(db, version, prev, nsec3param, diff));
679 * Fixup the previous NSEC3.
681 nsec3.next = nexthash;
682 nsec3.next_length = (unsigned char)next_length;
683 isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
684 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
685 dns_rdatatype_nsec3, &nsec3,
687 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
688 rdataset.ttl, &rdata, &tuple));
689 CHECK(do_one_tuple(&tuple, db, version, diff));
690 INSIST(old_length <= sizeof(nexthash));
691 memmove(nexthash, old_next, old_length);
692 if (!CREATE(nsec3param->flags))
694 dns_rdata_reset(&rdata);
695 dns_rdataset_disassociate(&rdataset);
701 * Create the NSEC3 RDATA.
703 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
704 CHECK(dns_nsec3_buildrdata(db, version, node, hash, flags, iterations,
705 salt, salt_length, nexthash, next_length,
707 dns_db_detachnode(db, &node);
710 * Delete the old NSEC3 and record the change.
712 CHECK(delete(db, version, hashname, nsec3param, diff));
714 * Add the new NSEC3 and record the change.
716 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
717 hashname, nsecttl, &rdata, &tuple));
718 CHECK(do_one_tuple(&tuple, db, version, diff));
719 INSIST(tuple == NULL);
720 dns_rdata_reset(&rdata);
721 dns_db_detachnode(db, &newnode);
724 * Add missing NSEC3 records for empty nodes
726 dns_name_init(&empty, NULL);
727 dns_name_clone(name, &empty);
729 labels = dns_name_countlabels(&empty) - 1;
730 if (labels <= dns_name_countlabels(origin))
732 dns_name_getlabelsequence(&empty, 1, labels, &empty);
733 CHECK(name_exists(db, version, &empty, &exists));
736 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
737 &empty, origin, hash, iterations,
741 * Create the node if it doesn't exist and hold
742 * a reference to it until we have added the NSEC3
743 * or we discover we don't need to add make a change.
745 CHECK(dns_db_findnsec3node(db, hashname, ISC_TRUE, &newnode));
746 result = dns_db_findrdataset(db, newnode, version,
747 dns_rdatatype_nsec3, 0,
748 (isc_stdtime_t) 0, &rdataset,
750 if (result == ISC_R_SUCCESS) {
751 result = find_nsec3(&nsec3, &rdataset, nsec3param);
752 dns_rdataset_disassociate(&rdataset);
753 if (result == ISC_R_SUCCESS) {
754 dns_db_detachnode(db, &newnode);
757 if (result != ISC_R_NOMORE)
762 * Find the previous NSEC3 and update it.
764 CHECK(dns_dbiterator_seek(dbit, hashname));
767 result = dns_dbiterator_prev(dbit);
768 if (result == ISC_R_NOMORE) {
770 CHECK(dns_dbiterator_last(dbit));
772 CHECK(dns_dbiterator_current(dbit, &node, prev));
773 CHECK(dns_dbiterator_pause(dbit));
774 result = dns_db_findrdataset(db, node, version,
775 dns_rdatatype_nsec3, 0,
778 dns_db_detachnode(db, &node);
779 if (result != ISC_R_SUCCESS)
781 result = find_nsec3(&nsec3, &rdataset, nsec3param);
782 if (result == ISC_R_NOMORE) {
783 dns_rdataset_disassociate(&rdataset);
786 if (result != ISC_R_SUCCESS)
789 old_next = nsec3.next;
790 old_length = nsec3.next_length;
793 * Delete the old previous NSEC3.
795 CHECK(delete(db, version, prev, nsec3param, diff));
798 * Fixup the previous NSEC3.
800 nsec3.next = nexthash;
801 nsec3.next_length = (unsigned char)next_length;
802 isc_buffer_init(&buffer, nsec3buf,
804 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
805 dns_rdatatype_nsec3, &nsec3,
807 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
808 prev, rdataset.ttl, &rdata,
810 CHECK(do_one_tuple(&tuple, db, version, diff));
811 INSIST(old_length <= sizeof(nexthash));
812 memmove(nexthash, old_next, old_length);
813 if (!CREATE(nsec3param->flags))
815 dns_rdata_reset(&rdata);
816 dns_rdataset_disassociate(&rdataset);
823 * Create the NSEC3 RDATA for the empty node.
825 CHECK(dns_nsec3_buildrdata(db, version, NULL, hash, flags,
826 iterations, salt, salt_length,
827 nexthash, next_length, nsec3buf,
830 * Delete the old NSEC3 and record the change.
832 CHECK(delete(db, version, hashname, nsec3param, diff));
835 * Add the new NSEC3 and record the change.
837 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
838 hashname, nsecttl, &rdata, &tuple));
839 CHECK(do_one_tuple(&tuple, db, version, diff));
840 INSIST(tuple == NULL);
841 dns_rdata_reset(&rdata);
842 dns_db_detachnode(db, &newnode);
845 if (result == ISC_R_NOMORE)
846 result = ISC_R_SUCCESS;
850 dns_dbiterator_destroy(&dbit);
851 if (dns_rdataset_isassociated(&rdataset))
852 dns_rdataset_disassociate(&rdataset);
854 dns_db_detachnode(db, &node);
856 dns_db_detachnode(db, &newnode);
861 * Add NSEC3 records for "name", recording the change in "diff".
862 * The existing NSEC3 records are removed.
865 dns_nsec3_addnsec3s(dns_db_t *db, dns_dbversion_t *version,
866 dns_name_t *name, dns_ttl_t nsecttl,
867 isc_boolean_t unsecure, dns_diff_t *diff)
869 dns_dbnode_t *node = NULL;
870 dns_rdata_nsec3param_t nsec3param;
871 dns_rdataset_t rdataset;
874 dns_rdataset_init(&rdataset);
877 * Find the NSEC3 parameters for this zone.
879 result = dns_db_getoriginnode(db, &node);
880 if (result != ISC_R_SUCCESS)
883 result = dns_db_findrdataset(db, node, version,
884 dns_rdatatype_nsec3param, 0, 0,
886 dns_db_detachnode(db, &node);
887 if (result == ISC_R_NOTFOUND)
888 return (ISC_R_SUCCESS);
889 if (result != ISC_R_SUCCESS)
893 * Update each active NSEC3 chain.
895 for (result = dns_rdataset_first(&rdataset);
896 result == ISC_R_SUCCESS;
897 result = dns_rdataset_next(&rdataset)) {
898 dns_rdata_t rdata = DNS_RDATA_INIT;
900 dns_rdataset_current(&rdataset, &rdata);
901 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
903 if (nsec3param.flags != 0)
906 * We have a active chain. Update it.
908 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
909 nsecttl, unsecure, diff));
911 if (result == ISC_R_NOMORE)
912 result = ISC_R_SUCCESS;
915 if (dns_rdataset_isassociated(&rdataset))
916 dns_rdataset_disassociate(&rdataset);
918 dns_db_detachnode(db, &node);
924 dns_nsec3param_fromprivate(dns_rdata_t *src, dns_rdata_t *target,
925 unsigned char *buf, size_t buflen)
927 dns_decompress_t dctx;
933 * Algorithm 0 (reserved by RFC 4034) is used to identify
934 * NSEC3PARAM records from DNSKEY pointers.
936 if (src->length < 1 || src->data[0] != 0)
939 isc_buffer_init(&buf1, src->data + 1, src->length - 1);
940 isc_buffer_add(&buf1, src->length - 1);
941 isc_buffer_setactive(&buf1, src->length - 1);
942 isc_buffer_init(&buf2, buf, (unsigned int)buflen);
943 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
944 result = dns_rdata_fromwire(target, src->rdclass,
945 dns_rdatatype_nsec3param,
946 &buf1, &dctx, 0, &buf2);
947 dns_decompress_invalidate(&dctx);
949 return (ISC_TF(result == ISC_R_SUCCESS));
953 dns_nsec3param_toprivate(dns_rdata_t *src, dns_rdata_t *target,
954 dns_rdatatype_t privatetype,
955 unsigned char *buf, size_t buflen)
957 REQUIRE(buflen >= src->length + 1);
959 REQUIRE(DNS_RDATA_INITIALIZED(target));
961 memmove(buf + 1, src->data, src->length);
964 target->length = src->length + 1;
965 target->type = privatetype;
966 target->rdclass = src->rdclass;
968 ISC_LINK_INIT(target, link);
973 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
974 const dns_rdata_t *rdata, isc_boolean_t *flag)
976 dns_rdataset_t rdataset;
977 dns_dbnode_t *node = NULL;
980 dns_rdataset_init(&rdataset);
981 if (rdata->type == dns_rdatatype_nsec3)
982 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
984 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
985 result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
986 (isc_stdtime_t) 0, &rdataset, NULL);
987 if (result == ISC_R_NOTFOUND) {
989 result = ISC_R_SUCCESS;
993 for (result = dns_rdataset_first(&rdataset);
994 result == ISC_R_SUCCESS;
995 result = dns_rdataset_next(&rdataset)) {
996 dns_rdata_t myrdata = DNS_RDATA_INIT;
997 dns_rdataset_current(&rdataset, &myrdata);
998 if (!dns_rdata_casecompare(&myrdata, rdata))
1001 dns_rdataset_disassociate(&rdataset);
1002 if (result == ISC_R_SUCCESS) {
1004 } else if (result == ISC_R_NOMORE) {
1006 result = ISC_R_SUCCESS;
1011 dns_db_detachnode(db, &node);
1018 dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver,
1019 dns_zone_t *zone, isc_boolean_t nonsec,
1022 dns_dbnode_t *node = NULL;
1023 dns_difftuple_t *tuple = NULL;
1025 dns_rdata_t rdata = DNS_RDATA_INIT;
1026 dns_rdataset_t rdataset;
1028 isc_result_t result = ISC_R_SUCCESS;
1029 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE + 1];
1030 dns_name_t *origin = dns_zone_getorigin(zone);
1031 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
1033 dns_name_init(&next, NULL);
1034 dns_rdataset_init(&rdataset);
1036 result = dns_db_getoriginnode(db, &node);
1037 if (result != ISC_R_SUCCESS)
1041 * Cause all NSEC3 chains to be deleted.
1043 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
1044 0, (isc_stdtime_t) 0, &rdataset, NULL);
1045 if (result == ISC_R_NOTFOUND)
1047 if (result != ISC_R_SUCCESS)
1050 for (result = dns_rdataset_first(&rdataset);
1051 result == ISC_R_SUCCESS;
1052 result = dns_rdataset_next(&rdataset)) {
1053 dns_rdata_t private = DNS_RDATA_INIT;
1055 dns_rdataset_current(&rdataset, &rdata);
1057 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
1058 rdataset.ttl, &rdata, &tuple));
1059 CHECK(do_one_tuple(&tuple, db, ver, diff));
1060 INSIST(tuple == NULL);
1062 dns_nsec3param_toprivate(&rdata, &private, privatetype,
1064 buf[2] = DNS_NSEC3FLAG_REMOVE;
1066 buf[2] |= DNS_NSEC3FLAG_NONSEC;
1068 CHECK(rr_exists(db, ver, origin, &private, &flag));
1071 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1072 origin, 0, &private,
1074 CHECK(do_one_tuple(&tuple, db, ver, diff));
1075 INSIST(tuple == NULL);
1077 dns_rdata_reset(&rdata);
1079 if (result != ISC_R_NOMORE)
1082 dns_rdataset_disassociate(&rdataset);
1085 if (privatetype == 0)
1087 result = dns_db_findrdataset(db, node, ver, privatetype, 0,
1088 (isc_stdtime_t) 0, &rdataset, NULL);
1089 if (result == ISC_R_NOTFOUND)
1091 if (result != ISC_R_SUCCESS)
1094 for (result = dns_rdataset_first(&rdataset);
1095 result == ISC_R_SUCCESS;
1096 result = dns_rdataset_next(&rdataset)) {
1097 dns_rdata_reset(&rdata);
1098 dns_rdataset_current(&rdataset, &rdata);
1099 INSIST(rdata.length <= sizeof(buf));
1100 memmove(buf, rdata.data, rdata.length);
1103 * Private NSEC3 record length >= 6.
1104 * <0(1), hash(1), flags(1), iterations(2), saltlen(1)>
1106 if (rdata.length < 6 || buf[0] != 0 ||
1107 (buf[2] & DNS_NSEC3FLAG_REMOVE) != 0 ||
1108 (nonsec && (buf[2] & DNS_NSEC3FLAG_NONSEC) != 0))
1111 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
1112 0, &rdata, &tuple));
1113 CHECK(do_one_tuple(&tuple, db, ver, diff));
1114 INSIST(tuple == NULL);
1117 buf[2] = DNS_NSEC3FLAG_REMOVE;
1119 buf[2] |= DNS_NSEC3FLAG_NONSEC;
1121 CHECK(rr_exists(db, ver, origin, &rdata, &flag));
1124 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1125 origin, 0, &rdata, &tuple));
1126 CHECK(do_one_tuple(&tuple, db, ver, diff));
1127 INSIST(tuple == NULL);
1130 if (result != ISC_R_NOMORE)
1133 result = ISC_R_SUCCESS;
1136 if (dns_rdataset_isassociated(&rdataset))
1137 dns_rdataset_disassociate(&rdataset);
1138 dns_db_detachnode(db, &node);
1144 dns_nsec3_addnsec3sx(dns_db_t *db, dns_dbversion_t *version,
1145 dns_name_t *name, dns_ttl_t nsecttl,
1146 isc_boolean_t unsecure, dns_rdatatype_t type,
1149 dns_dbnode_t *node = NULL;
1150 dns_rdata_nsec3param_t nsec3param;
1151 dns_rdataset_t rdataset;
1152 dns_rdataset_t prdataset;
1153 isc_result_t result;
1155 dns_rdataset_init(&rdataset);
1156 dns_rdataset_init(&prdataset);
1159 * Find the NSEC3 parameters for this zone.
1161 result = dns_db_getoriginnode(db, &node);
1162 if (result != ISC_R_SUCCESS)
1165 result = dns_db_findrdataset(db, node, version, type, 0, 0,
1167 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
1170 result = dns_db_findrdataset(db, node, version,
1171 dns_rdatatype_nsec3param, 0, 0,
1173 if (result == ISC_R_NOTFOUND)
1175 if (result != ISC_R_SUCCESS)
1179 * Update each active NSEC3 chain.
1181 for (result = dns_rdataset_first(&rdataset);
1182 result == ISC_R_SUCCESS;
1183 result = dns_rdataset_next(&rdataset)) {
1184 dns_rdata_t rdata = DNS_RDATA_INIT;
1186 dns_rdataset_current(&rdataset, &rdata);
1187 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
1189 if (nsec3param.flags != 0)
1193 * We have a active chain. Update it.
1195 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
1196 nsecttl, unsecure, diff));
1198 if (result != ISC_R_NOMORE)
1201 dns_rdataset_disassociate(&rdataset);
1204 if (!dns_rdataset_isassociated(&prdataset))
1207 * Update each active NSEC3 chain.
1209 for (result = dns_rdataset_first(&prdataset);
1210 result == ISC_R_SUCCESS;
1211 result = dns_rdataset_next(&prdataset)) {
1212 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1213 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1214 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1216 dns_rdataset_current(&prdataset, &rdata1);
1217 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
1220 CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
1222 if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
1224 if (better_param(&prdataset, &rdata2))
1228 * We have a active chain. Update it.
1230 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
1231 nsecttl, unsecure, diff));
1233 if (result == ISC_R_NOMORE)
1235 result = ISC_R_SUCCESS;
1237 if (dns_rdataset_isassociated(&rdataset))
1238 dns_rdataset_disassociate(&rdataset);
1239 if (dns_rdataset_isassociated(&prdataset))
1240 dns_rdataset_disassociate(&prdataset);
1242 dns_db_detachnode(db, &node);
1248 * Determine whether any NSEC3 records that were associated with
1249 * 'name' should be deleted or if they should continue to exist.
1250 * ISC_TRUE indicates they should be deleted.
1251 * ISC_FALSE indicates they should be retained.
1254 deleteit(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
1255 isc_boolean_t *yesno)
1257 isc_result_t result;
1258 dns_fixedname_t foundname;
1259 dns_fixedname_init(&foundname);
1261 result = dns_db_find(db, name, ver, dns_rdatatype_any,
1262 DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD,
1263 (isc_stdtime_t) 0, NULL,
1264 dns_fixedname_name(&foundname),
1266 if (result == DNS_R_EMPTYNAME || result == ISC_R_SUCCESS ||
1267 result == DNS_R_ZONECUT) {
1269 return (ISC_R_SUCCESS);
1271 if (result == DNS_R_GLUE || result == DNS_R_DNAME ||
1272 result == DNS_R_DELEGATION || result == DNS_R_NXDOMAIN) {
1274 return (ISC_R_SUCCESS);
1284 dns_nsec3_delnsec3(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1285 const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff)
1287 dns_dbiterator_t *dbit = NULL;
1288 dns_dbnode_t *node = NULL;
1289 dns_difftuple_t *tuple = NULL;
1290 dns_fixedname_t fixed;
1291 dns_fixedname_t fprev;
1293 dns_name_t *hashname;
1297 dns_rdata_nsec3_t nsec3;
1298 dns_rdata_t rdata = DNS_RDATA_INIT;
1299 dns_rdataset_t rdataset;
1301 isc_boolean_t yesno;
1302 isc_buffer_t buffer;
1303 isc_result_t result;
1304 unsigned char *salt;
1305 unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
1306 unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
1307 unsigned int iterations;
1308 unsigned int labels;
1310 unsigned int salt_length;
1312 dns_fixedname_init(&fixed);
1313 hashname = dns_fixedname_name(&fixed);
1314 dns_fixedname_init(&fprev);
1315 prev = dns_fixedname_name(&fprev);
1317 dns_rdataset_init(&rdataset);
1319 origin = dns_db_origin(db);
1324 hash = nsec3param->hash;
1325 iterations = nsec3param->iterations;
1326 salt_length = nsec3param->salt_length;
1327 salt = nsec3param->salt;
1330 * If this is the first NSEC3 in the chain nexthash will
1331 * remain pointing to itself.
1333 next_length = sizeof(nexthash);
1334 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
1335 name, origin, hash, iterations,
1336 salt, salt_length));
1338 CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
1340 result = dns_dbiterator_seek(dbit, hashname);
1341 if (result == ISC_R_NOTFOUND)
1343 if (result != ISC_R_SUCCESS)
1346 CHECK(dns_dbiterator_current(dbit, &node, NULL));
1347 CHECK(dns_dbiterator_pause(dbit));
1348 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3,
1349 0, (isc_stdtime_t) 0, &rdataset, NULL);
1350 dns_db_detachnode(db, &node);
1351 if (result == ISC_R_NOTFOUND)
1353 if (result != ISC_R_SUCCESS)
1357 * If we find a existing NSEC3 for this chain then save the
1360 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1361 if (result == ISC_R_SUCCESS) {
1362 next_length = nsec3.next_length;
1363 INSIST(next_length <= sizeof(nexthash));
1364 memmove(nexthash, nsec3.next, next_length);
1366 dns_rdataset_disassociate(&rdataset);
1367 if (result == ISC_R_NOMORE)
1369 if (result != ISC_R_SUCCESS)
1373 * Find the previous NSEC3 and update it.
1377 result = dns_dbiterator_prev(dbit);
1378 if (result == ISC_R_NOMORE) {
1380 CHECK(dns_dbiterator_last(dbit));
1382 CHECK(dns_dbiterator_current(dbit, &node, prev));
1383 CHECK(dns_dbiterator_pause(dbit));
1384 result = dns_db_findrdataset(db, node, version,
1385 dns_rdatatype_nsec3, 0,
1386 (isc_stdtime_t) 0, &rdataset,
1388 dns_db_detachnode(db, &node);
1389 if (result != ISC_R_SUCCESS)
1391 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1392 if (result == ISC_R_NOMORE) {
1393 dns_rdataset_disassociate(&rdataset);
1396 if (result != ISC_R_SUCCESS)
1400 * Delete the old previous NSEC3.
1402 CHECK(delete(db, version, prev, nsec3param, diff));
1405 * Fixup the previous NSEC3.
1407 nsec3.next = nexthash;
1408 nsec3.next_length = (unsigned char)next_length;
1409 if (CREATE(nsec3param->flags))
1410 nsec3.flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
1411 isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
1412 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
1413 dns_rdatatype_nsec3, &nsec3,
1415 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
1416 rdataset.ttl, &rdata, &tuple));
1417 CHECK(do_one_tuple(&tuple, db, version, diff));
1418 dns_rdata_reset(&rdata);
1419 dns_rdataset_disassociate(&rdataset);
1424 * Delete the old NSEC3 and record the change.
1426 CHECK(delete(db, version, hashname, nsec3param, diff));
1429 * Delete NSEC3 records for now non active nodes.
1431 dns_name_init(&empty, NULL);
1432 dns_name_clone(name, &empty);
1434 labels = dns_name_countlabels(&empty) - 1;
1435 if (labels <= dns_name_countlabels(origin))
1437 dns_name_getlabelsequence(&empty, 1, labels, &empty);
1438 CHECK(deleteit(db, version, &empty, &yesno));
1442 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
1443 &empty, origin, hash, iterations,
1444 salt, salt_length));
1445 result = dns_dbiterator_seek(dbit, hashname);
1446 if (result == ISC_R_NOTFOUND)
1448 if (result != ISC_R_SUCCESS)
1451 CHECK(dns_dbiterator_current(dbit, &node, NULL));
1452 CHECK(dns_dbiterator_pause(dbit));
1453 result = dns_db_findrdataset(db, node, version,
1454 dns_rdatatype_nsec3, 0,
1455 (isc_stdtime_t) 0, &rdataset,
1457 dns_db_detachnode(db, &node);
1458 if (result == ISC_R_NOTFOUND)
1460 if (result != ISC_R_SUCCESS)
1463 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1464 if (result == ISC_R_SUCCESS) {
1465 next_length = nsec3.next_length;
1466 INSIST(next_length <= sizeof(nexthash));
1467 memmove(nexthash, nsec3.next, next_length);
1469 dns_rdataset_disassociate(&rdataset);
1470 if (result == ISC_R_NOMORE)
1472 if (result != ISC_R_SUCCESS)
1477 result = dns_dbiterator_prev(dbit);
1478 if (result == ISC_R_NOMORE) {
1480 CHECK(dns_dbiterator_last(dbit));
1482 CHECK(dns_dbiterator_current(dbit, &node, prev));
1483 CHECK(dns_dbiterator_pause(dbit));
1484 result = dns_db_findrdataset(db, node, version,
1485 dns_rdatatype_nsec3, 0,
1488 dns_db_detachnode(db, &node);
1489 if (result != ISC_R_SUCCESS)
1491 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1492 if (result == ISC_R_NOMORE) {
1493 dns_rdataset_disassociate(&rdataset);
1496 if (result != ISC_R_SUCCESS)
1500 * Delete the old previous NSEC3.
1502 CHECK(delete(db, version, prev, nsec3param, diff));
1505 * Fixup the previous NSEC3.
1507 nsec3.next = nexthash;
1508 nsec3.next_length = (unsigned char)next_length;
1509 isc_buffer_init(&buffer, nsec3buf,
1511 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
1512 dns_rdatatype_nsec3, &nsec3,
1514 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1515 prev, rdataset.ttl, &rdata,
1517 CHECK(do_one_tuple(&tuple, db, version, diff));
1518 dns_rdata_reset(&rdata);
1519 dns_rdataset_disassociate(&rdataset);
1526 * Delete the old NSEC3 and record the change.
1528 CHECK(delete(db, version, hashname, nsec3param, diff));
1532 result = ISC_R_SUCCESS;
1536 dns_dbiterator_destroy(&dbit);
1537 if (dns_rdataset_isassociated(&rdataset))
1538 dns_rdataset_disassociate(&rdataset);
1540 dns_db_detachnode(db, &node);
1545 dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1548 return (dns_nsec3_delnsec3sx(db, version, name, 0, diff));
1552 dns_nsec3_delnsec3sx(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1553 dns_rdatatype_t privatetype, dns_diff_t *diff)
1555 dns_dbnode_t *node = NULL;
1556 dns_rdata_nsec3param_t nsec3param;
1557 dns_rdataset_t rdataset;
1558 isc_result_t result;
1560 dns_rdataset_init(&rdataset);
1563 * Find the NSEC3 parameters for this zone.
1565 result = dns_db_getoriginnode(db, &node);
1566 if (result != ISC_R_SUCCESS)
1569 result = dns_db_findrdataset(db, node, version,
1570 dns_rdatatype_nsec3param, 0, 0,
1572 if (result == ISC_R_NOTFOUND)
1574 if (result != ISC_R_SUCCESS)
1578 * Update each active NSEC3 chain.
1580 for (result = dns_rdataset_first(&rdataset);
1581 result == ISC_R_SUCCESS;
1582 result = dns_rdataset_next(&rdataset)) {
1583 dns_rdata_t rdata = DNS_RDATA_INIT;
1585 dns_rdataset_current(&rdataset, &rdata);
1586 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
1588 if (nsec3param.flags != 0)
1591 * We have a active chain. Update it.
1593 CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
1595 dns_rdataset_disassociate(&rdataset);
1598 if (privatetype == 0)
1600 result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
1602 if (result == ISC_R_NOTFOUND)
1604 if (result != ISC_R_SUCCESS)
1608 * Update each NSEC3 chain being built.
1610 for (result = dns_rdataset_first(&rdataset);
1611 result == ISC_R_SUCCESS;
1612 result = dns_rdataset_next(&rdataset)) {
1613 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1614 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1615 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1617 dns_rdataset_current(&rdataset, &rdata1);
1618 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
1621 CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
1623 if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
1625 if (better_param(&rdataset, &rdata2))
1629 * We have a active chain. Update it.
1631 CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
1633 if (result == ISC_R_NOMORE)
1635 result = ISC_R_SUCCESS;
1638 if (dns_rdataset_isassociated(&rdataset))
1639 dns_rdataset_disassociate(&rdataset);
1641 dns_db_detachnode(db, &node);
1647 dns_nsec3_active(dns_db_t *db, dns_dbversion_t *version,
1648 isc_boolean_t complete, isc_boolean_t *answer)
1650 return (dns_nsec3_activex(db, version, complete, 0, answer));
1654 dns_nsec3_activex(dns_db_t *db, dns_dbversion_t *version,
1655 isc_boolean_t complete, dns_rdatatype_t privatetype,
1656 isc_boolean_t *answer)
1658 dns_dbnode_t *node = NULL;
1659 dns_rdataset_t rdataset;
1660 dns_rdata_nsec3param_t nsec3param;
1661 isc_result_t result;
1663 REQUIRE(answer != NULL);
1665 dns_rdataset_init(&rdataset);
1667 result = dns_db_getoriginnode(db, &node);
1668 if (result != ISC_R_SUCCESS)
1671 result = dns_db_findrdataset(db, node, version,
1672 dns_rdatatype_nsec3param, 0, 0,
1675 if (result == ISC_R_NOTFOUND)
1678 if (result != ISC_R_SUCCESS) {
1679 dns_db_detachnode(db, &node);
1682 for (result = dns_rdataset_first(&rdataset);
1683 result == ISC_R_SUCCESS;
1684 result = dns_rdataset_next(&rdataset)) {
1685 dns_rdata_t rdata = DNS_RDATA_INIT;
1687 dns_rdataset_current(&rdataset, &rdata);
1688 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
1689 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1691 if (nsec3param.flags == 0)
1694 dns_rdataset_disassociate(&rdataset);
1695 if (result == ISC_R_SUCCESS) {
1696 dns_db_detachnode(db, &node);
1698 return (ISC_R_SUCCESS);
1700 if (result == ISC_R_NOMORE)
1701 *answer = ISC_FALSE;
1704 if (privatetype == 0 || complete) {
1705 *answer = ISC_FALSE;
1706 return (ISC_R_SUCCESS);
1708 result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
1711 dns_db_detachnode(db, &node);
1712 if (result == ISC_R_NOTFOUND) {
1713 *answer = ISC_FALSE;
1714 return (ISC_R_SUCCESS);
1716 if (result != ISC_R_SUCCESS)
1719 for (result = dns_rdataset_first(&rdataset);
1720 result == ISC_R_SUCCESS;
1721 result = dns_rdataset_next(&rdataset)) {
1722 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1723 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1724 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1726 dns_rdataset_current(&rdataset, &rdata1);
1727 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
1730 result = dns_rdata_tostruct(&rdata2, &nsec3param, NULL);
1731 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1733 if (!complete && CREATE(nsec3param.flags))
1736 dns_rdataset_disassociate(&rdataset);
1737 if (result == ISC_R_SUCCESS) {
1739 result = ISC_R_SUCCESS;
1741 if (result == ISC_R_NOMORE) {
1742 *answer = ISC_FALSE;
1743 result = ISC_R_SUCCESS;
1750 dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version,
1751 isc_mem_t *mctx, unsigned int *iterationsp)
1753 dns_dbnode_t *node = NULL;
1754 dns_rdataset_t rdataset;
1755 dst_key_t *key = NULL;
1756 isc_buffer_t buffer;
1757 isc_result_t result;
1758 unsigned int bits, minbits = 4096;
1760 result = dns_db_getoriginnode(db, &node);
1761 if (result != ISC_R_SUCCESS)
1764 dns_rdataset_init(&rdataset);
1765 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
1766 0, 0, &rdataset, NULL);
1767 dns_db_detachnode(db, &node);
1768 if (result == ISC_R_NOTFOUND) {
1770 return (ISC_R_SUCCESS);
1772 if (result != ISC_R_SUCCESS)
1775 for (result = dns_rdataset_first(&rdataset);
1776 result == ISC_R_SUCCESS;
1777 result = dns_rdataset_next(&rdataset)) {
1778 dns_rdata_t rdata = DNS_RDATA_INIT;
1780 dns_rdataset_current(&rdataset, &rdata);
1781 isc_buffer_init(&buffer, rdata.data, rdata.length);
1782 isc_buffer_add(&buffer, rdata.length);
1783 CHECK(dst_key_fromdns(dns_db_origin(db), rdataset.rdclass,
1784 &buffer, mctx, &key));
1785 bits = dst_key_size(key);
1790 if (result != ISC_R_NOMORE)
1793 if (minbits <= 1024)
1795 else if (minbits <= 2048)
1798 *iterationsp = 2500;
1799 result = ISC_R_SUCCESS;
1802 if (dns_rdataset_isassociated(&rdataset))
1803 dns_rdataset_disassociate(&rdataset);
1808 dns_nsec3_noexistnodata(dns_rdatatype_t type, dns_name_t* name,
1809 dns_name_t *nsec3name, dns_rdataset_t *nsec3set,
1810 dns_name_t *zonename, isc_boolean_t *exists,
1811 isc_boolean_t *data, isc_boolean_t *optout,
1812 isc_boolean_t *unknown, isc_boolean_t *setclosest,
1813 isc_boolean_t *setnearest, dns_name_t *closest,
1814 dns_name_t *nearest, dns_nseclog_t logit, void *arg)
1816 char namebuf[DNS_NAME_FORMATSIZE];
1817 dns_fixedname_t fzone;
1818 dns_fixedname_t qfixed;
1819 dns_label_t hashlabel;
1822 dns_rdata_nsec3_t nsec3;
1823 dns_rdata_t rdata = DNS_RDATA_INIT;
1826 isc_boolean_t atparent;
1827 isc_boolean_t first;
1830 isc_buffer_t buffer;
1831 isc_result_t answer = ISC_R_IGNORE;
1832 isc_result_t result;
1833 unsigned char hash[NSEC3_MAX_HASH_LENGTH];
1834 unsigned char owner[NSEC3_MAX_HASH_LENGTH];
1835 unsigned int length;
1836 unsigned int qlabels;
1837 unsigned int zlabels;
1839 REQUIRE((exists == NULL && data == NULL) ||
1840 (exists != NULL && data != NULL));
1841 REQUIRE(nsec3set != NULL && nsec3set->type == dns_rdatatype_nsec3);
1842 REQUIRE((setclosest == NULL && closest == NULL) ||
1843 (setclosest != NULL && closest != NULL));
1844 REQUIRE((setnearest == NULL && nearest == NULL) ||
1845 (setnearest != NULL && nearest != NULL));
1847 result = dns_rdataset_first(nsec3set);
1848 if (result != ISC_R_SUCCESS) {
1849 (*logit)(arg, ISC_LOG_DEBUG(3), "failure processing NSEC3 set");
1853 dns_rdataset_current(nsec3set, &rdata);
1855 result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
1856 if (result != ISC_R_SUCCESS)
1859 (*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant NSEC3");
1861 dns_fixedname_init(&fzone);
1862 zone = dns_fixedname_name(&fzone);
1863 zlabels = dns_name_countlabels(nsec3name);
1866 * NSEC3 records must have two or more labels to be valid.
1869 return (ISC_R_IGNORE);
1872 * Strip off the NSEC3 hash to get the zone.
1875 dns_name_split(nsec3name, zlabels, NULL, zone);
1878 * If not below the zone name we can ignore this record.
1880 if (!dns_name_issubdomain(name, zone))
1881 return (ISC_R_IGNORE);
1884 * Is this zone the same or deeper than the current zone?
1886 if (dns_name_countlabels(zonename) == 0 ||
1887 dns_name_issubdomain(zone, zonename))
1888 dns_name_copy(zone, zonename, NULL);
1890 if (!dns_name_equal(zone, zonename))
1891 return (ISC_R_IGNORE);
1894 * Are we only looking for the most enclosing zone?
1896 if (exists == NULL || data == NULL)
1897 return (ISC_R_SUCCESS);
1900 * Only set unknown once we are sure that this NSEC3 is from
1901 * the deepest covering zone.
1903 if (!dns_nsec3_supportedhash(nsec3.hash)) {
1904 if (unknown != NULL)
1905 *unknown = ISC_TRUE;
1906 return (ISC_R_IGNORE);
1910 * Recover the hash from the first label.
1912 dns_name_getlabel(nsec3name, 0, &hashlabel);
1913 isc_region_consume(&hashlabel, 1);
1914 isc_buffer_init(&buffer, owner, sizeof(owner));
1915 result = isc_base32hex_decoderegion(&hashlabel, &buffer);
1916 if (result != ISC_R_SUCCESS)
1920 * The hash lengths should match. If not ignore the record.
1922 if (isc_buffer_usedlength(&buffer) != nsec3.next_length)
1923 return (ISC_R_IGNORE);
1926 * Work out what this NSEC3 covers.
1927 * Inside (<0) or outside (>=0).
1929 scope = memcmp(owner, nsec3.next, nsec3.next_length);
1932 * Prepare to compute all the hashes.
1934 dns_fixedname_init(&qfixed);
1935 qname = dns_fixedname_name(&qfixed);
1936 dns_name_downcase(name, qname, NULL);
1937 qlabels = dns_name_countlabels(qname);
1940 while (qlabels >= zlabels) {
1941 length = isc_iterated_hash(hash, nsec3.hash, nsec3.iterations,
1942 nsec3.salt, nsec3.salt_length,
1943 qname->ndata, qname->length);
1945 * The computed hash length should match.
1947 if (length != nsec3.next_length) {
1948 (*logit)(arg, ISC_LOG_DEBUG(3),
1949 "ignoring NSEC bad length %u vs %u",
1950 length, nsec3.next_length);
1951 return (ISC_R_IGNORE);
1954 order = memcmp(hash, owner, length);
1955 if (first && order == 0) {
1957 * The hashes are the same.
1959 atparent = dns_rdatatype_atparent(type);
1960 ns = dns_nsec3_typepresent(&rdata, dns_rdatatype_ns);
1961 soa = dns_nsec3_typepresent(&rdata, dns_rdatatype_soa);
1965 * This NSEC3 record is from somewhere
1966 * higher in the DNS, and at the
1967 * parent of a delegation. It can not
1968 * be legitimately used here.
1970 (*logit)(arg, ISC_LOG_DEBUG(3),
1971 "ignoring parent NSEC3");
1972 return (ISC_R_IGNORE);
1974 } else if (atparent && ns && soa) {
1976 * This NSEC3 record is from the child.
1977 * It can not be legitimately used here.
1979 (*logit)(arg, ISC_LOG_DEBUG(3),
1980 "ignoring child NSEC3");
1981 return (ISC_R_IGNORE);
1983 if (type == dns_rdatatype_cname ||
1984 type == dns_rdatatype_nxt ||
1985 type == dns_rdatatype_nsec ||
1986 type == dns_rdatatype_key ||
1987 !dns_nsec3_typepresent(&rdata, dns_rdatatype_cname)) {
1989 *data = dns_nsec3_typepresent(&rdata, type);
1990 (*logit)(arg, ISC_LOG_DEBUG(3),
1991 "NSEC3 proves name exists (owner) "
1993 return (ISC_R_SUCCESS);
1995 (*logit)(arg, ISC_LOG_DEBUG(3),
1996 "NSEC3 proves CNAME exists");
1997 return (ISC_R_IGNORE);
2001 dns_nsec3_typepresent(&rdata, dns_rdatatype_ns) &&
2002 !dns_nsec3_typepresent(&rdata, dns_rdatatype_soa))
2005 * This NSEC3 record is from somewhere higher in
2006 * the DNS, and at the parent of a delegation.
2007 * It can not be legitimately used here.
2009 (*logit)(arg, ISC_LOG_DEBUG(3),
2010 "ignoring parent NSEC3");
2011 return (ISC_R_IGNORE);
2015 * Potential closest encloser.
2018 if (closest != NULL &&
2019 (dns_name_countlabels(closest) == 0 ||
2020 dns_name_issubdomain(qname, closest)) &&
2021 !dns_nsec3_typepresent(&rdata, dns_rdatatype_ds) &&
2022 !dns_nsec3_typepresent(&rdata, dns_rdatatype_dname) &&
2023 (dns_nsec3_typepresent(&rdata, dns_rdatatype_soa) ||
2024 !dns_nsec3_typepresent(&rdata, dns_rdatatype_ns)))
2027 dns_name_format(qname, namebuf,
2029 (*logit)(arg, ISC_LOG_DEBUG(3),
2030 "NSEC3 indicates potential closest "
2031 "encloser: '%s'", namebuf);
2032 dns_name_copy(qname, closest, NULL);
2033 *setclosest = ISC_TRUE;
2035 dns_name_format(qname, namebuf, sizeof(namebuf));
2036 (*logit)(arg, ISC_LOG_DEBUG(3),
2037 "NSEC3 at super-domain %s", namebuf);
2042 * Find if the name does not exist.
2044 * We continue as we need to find the name closest to the
2045 * closest encloser that doesn't exist.
2047 * We also need to continue to ensure that we are not
2048 * proving the non-existence of a record in a sub-zone.
2049 * If that would be the case we will return ISC_R_IGNORE
2052 if ((scope < 0 && order > 0 &&
2053 memcmp(hash, nsec3.next, length) < 0) ||
2054 (scope >= 0 && (order > 0 ||
2055 memcmp(hash, nsec3.next, length) < 0)))
2057 char namebuf[DNS_NAME_FORMATSIZE];
2059 dns_name_format(qname, namebuf, sizeof(namebuf));
2060 (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC3 proves "
2061 "name does not exist: '%s'", namebuf);
2062 if (nearest != NULL &&
2063 (dns_name_countlabels(nearest) == 0 ||
2064 dns_name_issubdomain(nearest, qname))) {
2065 dns_name_copy(qname, nearest, NULL);
2066 *setnearest = ISC_TRUE;
2069 *exists = ISC_FALSE;
2071 if (optout != NULL) {
2072 if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0)
2073 (*logit)(arg, ISC_LOG_DEBUG(3),
2074 "NSEC3 indicates optout");
2076 ISC_TF(nsec3.flags & DNS_NSEC3FLAG_OPTOUT);
2078 answer = ISC_R_SUCCESS;
2083 dns_name_split(qname, qlabels, NULL, qname);