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