2 * Copyright (C) 2006, 2008-2012 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>
25 #include <isc/string.h>
32 #include <dns/compress.h>
33 #include <dns/dbiterator.h>
35 #include <dns/fixedname.h>
36 #include <dns/nsec3.h>
37 #include <dns/rdata.h>
38 #include <dns/rdatalist.h>
39 #include <dns/rdataset.h>
40 #include <dns/rdatasetiter.h>
41 #include <dns/rdatastruct.h>
42 #include <dns/result.h>
44 #define CHECK(x) do { \
46 if (result != ISC_R_SUCCESS) \
50 #define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0)
51 #define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0)
52 #define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
55 set_bit(unsigned char *array, unsigned int index, unsigned int bit) {
56 unsigned int shift, mask;
58 shift = 7 - (index % 8);
62 array[index / 8] |= mask;
64 array[index / 8] &= (~mask & 0xFF);
68 bit_isset(unsigned char *array, unsigned int index) {
69 unsigned int byte, shift, mask;
71 byte = array[index / 8];
72 shift = 7 - (index % 8);
75 return ((byte & mask) != 0);
79 dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
80 dns_dbnode_t *node, unsigned int hashalg,
81 unsigned int flags, unsigned int iterations,
82 const unsigned char *salt, size_t salt_length,
83 const unsigned char *nexthash, size_t hash_length,
84 unsigned char *buffer, dns_rdata_t *rdata)
87 dns_rdataset_t rdataset;
89 unsigned int i, window;
92 isc_boolean_t found_ns;
93 isc_boolean_t need_rrsig;
95 unsigned char *nsec_bits, *bm;
96 unsigned int max_type;
97 dns_rdatasetiter_t *rdsiter;
100 REQUIRE(salt_length < 256U);
101 REQUIRE(hash_length < 256U);
102 REQUIRE(flags <= 0xffU);
103 REQUIRE(hashalg <= 0xffU);
104 REQUIRE(iterations <= 0xffffU);
108 REQUIRE(hash_length == ISC_SHA1_DIGESTLENGTH);
112 memset(buffer, 0, DNS_NSEC3_BUFFERSIZE);
119 *p++ = iterations >> 8;
123 memcpy(p, salt, salt_length);
127 memcpy(p, nexthash, hash_length);
130 r.length = p - buffer;
134 * Use the end of the space for a raw bitmap leaving enough
135 * space for the window identifiers and length octets.
137 bm = r.base + r.length + 512;
138 nsec_bits = r.base + r.length;
141 goto collapse_bitmap;
142 dns_rdataset_init(&rdataset);
144 result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
145 if (result != ISC_R_SUCCESS)
147 found = found_ns = need_rrsig = ISC_FALSE;
148 for (result = dns_rdatasetiter_first(rdsiter);
149 result == ISC_R_SUCCESS;
150 result = dns_rdatasetiter_next(rdsiter))
152 dns_rdatasetiter_current(rdsiter, &rdataset);
153 if (rdataset.type != dns_rdatatype_nsec &&
154 rdataset.type != dns_rdatatype_nsec3 &&
155 rdataset.type != dns_rdatatype_rrsig) {
156 if (rdataset.type > max_type)
157 max_type = rdataset.type;
158 set_bit(bm, rdataset.type, 1);
160 * Work out if we need to set the RRSIG bit for
161 * this node. We set the RRSIG bit if either of
162 * the following conditions are met:
163 * 1) We have a SOA or DS then we need to set
164 * the RRSIG bit as both always will be signed.
165 * 2) We set the RRSIG bit if we don't have
166 * a NS record but do have other data.
168 if (rdataset.type == dns_rdatatype_soa ||
169 rdataset.type == dns_rdatatype_ds)
170 need_rrsig = ISC_TRUE;
171 else if (rdataset.type == dns_rdatatype_ns)
176 dns_rdataset_disassociate(&rdataset);
178 if ((found && !found_ns) || need_rrsig) {
179 if (dns_rdatatype_rrsig > max_type)
180 max_type = dns_rdatatype_rrsig;
181 set_bit(bm, dns_rdatatype_rrsig, 1);
185 * At zone cuts, deny the existence of glue in the parent zone.
187 if (bit_isset(bm, dns_rdatatype_ns) &&
188 ! bit_isset(bm, dns_rdatatype_soa)) {
189 for (i = 0; i <= max_type; i++) {
190 if (bit_isset(bm, i) &&
191 ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i))
196 dns_rdatasetiter_destroy(&rdsiter);
197 if (result != ISC_R_NOMORE)
201 for (window = 0; window < 256; window++) {
202 if (window * 256 > max_type)
204 for (octet = 31; octet >= 0; octet--)
205 if (bm[window * 32 + octet] != 0)
209 nsec_bits[0] = window;
210 nsec_bits[1] = octet + 1;
212 * Note: potentially overlapping move.
214 memmove(&nsec_bits[2], &bm[window * 32], octet + 1);
215 nsec_bits += 3 + octet;
217 r.length = nsec_bits - r.base;
218 INSIST(r.length <= DNS_NSEC3_BUFFERSIZE);
219 dns_rdata_fromregion(rdata, dns_db_class(db), dns_rdatatype_nsec3, &r);
221 return (ISC_R_SUCCESS);
225 dns_nsec3_typepresent(dns_rdata_t *rdata, dns_rdatatype_t type) {
226 dns_rdata_nsec3_t nsec3;
228 isc_boolean_t present;
229 unsigned int i, len, window;
231 REQUIRE(rdata != NULL);
232 REQUIRE(rdata->type == dns_rdatatype_nsec3);
234 /* This should never fail */
235 result = dns_rdata_tostruct(rdata, &nsec3, NULL);
236 INSIST(result == ISC_R_SUCCESS);
239 for (i = 0; i < nsec3.len; i += len) {
240 INSIST(i + 2 <= nsec3.len);
241 window = nsec3.typebits[i];
242 len = nsec3.typebits[i + 1];
243 INSIST(len > 0 && len <= 32);
245 INSIST(i + len <= nsec3.len);
246 if (window * 256 > type)
248 if ((window + 1) * 256 <= type)
250 if (type < (window * 256) + len * 8)
251 present = ISC_TF(bit_isset(&nsec3.typebits[i],
255 dns_rdata_freestruct(&nsec3);
260 dns_nsec3_hashname(dns_fixedname_t *result,
261 unsigned char rethash[NSEC3_MAX_HASH_LENGTH],
262 size_t *hash_length, dns_name_t *name, dns_name_t *origin,
263 dns_hash_t hashalg, unsigned int iterations,
264 const unsigned char *salt, size_t saltlength)
266 unsigned char hash[NSEC3_MAX_HASH_LENGTH];
267 unsigned char nametext[DNS_NAME_FORMATSIZE];
268 dns_fixedname_t fixed;
269 dns_name_t *downcased;
270 isc_buffer_t namebuffer;
277 memset(rethash, 0, NSEC3_MAX_HASH_LENGTH);
279 dns_fixedname_init(&fixed);
280 downcased = dns_fixedname_name(&fixed);
281 dns_name_downcase(name, downcased, NULL);
283 /* hash the node name */
284 len = isc_iterated_hash(rethash, hashalg, iterations, salt, saltlength,
285 downcased->ndata, downcased->length);
287 return (DNS_R_BADALG);
289 if (hash_length != NULL)
292 /* convert the hash to base32hex */
293 region.base = rethash;
295 isc_buffer_init(&namebuffer, nametext, sizeof nametext);
296 isc_base32hex_totext(®ion, 1, "", &namebuffer);
298 /* convert the hex to a domain name */
299 dns_fixedname_init(result);
300 return (dns_name_fromtext(dns_fixedname_name(result), &namebuffer,
305 dns_nsec3_hashlength(dns_hash_t hash) {
308 case dns_hash_sha1: return(ISC_SHA1_DIGESTLENGTH);
314 dns_nsec3_supportedhash(dns_hash_t hash) {
316 case dns_hash_sha1: return (ISC_TRUE);
322 * Update a single RR in version 'ver' of 'db' and log the
326 * \li '*tuple' == NULL. Either the tuple is freed, or its
327 * ownership has been transferred to the diff.
330 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
333 dns_diff_t temp_diff;
337 * Create a singleton diff.
339 dns_diff_init(diff->mctx, &temp_diff);
340 temp_diff.resign = diff->resign;
341 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
344 * Apply it to the database.
346 result = dns_diff_apply(&temp_diff, db, ver);
347 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
348 if (result != ISC_R_SUCCESS) {
349 dns_difftuple_free(tuple);
354 * Merge it into the current pending journal entry.
356 dns_diff_appendminimal(diff, tuple);
359 * Do not clear temp_diff.
361 return (ISC_R_SUCCESS);
365 * Set '*exists' to true iff the given name exists, to false otherwise.
368 name_exists(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
369 isc_boolean_t *exists)
372 dns_dbnode_t *node = NULL;
373 dns_rdatasetiter_t *iter = NULL;
375 result = dns_db_findnode(db, name, ISC_FALSE, &node);
376 if (result == ISC_R_NOTFOUND) {
378 return (ISC_R_SUCCESS);
380 if (result != ISC_R_SUCCESS)
383 result = dns_db_allrdatasets(db, node, version,
384 (isc_stdtime_t) 0, &iter);
385 if (result != ISC_R_SUCCESS)
388 result = dns_rdatasetiter_first(iter);
389 if (result == ISC_R_SUCCESS) {
391 } else if (result == ISC_R_NOMORE) {
393 result = ISC_R_SUCCESS;
396 dns_rdatasetiter_destroy(&iter);
399 dns_db_detachnode(db, &node);
404 match_nsec3param(const dns_rdata_nsec3_t *nsec3,
405 const dns_rdata_nsec3param_t *nsec3param)
407 if (nsec3->hash == nsec3param->hash &&
408 nsec3->iterations == nsec3param->iterations &&
409 nsec3->salt_length == nsec3param->salt_length &&
410 !memcmp(nsec3->salt, nsec3param->salt, nsec3->salt_length))
416 * Delete NSEC3 records at "name" which match "param", recording the
420 delete(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
421 const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff)
423 dns_dbnode_t *node = NULL ;
424 dns_difftuple_t *tuple = NULL;
425 dns_rdata_nsec3_t nsec3;
426 dns_rdataset_t rdataset;
429 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
430 if (result == ISC_R_NOTFOUND)
431 return (ISC_R_SUCCESS);
432 if (result != ISC_R_SUCCESS)
435 dns_rdataset_init(&rdataset);
436 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, 0,
437 (isc_stdtime_t) 0, &rdataset, NULL);
439 if (result == ISC_R_NOTFOUND) {
440 result = ISC_R_SUCCESS;
443 if (result != ISC_R_SUCCESS)
446 for (result = dns_rdataset_first(&rdataset);
447 result == ISC_R_SUCCESS;
448 result = dns_rdataset_next(&rdataset))
450 dns_rdata_t rdata = DNS_RDATA_INIT;
451 dns_rdataset_current(&rdataset, &rdata);
452 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
454 if (!match_nsec3param(&nsec3, nsec3param))
457 result = dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, name,
458 rdataset.ttl, &rdata, &tuple);
459 if (result != ISC_R_SUCCESS)
461 result = do_one_tuple(&tuple, db, version, diff);
462 if (result != ISC_R_SUCCESS)
465 if (result != ISC_R_NOMORE)
467 result = ISC_R_SUCCESS;
470 dns_rdataset_disassociate(&rdataset);
472 dns_db_detachnode(db, &node);
478 better_param(dns_rdataset_t *nsec3paramset, dns_rdata_t *param) {
479 dns_rdataset_t rdataset;
482 if (REMOVE(param->data[1]))
485 dns_rdataset_init(&rdataset);
486 dns_rdataset_clone(nsec3paramset, &rdataset);
487 for (result = dns_rdataset_first(&rdataset);
488 result == ISC_R_SUCCESS;
489 result = dns_rdataset_next(&rdataset)) {
490 dns_rdata_t rdata = DNS_RDATA_INIT;
491 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
493 if (rdataset.type != dns_rdatatype_nsec3param) {
494 dns_rdata_t tmprdata = DNS_RDATA_INIT;
495 dns_rdataset_current(&rdataset, &tmprdata);
496 if (!dns_nsec3param_fromprivate(&tmprdata, &rdata,
500 dns_rdataset_current(&rdataset, &rdata);
502 if (rdata.length != param->length)
504 if (rdata.data[0] != param->data[0] ||
505 REMOVE(rdata.data[1]) ||
506 rdata.data[2] != param->data[2] ||
507 rdata.data[3] != param->data[3] ||
508 rdata.data[4] != param->data[4] ||
509 memcmp(&rdata.data[5], ¶m->data[5], param->data[4]))
511 if (CREATE(rdata.data[1]) && !CREATE(param->data[1])) {
512 dns_rdataset_disassociate(&rdataset);
516 dns_rdataset_disassociate(&rdataset);
521 find_nsec3(dns_rdata_nsec3_t *nsec3, dns_rdataset_t *rdataset,
522 const dns_rdata_nsec3param_t *nsec3param)
525 for (result = dns_rdataset_first(rdataset);
526 result == ISC_R_SUCCESS;
527 result = dns_rdataset_next(rdataset)) {
528 dns_rdata_t rdata = DNS_RDATA_INIT;
530 dns_rdataset_current(rdataset, &rdata);
531 CHECK(dns_rdata_tostruct(&rdata, nsec3, NULL));
532 dns_rdata_reset(&rdata);
533 if (match_nsec3param(nsec3, nsec3param))
541 dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version,
542 dns_name_t *name, const dns_rdata_nsec3param_t *nsec3param,
543 dns_ttl_t nsecttl, isc_boolean_t unsecure, dns_diff_t *diff)
545 dns_dbiterator_t *dbit = NULL;
546 dns_dbnode_t *node = NULL;
547 dns_dbnode_t *newnode = NULL;
548 dns_difftuple_t *tuple = NULL;
549 dns_fixedname_t fixed;
550 dns_fixedname_t fprev;
552 dns_name_t *hashname;
556 dns_rdata_nsec3_t nsec3;
557 dns_rdata_t rdata = DNS_RDATA_INIT;
558 dns_rdataset_t rdataset;
560 isc_boolean_t exists = ISC_FALSE;
561 isc_boolean_t maybe_remove_unsecure = ISC_FALSE;
565 unsigned char *old_next;
567 unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
568 unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
569 unsigned int iterations;
572 unsigned int old_length;
573 unsigned int salt_length;
575 dns_fixedname_init(&fixed);
576 hashname = dns_fixedname_name(&fixed);
577 dns_fixedname_init(&fprev);
578 prev = dns_fixedname_name(&fprev);
580 dns_rdataset_init(&rdataset);
582 origin = dns_db_origin(db);
587 hash = nsec3param->hash;
588 iterations = nsec3param->iterations;
589 salt_length = nsec3param->salt_length;
590 salt = nsec3param->salt;
593 * Default flags for a new chain.
595 flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
598 * If this is the first NSEC3 in the chain nexthash will
599 * remain pointing to itself.
601 next_length = sizeof(nexthash);
602 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
603 name, origin, hash, iterations,
607 * Create the node if it doesn't exist and hold
608 * a reference to it until we have added the NSEC3.
610 CHECK(dns_db_findnsec3node(db, hashname, ISC_TRUE, &newnode));
613 * Seek the iterator to the 'newnode'.
615 CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
616 CHECK(dns_dbiterator_seek(dbit, hashname));
617 CHECK(dns_dbiterator_pause(dbit));
618 result = dns_db_findrdataset(db, newnode, version, dns_rdatatype_nsec3,
619 0, (isc_stdtime_t) 0, &rdataset, NULL);
621 * If we updating a existing NSEC3 then find its
624 if (result == ISC_R_SUCCESS) {
625 result = find_nsec3(&nsec3, &rdataset, nsec3param);
626 if (result == ISC_R_SUCCESS) {
627 if (!CREATE(nsec3param->flags))
629 next_length = nsec3.next_length;
630 INSIST(next_length <= sizeof(nexthash));
631 memcpy(nexthash, nsec3.next, next_length);
632 dns_rdataset_disassociate(&rdataset);
634 * If the NSEC3 is not for a unsecure delegation then
635 * we are just updating it. If it is for a unsecure
636 * delegation then we need find out if we need to
637 * remove the NSEC3 record or not by examining the
638 * previous NSEC3 record.
642 else if (CREATE(nsec3param->flags) && OPTOUT(flags)) {
643 result = dns_nsec3_delnsec3(db, version, name,
647 maybe_remove_unsecure = ISC_TRUE;
649 dns_rdataset_disassociate(&rdataset);
650 if (result != ISC_R_NOMORE)
656 * Find the previous NSEC3 (if any) and update it if required.
660 result = dns_dbiterator_prev(dbit);
661 if (result == ISC_R_NOMORE) {
663 CHECK(dns_dbiterator_last(dbit));
665 CHECK(dns_dbiterator_current(dbit, &node, prev));
666 CHECK(dns_dbiterator_pause(dbit));
667 result = dns_db_findrdataset(db, node, version,
668 dns_rdatatype_nsec3, 0,
669 (isc_stdtime_t) 0, &rdataset,
671 dns_db_detachnode(db, &node);
672 if (result != ISC_R_SUCCESS)
675 result = find_nsec3(&nsec3, &rdataset, nsec3param);
676 if (result == ISC_R_NOMORE) {
677 dns_rdataset_disassociate(&rdataset);
680 if (result != ISC_R_SUCCESS)
683 if (maybe_remove_unsecure) {
684 dns_rdataset_disassociate(&rdataset);
686 * If we have OPTOUT set in the previous NSEC3 record
687 * we actually need to delete the NSEC3 record.
688 * Otherwise we just need to replace the NSEC3 record.
690 if (OPTOUT(nsec3.flags)) {
691 result = dns_nsec3_delnsec3(db, version, name,
698 * Is this is a unsecure delegation we are adding?
699 * If so no change is required.
701 if (OPTOUT(nsec3.flags) && unsecure) {
702 dns_rdataset_disassociate(&rdataset);
707 old_next = nsec3.next;
708 old_length = nsec3.next_length;
711 * Delete the old previous NSEC3.
713 CHECK(delete(db, version, prev, nsec3param, diff));
716 * Fixup the previous NSEC3.
718 nsec3.next = nexthash;
719 nsec3.next_length = next_length;
720 isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
721 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
722 dns_rdatatype_nsec3, &nsec3,
724 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
725 rdataset.ttl, &rdata, &tuple));
726 CHECK(do_one_tuple(&tuple, db, version, diff));
727 INSIST(old_length <= sizeof(nexthash));
728 memcpy(nexthash, old_next, old_length);
729 if (!CREATE(nsec3param->flags))
731 dns_rdata_reset(&rdata);
732 dns_rdataset_disassociate(&rdataset);
738 * Create the NSEC3 RDATA.
740 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
741 CHECK(dns_nsec3_buildrdata(db, version, node, hash, flags, iterations,
742 salt, salt_length, nexthash, next_length,
744 dns_db_detachnode(db, &node);
747 * Delete the old NSEC3 and record the change.
749 CHECK(delete(db, version, hashname, nsec3param, diff));
751 * Add the new NSEC3 and record the change.
753 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
754 hashname, nsecttl, &rdata, &tuple));
755 CHECK(do_one_tuple(&tuple, db, version, diff));
756 INSIST(tuple == NULL);
757 dns_rdata_reset(&rdata);
758 dns_db_detachnode(db, &newnode);
761 * Add missing NSEC3 records for empty nodes
763 dns_name_init(&empty, NULL);
764 dns_name_clone(name, &empty);
766 labels = dns_name_countlabels(&empty) - 1;
767 if (labels <= dns_name_countlabels(origin))
769 dns_name_getlabelsequence(&empty, 1, labels, &empty);
770 CHECK(name_exists(db, version, &empty, &exists));
773 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
774 &empty, origin, hash, iterations,
778 * Create the node if it doesn't exist and hold
779 * a reference to it until we have added the NSEC3
780 * or we discover we don't need to add make a change.
782 CHECK(dns_db_findnsec3node(db, hashname, ISC_TRUE, &newnode));
783 result = dns_db_findrdataset(db, newnode, version,
784 dns_rdatatype_nsec3, 0,
785 (isc_stdtime_t) 0, &rdataset,
787 if (result == ISC_R_SUCCESS) {
788 result = find_nsec3(&nsec3, &rdataset, nsec3param);
789 dns_rdataset_disassociate(&rdataset);
790 if (result == ISC_R_SUCCESS) {
791 dns_db_detachnode(db, &newnode);
794 if (result != ISC_R_NOMORE)
799 * Find the previous NSEC3 and update it.
801 CHECK(dns_dbiterator_seek(dbit, hashname));
804 result = dns_dbiterator_prev(dbit);
805 if (result == ISC_R_NOMORE) {
807 CHECK(dns_dbiterator_last(dbit));
809 CHECK(dns_dbiterator_current(dbit, &node, prev));
810 CHECK(dns_dbiterator_pause(dbit));
811 result = dns_db_findrdataset(db, node, version,
812 dns_rdatatype_nsec3, 0,
815 dns_db_detachnode(db, &node);
816 if (result != ISC_R_SUCCESS)
818 result = find_nsec3(&nsec3, &rdataset, nsec3param);
819 if (result == ISC_R_NOMORE) {
820 dns_rdataset_disassociate(&rdataset);
823 if (result != ISC_R_SUCCESS)
826 old_next = nsec3.next;
827 old_length = nsec3.next_length;
830 * Delete the old previous NSEC3.
832 CHECK(delete(db, version, prev, nsec3param, diff));
835 * Fixup the previous NSEC3.
837 nsec3.next = nexthash;
838 nsec3.next_length = next_length;
839 isc_buffer_init(&buffer, nsec3buf,
841 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
842 dns_rdatatype_nsec3, &nsec3,
844 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
845 prev, rdataset.ttl, &rdata,
847 CHECK(do_one_tuple(&tuple, db, version, diff));
848 INSIST(old_length <= sizeof(nexthash));
849 memcpy(nexthash, old_next, old_length);
850 if (!CREATE(nsec3param->flags))
852 dns_rdata_reset(&rdata);
853 dns_rdataset_disassociate(&rdataset);
860 * Create the NSEC3 RDATA for the empty node.
862 CHECK(dns_nsec3_buildrdata(db, version, NULL, hash, flags,
863 iterations, salt, salt_length,
864 nexthash, next_length, nsec3buf,
867 * Delete the old NSEC3 and record the change.
869 CHECK(delete(db, version, hashname, nsec3param, diff));
872 * Add the new NSEC3 and record the change.
874 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
875 hashname, nsecttl, &rdata, &tuple));
876 CHECK(do_one_tuple(&tuple, db, version, diff));
877 INSIST(tuple == NULL);
878 dns_rdata_reset(&rdata);
879 dns_db_detachnode(db, &newnode);
882 if (result == ISC_R_NOMORE)
883 result = ISC_R_SUCCESS;
887 dns_dbiterator_destroy(&dbit);
888 if (dns_rdataset_isassociated(&rdataset))
889 dns_rdataset_disassociate(&rdataset);
891 dns_db_detachnode(db, &node);
893 dns_db_detachnode(db, &newnode);
898 * Add NSEC3 records for "name", recording the change in "diff".
899 * The existing NSEC3 records are removed.
902 dns_nsec3_addnsec3s(dns_db_t *db, dns_dbversion_t *version,
903 dns_name_t *name, dns_ttl_t nsecttl,
904 isc_boolean_t unsecure, dns_diff_t *diff)
906 dns_dbnode_t *node = NULL;
907 dns_rdata_nsec3param_t nsec3param;
908 dns_rdataset_t rdataset;
911 dns_rdataset_init(&rdataset);
914 * Find the NSEC3 parameters for this zone.
916 result = dns_db_getoriginnode(db, &node);
917 if (result != ISC_R_SUCCESS)
920 result = dns_db_findrdataset(db, node, version,
921 dns_rdatatype_nsec3param, 0, 0,
923 dns_db_detachnode(db, &node);
924 if (result == ISC_R_NOTFOUND)
925 return (ISC_R_SUCCESS);
926 if (result != ISC_R_SUCCESS)
930 * Update each active NSEC3 chain.
932 for (result = dns_rdataset_first(&rdataset);
933 result == ISC_R_SUCCESS;
934 result = dns_rdataset_next(&rdataset)) {
935 dns_rdata_t rdata = DNS_RDATA_INIT;
937 dns_rdataset_current(&rdataset, &rdata);
938 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
940 if (nsec3param.flags != 0)
943 * We have a active chain. Update it.
945 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
946 nsecttl, unsecure, diff));
948 if (result == ISC_R_NOMORE)
949 result = ISC_R_SUCCESS;
952 if (dns_rdataset_isassociated(&rdataset))
953 dns_rdataset_disassociate(&rdataset);
955 dns_db_detachnode(db, &node);
961 dns_nsec3param_fromprivate(dns_rdata_t *src, dns_rdata_t *target,
962 unsigned char *buf, size_t buflen)
964 dns_decompress_t dctx;
970 * Algorithm 0 (reserved by RFC 4034) is used to identify
971 * NSEC3PARAM records from DNSKEY pointers.
973 if (src->length < 1 || src->data[0] != 0)
976 isc_buffer_init(&buf1, src->data + 1, src->length - 1);
977 isc_buffer_add(&buf1, src->length - 1);
978 isc_buffer_setactive(&buf1, src->length - 1);
979 isc_buffer_init(&buf2, buf, buflen);
980 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
981 result = dns_rdata_fromwire(target, src->rdclass,
982 dns_rdatatype_nsec3param,
983 &buf1, &dctx, 0, &buf2);
984 dns_decompress_invalidate(&dctx);
986 return (ISC_TF(result == ISC_R_SUCCESS));
990 dns_nsec3param_toprivate(dns_rdata_t *src, dns_rdata_t *target,
991 dns_rdatatype_t privatetype,
992 unsigned char *buf, size_t buflen)
994 REQUIRE(buflen >= src->length + 1);
996 REQUIRE(DNS_RDATA_INITIALIZED(target));
998 memcpy(buf + 1, src->data, src->length);
1001 target->length = src->length + 1;
1002 target->type = privatetype;
1003 target->rdclass = src->rdclass;
1005 ISC_LINK_INIT(target, link);
1010 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
1011 const dns_rdata_t *rdata, isc_boolean_t *flag)
1013 dns_rdataset_t rdataset;
1014 dns_dbnode_t *node = NULL;
1015 isc_result_t result;
1017 dns_rdataset_init(&rdataset);
1018 if (rdata->type == dns_rdatatype_nsec3)
1019 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
1021 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
1022 result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
1023 (isc_stdtime_t) 0, &rdataset, NULL);
1024 if (result == ISC_R_NOTFOUND) {
1026 result = ISC_R_SUCCESS;
1030 for (result = dns_rdataset_first(&rdataset);
1031 result == ISC_R_SUCCESS;
1032 result = dns_rdataset_next(&rdataset)) {
1033 dns_rdata_t myrdata = DNS_RDATA_INIT;
1034 dns_rdataset_current(&rdataset, &myrdata);
1035 if (!dns_rdata_casecompare(&myrdata, rdata))
1038 dns_rdataset_disassociate(&rdataset);
1039 if (result == ISC_R_SUCCESS) {
1041 } else if (result == ISC_R_NOMORE) {
1043 result = ISC_R_SUCCESS;
1048 dns_db_detachnode(db, &node);
1055 dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver,
1056 dns_zone_t *zone, dns_diff_t *diff)
1058 dns_dbnode_t *node = NULL;
1059 dns_difftuple_t *tuple = NULL;
1061 dns_rdata_t rdata = DNS_RDATA_INIT;
1062 dns_rdataset_t rdataset;
1064 isc_result_t result = ISC_R_SUCCESS;
1065 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE + 1];
1066 dns_name_t *origin = dns_zone_getorigin(zone);
1067 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
1069 dns_name_init(&next, NULL);
1070 dns_rdataset_init(&rdataset);
1072 result = dns_db_getoriginnode(db, &node);
1073 if (result != ISC_R_SUCCESS)
1077 * Cause all NSEC3 chains to be deleted.
1079 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
1080 0, (isc_stdtime_t) 0, &rdataset, NULL);
1081 if (result == ISC_R_NOTFOUND)
1083 if (result != ISC_R_SUCCESS)
1086 for (result = dns_rdataset_first(&rdataset);
1087 result == ISC_R_SUCCESS;
1088 result = dns_rdataset_next(&rdataset)) {
1089 dns_rdata_t private = DNS_RDATA_INIT;
1091 dns_rdataset_current(&rdataset, &rdata);
1093 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
1094 rdataset.ttl, &rdata, &tuple));
1095 CHECK(do_one_tuple(&tuple, db, ver, diff));
1096 INSIST(tuple == NULL);
1098 dns_nsec3param_toprivate(&rdata, &private, privatetype,
1100 buf[2] = DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC;
1102 CHECK(rr_exists(db, ver, origin, &private, &flag));
1105 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1106 origin, 0, &private,
1108 CHECK(do_one_tuple(&tuple, db, ver, diff));
1109 INSIST(tuple == NULL);
1111 dns_rdata_reset(&rdata);
1113 if (result != ISC_R_NOMORE)
1116 dns_rdataset_disassociate(&rdataset);
1119 if (privatetype == 0)
1121 result = dns_db_findrdataset(db, node, ver, privatetype, 0,
1122 (isc_stdtime_t) 0, &rdataset, NULL);
1123 if (result == ISC_R_NOTFOUND)
1125 if (result != ISC_R_SUCCESS)
1128 for (result = dns_rdataset_first(&rdataset);
1129 result == ISC_R_SUCCESS;
1130 result = dns_rdataset_next(&rdataset)) {
1131 dns_rdataset_current(&rdataset, &rdata);
1132 INSIST(rdata.length <= sizeof(buf));
1133 memcpy(buf, rdata.data, rdata.length);
1136 buf[2] == (DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC)) {
1137 dns_rdata_reset(&rdata);
1141 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
1142 0, &rdata, &tuple));
1143 CHECK(do_one_tuple(&tuple, db, ver, diff));
1144 INSIST(tuple == NULL);
1147 buf[2] = DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC;
1149 CHECK(rr_exists(db, ver, origin, &rdata, &flag));
1152 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1153 origin, 0, &rdata, &tuple));
1154 CHECK(do_one_tuple(&tuple, db, ver, diff));
1155 INSIST(tuple == NULL);
1157 dns_rdata_reset(&rdata);
1159 if (result != ISC_R_NOMORE)
1162 result = ISC_R_SUCCESS;
1165 if (dns_rdataset_isassociated(&rdataset))
1166 dns_rdataset_disassociate(&rdataset);
1167 dns_db_detachnode(db, &node);
1173 dns_nsec3_addnsec3sx(dns_db_t *db, dns_dbversion_t *version,
1174 dns_name_t *name, dns_ttl_t nsecttl,
1175 isc_boolean_t unsecure, dns_rdatatype_t type,
1178 dns_dbnode_t *node = NULL;
1179 dns_rdata_nsec3param_t nsec3param;
1180 dns_rdataset_t rdataset;
1181 dns_rdataset_t prdataset;
1182 isc_result_t result;
1184 dns_rdataset_init(&rdataset);
1185 dns_rdataset_init(&prdataset);
1188 * Find the NSEC3 parameters for this zone.
1190 result = dns_db_getoriginnode(db, &node);
1191 if (result != ISC_R_SUCCESS)
1194 result = dns_db_findrdataset(db, node, version, type, 0, 0,
1196 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
1199 result = dns_db_findrdataset(db, node, version,
1200 dns_rdatatype_nsec3param, 0, 0,
1202 if (result == ISC_R_NOTFOUND)
1204 if (result != ISC_R_SUCCESS)
1208 * Update each active NSEC3 chain.
1210 for (result = dns_rdataset_first(&rdataset);
1211 result == ISC_R_SUCCESS;
1212 result = dns_rdataset_next(&rdataset)) {
1213 dns_rdata_t rdata = DNS_RDATA_INIT;
1215 dns_rdataset_current(&rdataset, &rdata);
1216 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
1218 if (nsec3param.flags != 0)
1222 * We have a active chain. Update it.
1224 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
1225 nsecttl, unsecure, diff));
1227 if (result != ISC_R_NOMORE)
1230 dns_rdataset_disassociate(&rdataset);
1233 if (!dns_rdataset_isassociated(&prdataset))
1236 * Update each active NSEC3 chain.
1238 for (result = dns_rdataset_first(&prdataset);
1239 result == ISC_R_SUCCESS;
1240 result = dns_rdataset_next(&prdataset)) {
1241 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1242 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1243 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1245 dns_rdataset_current(&prdataset, &rdata1);
1246 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
1249 CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
1251 if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
1253 if (better_param(&prdataset, &rdata2))
1257 * We have a active chain. Update it.
1259 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
1260 nsecttl, unsecure, diff));
1262 if (result == ISC_R_NOMORE)
1264 result = ISC_R_SUCCESS;
1266 if (dns_rdataset_isassociated(&rdataset))
1267 dns_rdataset_disassociate(&rdataset);
1268 if (dns_rdataset_isassociated(&prdataset))
1269 dns_rdataset_disassociate(&prdataset);
1271 dns_db_detachnode(db, &node);
1277 * Determine whether any NSEC3 records that were associated with
1278 * 'name' should be deleted or if they should continue to exist.
1279 * ISC_TRUE indicates they should be deleted.
1280 * ISC_FALSE indicates they should be retained.
1283 deleteit(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
1284 isc_boolean_t *yesno)
1286 isc_result_t result;
1287 dns_fixedname_t foundname;
1288 dns_fixedname_init(&foundname);
1290 result = dns_db_find(db, name, ver, dns_rdatatype_any,
1291 DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD,
1292 (isc_stdtime_t) 0, NULL,
1293 dns_fixedname_name(&foundname),
1295 if (result == DNS_R_EMPTYNAME || result == ISC_R_SUCCESS ||
1296 result == DNS_R_ZONECUT) {
1298 return (ISC_R_SUCCESS);
1300 if (result == DNS_R_GLUE || result == DNS_R_DNAME ||
1301 result == DNS_R_DELEGATION || result == DNS_R_NXDOMAIN) {
1303 return (ISC_R_SUCCESS);
1313 dns_nsec3_delnsec3(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1314 const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff)
1316 dns_dbiterator_t *dbit = NULL;
1317 dns_dbnode_t *node = NULL;
1318 dns_difftuple_t *tuple = NULL;
1319 dns_fixedname_t fixed;
1320 dns_fixedname_t fprev;
1322 dns_name_t *hashname;
1326 dns_rdata_nsec3_t nsec3;
1327 dns_rdata_t rdata = DNS_RDATA_INIT;
1328 dns_rdataset_t rdataset;
1330 isc_boolean_t yesno;
1331 isc_buffer_t buffer;
1332 isc_result_t result;
1333 unsigned char *salt;
1334 unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
1335 unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
1336 unsigned int iterations;
1337 unsigned int labels;
1339 unsigned int salt_length;
1341 dns_fixedname_init(&fixed);
1342 hashname = dns_fixedname_name(&fixed);
1343 dns_fixedname_init(&fprev);
1344 prev = dns_fixedname_name(&fprev);
1346 dns_rdataset_init(&rdataset);
1348 origin = dns_db_origin(db);
1353 hash = nsec3param->hash;
1354 iterations = nsec3param->iterations;
1355 salt_length = nsec3param->salt_length;
1356 salt = nsec3param->salt;
1359 * If this is the first NSEC3 in the chain nexthash will
1360 * remain pointing to itself.
1362 next_length = sizeof(nexthash);
1363 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
1364 name, origin, hash, iterations,
1365 salt, salt_length));
1367 CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
1369 result = dns_dbiterator_seek(dbit, hashname);
1370 if (result == ISC_R_NOTFOUND)
1372 if (result != ISC_R_SUCCESS)
1375 CHECK(dns_dbiterator_current(dbit, &node, NULL));
1376 CHECK(dns_dbiterator_pause(dbit));
1377 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3,
1378 0, (isc_stdtime_t) 0, &rdataset, NULL);
1379 dns_db_detachnode(db, &node);
1380 if (result == ISC_R_NOTFOUND)
1382 if (result != ISC_R_SUCCESS)
1386 * If we find a existing NSEC3 for this chain then save the
1389 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1390 if (result == ISC_R_SUCCESS) {
1391 next_length = nsec3.next_length;
1392 INSIST(next_length <= sizeof(nexthash));
1393 memcpy(nexthash, nsec3.next, next_length);
1395 dns_rdataset_disassociate(&rdataset);
1396 if (result == ISC_R_NOMORE)
1398 if (result != ISC_R_SUCCESS)
1402 * Find the previous NSEC3 and update it.
1406 result = dns_dbiterator_prev(dbit);
1407 if (result == ISC_R_NOMORE) {
1409 CHECK(dns_dbiterator_last(dbit));
1411 CHECK(dns_dbiterator_current(dbit, &node, prev));
1412 CHECK(dns_dbiterator_pause(dbit));
1413 result = dns_db_findrdataset(db, node, version,
1414 dns_rdatatype_nsec3, 0,
1415 (isc_stdtime_t) 0, &rdataset,
1417 dns_db_detachnode(db, &node);
1418 if (result != ISC_R_SUCCESS)
1420 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1421 if (result == ISC_R_NOMORE) {
1422 dns_rdataset_disassociate(&rdataset);
1425 if (result != ISC_R_SUCCESS)
1429 * Delete the old previous NSEC3.
1431 CHECK(delete(db, version, prev, nsec3param, diff));
1434 * Fixup the previous NSEC3.
1436 nsec3.next = nexthash;
1437 nsec3.next_length = next_length;
1438 if (CREATE(nsec3param->flags))
1439 nsec3.flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
1440 isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
1441 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
1442 dns_rdatatype_nsec3, &nsec3,
1444 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
1445 rdataset.ttl, &rdata, &tuple));
1446 CHECK(do_one_tuple(&tuple, db, version, diff));
1447 dns_rdata_reset(&rdata);
1448 dns_rdataset_disassociate(&rdataset);
1453 * Delete the old NSEC3 and record the change.
1455 CHECK(delete(db, version, hashname, nsec3param, diff));
1458 * Delete NSEC3 records for now non active nodes.
1460 dns_name_init(&empty, NULL);
1461 dns_name_clone(name, &empty);
1463 labels = dns_name_countlabels(&empty) - 1;
1464 if (labels <= dns_name_countlabels(origin))
1466 dns_name_getlabelsequence(&empty, 1, labels, &empty);
1467 CHECK(deleteit(db, version, &empty, &yesno));
1471 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
1472 &empty, origin, hash, iterations,
1473 salt, salt_length));
1474 result = dns_dbiterator_seek(dbit, hashname);
1475 if (result == ISC_R_NOTFOUND)
1477 if (result != ISC_R_SUCCESS)
1480 CHECK(dns_dbiterator_current(dbit, &node, NULL));
1481 CHECK(dns_dbiterator_pause(dbit));
1482 result = dns_db_findrdataset(db, node, version,
1483 dns_rdatatype_nsec3, 0,
1484 (isc_stdtime_t) 0, &rdataset,
1486 dns_db_detachnode(db, &node);
1487 if (result == ISC_R_NOTFOUND)
1489 if (result != ISC_R_SUCCESS)
1492 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1493 if (result == ISC_R_SUCCESS) {
1494 next_length = nsec3.next_length;
1495 INSIST(next_length <= sizeof(nexthash));
1496 memcpy(nexthash, nsec3.next, next_length);
1498 dns_rdataset_disassociate(&rdataset);
1499 if (result == ISC_R_NOMORE)
1501 if (result != ISC_R_SUCCESS)
1506 result = dns_dbiterator_prev(dbit);
1507 if (result == ISC_R_NOMORE) {
1509 CHECK(dns_dbiterator_last(dbit));
1511 CHECK(dns_dbiterator_current(dbit, &node, prev));
1512 CHECK(dns_dbiterator_pause(dbit));
1513 result = dns_db_findrdataset(db, node, version,
1514 dns_rdatatype_nsec3, 0,
1517 dns_db_detachnode(db, &node);
1518 if (result != ISC_R_SUCCESS)
1520 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1521 if (result == ISC_R_NOMORE) {
1522 dns_rdataset_disassociate(&rdataset);
1525 if (result != ISC_R_SUCCESS)
1529 * Delete the old previous NSEC3.
1531 CHECK(delete(db, version, prev, nsec3param, diff));
1534 * Fixup the previous NSEC3.
1536 nsec3.next = nexthash;
1537 nsec3.next_length = next_length;
1538 isc_buffer_init(&buffer, nsec3buf,
1540 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
1541 dns_rdatatype_nsec3, &nsec3,
1543 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1544 prev, rdataset.ttl, &rdata,
1546 CHECK(do_one_tuple(&tuple, db, version, diff));
1547 dns_rdata_reset(&rdata);
1548 dns_rdataset_disassociate(&rdataset);
1555 * Delete the old NSEC3 and record the change.
1557 CHECK(delete(db, version, hashname, nsec3param, diff));
1561 result = ISC_R_SUCCESS;
1565 dns_dbiterator_destroy(&dbit);
1566 if (dns_rdataset_isassociated(&rdataset))
1567 dns_rdataset_disassociate(&rdataset);
1569 dns_db_detachnode(db, &node);
1574 dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1577 return (dns_nsec3_delnsec3sx(db, version, name, 0, diff));
1581 dns_nsec3_delnsec3sx(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1582 dns_rdatatype_t privatetype, dns_diff_t *diff)
1584 dns_dbnode_t *node = NULL;
1585 dns_rdata_nsec3param_t nsec3param;
1586 dns_rdataset_t rdataset;
1587 isc_result_t result;
1589 dns_rdataset_init(&rdataset);
1592 * Find the NSEC3 parameters for this zone.
1594 result = dns_db_getoriginnode(db, &node);
1595 if (result != ISC_R_SUCCESS)
1598 result = dns_db_findrdataset(db, node, version,
1599 dns_rdatatype_nsec3param, 0, 0,
1601 if (result == ISC_R_NOTFOUND)
1603 if (result != ISC_R_SUCCESS)
1607 * Update each active NSEC3 chain.
1609 for (result = dns_rdataset_first(&rdataset);
1610 result == ISC_R_SUCCESS;
1611 result = dns_rdataset_next(&rdataset)) {
1612 dns_rdata_t rdata = DNS_RDATA_INIT;
1614 dns_rdataset_current(&rdataset, &rdata);
1615 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
1617 if (nsec3param.flags != 0)
1620 * We have a active chain. Update it.
1622 CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
1624 dns_rdataset_disassociate(&rdataset);
1627 if (privatetype == 0)
1629 result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
1631 if (result == ISC_R_NOTFOUND)
1633 if (result != ISC_R_SUCCESS)
1637 * Update each NSEC3 chain being built.
1639 for (result = dns_rdataset_first(&rdataset);
1640 result == ISC_R_SUCCESS;
1641 result = dns_rdataset_next(&rdataset)) {
1642 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1643 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1644 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1646 dns_rdataset_current(&rdataset, &rdata1);
1647 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
1650 CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
1652 if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
1654 if (better_param(&rdataset, &rdata2))
1658 * We have a active chain. Update it.
1660 CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
1662 if (result == ISC_R_NOMORE)
1664 result = ISC_R_SUCCESS;
1667 if (dns_rdataset_isassociated(&rdataset))
1668 dns_rdataset_disassociate(&rdataset);
1670 dns_db_detachnode(db, &node);
1676 dns_nsec3_active(dns_db_t *db, dns_dbversion_t *version,
1677 isc_boolean_t complete, isc_boolean_t *answer)
1679 return (dns_nsec3_activex(db, version, complete, 0, answer));
1683 dns_nsec3_activex(dns_db_t *db, dns_dbversion_t *version,
1684 isc_boolean_t complete, dns_rdatatype_t privatetype,
1685 isc_boolean_t *answer)
1687 dns_dbnode_t *node = NULL;
1688 dns_rdataset_t rdataset;
1689 dns_rdata_nsec3param_t nsec3param;
1690 isc_result_t result;
1692 REQUIRE(answer != NULL);
1694 dns_rdataset_init(&rdataset);
1696 result = dns_db_getoriginnode(db, &node);
1697 if (result != ISC_R_SUCCESS)
1700 result = dns_db_findrdataset(db, node, version,
1701 dns_rdatatype_nsec3param, 0, 0,
1704 if (result == ISC_R_NOTFOUND)
1707 if (result != ISC_R_SUCCESS) {
1708 dns_db_detachnode(db, &node);
1711 for (result = dns_rdataset_first(&rdataset);
1712 result == ISC_R_SUCCESS;
1713 result = dns_rdataset_next(&rdataset)) {
1714 dns_rdata_t rdata = DNS_RDATA_INIT;
1716 dns_rdataset_current(&rdataset, &rdata);
1717 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
1718 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1720 if (nsec3param.flags == 0)
1723 dns_rdataset_disassociate(&rdataset);
1724 if (result == ISC_R_SUCCESS) {
1725 dns_db_detachnode(db, &node);
1727 return (ISC_R_SUCCESS);
1729 if (result == ISC_R_NOMORE)
1730 *answer = ISC_FALSE;
1733 if (privatetype == 0 || complete) {
1734 *answer = ISC_FALSE;
1735 return (ISC_R_SUCCESS);
1737 result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
1740 dns_db_detachnode(db, &node);
1741 if (result == ISC_R_NOTFOUND) {
1742 *answer = ISC_FALSE;
1743 return (ISC_R_SUCCESS);
1745 if (result != ISC_R_SUCCESS)
1748 for (result = dns_rdataset_first(&rdataset);
1749 result == ISC_R_SUCCESS;
1750 result = dns_rdataset_next(&rdataset)) {
1751 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1752 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1753 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1755 dns_rdataset_current(&rdataset, &rdata1);
1756 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
1759 result = dns_rdata_tostruct(&rdata2, &nsec3param, NULL);
1760 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1762 if (!complete && CREATE(nsec3param.flags))
1765 dns_rdataset_disassociate(&rdataset);
1766 if (result == ISC_R_SUCCESS) {
1768 result = ISC_R_SUCCESS;
1770 if (result == ISC_R_NOMORE) {
1771 *answer = ISC_FALSE;
1772 result = ISC_R_SUCCESS;
1779 dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version,
1780 isc_mem_t *mctx, unsigned int *iterationsp)
1782 dns_dbnode_t *node = NULL;
1783 dns_rdataset_t rdataset;
1784 dst_key_t *key = NULL;
1785 isc_buffer_t buffer;
1786 isc_result_t result;
1787 unsigned int bits, minbits = 4096;
1789 result = dns_db_getoriginnode(db, &node);
1790 if (result != ISC_R_SUCCESS)
1793 dns_rdataset_init(&rdataset);
1794 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
1795 0, 0, &rdataset, NULL);
1796 dns_db_detachnode(db, &node);
1797 if (result == ISC_R_NOTFOUND) {
1799 return (ISC_R_SUCCESS);
1801 if (result != ISC_R_SUCCESS)
1804 for (result = dns_rdataset_first(&rdataset);
1805 result == ISC_R_SUCCESS;
1806 result = dns_rdataset_next(&rdataset)) {
1807 dns_rdata_t rdata = DNS_RDATA_INIT;
1809 dns_rdataset_current(&rdataset, &rdata);
1810 isc_buffer_init(&buffer, rdata.data, rdata.length);
1811 isc_buffer_add(&buffer, rdata.length);
1812 CHECK(dst_key_fromdns(dns_db_origin(db), rdataset.rdclass,
1813 &buffer, mctx, &key));
1814 bits = dst_key_size(key);
1819 if (result != ISC_R_NOMORE)
1822 if (minbits <= 1024)
1824 else if (minbits <= 2048)
1827 *iterationsp = 2500;
1828 result = ISC_R_SUCCESS;
1831 if (dns_rdataset_isassociated(&rdataset))
1832 dns_rdataset_disassociate(&rdataset);