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