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