nsec3.c revision 1.16 1 /* $NetBSD: nsec3.c,v 1.16 2025/07/17 19:01:45 christos Exp $ */
2
3 /*
4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5 *
6 * SPDX-License-Identifier: MPL-2.0
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11 *
12 * See the COPYRIGHT file distributed with this work for additional
13 * information regarding copyright ownership.
14 */
15
16 #include <inttypes.h>
17 #include <stdbool.h>
18
19 #include <isc/base32.h>
20 #include <isc/buffer.h>
21 #include <isc/hex.h>
22 #include <isc/iterated_hash.h>
23 #include <isc/md.h>
24 #include <isc/nonce.h>
25 #include <isc/result.h>
26 #include <isc/safe.h>
27 #include <isc/string.h>
28 #include <isc/util.h>
29
30 #include <dns/compress.h>
31 #include <dns/db.h>
32 #include <dns/dbiterator.h>
33 #include <dns/diff.h>
34 #include <dns/fixedname.h>
35 #include <dns/nsec.h>
36 #include <dns/nsec3.h>
37 #include <dns/rdata.h>
38 #include <dns/rdatalist.h>
39 #include <dns/rdataset.h>
40 #include <dns/rdatasetiter.h>
41 #include <dns/rdatastruct.h>
42 #include <dns/zone.h>
43
44 #include <dst/dst.h>
45
46 #define CHECK(x) \
47 do { \
48 result = (x); \
49 if (result != ISC_R_SUCCESS) \
50 goto failure; \
51 } while (0)
52
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)
57
58 isc_result_t
59 dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node,
60 unsigned int hashalg, unsigned int flags,
61 unsigned int iterations, const unsigned char *salt,
62 size_t salt_length, const unsigned char *nexthash,
63 size_t hash_length, unsigned char *buffer,
64 dns_rdata_t *rdata) {
65 isc_result_t result;
66 dns_rdataset_t rdataset;
67 isc_region_t r;
68 unsigned int i;
69 bool found;
70 bool found_ns;
71 bool need_rrsig;
72
73 unsigned char *nsec_bits, *bm;
74 unsigned int max_type;
75 dns_rdatasetiter_t *rdsiter;
76 unsigned char *p;
77
78 REQUIRE(salt_length < 256U);
79 REQUIRE(hash_length < 256U);
80 REQUIRE(flags <= 0xffU);
81 REQUIRE(hashalg <= 0xffU);
82 REQUIRE(iterations <= 0xffffU);
83
84 switch (hashalg) {
85 case dns_hash_sha1:
86 REQUIRE(hash_length == ISC_SHA1_DIGESTLENGTH);
87 break;
88 }
89
90 memset(buffer, 0, DNS_NSEC3_BUFFERSIZE);
91
92 p = buffer;
93
94 *p++ = hashalg;
95 *p++ = flags;
96
97 *p++ = iterations >> 8;
98 *p++ = iterations;
99
100 *p++ = (unsigned char)salt_length;
101 memmove(p, salt, salt_length);
102 p += salt_length;
103
104 *p++ = (unsigned char)hash_length;
105 memmove(p, nexthash, hash_length);
106 p += hash_length;
107
108 r.length = (unsigned int)(p - buffer);
109 r.base = buffer;
110
111 /*
112 * Use the end of the space for a raw bitmap leaving enough
113 * space for the window identifiers and length octets.
114 */
115 bm = r.base + r.length + 512;
116 nsec_bits = r.base + r.length;
117 max_type = 0;
118 if (node == NULL) {
119 goto collapse_bitmap;
120 }
121 dns_rdataset_init(&rdataset);
122 rdsiter = NULL;
123 result = dns_db_allrdatasets(db, node, version, 0, 0, &rdsiter);
124 if (result != ISC_R_SUCCESS) {
125 return result;
126 }
127 found = found_ns = need_rrsig = false;
128 for (result = dns_rdatasetiter_first(rdsiter); result == ISC_R_SUCCESS;
129 result = dns_rdatasetiter_next(rdsiter))
130 {
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 {
136 if (rdataset.type > max_type) {
137 max_type = rdataset.type;
138 }
139 dns_nsec_setbit(bm, rdataset.type, 1);
140 /*
141 * Work out if we need to set the RRSIG bit for
142 * this node. We set the RRSIG bit if either of
143 * the following conditions are met:
144 * 1) We have a SOA or DS then we need to set
145 * the RRSIG bit as both always will be signed.
146 * 2) We set the RRSIG bit if we don't have
147 * a NS record but do have other data.
148 */
149 if (rdataset.type == dns_rdatatype_soa ||
150 rdataset.type == dns_rdatatype_ds)
151 {
152 need_rrsig = true;
153 } else if (rdataset.type == dns_rdatatype_ns) {
154 found_ns = true;
155 } else {
156 found = true;
157 }
158 }
159 dns_rdataset_disassociate(&rdataset);
160 }
161 if ((found && !found_ns) || need_rrsig) {
162 if (dns_rdatatype_rrsig > max_type) {
163 max_type = dns_rdatatype_rrsig;
164 }
165 dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1);
166 }
167
168 /*
169 * At zone cuts, deny the existence of glue in the parent zone.
170 */
171 if (dns_nsec_isset(bm, dns_rdatatype_ns) &&
172 !dns_nsec_isset(bm, dns_rdatatype_soa))
173 {
174 for (i = 0; i <= max_type; i++) {
175 if (dns_nsec_isset(bm, i) &&
176 !dns_rdatatype_iszonecutauth((dns_rdatatype_t)i))
177 {
178 dns_nsec_setbit(bm, i, 0);
179 }
180 }
181 }
182
183 dns_rdatasetiter_destroy(&rdsiter);
184 if (result != ISC_R_NOMORE) {
185 return result;
186 }
187
188 collapse_bitmap:
189 nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type);
190 r.length = (unsigned int)(nsec_bits - r.base);
191 INSIST(r.length <= DNS_NSEC3_BUFFERSIZE);
192 dns_rdata_fromregion(rdata, dns_db_class(db), dns_rdatatype_nsec3, &r);
193
194 return ISC_R_SUCCESS;
195 }
196
197 bool
198 dns_nsec3_typepresent(dns_rdata_t *rdata, dns_rdatatype_t type) {
199 dns_rdata_nsec3_t nsec3;
200 isc_result_t result;
201 bool present;
202 unsigned int i, len, window;
203
204 REQUIRE(rdata != NULL);
205 REQUIRE(rdata->type == dns_rdatatype_nsec3);
206
207 /* This should never fail */
208 result = dns_rdata_tostruct(rdata, &nsec3, NULL);
209 INSIST(result == ISC_R_SUCCESS);
210
211 present = false;
212 for (i = 0; i < nsec3.len; i += len) {
213 INSIST(i + 2 <= nsec3.len);
214 window = nsec3.typebits[i];
215 len = nsec3.typebits[i + 1];
216 INSIST(len > 0 && len <= 32);
217 i += 2;
218 INSIST(i + len <= nsec3.len);
219 if (window * 256 > type) {
220 break;
221 }
222 if ((window + 1) * 256 <= type) {
223 continue;
224 }
225 if (type < (window * 256) + len * 8) {
226 present = dns_nsec_isset(&nsec3.typebits[i],
227 type % 256);
228 }
229 break;
230 }
231 dns_rdata_freestruct(&nsec3);
232 return present;
233 }
234
235 isc_result_t
236 dns_nsec3_generate_salt(unsigned char *salt, size_t saltlen) {
237 if (saltlen > 255U) {
238 return ISC_R_RANGE;
239 }
240 isc_nonce_buf(salt, saltlen);
241 return ISC_R_SUCCESS;
242 }
243
244 isc_result_t
245 dns_nsec3_hashname(dns_fixedname_t *result,
246 unsigned char rethash[NSEC3_MAX_HASH_LENGTH],
247 size_t *hash_length, const dns_name_t *name,
248 const dns_name_t *origin, dns_hash_t hashalg,
249 unsigned int iterations, const unsigned char *salt,
250 size_t saltlength) {
251 unsigned char hash[NSEC3_MAX_HASH_LENGTH];
252 unsigned char nametext[DNS_NAME_FORMATSIZE];
253 dns_fixedname_t fixed;
254 dns_name_t *downcased;
255 isc_buffer_t namebuffer;
256 isc_region_t region;
257 size_t len;
258
259 if (rethash == NULL) {
260 rethash = hash;
261 }
262
263 memset(rethash, 0, NSEC3_MAX_HASH_LENGTH);
264
265 downcased = dns_fixedname_initname(&fixed);
266 dns_name_downcase(name, downcased, NULL);
267
268 /* hash the node name */
269 len = isc_iterated_hash(rethash, hashalg, iterations, salt,
270 (int)saltlength, downcased->ndata,
271 downcased->length);
272 if (len == 0U) {
273 return DNS_R_BADALG;
274 }
275
276 SET_IF_NOT_NULL(hash_length, len);
277
278 /* convert the hash to base32hex non-padded */
279 region.base = rethash;
280 region.length = (unsigned int)len;
281 isc_buffer_init(&namebuffer, nametext, sizeof nametext);
282 isc_base32hexnp_totext(®ion, 1, "", &namebuffer);
283
284 /* convert the hex to a domain name */
285 dns_fixedname_init(result);
286 return dns_name_fromtext(dns_fixedname_name(result), &namebuffer,
287 origin, 0, NULL);
288 }
289
290 unsigned int
291 dns_nsec3_hashlength(dns_hash_t hash) {
292 switch (hash) {
293 case dns_hash_sha1:
294 return ISC_SHA1_DIGESTLENGTH;
295 }
296 return 0;
297 }
298
299 bool
300 dns_nsec3_supportedhash(dns_hash_t hash) {
301 switch (hash) {
302 case dns_hash_sha1:
303 return true;
304 }
305 return false;
306 }
307
308 /*%
309 * Update a single RR in version 'ver' of 'db' and log the
310 * update in 'diff'.
311 *
312 * Ensures:
313 * \li '*tuple' == NULL. Either the tuple is freed, or its
314 * ownership has been transferred to the diff.
315 */
316 static isc_result_t
317 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
318 dns_diff_t *diff) {
319 dns_diff_t temp_diff;
320 isc_result_t result;
321
322 /*
323 * Create a singleton diff.
324 */
325 dns_diff_init(diff->mctx, &temp_diff);
326 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
327
328 /*
329 * Apply it to the database.
330 */
331 result = dns_diff_apply(&temp_diff, db, ver);
332 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
333 if (result != ISC_R_SUCCESS) {
334 dns_difftuple_free(tuple);
335 return result;
336 }
337
338 /*
339 * Merge it into the current pending journal entry.
340 */
341 dns_diff_appendminimal(diff, tuple);
342
343 /*
344 * Do not clear temp_diff.
345 */
346 return ISC_R_SUCCESS;
347 }
348
349 /*%
350 * Set '*exists' to true iff the given name exists, to false otherwise.
351 */
352 static isc_result_t
353 name_exists(dns_db_t *db, dns_dbversion_t *version, const dns_name_t *name,
354 bool *exists) {
355 isc_result_t result;
356 dns_dbnode_t *node = NULL;
357 dns_rdatasetiter_t *iter = NULL;
358
359 result = dns_db_findnode(db, name, false, &node);
360 if (result == ISC_R_NOTFOUND) {
361 *exists = false;
362 return ISC_R_SUCCESS;
363 }
364 if (result != ISC_R_SUCCESS) {
365 return result;
366 }
367
368 result = dns_db_allrdatasets(db, node, version, 0, (isc_stdtime_t)0,
369 &iter);
370 if (result != ISC_R_SUCCESS) {
371 goto cleanup_node;
372 }
373
374 result = dns_rdatasetiter_first(iter);
375 if (result == ISC_R_SUCCESS) {
376 *exists = true;
377 } else if (result == ISC_R_NOMORE) {
378 *exists = false;
379 result = ISC_R_SUCCESS;
380 } else {
381 *exists = false;
382 }
383 dns_rdatasetiter_destroy(&iter);
384
385 cleanup_node:
386 dns_db_detachnode(db, &node);
387 return result;
388 }
389
390 static bool
391 match_nsec3param(const dns_rdata_nsec3_t *nsec3,
392 const dns_rdata_nsec3param_t *nsec3param) {
393 if (nsec3->hash == nsec3param->hash &&
394 nsec3->iterations == nsec3param->iterations &&
395 nsec3->salt_length == nsec3param->salt_length &&
396 !memcmp(nsec3->salt, nsec3param->salt, nsec3->salt_length))
397 {
398 return true;
399 }
400 return false;
401 }
402
403 /*%
404 * Delete NSEC3 records at "name" which match "param", recording the
405 * change in "diff".
406 */
407 static isc_result_t
408 delnsec3(dns_db_t *db, dns_dbversion_t *version, const dns_name_t *name,
409 const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff) {
410 dns_dbnode_t *node = NULL;
411 dns_difftuple_t *tuple = NULL;
412 dns_rdata_nsec3_t nsec3;
413 dns_rdataset_t rdataset;
414 isc_result_t result;
415
416 result = dns_db_findnsec3node(db, name, false, &node);
417 if (result == ISC_R_NOTFOUND) {
418 return ISC_R_SUCCESS;
419 }
420 if (result != ISC_R_SUCCESS) {
421 return result;
422 }
423
424 dns_rdataset_init(&rdataset);
425 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, 0,
426 (isc_stdtime_t)0, &rdataset, NULL);
427
428 if (result == ISC_R_NOTFOUND) {
429 result = ISC_R_SUCCESS;
430 goto cleanup_node;
431 }
432 if (result != ISC_R_SUCCESS) {
433 goto cleanup_node;
434 }
435
436 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
437 result = dns_rdataset_next(&rdataset))
438 {
439 dns_rdata_t rdata = DNS_RDATA_INIT;
440 dns_rdataset_current(&rdataset, &rdata);
441 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
442
443 if (!match_nsec3param(&nsec3, nsec3param)) {
444 continue;
445 }
446
447 result = dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, name,
448 rdataset.ttl, &rdata, &tuple);
449 if (result != ISC_R_SUCCESS) {
450 goto failure;
451 }
452 result = do_one_tuple(&tuple, db, version, diff);
453 if (result != ISC_R_SUCCESS) {
454 goto failure;
455 }
456 }
457 if (result != ISC_R_NOMORE) {
458 goto failure;
459 }
460 result = ISC_R_SUCCESS;
461
462 failure:
463 dns_rdataset_disassociate(&rdataset);
464 cleanup_node:
465 dns_db_detachnode(db, &node);
466
467 return result;
468 }
469
470 static bool
471 better_param(dns_rdataset_t *nsec3paramset, dns_rdata_t *param) {
472 dns_rdataset_t rdataset;
473 isc_result_t result;
474
475 if (REMOVE(param->data[1])) {
476 return true;
477 }
478
479 dns_rdataset_init(&rdataset);
480 dns_rdataset_clone(nsec3paramset, &rdataset);
481 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
482 result = dns_rdataset_next(&rdataset))
483 {
484 dns_rdata_t rdata = DNS_RDATA_INIT;
485 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
486
487 if (rdataset.type != dns_rdatatype_nsec3param) {
488 dns_rdata_t tmprdata = DNS_RDATA_INIT;
489 dns_rdataset_current(&rdataset, &tmprdata);
490 if (!dns_nsec3param_fromprivate(&tmprdata, &rdata, buf,
491 sizeof(buf)))
492 {
493 continue;
494 }
495 } else {
496 dns_rdataset_current(&rdataset, &rdata);
497 }
498
499 if (rdata.length != param->length) {
500 continue;
501 }
502 if (rdata.data[0] != param->data[0] || REMOVE(rdata.data[1]) ||
503 rdata.data[2] != param->data[2] ||
504 rdata.data[3] != param->data[3] ||
505 rdata.data[4] != param->data[4] ||
506 memcmp(&rdata.data[5], ¶m->data[5], param->data[4]))
507 {
508 continue;
509 }
510 if (CREATE(rdata.data[1]) && !CREATE(param->data[1])) {
511 dns_rdataset_disassociate(&rdataset);
512 return true;
513 }
514 }
515 dns_rdataset_disassociate(&rdataset);
516 return false;
517 }
518
519 static isc_result_t
520 find_nsec3(dns_rdata_nsec3_t *nsec3, dns_rdataset_t *rdataset,
521 const dns_rdata_nsec3param_t *nsec3param) {
522 isc_result_t result;
523 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
524 result = dns_rdataset_next(rdataset))
525 {
526 dns_rdata_t rdata = DNS_RDATA_INIT;
527
528 dns_rdataset_current(rdataset, &rdata);
529 CHECK(dns_rdata_tostruct(&rdata, nsec3, NULL));
530 dns_rdata_reset(&rdata);
531 if (match_nsec3param(nsec3, nsec3param)) {
532 break;
533 }
534 }
535 failure:
536 return result;
537 }
538
539 isc_result_t
540 dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version,
541 const dns_name_t *name,
542 const dns_rdata_nsec3param_t *nsec3param, dns_ttl_t nsecttl,
543 bool unsecure, dns_diff_t *diff) {
544 dns_dbiterator_t *dbit = NULL;
545 dns_dbnode_t *node = NULL;
546 dns_dbnode_t *newnode = NULL;
547 dns_difftuple_t *tuple = NULL;
548 dns_fixedname_t fixed;
549 dns_fixedname_t fprev;
550 dns_hash_t hash;
551 dns_name_t *hashname;
552 dns_name_t *origin;
553 dns_name_t *prev;
554 dns_name_t empty;
555 dns_rdata_nsec3_t nsec3;
556 dns_rdata_t rdata = DNS_RDATA_INIT;
557 dns_rdataset_t rdataset;
558 int pass;
559 bool exists = false;
560 bool maybe_remove_unsecure = false;
561 uint8_t flags;
562 isc_buffer_t buffer;
563 isc_result_t result;
564 unsigned char *old_next;
565 unsigned char *salt;
566 unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
567 unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
568 unsigned int iterations;
569 unsigned int labels;
570 size_t next_length;
571 unsigned int old_length;
572 unsigned int salt_length;
573
574 hashname = dns_fixedname_initname(&fixed);
575 prev = dns_fixedname_initname(&fprev);
576
577 dns_rdataset_init(&rdataset);
578
579 origin = dns_db_origin(db);
580
581 /*
582 * Chain parameters.
583 */
584 hash = nsec3param->hash;
585 iterations = nsec3param->iterations;
586 salt_length = nsec3param->salt_length;
587 salt = nsec3param->salt;
588
589 /*
590 * Default flags for a new chain.
591 */
592 flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
593
594 /*
595 * If this is the first NSEC3 in the chain nexthash will
596 * remain pointing to itself.
597 */
598 next_length = sizeof(nexthash);
599 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length, name, origin,
600 hash, iterations, salt, salt_length));
601 INSIST(next_length <= sizeof(nexthash));
602
603 /*
604 * Create the node if it doesn't exist and hold
605 * a reference to it until we have added the NSEC3.
606 */
607 CHECK(dns_db_findnsec3node(db, hashname, true, &newnode));
608
609 /*
610 * Seek the iterator to the 'newnode'.
611 */
612 CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
613 CHECK(dns_dbiterator_seek(dbit, hashname));
614 CHECK(dns_dbiterator_pause(dbit));
615 result = dns_db_findrdataset(db, newnode, version, dns_rdatatype_nsec3,
616 0, (isc_stdtime_t)0, &rdataset, NULL);
617 /*
618 * If we updating a existing NSEC3 then find its
619 * next field.
620 */
621 if (result == ISC_R_SUCCESS) {
622 result = find_nsec3(&nsec3, &rdataset, nsec3param);
623 if (result == ISC_R_SUCCESS) {
624 if (!CREATE(nsec3param->flags)) {
625 flags = nsec3.flags;
626 }
627 next_length = nsec3.next_length;
628 INSIST(next_length <= sizeof(nexthash));
629 memmove(nexthash, nsec3.next, next_length);
630 dns_rdataset_disassociate(&rdataset);
631 /*
632 * If the NSEC3 is not for a unsecure delegation then
633 * we are just updating it. If it is for a unsecure
634 * delegation then we need find out if we need to
635 * remove the NSEC3 record or not by examining the
636 * previous NSEC3 record.
637 */
638 if (!unsecure) {
639 goto addnsec3;
640 } else if (CREATE(nsec3param->flags) && OPTOUT(flags)) {
641 result = dns_nsec3_delnsec3(db, version, name,
642 nsec3param, diff);
643 goto failure;
644 } else {
645 maybe_remove_unsecure = true;
646 }
647 } else {
648 dns_rdataset_disassociate(&rdataset);
649 if (result != ISC_R_NOMORE) {
650 goto failure;
651 }
652 }
653 }
654
655 /*
656 * Find the previous NSEC3 (if any) and update it if required.
657 */
658 pass = 0;
659 do {
660 result = dns_dbiterator_prev(dbit);
661 if (result == ISC_R_NOMORE) {
662 pass++;
663 CHECK(dns_dbiterator_last(dbit));
664 }
665 CHECK(dns_dbiterator_current(dbit, &node, prev));
666 CHECK(dns_dbiterator_pause(dbit));
667 result = dns_db_findrdataset(db, node, version,
668 dns_rdatatype_nsec3, 0,
669 (isc_stdtime_t)0, &rdataset, NULL);
670 dns_db_detachnode(db, &node);
671 if (result != ISC_R_SUCCESS) {
672 continue;
673 }
674
675 result = find_nsec3(&nsec3, &rdataset, nsec3param);
676 if (result == ISC_R_NOMORE) {
677 dns_rdataset_disassociate(&rdataset);
678 continue;
679 }
680 if (result != ISC_R_SUCCESS) {
681 goto failure;
682 }
683
684 if (maybe_remove_unsecure) {
685 dns_rdataset_disassociate(&rdataset);
686 /*
687 * If we have OPTOUT set in the previous NSEC3 record
688 * we actually need to delete the NSEC3 record.
689 * Otherwise we just need to replace the NSEC3 record.
690 */
691 if (OPTOUT(nsec3.flags)) {
692 result = dns_nsec3_delnsec3(db, version, name,
693 nsec3param, diff);
694 goto failure;
695 }
696 goto addnsec3;
697 } else {
698 /*
699 * Is this is a unsecure delegation we are adding?
700 * If so no change is required.
701 */
702 if (OPTOUT(nsec3.flags) && unsecure) {
703 dns_rdataset_disassociate(&rdataset);
704 goto failure;
705 }
706 }
707
708 old_next = nsec3.next;
709 old_length = nsec3.next_length;
710
711 /*
712 * Delete the old previous NSEC3.
713 */
714 CHECK(delnsec3(db, version, prev, nsec3param, diff));
715
716 /*
717 * Fixup the previous NSEC3.
718 */
719 nsec3.next = nexthash;
720 nsec3.next_length = (unsigned char)next_length;
721 isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
722 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
723 dns_rdatatype_nsec3, &nsec3,
724 &buffer));
725 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
726 rdataset.ttl, &rdata, &tuple));
727 CHECK(do_one_tuple(&tuple, db, version, diff));
728 INSIST(old_length <= sizeof(nexthash));
729 memmove(nexthash, old_next, old_length);
730 if (!CREATE(nsec3param->flags)) {
731 flags = nsec3.flags;
732 }
733 dns_rdata_reset(&rdata);
734 dns_rdataset_disassociate(&rdataset);
735 break;
736 } while (pass < 2);
737
738 addnsec3:
739 /*
740 * Create the NSEC3 RDATA.
741 */
742 CHECK(dns_db_findnode(db, name, false, &node));
743 CHECK(dns_nsec3_buildrdata(db, version, node, hash, flags, iterations,
744 salt, salt_length, nexthash, next_length,
745 nsec3buf, &rdata));
746 dns_db_detachnode(db, &node);
747
748 /*
749 * Delete the old NSEC3 and record the change.
750 */
751 CHECK(delnsec3(db, version, hashname, nsec3param, diff));
752 /*
753 * Add the new NSEC3 and record the change.
754 */
755 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, hashname,
756 nsecttl, &rdata, &tuple));
757 CHECK(do_one_tuple(&tuple, db, version, diff));
758 INSIST(tuple == NULL);
759 dns_rdata_reset(&rdata);
760 dns_db_detachnode(db, &newnode);
761
762 /*
763 * Add missing NSEC3 records for empty nodes
764 */
765 dns_name_init(&empty, NULL);
766 dns_name_clone(name, &empty);
767 do {
768 labels = dns_name_countlabels(&empty) - 1;
769 if (labels <= dns_name_countlabels(origin)) {
770 break;
771 }
772 dns_name_getlabelsequence(&empty, 1, labels, &empty);
773 CHECK(name_exists(db, version, &empty, &exists));
774 if (exists) {
775 break;
776 }
777 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length, &empty,
778 origin, hash, iterations, salt,
779 salt_length));
780
781 /*
782 * Create the node if it doesn't exist and hold
783 * a reference to it until we have added the NSEC3
784 * or we discover we don't need to make a change.
785 */
786 CHECK(dns_db_findnsec3node(db, hashname, true, &newnode));
787 result = dns_db_findrdataset(db, newnode, version,
788 dns_rdatatype_nsec3, 0,
789 (isc_stdtime_t)0, &rdataset, NULL);
790 if (result == ISC_R_SUCCESS) {
791 result = find_nsec3(&nsec3, &rdataset, nsec3param);
792 dns_rdataset_disassociate(&rdataset);
793 if (result == ISC_R_SUCCESS) {
794 dns_db_detachnode(db, &newnode);
795 break;
796 }
797 if (result != ISC_R_NOMORE) {
798 goto failure;
799 }
800 } else if (result == ISC_R_NOTFOUND) {
801 /*
802 * If we didn't find an NSEC3 in the node,
803 * then the node must have been newly created
804 * by dns_db_findnsec3node(). The iterator
805 * needs to be updated so we can seek for
806 * the node's predecessor.
807 */
808 dns_dbiterator_destroy(&dbit);
809 CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY,
810 &dbit));
811 }
812
813 /*
814 * Find the previous NSEC3 and update it.
815 */
816 CHECK(dns_dbiterator_seek(dbit, hashname));
817 pass = 0;
818 do {
819 result = dns_dbiterator_prev(dbit);
820 if (result == ISC_R_NOMORE) {
821 pass++;
822 CHECK(dns_dbiterator_last(dbit));
823 }
824 CHECK(dns_dbiterator_current(dbit, &node, prev));
825 CHECK(dns_dbiterator_pause(dbit));
826 result = dns_db_findrdataset(
827 db, node, version, dns_rdatatype_nsec3, 0,
828 (isc_stdtime_t)0, &rdataset, NULL);
829 dns_db_detachnode(db, &node);
830 if (result != ISC_R_SUCCESS) {
831 continue;
832 }
833 result = find_nsec3(&nsec3, &rdataset, nsec3param);
834 if (result == ISC_R_NOMORE) {
835 dns_rdataset_disassociate(&rdataset);
836 continue;
837 }
838 if (result != ISC_R_SUCCESS) {
839 goto failure;
840 }
841
842 old_next = nsec3.next;
843 old_length = nsec3.next_length;
844
845 /*
846 * Delete the old previous NSEC3.
847 */
848 CHECK(delnsec3(db, version, prev, nsec3param, diff));
849
850 /*
851 * Fixup the previous NSEC3.
852 */
853 nsec3.next = nexthash;
854 nsec3.next_length = (unsigned char)next_length;
855 isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
856 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
857 dns_rdatatype_nsec3, &nsec3,
858 &buffer));
859 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
860 prev, rdataset.ttl, &rdata,
861 &tuple));
862 CHECK(do_one_tuple(&tuple, db, version, diff));
863 INSIST(old_length <= sizeof(nexthash));
864 memmove(nexthash, old_next, old_length);
865 if (!CREATE(nsec3param->flags)) {
866 flags = nsec3.flags;
867 }
868 dns_rdata_reset(&rdata);
869 dns_rdataset_disassociate(&rdataset);
870 break;
871 } while (pass < 2);
872
873 INSIST(pass < 2);
874
875 /*
876 * Create the NSEC3 RDATA for the empty node.
877 */
878 CHECK(dns_nsec3_buildrdata(
879 db, version, NULL, hash, flags, iterations, salt,
880 salt_length, nexthash, next_length, nsec3buf, &rdata));
881 /*
882 * Delete the old NSEC3 and record the change.
883 */
884 CHECK(delnsec3(db, version, hashname, nsec3param, diff));
885
886 /*
887 * Add the new NSEC3 and record the change.
888 */
889 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, hashname,
890 nsecttl, &rdata, &tuple));
891 CHECK(do_one_tuple(&tuple, db, version, diff));
892 INSIST(tuple == NULL);
893 dns_rdata_reset(&rdata);
894 dns_db_detachnode(db, &newnode);
895 } while (1);
896
897 /* result cannot be ISC_R_NOMORE here */
898 INSIST(result != ISC_R_NOMORE);
899
900 failure:
901 if (dbit != NULL) {
902 dns_dbiterator_destroy(&dbit);
903 }
904 if (dns_rdataset_isassociated(&rdataset)) {
905 dns_rdataset_disassociate(&rdataset);
906 }
907 if (node != NULL) {
908 dns_db_detachnode(db, &node);
909 }
910 if (newnode != NULL) {
911 dns_db_detachnode(db, &newnode);
912 }
913 return result;
914 }
915
916 /*%
917 * Add NSEC3 records for "name", recording the change in "diff".
918 * The existing NSEC3 records are removed.
919 */
920 isc_result_t
921 dns_nsec3_addnsec3s(dns_db_t *db, dns_dbversion_t *version,
922 const dns_name_t *name, dns_ttl_t nsecttl, bool unsecure,
923 dns_diff_t *diff) {
924 dns_dbnode_t *node = NULL;
925 dns_rdata_nsec3param_t nsec3param;
926 dns_rdataset_t rdataset;
927 isc_result_t result;
928
929 dns_rdataset_init(&rdataset);
930
931 /*
932 * Find the NSEC3 parameters for this zone.
933 */
934 result = dns_db_getoriginnode(db, &node);
935 if (result != ISC_R_SUCCESS) {
936 return result;
937 }
938
939 result = dns_db_findrdataset(db, node, version,
940 dns_rdatatype_nsec3param, 0, 0, &rdataset,
941 NULL);
942 dns_db_detachnode(db, &node);
943 if (result == ISC_R_NOTFOUND) {
944 return ISC_R_SUCCESS;
945 }
946 if (result != ISC_R_SUCCESS) {
947 return result;
948 }
949
950 /*
951 * Update each active NSEC3 chain.
952 */
953 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
954 result = dns_rdataset_next(&rdataset))
955 {
956 dns_rdata_t rdata = DNS_RDATA_INIT;
957
958 dns_rdataset_current(&rdataset, &rdata);
959 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
960
961 if (nsec3param.flags != 0) {
962 continue;
963 }
964 /*
965 * We have a active chain. Update it.
966 */
967 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
968 nsecttl, unsecure, diff));
969 }
970 if (result == ISC_R_NOMORE) {
971 result = ISC_R_SUCCESS;
972 }
973
974 failure:
975 if (dns_rdataset_isassociated(&rdataset)) {
976 dns_rdataset_disassociate(&rdataset);
977 }
978 if (node != NULL) {
979 dns_db_detachnode(db, &node);
980 }
981
982 return result;
983 }
984
985 bool
986 dns_nsec3param_fromprivate(dns_rdata_t *src, dns_rdata_t *target,
987 unsigned char *buf, size_t buflen) {
988 isc_result_t result;
989 isc_buffer_t buf1;
990 isc_buffer_t buf2;
991
992 /*
993 * Algorithm 0 (reserved by RFC 4034) is used to identify
994 * NSEC3PARAM records from DNSKEY pointers.
995 */
996 if (src->length < 1 || src->data[0] != 0) {
997 return false;
998 }
999
1000 isc_buffer_init(&buf1, src->data + 1, src->length - 1);
1001 isc_buffer_add(&buf1, src->length - 1);
1002 isc_buffer_setactive(&buf1, src->length - 1);
1003 isc_buffer_init(&buf2, buf, (unsigned int)buflen);
1004 result = dns_rdata_fromwire(target, src->rdclass,
1005 dns_rdatatype_nsec3param, &buf1,
1006 DNS_DECOMPRESS_NEVER, &buf2);
1007
1008 return result == ISC_R_SUCCESS;
1009 }
1010
1011 void
1012 dns_nsec3param_toprivate(dns_rdata_t *src, dns_rdata_t *target,
1013 dns_rdatatype_t privatetype, unsigned char *buf,
1014 size_t buflen) {
1015 REQUIRE(buflen >= (unsigned int)src->length + 1);
1016
1017 REQUIRE(DNS_RDATA_INITIALIZED(target));
1018
1019 memmove(buf + 1, src->data, src->length);
1020 buf[0] = 0;
1021 target->data = buf;
1022 target->length = src->length + 1;
1023 target->type = privatetype;
1024 target->rdclass = src->rdclass;
1025 target->flags = 0;
1026 ISC_LINK_INIT(target, link);
1027 }
1028
1029 static isc_result_t
1030 rr_exists(dns_db_t *db, dns_dbversion_t *ver, const dns_name_t *name,
1031 const dns_rdata_t *rdata, bool *flag) {
1032 dns_rdataset_t rdataset;
1033 dns_dbnode_t *node = NULL;
1034 isc_result_t result;
1035
1036 dns_rdataset_init(&rdataset);
1037 if (rdata->type == dns_rdatatype_nsec3) {
1038 CHECK(dns_db_findnsec3node(db, name, false, &node));
1039 } else {
1040 CHECK(dns_db_findnode(db, name, false, &node));
1041 }
1042 result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
1043 (isc_stdtime_t)0, &rdataset, NULL);
1044 if (result == ISC_R_NOTFOUND) {
1045 *flag = false;
1046 result = ISC_R_SUCCESS;
1047 goto failure;
1048 }
1049
1050 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
1051 result = dns_rdataset_next(&rdataset))
1052 {
1053 dns_rdata_t myrdata = DNS_RDATA_INIT;
1054 dns_rdataset_current(&rdataset, &myrdata);
1055 if (!dns_rdata_casecompare(&myrdata, rdata)) {
1056 break;
1057 }
1058 }
1059 dns_rdataset_disassociate(&rdataset);
1060 if (result == ISC_R_SUCCESS) {
1061 *flag = true;
1062 } else if (result == ISC_R_NOMORE) {
1063 *flag = false;
1064 result = ISC_R_SUCCESS;
1065 }
1066
1067 failure:
1068 if (node != NULL) {
1069 dns_db_detachnode(db, &node);
1070 }
1071 return result;
1072 }
1073
1074 isc_result_t
1075 dns_nsec3param_salttotext(dns_rdata_nsec3param_t *nsec3param, char *dst,
1076 size_t dstlen) {
1077 isc_result_t result;
1078 isc_region_t r;
1079 isc_buffer_t b;
1080
1081 REQUIRE(nsec3param != NULL);
1082 REQUIRE(dst != NULL);
1083
1084 if (nsec3param->salt_length == 0) {
1085 if (dstlen < 2U) {
1086 return ISC_R_NOSPACE;
1087 }
1088 strlcpy(dst, "-", dstlen);
1089 return ISC_R_SUCCESS;
1090 }
1091
1092 r.base = nsec3param->salt;
1093 r.length = nsec3param->salt_length;
1094 isc_buffer_init(&b, dst, (unsigned int)dstlen);
1095
1096 result = isc_hex_totext(&r, 2, "", &b);
1097 if (result != ISC_R_SUCCESS) {
1098 return result;
1099 }
1100
1101 if (isc_buffer_availablelength(&b) < 1) {
1102 return ISC_R_NOSPACE;
1103 }
1104 isc_buffer_putuint8(&b, 0);
1105
1106 return ISC_R_SUCCESS;
1107 }
1108
1109 isc_result_t
1110 dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver,
1111 dns_zone_t *zone, bool nonsec, dns_diff_t *diff) {
1112 dns_dbnode_t *node = NULL;
1113 dns_difftuple_t *tuple = NULL;
1114 dns_name_t next;
1115 dns_rdata_t rdata = DNS_RDATA_INIT;
1116 dns_rdataset_t rdataset;
1117 bool flag;
1118 isc_result_t result = ISC_R_SUCCESS;
1119 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE + 1];
1120 dns_name_t *origin = dns_zone_getorigin(zone);
1121 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
1122
1123 dns_name_init(&next, NULL);
1124 dns_rdataset_init(&rdataset);
1125
1126 result = dns_db_getoriginnode(db, &node);
1127 if (result != ISC_R_SUCCESS) {
1128 return result;
1129 }
1130
1131 /*
1132 * Cause all NSEC3 chains to be deleted.
1133 */
1134 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0,
1135 (isc_stdtime_t)0, &rdataset, NULL);
1136 if (result == ISC_R_NOTFOUND) {
1137 goto try_private;
1138 }
1139 if (result != ISC_R_SUCCESS) {
1140 goto failure;
1141 }
1142
1143 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
1144 result = dns_rdataset_next(&rdataset))
1145 {
1146 dns_rdata_t private = DNS_RDATA_INIT;
1147
1148 dns_rdataset_current(&rdataset, &rdata);
1149 dns_nsec3param_toprivate(&rdata, &private, privatetype, buf,
1150 sizeof(buf));
1151 buf[2] = DNS_NSEC3FLAG_REMOVE;
1152 if (nonsec) {
1153 buf[2] |= DNS_NSEC3FLAG_NONSEC;
1154 }
1155
1156 CHECK(rr_exists(db, ver, origin, &private, &flag));
1157
1158 if (!flag) {
1159 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1160 origin, 0, &private,
1161 &tuple));
1162 CHECK(do_one_tuple(&tuple, db, ver, diff));
1163 INSIST(tuple == NULL);
1164 }
1165 dns_rdata_reset(&rdata);
1166 }
1167 if (result != ISC_R_NOMORE) {
1168 goto failure;
1169 }
1170
1171 dns_rdataset_disassociate(&rdataset);
1172
1173 try_private:
1174 if (privatetype == 0) {
1175 goto success;
1176 }
1177 result = dns_db_findrdataset(db, node, ver, privatetype, 0,
1178 (isc_stdtime_t)0, &rdataset, NULL);
1179 if (result == ISC_R_NOTFOUND) {
1180 goto success;
1181 }
1182 if (result != ISC_R_SUCCESS) {
1183 goto failure;
1184 }
1185
1186 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
1187 result = dns_rdataset_next(&rdataset))
1188 {
1189 dns_rdata_reset(&rdata);
1190 dns_rdataset_current(&rdataset, &rdata);
1191 INSIST(rdata.length <= sizeof(buf));
1192 memmove(buf, rdata.data, rdata.length);
1193
1194 /*
1195 * Private NSEC3 record length >= 6.
1196 * <0(1), hash(1), flags(1), iterations(2), saltlen(1)>
1197 */
1198 if (rdata.length < 6 || buf[0] != 0 ||
1199 (buf[2] & DNS_NSEC3FLAG_REMOVE) != 0 ||
1200 (nonsec && (buf[2] & DNS_NSEC3FLAG_NONSEC) != 0))
1201 {
1202 continue;
1203 }
1204
1205 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
1206 0, &rdata, &tuple));
1207 CHECK(do_one_tuple(&tuple, db, ver, diff));
1208 INSIST(tuple == NULL);
1209
1210 rdata.data = buf;
1211 buf[2] = DNS_NSEC3FLAG_REMOVE;
1212 if (nonsec) {
1213 buf[2] |= DNS_NSEC3FLAG_NONSEC;
1214 }
1215
1216 CHECK(rr_exists(db, ver, origin, &rdata, &flag));
1217
1218 if (!flag) {
1219 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1220 origin, 0, &rdata, &tuple));
1221 CHECK(do_one_tuple(&tuple, db, ver, diff));
1222 INSIST(tuple == NULL);
1223 }
1224 }
1225 if (result != ISC_R_NOMORE) {
1226 goto failure;
1227 }
1228 success:
1229 result = ISC_R_SUCCESS;
1230
1231 failure:
1232 if (dns_rdataset_isassociated(&rdataset)) {
1233 dns_rdataset_disassociate(&rdataset);
1234 }
1235 dns_db_detachnode(db, &node);
1236 return result;
1237 }
1238
1239 isc_result_t
1240 dns_nsec3_addnsec3sx(dns_db_t *db, dns_dbversion_t *version,
1241 const dns_name_t *name, dns_ttl_t nsecttl, bool unsecure,
1242 dns_rdatatype_t type, dns_diff_t *diff) {
1243 dns_dbnode_t *node = NULL;
1244 dns_rdata_nsec3param_t nsec3param;
1245 dns_rdataset_t rdataset;
1246 dns_rdataset_t prdataset;
1247 isc_result_t result;
1248
1249 dns_rdataset_init(&rdataset);
1250 dns_rdataset_init(&prdataset);
1251
1252 /*
1253 * Find the NSEC3 parameters for this zone.
1254 */
1255 result = dns_db_getoriginnode(db, &node);
1256 if (result != ISC_R_SUCCESS) {
1257 return result;
1258 }
1259
1260 result = dns_db_findrdataset(db, node, version, type, 0, 0, &prdataset,
1261 NULL);
1262 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
1263 goto failure;
1264 }
1265
1266 result = dns_db_findrdataset(db, node, version,
1267 dns_rdatatype_nsec3param, 0, 0, &rdataset,
1268 NULL);
1269 if (result == ISC_R_NOTFOUND) {
1270 goto try_private;
1271 }
1272 if (result != ISC_R_SUCCESS) {
1273 goto failure;
1274 }
1275
1276 /*
1277 * Update each active NSEC3 chain.
1278 */
1279 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
1280 result = dns_rdataset_next(&rdataset))
1281 {
1282 dns_rdata_t rdata = DNS_RDATA_INIT;
1283
1284 dns_rdataset_current(&rdataset, &rdata);
1285 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
1286
1287 if (nsec3param.flags != 0) {
1288 continue;
1289 }
1290
1291 /*
1292 * We have a active chain. Update it.
1293 */
1294 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
1295 nsecttl, unsecure, diff));
1296 }
1297 if (result != ISC_R_NOMORE) {
1298 goto failure;
1299 }
1300
1301 dns_rdataset_disassociate(&rdataset);
1302
1303 try_private:
1304 if (!dns_rdataset_isassociated(&prdataset)) {
1305 goto success;
1306 }
1307 /*
1308 * Update each active NSEC3 chain.
1309 */
1310 for (result = dns_rdataset_first(&prdataset); result == ISC_R_SUCCESS;
1311 result = dns_rdataset_next(&prdataset))
1312 {
1313 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1314 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1315 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1316
1317 dns_rdataset_current(&prdataset, &rdata1);
1318 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2, buf,
1319 sizeof(buf)))
1320 {
1321 continue;
1322 }
1323 CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
1324
1325 if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
1326 continue;
1327 }
1328 if (better_param(&prdataset, &rdata2)) {
1329 continue;
1330 }
1331
1332 /*
1333 * We have a active chain. Update it.
1334 */
1335 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
1336 nsecttl, unsecure, diff));
1337 }
1338 if (result == ISC_R_NOMORE) {
1339 success:
1340 result = ISC_R_SUCCESS;
1341 }
1342 failure:
1343 if (dns_rdataset_isassociated(&rdataset)) {
1344 dns_rdataset_disassociate(&rdataset);
1345 }
1346 if (dns_rdataset_isassociated(&prdataset)) {
1347 dns_rdataset_disassociate(&prdataset);
1348 }
1349 if (node != NULL) {
1350 dns_db_detachnode(db, &node);
1351 }
1352
1353 return result;
1354 }
1355
1356 /*%
1357 * Determine whether any NSEC3 records that were associated with
1358 * 'name' should be deleted or if they should continue to exist.
1359 * true indicates they should be deleted.
1360 * false indicates they should be retained.
1361 */
1362 static isc_result_t
1363 deleteit(dns_db_t *db, dns_dbversion_t *ver, const dns_name_t *name,
1364 bool *yesno) {
1365 isc_result_t result;
1366 dns_fixedname_t foundname;
1367 dns_fixedname_init(&foundname);
1368
1369 result = dns_db_find(db, name, ver, dns_rdatatype_any,
1370 DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD,
1371 (isc_stdtime_t)0, NULL,
1372 dns_fixedname_name(&foundname), NULL, NULL);
1373 if (result == DNS_R_EMPTYNAME || result == ISC_R_SUCCESS ||
1374 result == DNS_R_ZONECUT)
1375 {
1376 *yesno = false;
1377 return ISC_R_SUCCESS;
1378 }
1379 if (result == DNS_R_GLUE || result == DNS_R_DNAME ||
1380 result == DNS_R_DELEGATION || result == DNS_R_NXDOMAIN)
1381 {
1382 *yesno = true;
1383 return ISC_R_SUCCESS;
1384 }
1385 /*
1386 * Silence compiler.
1387 */
1388 *yesno = true;
1389 return result;
1390 }
1391
1392 isc_result_t
1393 dns_nsec3_delnsec3(dns_db_t *db, dns_dbversion_t *version,
1394 const dns_name_t *name,
1395 const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff) {
1396 dns_dbiterator_t *dbit = NULL;
1397 dns_dbnode_t *node = NULL;
1398 dns_difftuple_t *tuple = NULL;
1399 dns_fixedname_t fixed;
1400 dns_fixedname_t fprev;
1401 dns_hash_t hash;
1402 dns_name_t *hashname;
1403 dns_name_t *origin;
1404 dns_name_t *prev;
1405 dns_name_t empty;
1406 dns_rdata_nsec3_t nsec3;
1407 dns_rdata_t rdata = DNS_RDATA_INIT;
1408 dns_rdataset_t rdataset;
1409 int pass;
1410 bool yesno;
1411 isc_buffer_t buffer;
1412 isc_result_t result;
1413 unsigned char *salt;
1414 unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
1415 unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
1416 unsigned int iterations;
1417 unsigned int labels;
1418 size_t next_length;
1419 unsigned int salt_length;
1420
1421 hashname = dns_fixedname_initname(&fixed);
1422 prev = dns_fixedname_initname(&fprev);
1423
1424 dns_rdataset_init(&rdataset);
1425
1426 origin = dns_db_origin(db);
1427
1428 /*
1429 * Chain parameters.
1430 */
1431 hash = nsec3param->hash;
1432 iterations = nsec3param->iterations;
1433 salt_length = nsec3param->salt_length;
1434 salt = nsec3param->salt;
1435
1436 /*
1437 * If this is the first NSEC3 in the chain nexthash will
1438 * remain pointing to itself.
1439 */
1440 next_length = sizeof(nexthash);
1441 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length, name, origin,
1442 hash, iterations, salt, salt_length));
1443
1444 CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
1445
1446 result = dns_dbiterator_seek(dbit, hashname);
1447 if (result == ISC_R_NOTFOUND || result == DNS_R_PARTIALMATCH) {
1448 goto cleanup_orphaned_ents;
1449 }
1450 if (result != ISC_R_SUCCESS) {
1451 goto failure;
1452 }
1453
1454 CHECK(dns_dbiterator_current(dbit, &node, NULL));
1455 CHECK(dns_dbiterator_pause(dbit));
1456 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, 0,
1457 (isc_stdtime_t)0, &rdataset, NULL);
1458 dns_db_detachnode(db, &node);
1459 if (result == ISC_R_NOTFOUND) {
1460 goto cleanup_orphaned_ents;
1461 }
1462 if (result != ISC_R_SUCCESS) {
1463 goto failure;
1464 }
1465
1466 /*
1467 * If we find a existing NSEC3 for this chain then save the
1468 * next field.
1469 */
1470 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1471 if (result == ISC_R_SUCCESS) {
1472 next_length = nsec3.next_length;
1473 INSIST(next_length <= sizeof(nexthash));
1474 memmove(nexthash, nsec3.next, next_length);
1475 }
1476 dns_rdataset_disassociate(&rdataset);
1477 if (result == ISC_R_NOMORE) {
1478 goto success;
1479 }
1480 if (result != ISC_R_SUCCESS) {
1481 goto failure;
1482 }
1483
1484 /*
1485 * Find the previous NSEC3 and update it.
1486 */
1487 pass = 0;
1488 do {
1489 result = dns_dbiterator_prev(dbit);
1490 if (result == ISC_R_NOMORE) {
1491 pass++;
1492 CHECK(dns_dbiterator_last(dbit));
1493 }
1494 CHECK(dns_dbiterator_current(dbit, &node, prev));
1495 CHECK(dns_dbiterator_pause(dbit));
1496 result = dns_db_findrdataset(db, node, version,
1497 dns_rdatatype_nsec3, 0,
1498 (isc_stdtime_t)0, &rdataset, NULL);
1499 dns_db_detachnode(db, &node);
1500 if (result != ISC_R_SUCCESS) {
1501 continue;
1502 }
1503 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1504 if (result == ISC_R_NOMORE) {
1505 dns_rdataset_disassociate(&rdataset);
1506 continue;
1507 }
1508 if (result != ISC_R_SUCCESS) {
1509 goto failure;
1510 }
1511
1512 /*
1513 * Delete the old previous NSEC3.
1514 */
1515 CHECK(delnsec3(db, version, prev, nsec3param, diff));
1516
1517 /*
1518 * Fixup the previous NSEC3.
1519 */
1520 nsec3.next = nexthash;
1521 nsec3.next_length = (unsigned char)next_length;
1522 if (CREATE(nsec3param->flags)) {
1523 nsec3.flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
1524 }
1525 isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
1526 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
1527 dns_rdatatype_nsec3, &nsec3,
1528 &buffer));
1529 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
1530 rdataset.ttl, &rdata, &tuple));
1531 CHECK(do_one_tuple(&tuple, db, version, diff));
1532 dns_rdata_reset(&rdata);
1533 dns_rdataset_disassociate(&rdataset);
1534 break;
1535 } while (pass < 2);
1536
1537 /*
1538 * Delete the old NSEC3 and record the change.
1539 */
1540 CHECK(delnsec3(db, version, hashname, nsec3param, diff));
1541
1542 /*
1543 * Delete NSEC3 records for now non active nodes.
1544 */
1545 cleanup_orphaned_ents:
1546 dns_name_init(&empty, NULL);
1547 dns_name_clone(name, &empty);
1548 do {
1549 labels = dns_name_countlabels(&empty) - 1;
1550 if (labels <= dns_name_countlabels(origin)) {
1551 break;
1552 }
1553 dns_name_getlabelsequence(&empty, 1, labels, &empty);
1554 CHECK(deleteit(db, version, &empty, &yesno));
1555 if (!yesno) {
1556 break;
1557 }
1558
1559 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length, &empty,
1560 origin, hash, iterations, salt,
1561 salt_length));
1562 result = dns_dbiterator_seek(dbit, hashname);
1563 if (result == ISC_R_NOTFOUND || result == DNS_R_PARTIALMATCH) {
1564 goto success;
1565 }
1566 if (result != ISC_R_SUCCESS) {
1567 goto failure;
1568 }
1569
1570 CHECK(dns_dbiterator_current(dbit, &node, NULL));
1571 CHECK(dns_dbiterator_pause(dbit));
1572 result = dns_db_findrdataset(db, node, version,
1573 dns_rdatatype_nsec3, 0,
1574 (isc_stdtime_t)0, &rdataset, NULL);
1575 dns_db_detachnode(db, &node);
1576 if (result == ISC_R_NOTFOUND) {
1577 goto success;
1578 }
1579 if (result != ISC_R_SUCCESS) {
1580 goto failure;
1581 }
1582
1583 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1584 if (result == ISC_R_SUCCESS) {
1585 next_length = nsec3.next_length;
1586 INSIST(next_length <= sizeof(nexthash));
1587 memmove(nexthash, nsec3.next, next_length);
1588 }
1589 dns_rdataset_disassociate(&rdataset);
1590 if (result == ISC_R_NOMORE) {
1591 goto success;
1592 }
1593 if (result != ISC_R_SUCCESS) {
1594 goto failure;
1595 }
1596
1597 pass = 0;
1598 do {
1599 result = dns_dbiterator_prev(dbit);
1600 if (result == ISC_R_NOMORE) {
1601 pass++;
1602 CHECK(dns_dbiterator_last(dbit));
1603 }
1604 CHECK(dns_dbiterator_current(dbit, &node, prev));
1605 CHECK(dns_dbiterator_pause(dbit));
1606 result = dns_db_findrdataset(
1607 db, node, version, dns_rdatatype_nsec3, 0,
1608 (isc_stdtime_t)0, &rdataset, NULL);
1609 dns_db_detachnode(db, &node);
1610 if (result != ISC_R_SUCCESS) {
1611 continue;
1612 }
1613 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1614 if (result == ISC_R_NOMORE) {
1615 dns_rdataset_disassociate(&rdataset);
1616 continue;
1617 }
1618 if (result != ISC_R_SUCCESS) {
1619 goto failure;
1620 }
1621
1622 /*
1623 * Delete the old previous NSEC3.
1624 */
1625 CHECK(delnsec3(db, version, prev, nsec3param, diff));
1626
1627 /*
1628 * Fixup the previous NSEC3.
1629 */
1630 nsec3.next = nexthash;
1631 nsec3.next_length = (unsigned char)next_length;
1632 isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
1633 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
1634 dns_rdatatype_nsec3, &nsec3,
1635 &buffer));
1636 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1637 prev, rdataset.ttl, &rdata,
1638 &tuple));
1639 CHECK(do_one_tuple(&tuple, db, version, diff));
1640 dns_rdata_reset(&rdata);
1641 dns_rdataset_disassociate(&rdataset);
1642 break;
1643 } while (pass < 2);
1644
1645 INSIST(pass < 2);
1646
1647 /*
1648 * Delete the old NSEC3 and record the change.
1649 */
1650 CHECK(delnsec3(db, version, hashname, nsec3param, diff));
1651 } while (1);
1652
1653 success:
1654 result = ISC_R_SUCCESS;
1655
1656 failure:
1657 if (dbit != NULL) {
1658 dns_dbiterator_destroy(&dbit);
1659 }
1660 if (dns_rdataset_isassociated(&rdataset)) {
1661 dns_rdataset_disassociate(&rdataset);
1662 }
1663 if (node != NULL) {
1664 dns_db_detachnode(db, &node);
1665 }
1666 return result;
1667 }
1668
1669 isc_result_t
1670 dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version,
1671 const dns_name_t *name, dns_diff_t *diff) {
1672 return dns_nsec3_delnsec3sx(db, version, name, 0, diff);
1673 }
1674
1675 isc_result_t
1676 dns_nsec3_delnsec3sx(dns_db_t *db, dns_dbversion_t *version,
1677 const dns_name_t *name, dns_rdatatype_t privatetype,
1678 dns_diff_t *diff) {
1679 dns_dbnode_t *node = NULL;
1680 dns_rdata_nsec3param_t nsec3param;
1681 dns_rdataset_t rdataset;
1682 isc_result_t result;
1683
1684 dns_rdataset_init(&rdataset);
1685
1686 /*
1687 * Find the NSEC3 parameters for this zone.
1688 */
1689 result = dns_db_getoriginnode(db, &node);
1690 if (result != ISC_R_SUCCESS) {
1691 return result;
1692 }
1693
1694 result = dns_db_findrdataset(db, node, version,
1695 dns_rdatatype_nsec3param, 0, 0, &rdataset,
1696 NULL);
1697 if (result == ISC_R_NOTFOUND) {
1698 goto try_private;
1699 }
1700 if (result != ISC_R_SUCCESS) {
1701 goto failure;
1702 }
1703
1704 /*
1705 * Update each active NSEC3 chain.
1706 */
1707 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
1708 result = dns_rdataset_next(&rdataset))
1709 {
1710 dns_rdata_t rdata = DNS_RDATA_INIT;
1711
1712 dns_rdataset_current(&rdataset, &rdata);
1713 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
1714
1715 if (nsec3param.flags != 0) {
1716 continue;
1717 }
1718 /*
1719 * We have a active chain. Update it.
1720 */
1721 CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
1722 }
1723 dns_rdataset_disassociate(&rdataset);
1724
1725 try_private:
1726 if (privatetype == 0) {
1727 goto success;
1728 }
1729 result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
1730 &rdataset, NULL);
1731 if (result == ISC_R_NOTFOUND) {
1732 goto success;
1733 }
1734 if (result != ISC_R_SUCCESS) {
1735 goto failure;
1736 }
1737
1738 /*
1739 * Update each NSEC3 chain being built.
1740 */
1741 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
1742 result = dns_rdataset_next(&rdataset))
1743 {
1744 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1745 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1746 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1747
1748 dns_rdataset_current(&rdataset, &rdata1);
1749 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2, buf,
1750 sizeof(buf)))
1751 {
1752 continue;
1753 }
1754 CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
1755
1756 if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
1757 continue;
1758 }
1759 if (better_param(&rdataset, &rdata2)) {
1760 continue;
1761 }
1762
1763 /*
1764 * We have a active chain. Update it.
1765 */
1766 CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
1767 }
1768 if (result == ISC_R_NOMORE) {
1769 success:
1770 result = ISC_R_SUCCESS;
1771 }
1772
1773 failure:
1774 if (dns_rdataset_isassociated(&rdataset)) {
1775 dns_rdataset_disassociate(&rdataset);
1776 }
1777 if (node != NULL) {
1778 dns_db_detachnode(db, &node);
1779 }
1780
1781 return result;
1782 }
1783
1784 isc_result_t
1785 dns_nsec3_active(dns_db_t *db, dns_dbversion_t *version, bool complete,
1786 bool *answer) {
1787 return dns_nsec3_activex(db, version, complete, 0, answer);
1788 }
1789
1790 isc_result_t
1791 dns_nsec3_activex(dns_db_t *db, dns_dbversion_t *version, bool complete,
1792 dns_rdatatype_t privatetype, bool *answer) {
1793 dns_dbnode_t *node = NULL;
1794 dns_rdataset_t rdataset;
1795 dns_rdata_nsec3param_t nsec3param;
1796 isc_result_t result;
1797
1798 REQUIRE(answer != NULL);
1799
1800 dns_rdataset_init(&rdataset);
1801
1802 result = dns_db_getoriginnode(db, &node);
1803 if (result != ISC_R_SUCCESS) {
1804 return result;
1805 }
1806
1807 result = dns_db_findrdataset(db, node, version,
1808 dns_rdatatype_nsec3param, 0, 0, &rdataset,
1809 NULL);
1810
1811 if (result == ISC_R_NOTFOUND) {
1812 goto try_private;
1813 }
1814
1815 if (result != ISC_R_SUCCESS) {
1816 dns_db_detachnode(db, &node);
1817 return result;
1818 }
1819 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
1820 result = dns_rdataset_next(&rdataset))
1821 {
1822 dns_rdata_t rdata = DNS_RDATA_INIT;
1823
1824 dns_rdataset_current(&rdataset, &rdata);
1825 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
1826 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1827
1828 if (nsec3param.flags == 0) {
1829 break;
1830 }
1831 }
1832 dns_rdataset_disassociate(&rdataset);
1833 if (result == ISC_R_SUCCESS) {
1834 dns_db_detachnode(db, &node);
1835 *answer = true;
1836 return ISC_R_SUCCESS;
1837 }
1838 if (result == ISC_R_NOMORE) {
1839 *answer = false;
1840 }
1841
1842 try_private:
1843 if (privatetype == 0 || complete) {
1844 dns_db_detachnode(db, &node);
1845 *answer = false;
1846 return ISC_R_SUCCESS;
1847 }
1848 result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
1849 &rdataset, NULL);
1850
1851 dns_db_detachnode(db, &node);
1852 if (result == ISC_R_NOTFOUND) {
1853 *answer = false;
1854 return ISC_R_SUCCESS;
1855 }
1856 if (result != ISC_R_SUCCESS) {
1857 return result;
1858 }
1859
1860 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
1861 result = dns_rdataset_next(&rdataset))
1862 {
1863 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1864 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1865 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1866
1867 dns_rdataset_current(&rdataset, &rdata1);
1868 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2, buf,
1869 sizeof(buf)))
1870 {
1871 continue;
1872 }
1873 result = dns_rdata_tostruct(&rdata2, &nsec3param, NULL);
1874 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1875
1876 if (!complete && CREATE(nsec3param.flags)) {
1877 break;
1878 }
1879 }
1880 dns_rdataset_disassociate(&rdataset);
1881 if (result == ISC_R_SUCCESS) {
1882 *answer = true;
1883 result = ISC_R_SUCCESS;
1884 }
1885 if (result == ISC_R_NOMORE) {
1886 *answer = false;
1887 result = ISC_R_SUCCESS;
1888 }
1889
1890 return result;
1891 }
1892
1893 unsigned int
1894 dns_nsec3_maxiterations(void) {
1895 return DNS_NSEC3_MAXITERATIONS;
1896 }
1897
1898 isc_result_t
1899 dns_nsec3_noexistnodata(dns_rdatatype_t type, const dns_name_t *name,
1900 const dns_name_t *nsec3name, dns_rdataset_t *nsec3set,
1901 dns_name_t *zonename, bool *exists, bool *data,
1902 bool *optout, bool *unknown, bool *setclosest,
1903 bool *setnearest, dns_name_t *closest,
1904 dns_name_t *nearest, dns_nseclog_t logit, void *arg) {
1905 char namebuf[DNS_NAME_FORMATSIZE];
1906 dns_fixedname_t fzone;
1907 dns_fixedname_t qfixed;
1908 dns_label_t hashlabel;
1909 dns_name_t *qname;
1910 dns_name_t *zone;
1911 dns_rdata_nsec3_t nsec3;
1912 dns_rdata_t rdata = DNS_RDATA_INIT;
1913 int order;
1914 int scope;
1915 bool atparent;
1916 bool first;
1917 bool ns;
1918 bool soa;
1919 isc_buffer_t buffer;
1920 isc_result_t answer = ISC_R_IGNORE;
1921 isc_result_t result;
1922 unsigned char hash[NSEC3_MAX_HASH_LENGTH];
1923 unsigned char owner[NSEC3_MAX_HASH_LENGTH];
1924 unsigned int length;
1925 unsigned int qlabels;
1926 unsigned int zlabels;
1927
1928 REQUIRE((exists == NULL && data == NULL) ||
1929 (exists != NULL && data != NULL));
1930 REQUIRE(nsec3set != NULL && nsec3set->type == dns_rdatatype_nsec3);
1931 REQUIRE((setclosest == NULL && closest == NULL) ||
1932 (setclosest != NULL && closest != NULL));
1933 REQUIRE((setnearest == NULL && nearest == NULL) ||
1934 (setnearest != NULL && nearest != NULL));
1935
1936 result = dns_rdataset_first(nsec3set);
1937 if (result != ISC_R_SUCCESS) {
1938 (*logit)(arg, ISC_LOG_DEBUG(3), "failure processing NSEC3 set");
1939 return result;
1940 }
1941
1942 dns_rdataset_current(nsec3set, &rdata);
1943
1944 result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
1945 if (result != ISC_R_SUCCESS) {
1946 return result;
1947 }
1948
1949 (*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant NSEC3");
1950
1951 zone = dns_fixedname_initname(&fzone);
1952 zlabels = dns_name_countlabels(nsec3name);
1953
1954 /*
1955 * NSEC3 records must have two or more labels to be valid.
1956 */
1957 if (zlabels < 2) {
1958 return ISC_R_IGNORE;
1959 }
1960
1961 /*
1962 * Strip off the NSEC3 hash to get the zone.
1963 */
1964 zlabels--;
1965 dns_name_split(nsec3name, zlabels, NULL, zone);
1966
1967 /*
1968 * If not below the zone name we can ignore this record.
1969 */
1970 if (!dns_name_issubdomain(name, zone)) {
1971 return ISC_R_IGNORE;
1972 }
1973
1974 /*
1975 * Is this zone the same or deeper than the current zone?
1976 */
1977 if (dns_name_countlabels(zonename) == 0 ||
1978 dns_name_issubdomain(zone, zonename))
1979 {
1980 dns_name_copy(zone, zonename);
1981 }
1982
1983 if (!dns_name_equal(zone, zonename)) {
1984 return ISC_R_IGNORE;
1985 }
1986
1987 /*
1988 * Are we only looking for the most enclosing zone?
1989 */
1990 if (exists == NULL || data == NULL) {
1991 return ISC_R_SUCCESS;
1992 }
1993
1994 /*
1995 * Only set unknown once we are sure that this NSEC3 is from
1996 * the deepest covering zone.
1997 */
1998 if (!dns_nsec3_supportedhash(nsec3.hash)) {
1999 if (unknown != NULL) {
2000 *unknown = true;
2001 }
2002 return ISC_R_IGNORE;
2003 }
2004
2005 /*
2006 * Recover the hash from the first label.
2007 */
2008 dns_name_getlabel(nsec3name, 0, &hashlabel);
2009 isc_region_consume(&hashlabel, 1);
2010 isc_buffer_init(&buffer, owner, sizeof(owner));
2011 result = isc_base32hex_decoderegion(&hashlabel, &buffer);
2012 if (result != ISC_R_SUCCESS) {
2013 return result;
2014 }
2015
2016 /*
2017 * The hash lengths should match. If not ignore the record.
2018 */
2019 if (isc_buffer_usedlength(&buffer) != nsec3.next_length) {
2020 return ISC_R_IGNORE;
2021 }
2022
2023 /*
2024 * Work out what this NSEC3 covers.
2025 * Inside (<0) or outside (>=0).
2026 */
2027 scope = memcmp(owner, nsec3.next, nsec3.next_length);
2028
2029 /*
2030 * Prepare to compute all the hashes.
2031 */
2032 qname = dns_fixedname_initname(&qfixed);
2033 dns_name_downcase(name, qname, NULL);
2034 qlabels = dns_name_countlabels(qname);
2035 first = true;
2036
2037 while (qlabels >= zlabels) {
2038 /*
2039 * If there are too many iterations reject the NSEC3 record.
2040 */
2041 if (nsec3.iterations > DNS_NSEC3_MAXITERATIONS) {
2042 return DNS_R_NSEC3ITERRANGE;
2043 }
2044
2045 length = isc_iterated_hash(hash, nsec3.hash, nsec3.iterations,
2046 nsec3.salt, nsec3.salt_length,
2047 qname->ndata, qname->length);
2048 /*
2049 * The computed hash length should match.
2050 */
2051 if (length != nsec3.next_length) {
2052 (*logit)(arg, ISC_LOG_DEBUG(3),
2053 "ignoring NSEC bad length %u vs %u", length,
2054 nsec3.next_length);
2055 return ISC_R_IGNORE;
2056 }
2057
2058 order = memcmp(hash, owner, length);
2059 if (first && order == 0) {
2060 /*
2061 * The hashes are the same.
2062 */
2063 atparent = dns_rdatatype_atparent(type);
2064 ns = dns_nsec3_typepresent(&rdata, dns_rdatatype_ns);
2065 soa = dns_nsec3_typepresent(&rdata, dns_rdatatype_soa);
2066 if (ns && !soa) {
2067 if (!atparent) {
2068 /*
2069 * This NSEC3 record is from somewhere
2070 * higher in the DNS, and at the
2071 * parent of a delegation. It can not
2072 * be legitimately used here.
2073 */
2074 (*logit)(arg, ISC_LOG_DEBUG(3),
2075 "ignoring parent NSEC3");
2076 return ISC_R_IGNORE;
2077 }
2078 } else if (atparent && ns && soa) {
2079 /*
2080 * This NSEC3 record is from the child.
2081 * It can not be legitimately used here.
2082 */
2083 (*logit)(arg, ISC_LOG_DEBUG(3),
2084 "ignoring child NSEC3");
2085 return ISC_R_IGNORE;
2086 }
2087 if (type == dns_rdatatype_cname ||
2088 type == dns_rdatatype_nxt ||
2089 type == dns_rdatatype_nsec ||
2090 type == dns_rdatatype_key ||
2091 !dns_nsec3_typepresent(&rdata, dns_rdatatype_cname))
2092 {
2093 *exists = true;
2094 *data = dns_nsec3_typepresent(&rdata, type);
2095 (*logit)(arg, ISC_LOG_DEBUG(3),
2096 "NSEC3 proves name exists (owner) "
2097 "data=%d",
2098 *data);
2099 return ISC_R_SUCCESS;
2100 }
2101 (*logit)(arg, ISC_LOG_DEBUG(3),
2102 "NSEC3 proves CNAME exists");
2103 return ISC_R_IGNORE;
2104 }
2105
2106 if (order == 0 &&
2107 dns_nsec3_typepresent(&rdata, dns_rdatatype_ns) &&
2108 !dns_nsec3_typepresent(&rdata, dns_rdatatype_soa))
2109 {
2110 /*
2111 * This NSEC3 record is from somewhere higher in
2112 * the DNS, and at the parent of a delegation.
2113 * It can not be legitimately used here.
2114 */
2115 (*logit)(arg, ISC_LOG_DEBUG(3),
2116 "ignoring parent NSEC3");
2117 return ISC_R_IGNORE;
2118 }
2119
2120 /*
2121 * Potential closest encloser.
2122 */
2123 if (order == 0) {
2124 if (closest != NULL &&
2125 (dns_name_countlabels(closest) == 0 ||
2126 dns_name_issubdomain(qname, closest)) &&
2127 !dns_nsec3_typepresent(&rdata, dns_rdatatype_ds) &&
2128 !dns_nsec3_typepresent(&rdata,
2129 dns_rdatatype_dname) &&
2130 (dns_nsec3_typepresent(&rdata, dns_rdatatype_soa) ||
2131 !dns_nsec3_typepresent(&rdata, dns_rdatatype_ns)))
2132 {
2133 dns_name_format(qname, namebuf,
2134 sizeof(namebuf));
2135 (*logit)(arg, ISC_LOG_DEBUG(3),
2136 "NSEC3 indicates potential closest "
2137 "encloser: '%s'",
2138 namebuf);
2139 dns_name_copy(qname, closest);
2140 *setclosest = true;
2141 }
2142 dns_name_format(qname, namebuf, sizeof(namebuf));
2143 (*logit)(arg, ISC_LOG_DEBUG(3),
2144 "NSEC3 at super-domain %s", namebuf);
2145 return answer;
2146 }
2147
2148 /*
2149 * Find if the name does not exist.
2150 *
2151 * We continue as we need to find the name closest to the
2152 * closest encloser that doesn't exist.
2153 *
2154 * We also need to continue to ensure that we are not
2155 * proving the non-existence of a record in a sub-zone.
2156 * If that would be the case we will return ISC_R_IGNORE
2157 * above.
2158 */
2159 if ((scope < 0 && order > 0 &&
2160 memcmp(hash, nsec3.next, length) < 0) ||
2161 (scope >= 0 &&
2162 (order > 0 || memcmp(hash, nsec3.next, length) < 0)))
2163 {
2164 dns_name_format(qname, namebuf, sizeof(namebuf));
2165 (*logit)(arg, ISC_LOG_DEBUG(3),
2166 "NSEC3 proves "
2167 "name does not exist: '%s'",
2168 namebuf);
2169 if (nearest != NULL &&
2170 (dns_name_countlabels(nearest) == 0 ||
2171 dns_name_issubdomain(nearest, qname)))
2172 {
2173 dns_name_copy(qname, nearest);
2174 *setnearest = true;
2175 }
2176
2177 *exists = false;
2178 *data = false;
2179 if (optout != NULL) {
2180 *optout = ((nsec3.flags &
2181 DNS_NSEC3FLAG_OPTOUT) != 0);
2182 (*logit)(arg, ISC_LOG_DEBUG(3),
2183 *optout ? "NSEC3 indicates optout"
2184 : "NSEC3 indicates secure "
2185 "range");
2186 }
2187 answer = ISC_R_SUCCESS;
2188 }
2189
2190 qlabels--;
2191 if (qlabels > 0) {
2192 dns_name_split(qname, qlabels, NULL, qname);
2193 }
2194 first = false;
2195 }
2196 return answer;
2197 }
2198