1 /* $NetBSD: nsec3.c,v 1.11 2015/07/08 17:28:58 christos Exp $ */
4 * Copyright (C) 2006, 2008-2015 Internet Systems Consortium, Inc. ("ISC")
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
23 #include <isc/base32.h>
24 #include <isc/buffer.h>
26 #include <isc/iterated_hash.h>
28 #include <isc/string.h>
35 #include <dns/compress.h>
36 #include <dns/dbiterator.h>
38 #include <dns/fixedname.h>
40 #include <dns/nsec3.h>
41 #include <dns/rdata.h>
42 #include <dns/rdatalist.h>
43 #include <dns/rdataset.h>
44 #include <dns/rdatasetiter.h>
45 #include <dns/rdatastruct.h>
46 #include <dns/result.h>
48 #define CHECK(x) do { \
50 if (result != ISC_R_SUCCESS) \
52 } while (/*CONSTCOND*/0)
54 #define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0)
55 #define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0)
56 #define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0)
57 #define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
60 dns_nsec3_buildrdata(dns_db_t
*db
, dns_dbversion_t
*version
,
61 dns_dbnode_t
*node
, unsigned int hashalg
,
62 unsigned int flags
, unsigned int iterations
,
63 const unsigned char *salt
, size_t salt_length
,
64 const unsigned char *nexthash
, size_t hash_length
,
65 unsigned char *buffer
, dns_rdata_t
*rdata
)
68 dns_rdataset_t rdataset
;
72 isc_boolean_t found_ns
;
73 isc_boolean_t need_rrsig
;
75 unsigned char *nsec_bits
, *bm
;
76 unsigned int max_type
;
77 dns_rdatasetiter_t
*rdsiter
;
80 REQUIRE(salt_length
< 256U);
81 REQUIRE(hash_length
< 256U);
82 REQUIRE(flags
<= 0xffU
);
83 REQUIRE(hashalg
<= 0xffU
);
84 REQUIRE(iterations
<= 0xffffU
);
88 REQUIRE(hash_length
== ISC_SHA1_DIGESTLENGTH
);
92 memset(buffer
, 0, DNS_NSEC3_BUFFERSIZE
);
99 *p
++ = iterations
>> 8;
102 *p
++ = (unsigned char)salt_length
;
103 memmove(p
, salt
, salt_length
);
106 *p
++ = (unsigned char)hash_length
;
107 memmove(p
, nexthash
, hash_length
);
110 r
.length
= (unsigned int)(p
- buffer
);
114 * Use the end of the space for a raw bitmap leaving enough
115 * space for the window identifiers and length octets.
117 bm
= r
.base
+ r
.length
+ 512;
118 nsec_bits
= r
.base
+ r
.length
;
121 goto collapse_bitmap
;
122 dns_rdataset_init(&rdataset
);
124 result
= dns_db_allrdatasets(db
, node
, version
, 0, &rdsiter
);
125 if (result
!= ISC_R_SUCCESS
)
127 found
= found_ns
= need_rrsig
= ISC_FALSE
;
128 for (result
= dns_rdatasetiter_first(rdsiter
);
129 result
== ISC_R_SUCCESS
;
130 result
= dns_rdatasetiter_next(rdsiter
))
132 dns_rdatasetiter_current(rdsiter
, &rdataset
);
133 if (rdataset
.type
!= dns_rdatatype_nsec
&&
134 rdataset
.type
!= dns_rdatatype_nsec3
&&
135 rdataset
.type
!= dns_rdatatype_rrsig
) {
136 if (rdataset
.type
> max_type
)
137 max_type
= rdataset
.type
;
138 dns_nsec_setbit(bm
, rdataset
.type
, 1);
140 * Work out if we need to set the RRSIG bit for
141 * this node. We set the RRSIG bit if either of
142 * the following conditions are met:
143 * 1) We have a SOA or DS then we need to set
144 * the RRSIG bit as both always will be signed.
145 * 2) We set the RRSIG bit if we don't have
146 * a NS record but do have other data.
148 if (rdataset
.type
== dns_rdatatype_soa
||
149 rdataset
.type
== dns_rdatatype_ds
)
150 need_rrsig
= ISC_TRUE
;
151 else if (rdataset
.type
== dns_rdatatype_ns
)
156 dns_rdataset_disassociate(&rdataset
);
158 if ((found
&& !found_ns
) || need_rrsig
) {
159 if (dns_rdatatype_rrsig
> max_type
)
160 max_type
= dns_rdatatype_rrsig
;
161 dns_nsec_setbit(bm
, dns_rdatatype_rrsig
, 1);
165 * At zone cuts, deny the existence of glue in the parent zone.
167 if (dns_nsec_isset(bm
, dns_rdatatype_ns
) &&
168 ! dns_nsec_isset(bm
, dns_rdatatype_soa
)) {
169 for (i
= 0; i
<= max_type
; i
++) {
170 if (dns_nsec_isset(bm
, i
) &&
171 ! dns_rdatatype_iszonecutauth((dns_rdatatype_t
)i
))
172 dns_nsec_setbit(bm
, i
, 0);
176 dns_rdatasetiter_destroy(&rdsiter
);
177 if (result
!= ISC_R_NOMORE
)
181 nsec_bits
+= dns_nsec_compressbitmap(nsec_bits
, bm
, max_type
);
182 r
.length
= (unsigned int)(nsec_bits
- r
.base
);
183 INSIST(r
.length
<= DNS_NSEC3_BUFFERSIZE
);
184 dns_rdata_fromregion(rdata
, dns_db_class(db
), dns_rdatatype_nsec3
, &r
);
186 return (ISC_R_SUCCESS
);
190 dns_nsec3_typepresent(dns_rdata_t
*rdata
, dns_rdatatype_t type
) {
191 dns_rdata_nsec3_t nsec3
;
193 isc_boolean_t present
;
194 unsigned int i
, len
, window
;
196 REQUIRE(rdata
!= NULL
);
197 REQUIRE(rdata
->type
== dns_rdatatype_nsec3
);
199 /* This should never fail */
200 result
= dns_rdata_tostruct(rdata
, &nsec3
, NULL
);
201 INSIST(result
== ISC_R_SUCCESS
);
204 for (i
= 0; i
< nsec3
.len
; i
+= len
) {
205 INSIST(i
+ 2 <= nsec3
.len
);
206 window
= nsec3
.typebits
[i
];
207 len
= nsec3
.typebits
[i
+ 1];
208 INSIST(len
> 0 && len
<= 32);
210 INSIST(i
+ len
<= nsec3
.len
);
211 if (window
* 256 > type
)
213 if ((window
+ 1) * 256 <= type
)
215 if (type
< (window
* 256) + len
* 8)
216 present
= ISC_TF(dns_nsec_isset(&nsec3
.typebits
[i
],
220 dns_rdata_freestruct(&nsec3
);
225 dns_nsec3_hashname(dns_fixedname_t
*result
,
226 unsigned char rethash
[NSEC3_MAX_HASH_LENGTH
],
227 size_t *hash_length
, dns_name_t
*name
, dns_name_t
*origin
,
228 dns_hash_t hashalg
, unsigned int iterations
,
229 const unsigned char *salt
, size_t saltlength
)
231 unsigned char hash
[NSEC3_MAX_HASH_LENGTH
];
232 unsigned char nametext
[DNS_NAME_FORMATSIZE
];
233 dns_fixedname_t fixed
;
234 dns_name_t
*downcased
;
235 isc_buffer_t namebuffer
;
242 memset(rethash
, 0, NSEC3_MAX_HASH_LENGTH
);
244 dns_fixedname_init(&fixed
);
245 downcased
= dns_fixedname_name(&fixed
);
246 dns_name_downcase(name
, downcased
, NULL
);
248 /* hash the node name */
249 len
= isc_iterated_hash(rethash
, hashalg
, iterations
,
250 salt
, (int)saltlength
,
251 downcased
->ndata
, downcased
->length
);
253 return (DNS_R_BADALG
);
255 if (hash_length
!= NULL
)
258 /* convert the hash to base32hex non-padded */
259 region
.base
= rethash
;
260 region
.length
= (unsigned int)len
;
261 isc_buffer_init(&namebuffer
, nametext
, sizeof nametext
);
262 isc_base32hexnp_totext(®ion
, 1, "", &namebuffer
);
264 /* convert the hex to a domain name */
265 dns_fixedname_init(result
);
266 return (dns_name_fromtext(dns_fixedname_name(result
), &namebuffer
,
271 dns_nsec3_hashlength(dns_hash_t hash
) {
275 return(ISC_SHA1_DIGESTLENGTH
);
281 dns_nsec3_supportedhash(dns_hash_t hash
) {
290 * Update a single RR in version 'ver' of 'db' and log the
294 * \li '*tuple' == NULL. Either the tuple is freed, or its
295 * ownership has been transferred to the diff.
298 do_one_tuple(dns_difftuple_t
**tuple
, dns_db_t
*db
, dns_dbversion_t
*ver
,
301 dns_diff_t temp_diff
;
305 * Create a singleton diff.
307 dns_diff_init(diff
->mctx
, &temp_diff
);
308 ISC_LIST_APPEND(temp_diff
.tuples
, *tuple
, link
);
311 * Apply it to the database.
313 result
= dns_diff_apply(&temp_diff
, db
, ver
);
314 ISC_LIST_UNLINK(temp_diff
.tuples
, *tuple
, link
);
315 if (result
!= ISC_R_SUCCESS
) {
316 dns_difftuple_free(tuple
);
321 * Merge it into the current pending journal entry.
323 dns_diff_appendminimal(diff
, tuple
);
326 * Do not clear temp_diff.
328 return (ISC_R_SUCCESS
);
332 * Set '*exists' to true iff the given name exists, to false otherwise.
335 name_exists(dns_db_t
*db
, dns_dbversion_t
*version
, dns_name_t
*name
,
336 isc_boolean_t
*exists
)
339 dns_dbnode_t
*node
= NULL
;
340 dns_rdatasetiter_t
*iter
= NULL
;
342 result
= dns_db_findnode(db
, name
, ISC_FALSE
, &node
);
343 if (result
== ISC_R_NOTFOUND
) {
345 return (ISC_R_SUCCESS
);
347 if (result
!= ISC_R_SUCCESS
)
350 result
= dns_db_allrdatasets(db
, node
, version
,
351 (isc_stdtime_t
) 0, &iter
);
352 if (result
!= ISC_R_SUCCESS
)
355 result
= dns_rdatasetiter_first(iter
);
356 if (result
== ISC_R_SUCCESS
) {
358 } else if (result
== ISC_R_NOMORE
) {
360 result
= ISC_R_SUCCESS
;
363 dns_rdatasetiter_destroy(&iter
);
366 dns_db_detachnode(db
, &node
);
371 match_nsec3param(const dns_rdata_nsec3_t
*nsec3
,
372 const dns_rdata_nsec3param_t
*nsec3param
)
374 if (nsec3
->hash
== nsec3param
->hash
&&
375 nsec3
->iterations
== nsec3param
->iterations
&&
376 nsec3
->salt_length
== nsec3param
->salt_length
&&
377 !memcmp(nsec3
->salt
, nsec3param
->salt
, nsec3
->salt_length
))
383 * Delete NSEC3 records at "name" which match "param", recording the
387 delete(dns_db_t
*db
, dns_dbversion_t
*version
, dns_name_t
*name
,
388 const dns_rdata_nsec3param_t
*nsec3param
, dns_diff_t
*diff
)
390 dns_dbnode_t
*node
= NULL
;
391 dns_difftuple_t
*tuple
= NULL
;
392 dns_rdata_nsec3_t nsec3
;
393 dns_rdataset_t rdataset
;
396 result
= dns_db_findnsec3node(db
, name
, ISC_FALSE
, &node
);
397 if (result
== ISC_R_NOTFOUND
)
398 return (ISC_R_SUCCESS
);
399 if (result
!= ISC_R_SUCCESS
)
402 dns_rdataset_init(&rdataset
);
403 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_nsec3
, 0,
404 (isc_stdtime_t
) 0, &rdataset
, NULL
);
406 if (result
== ISC_R_NOTFOUND
) {
407 result
= ISC_R_SUCCESS
;
410 if (result
!= ISC_R_SUCCESS
)
413 for (result
= dns_rdataset_first(&rdataset
);
414 result
== ISC_R_SUCCESS
;
415 result
= dns_rdataset_next(&rdataset
))
417 dns_rdata_t rdata
= DNS_RDATA_INIT
;
418 dns_rdataset_current(&rdataset
, &rdata
);
419 CHECK(dns_rdata_tostruct(&rdata
, &nsec3
, NULL
));
421 if (!match_nsec3param(&nsec3
, nsec3param
))
424 result
= dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_DEL
, name
,
425 rdataset
.ttl
, &rdata
, &tuple
);
426 if (result
!= ISC_R_SUCCESS
)
428 result
= do_one_tuple(&tuple
, db
, version
, diff
);
429 if (result
!= ISC_R_SUCCESS
)
432 if (result
!= ISC_R_NOMORE
)
434 result
= ISC_R_SUCCESS
;
437 dns_rdataset_disassociate(&rdataset
);
439 dns_db_detachnode(db
, &node
);
445 better_param(dns_rdataset_t
*nsec3paramset
, dns_rdata_t
*param
) {
446 dns_rdataset_t rdataset
;
449 if (REMOVE(param
->data
[1]))
452 dns_rdataset_init(&rdataset
);
453 dns_rdataset_clone(nsec3paramset
, &rdataset
);
454 for (result
= dns_rdataset_first(&rdataset
);
455 result
== ISC_R_SUCCESS
;
456 result
= dns_rdataset_next(&rdataset
)) {
457 dns_rdata_t rdata
= DNS_RDATA_INIT
;
458 unsigned char buf
[DNS_NSEC3PARAM_BUFFERSIZE
];
460 if (rdataset
.type
!= dns_rdatatype_nsec3param
) {
461 dns_rdata_t tmprdata
= DNS_RDATA_INIT
;
462 dns_rdataset_current(&rdataset
, &tmprdata
);
463 if (!dns_nsec3param_fromprivate(&tmprdata
, &rdata
,
467 dns_rdataset_current(&rdataset
, &rdata
);
469 if (rdata
.length
!= param
->length
)
471 if (rdata
.data
[0] != param
->data
[0] ||
472 REMOVE(rdata
.data
[1]) ||
473 rdata
.data
[2] != param
->data
[2] ||
474 rdata
.data
[3] != param
->data
[3] ||
475 rdata
.data
[4] != param
->data
[4] ||
476 memcmp(&rdata
.data
[5], ¶m
->data
[5], param
->data
[4]))
478 if (CREATE(rdata
.data
[1]) && !CREATE(param
->data
[1])) {
479 dns_rdataset_disassociate(&rdataset
);
483 dns_rdataset_disassociate(&rdataset
);
488 find_nsec3(dns_rdata_nsec3_t
*nsec3
, dns_rdataset_t
*rdataset
,
489 const dns_rdata_nsec3param_t
*nsec3param
)
492 for (result
= dns_rdataset_first(rdataset
);
493 result
== ISC_R_SUCCESS
;
494 result
= dns_rdataset_next(rdataset
)) {
495 dns_rdata_t rdata
= DNS_RDATA_INIT
;
497 dns_rdataset_current(rdataset
, &rdata
);
498 CHECK(dns_rdata_tostruct(&rdata
, nsec3
, NULL
));
499 dns_rdata_reset(&rdata
);
500 if (match_nsec3param(nsec3
, nsec3param
))
508 dns_nsec3_addnsec3(dns_db_t
*db
, dns_dbversion_t
*version
,
509 dns_name_t
*name
, const dns_rdata_nsec3param_t
*nsec3param
,
510 dns_ttl_t nsecttl
, isc_boolean_t unsecure
, dns_diff_t
*diff
)
512 dns_dbiterator_t
*dbit
= NULL
;
513 dns_dbnode_t
*node
= NULL
;
514 dns_dbnode_t
*newnode
= NULL
;
515 dns_difftuple_t
*tuple
= NULL
;
516 dns_fixedname_t fixed
;
517 dns_fixedname_t fprev
;
519 dns_name_t
*hashname
;
523 dns_rdata_nsec3_t nsec3
;
524 dns_rdata_t rdata
= DNS_RDATA_INIT
;
525 dns_rdataset_t rdataset
;
527 isc_boolean_t exists
= ISC_FALSE
;
528 isc_boolean_t maybe_remove_unsecure
= ISC_FALSE
;
532 unsigned char *old_next
;
534 unsigned char nexthash
[NSEC3_MAX_HASH_LENGTH
];
535 unsigned char nsec3buf
[DNS_NSEC3_BUFFERSIZE
];
536 unsigned int iterations
;
539 unsigned int old_length
;
540 unsigned int salt_length
;
542 dns_fixedname_init(&fixed
);
543 hashname
= dns_fixedname_name(&fixed
);
544 dns_fixedname_init(&fprev
);
545 prev
= dns_fixedname_name(&fprev
);
547 dns_rdataset_init(&rdataset
);
549 origin
= dns_db_origin(db
);
554 hash
= nsec3param
->hash
;
555 iterations
= nsec3param
->iterations
;
556 salt_length
= nsec3param
->salt_length
;
557 salt
= nsec3param
->salt
;
560 * Default flags for a new chain.
562 flags
= nsec3param
->flags
& DNS_NSEC3FLAG_OPTOUT
;
565 * If this is the first NSEC3 in the chain nexthash will
566 * remain pointing to itself.
568 next_length
= sizeof(nexthash
);
569 CHECK(dns_nsec3_hashname(&fixed
, nexthash
, &next_length
,
570 name
, origin
, hash
, iterations
,
572 INSIST(next_length
<= sizeof(nexthash
));
575 * Create the node if it doesn't exist and hold
576 * a reference to it until we have added the NSEC3.
578 CHECK(dns_db_findnsec3node(db
, hashname
, ISC_TRUE
, &newnode
));
581 * Seek the iterator to the 'newnode'.
583 CHECK(dns_db_createiterator(db
, DNS_DB_NSEC3ONLY
, &dbit
));
584 CHECK(dns_dbiterator_seek(dbit
, hashname
));
585 CHECK(dns_dbiterator_pause(dbit
));
586 result
= dns_db_findrdataset(db
, newnode
, version
, dns_rdatatype_nsec3
,
587 0, (isc_stdtime_t
) 0, &rdataset
, NULL
);
589 * If we updating a existing NSEC3 then find its
592 if (result
== ISC_R_SUCCESS
) {
593 result
= find_nsec3(&nsec3
, &rdataset
, nsec3param
);
594 if (result
== ISC_R_SUCCESS
) {
595 if (!CREATE(nsec3param
->flags
))
597 next_length
= nsec3
.next_length
;
598 INSIST(next_length
<= sizeof(nexthash
));
599 memmove(nexthash
, nsec3
.next
, next_length
);
600 dns_rdataset_disassociate(&rdataset
);
602 * If the NSEC3 is not for a unsecure delegation then
603 * we are just updating it. If it is for a unsecure
604 * delegation then we need find out if we need to
605 * remove the NSEC3 record or not by examining the
606 * previous NSEC3 record.
610 else if (CREATE(nsec3param
->flags
) && OPTOUT(flags
)) {
611 result
= dns_nsec3_delnsec3(db
, version
, name
,
615 maybe_remove_unsecure
= ISC_TRUE
;
617 dns_rdataset_disassociate(&rdataset
);
618 if (result
!= ISC_R_NOMORE
)
624 * Find the previous NSEC3 (if any) and update it if required.
628 result
= dns_dbiterator_prev(dbit
);
629 if (result
== ISC_R_NOMORE
) {
631 CHECK(dns_dbiterator_last(dbit
));
633 CHECK(dns_dbiterator_current(dbit
, &node
, prev
));
634 CHECK(dns_dbiterator_pause(dbit
));
635 result
= dns_db_findrdataset(db
, node
, version
,
636 dns_rdatatype_nsec3
, 0,
637 (isc_stdtime_t
) 0, &rdataset
,
639 dns_db_detachnode(db
, &node
);
640 if (result
!= ISC_R_SUCCESS
)
643 result
= find_nsec3(&nsec3
, &rdataset
, nsec3param
);
644 if (result
== ISC_R_NOMORE
) {
645 dns_rdataset_disassociate(&rdataset
);
648 if (result
!= ISC_R_SUCCESS
)
651 if (maybe_remove_unsecure
) {
652 dns_rdataset_disassociate(&rdataset
);
654 * If we have OPTOUT set in the previous NSEC3 record
655 * we actually need to delete the NSEC3 record.
656 * Otherwise we just need to replace the NSEC3 record.
658 if (OPTOUT(nsec3
.flags
)) {
659 result
= dns_nsec3_delnsec3(db
, version
, name
,
666 * Is this is a unsecure delegation we are adding?
667 * If so no change is required.
669 if (OPTOUT(nsec3
.flags
) && unsecure
) {
670 dns_rdataset_disassociate(&rdataset
);
675 old_next
= nsec3
.next
;
676 old_length
= nsec3
.next_length
;
679 * Delete the old previous NSEC3.
681 CHECK(delete(db
, version
, prev
, nsec3param
, diff
));
684 * Fixup the previous NSEC3.
686 nsec3
.next
= nexthash
;
687 nsec3
.next_length
= (unsigned char)next_length
;
688 isc_buffer_init(&buffer
, nsec3buf
, sizeof(nsec3buf
));
689 CHECK(dns_rdata_fromstruct(&rdata
, rdataset
.rdclass
,
690 dns_rdatatype_nsec3
, &nsec3
,
692 CHECK(dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_ADD
, prev
,
693 rdataset
.ttl
, &rdata
, &tuple
));
694 CHECK(do_one_tuple(&tuple
, db
, version
, diff
));
695 INSIST(old_length
<= sizeof(nexthash
));
696 memmove(nexthash
, old_next
, old_length
);
697 if (!CREATE(nsec3param
->flags
))
699 dns_rdata_reset(&rdata
);
700 dns_rdataset_disassociate(&rdataset
);
706 * Create the NSEC3 RDATA.
708 CHECK(dns_db_findnode(db
, name
, ISC_FALSE
, &node
));
709 CHECK(dns_nsec3_buildrdata(db
, version
, node
, hash
, flags
, iterations
,
710 salt
, salt_length
, nexthash
, next_length
,
712 dns_db_detachnode(db
, &node
);
715 * Delete the old NSEC3 and record the change.
717 CHECK(delete(db
, version
, hashname
, nsec3param
, diff
));
719 * Add the new NSEC3 and record the change.
721 CHECK(dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_ADD
,
722 hashname
, nsecttl
, &rdata
, &tuple
));
723 CHECK(do_one_tuple(&tuple
, db
, version
, diff
));
724 INSIST(tuple
== NULL
);
725 dns_rdata_reset(&rdata
);
726 dns_db_detachnode(db
, &newnode
);
729 * Add missing NSEC3 records for empty nodes
731 dns_name_init(&empty
, NULL
);
732 dns_name_clone(name
, &empty
);
734 labels
= dns_name_countlabels(&empty
) - 1;
735 if (labels
<= dns_name_countlabels(origin
))
737 dns_name_getlabelsequence(&empty
, 1, labels
, &empty
);
738 CHECK(name_exists(db
, version
, &empty
, &exists
));
741 CHECK(dns_nsec3_hashname(&fixed
, nexthash
, &next_length
,
742 &empty
, origin
, hash
, iterations
,
746 * Create the node if it doesn't exist and hold
747 * a reference to it until we have added the NSEC3
748 * or we discover we don't need to add make a change.
750 CHECK(dns_db_findnsec3node(db
, hashname
, ISC_TRUE
, &newnode
));
751 result
= dns_db_findrdataset(db
, newnode
, version
,
752 dns_rdatatype_nsec3
, 0,
753 (isc_stdtime_t
) 0, &rdataset
,
755 if (result
== ISC_R_SUCCESS
) {
756 result
= find_nsec3(&nsec3
, &rdataset
, nsec3param
);
757 dns_rdataset_disassociate(&rdataset
);
758 if (result
== ISC_R_SUCCESS
) {
759 dns_db_detachnode(db
, &newnode
);
762 if (result
!= ISC_R_NOMORE
)
767 * Find the previous NSEC3 and update it.
769 CHECK(dns_dbiterator_seek(dbit
, hashname
));
772 result
= dns_dbiterator_prev(dbit
);
773 if (result
== ISC_R_NOMORE
) {
775 CHECK(dns_dbiterator_last(dbit
));
777 CHECK(dns_dbiterator_current(dbit
, &node
, prev
));
778 CHECK(dns_dbiterator_pause(dbit
));
779 result
= dns_db_findrdataset(db
, node
, version
,
780 dns_rdatatype_nsec3
, 0,
783 dns_db_detachnode(db
, &node
);
784 if (result
!= ISC_R_SUCCESS
)
786 result
= find_nsec3(&nsec3
, &rdataset
, nsec3param
);
787 if (result
== ISC_R_NOMORE
) {
788 dns_rdataset_disassociate(&rdataset
);
791 if (result
!= ISC_R_SUCCESS
)
794 old_next
= nsec3
.next
;
795 old_length
= nsec3
.next_length
;
798 * Delete the old previous NSEC3.
800 CHECK(delete(db
, version
, prev
, nsec3param
, diff
));
803 * Fixup the previous NSEC3.
805 nsec3
.next
= nexthash
;
806 nsec3
.next_length
= (unsigned char)next_length
;
807 isc_buffer_init(&buffer
, nsec3buf
,
809 CHECK(dns_rdata_fromstruct(&rdata
, rdataset
.rdclass
,
810 dns_rdatatype_nsec3
, &nsec3
,
812 CHECK(dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_ADD
,
813 prev
, rdataset
.ttl
, &rdata
,
815 CHECK(do_one_tuple(&tuple
, db
, version
, diff
));
816 INSIST(old_length
<= sizeof(nexthash
));
817 memmove(nexthash
, old_next
, old_length
);
818 if (!CREATE(nsec3param
->flags
))
820 dns_rdata_reset(&rdata
);
821 dns_rdataset_disassociate(&rdataset
);
828 * Create the NSEC3 RDATA for the empty node.
830 CHECK(dns_nsec3_buildrdata(db
, version
, NULL
, hash
, flags
,
831 iterations
, salt
, salt_length
,
832 nexthash
, next_length
, nsec3buf
,
835 * Delete the old NSEC3 and record the change.
837 CHECK(delete(db
, version
, hashname
, nsec3param
, diff
));
840 * Add the new NSEC3 and record the change.
842 CHECK(dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_ADD
,
843 hashname
, nsecttl
, &rdata
, &tuple
));
844 CHECK(do_one_tuple(&tuple
, db
, version
, diff
));
845 INSIST(tuple
== NULL
);
846 dns_rdata_reset(&rdata
);
847 dns_db_detachnode(db
, &newnode
);
850 /* result cannot be ISC_R_NOMORE here */
851 INSIST(result
!= ISC_R_NOMORE
);
855 dns_dbiterator_destroy(&dbit
);
856 if (dns_rdataset_isassociated(&rdataset
))
857 dns_rdataset_disassociate(&rdataset
);
859 dns_db_detachnode(db
, &node
);
861 dns_db_detachnode(db
, &newnode
);
866 * Add NSEC3 records for "name", recording the change in "diff".
867 * The existing NSEC3 records are removed.
870 dns_nsec3_addnsec3s(dns_db_t
*db
, dns_dbversion_t
*version
,
871 dns_name_t
*name
, dns_ttl_t nsecttl
,
872 isc_boolean_t unsecure
, dns_diff_t
*diff
)
874 dns_dbnode_t
*node
= NULL
;
875 dns_rdata_nsec3param_t nsec3param
;
876 dns_rdataset_t rdataset
;
879 dns_rdataset_init(&rdataset
);
882 * Find the NSEC3 parameters for this zone.
884 result
= dns_db_getoriginnode(db
, &node
);
885 if (result
!= ISC_R_SUCCESS
)
888 result
= dns_db_findrdataset(db
, node
, version
,
889 dns_rdatatype_nsec3param
, 0, 0,
891 dns_db_detachnode(db
, &node
);
892 if (result
== ISC_R_NOTFOUND
)
893 return (ISC_R_SUCCESS
);
894 if (result
!= ISC_R_SUCCESS
)
898 * Update each active NSEC3 chain.
900 for (result
= dns_rdataset_first(&rdataset
);
901 result
== ISC_R_SUCCESS
;
902 result
= dns_rdataset_next(&rdataset
)) {
903 dns_rdata_t rdata
= DNS_RDATA_INIT
;
905 dns_rdataset_current(&rdataset
, &rdata
);
906 CHECK(dns_rdata_tostruct(&rdata
, &nsec3param
, NULL
));
908 if (nsec3param
.flags
!= 0)
911 * We have a active chain. Update it.
913 CHECK(dns_nsec3_addnsec3(db
, version
, name
, &nsec3param
,
914 nsecttl
, unsecure
, diff
));
916 if (result
== ISC_R_NOMORE
)
917 result
= ISC_R_SUCCESS
;
920 if (dns_rdataset_isassociated(&rdataset
))
921 dns_rdataset_disassociate(&rdataset
);
923 dns_db_detachnode(db
, &node
);
929 dns_nsec3param_fromprivate(dns_rdata_t
*src
, dns_rdata_t
*target
,
930 unsigned char *buf
, size_t buflen
)
932 dns_decompress_t dctx
;
938 * Algorithm 0 (reserved by RFC 4034) is used to identify
939 * NSEC3PARAM records from DNSKEY pointers.
941 if (src
->length
< 1 || src
->data
[0] != 0)
944 isc_buffer_init(&buf1
, src
->data
+ 1, src
->length
- 1);
945 isc_buffer_add(&buf1
, src
->length
- 1);
946 isc_buffer_setactive(&buf1
, src
->length
- 1);
947 isc_buffer_init(&buf2
, buf
, (unsigned int)buflen
);
948 dns_decompress_init(&dctx
, -1, DNS_DECOMPRESS_NONE
);
949 result
= dns_rdata_fromwire(target
, src
->rdclass
,
950 dns_rdatatype_nsec3param
,
951 &buf1
, &dctx
, 0, &buf2
);
952 dns_decompress_invalidate(&dctx
);
954 return (ISC_TF(result
== ISC_R_SUCCESS
));
958 dns_nsec3param_toprivate(dns_rdata_t
*src
, dns_rdata_t
*target
,
959 dns_rdatatype_t privatetype
,
960 unsigned char *buf
, size_t buflen
)
962 REQUIRE(buflen
>= src
->length
+ 1);
964 REQUIRE(DNS_RDATA_INITIALIZED(target
));
966 memmove(buf
+ 1, src
->data
, src
->length
);
969 target
->length
= src
->length
+ 1;
970 target
->type
= privatetype
;
971 target
->rdclass
= src
->rdclass
;
973 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
);
1020 dns_nsec3param_deletechains(dns_db_t
*db
, dns_dbversion_t
*ver
,
1021 dns_zone_t
*zone
, isc_boolean_t nonsec
,
1024 dns_dbnode_t
*node
= NULL
;
1025 dns_difftuple_t
*tuple
= NULL
;
1027 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1028 dns_rdataset_t rdataset
;
1030 isc_result_t result
= ISC_R_SUCCESS
;
1031 unsigned char buf
[DNS_NSEC3PARAM_BUFFERSIZE
+ 1];
1032 dns_name_t
*origin
= dns_zone_getorigin(zone
);
1033 dns_rdatatype_t privatetype
= dns_zone_getprivatetype(zone
);
1035 dns_name_init(&next
, NULL
);
1036 dns_rdataset_init(&rdataset
);
1038 result
= dns_db_getoriginnode(db
, &node
);
1039 if (result
!= ISC_R_SUCCESS
)
1043 * Cause all NSEC3 chains to be deleted.
1045 result
= dns_db_findrdataset(db
, node
, ver
, dns_rdatatype_nsec3param
,
1046 0, (isc_stdtime_t
) 0, &rdataset
, NULL
);
1047 if (result
== ISC_R_NOTFOUND
)
1049 if (result
!= ISC_R_SUCCESS
)
1052 for (result
= dns_rdataset_first(&rdataset
);
1053 result
== ISC_R_SUCCESS
;
1054 result
= dns_rdataset_next(&rdataset
)) {
1055 dns_rdata_t
private = DNS_RDATA_INIT
;
1057 dns_rdataset_current(&rdataset
, &rdata
);
1059 CHECK(dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_DEL
, origin
,
1060 rdataset
.ttl
, &rdata
, &tuple
));
1061 CHECK(do_one_tuple(&tuple
, db
, ver
, diff
));
1062 INSIST(tuple
== NULL
);
1064 dns_nsec3param_toprivate(&rdata
, &private, privatetype
,
1066 buf
[2] = DNS_NSEC3FLAG_REMOVE
;
1068 buf
[2] |= DNS_NSEC3FLAG_NONSEC
;
1070 CHECK(rr_exists(db
, ver
, origin
, &private, &flag
));
1073 CHECK(dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_ADD
,
1074 origin
, 0, &private,
1076 CHECK(do_one_tuple(&tuple
, db
, ver
, diff
));
1077 INSIST(tuple
== NULL
);
1079 dns_rdata_reset(&rdata
);
1081 if (result
!= ISC_R_NOMORE
)
1084 dns_rdataset_disassociate(&rdataset
);
1087 if (privatetype
== 0)
1089 result
= dns_db_findrdataset(db
, node
, ver
, privatetype
, 0,
1090 (isc_stdtime_t
) 0, &rdataset
, NULL
);
1091 if (result
== ISC_R_NOTFOUND
)
1093 if (result
!= ISC_R_SUCCESS
)
1096 for (result
= dns_rdataset_first(&rdataset
);
1097 result
== ISC_R_SUCCESS
;
1098 result
= dns_rdataset_next(&rdataset
)) {
1099 dns_rdata_reset(&rdata
);
1100 dns_rdataset_current(&rdataset
, &rdata
);
1101 INSIST(rdata
.length
<= sizeof(buf
));
1102 memmove(buf
, rdata
.data
, rdata
.length
);
1105 * Private NSEC3 record length >= 6.
1106 * <0(1), hash(1), flags(1), iterations(2), saltlen(1)>
1108 if (rdata
.length
< 6 || buf
[0] != 0 ||
1109 (buf
[2] & DNS_NSEC3FLAG_REMOVE
) != 0 ||
1110 (nonsec
&& (buf
[2] & DNS_NSEC3FLAG_NONSEC
) != 0))
1113 CHECK(dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_DEL
, origin
,
1114 0, &rdata
, &tuple
));
1115 CHECK(do_one_tuple(&tuple
, db
, ver
, diff
));
1116 INSIST(tuple
== NULL
);
1119 buf
[2] = DNS_NSEC3FLAG_REMOVE
;
1121 buf
[2] |= DNS_NSEC3FLAG_NONSEC
;
1123 CHECK(rr_exists(db
, ver
, origin
, &rdata
, &flag
));
1126 CHECK(dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_ADD
,
1127 origin
, 0, &rdata
, &tuple
));
1128 CHECK(do_one_tuple(&tuple
, db
, ver
, diff
));
1129 INSIST(tuple
== NULL
);
1132 if (result
!= ISC_R_NOMORE
)
1135 result
= ISC_R_SUCCESS
;
1138 if (dns_rdataset_isassociated(&rdataset
))
1139 dns_rdataset_disassociate(&rdataset
);
1140 dns_db_detachnode(db
, &node
);
1145 dns_nsec3_addnsec3sx(dns_db_t
*db
, dns_dbversion_t
*version
,
1146 dns_name_t
*name
, dns_ttl_t nsecttl
,
1147 isc_boolean_t unsecure
, dns_rdatatype_t type
,
1150 dns_dbnode_t
*node
= NULL
;
1151 dns_rdata_nsec3param_t nsec3param
;
1152 dns_rdataset_t rdataset
;
1153 dns_rdataset_t prdataset
;
1154 isc_result_t result
;
1156 dns_rdataset_init(&rdataset
);
1157 dns_rdataset_init(&prdataset
);
1160 * Find the NSEC3 parameters for this zone.
1162 result
= dns_db_getoriginnode(db
, &node
);
1163 if (result
!= ISC_R_SUCCESS
)
1166 result
= dns_db_findrdataset(db
, node
, version
, type
, 0, 0,
1168 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
)
1171 result
= dns_db_findrdataset(db
, node
, version
,
1172 dns_rdatatype_nsec3param
, 0, 0,
1174 if (result
== ISC_R_NOTFOUND
)
1176 if (result
!= ISC_R_SUCCESS
)
1180 * Update each active NSEC3 chain.
1182 for (result
= dns_rdataset_first(&rdataset
);
1183 result
== ISC_R_SUCCESS
;
1184 result
= dns_rdataset_next(&rdataset
)) {
1185 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1187 dns_rdataset_current(&rdataset
, &rdata
);
1188 CHECK(dns_rdata_tostruct(&rdata
, &nsec3param
, NULL
));
1190 if (nsec3param
.flags
!= 0)
1194 * We have a active chain. Update it.
1196 CHECK(dns_nsec3_addnsec3(db
, version
, name
, &nsec3param
,
1197 nsecttl
, unsecure
, diff
));
1199 if (result
!= ISC_R_NOMORE
)
1202 dns_rdataset_disassociate(&rdataset
);
1205 if (!dns_rdataset_isassociated(&prdataset
))
1208 * Update each active NSEC3 chain.
1210 for (result
= dns_rdataset_first(&prdataset
);
1211 result
== ISC_R_SUCCESS
;
1212 result
= dns_rdataset_next(&prdataset
)) {
1213 dns_rdata_t rdata1
= DNS_RDATA_INIT
;
1214 dns_rdata_t rdata2
= DNS_RDATA_INIT
;
1215 unsigned char buf
[DNS_NSEC3PARAM_BUFFERSIZE
];
1217 dns_rdataset_current(&prdataset
, &rdata1
);
1218 if (!dns_nsec3param_fromprivate(&rdata1
, &rdata2
,
1221 CHECK(dns_rdata_tostruct(&rdata2
, &nsec3param
, NULL
));
1223 if ((nsec3param
.flags
& DNS_NSEC3FLAG_REMOVE
) != 0)
1225 if (better_param(&prdataset
, &rdata2
))
1229 * We have a active chain. Update it.
1231 CHECK(dns_nsec3_addnsec3(db
, version
, name
, &nsec3param
,
1232 nsecttl
, unsecure
, diff
));
1234 if (result
== ISC_R_NOMORE
)
1236 result
= ISC_R_SUCCESS
;
1238 if (dns_rdataset_isassociated(&rdataset
))
1239 dns_rdataset_disassociate(&rdataset
);
1240 if (dns_rdataset_isassociated(&prdataset
))
1241 dns_rdataset_disassociate(&prdataset
);
1243 dns_db_detachnode(db
, &node
);
1249 * Determine whether any NSEC3 records that were associated with
1250 * 'name' should be deleted or if they should continue to exist.
1251 * ISC_TRUE indicates they should be deleted.
1252 * ISC_FALSE indicates they should be retained.
1255 deleteit(dns_db_t
*db
, dns_dbversion_t
*ver
, dns_name_t
*name
,
1256 isc_boolean_t
*yesno
)
1258 isc_result_t result
;
1259 dns_fixedname_t foundname
;
1260 dns_fixedname_init(&foundname
);
1262 result
= dns_db_find(db
, name
, ver
, dns_rdatatype_any
,
1263 DNS_DBFIND_GLUEOK
| DNS_DBFIND_NOWILD
,
1264 (isc_stdtime_t
) 0, NULL
,
1265 dns_fixedname_name(&foundname
),
1267 if (result
== DNS_R_EMPTYNAME
|| result
== ISC_R_SUCCESS
||
1268 result
== DNS_R_ZONECUT
) {
1270 return (ISC_R_SUCCESS
);
1272 if (result
== DNS_R_GLUE
|| result
== DNS_R_DNAME
||
1273 result
== DNS_R_DELEGATION
|| result
== DNS_R_NXDOMAIN
) {
1275 return (ISC_R_SUCCESS
);
1285 dns_nsec3_delnsec3(dns_db_t
*db
, dns_dbversion_t
*version
, dns_name_t
*name
,
1286 const dns_rdata_nsec3param_t
*nsec3param
, dns_diff_t
*diff
)
1288 dns_dbiterator_t
*dbit
= NULL
;
1289 dns_dbnode_t
*node
= NULL
;
1290 dns_difftuple_t
*tuple
= NULL
;
1291 dns_fixedname_t fixed
;
1292 dns_fixedname_t fprev
;
1294 dns_name_t
*hashname
;
1298 dns_rdata_nsec3_t nsec3
;
1299 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1300 dns_rdataset_t rdataset
;
1302 isc_boolean_t yesno
;
1303 isc_buffer_t buffer
;
1304 isc_result_t result
;
1305 unsigned char *salt
;
1306 unsigned char nexthash
[NSEC3_MAX_HASH_LENGTH
];
1307 unsigned char nsec3buf
[DNS_NSEC3_BUFFERSIZE
];
1308 unsigned int iterations
;
1309 unsigned int labels
;
1311 unsigned int salt_length
;
1313 dns_fixedname_init(&fixed
);
1314 hashname
= dns_fixedname_name(&fixed
);
1315 dns_fixedname_init(&fprev
);
1316 prev
= dns_fixedname_name(&fprev
);
1318 dns_rdataset_init(&rdataset
);
1320 origin
= dns_db_origin(db
);
1325 hash
= nsec3param
->hash
;
1326 iterations
= nsec3param
->iterations
;
1327 salt_length
= nsec3param
->salt_length
;
1328 salt
= nsec3param
->salt
;
1331 * If this is the first NSEC3 in the chain nexthash will
1332 * remain pointing to itself.
1334 next_length
= sizeof(nexthash
);
1335 CHECK(dns_nsec3_hashname(&fixed
, nexthash
, &next_length
,
1336 name
, origin
, hash
, iterations
,
1337 salt
, salt_length
));
1339 CHECK(dns_db_createiterator(db
, DNS_DB_NSEC3ONLY
, &dbit
));
1341 result
= dns_dbiterator_seek(dbit
, hashname
);
1342 if (result
== ISC_R_NOTFOUND
)
1344 if (result
!= ISC_R_SUCCESS
)
1347 CHECK(dns_dbiterator_current(dbit
, &node
, NULL
));
1348 CHECK(dns_dbiterator_pause(dbit
));
1349 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_nsec3
,
1350 0, (isc_stdtime_t
) 0, &rdataset
, NULL
);
1351 dns_db_detachnode(db
, &node
);
1352 if (result
== ISC_R_NOTFOUND
)
1354 if (result
!= ISC_R_SUCCESS
)
1358 * If we find a existing NSEC3 for this chain then save the
1361 result
= find_nsec3(&nsec3
, &rdataset
, nsec3param
);
1362 if (result
== ISC_R_SUCCESS
) {
1363 next_length
= nsec3
.next_length
;
1364 INSIST(next_length
<= sizeof(nexthash
));
1365 memmove(nexthash
, nsec3
.next
, next_length
);
1367 dns_rdataset_disassociate(&rdataset
);
1368 if (result
== ISC_R_NOMORE
)
1370 if (result
!= ISC_R_SUCCESS
)
1374 * Find the previous NSEC3 and update it.
1378 result
= dns_dbiterator_prev(dbit
);
1379 if (result
== ISC_R_NOMORE
) {
1381 CHECK(dns_dbiterator_last(dbit
));
1383 CHECK(dns_dbiterator_current(dbit
, &node
, prev
));
1384 CHECK(dns_dbiterator_pause(dbit
));
1385 result
= dns_db_findrdataset(db
, node
, version
,
1386 dns_rdatatype_nsec3
, 0,
1387 (isc_stdtime_t
) 0, &rdataset
,
1389 dns_db_detachnode(db
, &node
);
1390 if (result
!= ISC_R_SUCCESS
)
1392 result
= find_nsec3(&nsec3
, &rdataset
, nsec3param
);
1393 if (result
== ISC_R_NOMORE
) {
1394 dns_rdataset_disassociate(&rdataset
);
1397 if (result
!= ISC_R_SUCCESS
)
1401 * Delete the old previous NSEC3.
1403 CHECK(delete(db
, version
, prev
, nsec3param
, diff
));
1406 * Fixup the previous NSEC3.
1408 nsec3
.next
= nexthash
;
1409 nsec3
.next_length
= (unsigned char)next_length
;
1410 if (CREATE(nsec3param
->flags
))
1411 nsec3
.flags
= nsec3param
->flags
& DNS_NSEC3FLAG_OPTOUT
;
1412 isc_buffer_init(&buffer
, nsec3buf
, sizeof(nsec3buf
));
1413 CHECK(dns_rdata_fromstruct(&rdata
, rdataset
.rdclass
,
1414 dns_rdatatype_nsec3
, &nsec3
,
1416 CHECK(dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_ADD
, prev
,
1417 rdataset
.ttl
, &rdata
, &tuple
));
1418 CHECK(do_one_tuple(&tuple
, db
, version
, diff
));
1419 dns_rdata_reset(&rdata
);
1420 dns_rdataset_disassociate(&rdataset
);
1425 * Delete the old NSEC3 and record the change.
1427 CHECK(delete(db
, version
, hashname
, nsec3param
, diff
));
1430 * Delete NSEC3 records for now non active nodes.
1432 dns_name_init(&empty
, NULL
);
1433 dns_name_clone(name
, &empty
);
1435 labels
= dns_name_countlabels(&empty
) - 1;
1436 if (labels
<= dns_name_countlabels(origin
))
1438 dns_name_getlabelsequence(&empty
, 1, labels
, &empty
);
1439 CHECK(deleteit(db
, version
, &empty
, &yesno
));
1443 CHECK(dns_nsec3_hashname(&fixed
, nexthash
, &next_length
,
1444 &empty
, origin
, hash
, iterations
,
1445 salt
, salt_length
));
1446 result
= dns_dbiterator_seek(dbit
, hashname
);
1447 if (result
== ISC_R_NOTFOUND
)
1449 if (result
!= ISC_R_SUCCESS
)
1452 CHECK(dns_dbiterator_current(dbit
, &node
, NULL
));
1453 CHECK(dns_dbiterator_pause(dbit
));
1454 result
= dns_db_findrdataset(db
, node
, version
,
1455 dns_rdatatype_nsec3
, 0,
1456 (isc_stdtime_t
) 0, &rdataset
,
1458 dns_db_detachnode(db
, &node
);
1459 if (result
== ISC_R_NOTFOUND
)
1461 if (result
!= ISC_R_SUCCESS
)
1464 result
= find_nsec3(&nsec3
, &rdataset
, nsec3param
);
1465 if (result
== ISC_R_SUCCESS
) {
1466 next_length
= nsec3
.next_length
;
1467 INSIST(next_length
<= sizeof(nexthash
));
1468 memmove(nexthash
, nsec3
.next
, next_length
);
1470 dns_rdataset_disassociate(&rdataset
);
1471 if (result
== ISC_R_NOMORE
)
1473 if (result
!= ISC_R_SUCCESS
)
1478 result
= dns_dbiterator_prev(dbit
);
1479 if (result
== ISC_R_NOMORE
) {
1481 CHECK(dns_dbiterator_last(dbit
));
1483 CHECK(dns_dbiterator_current(dbit
, &node
, prev
));
1484 CHECK(dns_dbiterator_pause(dbit
));
1485 result
= dns_db_findrdataset(db
, node
, version
,
1486 dns_rdatatype_nsec3
, 0,
1489 dns_db_detachnode(db
, &node
);
1490 if (result
!= ISC_R_SUCCESS
)
1492 result
= find_nsec3(&nsec3
, &rdataset
, nsec3param
);
1493 if (result
== ISC_R_NOMORE
) {
1494 dns_rdataset_disassociate(&rdataset
);
1497 if (result
!= ISC_R_SUCCESS
)
1501 * Delete the old previous NSEC3.
1503 CHECK(delete(db
, version
, prev
, nsec3param
, diff
));
1506 * Fixup the previous NSEC3.
1508 nsec3
.next
= nexthash
;
1509 nsec3
.next_length
= (unsigned char)next_length
;
1510 isc_buffer_init(&buffer
, nsec3buf
,
1512 CHECK(dns_rdata_fromstruct(&rdata
, rdataset
.rdclass
,
1513 dns_rdatatype_nsec3
, &nsec3
,
1515 CHECK(dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_ADD
,
1516 prev
, rdataset
.ttl
, &rdata
,
1518 CHECK(do_one_tuple(&tuple
, db
, version
, diff
));
1519 dns_rdata_reset(&rdata
);
1520 dns_rdataset_disassociate(&rdataset
);
1527 * Delete the old NSEC3 and record the change.
1529 CHECK(delete(db
, version
, hashname
, nsec3param
, diff
));
1533 result
= ISC_R_SUCCESS
;
1537 dns_dbiterator_destroy(&dbit
);
1538 if (dns_rdataset_isassociated(&rdataset
))
1539 dns_rdataset_disassociate(&rdataset
);
1541 dns_db_detachnode(db
, &node
);
1546 dns_nsec3_delnsec3s(dns_db_t
*db
, dns_dbversion_t
*version
, dns_name_t
*name
,
1549 return (dns_nsec3_delnsec3sx(db
, version
, name
, 0, diff
));
1553 dns_nsec3_delnsec3sx(dns_db_t
*db
, dns_dbversion_t
*version
, dns_name_t
*name
,
1554 dns_rdatatype_t privatetype
, dns_diff_t
*diff
)
1556 dns_dbnode_t
*node
= NULL
;
1557 dns_rdata_nsec3param_t nsec3param
;
1558 dns_rdataset_t rdataset
;
1559 isc_result_t result
;
1561 dns_rdataset_init(&rdataset
);
1564 * Find the NSEC3 parameters for this zone.
1566 result
= dns_db_getoriginnode(db
, &node
);
1567 if (result
!= ISC_R_SUCCESS
)
1570 result
= dns_db_findrdataset(db
, node
, version
,
1571 dns_rdatatype_nsec3param
, 0, 0,
1573 if (result
== ISC_R_NOTFOUND
)
1575 if (result
!= ISC_R_SUCCESS
)
1579 * Update each active NSEC3 chain.
1581 for (result
= dns_rdataset_first(&rdataset
);
1582 result
== ISC_R_SUCCESS
;
1583 result
= dns_rdataset_next(&rdataset
)) {
1584 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1586 dns_rdataset_current(&rdataset
, &rdata
);
1587 CHECK(dns_rdata_tostruct(&rdata
, &nsec3param
, NULL
));
1589 if (nsec3param
.flags
!= 0)
1592 * We have a active chain. Update it.
1594 CHECK(dns_nsec3_delnsec3(db
, version
, name
, &nsec3param
, diff
));
1596 dns_rdataset_disassociate(&rdataset
);
1599 if (privatetype
== 0)
1601 result
= dns_db_findrdataset(db
, node
, version
, privatetype
, 0, 0,
1603 if (result
== ISC_R_NOTFOUND
)
1605 if (result
!= ISC_R_SUCCESS
)
1609 * Update each NSEC3 chain being built.
1611 for (result
= dns_rdataset_first(&rdataset
);
1612 result
== ISC_R_SUCCESS
;
1613 result
= dns_rdataset_next(&rdataset
)) {
1614 dns_rdata_t rdata1
= DNS_RDATA_INIT
;
1615 dns_rdata_t rdata2
= DNS_RDATA_INIT
;
1616 unsigned char buf
[DNS_NSEC3PARAM_BUFFERSIZE
];
1618 dns_rdataset_current(&rdataset
, &rdata1
);
1619 if (!dns_nsec3param_fromprivate(&rdata1
, &rdata2
,
1622 CHECK(dns_rdata_tostruct(&rdata2
, &nsec3param
, NULL
));
1624 if ((nsec3param
.flags
& DNS_NSEC3FLAG_REMOVE
) != 0)
1626 if (better_param(&rdataset
, &rdata2
))
1630 * We have a active chain. Update it.
1632 CHECK(dns_nsec3_delnsec3(db
, version
, name
, &nsec3param
, diff
));
1634 if (result
== ISC_R_NOMORE
)
1636 result
= ISC_R_SUCCESS
;
1639 if (dns_rdataset_isassociated(&rdataset
))
1640 dns_rdataset_disassociate(&rdataset
);
1642 dns_db_detachnode(db
, &node
);
1648 dns_nsec3_active(dns_db_t
*db
, dns_dbversion_t
*version
,
1649 isc_boolean_t complete
, isc_boolean_t
*answer
)
1651 return (dns_nsec3_activex(db
, version
, complete
, 0, answer
));
1655 dns_nsec3_activex(dns_db_t
*db
, dns_dbversion_t
*version
,
1656 isc_boolean_t complete
, dns_rdatatype_t privatetype
,
1657 isc_boolean_t
*answer
)
1659 dns_dbnode_t
*node
= NULL
;
1660 dns_rdataset_t rdataset
;
1661 dns_rdata_nsec3param_t nsec3param
;
1662 isc_result_t result
;
1664 REQUIRE(answer
!= NULL
);
1666 dns_rdataset_init(&rdataset
);
1668 result
= dns_db_getoriginnode(db
, &node
);
1669 if (result
!= ISC_R_SUCCESS
)
1672 result
= dns_db_findrdataset(db
, node
, version
,
1673 dns_rdatatype_nsec3param
, 0, 0,
1676 if (result
== ISC_R_NOTFOUND
)
1679 if (result
!= ISC_R_SUCCESS
) {
1680 dns_db_detachnode(db
, &node
);
1683 for (result
= dns_rdataset_first(&rdataset
);
1684 result
== ISC_R_SUCCESS
;
1685 result
= dns_rdataset_next(&rdataset
)) {
1686 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1688 dns_rdataset_current(&rdataset
, &rdata
);
1689 result
= dns_rdata_tostruct(&rdata
, &nsec3param
, NULL
);
1690 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
1692 if (nsec3param
.flags
== 0)
1695 dns_rdataset_disassociate(&rdataset
);
1696 if (result
== ISC_R_SUCCESS
) {
1697 dns_db_detachnode(db
, &node
);
1699 return (ISC_R_SUCCESS
);
1701 if (result
== ISC_R_NOMORE
)
1702 *answer
= ISC_FALSE
;
1705 if (privatetype
== 0 || complete
) {
1706 *answer
= ISC_FALSE
;
1707 return (ISC_R_SUCCESS
);
1709 result
= dns_db_findrdataset(db
, node
, version
, privatetype
, 0, 0,
1712 dns_db_detachnode(db
, &node
);
1713 if (result
== ISC_R_NOTFOUND
) {
1714 *answer
= ISC_FALSE
;
1715 return (ISC_R_SUCCESS
);
1717 if (result
!= ISC_R_SUCCESS
)
1720 for (result
= dns_rdataset_first(&rdataset
);
1721 result
== ISC_R_SUCCESS
;
1722 result
= dns_rdataset_next(&rdataset
)) {
1723 dns_rdata_t rdata1
= DNS_RDATA_INIT
;
1724 dns_rdata_t rdata2
= DNS_RDATA_INIT
;
1725 unsigned char buf
[DNS_NSEC3PARAM_BUFFERSIZE
];
1727 dns_rdataset_current(&rdataset
, &rdata1
);
1728 if (!dns_nsec3param_fromprivate(&rdata1
, &rdata2
,
1731 result
= dns_rdata_tostruct(&rdata2
, &nsec3param
, NULL
);
1732 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
1734 if (!complete
&& CREATE(nsec3param
.flags
))
1737 dns_rdataset_disassociate(&rdataset
);
1738 if (result
== ISC_R_SUCCESS
) {
1740 result
= ISC_R_SUCCESS
;
1742 if (result
== ISC_R_NOMORE
) {
1743 *answer
= ISC_FALSE
;
1744 result
= ISC_R_SUCCESS
;
1751 dns_nsec3_maxiterations(dns_db_t
*db
, dns_dbversion_t
*version
,
1752 isc_mem_t
*mctx
, unsigned int *iterationsp
)
1754 dns_dbnode_t
*node
= NULL
;
1755 dns_rdataset_t rdataset
;
1756 dst_key_t
*key
= NULL
;
1757 isc_buffer_t buffer
;
1758 isc_result_t result
;
1759 unsigned int bits
, minbits
= 4096;
1761 result
= dns_db_getoriginnode(db
, &node
);
1762 if (result
!= ISC_R_SUCCESS
)
1765 dns_rdataset_init(&rdataset
);
1766 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_dnskey
,
1767 0, 0, &rdataset
, NULL
);
1768 dns_db_detachnode(db
, &node
);
1769 if (result
== ISC_R_NOTFOUND
) {
1771 return (ISC_R_SUCCESS
);
1773 if (result
!= ISC_R_SUCCESS
)
1776 for (result
= dns_rdataset_first(&rdataset
);
1777 result
== ISC_R_SUCCESS
;
1778 result
= dns_rdataset_next(&rdataset
)) {
1779 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1781 dns_rdataset_current(&rdataset
, &rdata
);
1782 isc_buffer_init(&buffer
, rdata
.data
, rdata
.length
);
1783 isc_buffer_add(&buffer
, rdata
.length
);
1784 CHECK(dst_key_fromdns(dns_db_origin(db
), rdataset
.rdclass
,
1785 &buffer
, mctx
, &key
));
1786 bits
= dst_key_size(key
);
1791 if (result
!= ISC_R_NOMORE
)
1794 if (minbits
<= 1024)
1796 else if (minbits
<= 2048)
1799 *iterationsp
= 2500;
1800 result
= ISC_R_SUCCESS
;
1803 if (dns_rdataset_isassociated(&rdataset
))
1804 dns_rdataset_disassociate(&rdataset
);
1809 dns_nsec3_noexistnodata(dns_rdatatype_t type
, dns_name_t
* name
,
1810 dns_name_t
*nsec3name
, dns_rdataset_t
*nsec3set
,
1811 dns_name_t
*zonename
, isc_boolean_t
*exists
,
1812 isc_boolean_t
*data
, isc_boolean_t
*optout
,
1813 isc_boolean_t
*unknown
, isc_boolean_t
*setclosest
,
1814 isc_boolean_t
*setnearest
, dns_name_t
*closest
,
1815 dns_name_t
*nearest
, dns_nseclog_t logit
, void *arg
)
1817 char namebuf
[DNS_NAME_FORMATSIZE
];
1818 dns_fixedname_t fzone
;
1819 dns_fixedname_t qfixed
;
1820 dns_label_t hashlabel
;
1823 dns_rdata_nsec3_t nsec3
;
1824 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1827 isc_boolean_t atparent
;
1828 isc_boolean_t first
;
1831 isc_buffer_t buffer
;
1832 isc_result_t answer
= ISC_R_IGNORE
;
1833 isc_result_t result
;
1834 unsigned char hash
[NSEC3_MAX_HASH_LENGTH
];
1835 unsigned char owner
[NSEC3_MAX_HASH_LENGTH
];
1836 unsigned int length
;
1837 unsigned int qlabels
;
1838 unsigned int zlabels
;
1840 REQUIRE((exists
== NULL
&& data
== NULL
) ||
1841 (exists
!= NULL
&& data
!= NULL
));
1842 REQUIRE(nsec3set
!= NULL
&& nsec3set
->type
== dns_rdatatype_nsec3
);
1843 REQUIRE((setclosest
== NULL
&& closest
== NULL
) ||
1844 (setclosest
!= NULL
&& closest
!= NULL
));
1845 REQUIRE((setnearest
== NULL
&& nearest
== NULL
) ||
1846 (setnearest
!= NULL
&& nearest
!= NULL
));
1848 result
= dns_rdataset_first(nsec3set
);
1849 if (result
!= ISC_R_SUCCESS
) {
1850 (*logit
)(arg
, ISC_LOG_DEBUG(3), "failure processing NSEC3 set");
1854 dns_rdataset_current(nsec3set
, &rdata
);
1856 result
= dns_rdata_tostruct(&rdata
, &nsec3
, NULL
);
1857 if (result
!= ISC_R_SUCCESS
)
1860 (*logit
)(arg
, ISC_LOG_DEBUG(3), "looking for relevant NSEC3");
1862 dns_fixedname_init(&fzone
);
1863 zone
= dns_fixedname_name(&fzone
);
1864 zlabels
= dns_name_countlabels(nsec3name
);
1867 * NSEC3 records must have two or more labels to be valid.
1870 return (ISC_R_IGNORE
);
1873 * Strip off the NSEC3 hash to get the zone.
1876 dns_name_split(nsec3name
, zlabels
, NULL
, zone
);
1879 * If not below the zone name we can ignore this record.
1881 if (!dns_name_issubdomain(name
, zone
))
1882 return (ISC_R_IGNORE
);
1885 * Is this zone the same or deeper than the current zone?
1887 if (dns_name_countlabels(zonename
) == 0 ||
1888 dns_name_issubdomain(zone
, zonename
))
1889 dns_name_copy(zone
, zonename
, NULL
);
1891 if (!dns_name_equal(zone
, zonename
))
1892 return (ISC_R_IGNORE
);
1895 * Are we only looking for the most enclosing zone?
1897 if (exists
== NULL
|| data
== NULL
)
1898 return (ISC_R_SUCCESS
);
1901 * Only set unknown once we are sure that this NSEC3 is from
1902 * the deepest covering zone.
1904 if (!dns_nsec3_supportedhash(nsec3
.hash
)) {
1905 if (unknown
!= NULL
)
1906 *unknown
= ISC_TRUE
;
1907 return (ISC_R_IGNORE
);
1911 * Recover the hash from the first label.
1913 dns_name_getlabel(nsec3name
, 0, &hashlabel
);
1914 isc_region_consume(&hashlabel
, 1);
1915 isc_buffer_init(&buffer
, owner
, sizeof(owner
));
1916 result
= isc_base32hex_decoderegion(&hashlabel
, &buffer
);
1917 if (result
!= ISC_R_SUCCESS
)
1921 * The hash lengths should match. If not ignore the record.
1923 if (isc_buffer_usedlength(&buffer
) != nsec3
.next_length
)
1924 return (ISC_R_IGNORE
);
1927 * Work out what this NSEC3 covers.
1928 * Inside (<0) or outside (>=0).
1930 scope
= memcmp(owner
, nsec3
.next
, nsec3
.next_length
);
1933 * Prepare to compute all the hashes.
1935 dns_fixedname_init(&qfixed
);
1936 qname
= dns_fixedname_name(&qfixed
);
1937 dns_name_downcase(name
, qname
, NULL
);
1938 qlabels
= dns_name_countlabels(qname
);
1941 while (qlabels
>= zlabels
) {
1942 length
= isc_iterated_hash(hash
, nsec3
.hash
, nsec3
.iterations
,
1943 nsec3
.salt
, nsec3
.salt_length
,
1944 qname
->ndata
, qname
->length
);
1946 * The computed hash length should match.
1948 if (length
!= nsec3
.next_length
) {
1949 (*logit
)(arg
, ISC_LOG_DEBUG(3),
1950 "ignoring NSEC bad length %u vs %u",
1951 length
, nsec3
.next_length
);
1952 return (ISC_R_IGNORE
);
1955 order
= memcmp(hash
, owner
, length
);
1956 if (first
&& order
== 0) {
1958 * The hashes are the same.
1960 atparent
= dns_rdatatype_atparent(type
);
1961 ns
= dns_nsec3_typepresent(&rdata
, dns_rdatatype_ns
);
1962 soa
= dns_nsec3_typepresent(&rdata
, dns_rdatatype_soa
);
1966 * This NSEC3 record is from somewhere
1967 * higher in the DNS, and at the
1968 * parent of a delegation. It can not
1969 * be legitimately used here.
1971 (*logit
)(arg
, ISC_LOG_DEBUG(3),
1972 "ignoring parent NSEC3");
1973 return (ISC_R_IGNORE
);
1975 } else if (atparent
&& ns
&& soa
) {
1977 * This NSEC3 record is from the child.
1978 * It can not be legitimately used here.
1980 (*logit
)(arg
, ISC_LOG_DEBUG(3),
1981 "ignoring child NSEC3");
1982 return (ISC_R_IGNORE
);
1984 if (type
== dns_rdatatype_cname
||
1985 type
== dns_rdatatype_nxt
||
1986 type
== dns_rdatatype_nsec
||
1987 type
== dns_rdatatype_key
||
1988 !dns_nsec3_typepresent(&rdata
, dns_rdatatype_cname
)) {
1990 *data
= dns_nsec3_typepresent(&rdata
, type
);
1991 (*logit
)(arg
, ISC_LOG_DEBUG(3),
1992 "NSEC3 proves name exists (owner) "
1994 return (ISC_R_SUCCESS
);
1996 (*logit
)(arg
, ISC_LOG_DEBUG(3),
1997 "NSEC3 proves CNAME exists");
1998 return (ISC_R_IGNORE
);
2002 dns_nsec3_typepresent(&rdata
, dns_rdatatype_ns
) &&
2003 !dns_nsec3_typepresent(&rdata
, dns_rdatatype_soa
))
2006 * This NSEC3 record is from somewhere higher in
2007 * the DNS, and at the parent of a delegation.
2008 * It can not be legitimately used here.
2010 (*logit
)(arg
, ISC_LOG_DEBUG(3),
2011 "ignoring parent NSEC3");
2012 return (ISC_R_IGNORE
);
2016 * Potential closest encloser.
2019 if (closest
!= NULL
&&
2020 (dns_name_countlabels(closest
) == 0 ||
2021 dns_name_issubdomain(qname
, closest
)) &&
2022 !dns_nsec3_typepresent(&rdata
, dns_rdatatype_ds
) &&
2023 !dns_nsec3_typepresent(&rdata
, dns_rdatatype_dname
) &&
2024 (dns_nsec3_typepresent(&rdata
, dns_rdatatype_soa
) ||
2025 !dns_nsec3_typepresent(&rdata
, dns_rdatatype_ns
)))
2028 dns_name_format(qname
, namebuf
,
2030 (*logit
)(arg
, ISC_LOG_DEBUG(3),
2031 "NSEC3 indicates potential closest "
2032 "encloser: '%s'", namebuf
);
2033 dns_name_copy(qname
, closest
, NULL
);
2034 *setclosest
= ISC_TRUE
;
2036 dns_name_format(qname
, namebuf
, sizeof(namebuf
));
2037 (*logit
)(arg
, ISC_LOG_DEBUG(3),
2038 "NSEC3 at super-domain %s", namebuf
);
2043 * Find if the name does not exist.
2045 * We continue as we need to find the name closest to the
2046 * closest encloser that doesn't exist.
2048 * We also need to continue to ensure that we are not
2049 * proving the non-existence of a record in a sub-zone.
2050 * If that would be the case we will return ISC_R_IGNORE
2053 if ((scope
< 0 && order
> 0 &&
2054 memcmp(hash
, nsec3
.next
, length
) < 0) ||
2055 (scope
>= 0 && (order
> 0 ||
2056 memcmp(hash
, nsec3
.next
, length
) < 0)))
2058 dns_name_format(qname
, namebuf
, sizeof(namebuf
));
2059 (*logit
)(arg
, ISC_LOG_DEBUG(3), "NSEC3 proves "
2060 "name does not exist: '%s'", namebuf
);
2061 if (nearest
!= NULL
&&
2062 (dns_name_countlabels(nearest
) == 0 ||
2063 dns_name_issubdomain(nearest
, qname
))) {
2064 dns_name_copy(qname
, nearest
, NULL
);
2065 *setnearest
= ISC_TRUE
;
2068 *exists
= ISC_FALSE
;
2070 if (optout
!= NULL
) {
2071 if ((nsec3
.flags
& DNS_NSEC3FLAG_OPTOUT
) != 0)
2072 (*logit
)(arg
, ISC_LOG_DEBUG(3),
2073 "NSEC3 indicates optout");
2075 (*logit
)(arg
, ISC_LOG_DEBUG(3),
2076 "NSEC3 indicates secure range");
2078 ISC_TF(nsec3
.flags
& DNS_NSEC3FLAG_OPTOUT
);
2080 answer
= ISC_R_SUCCESS
;
2085 dns_name_split(qname
, qlabels
, NULL
, qname
);