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