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