2 * Copyright (C) 2006, 2008-2015 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>
34 #include <dns/compress.h>
35 #include <dns/dbiterator.h>
37 #include <dns/fixedname.h>
39 #include <dns/nsec3.h>
40 #include <dns/rdata.h>
41 #include <dns/rdatalist.h>
42 #include <dns/rdataset.h>
43 #include <dns/rdatasetiter.h>
44 #include <dns/rdatastruct.h>
45 #include <dns/result.h>
47 #define CHECK(x) do { \
49 if (result != ISC_R_SUCCESS) \
53 #define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0)
54 #define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0)
55 #define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0)
56 #define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
59 dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
60 dns_dbnode_t *node, unsigned int hashalg,
61 unsigned int flags, unsigned int iterations,
62 const unsigned char *salt, size_t salt_length,
63 const unsigned char *nexthash, size_t hash_length,
64 unsigned char *buffer, dns_rdata_t *rdata)
67 dns_rdataset_t rdataset;
71 isc_boolean_t found_ns;
72 isc_boolean_t need_rrsig;
74 unsigned char *nsec_bits, *bm;
75 unsigned int max_type;
76 dns_rdatasetiter_t *rdsiter;
79 REQUIRE(salt_length < 256U);
80 REQUIRE(hash_length < 256U);
81 REQUIRE(flags <= 0xffU);
82 REQUIRE(hashalg <= 0xffU);
83 REQUIRE(iterations <= 0xffffU);
87 REQUIRE(hash_length == ISC_SHA1_DIGESTLENGTH);
91 memset(buffer, 0, DNS_NSEC3_BUFFERSIZE);
98 *p++ = iterations >> 8;
101 *p++ = (unsigned char)salt_length;
102 memmove(p, salt, salt_length);
105 *p++ = (unsigned char)hash_length;
106 memmove(p, nexthash, hash_length);
109 r.length = (unsigned int)(p - buffer);
113 * Use the end of the space for a raw bitmap leaving enough
114 * space for the window identifiers and length octets.
116 bm = r.base + r.length + 512;
117 nsec_bits = r.base + r.length;
120 goto collapse_bitmap;
121 dns_rdataset_init(&rdataset);
123 result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
124 if (result != ISC_R_SUCCESS)
126 found = found_ns = need_rrsig = ISC_FALSE;
127 for (result = dns_rdatasetiter_first(rdsiter);
128 result == ISC_R_SUCCESS;
129 result = dns_rdatasetiter_next(rdsiter))
131 dns_rdatasetiter_current(rdsiter, &rdataset);
132 if (rdataset.type != dns_rdatatype_nsec &&
133 rdataset.type != dns_rdatatype_nsec3 &&
134 rdataset.type != dns_rdatatype_rrsig) {
135 if (rdataset.type > max_type)
136 max_type = rdataset.type;
137 dns_nsec_setbit(bm, rdataset.type, 1);
139 * Work out if we need to set the RRSIG bit for
140 * this node. We set the RRSIG bit if either of
141 * the following conditions are met:
142 * 1) We have a SOA or DS then we need to set
143 * the RRSIG bit as both always will be signed.
144 * 2) We set the RRSIG bit if we don't have
145 * a NS record but do have other data.
147 if (rdataset.type == dns_rdatatype_soa ||
148 rdataset.type == dns_rdatatype_ds)
149 need_rrsig = ISC_TRUE;
150 else if (rdataset.type == dns_rdatatype_ns)
155 dns_rdataset_disassociate(&rdataset);
157 if ((found && !found_ns) || need_rrsig) {
158 if (dns_rdatatype_rrsig > max_type)
159 max_type = dns_rdatatype_rrsig;
160 dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1);
164 * At zone cuts, deny the existence of glue in the parent zone.
166 if (dns_nsec_isset(bm, dns_rdatatype_ns) &&
167 ! dns_nsec_isset(bm, dns_rdatatype_soa)) {
168 for (i = 0; i <= max_type; i++) {
169 if (dns_nsec_isset(bm, i) &&
170 ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i))
171 dns_nsec_setbit(bm, i, 0);
175 dns_rdatasetiter_destroy(&rdsiter);
176 if (result != ISC_R_NOMORE)
180 nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type);
181 r.length = (unsigned int)(nsec_bits - r.base);
182 INSIST(r.length <= DNS_NSEC3_BUFFERSIZE);
183 dns_rdata_fromregion(rdata, dns_db_class(db), dns_rdatatype_nsec3, &r);
185 return (ISC_R_SUCCESS);
189 dns_nsec3_typepresent(dns_rdata_t *rdata, dns_rdatatype_t type) {
190 dns_rdata_nsec3_t nsec3;
192 isc_boolean_t present;
193 unsigned int i, len, window;
195 REQUIRE(rdata != NULL);
196 REQUIRE(rdata->type == dns_rdatatype_nsec3);
198 /* This should never fail */
199 result = dns_rdata_tostruct(rdata, &nsec3, NULL);
200 INSIST(result == ISC_R_SUCCESS);
203 for (i = 0; i < nsec3.len; i += len) {
204 INSIST(i + 2 <= nsec3.len);
205 window = nsec3.typebits[i];
206 len = nsec3.typebits[i + 1];
207 INSIST(len > 0 && len <= 32);
209 INSIST(i + len <= nsec3.len);
210 if (window * 256 > type)
212 if ((window + 1) * 256 <= type)
214 if (type < (window * 256) + len * 8)
215 present = ISC_TF(dns_nsec_isset(&nsec3.typebits[i],
219 dns_rdata_freestruct(&nsec3);
224 dns_nsec3_hashname(dns_fixedname_t *result,
225 unsigned char rethash[NSEC3_MAX_HASH_LENGTH],
226 size_t *hash_length, dns_name_t *name, dns_name_t *origin,
227 dns_hash_t hashalg, unsigned int iterations,
228 const unsigned char *salt, size_t saltlength)
230 unsigned char hash[NSEC3_MAX_HASH_LENGTH];
231 unsigned char nametext[DNS_NAME_FORMATSIZE];
232 dns_fixedname_t fixed;
233 dns_name_t *downcased;
234 isc_buffer_t namebuffer;
241 memset(rethash, 0, NSEC3_MAX_HASH_LENGTH);
243 dns_fixedname_init(&fixed);
244 downcased = dns_fixedname_name(&fixed);
245 dns_name_downcase(name, downcased, NULL);
247 /* hash the node name */
248 len = isc_iterated_hash(rethash, hashalg, iterations,
249 salt, (int)saltlength,
250 downcased->ndata, downcased->length);
252 return (DNS_R_BADALG);
254 if (hash_length != NULL)
257 /* convert the hash to base32hex non-padded */
258 region.base = rethash;
259 region.length = (unsigned int)len;
260 isc_buffer_init(&namebuffer, nametext, sizeof nametext);
261 isc_base32hexnp_totext(®ion, 1, "", &namebuffer);
263 /* convert the hex to a domain name */
264 dns_fixedname_init(result);
265 return (dns_name_fromtext(dns_fixedname_name(result), &namebuffer,
270 dns_nsec3_hashlength(dns_hash_t hash) {
274 return(ISC_SHA1_DIGESTLENGTH);
280 dns_nsec3_supportedhash(dns_hash_t hash) {
289 * Update a single RR in version 'ver' of 'db' and log the
293 * \li '*tuple' == NULL. Either the tuple is freed, or its
294 * ownership has been transferred to the diff.
297 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
300 dns_diff_t temp_diff;
304 * Create a singleton diff.
306 dns_diff_init(diff->mctx, &temp_diff);
307 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
310 * Apply it to the database.
312 result = dns_diff_apply(&temp_diff, db, ver);
313 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
314 if (result != ISC_R_SUCCESS) {
315 dns_difftuple_free(tuple);
320 * Merge it into the current pending journal entry.
322 dns_diff_appendminimal(diff, tuple);
325 * Do not clear temp_diff.
327 return (ISC_R_SUCCESS);
331 * Set '*exists' to true iff the given name exists, to false otherwise.
334 name_exists(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
335 isc_boolean_t *exists)
338 dns_dbnode_t *node = NULL;
339 dns_rdatasetiter_t *iter = NULL;
341 result = dns_db_findnode(db, name, ISC_FALSE, &node);
342 if (result == ISC_R_NOTFOUND) {
344 return (ISC_R_SUCCESS);
346 if (result != ISC_R_SUCCESS)
349 result = dns_db_allrdatasets(db, node, version,
350 (isc_stdtime_t) 0, &iter);
351 if (result != ISC_R_SUCCESS)
354 result = dns_rdatasetiter_first(iter);
355 if (result == ISC_R_SUCCESS) {
357 } else if (result == ISC_R_NOMORE) {
359 result = ISC_R_SUCCESS;
362 dns_rdatasetiter_destroy(&iter);
365 dns_db_detachnode(db, &node);
370 match_nsec3param(const dns_rdata_nsec3_t *nsec3,
371 const dns_rdata_nsec3param_t *nsec3param)
373 if (nsec3->hash == nsec3param->hash &&
374 nsec3->iterations == nsec3param->iterations &&
375 nsec3->salt_length == nsec3param->salt_length &&
376 !memcmp(nsec3->salt, nsec3param->salt, nsec3->salt_length))
382 * Delete NSEC3 records at "name" which match "param", recording the
386 delete(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
387 const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff)
389 dns_dbnode_t *node = NULL ;
390 dns_difftuple_t *tuple = NULL;
391 dns_rdata_nsec3_t nsec3;
392 dns_rdataset_t rdataset;
395 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
396 if (result == ISC_R_NOTFOUND)
397 return (ISC_R_SUCCESS);
398 if (result != ISC_R_SUCCESS)
401 dns_rdataset_init(&rdataset);
402 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, 0,
403 (isc_stdtime_t) 0, &rdataset, NULL);
405 if (result == ISC_R_NOTFOUND) {
406 result = ISC_R_SUCCESS;
409 if (result != ISC_R_SUCCESS)
412 for (result = dns_rdataset_first(&rdataset);
413 result == ISC_R_SUCCESS;
414 result = dns_rdataset_next(&rdataset))
416 dns_rdata_t rdata = DNS_RDATA_INIT;
417 dns_rdataset_current(&rdataset, &rdata);
418 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
420 if (!match_nsec3param(&nsec3, nsec3param))
423 result = dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, name,
424 rdataset.ttl, &rdata, &tuple);
425 if (result != ISC_R_SUCCESS)
427 result = do_one_tuple(&tuple, db, version, diff);
428 if (result != ISC_R_SUCCESS)
431 if (result != ISC_R_NOMORE)
433 result = ISC_R_SUCCESS;
436 dns_rdataset_disassociate(&rdataset);
438 dns_db_detachnode(db, &node);
444 better_param(dns_rdataset_t *nsec3paramset, dns_rdata_t *param) {
445 dns_rdataset_t rdataset;
448 if (REMOVE(param->data[1]))
451 dns_rdataset_init(&rdataset);
452 dns_rdataset_clone(nsec3paramset, &rdataset);
453 for (result = dns_rdataset_first(&rdataset);
454 result == ISC_R_SUCCESS;
455 result = dns_rdataset_next(&rdataset)) {
456 dns_rdata_t rdata = DNS_RDATA_INIT;
457 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
459 if (rdataset.type != dns_rdatatype_nsec3param) {
460 dns_rdata_t tmprdata = DNS_RDATA_INIT;
461 dns_rdataset_current(&rdataset, &tmprdata);
462 if (!dns_nsec3param_fromprivate(&tmprdata, &rdata,
466 dns_rdataset_current(&rdataset, &rdata);
468 if (rdata.length != param->length)
470 if (rdata.data[0] != param->data[0] ||
471 REMOVE(rdata.data[1]) ||
472 rdata.data[2] != param->data[2] ||
473 rdata.data[3] != param->data[3] ||
474 rdata.data[4] != param->data[4] ||
475 memcmp(&rdata.data[5], ¶m->data[5], param->data[4]))
477 if (CREATE(rdata.data[1]) && !CREATE(param->data[1])) {
478 dns_rdataset_disassociate(&rdataset);
482 dns_rdataset_disassociate(&rdataset);
487 find_nsec3(dns_rdata_nsec3_t *nsec3, dns_rdataset_t *rdataset,
488 const dns_rdata_nsec3param_t *nsec3param)
491 for (result = dns_rdataset_first(rdataset);
492 result == ISC_R_SUCCESS;
493 result = dns_rdataset_next(rdataset)) {
494 dns_rdata_t rdata = DNS_RDATA_INIT;
496 dns_rdataset_current(rdataset, &rdata);
497 CHECK(dns_rdata_tostruct(&rdata, nsec3, NULL));
498 dns_rdata_reset(&rdata);
499 if (match_nsec3param(nsec3, nsec3param))
507 dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version,
508 dns_name_t *name, const dns_rdata_nsec3param_t *nsec3param,
509 dns_ttl_t nsecttl, isc_boolean_t unsecure, dns_diff_t *diff)
511 dns_dbiterator_t *dbit = NULL;
512 dns_dbnode_t *node = NULL;
513 dns_dbnode_t *newnode = NULL;
514 dns_difftuple_t *tuple = NULL;
515 dns_fixedname_t fixed;
516 dns_fixedname_t fprev;
518 dns_name_t *hashname;
522 dns_rdata_nsec3_t nsec3;
523 dns_rdata_t rdata = DNS_RDATA_INIT;
524 dns_rdataset_t rdataset;
526 isc_boolean_t exists = ISC_FALSE;
527 isc_boolean_t maybe_remove_unsecure = ISC_FALSE;
531 unsigned char *old_next;
533 unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
534 unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
535 unsigned int iterations;
538 unsigned int old_length;
539 unsigned int salt_length;
541 dns_fixedname_init(&fixed);
542 hashname = dns_fixedname_name(&fixed);
543 dns_fixedname_init(&fprev);
544 prev = dns_fixedname_name(&fprev);
546 dns_rdataset_init(&rdataset);
548 origin = dns_db_origin(db);
553 hash = nsec3param->hash;
554 iterations = nsec3param->iterations;
555 salt_length = nsec3param->salt_length;
556 salt = nsec3param->salt;
559 * Default flags for a new chain.
561 flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
564 * If this is the first NSEC3 in the chain nexthash will
565 * remain pointing to itself.
567 next_length = sizeof(nexthash);
568 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
569 name, origin, hash, iterations,
571 INSIST(next_length <= sizeof(nexthash));
574 * Create the node if it doesn't exist and hold
575 * a reference to it until we have added the NSEC3.
577 CHECK(dns_db_findnsec3node(db, hashname, ISC_TRUE, &newnode));
580 * Seek the iterator to the 'newnode'.
582 CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
583 CHECK(dns_dbiterator_seek(dbit, hashname));
584 CHECK(dns_dbiterator_pause(dbit));
585 result = dns_db_findrdataset(db, newnode, version, dns_rdatatype_nsec3,
586 0, (isc_stdtime_t) 0, &rdataset, NULL);
588 * If we updating a existing NSEC3 then find its
591 if (result == ISC_R_SUCCESS) {
592 result = find_nsec3(&nsec3, &rdataset, nsec3param);
593 if (result == ISC_R_SUCCESS) {
594 if (!CREATE(nsec3param->flags))
596 next_length = nsec3.next_length;
597 INSIST(next_length <= sizeof(nexthash));
598 memmove(nexthash, nsec3.next, next_length);
599 dns_rdataset_disassociate(&rdataset);
601 * If the NSEC3 is not for a unsecure delegation then
602 * we are just updating it. If it is for a unsecure
603 * delegation then we need find out if we need to
604 * remove the NSEC3 record or not by examining the
605 * previous NSEC3 record.
609 else if (CREATE(nsec3param->flags) && OPTOUT(flags)) {
610 result = dns_nsec3_delnsec3(db, version, name,
614 maybe_remove_unsecure = ISC_TRUE;
616 dns_rdataset_disassociate(&rdataset);
617 if (result != ISC_R_NOMORE)
623 * Find the previous NSEC3 (if any) and update it if required.
627 result = dns_dbiterator_prev(dbit);
628 if (result == ISC_R_NOMORE) {
630 CHECK(dns_dbiterator_last(dbit));
632 CHECK(dns_dbiterator_current(dbit, &node, prev));
633 CHECK(dns_dbiterator_pause(dbit));
634 result = dns_db_findrdataset(db, node, version,
635 dns_rdatatype_nsec3, 0,
636 (isc_stdtime_t) 0, &rdataset,
638 dns_db_detachnode(db, &node);
639 if (result != ISC_R_SUCCESS)
642 result = find_nsec3(&nsec3, &rdataset, nsec3param);
643 if (result == ISC_R_NOMORE) {
644 dns_rdataset_disassociate(&rdataset);
647 if (result != ISC_R_SUCCESS)
650 if (maybe_remove_unsecure) {
651 dns_rdataset_disassociate(&rdataset);
653 * If we have OPTOUT set in the previous NSEC3 record
654 * we actually need to delete the NSEC3 record.
655 * Otherwise we just need to replace the NSEC3 record.
657 if (OPTOUT(nsec3.flags)) {
658 result = dns_nsec3_delnsec3(db, version, name,
665 * Is this is a unsecure delegation we are adding?
666 * If so no change is required.
668 if (OPTOUT(nsec3.flags) && unsecure) {
669 dns_rdataset_disassociate(&rdataset);
674 old_next = nsec3.next;
675 old_length = nsec3.next_length;
678 * Delete the old previous NSEC3.
680 CHECK(delete(db, version, prev, nsec3param, diff));
683 * Fixup the previous NSEC3.
685 nsec3.next = nexthash;
686 nsec3.next_length = (unsigned char)next_length;
687 isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
688 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
689 dns_rdatatype_nsec3, &nsec3,
691 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
692 rdataset.ttl, &rdata, &tuple));
693 CHECK(do_one_tuple(&tuple, db, version, diff));
694 INSIST(old_length <= sizeof(nexthash));
695 memmove(nexthash, old_next, old_length);
696 if (!CREATE(nsec3param->flags))
698 dns_rdata_reset(&rdata);
699 dns_rdataset_disassociate(&rdataset);
705 * Create the NSEC3 RDATA.
707 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
708 CHECK(dns_nsec3_buildrdata(db, version, node, hash, flags, iterations,
709 salt, salt_length, nexthash, next_length,
711 dns_db_detachnode(db, &node);
714 * Delete the old NSEC3 and record the change.
716 CHECK(delete(db, version, hashname, nsec3param, diff));
718 * Add the new NSEC3 and record the change.
720 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
721 hashname, nsecttl, &rdata, &tuple));
722 CHECK(do_one_tuple(&tuple, db, version, diff));
723 INSIST(tuple == NULL);
724 dns_rdata_reset(&rdata);
725 dns_db_detachnode(db, &newnode);
728 * Add missing NSEC3 records for empty nodes
730 dns_name_init(&empty, NULL);
731 dns_name_clone(name, &empty);
733 labels = dns_name_countlabels(&empty) - 1;
734 if (labels <= dns_name_countlabels(origin))
736 dns_name_getlabelsequence(&empty, 1, labels, &empty);
737 CHECK(name_exists(db, version, &empty, &exists));
740 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
741 &empty, origin, hash, iterations,
745 * Create the node if it doesn't exist and hold
746 * a reference to it until we have added the NSEC3
747 * or we discover we don't need to add make a change.
749 CHECK(dns_db_findnsec3node(db, hashname, ISC_TRUE, &newnode));
750 result = dns_db_findrdataset(db, newnode, version,
751 dns_rdatatype_nsec3, 0,
752 (isc_stdtime_t) 0, &rdataset,
754 if (result == ISC_R_SUCCESS) {
755 result = find_nsec3(&nsec3, &rdataset, nsec3param);
756 dns_rdataset_disassociate(&rdataset);
757 if (result == ISC_R_SUCCESS) {
758 dns_db_detachnode(db, &newnode);
761 if (result != ISC_R_NOMORE)
766 * Find the previous NSEC3 and update it.
768 CHECK(dns_dbiterator_seek(dbit, hashname));
771 result = dns_dbiterator_prev(dbit);
772 if (result == ISC_R_NOMORE) {
774 CHECK(dns_dbiterator_last(dbit));
776 CHECK(dns_dbiterator_current(dbit, &node, prev));
777 CHECK(dns_dbiterator_pause(dbit));
778 result = dns_db_findrdataset(db, node, version,
779 dns_rdatatype_nsec3, 0,
782 dns_db_detachnode(db, &node);
783 if (result != ISC_R_SUCCESS)
785 result = find_nsec3(&nsec3, &rdataset, nsec3param);
786 if (result == ISC_R_NOMORE) {
787 dns_rdataset_disassociate(&rdataset);
790 if (result != ISC_R_SUCCESS)
793 old_next = nsec3.next;
794 old_length = nsec3.next_length;
797 * Delete the old previous NSEC3.
799 CHECK(delete(db, version, prev, nsec3param, diff));
802 * Fixup the previous NSEC3.
804 nsec3.next = nexthash;
805 nsec3.next_length = (unsigned char)next_length;
806 isc_buffer_init(&buffer, nsec3buf,
808 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
809 dns_rdatatype_nsec3, &nsec3,
811 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
812 prev, rdataset.ttl, &rdata,
814 CHECK(do_one_tuple(&tuple, db, version, diff));
815 INSIST(old_length <= sizeof(nexthash));
816 memmove(nexthash, old_next, old_length);
817 if (!CREATE(nsec3param->flags))
819 dns_rdata_reset(&rdata);
820 dns_rdataset_disassociate(&rdataset);
827 * Create the NSEC3 RDATA for the empty node.
829 CHECK(dns_nsec3_buildrdata(db, version, NULL, hash, flags,
830 iterations, salt, salt_length,
831 nexthash, next_length, nsec3buf,
834 * Delete the old NSEC3 and record the change.
836 CHECK(delete(db, version, hashname, nsec3param, diff));
839 * Add the new NSEC3 and record the change.
841 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
842 hashname, nsecttl, &rdata, &tuple));
843 CHECK(do_one_tuple(&tuple, db, version, diff));
844 INSIST(tuple == NULL);
845 dns_rdata_reset(&rdata);
846 dns_db_detachnode(db, &newnode);
849 /* result cannot be ISC_R_NOMORE here */
850 INSIST(result != ISC_R_NOMORE);
854 dns_dbiterator_destroy(&dbit);
855 if (dns_rdataset_isassociated(&rdataset))
856 dns_rdataset_disassociate(&rdataset);
858 dns_db_detachnode(db, &node);
860 dns_db_detachnode(db, &newnode);
865 * Add NSEC3 records for "name", recording the change in "diff".
866 * The existing NSEC3 records are removed.
869 dns_nsec3_addnsec3s(dns_db_t *db, dns_dbversion_t *version,
870 dns_name_t *name, dns_ttl_t nsecttl,
871 isc_boolean_t unsecure, dns_diff_t *diff)
873 dns_dbnode_t *node = NULL;
874 dns_rdata_nsec3param_t nsec3param;
875 dns_rdataset_t rdataset;
878 dns_rdataset_init(&rdataset);
881 * Find the NSEC3 parameters for this zone.
883 result = dns_db_getoriginnode(db, &node);
884 if (result != ISC_R_SUCCESS)
887 result = dns_db_findrdataset(db, node, version,
888 dns_rdatatype_nsec3param, 0, 0,
890 dns_db_detachnode(db, &node);
891 if (result == ISC_R_NOTFOUND)
892 return (ISC_R_SUCCESS);
893 if (result != ISC_R_SUCCESS)
897 * Update each active NSEC3 chain.
899 for (result = dns_rdataset_first(&rdataset);
900 result == ISC_R_SUCCESS;
901 result = dns_rdataset_next(&rdataset)) {
902 dns_rdata_t rdata = DNS_RDATA_INIT;
904 dns_rdataset_current(&rdataset, &rdata);
905 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
907 if (nsec3param.flags != 0)
910 * We have a active chain. Update it.
912 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
913 nsecttl, unsecure, diff));
915 if (result == ISC_R_NOMORE)
916 result = ISC_R_SUCCESS;
919 if (dns_rdataset_isassociated(&rdataset))
920 dns_rdataset_disassociate(&rdataset);
922 dns_db_detachnode(db, &node);
928 dns_nsec3param_fromprivate(dns_rdata_t *src, dns_rdata_t *target,
929 unsigned char *buf, size_t buflen)
931 dns_decompress_t dctx;
937 * Algorithm 0 (reserved by RFC 4034) is used to identify
938 * NSEC3PARAM records from DNSKEY pointers.
940 if (src->length < 1 || src->data[0] != 0)
943 isc_buffer_init(&buf1, src->data + 1, src->length - 1);
944 isc_buffer_add(&buf1, src->length - 1);
945 isc_buffer_setactive(&buf1, src->length - 1);
946 isc_buffer_init(&buf2, buf, (unsigned int)buflen);
947 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
948 result = dns_rdata_fromwire(target, src->rdclass,
949 dns_rdatatype_nsec3param,
950 &buf1, &dctx, 0, &buf2);
951 dns_decompress_invalidate(&dctx);
953 return (ISC_TF(result == ISC_R_SUCCESS));
957 dns_nsec3param_toprivate(dns_rdata_t *src, dns_rdata_t *target,
958 dns_rdatatype_t privatetype,
959 unsigned char *buf, size_t buflen)
961 REQUIRE(buflen >= src->length + 1);
963 REQUIRE(DNS_RDATA_INITIALIZED(target));
965 memmove(buf + 1, src->data, src->length);
968 target->length = src->length + 1;
969 target->type = privatetype;
970 target->rdclass = src->rdclass;
972 ISC_LINK_INIT(target, link);
977 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
978 const dns_rdata_t *rdata, isc_boolean_t *flag)
980 dns_rdataset_t rdataset;
981 dns_dbnode_t *node = NULL;
984 dns_rdataset_init(&rdataset);
985 if (rdata->type == dns_rdatatype_nsec3)
986 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
988 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
989 result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
990 (isc_stdtime_t) 0, &rdataset, NULL);
991 if (result == ISC_R_NOTFOUND) {
993 result = ISC_R_SUCCESS;
997 for (result = dns_rdataset_first(&rdataset);
998 result == ISC_R_SUCCESS;
999 result = dns_rdataset_next(&rdataset)) {
1000 dns_rdata_t myrdata = DNS_RDATA_INIT;
1001 dns_rdataset_current(&rdataset, &myrdata);
1002 if (!dns_rdata_casecompare(&myrdata, rdata))
1005 dns_rdataset_disassociate(&rdataset);
1006 if (result == ISC_R_SUCCESS) {
1008 } else if (result == ISC_R_NOMORE) {
1010 result = ISC_R_SUCCESS;
1015 dns_db_detachnode(db, &node);
1022 dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver,
1023 dns_zone_t *zone, isc_boolean_t nonsec,
1026 dns_dbnode_t *node = NULL;
1027 dns_difftuple_t *tuple = NULL;
1029 dns_rdata_t rdata = DNS_RDATA_INIT;
1030 dns_rdataset_t rdataset;
1032 isc_result_t result = ISC_R_SUCCESS;
1033 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE + 1];
1034 dns_name_t *origin = dns_zone_getorigin(zone);
1035 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
1037 dns_name_init(&next, NULL);
1038 dns_rdataset_init(&rdataset);
1040 result = dns_db_getoriginnode(db, &node);
1041 if (result != ISC_R_SUCCESS)
1045 * Cause all NSEC3 chains to be deleted.
1047 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
1048 0, (isc_stdtime_t) 0, &rdataset, NULL);
1049 if (result == ISC_R_NOTFOUND)
1051 if (result != ISC_R_SUCCESS)
1054 for (result = dns_rdataset_first(&rdataset);
1055 result == ISC_R_SUCCESS;
1056 result = dns_rdataset_next(&rdataset)) {
1057 dns_rdata_t private = DNS_RDATA_INIT;
1059 dns_rdataset_current(&rdataset, &rdata);
1061 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
1062 rdataset.ttl, &rdata, &tuple));
1063 CHECK(do_one_tuple(&tuple, db, ver, diff));
1064 INSIST(tuple == NULL);
1066 dns_nsec3param_toprivate(&rdata, &private, privatetype,
1068 buf[2] = DNS_NSEC3FLAG_REMOVE;
1070 buf[2] |= DNS_NSEC3FLAG_NONSEC;
1072 CHECK(rr_exists(db, ver, origin, &private, &flag));
1075 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1076 origin, 0, &private,
1078 CHECK(do_one_tuple(&tuple, db, ver, diff));
1079 INSIST(tuple == NULL);
1081 dns_rdata_reset(&rdata);
1083 if (result != ISC_R_NOMORE)
1086 dns_rdataset_disassociate(&rdataset);
1089 if (privatetype == 0)
1091 result = dns_db_findrdataset(db, node, ver, privatetype, 0,
1092 (isc_stdtime_t) 0, &rdataset, NULL);
1093 if (result == ISC_R_NOTFOUND)
1095 if (result != ISC_R_SUCCESS)
1098 for (result = dns_rdataset_first(&rdataset);
1099 result == ISC_R_SUCCESS;
1100 result = dns_rdataset_next(&rdataset)) {
1101 dns_rdata_reset(&rdata);
1102 dns_rdataset_current(&rdataset, &rdata);
1103 INSIST(rdata.length <= sizeof(buf));
1104 memmove(buf, rdata.data, rdata.length);
1107 * Private NSEC3 record length >= 6.
1108 * <0(1), hash(1), flags(1), iterations(2), saltlen(1)>
1110 if (rdata.length < 6 || buf[0] != 0 ||
1111 (buf[2] & DNS_NSEC3FLAG_REMOVE) != 0 ||
1112 (nonsec && (buf[2] & DNS_NSEC3FLAG_NONSEC) != 0))
1115 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
1116 0, &rdata, &tuple));
1117 CHECK(do_one_tuple(&tuple, db, ver, diff));
1118 INSIST(tuple == NULL);
1121 buf[2] = DNS_NSEC3FLAG_REMOVE;
1123 buf[2] |= DNS_NSEC3FLAG_NONSEC;
1125 CHECK(rr_exists(db, ver, origin, &rdata, &flag));
1128 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1129 origin, 0, &rdata, &tuple));
1130 CHECK(do_one_tuple(&tuple, db, ver, diff));
1131 INSIST(tuple == NULL);
1134 if (result != ISC_R_NOMORE)
1137 result = ISC_R_SUCCESS;
1140 if (dns_rdataset_isassociated(&rdataset))
1141 dns_rdataset_disassociate(&rdataset);
1142 dns_db_detachnode(db, &node);
1148 dns_nsec3_addnsec3sx(dns_db_t *db, dns_dbversion_t *version,
1149 dns_name_t *name, dns_ttl_t nsecttl,
1150 isc_boolean_t unsecure, dns_rdatatype_t type,
1153 dns_dbnode_t *node = NULL;
1154 dns_rdata_nsec3param_t nsec3param;
1155 dns_rdataset_t rdataset;
1156 dns_rdataset_t prdataset;
1157 isc_result_t result;
1159 dns_rdataset_init(&rdataset);
1160 dns_rdataset_init(&prdataset);
1163 * Find the NSEC3 parameters for this zone.
1165 result = dns_db_getoriginnode(db, &node);
1166 if (result != ISC_R_SUCCESS)
1169 result = dns_db_findrdataset(db, node, version, type, 0, 0,
1171 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
1174 result = dns_db_findrdataset(db, node, version,
1175 dns_rdatatype_nsec3param, 0, 0,
1177 if (result == ISC_R_NOTFOUND)
1179 if (result != ISC_R_SUCCESS)
1183 * Update each active NSEC3 chain.
1185 for (result = dns_rdataset_first(&rdataset);
1186 result == ISC_R_SUCCESS;
1187 result = dns_rdataset_next(&rdataset)) {
1188 dns_rdata_t rdata = DNS_RDATA_INIT;
1190 dns_rdataset_current(&rdataset, &rdata);
1191 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
1193 if (nsec3param.flags != 0)
1197 * We have a active chain. Update it.
1199 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
1200 nsecttl, unsecure, diff));
1202 if (result != ISC_R_NOMORE)
1205 dns_rdataset_disassociate(&rdataset);
1208 if (!dns_rdataset_isassociated(&prdataset))
1211 * Update each active NSEC3 chain.
1213 for (result = dns_rdataset_first(&prdataset);
1214 result == ISC_R_SUCCESS;
1215 result = dns_rdataset_next(&prdataset)) {
1216 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1217 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1218 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1220 dns_rdataset_current(&prdataset, &rdata1);
1221 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
1224 CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
1226 if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
1228 if (better_param(&prdataset, &rdata2))
1232 * We have a active chain. Update it.
1234 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
1235 nsecttl, unsecure, diff));
1237 if (result == ISC_R_NOMORE)
1239 result = ISC_R_SUCCESS;
1241 if (dns_rdataset_isassociated(&rdataset))
1242 dns_rdataset_disassociate(&rdataset);
1243 if (dns_rdataset_isassociated(&prdataset))
1244 dns_rdataset_disassociate(&prdataset);
1246 dns_db_detachnode(db, &node);
1252 * Determine whether any NSEC3 records that were associated with
1253 * 'name' should be deleted or if they should continue to exist.
1254 * ISC_TRUE indicates they should be deleted.
1255 * ISC_FALSE indicates they should be retained.
1258 deleteit(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
1259 isc_boolean_t *yesno)
1261 isc_result_t result;
1262 dns_fixedname_t foundname;
1263 dns_fixedname_init(&foundname);
1265 result = dns_db_find(db, name, ver, dns_rdatatype_any,
1266 DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD,
1267 (isc_stdtime_t) 0, NULL,
1268 dns_fixedname_name(&foundname),
1270 if (result == DNS_R_EMPTYNAME || result == ISC_R_SUCCESS ||
1271 result == DNS_R_ZONECUT) {
1273 return (ISC_R_SUCCESS);
1275 if (result == DNS_R_GLUE || result == DNS_R_DNAME ||
1276 result == DNS_R_DELEGATION || result == DNS_R_NXDOMAIN) {
1278 return (ISC_R_SUCCESS);
1288 dns_nsec3_delnsec3(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1289 const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff)
1291 dns_dbiterator_t *dbit = NULL;
1292 dns_dbnode_t *node = NULL;
1293 dns_difftuple_t *tuple = NULL;
1294 dns_fixedname_t fixed;
1295 dns_fixedname_t fprev;
1297 dns_name_t *hashname;
1301 dns_rdata_nsec3_t nsec3;
1302 dns_rdata_t rdata = DNS_RDATA_INIT;
1303 dns_rdataset_t rdataset;
1305 isc_boolean_t yesno;
1306 isc_buffer_t buffer;
1307 isc_result_t result;
1308 unsigned char *salt;
1309 unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
1310 unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
1311 unsigned int iterations;
1312 unsigned int labels;
1314 unsigned int salt_length;
1316 dns_fixedname_init(&fixed);
1317 hashname = dns_fixedname_name(&fixed);
1318 dns_fixedname_init(&fprev);
1319 prev = dns_fixedname_name(&fprev);
1321 dns_rdataset_init(&rdataset);
1323 origin = dns_db_origin(db);
1328 hash = nsec3param->hash;
1329 iterations = nsec3param->iterations;
1330 salt_length = nsec3param->salt_length;
1331 salt = nsec3param->salt;
1334 * If this is the first NSEC3 in the chain nexthash will
1335 * remain pointing to itself.
1337 next_length = sizeof(nexthash);
1338 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
1339 name, origin, hash, iterations,
1340 salt, salt_length));
1342 CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
1344 result = dns_dbiterator_seek(dbit, hashname);
1345 if (result == ISC_R_NOTFOUND)
1347 if (result != ISC_R_SUCCESS)
1350 CHECK(dns_dbiterator_current(dbit, &node, NULL));
1351 CHECK(dns_dbiterator_pause(dbit));
1352 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3,
1353 0, (isc_stdtime_t) 0, &rdataset, NULL);
1354 dns_db_detachnode(db, &node);
1355 if (result == ISC_R_NOTFOUND)
1357 if (result != ISC_R_SUCCESS)
1361 * If we find a existing NSEC3 for this chain then save the
1364 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1365 if (result == ISC_R_SUCCESS) {
1366 next_length = nsec3.next_length;
1367 INSIST(next_length <= sizeof(nexthash));
1368 memmove(nexthash, nsec3.next, next_length);
1370 dns_rdataset_disassociate(&rdataset);
1371 if (result == ISC_R_NOMORE)
1373 if (result != ISC_R_SUCCESS)
1377 * Find the previous NSEC3 and update it.
1381 result = dns_dbiterator_prev(dbit);
1382 if (result == ISC_R_NOMORE) {
1384 CHECK(dns_dbiterator_last(dbit));
1386 CHECK(dns_dbiterator_current(dbit, &node, prev));
1387 CHECK(dns_dbiterator_pause(dbit));
1388 result = dns_db_findrdataset(db, node, version,
1389 dns_rdatatype_nsec3, 0,
1390 (isc_stdtime_t) 0, &rdataset,
1392 dns_db_detachnode(db, &node);
1393 if (result != ISC_R_SUCCESS)
1395 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1396 if (result == ISC_R_NOMORE) {
1397 dns_rdataset_disassociate(&rdataset);
1400 if (result != ISC_R_SUCCESS)
1404 * Delete the old previous NSEC3.
1406 CHECK(delete(db, version, prev, nsec3param, diff));
1409 * Fixup the previous NSEC3.
1411 nsec3.next = nexthash;
1412 nsec3.next_length = (unsigned char)next_length;
1413 if (CREATE(nsec3param->flags))
1414 nsec3.flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
1415 isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
1416 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
1417 dns_rdatatype_nsec3, &nsec3,
1419 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
1420 rdataset.ttl, &rdata, &tuple));
1421 CHECK(do_one_tuple(&tuple, db, version, diff));
1422 dns_rdata_reset(&rdata);
1423 dns_rdataset_disassociate(&rdataset);
1428 * Delete the old NSEC3 and record the change.
1430 CHECK(delete(db, version, hashname, nsec3param, diff));
1433 * Delete NSEC3 records for now non active nodes.
1435 dns_name_init(&empty, NULL);
1436 dns_name_clone(name, &empty);
1438 labels = dns_name_countlabels(&empty) - 1;
1439 if (labels <= dns_name_countlabels(origin))
1441 dns_name_getlabelsequence(&empty, 1, labels, &empty);
1442 CHECK(deleteit(db, version, &empty, &yesno));
1446 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
1447 &empty, origin, hash, iterations,
1448 salt, salt_length));
1449 result = dns_dbiterator_seek(dbit, hashname);
1450 if (result == ISC_R_NOTFOUND)
1452 if (result != ISC_R_SUCCESS)
1455 CHECK(dns_dbiterator_current(dbit, &node, NULL));
1456 CHECK(dns_dbiterator_pause(dbit));
1457 result = dns_db_findrdataset(db, node, version,
1458 dns_rdatatype_nsec3, 0,
1459 (isc_stdtime_t) 0, &rdataset,
1461 dns_db_detachnode(db, &node);
1462 if (result == ISC_R_NOTFOUND)
1464 if (result != ISC_R_SUCCESS)
1467 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1468 if (result == ISC_R_SUCCESS) {
1469 next_length = nsec3.next_length;
1470 INSIST(next_length <= sizeof(nexthash));
1471 memmove(nexthash, nsec3.next, next_length);
1473 dns_rdataset_disassociate(&rdataset);
1474 if (result == ISC_R_NOMORE)
1476 if (result != ISC_R_SUCCESS)
1481 result = dns_dbiterator_prev(dbit);
1482 if (result == ISC_R_NOMORE) {
1484 CHECK(dns_dbiterator_last(dbit));
1486 CHECK(dns_dbiterator_current(dbit, &node, prev));
1487 CHECK(dns_dbiterator_pause(dbit));
1488 result = dns_db_findrdataset(db, node, version,
1489 dns_rdatatype_nsec3, 0,
1492 dns_db_detachnode(db, &node);
1493 if (result != ISC_R_SUCCESS)
1495 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1496 if (result == ISC_R_NOMORE) {
1497 dns_rdataset_disassociate(&rdataset);
1500 if (result != ISC_R_SUCCESS)
1504 * Delete the old previous NSEC3.
1506 CHECK(delete(db, version, prev, nsec3param, diff));
1509 * Fixup the previous NSEC3.
1511 nsec3.next = nexthash;
1512 nsec3.next_length = (unsigned char)next_length;
1513 isc_buffer_init(&buffer, nsec3buf,
1515 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
1516 dns_rdatatype_nsec3, &nsec3,
1518 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1519 prev, rdataset.ttl, &rdata,
1521 CHECK(do_one_tuple(&tuple, db, version, diff));
1522 dns_rdata_reset(&rdata);
1523 dns_rdataset_disassociate(&rdataset);
1530 * Delete the old NSEC3 and record the change.
1532 CHECK(delete(db, version, hashname, nsec3param, diff));
1536 result = ISC_R_SUCCESS;
1540 dns_dbiterator_destroy(&dbit);
1541 if (dns_rdataset_isassociated(&rdataset))
1542 dns_rdataset_disassociate(&rdataset);
1544 dns_db_detachnode(db, &node);
1549 dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1552 return (dns_nsec3_delnsec3sx(db, version, name, 0, diff));
1556 dns_nsec3_delnsec3sx(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1557 dns_rdatatype_t privatetype, dns_diff_t *diff)
1559 dns_dbnode_t *node = NULL;
1560 dns_rdata_nsec3param_t nsec3param;
1561 dns_rdataset_t rdataset;
1562 isc_result_t result;
1564 dns_rdataset_init(&rdataset);
1567 * Find the NSEC3 parameters for this zone.
1569 result = dns_db_getoriginnode(db, &node);
1570 if (result != ISC_R_SUCCESS)
1573 result = dns_db_findrdataset(db, node, version,
1574 dns_rdatatype_nsec3param, 0, 0,
1576 if (result == ISC_R_NOTFOUND)
1578 if (result != ISC_R_SUCCESS)
1582 * Update each active NSEC3 chain.
1584 for (result = dns_rdataset_first(&rdataset);
1585 result == ISC_R_SUCCESS;
1586 result = dns_rdataset_next(&rdataset)) {
1587 dns_rdata_t rdata = DNS_RDATA_INIT;
1589 dns_rdataset_current(&rdataset, &rdata);
1590 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
1592 if (nsec3param.flags != 0)
1595 * We have a active chain. Update it.
1597 CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
1599 dns_rdataset_disassociate(&rdataset);
1602 if (privatetype == 0)
1604 result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
1606 if (result == ISC_R_NOTFOUND)
1608 if (result != ISC_R_SUCCESS)
1612 * Update each NSEC3 chain being built.
1614 for (result = dns_rdataset_first(&rdataset);
1615 result == ISC_R_SUCCESS;
1616 result = dns_rdataset_next(&rdataset)) {
1617 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1618 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1619 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1621 dns_rdataset_current(&rdataset, &rdata1);
1622 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
1625 CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
1627 if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
1629 if (better_param(&rdataset, &rdata2))
1633 * We have a active chain. Update it.
1635 CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
1637 if (result == ISC_R_NOMORE)
1639 result = ISC_R_SUCCESS;
1642 if (dns_rdataset_isassociated(&rdataset))
1643 dns_rdataset_disassociate(&rdataset);
1645 dns_db_detachnode(db, &node);
1651 dns_nsec3_active(dns_db_t *db, dns_dbversion_t *version,
1652 isc_boolean_t complete, isc_boolean_t *answer)
1654 return (dns_nsec3_activex(db, version, complete, 0, answer));
1658 dns_nsec3_activex(dns_db_t *db, dns_dbversion_t *version,
1659 isc_boolean_t complete, dns_rdatatype_t privatetype,
1660 isc_boolean_t *answer)
1662 dns_dbnode_t *node = NULL;
1663 dns_rdataset_t rdataset;
1664 dns_rdata_nsec3param_t nsec3param;
1665 isc_result_t result;
1667 REQUIRE(answer != NULL);
1669 dns_rdataset_init(&rdataset);
1671 result = dns_db_getoriginnode(db, &node);
1672 if (result != ISC_R_SUCCESS)
1675 result = dns_db_findrdataset(db, node, version,
1676 dns_rdatatype_nsec3param, 0, 0,
1679 if (result == ISC_R_NOTFOUND)
1682 if (result != ISC_R_SUCCESS) {
1683 dns_db_detachnode(db, &node);
1686 for (result = dns_rdataset_first(&rdataset);
1687 result == ISC_R_SUCCESS;
1688 result = dns_rdataset_next(&rdataset)) {
1689 dns_rdata_t rdata = DNS_RDATA_INIT;
1691 dns_rdataset_current(&rdataset, &rdata);
1692 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
1693 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1695 if (nsec3param.flags == 0)
1698 dns_rdataset_disassociate(&rdataset);
1699 if (result == ISC_R_SUCCESS) {
1700 dns_db_detachnode(db, &node);
1702 return (ISC_R_SUCCESS);
1704 if (result == ISC_R_NOMORE)
1705 *answer = ISC_FALSE;
1708 if (privatetype == 0 || complete) {
1709 *answer = ISC_FALSE;
1710 return (ISC_R_SUCCESS);
1712 result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
1715 dns_db_detachnode(db, &node);
1716 if (result == ISC_R_NOTFOUND) {
1717 *answer = ISC_FALSE;
1718 return (ISC_R_SUCCESS);
1720 if (result != ISC_R_SUCCESS)
1723 for (result = dns_rdataset_first(&rdataset);
1724 result == ISC_R_SUCCESS;
1725 result = dns_rdataset_next(&rdataset)) {
1726 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1727 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1728 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1730 dns_rdataset_current(&rdataset, &rdata1);
1731 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
1734 result = dns_rdata_tostruct(&rdata2, &nsec3param, NULL);
1735 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1737 if (!complete && CREATE(nsec3param.flags))
1740 dns_rdataset_disassociate(&rdataset);
1741 if (result == ISC_R_SUCCESS) {
1743 result = ISC_R_SUCCESS;
1745 if (result == ISC_R_NOMORE) {
1746 *answer = ISC_FALSE;
1747 result = ISC_R_SUCCESS;
1754 dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version,
1755 isc_mem_t *mctx, unsigned int *iterationsp)
1757 dns_dbnode_t *node = NULL;
1758 dns_rdataset_t rdataset;
1759 dst_key_t *key = NULL;
1760 isc_buffer_t buffer;
1761 isc_result_t result;
1762 unsigned int bits, minbits = 4096;
1764 result = dns_db_getoriginnode(db, &node);
1765 if (result != ISC_R_SUCCESS)
1768 dns_rdataset_init(&rdataset);
1769 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
1770 0, 0, &rdataset, NULL);
1771 dns_db_detachnode(db, &node);
1772 if (result == ISC_R_NOTFOUND) {
1774 return (ISC_R_SUCCESS);
1776 if (result != ISC_R_SUCCESS)
1779 for (result = dns_rdataset_first(&rdataset);
1780 result == ISC_R_SUCCESS;
1781 result = dns_rdataset_next(&rdataset)) {
1782 dns_rdata_t rdata = DNS_RDATA_INIT;
1784 dns_rdataset_current(&rdataset, &rdata);
1785 isc_buffer_init(&buffer, rdata.data, rdata.length);
1786 isc_buffer_add(&buffer, rdata.length);
1787 CHECK(dst_key_fromdns(dns_db_origin(db), rdataset.rdclass,
1788 &buffer, mctx, &key));
1789 bits = dst_key_size(key);
1794 if (result != ISC_R_NOMORE)
1797 if (minbits <= 1024)
1799 else if (minbits <= 2048)
1802 *iterationsp = 2500;
1803 result = ISC_R_SUCCESS;
1806 if (dns_rdataset_isassociated(&rdataset))
1807 dns_rdataset_disassociate(&rdataset);
1812 dns_nsec3_noexistnodata(dns_rdatatype_t type, dns_name_t* name,
1813 dns_name_t *nsec3name, dns_rdataset_t *nsec3set,
1814 dns_name_t *zonename, isc_boolean_t *exists,
1815 isc_boolean_t *data, isc_boolean_t *optout,
1816 isc_boolean_t *unknown, isc_boolean_t *setclosest,
1817 isc_boolean_t *setnearest, dns_name_t *closest,
1818 dns_name_t *nearest, dns_nseclog_t logit, void *arg)
1820 char namebuf[DNS_NAME_FORMATSIZE];
1821 dns_fixedname_t fzone;
1822 dns_fixedname_t qfixed;
1823 dns_label_t hashlabel;
1826 dns_rdata_nsec3_t nsec3;
1827 dns_rdata_t rdata = DNS_RDATA_INIT;
1830 isc_boolean_t atparent;
1831 isc_boolean_t first;
1834 isc_buffer_t buffer;
1835 isc_result_t answer = ISC_R_IGNORE;
1836 isc_result_t result;
1837 unsigned char hash[NSEC3_MAX_HASH_LENGTH];
1838 unsigned char owner[NSEC3_MAX_HASH_LENGTH];
1839 unsigned int length;
1840 unsigned int qlabels;
1841 unsigned int zlabels;
1843 REQUIRE((exists == NULL && data == NULL) ||
1844 (exists != NULL && data != NULL));
1845 REQUIRE(nsec3set != NULL && nsec3set->type == dns_rdatatype_nsec3);
1846 REQUIRE((setclosest == NULL && closest == NULL) ||
1847 (setclosest != NULL && closest != NULL));
1848 REQUIRE((setnearest == NULL && nearest == NULL) ||
1849 (setnearest != NULL && nearest != NULL));
1851 result = dns_rdataset_first(nsec3set);
1852 if (result != ISC_R_SUCCESS) {
1853 (*logit)(arg, ISC_LOG_DEBUG(3), "failure processing NSEC3 set");
1857 dns_rdataset_current(nsec3set, &rdata);
1859 result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
1860 if (result != ISC_R_SUCCESS)
1863 (*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant NSEC3");
1865 dns_fixedname_init(&fzone);
1866 zone = dns_fixedname_name(&fzone);
1867 zlabels = dns_name_countlabels(nsec3name);
1870 * NSEC3 records must have two or more labels to be valid.
1873 return (ISC_R_IGNORE);
1876 * Strip off the NSEC3 hash to get the zone.
1879 dns_name_split(nsec3name, zlabels, NULL, zone);
1882 * If not below the zone name we can ignore this record.
1884 if (!dns_name_issubdomain(name, zone))
1885 return (ISC_R_IGNORE);
1888 * Is this zone the same or deeper than the current zone?
1890 if (dns_name_countlabels(zonename) == 0 ||
1891 dns_name_issubdomain(zone, zonename))
1892 dns_name_copy(zone, zonename, NULL);
1894 if (!dns_name_equal(zone, zonename))
1895 return (ISC_R_IGNORE);
1898 * Are we only looking for the most enclosing zone?
1900 if (exists == NULL || data == NULL)
1901 return (ISC_R_SUCCESS);
1904 * Only set unknown once we are sure that this NSEC3 is from
1905 * the deepest covering zone.
1907 if (!dns_nsec3_supportedhash(nsec3.hash)) {
1908 if (unknown != NULL)
1909 *unknown = ISC_TRUE;
1910 return (ISC_R_IGNORE);
1914 * Recover the hash from the first label.
1916 dns_name_getlabel(nsec3name, 0, &hashlabel);
1917 isc_region_consume(&hashlabel, 1);
1918 isc_buffer_init(&buffer, owner, sizeof(owner));
1919 result = isc_base32hex_decoderegion(&hashlabel, &buffer);
1920 if (result != ISC_R_SUCCESS)
1924 * The hash lengths should match. If not ignore the record.
1926 if (isc_buffer_usedlength(&buffer) != nsec3.next_length)
1927 return (ISC_R_IGNORE);
1930 * Work out what this NSEC3 covers.
1931 * Inside (<0) or outside (>=0).
1933 scope = isc_safe_memcompare(owner, nsec3.next, nsec3.next_length);
1936 * Prepare to compute all the hashes.
1938 dns_fixedname_init(&qfixed);
1939 qname = dns_fixedname_name(&qfixed);
1940 dns_name_downcase(name, qname, NULL);
1941 qlabels = dns_name_countlabels(qname);
1944 while (qlabels >= zlabels) {
1945 length = isc_iterated_hash(hash, nsec3.hash, nsec3.iterations,
1946 nsec3.salt, nsec3.salt_length,
1947 qname->ndata, qname->length);
1949 * The computed hash length should match.
1951 if (length != nsec3.next_length) {
1952 (*logit)(arg, ISC_LOG_DEBUG(3),
1953 "ignoring NSEC bad length %u vs %u",
1954 length, nsec3.next_length);
1955 return (ISC_R_IGNORE);
1958 order = isc_safe_memcompare(hash, owner, length);
1959 if (first && order == 0) {
1961 * The hashes are the same.
1963 atparent = dns_rdatatype_atparent(type);
1964 ns = dns_nsec3_typepresent(&rdata, dns_rdatatype_ns);
1965 soa = dns_nsec3_typepresent(&rdata, dns_rdatatype_soa);
1969 * This NSEC3 record is from somewhere
1970 * higher in the DNS, and at the
1971 * parent of a delegation. It can not
1972 * be legitimately used here.
1974 (*logit)(arg, ISC_LOG_DEBUG(3),
1975 "ignoring parent NSEC3");
1976 return (ISC_R_IGNORE);
1978 } else if (atparent && ns && soa) {
1980 * This NSEC3 record is from the child.
1981 * It can not be legitimately used here.
1983 (*logit)(arg, ISC_LOG_DEBUG(3),
1984 "ignoring child NSEC3");
1985 return (ISC_R_IGNORE);
1987 if (type == dns_rdatatype_cname ||
1988 type == dns_rdatatype_nxt ||
1989 type == dns_rdatatype_nsec ||
1990 type == dns_rdatatype_key ||
1991 !dns_nsec3_typepresent(&rdata, dns_rdatatype_cname)) {
1993 *data = dns_nsec3_typepresent(&rdata, type);
1994 (*logit)(arg, ISC_LOG_DEBUG(3),
1995 "NSEC3 proves name exists (owner) "
1997 return (ISC_R_SUCCESS);
1999 (*logit)(arg, ISC_LOG_DEBUG(3),
2000 "NSEC3 proves CNAME exists");
2001 return (ISC_R_IGNORE);
2005 dns_nsec3_typepresent(&rdata, dns_rdatatype_ns) &&
2006 !dns_nsec3_typepresent(&rdata, dns_rdatatype_soa))
2009 * This NSEC3 record is from somewhere higher in
2010 * the DNS, and at the parent of a delegation.
2011 * It can not be legitimately used here.
2013 (*logit)(arg, ISC_LOG_DEBUG(3),
2014 "ignoring parent NSEC3");
2015 return (ISC_R_IGNORE);
2019 * Potential closest encloser.
2022 if (closest != NULL &&
2023 (dns_name_countlabels(closest) == 0 ||
2024 dns_name_issubdomain(qname, closest)) &&
2025 !dns_nsec3_typepresent(&rdata, dns_rdatatype_ds) &&
2026 !dns_nsec3_typepresent(&rdata, dns_rdatatype_dname) &&
2027 (dns_nsec3_typepresent(&rdata, dns_rdatatype_soa) ||
2028 !dns_nsec3_typepresent(&rdata, dns_rdatatype_ns)))
2031 dns_name_format(qname, namebuf,
2033 (*logit)(arg, ISC_LOG_DEBUG(3),
2034 "NSEC3 indicates potential closest "
2035 "encloser: '%s'", namebuf);
2036 dns_name_copy(qname, closest, NULL);
2037 *setclosest = ISC_TRUE;
2039 dns_name_format(qname, namebuf, sizeof(namebuf));
2040 (*logit)(arg, ISC_LOG_DEBUG(3),
2041 "NSEC3 at super-domain %s", namebuf);
2046 * Find if the name does not exist.
2048 * We continue as we need to find the name closest to the
2049 * closest encloser that doesn't exist.
2051 * We also need to continue to ensure that we are not
2052 * proving the non-existence of a record in a sub-zone.
2053 * If that would be the case we will return ISC_R_IGNORE
2056 if ((scope < 0 && order > 0 &&
2057 memcmp(hash, nsec3.next, length) < 0) ||
2058 (scope >= 0 && (order > 0 ||
2059 memcmp(hash, nsec3.next, length) < 0)))
2061 dns_name_format(qname, namebuf, sizeof(namebuf));
2062 (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC3 proves "
2063 "name does not exist: '%s'", namebuf);
2064 if (nearest != NULL &&
2065 (dns_name_countlabels(nearest) == 0 ||
2066 dns_name_issubdomain(nearest, qname))) {
2067 dns_name_copy(qname, nearest, NULL);
2068 *setnearest = ISC_TRUE;
2071 *exists = ISC_FALSE;
2073 if (optout != NULL) {
2074 if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0)
2075 (*logit)(arg, ISC_LOG_DEBUG(3),
2076 "NSEC3 indicates optout");
2078 (*logit)(arg, ISC_LOG_DEBUG(3),
2079 "NSEC3 indicates secure range");
2081 ISC_TF(nsec3.flags & DNS_NSEC3FLAG_OPTOUT);
2083 answer = ISC_R_SUCCESS;
2088 dns_name_split(qname, qlabels, NULL, qname);