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