2 * Copyright (C) 2006, 2008-2014 Internet Systems Consortium, Inc. ("ISC")
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
21 #include <isc/base32.h>
22 #include <isc/buffer.h>
24 #include <isc/iterated_hash.h>
26 #include <isc/string.h>
33 #include <dns/compress.h>
34 #include <dns/dbiterator.h>
36 #include <dns/fixedname.h>
38 #include <dns/nsec3.h>
39 #include <dns/rdata.h>
40 #include <dns/rdatalist.h>
41 #include <dns/rdataset.h>
42 #include <dns/rdatasetiter.h>
43 #include <dns/rdatastruct.h>
44 #include <dns/result.h>
46 #define CHECK(x) do { \
48 if (result != ISC_R_SUCCESS) \
52 #define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0)
53 #define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0)
54 #define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0)
55 #define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
58 dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
59 dns_dbnode_t *node, unsigned int hashalg,
60 unsigned int flags, unsigned int iterations,
61 const unsigned char *salt, size_t salt_length,
62 const unsigned char *nexthash, size_t hash_length,
63 unsigned char *buffer, dns_rdata_t *rdata)
66 dns_rdataset_t rdataset;
70 isc_boolean_t found_ns;
71 isc_boolean_t need_rrsig;
73 unsigned char *nsec_bits, *bm;
74 unsigned int max_type;
75 dns_rdatasetiter_t *rdsiter;
78 REQUIRE(salt_length < 256U);
79 REQUIRE(hash_length < 256U);
80 REQUIRE(flags <= 0xffU);
81 REQUIRE(hashalg <= 0xffU);
82 REQUIRE(iterations <= 0xffffU);
86 REQUIRE(hash_length == ISC_SHA1_DIGESTLENGTH);
90 memset(buffer, 0, DNS_NSEC3_BUFFERSIZE);
97 *p++ = iterations >> 8;
100 *p++ = (unsigned char)salt_length;
101 memmove(p, salt, salt_length);
104 *p++ = (unsigned char)hash_length;
105 memmove(p, nexthash, hash_length);
108 r.length = (unsigned int)(p - buffer);
112 * Use the end of the space for a raw bitmap leaving enough
113 * space for the window identifiers and length octets.
115 bm = r.base + r.length + 512;
116 nsec_bits = r.base + r.length;
119 goto collapse_bitmap;
120 dns_rdataset_init(&rdataset);
122 result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
123 if (result != ISC_R_SUCCESS)
125 found = found_ns = need_rrsig = ISC_FALSE;
126 for (result = dns_rdatasetiter_first(rdsiter);
127 result == ISC_R_SUCCESS;
128 result = dns_rdatasetiter_next(rdsiter))
130 dns_rdatasetiter_current(rdsiter, &rdataset);
131 if (rdataset.type != dns_rdatatype_nsec &&
132 rdataset.type != dns_rdatatype_nsec3 &&
133 rdataset.type != dns_rdatatype_rrsig) {
134 if (rdataset.type > max_type)
135 max_type = rdataset.type;
136 dns_nsec_setbit(bm, rdataset.type, 1);
138 * Work out if we need to set the RRSIG bit for
139 * this node. We set the RRSIG bit if either of
140 * the following conditions are met:
141 * 1) We have a SOA or DS then we need to set
142 * the RRSIG bit as both always will be signed.
143 * 2) We set the RRSIG bit if we don't have
144 * a NS record but do have other data.
146 if (rdataset.type == dns_rdatatype_soa ||
147 rdataset.type == dns_rdatatype_ds)
148 need_rrsig = ISC_TRUE;
149 else if (rdataset.type == dns_rdatatype_ns)
154 dns_rdataset_disassociate(&rdataset);
156 if ((found && !found_ns) || need_rrsig) {
157 if (dns_rdatatype_rrsig > max_type)
158 max_type = dns_rdatatype_rrsig;
159 dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1);
163 * At zone cuts, deny the existence of glue in the parent zone.
165 if (dns_nsec_isset(bm, dns_rdatatype_ns) &&
166 ! dns_nsec_isset(bm, dns_rdatatype_soa)) {
167 for (i = 0; i <= max_type; i++) {
168 if (dns_nsec_isset(bm, i) &&
169 ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i))
170 dns_nsec_setbit(bm, i, 0);
174 dns_rdatasetiter_destroy(&rdsiter);
175 if (result != ISC_R_NOMORE)
179 nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type);
180 r.length = (unsigned int)(nsec_bits - r.base);
181 INSIST(r.length <= DNS_NSEC3_BUFFERSIZE);
182 dns_rdata_fromregion(rdata, dns_db_class(db), dns_rdatatype_nsec3, &r);
184 return (ISC_R_SUCCESS);
188 dns_nsec3_typepresent(dns_rdata_t *rdata, dns_rdatatype_t type) {
189 dns_rdata_nsec3_t nsec3;
191 isc_boolean_t present;
192 unsigned int i, len, window;
194 REQUIRE(rdata != NULL);
195 REQUIRE(rdata->type == dns_rdatatype_nsec3);
197 /* This should never fail */
198 result = dns_rdata_tostruct(rdata, &nsec3, NULL);
199 INSIST(result == ISC_R_SUCCESS);
202 for (i = 0; i < nsec3.len; i += len) {
203 INSIST(i + 2 <= nsec3.len);
204 window = nsec3.typebits[i];
205 len = nsec3.typebits[i + 1];
206 INSIST(len > 0 && len <= 32);
208 INSIST(i + len <= nsec3.len);
209 if (window * 256 > type)
211 if ((window + 1) * 256 <= type)
213 if (type < (window * 256) + len * 8)
214 present = ISC_TF(dns_nsec_isset(&nsec3.typebits[i],
218 dns_rdata_freestruct(&nsec3);
223 dns_nsec3_hashname(dns_fixedname_t *result,
224 unsigned char rethash[NSEC3_MAX_HASH_LENGTH],
225 size_t *hash_length, dns_name_t *name, dns_name_t *origin,
226 dns_hash_t hashalg, unsigned int iterations,
227 const unsigned char *salt, size_t saltlength)
229 unsigned char hash[NSEC3_MAX_HASH_LENGTH];
230 unsigned char nametext[DNS_NAME_FORMATSIZE];
231 dns_fixedname_t fixed;
232 dns_name_t *downcased;
233 isc_buffer_t namebuffer;
240 memset(rethash, 0, NSEC3_MAX_HASH_LENGTH);
242 dns_fixedname_init(&fixed);
243 downcased = dns_fixedname_name(&fixed);
244 dns_name_downcase(name, downcased, NULL);
246 /* hash the node name */
247 len = isc_iterated_hash(rethash, hashalg, iterations,
248 salt, (int)saltlength,
249 downcased->ndata, downcased->length);
251 return (DNS_R_BADALG);
253 if (hash_length != NULL)
256 /* convert the hash to base32hex non-padded */
257 region.base = rethash;
258 region.length = (unsigned int)len;
259 isc_buffer_init(&namebuffer, nametext, sizeof nametext);
260 isc_base32hexnp_totext(®ion, 1, "", &namebuffer);
262 /* convert the hex to a domain name */
263 dns_fixedname_init(result);
264 return (dns_name_fromtext(dns_fixedname_name(result), &namebuffer,
269 dns_nsec3_hashlength(dns_hash_t hash) {
273 return(ISC_SHA1_DIGESTLENGTH);
279 dns_nsec3_supportedhash(dns_hash_t hash) {
288 * Update a single RR in version 'ver' of 'db' and log the
292 * \li '*tuple' == NULL. Either the tuple is freed, or its
293 * ownership has been transferred to the diff.
296 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
299 dns_diff_t temp_diff;
303 * Create a singleton diff.
305 dns_diff_init(diff->mctx, &temp_diff);
306 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
309 * Apply it to the database.
311 result = dns_diff_apply(&temp_diff, db, ver);
312 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
313 if (result != ISC_R_SUCCESS) {
314 dns_difftuple_free(tuple);
319 * Merge it into the current pending journal entry.
321 dns_diff_appendminimal(diff, tuple);
324 * Do not clear temp_diff.
326 return (ISC_R_SUCCESS);
330 * Set '*exists' to true iff the given name exists, to false otherwise.
333 name_exists(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
334 isc_boolean_t *exists)
337 dns_dbnode_t *node = NULL;
338 dns_rdatasetiter_t *iter = NULL;
340 result = dns_db_findnode(db, name, ISC_FALSE, &node);
341 if (result == ISC_R_NOTFOUND) {
343 return (ISC_R_SUCCESS);
345 if (result != ISC_R_SUCCESS)
348 result = dns_db_allrdatasets(db, node, version,
349 (isc_stdtime_t) 0, &iter);
350 if (result != ISC_R_SUCCESS)
353 result = dns_rdatasetiter_first(iter);
354 if (result == ISC_R_SUCCESS) {
356 } else if (result == ISC_R_NOMORE) {
358 result = ISC_R_SUCCESS;
361 dns_rdatasetiter_destroy(&iter);
364 dns_db_detachnode(db, &node);
369 match_nsec3param(const dns_rdata_nsec3_t *nsec3,
370 const dns_rdata_nsec3param_t *nsec3param)
372 if (nsec3->hash == nsec3param->hash &&
373 nsec3->iterations == nsec3param->iterations &&
374 nsec3->salt_length == nsec3param->salt_length &&
375 !memcmp(nsec3->salt, nsec3param->salt, nsec3->salt_length))
381 * Delete NSEC3 records at "name" which match "param", recording the
385 delete(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
386 const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff)
388 dns_dbnode_t *node = NULL ;
389 dns_difftuple_t *tuple = NULL;
390 dns_rdata_nsec3_t nsec3;
391 dns_rdataset_t rdataset;
394 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
395 if (result == ISC_R_NOTFOUND)
396 return (ISC_R_SUCCESS);
397 if (result != ISC_R_SUCCESS)
400 dns_rdataset_init(&rdataset);
401 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, 0,
402 (isc_stdtime_t) 0, &rdataset, NULL);
404 if (result == ISC_R_NOTFOUND) {
405 result = ISC_R_SUCCESS;
408 if (result != ISC_R_SUCCESS)
411 for (result = dns_rdataset_first(&rdataset);
412 result == ISC_R_SUCCESS;
413 result = dns_rdataset_next(&rdataset))
415 dns_rdata_t rdata = DNS_RDATA_INIT;
416 dns_rdataset_current(&rdataset, &rdata);
417 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
419 if (!match_nsec3param(&nsec3, nsec3param))
422 result = dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, name,
423 rdataset.ttl, &rdata, &tuple);
424 if (result != ISC_R_SUCCESS)
426 result = do_one_tuple(&tuple, db, version, diff);
427 if (result != ISC_R_SUCCESS)
430 if (result != ISC_R_NOMORE)
432 result = ISC_R_SUCCESS;
435 dns_rdataset_disassociate(&rdataset);
437 dns_db_detachnode(db, &node);
443 better_param(dns_rdataset_t *nsec3paramset, dns_rdata_t *param) {
444 dns_rdataset_t rdataset;
447 if (REMOVE(param->data[1]))
450 dns_rdataset_init(&rdataset);
451 dns_rdataset_clone(nsec3paramset, &rdataset);
452 for (result = dns_rdataset_first(&rdataset);
453 result == ISC_R_SUCCESS;
454 result = dns_rdataset_next(&rdataset)) {
455 dns_rdata_t rdata = DNS_RDATA_INIT;
456 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
458 if (rdataset.type != dns_rdatatype_nsec3param) {
459 dns_rdata_t tmprdata = DNS_RDATA_INIT;
460 dns_rdataset_current(&rdataset, &tmprdata);
461 if (!dns_nsec3param_fromprivate(&tmprdata, &rdata,
465 dns_rdataset_current(&rdataset, &rdata);
467 if (rdata.length != param->length)
469 if (rdata.data[0] != param->data[0] ||
470 REMOVE(rdata.data[1]) ||
471 rdata.data[2] != param->data[2] ||
472 rdata.data[3] != param->data[3] ||
473 rdata.data[4] != param->data[4] ||
474 memcmp(&rdata.data[5], ¶m->data[5], param->data[4]))
476 if (CREATE(rdata.data[1]) && !CREATE(param->data[1])) {
477 dns_rdataset_disassociate(&rdataset);
481 dns_rdataset_disassociate(&rdataset);
486 find_nsec3(dns_rdata_nsec3_t *nsec3, dns_rdataset_t *rdataset,
487 const dns_rdata_nsec3param_t *nsec3param)
490 for (result = dns_rdataset_first(rdataset);
491 result == ISC_R_SUCCESS;
492 result = dns_rdataset_next(rdataset)) {
493 dns_rdata_t rdata = DNS_RDATA_INIT;
495 dns_rdataset_current(rdataset, &rdata);
496 CHECK(dns_rdata_tostruct(&rdata, nsec3, NULL));
497 dns_rdata_reset(&rdata);
498 if (match_nsec3param(nsec3, nsec3param))
506 dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version,
507 dns_name_t *name, const dns_rdata_nsec3param_t *nsec3param,
508 dns_ttl_t nsecttl, isc_boolean_t unsecure, dns_diff_t *diff)
510 dns_dbiterator_t *dbit = NULL;
511 dns_dbnode_t *node = NULL;
512 dns_dbnode_t *newnode = NULL;
513 dns_difftuple_t *tuple = NULL;
514 dns_fixedname_t fixed;
515 dns_fixedname_t fprev;
517 dns_name_t *hashname;
521 dns_rdata_nsec3_t nsec3;
522 dns_rdata_t rdata = DNS_RDATA_INIT;
523 dns_rdataset_t rdataset;
525 isc_boolean_t exists = ISC_FALSE;
526 isc_boolean_t maybe_remove_unsecure = ISC_FALSE;
530 unsigned char *old_next;
532 unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
533 unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
534 unsigned int iterations;
537 unsigned int old_length;
538 unsigned int salt_length;
540 dns_fixedname_init(&fixed);
541 hashname = dns_fixedname_name(&fixed);
542 dns_fixedname_init(&fprev);
543 prev = dns_fixedname_name(&fprev);
545 dns_rdataset_init(&rdataset);
547 origin = dns_db_origin(db);
552 hash = nsec3param->hash;
553 iterations = nsec3param->iterations;
554 salt_length = nsec3param->salt_length;
555 salt = nsec3param->salt;
558 * Default flags for a new chain.
560 flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
563 * If this is the first NSEC3 in the chain nexthash will
564 * remain pointing to itself.
566 next_length = sizeof(nexthash);
567 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
568 name, origin, hash, iterations,
570 INSIST(next_length <= sizeof(nexthash));
573 * Create the node if it doesn't exist and hold
574 * a reference to it until we have added the NSEC3.
576 CHECK(dns_db_findnsec3node(db, hashname, ISC_TRUE, &newnode));
579 * Seek the iterator to the 'newnode'.
581 CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
582 CHECK(dns_dbiterator_seek(dbit, hashname));
583 CHECK(dns_dbiterator_pause(dbit));
584 result = dns_db_findrdataset(db, newnode, version, dns_rdatatype_nsec3,
585 0, (isc_stdtime_t) 0, &rdataset, NULL);
587 * If we updating a existing NSEC3 then find its
590 if (result == ISC_R_SUCCESS) {
591 result = find_nsec3(&nsec3, &rdataset, nsec3param);
592 if (result == ISC_R_SUCCESS) {
593 if (!CREATE(nsec3param->flags))
595 next_length = nsec3.next_length;
596 INSIST(next_length <= sizeof(nexthash));
597 memmove(nexthash, nsec3.next, next_length);
598 dns_rdataset_disassociate(&rdataset);
600 * If the NSEC3 is not for a unsecure delegation then
601 * we are just updating it. If it is for a unsecure
602 * delegation then we need find out if we need to
603 * remove the NSEC3 record or not by examining the
604 * previous NSEC3 record.
608 else if (CREATE(nsec3param->flags) && OPTOUT(flags)) {
609 result = dns_nsec3_delnsec3(db, version, name,
613 maybe_remove_unsecure = ISC_TRUE;
615 dns_rdataset_disassociate(&rdataset);
616 if (result != ISC_R_NOMORE)
622 * Find the previous NSEC3 (if any) and update it if required.
626 result = dns_dbiterator_prev(dbit);
627 if (result == ISC_R_NOMORE) {
629 CHECK(dns_dbiterator_last(dbit));
631 CHECK(dns_dbiterator_current(dbit, &node, prev));
632 CHECK(dns_dbiterator_pause(dbit));
633 result = dns_db_findrdataset(db, node, version,
634 dns_rdatatype_nsec3, 0,
635 (isc_stdtime_t) 0, &rdataset,
637 dns_db_detachnode(db, &node);
638 if (result != ISC_R_SUCCESS)
641 result = find_nsec3(&nsec3, &rdataset, nsec3param);
642 if (result == ISC_R_NOMORE) {
643 dns_rdataset_disassociate(&rdataset);
646 if (result != ISC_R_SUCCESS)
649 if (maybe_remove_unsecure) {
650 dns_rdataset_disassociate(&rdataset);
652 * If we have OPTOUT set in the previous NSEC3 record
653 * we actually need to delete the NSEC3 record.
654 * Otherwise we just need to replace the NSEC3 record.
656 if (OPTOUT(nsec3.flags)) {
657 result = dns_nsec3_delnsec3(db, version, name,
664 * Is this is a unsecure delegation we are adding?
665 * If so no change is required.
667 if (OPTOUT(nsec3.flags) && unsecure) {
668 dns_rdataset_disassociate(&rdataset);
673 old_next = nsec3.next;
674 old_length = nsec3.next_length;
677 * Delete the old previous NSEC3.
679 CHECK(delete(db, version, prev, nsec3param, diff));
682 * Fixup the previous NSEC3.
684 nsec3.next = nexthash;
685 nsec3.next_length = (unsigned char)next_length;
686 isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
687 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
688 dns_rdatatype_nsec3, &nsec3,
690 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
691 rdataset.ttl, &rdata, &tuple));
692 CHECK(do_one_tuple(&tuple, db, version, diff));
693 INSIST(old_length <= sizeof(nexthash));
694 memmove(nexthash, old_next, old_length);
695 if (!CREATE(nsec3param->flags))
697 dns_rdata_reset(&rdata);
698 dns_rdataset_disassociate(&rdataset);
704 * Create the NSEC3 RDATA.
706 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
707 CHECK(dns_nsec3_buildrdata(db, version, node, hash, flags, iterations,
708 salt, salt_length, nexthash, next_length,
710 dns_db_detachnode(db, &node);
713 * Delete the old NSEC3 and record the change.
715 CHECK(delete(db, version, hashname, nsec3param, diff));
717 * Add the new NSEC3 and record the change.
719 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
720 hashname, nsecttl, &rdata, &tuple));
721 CHECK(do_one_tuple(&tuple, db, version, diff));
722 INSIST(tuple == NULL);
723 dns_rdata_reset(&rdata);
724 dns_db_detachnode(db, &newnode);
727 * Add missing NSEC3 records for empty nodes
729 dns_name_init(&empty, NULL);
730 dns_name_clone(name, &empty);
732 labels = dns_name_countlabels(&empty) - 1;
733 if (labels <= dns_name_countlabels(origin))
735 dns_name_getlabelsequence(&empty, 1, labels, &empty);
736 CHECK(name_exists(db, version, &empty, &exists));
739 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
740 &empty, origin, hash, iterations,
744 * Create the node if it doesn't exist and hold
745 * a reference to it until we have added the NSEC3
746 * or we discover we don't need to add make a change.
748 CHECK(dns_db_findnsec3node(db, hashname, ISC_TRUE, &newnode));
749 result = dns_db_findrdataset(db, newnode, version,
750 dns_rdatatype_nsec3, 0,
751 (isc_stdtime_t) 0, &rdataset,
753 if (result == ISC_R_SUCCESS) {
754 result = find_nsec3(&nsec3, &rdataset, nsec3param);
755 dns_rdataset_disassociate(&rdataset);
756 if (result == ISC_R_SUCCESS) {
757 dns_db_detachnode(db, &newnode);
760 if (result != ISC_R_NOMORE)
765 * Find the previous NSEC3 and update it.
767 CHECK(dns_dbiterator_seek(dbit, hashname));
770 result = dns_dbiterator_prev(dbit);
771 if (result == ISC_R_NOMORE) {
773 CHECK(dns_dbiterator_last(dbit));
775 CHECK(dns_dbiterator_current(dbit, &node, prev));
776 CHECK(dns_dbiterator_pause(dbit));
777 result = dns_db_findrdataset(db, node, version,
778 dns_rdatatype_nsec3, 0,
781 dns_db_detachnode(db, &node);
782 if (result != ISC_R_SUCCESS)
784 result = find_nsec3(&nsec3, &rdataset, nsec3param);
785 if (result == ISC_R_NOMORE) {
786 dns_rdataset_disassociate(&rdataset);
789 if (result != ISC_R_SUCCESS)
792 old_next = nsec3.next;
793 old_length = nsec3.next_length;
796 * Delete the old previous NSEC3.
798 CHECK(delete(db, version, prev, nsec3param, diff));
801 * Fixup the previous NSEC3.
803 nsec3.next = nexthash;
804 nsec3.next_length = (unsigned char)next_length;
805 isc_buffer_init(&buffer, nsec3buf,
807 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
808 dns_rdatatype_nsec3, &nsec3,
810 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
811 prev, rdataset.ttl, &rdata,
813 CHECK(do_one_tuple(&tuple, db, version, diff));
814 INSIST(old_length <= sizeof(nexthash));
815 memmove(nexthash, old_next, old_length);
816 if (!CREATE(nsec3param->flags))
818 dns_rdata_reset(&rdata);
819 dns_rdataset_disassociate(&rdataset);
826 * Create the NSEC3 RDATA for the empty node.
828 CHECK(dns_nsec3_buildrdata(db, version, NULL, hash, flags,
829 iterations, salt, salt_length,
830 nexthash, next_length, nsec3buf,
833 * Delete the old NSEC3 and record the change.
835 CHECK(delete(db, version, hashname, nsec3param, diff));
838 * Add the new NSEC3 and record the change.
840 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
841 hashname, nsecttl, &rdata, &tuple));
842 CHECK(do_one_tuple(&tuple, db, version, diff));
843 INSIST(tuple == NULL);
844 dns_rdata_reset(&rdata);
845 dns_db_detachnode(db, &newnode);
848 /* result cannot be ISC_R_NOMORE here */
849 INSIST(result != ISC_R_NOMORE);
853 dns_dbiterator_destroy(&dbit);
854 if (dns_rdataset_isassociated(&rdataset))
855 dns_rdataset_disassociate(&rdataset);
857 dns_db_detachnode(db, &node);
859 dns_db_detachnode(db, &newnode);
864 * Add NSEC3 records for "name", recording the change in "diff".
865 * The existing NSEC3 records are removed.
868 dns_nsec3_addnsec3s(dns_db_t *db, dns_dbversion_t *version,
869 dns_name_t *name, dns_ttl_t nsecttl,
870 isc_boolean_t unsecure, dns_diff_t *diff)
872 dns_dbnode_t *node = NULL;
873 dns_rdata_nsec3param_t nsec3param;
874 dns_rdataset_t rdataset;
877 dns_rdataset_init(&rdataset);
880 * Find the NSEC3 parameters for this zone.
882 result = dns_db_getoriginnode(db, &node);
883 if (result != ISC_R_SUCCESS)
886 result = dns_db_findrdataset(db, node, version,
887 dns_rdatatype_nsec3param, 0, 0,
889 dns_db_detachnode(db, &node);
890 if (result == ISC_R_NOTFOUND)
891 return (ISC_R_SUCCESS);
892 if (result != ISC_R_SUCCESS)
896 * Update each active NSEC3 chain.
898 for (result = dns_rdataset_first(&rdataset);
899 result == ISC_R_SUCCESS;
900 result = dns_rdataset_next(&rdataset)) {
901 dns_rdata_t rdata = DNS_RDATA_INIT;
903 dns_rdataset_current(&rdataset, &rdata);
904 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
906 if (nsec3param.flags != 0)
909 * We have a active chain. Update it.
911 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
912 nsecttl, unsecure, diff));
914 if (result == ISC_R_NOMORE)
915 result = ISC_R_SUCCESS;
918 if (dns_rdataset_isassociated(&rdataset))
919 dns_rdataset_disassociate(&rdataset);
921 dns_db_detachnode(db, &node);
927 dns_nsec3param_fromprivate(dns_rdata_t *src, dns_rdata_t *target,
928 unsigned char *buf, size_t buflen)
930 dns_decompress_t dctx;
936 * Algorithm 0 (reserved by RFC 4034) is used to identify
937 * NSEC3PARAM records from DNSKEY pointers.
939 if (src->length < 1 || src->data[0] != 0)
942 isc_buffer_init(&buf1, src->data + 1, src->length - 1);
943 isc_buffer_add(&buf1, src->length - 1);
944 isc_buffer_setactive(&buf1, src->length - 1);
945 isc_buffer_init(&buf2, buf, (unsigned int)buflen);
946 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
947 result = dns_rdata_fromwire(target, src->rdclass,
948 dns_rdatatype_nsec3param,
949 &buf1, &dctx, 0, &buf2);
950 dns_decompress_invalidate(&dctx);
952 return (ISC_TF(result == ISC_R_SUCCESS));
956 dns_nsec3param_toprivate(dns_rdata_t *src, dns_rdata_t *target,
957 dns_rdatatype_t privatetype,
958 unsigned char *buf, size_t buflen)
960 REQUIRE(buflen >= src->length + 1);
962 REQUIRE(DNS_RDATA_INITIALIZED(target));
964 memmove(buf + 1, src->data, src->length);
967 target->length = src->length + 1;
968 target->type = privatetype;
969 target->rdclass = src->rdclass;
971 ISC_LINK_INIT(target, link);
976 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
977 const dns_rdata_t *rdata, isc_boolean_t *flag)
979 dns_rdataset_t rdataset;
980 dns_dbnode_t *node = NULL;
983 dns_rdataset_init(&rdataset);
984 if (rdata->type == dns_rdatatype_nsec3)
985 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
987 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
988 result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
989 (isc_stdtime_t) 0, &rdataset, NULL);
990 if (result == ISC_R_NOTFOUND) {
992 result = ISC_R_SUCCESS;
996 for (result = dns_rdataset_first(&rdataset);
997 result == ISC_R_SUCCESS;
998 result = dns_rdataset_next(&rdataset)) {
999 dns_rdata_t myrdata = DNS_RDATA_INIT;
1000 dns_rdataset_current(&rdataset, &myrdata);
1001 if (!dns_rdata_casecompare(&myrdata, rdata))
1004 dns_rdataset_disassociate(&rdataset);
1005 if (result == ISC_R_SUCCESS) {
1007 } else if (result == ISC_R_NOMORE) {
1009 result = ISC_R_SUCCESS;
1014 dns_db_detachnode(db, &node);
1021 dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver,
1022 dns_zone_t *zone, isc_boolean_t nonsec,
1025 dns_dbnode_t *node = NULL;
1026 dns_difftuple_t *tuple = NULL;
1028 dns_rdata_t rdata = DNS_RDATA_INIT;
1029 dns_rdataset_t rdataset;
1031 isc_result_t result = ISC_R_SUCCESS;
1032 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE + 1];
1033 dns_name_t *origin = dns_zone_getorigin(zone);
1034 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
1036 dns_name_init(&next, NULL);
1037 dns_rdataset_init(&rdataset);
1039 result = dns_db_getoriginnode(db, &node);
1040 if (result != ISC_R_SUCCESS)
1044 * Cause all NSEC3 chains to be deleted.
1046 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
1047 0, (isc_stdtime_t) 0, &rdataset, NULL);
1048 if (result == ISC_R_NOTFOUND)
1050 if (result != ISC_R_SUCCESS)
1053 for (result = dns_rdataset_first(&rdataset);
1054 result == ISC_R_SUCCESS;
1055 result = dns_rdataset_next(&rdataset)) {
1056 dns_rdata_t private = DNS_RDATA_INIT;
1058 dns_rdataset_current(&rdataset, &rdata);
1060 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
1061 rdataset.ttl, &rdata, &tuple));
1062 CHECK(do_one_tuple(&tuple, db, ver, diff));
1063 INSIST(tuple == NULL);
1065 dns_nsec3param_toprivate(&rdata, &private, privatetype,
1067 buf[2] = DNS_NSEC3FLAG_REMOVE;
1069 buf[2] |= DNS_NSEC3FLAG_NONSEC;
1071 CHECK(rr_exists(db, ver, origin, &private, &flag));
1074 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1075 origin, 0, &private,
1077 CHECK(do_one_tuple(&tuple, db, ver, diff));
1078 INSIST(tuple == NULL);
1080 dns_rdata_reset(&rdata);
1082 if (result != ISC_R_NOMORE)
1085 dns_rdataset_disassociate(&rdataset);
1088 if (privatetype == 0)
1090 result = dns_db_findrdataset(db, node, ver, privatetype, 0,
1091 (isc_stdtime_t) 0, &rdataset, NULL);
1092 if (result == ISC_R_NOTFOUND)
1094 if (result != ISC_R_SUCCESS)
1097 for (result = dns_rdataset_first(&rdataset);
1098 result == ISC_R_SUCCESS;
1099 result = dns_rdataset_next(&rdataset)) {
1100 dns_rdata_reset(&rdata);
1101 dns_rdataset_current(&rdataset, &rdata);
1102 INSIST(rdata.length <= sizeof(buf));
1103 memmove(buf, rdata.data, rdata.length);
1106 * Private NSEC3 record length >= 6.
1107 * <0(1), hash(1), flags(1), iterations(2), saltlen(1)>
1109 if (rdata.length < 6 || buf[0] != 0 ||
1110 (buf[2] & DNS_NSEC3FLAG_REMOVE) != 0 ||
1111 (nonsec && (buf[2] & DNS_NSEC3FLAG_NONSEC) != 0))
1114 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
1115 0, &rdata, &tuple));
1116 CHECK(do_one_tuple(&tuple, db, ver, diff));
1117 INSIST(tuple == NULL);
1120 buf[2] = DNS_NSEC3FLAG_REMOVE;
1122 buf[2] |= DNS_NSEC3FLAG_NONSEC;
1124 CHECK(rr_exists(db, ver, origin, &rdata, &flag));
1127 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1128 origin, 0, &rdata, &tuple));
1129 CHECK(do_one_tuple(&tuple, db, ver, diff));
1130 INSIST(tuple == NULL);
1133 if (result != ISC_R_NOMORE)
1136 result = ISC_R_SUCCESS;
1139 if (dns_rdataset_isassociated(&rdataset))
1140 dns_rdataset_disassociate(&rdataset);
1141 dns_db_detachnode(db, &node);
1147 dns_nsec3_addnsec3sx(dns_db_t *db, dns_dbversion_t *version,
1148 dns_name_t *name, dns_ttl_t nsecttl,
1149 isc_boolean_t unsecure, dns_rdatatype_t type,
1152 dns_dbnode_t *node = NULL;
1153 dns_rdata_nsec3param_t nsec3param;
1154 dns_rdataset_t rdataset;
1155 dns_rdataset_t prdataset;
1156 isc_result_t result;
1158 dns_rdataset_init(&rdataset);
1159 dns_rdataset_init(&prdataset);
1162 * Find the NSEC3 parameters for this zone.
1164 result = dns_db_getoriginnode(db, &node);
1165 if (result != ISC_R_SUCCESS)
1168 result = dns_db_findrdataset(db, node, version, type, 0, 0,
1170 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
1173 result = dns_db_findrdataset(db, node, version,
1174 dns_rdatatype_nsec3param, 0, 0,
1176 if (result == ISC_R_NOTFOUND)
1178 if (result != ISC_R_SUCCESS)
1182 * Update each active NSEC3 chain.
1184 for (result = dns_rdataset_first(&rdataset);
1185 result == ISC_R_SUCCESS;
1186 result = dns_rdataset_next(&rdataset)) {
1187 dns_rdata_t rdata = DNS_RDATA_INIT;
1189 dns_rdataset_current(&rdataset, &rdata);
1190 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
1192 if (nsec3param.flags != 0)
1196 * We have a active chain. Update it.
1198 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
1199 nsecttl, unsecure, diff));
1201 if (result != ISC_R_NOMORE)
1204 dns_rdataset_disassociate(&rdataset);
1207 if (!dns_rdataset_isassociated(&prdataset))
1210 * Update each active NSEC3 chain.
1212 for (result = dns_rdataset_first(&prdataset);
1213 result == ISC_R_SUCCESS;
1214 result = dns_rdataset_next(&prdataset)) {
1215 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1216 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1217 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1219 dns_rdataset_current(&prdataset, &rdata1);
1220 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
1223 CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
1225 if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
1227 if (better_param(&prdataset, &rdata2))
1231 * We have a active chain. Update it.
1233 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
1234 nsecttl, unsecure, diff));
1236 if (result == ISC_R_NOMORE)
1238 result = ISC_R_SUCCESS;
1240 if (dns_rdataset_isassociated(&rdataset))
1241 dns_rdataset_disassociate(&rdataset);
1242 if (dns_rdataset_isassociated(&prdataset))
1243 dns_rdataset_disassociate(&prdataset);
1245 dns_db_detachnode(db, &node);
1251 * Determine whether any NSEC3 records that were associated with
1252 * 'name' should be deleted or if they should continue to exist.
1253 * ISC_TRUE indicates they should be deleted.
1254 * ISC_FALSE indicates they should be retained.
1257 deleteit(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
1258 isc_boolean_t *yesno)
1260 isc_result_t result;
1261 dns_fixedname_t foundname;
1262 dns_fixedname_init(&foundname);
1264 result = dns_db_find(db, name, ver, dns_rdatatype_any,
1265 DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD,
1266 (isc_stdtime_t) 0, NULL,
1267 dns_fixedname_name(&foundname),
1269 if (result == DNS_R_EMPTYNAME || result == ISC_R_SUCCESS ||
1270 result == DNS_R_ZONECUT) {
1272 return (ISC_R_SUCCESS);
1274 if (result == DNS_R_GLUE || result == DNS_R_DNAME ||
1275 result == DNS_R_DELEGATION || result == DNS_R_NXDOMAIN) {
1277 return (ISC_R_SUCCESS);
1287 dns_nsec3_delnsec3(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1288 const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff)
1290 dns_dbiterator_t *dbit = NULL;
1291 dns_dbnode_t *node = NULL;
1292 dns_difftuple_t *tuple = NULL;
1293 dns_fixedname_t fixed;
1294 dns_fixedname_t fprev;
1296 dns_name_t *hashname;
1300 dns_rdata_nsec3_t nsec3;
1301 dns_rdata_t rdata = DNS_RDATA_INIT;
1302 dns_rdataset_t rdataset;
1304 isc_boolean_t yesno;
1305 isc_buffer_t buffer;
1306 isc_result_t result;
1307 unsigned char *salt;
1308 unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
1309 unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
1310 unsigned int iterations;
1311 unsigned int labels;
1313 unsigned int salt_length;
1315 dns_fixedname_init(&fixed);
1316 hashname = dns_fixedname_name(&fixed);
1317 dns_fixedname_init(&fprev);
1318 prev = dns_fixedname_name(&fprev);
1320 dns_rdataset_init(&rdataset);
1322 origin = dns_db_origin(db);
1327 hash = nsec3param->hash;
1328 iterations = nsec3param->iterations;
1329 salt_length = nsec3param->salt_length;
1330 salt = nsec3param->salt;
1333 * If this is the first NSEC3 in the chain nexthash will
1334 * remain pointing to itself.
1336 next_length = sizeof(nexthash);
1337 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
1338 name, origin, hash, iterations,
1339 salt, salt_length));
1341 CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
1343 result = dns_dbiterator_seek(dbit, hashname);
1344 if (result == ISC_R_NOTFOUND)
1346 if (result != ISC_R_SUCCESS)
1349 CHECK(dns_dbiterator_current(dbit, &node, NULL));
1350 CHECK(dns_dbiterator_pause(dbit));
1351 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3,
1352 0, (isc_stdtime_t) 0, &rdataset, NULL);
1353 dns_db_detachnode(db, &node);
1354 if (result == ISC_R_NOTFOUND)
1356 if (result != ISC_R_SUCCESS)
1360 * If we find a existing NSEC3 for this chain then save the
1363 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1364 if (result == ISC_R_SUCCESS) {
1365 next_length = nsec3.next_length;
1366 INSIST(next_length <= sizeof(nexthash));
1367 memmove(nexthash, nsec3.next, next_length);
1369 dns_rdataset_disassociate(&rdataset);
1370 if (result == ISC_R_NOMORE)
1372 if (result != ISC_R_SUCCESS)
1376 * Find the previous NSEC3 and update it.
1380 result = dns_dbiterator_prev(dbit);
1381 if (result == ISC_R_NOMORE) {
1383 CHECK(dns_dbiterator_last(dbit));
1385 CHECK(dns_dbiterator_current(dbit, &node, prev));
1386 CHECK(dns_dbiterator_pause(dbit));
1387 result = dns_db_findrdataset(db, node, version,
1388 dns_rdatatype_nsec3, 0,
1389 (isc_stdtime_t) 0, &rdataset,
1391 dns_db_detachnode(db, &node);
1392 if (result != ISC_R_SUCCESS)
1394 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1395 if (result == ISC_R_NOMORE) {
1396 dns_rdataset_disassociate(&rdataset);
1399 if (result != ISC_R_SUCCESS)
1403 * Delete the old previous NSEC3.
1405 CHECK(delete(db, version, prev, nsec3param, diff));
1408 * Fixup the previous NSEC3.
1410 nsec3.next = nexthash;
1411 nsec3.next_length = (unsigned char)next_length;
1412 if (CREATE(nsec3param->flags))
1413 nsec3.flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
1414 isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
1415 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
1416 dns_rdatatype_nsec3, &nsec3,
1418 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
1419 rdataset.ttl, &rdata, &tuple));
1420 CHECK(do_one_tuple(&tuple, db, version, diff));
1421 dns_rdata_reset(&rdata);
1422 dns_rdataset_disassociate(&rdataset);
1427 * Delete the old NSEC3 and record the change.
1429 CHECK(delete(db, version, hashname, nsec3param, diff));
1432 * Delete NSEC3 records for now non active nodes.
1434 dns_name_init(&empty, NULL);
1435 dns_name_clone(name, &empty);
1437 labels = dns_name_countlabels(&empty) - 1;
1438 if (labels <= dns_name_countlabels(origin))
1440 dns_name_getlabelsequence(&empty, 1, labels, &empty);
1441 CHECK(deleteit(db, version, &empty, &yesno));
1445 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
1446 &empty, origin, hash, iterations,
1447 salt, salt_length));
1448 result = dns_dbiterator_seek(dbit, hashname);
1449 if (result == ISC_R_NOTFOUND)
1451 if (result != ISC_R_SUCCESS)
1454 CHECK(dns_dbiterator_current(dbit, &node, NULL));
1455 CHECK(dns_dbiterator_pause(dbit));
1456 result = dns_db_findrdataset(db, node, version,
1457 dns_rdatatype_nsec3, 0,
1458 (isc_stdtime_t) 0, &rdataset,
1460 dns_db_detachnode(db, &node);
1461 if (result == ISC_R_NOTFOUND)
1463 if (result != ISC_R_SUCCESS)
1466 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1467 if (result == ISC_R_SUCCESS) {
1468 next_length = nsec3.next_length;
1469 INSIST(next_length <= sizeof(nexthash));
1470 memmove(nexthash, nsec3.next, next_length);
1472 dns_rdataset_disassociate(&rdataset);
1473 if (result == ISC_R_NOMORE)
1475 if (result != ISC_R_SUCCESS)
1480 result = dns_dbiterator_prev(dbit);
1481 if (result == ISC_R_NOMORE) {
1483 CHECK(dns_dbiterator_last(dbit));
1485 CHECK(dns_dbiterator_current(dbit, &node, prev));
1486 CHECK(dns_dbiterator_pause(dbit));
1487 result = dns_db_findrdataset(db, node, version,
1488 dns_rdatatype_nsec3, 0,
1491 dns_db_detachnode(db, &node);
1492 if (result != ISC_R_SUCCESS)
1494 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1495 if (result == ISC_R_NOMORE) {
1496 dns_rdataset_disassociate(&rdataset);
1499 if (result != ISC_R_SUCCESS)
1503 * Delete the old previous NSEC3.
1505 CHECK(delete(db, version, prev, nsec3param, diff));
1508 * Fixup the previous NSEC3.
1510 nsec3.next = nexthash;
1511 nsec3.next_length = (unsigned char)next_length;
1512 isc_buffer_init(&buffer, nsec3buf,
1514 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
1515 dns_rdatatype_nsec3, &nsec3,
1517 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1518 prev, rdataset.ttl, &rdata,
1520 CHECK(do_one_tuple(&tuple, db, version, diff));
1521 dns_rdata_reset(&rdata);
1522 dns_rdataset_disassociate(&rdataset);
1529 * Delete the old NSEC3 and record the change.
1531 CHECK(delete(db, version, hashname, nsec3param, diff));
1535 result = ISC_R_SUCCESS;
1539 dns_dbiterator_destroy(&dbit);
1540 if (dns_rdataset_isassociated(&rdataset))
1541 dns_rdataset_disassociate(&rdataset);
1543 dns_db_detachnode(db, &node);
1548 dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1551 return (dns_nsec3_delnsec3sx(db, version, name, 0, diff));
1555 dns_nsec3_delnsec3sx(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1556 dns_rdatatype_t privatetype, dns_diff_t *diff)
1558 dns_dbnode_t *node = NULL;
1559 dns_rdata_nsec3param_t nsec3param;
1560 dns_rdataset_t rdataset;
1561 isc_result_t result;
1563 dns_rdataset_init(&rdataset);
1566 * Find the NSEC3 parameters for this zone.
1568 result = dns_db_getoriginnode(db, &node);
1569 if (result != ISC_R_SUCCESS)
1572 result = dns_db_findrdataset(db, node, version,
1573 dns_rdatatype_nsec3param, 0, 0,
1575 if (result == ISC_R_NOTFOUND)
1577 if (result != ISC_R_SUCCESS)
1581 * Update each active NSEC3 chain.
1583 for (result = dns_rdataset_first(&rdataset);
1584 result == ISC_R_SUCCESS;
1585 result = dns_rdataset_next(&rdataset)) {
1586 dns_rdata_t rdata = DNS_RDATA_INIT;
1588 dns_rdataset_current(&rdataset, &rdata);
1589 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
1591 if (nsec3param.flags != 0)
1594 * We have a active chain. Update it.
1596 CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
1598 dns_rdataset_disassociate(&rdataset);
1601 if (privatetype == 0)
1603 result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
1605 if (result == ISC_R_NOTFOUND)
1607 if (result != ISC_R_SUCCESS)
1611 * Update each NSEC3 chain being built.
1613 for (result = dns_rdataset_first(&rdataset);
1614 result == ISC_R_SUCCESS;
1615 result = dns_rdataset_next(&rdataset)) {
1616 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1617 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1618 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1620 dns_rdataset_current(&rdataset, &rdata1);
1621 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
1624 CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
1626 if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
1628 if (better_param(&rdataset, &rdata2))
1632 * We have a active chain. Update it.
1634 CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
1636 if (result == ISC_R_NOMORE)
1638 result = ISC_R_SUCCESS;
1641 if (dns_rdataset_isassociated(&rdataset))
1642 dns_rdataset_disassociate(&rdataset);
1644 dns_db_detachnode(db, &node);
1650 dns_nsec3_active(dns_db_t *db, dns_dbversion_t *version,
1651 isc_boolean_t complete, isc_boolean_t *answer)
1653 return (dns_nsec3_activex(db, version, complete, 0, answer));
1657 dns_nsec3_activex(dns_db_t *db, dns_dbversion_t *version,
1658 isc_boolean_t complete, dns_rdatatype_t privatetype,
1659 isc_boolean_t *answer)
1661 dns_dbnode_t *node = NULL;
1662 dns_rdataset_t rdataset;
1663 dns_rdata_nsec3param_t nsec3param;
1664 isc_result_t result;
1666 REQUIRE(answer != NULL);
1668 dns_rdataset_init(&rdataset);
1670 result = dns_db_getoriginnode(db, &node);
1671 if (result != ISC_R_SUCCESS)
1674 result = dns_db_findrdataset(db, node, version,
1675 dns_rdatatype_nsec3param, 0, 0,
1678 if (result == ISC_R_NOTFOUND)
1681 if (result != ISC_R_SUCCESS) {
1682 dns_db_detachnode(db, &node);
1685 for (result = dns_rdataset_first(&rdataset);
1686 result == ISC_R_SUCCESS;
1687 result = dns_rdataset_next(&rdataset)) {
1688 dns_rdata_t rdata = DNS_RDATA_INIT;
1690 dns_rdataset_current(&rdataset, &rdata);
1691 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
1692 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1694 if (nsec3param.flags == 0)
1697 dns_rdataset_disassociate(&rdataset);
1698 if (result == ISC_R_SUCCESS) {
1699 dns_db_detachnode(db, &node);
1701 return (ISC_R_SUCCESS);
1703 if (result == ISC_R_NOMORE)
1704 *answer = ISC_FALSE;
1707 if (privatetype == 0 || complete) {
1708 *answer = ISC_FALSE;
1709 return (ISC_R_SUCCESS);
1711 result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
1714 dns_db_detachnode(db, &node);
1715 if (result == ISC_R_NOTFOUND) {
1716 *answer = ISC_FALSE;
1717 return (ISC_R_SUCCESS);
1719 if (result != ISC_R_SUCCESS)
1722 for (result = dns_rdataset_first(&rdataset);
1723 result == ISC_R_SUCCESS;
1724 result = dns_rdataset_next(&rdataset)) {
1725 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1726 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1727 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1729 dns_rdataset_current(&rdataset, &rdata1);
1730 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
1733 result = dns_rdata_tostruct(&rdata2, &nsec3param, NULL);
1734 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1736 if (!complete && CREATE(nsec3param.flags))
1739 dns_rdataset_disassociate(&rdataset);
1740 if (result == ISC_R_SUCCESS) {
1742 result = ISC_R_SUCCESS;
1744 if (result == ISC_R_NOMORE) {
1745 *answer = ISC_FALSE;
1746 result = ISC_R_SUCCESS;
1753 dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version,
1754 isc_mem_t *mctx, unsigned int *iterationsp)
1756 dns_dbnode_t *node = NULL;
1757 dns_rdataset_t rdataset;
1758 dst_key_t *key = NULL;
1759 isc_buffer_t buffer;
1760 isc_result_t result;
1761 unsigned int bits, minbits = 4096;
1763 result = dns_db_getoriginnode(db, &node);
1764 if (result != ISC_R_SUCCESS)
1767 dns_rdataset_init(&rdataset);
1768 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
1769 0, 0, &rdataset, NULL);
1770 dns_db_detachnode(db, &node);
1771 if (result == ISC_R_NOTFOUND) {
1773 return (ISC_R_SUCCESS);
1775 if (result != ISC_R_SUCCESS)
1778 for (result = dns_rdataset_first(&rdataset);
1779 result == ISC_R_SUCCESS;
1780 result = dns_rdataset_next(&rdataset)) {
1781 dns_rdata_t rdata = DNS_RDATA_INIT;
1783 dns_rdataset_current(&rdataset, &rdata);
1784 isc_buffer_init(&buffer, rdata.data, rdata.length);
1785 isc_buffer_add(&buffer, rdata.length);
1786 CHECK(dst_key_fromdns(dns_db_origin(db), rdataset.rdclass,
1787 &buffer, mctx, &key));
1788 bits = dst_key_size(key);
1793 if (result != ISC_R_NOMORE)
1796 if (minbits <= 1024)
1798 else if (minbits <= 2048)
1801 *iterationsp = 2500;
1802 result = ISC_R_SUCCESS;
1805 if (dns_rdataset_isassociated(&rdataset))
1806 dns_rdataset_disassociate(&rdataset);
1811 dns_nsec3_noexistnodata(dns_rdatatype_t type, dns_name_t* name,
1812 dns_name_t *nsec3name, dns_rdataset_t *nsec3set,
1813 dns_name_t *zonename, isc_boolean_t *exists,
1814 isc_boolean_t *data, isc_boolean_t *optout,
1815 isc_boolean_t *unknown, isc_boolean_t *setclosest,
1816 isc_boolean_t *setnearest, dns_name_t *closest,
1817 dns_name_t *nearest, dns_nseclog_t logit, void *arg)
1819 char namebuf[DNS_NAME_FORMATSIZE];
1820 dns_fixedname_t fzone;
1821 dns_fixedname_t qfixed;
1822 dns_label_t hashlabel;
1825 dns_rdata_nsec3_t nsec3;
1826 dns_rdata_t rdata = DNS_RDATA_INIT;
1829 isc_boolean_t atparent;
1830 isc_boolean_t first;
1833 isc_buffer_t buffer;
1834 isc_result_t answer = ISC_R_IGNORE;
1835 isc_result_t result;
1836 unsigned char hash[NSEC3_MAX_HASH_LENGTH];
1837 unsigned char owner[NSEC3_MAX_HASH_LENGTH];
1838 unsigned int length;
1839 unsigned int qlabels;
1840 unsigned int zlabels;
1842 REQUIRE((exists == NULL && data == NULL) ||
1843 (exists != NULL && data != NULL));
1844 REQUIRE(nsec3set != NULL && nsec3set->type == dns_rdatatype_nsec3);
1845 REQUIRE((setclosest == NULL && closest == NULL) ||
1846 (setclosest != NULL && closest != NULL));
1847 REQUIRE((setnearest == NULL && nearest == NULL) ||
1848 (setnearest != NULL && nearest != NULL));
1850 result = dns_rdataset_first(nsec3set);
1851 if (result != ISC_R_SUCCESS) {
1852 (*logit)(arg, ISC_LOG_DEBUG(3), "failure processing NSEC3 set");
1856 dns_rdataset_current(nsec3set, &rdata);
1858 result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
1859 if (result != ISC_R_SUCCESS)
1862 (*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant NSEC3");
1864 dns_fixedname_init(&fzone);
1865 zone = dns_fixedname_name(&fzone);
1866 zlabels = dns_name_countlabels(nsec3name);
1869 * NSEC3 records must have two or more labels to be valid.
1872 return (ISC_R_IGNORE);
1875 * Strip off the NSEC3 hash to get the zone.
1878 dns_name_split(nsec3name, zlabels, NULL, zone);
1881 * If not below the zone name we can ignore this record.
1883 if (!dns_name_issubdomain(name, zone))
1884 return (ISC_R_IGNORE);
1887 * Is this zone the same or deeper than the current zone?
1889 if (dns_name_countlabels(zonename) == 0 ||
1890 dns_name_issubdomain(zone, zonename))
1891 dns_name_copy(zone, zonename, NULL);
1893 if (!dns_name_equal(zone, zonename))
1894 return (ISC_R_IGNORE);
1897 * Are we only looking for the most enclosing zone?
1899 if (exists == NULL || data == NULL)
1900 return (ISC_R_SUCCESS);
1903 * Only set unknown once we are sure that this NSEC3 is from
1904 * the deepest covering zone.
1906 if (!dns_nsec3_supportedhash(nsec3.hash)) {
1907 if (unknown != NULL)
1908 *unknown = ISC_TRUE;
1909 return (ISC_R_IGNORE);
1913 * Recover the hash from the first label.
1915 dns_name_getlabel(nsec3name, 0, &hashlabel);
1916 isc_region_consume(&hashlabel, 1);
1917 isc_buffer_init(&buffer, owner, sizeof(owner));
1918 result = isc_base32hex_decoderegion(&hashlabel, &buffer);
1919 if (result != ISC_R_SUCCESS)
1923 * The hash lengths should match. If not ignore the record.
1925 if (isc_buffer_usedlength(&buffer) != nsec3.next_length)
1926 return (ISC_R_IGNORE);
1929 * Work out what this NSEC3 covers.
1930 * Inside (<0) or outside (>=0).
1932 scope = memcmp(owner, nsec3.next, nsec3.next_length);
1935 * Prepare to compute all the hashes.
1937 dns_fixedname_init(&qfixed);
1938 qname = dns_fixedname_name(&qfixed);
1939 dns_name_downcase(name, qname, NULL);
1940 qlabels = dns_name_countlabels(qname);
1943 while (qlabels >= zlabels) {
1944 length = isc_iterated_hash(hash, nsec3.hash, nsec3.iterations,
1945 nsec3.salt, nsec3.salt_length,
1946 qname->ndata, qname->length);
1948 * The computed hash length should match.
1950 if (length != nsec3.next_length) {
1951 (*logit)(arg, ISC_LOG_DEBUG(3),
1952 "ignoring NSEC bad length %u vs %u",
1953 length, nsec3.next_length);
1954 return (ISC_R_IGNORE);
1957 order = memcmp(hash, owner, length);
1958 if (first && order == 0) {
1960 * The hashes are the same.
1962 atparent = dns_rdatatype_atparent(type);
1963 ns = dns_nsec3_typepresent(&rdata, dns_rdatatype_ns);
1964 soa = dns_nsec3_typepresent(&rdata, dns_rdatatype_soa);
1968 * This NSEC3 record is from somewhere
1969 * higher in the DNS, and at the
1970 * parent of a delegation. It can not
1971 * be legitimately used here.
1973 (*logit)(arg, ISC_LOG_DEBUG(3),
1974 "ignoring parent NSEC3");
1975 return (ISC_R_IGNORE);
1977 } else if (atparent && ns && soa) {
1979 * This NSEC3 record is from the child.
1980 * It can not be legitimately used here.
1982 (*logit)(arg, ISC_LOG_DEBUG(3),
1983 "ignoring child NSEC3");
1984 return (ISC_R_IGNORE);
1986 if (type == dns_rdatatype_cname ||
1987 type == dns_rdatatype_nxt ||
1988 type == dns_rdatatype_nsec ||
1989 type == dns_rdatatype_key ||
1990 !dns_nsec3_typepresent(&rdata, dns_rdatatype_cname)) {
1992 *data = dns_nsec3_typepresent(&rdata, type);
1993 (*logit)(arg, ISC_LOG_DEBUG(3),
1994 "NSEC3 proves name exists (owner) "
1996 return (ISC_R_SUCCESS);
1998 (*logit)(arg, ISC_LOG_DEBUG(3),
1999 "NSEC3 proves CNAME exists");
2000 return (ISC_R_IGNORE);
2004 dns_nsec3_typepresent(&rdata, dns_rdatatype_ns) &&
2005 !dns_nsec3_typepresent(&rdata, dns_rdatatype_soa))
2008 * This NSEC3 record is from somewhere higher in
2009 * the DNS, and at the parent of a delegation.
2010 * It can not be legitimately used here.
2012 (*logit)(arg, ISC_LOG_DEBUG(3),
2013 "ignoring parent NSEC3");
2014 return (ISC_R_IGNORE);
2018 * Potential closest encloser.
2021 if (closest != NULL &&
2022 (dns_name_countlabels(closest) == 0 ||
2023 dns_name_issubdomain(qname, closest)) &&
2024 !dns_nsec3_typepresent(&rdata, dns_rdatatype_ds) &&
2025 !dns_nsec3_typepresent(&rdata, dns_rdatatype_dname) &&
2026 (dns_nsec3_typepresent(&rdata, dns_rdatatype_soa) ||
2027 !dns_nsec3_typepresent(&rdata, dns_rdatatype_ns)))
2030 dns_name_format(qname, namebuf,
2032 (*logit)(arg, ISC_LOG_DEBUG(3),
2033 "NSEC3 indicates potential closest "
2034 "encloser: '%s'", namebuf);
2035 dns_name_copy(qname, closest, NULL);
2036 *setclosest = ISC_TRUE;
2038 dns_name_format(qname, namebuf, sizeof(namebuf));
2039 (*logit)(arg, ISC_LOG_DEBUG(3),
2040 "NSEC3 at super-domain %s", namebuf);
2045 * Find if the name does not exist.
2047 * We continue as we need to find the name closest to the
2048 * closest encloser that doesn't exist.
2050 * We also need to continue to ensure that we are not
2051 * proving the non-existence of a record in a sub-zone.
2052 * If that would be the case we will return ISC_R_IGNORE
2055 if ((scope < 0 && order > 0 &&
2056 memcmp(hash, nsec3.next, length) < 0) ||
2057 (scope >= 0 && (order > 0 ||
2058 memcmp(hash, nsec3.next, length) < 0)))
2060 char namebuf[DNS_NAME_FORMATSIZE];
2062 dns_name_format(qname, namebuf, sizeof(namebuf));
2063 (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC3 proves "
2064 "name does not exist: '%s'", namebuf);
2065 if (nearest != NULL &&
2066 (dns_name_countlabels(nearest) == 0 ||
2067 dns_name_issubdomain(nearest, qname))) {
2068 dns_name_copy(qname, nearest, NULL);
2069 *setnearest = ISC_TRUE;
2072 *exists = ISC_FALSE;
2074 if (optout != NULL) {
2075 if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0)
2076 (*logit)(arg, ISC_LOG_DEBUG(3),
2077 "NSEC3 indicates optout");
2079 (*logit)(arg, ISC_LOG_DEBUG(3),
2080 "NSEC3 indicates secure range");
2082 ISC_TF(nsec3.flags & DNS_NSEC3FLAG_OPTOUT);
2084 answer = ISC_R_SUCCESS;
2089 dns_name_split(qname, qlabels, NULL, qname);