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>
37 #include <dns/nsec3.h>
38 #include <dns/rdata.h>
39 #include <dns/rdatalist.h>
40 #include <dns/rdataset.h>
41 #include <dns/rdatasetiter.h>
42 #include <dns/rdatastruct.h>
43 #include <dns/result.h>
45 #define CHECK(x) do { \
47 if (result != ISC_R_SUCCESS) \
51 #define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0)
52 #define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0)
53 #define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
56 set_bit(unsigned char *array, unsigned int index, unsigned int bit) {
57 unsigned int shift, mask;
59 shift = 7 - (index % 8);
63 array[index / 8] |= mask;
65 array[index / 8] &= (~mask & 0xFF);
69 bit_isset(unsigned char *array, unsigned int index) {
70 unsigned int byte, shift, mask;
72 byte = array[index / 8];
73 shift = 7 - (index % 8);
76 return ((byte & mask) != 0);
80 dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
81 dns_dbnode_t *node, unsigned int hashalg,
82 unsigned int flags, unsigned int iterations,
83 const unsigned char *salt, size_t salt_length,
84 const unsigned char *nexthash, size_t hash_length,
85 unsigned char *buffer, dns_rdata_t *rdata)
88 dns_rdataset_t rdataset;
90 unsigned int i, window;
93 isc_boolean_t found_ns;
94 isc_boolean_t need_rrsig;
96 unsigned char *nsec_bits, *bm;
97 unsigned int max_type;
98 dns_rdatasetiter_t *rdsiter;
101 REQUIRE(salt_length < 256U);
102 REQUIRE(hash_length < 256U);
103 REQUIRE(flags <= 0xffU);
104 REQUIRE(hashalg <= 0xffU);
105 REQUIRE(iterations <= 0xffffU);
109 REQUIRE(hash_length == ISC_SHA1_DIGESTLENGTH);
113 memset(buffer, 0, DNS_NSEC3_BUFFERSIZE);
120 *p++ = iterations >> 8;
123 *p++ = (unsigned char)salt_length;
124 memmove(p, salt, salt_length);
127 *p++ = (unsigned char)hash_length;
128 memmove(p, nexthash, hash_length);
131 r.length = (unsigned int)(p - buffer);
135 * Use the end of the space for a raw bitmap leaving enough
136 * space for the window identifiers and length octets.
138 bm = r.base + r.length + 512;
139 nsec_bits = r.base + r.length;
142 goto collapse_bitmap;
143 dns_rdataset_init(&rdataset);
145 result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
146 if (result != ISC_R_SUCCESS)
148 found = found_ns = need_rrsig = ISC_FALSE;
149 for (result = dns_rdatasetiter_first(rdsiter);
150 result == ISC_R_SUCCESS;
151 result = dns_rdatasetiter_next(rdsiter))
153 dns_rdatasetiter_current(rdsiter, &rdataset);
154 if (rdataset.type != dns_rdatatype_nsec &&
155 rdataset.type != dns_rdatatype_nsec3 &&
156 rdataset.type != dns_rdatatype_rrsig) {
157 if (rdataset.type > max_type)
158 max_type = rdataset.type;
159 set_bit(bm, rdataset.type, 1);
161 * Work out if we need to set the RRSIG bit for
162 * this node. We set the RRSIG bit if either of
163 * the following conditions are met:
164 * 1) We have a SOA or DS then we need to set
165 * the RRSIG bit as both always will be signed.
166 * 2) We set the RRSIG bit if we don't have
167 * a NS record but do have other data.
169 if (rdataset.type == dns_rdatatype_soa ||
170 rdataset.type == dns_rdatatype_ds)
171 need_rrsig = ISC_TRUE;
172 else if (rdataset.type == dns_rdatatype_ns)
177 dns_rdataset_disassociate(&rdataset);
179 if ((found && !found_ns) || need_rrsig) {
180 if (dns_rdatatype_rrsig > max_type)
181 max_type = dns_rdatatype_rrsig;
182 set_bit(bm, dns_rdatatype_rrsig, 1);
186 * At zone cuts, deny the existence of glue in the parent zone.
188 if (bit_isset(bm, dns_rdatatype_ns) &&
189 ! bit_isset(bm, dns_rdatatype_soa)) {
190 for (i = 0; i <= max_type; i++) {
191 if (bit_isset(bm, i) &&
192 ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i))
197 dns_rdatasetiter_destroy(&rdsiter);
198 if (result != ISC_R_NOMORE)
202 for (window = 0; window < 256; window++) {
203 if (window * 256 > max_type)
205 for (octet = 31; octet >= 0; octet--)
206 if (bm[window * 32 + octet] != 0)
210 nsec_bits[0] = window;
211 nsec_bits[1] = octet + 1;
213 * Note: potentially overlapping move.
215 memmove(&nsec_bits[2], &bm[window * 32], octet + 1);
216 nsec_bits += 3 + octet;
218 r.length = (unsigned int)(nsec_bits - r.base);
219 INSIST(r.length <= DNS_NSEC3_BUFFERSIZE);
220 dns_rdata_fromregion(rdata, dns_db_class(db), dns_rdatatype_nsec3, &r);
222 return (ISC_R_SUCCESS);
226 dns_nsec3_typepresent(dns_rdata_t *rdata, dns_rdatatype_t type) {
227 dns_rdata_nsec3_t nsec3;
229 isc_boolean_t present;
230 unsigned int i, len, window;
232 REQUIRE(rdata != NULL);
233 REQUIRE(rdata->type == dns_rdatatype_nsec3);
235 /* This should never fail */
236 result = dns_rdata_tostruct(rdata, &nsec3, NULL);
237 INSIST(result == ISC_R_SUCCESS);
240 for (i = 0; i < nsec3.len; i += len) {
241 INSIST(i + 2 <= nsec3.len);
242 window = nsec3.typebits[i];
243 len = nsec3.typebits[i + 1];
244 INSIST(len > 0 && len <= 32);
246 INSIST(i + len <= nsec3.len);
247 if (window * 256 > type)
249 if ((window + 1) * 256 <= type)
251 if (type < (window * 256) + len * 8)
252 present = ISC_TF(bit_isset(&nsec3.typebits[i],
256 dns_rdata_freestruct(&nsec3);
261 dns_nsec3_hashname(dns_fixedname_t *result,
262 unsigned char rethash[NSEC3_MAX_HASH_LENGTH],
263 size_t *hash_length, dns_name_t *name, dns_name_t *origin,
264 dns_hash_t hashalg, unsigned int iterations,
265 const unsigned char *salt, size_t saltlength)
267 unsigned char hash[NSEC3_MAX_HASH_LENGTH];
268 unsigned char nametext[DNS_NAME_FORMATSIZE];
269 dns_fixedname_t fixed;
270 dns_name_t *downcased;
271 isc_buffer_t namebuffer;
278 memset(rethash, 0, NSEC3_MAX_HASH_LENGTH);
280 dns_fixedname_init(&fixed);
281 downcased = dns_fixedname_name(&fixed);
282 dns_name_downcase(name, downcased, NULL);
284 /* hash the node name */
285 len = isc_iterated_hash(rethash, hashalg, iterations,
286 salt, (int)saltlength,
287 downcased->ndata, downcased->length);
289 return (DNS_R_BADALG);
291 if (hash_length != NULL)
294 /* convert the hash to base32hex */
295 region.base = rethash;
296 region.length = (unsigned int)len;
297 isc_buffer_init(&namebuffer, nametext, sizeof nametext);
298 isc_base32hex_totext(®ion, 1, "", &namebuffer);
300 /* convert the hex to a domain name */
301 dns_fixedname_init(result);
302 return (dns_name_fromtext(dns_fixedname_name(result), &namebuffer,
307 dns_nsec3_hashlength(dns_hash_t hash) {
310 case dns_hash_sha1: return(ISC_SHA1_DIGESTLENGTH);
316 dns_nsec3_supportedhash(dns_hash_t hash) {
318 case dns_hash_sha1: return (ISC_TRUE);
324 * Update a single RR in version 'ver' of 'db' and log the
328 * \li '*tuple' == NULL. Either the tuple is freed, or its
329 * ownership has been transferred to the diff.
332 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
335 dns_diff_t temp_diff;
339 * Create a singleton diff.
341 dns_diff_init(diff->mctx, &temp_diff);
342 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
345 * Apply it to the database.
347 result = dns_diff_apply(&temp_diff, db, ver);
348 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
349 if (result != ISC_R_SUCCESS) {
350 dns_difftuple_free(tuple);
355 * Merge it into the current pending journal entry.
357 dns_diff_appendminimal(diff, tuple);
360 * Do not clear temp_diff.
362 return (ISC_R_SUCCESS);
366 * Set '*exists' to true iff the given name exists, to false otherwise.
369 name_exists(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
370 isc_boolean_t *exists)
373 dns_dbnode_t *node = NULL;
374 dns_rdatasetiter_t *iter = NULL;
376 result = dns_db_findnode(db, name, ISC_FALSE, &node);
377 if (result == ISC_R_NOTFOUND) {
379 return (ISC_R_SUCCESS);
381 if (result != ISC_R_SUCCESS)
384 result = dns_db_allrdatasets(db, node, version,
385 (isc_stdtime_t) 0, &iter);
386 if (result != ISC_R_SUCCESS)
389 result = dns_rdatasetiter_first(iter);
390 if (result == ISC_R_SUCCESS) {
392 } else if (result == ISC_R_NOMORE) {
394 result = ISC_R_SUCCESS;
397 dns_rdatasetiter_destroy(&iter);
400 dns_db_detachnode(db, &node);
405 match_nsec3param(const dns_rdata_nsec3_t *nsec3,
406 const dns_rdata_nsec3param_t *nsec3param)
408 if (nsec3->hash == nsec3param->hash &&
409 nsec3->iterations == nsec3param->iterations &&
410 nsec3->salt_length == nsec3param->salt_length &&
411 !memcmp(nsec3->salt, nsec3param->salt, nsec3->salt_length))
417 * Delete NSEC3 records at "name" which match "param", recording the
421 delete(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
422 const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff)
424 dns_dbnode_t *node = NULL ;
425 dns_difftuple_t *tuple = NULL;
426 dns_rdata_nsec3_t nsec3;
427 dns_rdataset_t rdataset;
430 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
431 if (result == ISC_R_NOTFOUND)
432 return (ISC_R_SUCCESS);
433 if (result != ISC_R_SUCCESS)
436 dns_rdataset_init(&rdataset);
437 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, 0,
438 (isc_stdtime_t) 0, &rdataset, NULL);
440 if (result == ISC_R_NOTFOUND) {
441 result = ISC_R_SUCCESS;
444 if (result != ISC_R_SUCCESS)
447 for (result = dns_rdataset_first(&rdataset);
448 result == ISC_R_SUCCESS;
449 result = dns_rdataset_next(&rdataset))
451 dns_rdata_t rdata = DNS_RDATA_INIT;
452 dns_rdataset_current(&rdataset, &rdata);
453 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
455 if (!match_nsec3param(&nsec3, nsec3param))
458 result = dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, name,
459 rdataset.ttl, &rdata, &tuple);
460 if (result != ISC_R_SUCCESS)
462 result = do_one_tuple(&tuple, db, version, diff);
463 if (result != ISC_R_SUCCESS)
466 if (result != ISC_R_NOMORE)
468 result = ISC_R_SUCCESS;
471 dns_rdataset_disassociate(&rdataset);
473 dns_db_detachnode(db, &node);
479 better_param(dns_rdataset_t *nsec3paramset, dns_rdata_t *param) {
480 dns_rdataset_t rdataset;
483 if (REMOVE(param->data[1]))
486 dns_rdataset_init(&rdataset);
487 dns_rdataset_clone(nsec3paramset, &rdataset);
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;
492 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
494 if (rdataset.type != dns_rdatatype_nsec3param) {
495 dns_rdata_t tmprdata = DNS_RDATA_INIT;
496 dns_rdataset_current(&rdataset, &tmprdata);
497 if (!dns_nsec3param_fromprivate(&tmprdata, &rdata,
501 dns_rdataset_current(&rdataset, &rdata);
503 if (rdata.length != param->length)
505 if (rdata.data[0] != param->data[0] ||
506 REMOVE(rdata.data[1]) ||
507 rdata.data[2] != param->data[2] ||
508 rdata.data[3] != param->data[3] ||
509 rdata.data[4] != param->data[4] ||
510 memcmp(&rdata.data[5], ¶m->data[5], param->data[4]))
512 if (CREATE(rdata.data[1]) && !CREATE(param->data[1])) {
513 dns_rdataset_disassociate(&rdataset);
517 dns_rdataset_disassociate(&rdataset);
522 find_nsec3(dns_rdata_nsec3_t *nsec3, dns_rdataset_t *rdataset,
523 const dns_rdata_nsec3param_t *nsec3param)
526 for (result = dns_rdataset_first(rdataset);
527 result == ISC_R_SUCCESS;
528 result = dns_rdataset_next(rdataset)) {
529 dns_rdata_t rdata = DNS_RDATA_INIT;
531 dns_rdataset_current(rdataset, &rdata);
532 CHECK(dns_rdata_tostruct(&rdata, nsec3, NULL));
533 dns_rdata_reset(&rdata);
534 if (match_nsec3param(nsec3, nsec3param))
542 dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version,
543 dns_name_t *name, const dns_rdata_nsec3param_t *nsec3param,
544 dns_ttl_t nsecttl, isc_boolean_t unsecure, dns_diff_t *diff)
546 dns_dbiterator_t *dbit = NULL;
547 dns_dbnode_t *node = NULL;
548 dns_dbnode_t *newnode = NULL;
549 dns_difftuple_t *tuple = NULL;
550 dns_fixedname_t fixed;
551 dns_fixedname_t fprev;
553 dns_name_t *hashname;
557 dns_rdata_nsec3_t nsec3;
558 dns_rdata_t rdata = DNS_RDATA_INIT;
559 dns_rdataset_t rdataset;
561 isc_boolean_t exists = ISC_FALSE;
562 isc_boolean_t maybe_remove_unsecure = ISC_FALSE;
566 unsigned char *old_next;
568 unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
569 unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
570 unsigned int iterations;
573 unsigned int old_length;
574 unsigned int salt_length;
576 dns_fixedname_init(&fixed);
577 hashname = dns_fixedname_name(&fixed);
578 dns_fixedname_init(&fprev);
579 prev = dns_fixedname_name(&fprev);
581 dns_rdataset_init(&rdataset);
583 origin = dns_db_origin(db);
588 hash = nsec3param->hash;
589 iterations = nsec3param->iterations;
590 salt_length = nsec3param->salt_length;
591 salt = nsec3param->salt;
594 * Default flags for a new chain.
596 flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
599 * If this is the first NSEC3 in the chain nexthash will
600 * remain pointing to itself.
602 next_length = sizeof(nexthash);
603 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
604 name, origin, hash, iterations,
608 * Create the node if it doesn't exist and hold
609 * a reference to it until we have added the NSEC3.
611 CHECK(dns_db_findnsec3node(db, hashname, ISC_TRUE, &newnode));
614 * Seek the iterator to the 'newnode'.
616 CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
617 CHECK(dns_dbiterator_seek(dbit, hashname));
618 CHECK(dns_dbiterator_pause(dbit));
619 result = dns_db_findrdataset(db, newnode, version, dns_rdatatype_nsec3,
620 0, (isc_stdtime_t) 0, &rdataset, NULL);
622 * If we updating a existing NSEC3 then find its
625 if (result == ISC_R_SUCCESS) {
626 result = find_nsec3(&nsec3, &rdataset, nsec3param);
627 if (result == ISC_R_SUCCESS) {
628 if (!CREATE(nsec3param->flags))
630 next_length = nsec3.next_length;
631 INSIST(next_length <= sizeof(nexthash));
632 memmove(nexthash, nsec3.next, next_length);
633 dns_rdataset_disassociate(&rdataset);
635 * If the NSEC3 is not for a unsecure delegation then
636 * we are just updating it. If it is for a unsecure
637 * delegation then we need find out if we need to
638 * remove the NSEC3 record or not by examining the
639 * previous NSEC3 record.
643 else if (CREATE(nsec3param->flags) && OPTOUT(flags)) {
644 result = dns_nsec3_delnsec3(db, version, name,
648 maybe_remove_unsecure = ISC_TRUE;
650 dns_rdataset_disassociate(&rdataset);
651 if (result != ISC_R_NOMORE)
657 * Find the previous NSEC3 (if any) and update it if required.
661 result = dns_dbiterator_prev(dbit);
662 if (result == ISC_R_NOMORE) {
664 CHECK(dns_dbiterator_last(dbit));
666 CHECK(dns_dbiterator_current(dbit, &node, prev));
667 CHECK(dns_dbiterator_pause(dbit));
668 result = dns_db_findrdataset(db, node, version,
669 dns_rdatatype_nsec3, 0,
670 (isc_stdtime_t) 0, &rdataset,
672 dns_db_detachnode(db, &node);
673 if (result != ISC_R_SUCCESS)
676 result = find_nsec3(&nsec3, &rdataset, nsec3param);
677 if (result == ISC_R_NOMORE) {
678 dns_rdataset_disassociate(&rdataset);
681 if (result != ISC_R_SUCCESS)
684 if (maybe_remove_unsecure) {
685 dns_rdataset_disassociate(&rdataset);
687 * If we have OPTOUT set in the previous NSEC3 record
688 * we actually need to delete the NSEC3 record.
689 * Otherwise we just need to replace the NSEC3 record.
691 if (OPTOUT(nsec3.flags)) {
692 result = dns_nsec3_delnsec3(db, version, name,
699 * Is this is a unsecure delegation we are adding?
700 * If so no change is required.
702 if (OPTOUT(nsec3.flags) && unsecure) {
703 dns_rdataset_disassociate(&rdataset);
708 old_next = nsec3.next;
709 old_length = nsec3.next_length;
712 * Delete the old previous NSEC3.
714 CHECK(delete(db, version, prev, nsec3param, diff));
717 * Fixup the previous NSEC3.
719 nsec3.next = nexthash;
720 nsec3.next_length = (unsigned char)next_length;
721 isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
722 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
723 dns_rdatatype_nsec3, &nsec3,
725 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
726 rdataset.ttl, &rdata, &tuple));
727 CHECK(do_one_tuple(&tuple, db, version, diff));
728 INSIST(old_length <= sizeof(nexthash));
729 memmove(nexthash, old_next, old_length);
730 if (!CREATE(nsec3param->flags))
732 dns_rdata_reset(&rdata);
733 dns_rdataset_disassociate(&rdataset);
739 * Create the NSEC3 RDATA.
741 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
742 CHECK(dns_nsec3_buildrdata(db, version, node, hash, flags, iterations,
743 salt, salt_length, nexthash, next_length,
745 dns_db_detachnode(db, &node);
748 * Delete the old NSEC3 and record the change.
750 CHECK(delete(db, version, hashname, nsec3param, diff));
752 * Add the new NSEC3 and record the change.
754 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
755 hashname, nsecttl, &rdata, &tuple));
756 CHECK(do_one_tuple(&tuple, db, version, diff));
757 INSIST(tuple == NULL);
758 dns_rdata_reset(&rdata);
759 dns_db_detachnode(db, &newnode);
762 * Add missing NSEC3 records for empty nodes
764 dns_name_init(&empty, NULL);
765 dns_name_clone(name, &empty);
767 labels = dns_name_countlabels(&empty) - 1;
768 if (labels <= dns_name_countlabels(origin))
770 dns_name_getlabelsequence(&empty, 1, labels, &empty);
771 CHECK(name_exists(db, version, &empty, &exists));
774 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
775 &empty, origin, hash, iterations,
779 * Create the node if it doesn't exist and hold
780 * a reference to it until we have added the NSEC3
781 * or we discover we don't need to add make a change.
783 CHECK(dns_db_findnsec3node(db, hashname, ISC_TRUE, &newnode));
784 result = dns_db_findrdataset(db, newnode, version,
785 dns_rdatatype_nsec3, 0,
786 (isc_stdtime_t) 0, &rdataset,
788 if (result == ISC_R_SUCCESS) {
789 result = find_nsec3(&nsec3, &rdataset, nsec3param);
790 dns_rdataset_disassociate(&rdataset);
791 if (result == ISC_R_SUCCESS) {
792 dns_db_detachnode(db, &newnode);
795 if (result != ISC_R_NOMORE)
800 * Find the previous NSEC3 and update it.
802 CHECK(dns_dbiterator_seek(dbit, hashname));
805 result = dns_dbiterator_prev(dbit);
806 if (result == ISC_R_NOMORE) {
808 CHECK(dns_dbiterator_last(dbit));
810 CHECK(dns_dbiterator_current(dbit, &node, prev));
811 CHECK(dns_dbiterator_pause(dbit));
812 result = dns_db_findrdataset(db, node, version,
813 dns_rdatatype_nsec3, 0,
816 dns_db_detachnode(db, &node);
817 if (result != ISC_R_SUCCESS)
819 result = find_nsec3(&nsec3, &rdataset, nsec3param);
820 if (result == ISC_R_NOMORE) {
821 dns_rdataset_disassociate(&rdataset);
824 if (result != ISC_R_SUCCESS)
827 old_next = nsec3.next;
828 old_length = nsec3.next_length;
831 * Delete the old previous NSEC3.
833 CHECK(delete(db, version, prev, nsec3param, diff));
836 * Fixup the previous NSEC3.
838 nsec3.next = nexthash;
839 nsec3.next_length = (unsigned char)next_length;
840 isc_buffer_init(&buffer, nsec3buf,
842 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
843 dns_rdatatype_nsec3, &nsec3,
845 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
846 prev, rdataset.ttl, &rdata,
848 CHECK(do_one_tuple(&tuple, db, version, diff));
849 INSIST(old_length <= sizeof(nexthash));
850 memmove(nexthash, old_next, old_length);
851 if (!CREATE(nsec3param->flags))
853 dns_rdata_reset(&rdata);
854 dns_rdataset_disassociate(&rdataset);
861 * Create the NSEC3 RDATA for the empty node.
863 CHECK(dns_nsec3_buildrdata(db, version, NULL, hash, flags,
864 iterations, salt, salt_length,
865 nexthash, next_length, nsec3buf,
868 * Delete the old NSEC3 and record the change.
870 CHECK(delete(db, version, hashname, nsec3param, diff));
873 * Add the new NSEC3 and record the change.
875 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
876 hashname, nsecttl, &rdata, &tuple));
877 CHECK(do_one_tuple(&tuple, db, version, diff));
878 INSIST(tuple == NULL);
879 dns_rdata_reset(&rdata);
880 dns_db_detachnode(db, &newnode);
883 if (result == ISC_R_NOMORE)
884 result = ISC_R_SUCCESS;
888 dns_dbiterator_destroy(&dbit);
889 if (dns_rdataset_isassociated(&rdataset))
890 dns_rdataset_disassociate(&rdataset);
892 dns_db_detachnode(db, &node);
894 dns_db_detachnode(db, &newnode);
899 * Add NSEC3 records for "name", recording the change in "diff".
900 * The existing NSEC3 records are removed.
903 dns_nsec3_addnsec3s(dns_db_t *db, dns_dbversion_t *version,
904 dns_name_t *name, dns_ttl_t nsecttl,
905 isc_boolean_t unsecure, dns_diff_t *diff)
907 dns_dbnode_t *node = NULL;
908 dns_rdata_nsec3param_t nsec3param;
909 dns_rdataset_t rdataset;
912 dns_rdataset_init(&rdataset);
915 * Find the NSEC3 parameters for this zone.
917 result = dns_db_getoriginnode(db, &node);
918 if (result != ISC_R_SUCCESS)
921 result = dns_db_findrdataset(db, node, version,
922 dns_rdatatype_nsec3param, 0, 0,
924 dns_db_detachnode(db, &node);
925 if (result == ISC_R_NOTFOUND)
926 return (ISC_R_SUCCESS);
927 if (result != ISC_R_SUCCESS)
931 * Update each active NSEC3 chain.
933 for (result = dns_rdataset_first(&rdataset);
934 result == ISC_R_SUCCESS;
935 result = dns_rdataset_next(&rdataset)) {
936 dns_rdata_t rdata = DNS_RDATA_INIT;
938 dns_rdataset_current(&rdataset, &rdata);
939 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
941 if (nsec3param.flags != 0)
944 * We have a active chain. Update it.
946 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
947 nsecttl, unsecure, diff));
949 if (result == ISC_R_NOMORE)
950 result = ISC_R_SUCCESS;
953 if (dns_rdataset_isassociated(&rdataset))
954 dns_rdataset_disassociate(&rdataset);
956 dns_db_detachnode(db, &node);
962 dns_nsec3param_fromprivate(dns_rdata_t *src, dns_rdata_t *target,
963 unsigned char *buf, size_t buflen)
965 dns_decompress_t dctx;
971 * Algorithm 0 (reserved by RFC 4034) is used to identify
972 * NSEC3PARAM records from DNSKEY pointers.
974 if (src->length < 1 || src->data[0] != 0)
977 isc_buffer_init(&buf1, src->data + 1, src->length - 1);
978 isc_buffer_add(&buf1, src->length - 1);
979 isc_buffer_setactive(&buf1, src->length - 1);
980 isc_buffer_init(&buf2, buf, (unsigned int)buflen);
981 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
982 result = dns_rdata_fromwire(target, src->rdclass,
983 dns_rdatatype_nsec3param,
984 &buf1, &dctx, 0, &buf2);
985 dns_decompress_invalidate(&dctx);
987 return (ISC_TF(result == ISC_R_SUCCESS));
991 dns_nsec3param_toprivate(dns_rdata_t *src, dns_rdata_t *target,
992 dns_rdatatype_t privatetype,
993 unsigned char *buf, size_t buflen)
995 REQUIRE(buflen >= src->length + 1);
997 REQUIRE(DNS_RDATA_INITIALIZED(target));
999 memmove(buf + 1, src->data, src->length);
1002 target->length = src->length + 1;
1003 target->type = privatetype;
1004 target->rdclass = src->rdclass;
1006 ISC_LINK_INIT(target, link);
1011 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
1012 const dns_rdata_t *rdata, isc_boolean_t *flag)
1014 dns_rdataset_t rdataset;
1015 dns_dbnode_t *node = NULL;
1016 isc_result_t result;
1018 dns_rdataset_init(&rdataset);
1019 if (rdata->type == dns_rdatatype_nsec3)
1020 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
1022 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
1023 result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
1024 (isc_stdtime_t) 0, &rdataset, NULL);
1025 if (result == ISC_R_NOTFOUND) {
1027 result = ISC_R_SUCCESS;
1031 for (result = dns_rdataset_first(&rdataset);
1032 result == ISC_R_SUCCESS;
1033 result = dns_rdataset_next(&rdataset)) {
1034 dns_rdata_t myrdata = DNS_RDATA_INIT;
1035 dns_rdataset_current(&rdataset, &myrdata);
1036 if (!dns_rdata_casecompare(&myrdata, rdata))
1039 dns_rdataset_disassociate(&rdataset);
1040 if (result == ISC_R_SUCCESS) {
1042 } else if (result == ISC_R_NOMORE) {
1044 result = ISC_R_SUCCESS;
1049 dns_db_detachnode(db, &node);
1056 dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver,
1057 dns_zone_t *zone, dns_diff_t *diff)
1059 dns_dbnode_t *node = NULL;
1060 dns_difftuple_t *tuple = NULL;
1062 dns_rdata_t rdata = DNS_RDATA_INIT;
1063 dns_rdataset_t rdataset;
1065 isc_result_t result = ISC_R_SUCCESS;
1066 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE + 1];
1067 dns_name_t *origin = dns_zone_getorigin(zone);
1068 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
1070 dns_name_init(&next, NULL);
1071 dns_rdataset_init(&rdataset);
1073 result = dns_db_getoriginnode(db, &node);
1074 if (result != ISC_R_SUCCESS)
1078 * Cause all NSEC3 chains to be deleted.
1080 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
1081 0, (isc_stdtime_t) 0, &rdataset, NULL);
1082 if (result == ISC_R_NOTFOUND)
1084 if (result != ISC_R_SUCCESS)
1087 for (result = dns_rdataset_first(&rdataset);
1088 result == ISC_R_SUCCESS;
1089 result = dns_rdataset_next(&rdataset)) {
1090 dns_rdata_t private = DNS_RDATA_INIT;
1092 dns_rdataset_current(&rdataset, &rdata);
1094 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
1095 rdataset.ttl, &rdata, &tuple));
1096 CHECK(do_one_tuple(&tuple, db, ver, diff));
1097 INSIST(tuple == NULL);
1099 dns_nsec3param_toprivate(&rdata, &private, privatetype,
1101 buf[2] = DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC;
1103 CHECK(rr_exists(db, ver, origin, &private, &flag));
1106 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1107 origin, 0, &private,
1109 CHECK(do_one_tuple(&tuple, db, ver, diff));
1110 INSIST(tuple == NULL);
1112 dns_rdata_reset(&rdata);
1114 if (result != ISC_R_NOMORE)
1117 dns_rdataset_disassociate(&rdataset);
1120 if (privatetype == 0)
1122 result = dns_db_findrdataset(db, node, ver, privatetype, 0,
1123 (isc_stdtime_t) 0, &rdataset, NULL);
1124 if (result == ISC_R_NOTFOUND)
1126 if (result != ISC_R_SUCCESS)
1129 for (result = dns_rdataset_first(&rdataset);
1130 result == ISC_R_SUCCESS;
1131 result = dns_rdataset_next(&rdataset)) {
1132 dns_rdataset_current(&rdataset, &rdata);
1133 INSIST(rdata.length <= sizeof(buf));
1134 memmove(buf, rdata.data, rdata.length);
1137 * Private NSEC3 record length >= 6.
1138 * <0(1), hash(1), flags(1), iterations(2), saltlen(1)>
1140 if (rdata.length < 6 || buf[0] != 0 ||
1141 buf[2] == (DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC)) {
1142 dns_rdata_reset(&rdata);
1146 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
1147 0, &rdata, &tuple));
1148 CHECK(do_one_tuple(&tuple, db, ver, diff));
1149 INSIST(tuple == NULL);
1152 buf[2] = DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC;
1154 CHECK(rr_exists(db, ver, origin, &rdata, &flag));
1157 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1158 origin, 0, &rdata, &tuple));
1159 CHECK(do_one_tuple(&tuple, db, ver, diff));
1160 INSIST(tuple == NULL);
1162 dns_rdata_reset(&rdata);
1164 if (result != ISC_R_NOMORE)
1167 result = ISC_R_SUCCESS;
1170 if (dns_rdataset_isassociated(&rdataset))
1171 dns_rdataset_disassociate(&rdataset);
1172 dns_db_detachnode(db, &node);
1178 dns_nsec3_addnsec3sx(dns_db_t *db, dns_dbversion_t *version,
1179 dns_name_t *name, dns_ttl_t nsecttl,
1180 isc_boolean_t unsecure, dns_rdatatype_t type,
1183 dns_dbnode_t *node = NULL;
1184 dns_rdata_nsec3param_t nsec3param;
1185 dns_rdataset_t rdataset;
1186 dns_rdataset_t prdataset;
1187 isc_result_t result;
1189 dns_rdataset_init(&rdataset);
1190 dns_rdataset_init(&prdataset);
1193 * Find the NSEC3 parameters for this zone.
1195 result = dns_db_getoriginnode(db, &node);
1196 if (result != ISC_R_SUCCESS)
1199 result = dns_db_findrdataset(db, node, version, type, 0, 0,
1201 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
1204 result = dns_db_findrdataset(db, node, version,
1205 dns_rdatatype_nsec3param, 0, 0,
1207 if (result == ISC_R_NOTFOUND)
1209 if (result != ISC_R_SUCCESS)
1213 * Update each active NSEC3 chain.
1215 for (result = dns_rdataset_first(&rdataset);
1216 result == ISC_R_SUCCESS;
1217 result = dns_rdataset_next(&rdataset)) {
1218 dns_rdata_t rdata = DNS_RDATA_INIT;
1220 dns_rdataset_current(&rdataset, &rdata);
1221 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
1223 if (nsec3param.flags != 0)
1227 * We have a active chain. Update it.
1229 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
1230 nsecttl, unsecure, diff));
1232 if (result != ISC_R_NOMORE)
1235 dns_rdataset_disassociate(&rdataset);
1238 if (!dns_rdataset_isassociated(&prdataset))
1241 * Update each active NSEC3 chain.
1243 for (result = dns_rdataset_first(&prdataset);
1244 result == ISC_R_SUCCESS;
1245 result = dns_rdataset_next(&prdataset)) {
1246 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1247 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1248 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1250 dns_rdataset_current(&prdataset, &rdata1);
1251 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
1254 CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
1256 if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
1258 if (better_param(&prdataset, &rdata2))
1262 * We have a active chain. Update it.
1264 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
1265 nsecttl, unsecure, diff));
1267 if (result == ISC_R_NOMORE)
1269 result = ISC_R_SUCCESS;
1271 if (dns_rdataset_isassociated(&rdataset))
1272 dns_rdataset_disassociate(&rdataset);
1273 if (dns_rdataset_isassociated(&prdataset))
1274 dns_rdataset_disassociate(&prdataset);
1276 dns_db_detachnode(db, &node);
1282 * Determine whether any NSEC3 records that were associated with
1283 * 'name' should be deleted or if they should continue to exist.
1284 * ISC_TRUE indicates they should be deleted.
1285 * ISC_FALSE indicates they should be retained.
1288 deleteit(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
1289 isc_boolean_t *yesno)
1291 isc_result_t result;
1292 dns_fixedname_t foundname;
1293 dns_fixedname_init(&foundname);
1295 result = dns_db_find(db, name, ver, dns_rdatatype_any,
1296 DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD,
1297 (isc_stdtime_t) 0, NULL,
1298 dns_fixedname_name(&foundname),
1300 if (result == DNS_R_EMPTYNAME || result == ISC_R_SUCCESS ||
1301 result == DNS_R_ZONECUT) {
1303 return (ISC_R_SUCCESS);
1305 if (result == DNS_R_GLUE || result == DNS_R_DNAME ||
1306 result == DNS_R_DELEGATION || result == DNS_R_NXDOMAIN) {
1308 return (ISC_R_SUCCESS);
1318 dns_nsec3_delnsec3(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1319 const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff)
1321 dns_dbiterator_t *dbit = NULL;
1322 dns_dbnode_t *node = NULL;
1323 dns_difftuple_t *tuple = NULL;
1324 dns_fixedname_t fixed;
1325 dns_fixedname_t fprev;
1327 dns_name_t *hashname;
1331 dns_rdata_nsec3_t nsec3;
1332 dns_rdata_t rdata = DNS_RDATA_INIT;
1333 dns_rdataset_t rdataset;
1335 isc_boolean_t yesno;
1336 isc_buffer_t buffer;
1337 isc_result_t result;
1338 unsigned char *salt;
1339 unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
1340 unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
1341 unsigned int iterations;
1342 unsigned int labels;
1344 unsigned int salt_length;
1346 dns_fixedname_init(&fixed);
1347 hashname = dns_fixedname_name(&fixed);
1348 dns_fixedname_init(&fprev);
1349 prev = dns_fixedname_name(&fprev);
1351 dns_rdataset_init(&rdataset);
1353 origin = dns_db_origin(db);
1358 hash = nsec3param->hash;
1359 iterations = nsec3param->iterations;
1360 salt_length = nsec3param->salt_length;
1361 salt = nsec3param->salt;
1364 * If this is the first NSEC3 in the chain nexthash will
1365 * remain pointing to itself.
1367 next_length = sizeof(nexthash);
1368 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
1369 name, origin, hash, iterations,
1370 salt, salt_length));
1372 CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
1374 result = dns_dbiterator_seek(dbit, hashname);
1375 if (result == ISC_R_NOTFOUND)
1377 if (result != ISC_R_SUCCESS)
1380 CHECK(dns_dbiterator_current(dbit, &node, NULL));
1381 CHECK(dns_dbiterator_pause(dbit));
1382 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3,
1383 0, (isc_stdtime_t) 0, &rdataset, NULL);
1384 dns_db_detachnode(db, &node);
1385 if (result == ISC_R_NOTFOUND)
1387 if (result != ISC_R_SUCCESS)
1391 * If we find a existing NSEC3 for this chain then save the
1394 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1395 if (result == ISC_R_SUCCESS) {
1396 next_length = nsec3.next_length;
1397 INSIST(next_length <= sizeof(nexthash));
1398 memmove(nexthash, nsec3.next, next_length);
1400 dns_rdataset_disassociate(&rdataset);
1401 if (result == ISC_R_NOMORE)
1403 if (result != ISC_R_SUCCESS)
1407 * Find the previous NSEC3 and update it.
1411 result = dns_dbiterator_prev(dbit);
1412 if (result == ISC_R_NOMORE) {
1414 CHECK(dns_dbiterator_last(dbit));
1416 CHECK(dns_dbiterator_current(dbit, &node, prev));
1417 CHECK(dns_dbiterator_pause(dbit));
1418 result = dns_db_findrdataset(db, node, version,
1419 dns_rdatatype_nsec3, 0,
1420 (isc_stdtime_t) 0, &rdataset,
1422 dns_db_detachnode(db, &node);
1423 if (result != ISC_R_SUCCESS)
1425 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1426 if (result == ISC_R_NOMORE) {
1427 dns_rdataset_disassociate(&rdataset);
1430 if (result != ISC_R_SUCCESS)
1434 * Delete the old previous NSEC3.
1436 CHECK(delete(db, version, prev, nsec3param, diff));
1439 * Fixup the previous NSEC3.
1441 nsec3.next = nexthash;
1442 nsec3.next_length = (unsigned char)next_length;
1443 if (CREATE(nsec3param->flags))
1444 nsec3.flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
1445 isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
1446 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
1447 dns_rdatatype_nsec3, &nsec3,
1449 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
1450 rdataset.ttl, &rdata, &tuple));
1451 CHECK(do_one_tuple(&tuple, db, version, diff));
1452 dns_rdata_reset(&rdata);
1453 dns_rdataset_disassociate(&rdataset);
1458 * Delete the old NSEC3 and record the change.
1460 CHECK(delete(db, version, hashname, nsec3param, diff));
1463 * Delete NSEC3 records for now non active nodes.
1465 dns_name_init(&empty, NULL);
1466 dns_name_clone(name, &empty);
1468 labels = dns_name_countlabels(&empty) - 1;
1469 if (labels <= dns_name_countlabels(origin))
1471 dns_name_getlabelsequence(&empty, 1, labels, &empty);
1472 CHECK(deleteit(db, version, &empty, &yesno));
1476 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
1477 &empty, origin, hash, iterations,
1478 salt, salt_length));
1479 result = dns_dbiterator_seek(dbit, hashname);
1480 if (result == ISC_R_NOTFOUND)
1482 if (result != ISC_R_SUCCESS)
1485 CHECK(dns_dbiterator_current(dbit, &node, NULL));
1486 CHECK(dns_dbiterator_pause(dbit));
1487 result = dns_db_findrdataset(db, node, version,
1488 dns_rdatatype_nsec3, 0,
1489 (isc_stdtime_t) 0, &rdataset,
1491 dns_db_detachnode(db, &node);
1492 if (result == ISC_R_NOTFOUND)
1494 if (result != ISC_R_SUCCESS)
1497 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1498 if (result == ISC_R_SUCCESS) {
1499 next_length = nsec3.next_length;
1500 INSIST(next_length <= sizeof(nexthash));
1501 memmove(nexthash, nsec3.next, next_length);
1503 dns_rdataset_disassociate(&rdataset);
1504 if (result == ISC_R_NOMORE)
1506 if (result != ISC_R_SUCCESS)
1511 result = dns_dbiterator_prev(dbit);
1512 if (result == ISC_R_NOMORE) {
1514 CHECK(dns_dbiterator_last(dbit));
1516 CHECK(dns_dbiterator_current(dbit, &node, prev));
1517 CHECK(dns_dbiterator_pause(dbit));
1518 result = dns_db_findrdataset(db, node, version,
1519 dns_rdatatype_nsec3, 0,
1522 dns_db_detachnode(db, &node);
1523 if (result != ISC_R_SUCCESS)
1525 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1526 if (result == ISC_R_NOMORE) {
1527 dns_rdataset_disassociate(&rdataset);
1530 if (result != ISC_R_SUCCESS)
1534 * Delete the old previous NSEC3.
1536 CHECK(delete(db, version, prev, nsec3param, diff));
1539 * Fixup the previous NSEC3.
1541 nsec3.next = nexthash;
1542 nsec3.next_length = (unsigned char)next_length;
1543 isc_buffer_init(&buffer, nsec3buf,
1545 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
1546 dns_rdatatype_nsec3, &nsec3,
1548 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1549 prev, rdataset.ttl, &rdata,
1551 CHECK(do_one_tuple(&tuple, db, version, diff));
1552 dns_rdata_reset(&rdata);
1553 dns_rdataset_disassociate(&rdataset);
1560 * Delete the old NSEC3 and record the change.
1562 CHECK(delete(db, version, hashname, nsec3param, diff));
1566 result = ISC_R_SUCCESS;
1570 dns_dbiterator_destroy(&dbit);
1571 if (dns_rdataset_isassociated(&rdataset))
1572 dns_rdataset_disassociate(&rdataset);
1574 dns_db_detachnode(db, &node);
1579 dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1582 return (dns_nsec3_delnsec3sx(db, version, name, 0, diff));
1586 dns_nsec3_delnsec3sx(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1587 dns_rdatatype_t privatetype, dns_diff_t *diff)
1589 dns_dbnode_t *node = NULL;
1590 dns_rdata_nsec3param_t nsec3param;
1591 dns_rdataset_t rdataset;
1592 isc_result_t result;
1594 dns_rdataset_init(&rdataset);
1597 * Find the NSEC3 parameters for this zone.
1599 result = dns_db_getoriginnode(db, &node);
1600 if (result != ISC_R_SUCCESS)
1603 result = dns_db_findrdataset(db, node, version,
1604 dns_rdatatype_nsec3param, 0, 0,
1606 if (result == ISC_R_NOTFOUND)
1608 if (result != ISC_R_SUCCESS)
1612 * Update each active NSEC3 chain.
1614 for (result = dns_rdataset_first(&rdataset);
1615 result == ISC_R_SUCCESS;
1616 result = dns_rdataset_next(&rdataset)) {
1617 dns_rdata_t rdata = DNS_RDATA_INIT;
1619 dns_rdataset_current(&rdataset, &rdata);
1620 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
1622 if (nsec3param.flags != 0)
1625 * We have a active chain. Update it.
1627 CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
1629 dns_rdataset_disassociate(&rdataset);
1632 if (privatetype == 0)
1634 result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
1636 if (result == ISC_R_NOTFOUND)
1638 if (result != ISC_R_SUCCESS)
1642 * Update each NSEC3 chain being built.
1644 for (result = dns_rdataset_first(&rdataset);
1645 result == ISC_R_SUCCESS;
1646 result = dns_rdataset_next(&rdataset)) {
1647 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1648 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1649 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1651 dns_rdataset_current(&rdataset, &rdata1);
1652 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
1655 CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
1657 if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
1659 if (better_param(&rdataset, &rdata2))
1663 * We have a active chain. Update it.
1665 CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
1667 if (result == ISC_R_NOMORE)
1669 result = ISC_R_SUCCESS;
1672 if (dns_rdataset_isassociated(&rdataset))
1673 dns_rdataset_disassociate(&rdataset);
1675 dns_db_detachnode(db, &node);
1681 dns_nsec3_active(dns_db_t *db, dns_dbversion_t *version,
1682 isc_boolean_t complete, isc_boolean_t *answer)
1684 return (dns_nsec3_activex(db, version, complete, 0, answer));
1688 dns_nsec3_activex(dns_db_t *db, dns_dbversion_t *version,
1689 isc_boolean_t complete, dns_rdatatype_t privatetype,
1690 isc_boolean_t *answer)
1692 dns_dbnode_t *node = NULL;
1693 dns_rdataset_t rdataset;
1694 dns_rdata_nsec3param_t nsec3param;
1695 isc_result_t result;
1697 REQUIRE(answer != NULL);
1699 dns_rdataset_init(&rdataset);
1701 result = dns_db_getoriginnode(db, &node);
1702 if (result != ISC_R_SUCCESS)
1705 result = dns_db_findrdataset(db, node, version,
1706 dns_rdatatype_nsec3param, 0, 0,
1709 if (result == ISC_R_NOTFOUND)
1712 if (result != ISC_R_SUCCESS) {
1713 dns_db_detachnode(db, &node);
1716 for (result = dns_rdataset_first(&rdataset);
1717 result == ISC_R_SUCCESS;
1718 result = dns_rdataset_next(&rdataset)) {
1719 dns_rdata_t rdata = DNS_RDATA_INIT;
1721 dns_rdataset_current(&rdataset, &rdata);
1722 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
1723 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1725 if (nsec3param.flags == 0)
1728 dns_rdataset_disassociate(&rdataset);
1729 if (result == ISC_R_SUCCESS) {
1730 dns_db_detachnode(db, &node);
1732 return (ISC_R_SUCCESS);
1734 if (result == ISC_R_NOMORE)
1735 *answer = ISC_FALSE;
1738 if (privatetype == 0 || complete) {
1739 *answer = ISC_FALSE;
1740 return (ISC_R_SUCCESS);
1742 result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
1745 dns_db_detachnode(db, &node);
1746 if (result == ISC_R_NOTFOUND) {
1747 *answer = ISC_FALSE;
1748 return (ISC_R_SUCCESS);
1750 if (result != ISC_R_SUCCESS)
1753 for (result = dns_rdataset_first(&rdataset);
1754 result == ISC_R_SUCCESS;
1755 result = dns_rdataset_next(&rdataset)) {
1756 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1757 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1758 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1760 dns_rdataset_current(&rdataset, &rdata1);
1761 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
1764 result = dns_rdata_tostruct(&rdata2, &nsec3param, NULL);
1765 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1767 if (!complete && CREATE(nsec3param.flags))
1770 dns_rdataset_disassociate(&rdataset);
1771 if (result == ISC_R_SUCCESS) {
1773 result = ISC_R_SUCCESS;
1775 if (result == ISC_R_NOMORE) {
1776 *answer = ISC_FALSE;
1777 result = ISC_R_SUCCESS;
1784 dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version,
1785 isc_mem_t *mctx, unsigned int *iterationsp)
1787 dns_dbnode_t *node = NULL;
1788 dns_rdataset_t rdataset;
1789 dst_key_t *key = NULL;
1790 isc_buffer_t buffer;
1791 isc_result_t result;
1792 unsigned int bits, minbits = 4096;
1794 result = dns_db_getoriginnode(db, &node);
1795 if (result != ISC_R_SUCCESS)
1798 dns_rdataset_init(&rdataset);
1799 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
1800 0, 0, &rdataset, NULL);
1801 dns_db_detachnode(db, &node);
1802 if (result == ISC_R_NOTFOUND) {
1804 return (ISC_R_SUCCESS);
1806 if (result != ISC_R_SUCCESS)
1809 for (result = dns_rdataset_first(&rdataset);
1810 result == ISC_R_SUCCESS;
1811 result = dns_rdataset_next(&rdataset)) {
1812 dns_rdata_t rdata = DNS_RDATA_INIT;
1814 dns_rdataset_current(&rdataset, &rdata);
1815 isc_buffer_init(&buffer, rdata.data, rdata.length);
1816 isc_buffer_add(&buffer, rdata.length);
1817 CHECK(dst_key_fromdns(dns_db_origin(db), rdataset.rdclass,
1818 &buffer, mctx, &key));
1819 bits = dst_key_size(key);
1824 if (result != ISC_R_NOMORE)
1827 if (minbits <= 1024)
1829 else if (minbits <= 2048)
1832 *iterationsp = 2500;
1833 result = ISC_R_SUCCESS;
1836 if (dns_rdataset_isassociated(&rdataset))
1837 dns_rdataset_disassociate(&rdataset);
1842 dns_nsec3_noexistnodata(dns_rdatatype_t type, dns_name_t* name,
1843 dns_name_t *nsec3name, dns_rdataset_t *nsec3set,
1844 dns_name_t *zonename, isc_boolean_t *exists,
1845 isc_boolean_t *data, isc_boolean_t *optout,
1846 isc_boolean_t *unknown, isc_boolean_t *setclosest,
1847 isc_boolean_t *setnearest, dns_name_t *closest,
1848 dns_name_t *nearest, dns_nseclog_t logit, void *arg)
1850 char namebuf[DNS_NAME_FORMATSIZE];
1851 dns_fixedname_t fzone;
1852 dns_fixedname_t qfixed;
1853 dns_label_t hashlabel;
1856 dns_rdata_nsec3_t nsec3;
1857 dns_rdata_t rdata = DNS_RDATA_INIT;
1860 isc_boolean_t atparent;
1861 isc_boolean_t first;
1864 isc_buffer_t buffer;
1865 isc_result_t answer = ISC_R_IGNORE;
1866 isc_result_t result;
1867 unsigned char hash[NSEC3_MAX_HASH_LENGTH];
1868 unsigned char owner[NSEC3_MAX_HASH_LENGTH];
1869 unsigned int length;
1870 unsigned int qlabels;
1871 unsigned int zlabels;
1873 REQUIRE((exists == NULL && data == NULL) ||
1874 (exists != NULL && data != NULL));
1875 REQUIRE(nsec3set != NULL && nsec3set->type == dns_rdatatype_nsec3);
1876 REQUIRE((setclosest == NULL && closest == NULL) ||
1877 (setclosest != NULL && closest != NULL));
1878 REQUIRE((setnearest == NULL && nearest == NULL) ||
1879 (setnearest != NULL && nearest != NULL));
1881 result = dns_rdataset_first(nsec3set);
1882 if (result != ISC_R_SUCCESS) {
1883 (*logit)(arg, ISC_LOG_DEBUG(3), "failure processing NSEC3 set");
1887 dns_rdataset_current(nsec3set, &rdata);
1889 result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
1890 if (result != ISC_R_SUCCESS)
1893 (*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant NSEC3");
1895 dns_fixedname_init(&fzone);
1896 zone = dns_fixedname_name(&fzone);
1897 zlabels = dns_name_countlabels(nsec3name);
1900 * NSEC3 records must have two or more labels to be valid.
1903 return (ISC_R_IGNORE);
1906 * Strip off the NSEC3 hash to get the zone.
1909 dns_name_split(nsec3name, zlabels, NULL, zone);
1912 * If not below the zone name we can ignore this record.
1914 if (!dns_name_issubdomain(name, zone))
1915 return (ISC_R_IGNORE);
1918 * Is this zone the same or deeper than the current zone?
1920 if (dns_name_countlabels(zonename) == 0 ||
1921 dns_name_issubdomain(zone, zonename))
1922 dns_name_copy(zone, zonename, NULL);
1924 if (!dns_name_equal(zone, zonename))
1925 return (ISC_R_IGNORE);
1928 * Are we only looking for the most enclosing zone?
1930 if (exists == NULL || data == NULL)
1931 return (ISC_R_SUCCESS);
1934 * Only set unknown once we are sure that this NSEC3 is from
1935 * the deepest covering zone.
1937 if (!dns_nsec3_supportedhash(nsec3.hash)) {
1938 if (unknown != NULL)
1939 *unknown = ISC_TRUE;
1940 return (ISC_R_IGNORE);
1944 * Recover the hash from the first label.
1946 dns_name_getlabel(nsec3name, 0, &hashlabel);
1947 isc_region_consume(&hashlabel, 1);
1948 isc_buffer_init(&buffer, owner, sizeof(owner));
1949 result = isc_base32hex_decoderegion(&hashlabel, &buffer);
1950 if (result != ISC_R_SUCCESS)
1954 * The hash lengths should match. If not ignore the record.
1956 if (isc_buffer_usedlength(&buffer) != nsec3.next_length)
1957 return (ISC_R_IGNORE);
1960 * Work out what this NSEC3 covers.
1961 * Inside (<0) or outside (>=0).
1963 scope = memcmp(owner, nsec3.next, nsec3.next_length);
1966 * Prepare to compute all the hashes.
1968 dns_fixedname_init(&qfixed);
1969 qname = dns_fixedname_name(&qfixed);
1970 dns_name_downcase(name, qname, NULL);
1971 qlabels = dns_name_countlabels(qname);
1974 while (qlabels >= zlabels) {
1975 length = isc_iterated_hash(hash, nsec3.hash, nsec3.iterations,
1976 nsec3.salt, nsec3.salt_length,
1977 qname->ndata, qname->length);
1979 * The computed hash length should match.
1981 if (length != nsec3.next_length) {
1982 (*logit)(arg, ISC_LOG_DEBUG(3),
1983 "ignoring NSEC bad length %u vs %u",
1984 length, nsec3.next_length);
1985 return (ISC_R_IGNORE);
1988 order = memcmp(hash, owner, length);
1989 if (first && order == 0) {
1991 * The hashes are the same.
1993 atparent = dns_rdatatype_atparent(type);
1994 ns = dns_nsec3_typepresent(&rdata, dns_rdatatype_ns);
1995 soa = dns_nsec3_typepresent(&rdata, dns_rdatatype_soa);
1999 * This NSEC3 record is from somewhere
2000 * higher in the DNS, and at the
2001 * parent of a delegation. It can not
2002 * be legitimately used here.
2004 (*logit)(arg, ISC_LOG_DEBUG(3),
2005 "ignoring parent NSEC3");
2006 return (ISC_R_IGNORE);
2008 } else if (atparent && ns && soa) {
2010 * This NSEC3 record is from the child.
2011 * It can not be legitimately used here.
2013 (*logit)(arg, ISC_LOG_DEBUG(3),
2014 "ignoring child NSEC3");
2015 return (ISC_R_IGNORE);
2017 if (type == dns_rdatatype_cname ||
2018 type == dns_rdatatype_nxt ||
2019 type == dns_rdatatype_nsec ||
2020 type == dns_rdatatype_key ||
2021 !dns_nsec3_typepresent(&rdata, dns_rdatatype_cname)) {
2023 *data = dns_nsec3_typepresent(&rdata, type);
2024 (*logit)(arg, ISC_LOG_DEBUG(3),
2025 "NSEC3 proves name exists (owner) "
2027 return (ISC_R_SUCCESS);
2029 (*logit)(arg, ISC_LOG_DEBUG(3),
2030 "NSEC3 proves CNAME exists");
2031 return (ISC_R_IGNORE);
2035 dns_nsec3_typepresent(&rdata, dns_rdatatype_ns) &&
2036 !dns_nsec3_typepresent(&rdata, dns_rdatatype_soa))
2039 * This NSEC3 record is from somewhere higher in
2040 * the DNS, and at the parent of a delegation.
2041 * It can not be legitimately used here.
2043 (*logit)(arg, ISC_LOG_DEBUG(3),
2044 "ignoring parent NSEC3");
2045 return (ISC_R_IGNORE);
2049 * Potential closest encloser.
2052 if (closest != NULL &&
2053 (dns_name_countlabels(closest) == 0 ||
2054 dns_name_issubdomain(qname, closest)) &&
2055 !dns_nsec3_typepresent(&rdata, dns_rdatatype_ds) &&
2056 !dns_nsec3_typepresent(&rdata, dns_rdatatype_dname) &&
2057 (dns_nsec3_typepresent(&rdata, dns_rdatatype_soa) ||
2058 !dns_nsec3_typepresent(&rdata, dns_rdatatype_ns)))
2061 dns_name_format(qname, namebuf,
2063 (*logit)(arg, ISC_LOG_DEBUG(3),
2064 "NSEC3 indicates potential closest "
2065 "encloser: '%s'", namebuf);
2066 dns_name_copy(qname, closest, NULL);
2067 *setclosest = ISC_TRUE;
2069 dns_name_format(qname, namebuf, sizeof(namebuf));
2070 (*logit)(arg, ISC_LOG_DEBUG(3),
2071 "NSEC3 at super-domain %s", namebuf);
2076 * Find if the name does not exist.
2078 * We continue as we need to find the name closest to the
2079 * closest encloser that doesn't exist.
2081 * We also need to continue to ensure that we are not
2082 * proving the non-existence of a record in a sub-zone.
2083 * If that would be the case we will return ISC_R_IGNORE
2086 if ((scope < 0 && order > 0 &&
2087 memcmp(hash, nsec3.next, length) < 0) ||
2088 (scope >= 0 && (order > 0 ||
2089 memcmp(hash, nsec3.next, length) < 0)))
2091 char namebuf[DNS_NAME_FORMATSIZE];
2093 dns_name_format(qname, namebuf, sizeof(namebuf));
2094 (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC3 proves "
2095 "name does not exist: '%s'", namebuf);
2096 if (nearest != NULL &&
2097 (dns_name_countlabels(nearest) == 0 ||
2098 dns_name_issubdomain(nearest, qname))) {
2099 dns_name_copy(qname, nearest, NULL);
2100 *setnearest = ISC_TRUE;
2103 *exists = ISC_FALSE;
2105 if (optout != NULL) {
2106 if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0)
2107 (*logit)(arg, ISC_LOG_DEBUG(3),
2108 "NSEC3 indicates optout");
2110 ISC_TF(nsec3.flags & DNS_NSEC3FLAG_OPTOUT);
2112 answer = ISC_R_SUCCESS;
2117 dns_name_split(qname, qlabels, NULL, qname);