Home | History | Annotate | Line # | Download | only in dns
nsec3.c revision 1.11
      1 /*	$NetBSD: nsec3.c,v 1.11 2023/01/25 21:43:30 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/safe.h>
     26 #include <isc/string.h>
     27 #include <isc/util.h>
     28 
     29 #include <dns/compress.h>
     30 #include <dns/db.h>
     31 #include <dns/dbiterator.h>
     32 #include <dns/diff.h>
     33 #include <dns/fixedname.h>
     34 #include <dns/nsec.h>
     35 #include <dns/nsec3.h>
     36 #include <dns/rdata.h>
     37 #include <dns/rdatalist.h>
     38 #include <dns/rdataset.h>
     39 #include <dns/rdatasetiter.h>
     40 #include <dns/rdatastruct.h>
     41 #include <dns/result.h>
     42 #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 
   1144 		CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
   1145 					   rdataset.ttl, &rdata, &tuple));
   1146 		CHECK(do_one_tuple(&tuple, db, ver, diff));
   1147 		INSIST(tuple == NULL);
   1148 
   1149 		dns_nsec3param_toprivate(&rdata, &private, privatetype, buf,
   1150 					 sizeof(buf));
   1151 		buf[2] = DNS_NSEC3FLAG_REMOVE;
   1152 		if (nonsec) {
   1153 			buf[2] |= DNS_NSEC3FLAG_NONSEC;
   1154 		}
   1155 
   1156 		CHECK(rr_exists(db, ver, origin, &private, &flag));
   1157 
   1158 		if (!flag) {
   1159 			CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
   1160 						   origin, 0, &private,
   1161 						   &tuple));
   1162 			CHECK(do_one_tuple(&tuple, db, ver, diff));
   1163 			INSIST(tuple == NULL);
   1164 		}
   1165 		dns_rdata_reset(&rdata);
   1166 	}
   1167 	if (result != ISC_R_NOMORE) {
   1168 		goto failure;
   1169 	}
   1170 
   1171 	dns_rdataset_disassociate(&rdataset);
   1172 
   1173 try_private:
   1174 	if (privatetype == 0) {
   1175 		goto success;
   1176 	}
   1177 	result = dns_db_findrdataset(db, node, ver, privatetype, 0,
   1178 				     (isc_stdtime_t)0, &rdataset, NULL);
   1179 	if (result == ISC_R_NOTFOUND) {
   1180 		goto success;
   1181 	}
   1182 	if (result != ISC_R_SUCCESS) {
   1183 		goto failure;
   1184 	}
   1185 
   1186 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   1187 	     result = dns_rdataset_next(&rdataset))
   1188 	{
   1189 		dns_rdata_reset(&rdata);
   1190 		dns_rdataset_current(&rdataset, &rdata);
   1191 		INSIST(rdata.length <= sizeof(buf));
   1192 		memmove(buf, rdata.data, rdata.length);
   1193 
   1194 		/*
   1195 		 * Private NSEC3 record length >= 6.
   1196 		 * <0(1), hash(1), flags(1), iterations(2), saltlen(1)>
   1197 		 */
   1198 		if (rdata.length < 6 || buf[0] != 0 ||
   1199 		    (buf[2] & DNS_NSEC3FLAG_REMOVE) != 0 ||
   1200 		    (nonsec && (buf[2] & DNS_NSEC3FLAG_NONSEC) != 0))
   1201 		{
   1202 			continue;
   1203 		}
   1204 
   1205 		CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
   1206 					   0, &rdata, &tuple));
   1207 		CHECK(do_one_tuple(&tuple, db, ver, diff));
   1208 		INSIST(tuple == NULL);
   1209 
   1210 		rdata.data = buf;
   1211 		buf[2] = DNS_NSEC3FLAG_REMOVE;
   1212 		if (nonsec) {
   1213 			buf[2] |= DNS_NSEC3FLAG_NONSEC;
   1214 		}
   1215 
   1216 		CHECK(rr_exists(db, ver, origin, &rdata, &flag));
   1217 
   1218 		if (!flag) {
   1219 			CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
   1220 						   origin, 0, &rdata, &tuple));
   1221 			CHECK(do_one_tuple(&tuple, db, ver, diff));
   1222 			INSIST(tuple == NULL);
   1223 		}
   1224 	}
   1225 	if (result != ISC_R_NOMORE) {
   1226 		goto failure;
   1227 	}
   1228 success:
   1229 	result = ISC_R_SUCCESS;
   1230 
   1231 failure:
   1232 	if (dns_rdataset_isassociated(&rdataset)) {
   1233 		dns_rdataset_disassociate(&rdataset);
   1234 	}
   1235 	dns_db_detachnode(db, &node);
   1236 	return (result);
   1237 }
   1238 
   1239 isc_result_t
   1240 dns_nsec3_addnsec3sx(dns_db_t *db, dns_dbversion_t *version,
   1241 		     const dns_name_t *name, dns_ttl_t nsecttl, bool unsecure,
   1242 		     dns_rdatatype_t type, dns_diff_t *diff) {
   1243 	dns_dbnode_t *node = NULL;
   1244 	dns_rdata_nsec3param_t nsec3param;
   1245 	dns_rdataset_t rdataset;
   1246 	dns_rdataset_t prdataset;
   1247 	isc_result_t result;
   1248 
   1249 	dns_rdataset_init(&rdataset);
   1250 	dns_rdataset_init(&prdataset);
   1251 
   1252 	/*
   1253 	 * Find the NSEC3 parameters for this zone.
   1254 	 */
   1255 	result = dns_db_getoriginnode(db, &node);
   1256 	if (result != ISC_R_SUCCESS) {
   1257 		return (result);
   1258 	}
   1259 
   1260 	result = dns_db_findrdataset(db, node, version, type, 0, 0, &prdataset,
   1261 				     NULL);
   1262 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   1263 		goto failure;
   1264 	}
   1265 
   1266 	result = dns_db_findrdataset(db, node, version,
   1267 				     dns_rdatatype_nsec3param, 0, 0, &rdataset,
   1268 				     NULL);
   1269 	if (result == ISC_R_NOTFOUND) {
   1270 		goto try_private;
   1271 	}
   1272 	if (result != ISC_R_SUCCESS) {
   1273 		goto failure;
   1274 	}
   1275 
   1276 	/*
   1277 	 * Update each active NSEC3 chain.
   1278 	 */
   1279 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   1280 	     result = dns_rdataset_next(&rdataset))
   1281 	{
   1282 		dns_rdata_t rdata = DNS_RDATA_INIT;
   1283 
   1284 		dns_rdataset_current(&rdataset, &rdata);
   1285 		CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
   1286 
   1287 		if (nsec3param.flags != 0) {
   1288 			continue;
   1289 		}
   1290 
   1291 		/*
   1292 		 * We have a active chain.  Update it.
   1293 		 */
   1294 		CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
   1295 					 nsecttl, unsecure, diff));
   1296 	}
   1297 	if (result != ISC_R_NOMORE) {
   1298 		goto failure;
   1299 	}
   1300 
   1301 	dns_rdataset_disassociate(&rdataset);
   1302 
   1303 try_private:
   1304 	if (!dns_rdataset_isassociated(&prdataset)) {
   1305 		goto success;
   1306 	}
   1307 	/*
   1308 	 * Update each active NSEC3 chain.
   1309 	 */
   1310 	for (result = dns_rdataset_first(&prdataset); result == ISC_R_SUCCESS;
   1311 	     result = dns_rdataset_next(&prdataset))
   1312 	{
   1313 		dns_rdata_t rdata1 = DNS_RDATA_INIT;
   1314 		dns_rdata_t rdata2 = DNS_RDATA_INIT;
   1315 		unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   1316 
   1317 		dns_rdataset_current(&prdataset, &rdata1);
   1318 		if (!dns_nsec3param_fromprivate(&rdata1, &rdata2, buf,
   1319 						sizeof(buf)))
   1320 		{
   1321 			continue;
   1322 		}
   1323 		CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
   1324 
   1325 		if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
   1326 			continue;
   1327 		}
   1328 		if (better_param(&prdataset, &rdata2)) {
   1329 			continue;
   1330 		}
   1331 
   1332 		/*
   1333 		 * We have a active chain.  Update it.
   1334 		 */
   1335 		CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
   1336 					 nsecttl, unsecure, diff));
   1337 	}
   1338 	if (result == ISC_R_NOMORE) {
   1339 	success:
   1340 		result = ISC_R_SUCCESS;
   1341 	}
   1342 failure:
   1343 	if (dns_rdataset_isassociated(&rdataset)) {
   1344 		dns_rdataset_disassociate(&rdataset);
   1345 	}
   1346 	if (dns_rdataset_isassociated(&prdataset)) {
   1347 		dns_rdataset_disassociate(&prdataset);
   1348 	}
   1349 	if (node != NULL) {
   1350 		dns_db_detachnode(db, &node);
   1351 	}
   1352 
   1353 	return (result);
   1354 }
   1355 
   1356 /*%
   1357  * Determine whether any NSEC3 records that were associated with
   1358  * 'name' should be deleted or if they should continue to exist.
   1359  * true indicates they should be deleted.
   1360  * false indicates they should be retained.
   1361  */
   1362 static isc_result_t
   1363 deleteit(dns_db_t *db, dns_dbversion_t *ver, const dns_name_t *name,
   1364 	 bool *yesno) {
   1365 	isc_result_t result;
   1366 	dns_fixedname_t foundname;
   1367 	dns_fixedname_init(&foundname);
   1368 
   1369 	result = dns_db_find(db, name, ver, dns_rdatatype_any,
   1370 			     DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD,
   1371 			     (isc_stdtime_t)0, NULL,
   1372 			     dns_fixedname_name(&foundname), NULL, NULL);
   1373 	if (result == DNS_R_EMPTYNAME || result == ISC_R_SUCCESS ||
   1374 	    result == DNS_R_ZONECUT)
   1375 	{
   1376 		*yesno = false;
   1377 		return (ISC_R_SUCCESS);
   1378 	}
   1379 	if (result == DNS_R_GLUE || result == DNS_R_DNAME ||
   1380 	    result == DNS_R_DELEGATION || result == DNS_R_NXDOMAIN)
   1381 	{
   1382 		*yesno = true;
   1383 		return (ISC_R_SUCCESS);
   1384 	}
   1385 	/*
   1386 	 * Silence compiler.
   1387 	 */
   1388 	*yesno = true;
   1389 	return (result);
   1390 }
   1391 
   1392 isc_result_t
   1393 dns_nsec3_delnsec3(dns_db_t *db, dns_dbversion_t *version,
   1394 		   const dns_name_t *name,
   1395 		   const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff) {
   1396 	dns_dbiterator_t *dbit = NULL;
   1397 	dns_dbnode_t *node = NULL;
   1398 	dns_difftuple_t *tuple = NULL;
   1399 	dns_fixedname_t fixed;
   1400 	dns_fixedname_t fprev;
   1401 	dns_hash_t hash;
   1402 	dns_name_t *hashname;
   1403 	dns_name_t *origin;
   1404 	dns_name_t *prev;
   1405 	dns_name_t empty;
   1406 	dns_rdata_nsec3_t nsec3;
   1407 	dns_rdata_t rdata = DNS_RDATA_INIT;
   1408 	dns_rdataset_t rdataset;
   1409 	int pass;
   1410 	bool yesno;
   1411 	isc_buffer_t buffer;
   1412 	isc_result_t result;
   1413 	unsigned char *salt;
   1414 	unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
   1415 	unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
   1416 	unsigned int iterations;
   1417 	unsigned int labels;
   1418 	size_t next_length;
   1419 	unsigned int salt_length;
   1420 
   1421 	hashname = dns_fixedname_initname(&fixed);
   1422 	prev = dns_fixedname_initname(&fprev);
   1423 
   1424 	dns_rdataset_init(&rdataset);
   1425 
   1426 	origin = dns_db_origin(db);
   1427 
   1428 	/*
   1429 	 * Chain parameters.
   1430 	 */
   1431 	hash = nsec3param->hash;
   1432 	iterations = nsec3param->iterations;
   1433 	salt_length = nsec3param->salt_length;
   1434 	salt = nsec3param->salt;
   1435 
   1436 	/*
   1437 	 * If this is the first NSEC3 in the chain nexthash will
   1438 	 * remain pointing to itself.
   1439 	 */
   1440 	next_length = sizeof(nexthash);
   1441 	CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length, name, origin,
   1442 				 hash, iterations, salt, salt_length));
   1443 
   1444 	CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
   1445 
   1446 	result = dns_dbiterator_seek(dbit, hashname);
   1447 	if (result == ISC_R_NOTFOUND || result == DNS_R_PARTIALMATCH) {
   1448 		goto success;
   1449 	}
   1450 	if (result != ISC_R_SUCCESS) {
   1451 		goto failure;
   1452 	}
   1453 
   1454 	CHECK(dns_dbiterator_current(dbit, &node, NULL));
   1455 	CHECK(dns_dbiterator_pause(dbit));
   1456 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, 0,
   1457 				     (isc_stdtime_t)0, &rdataset, NULL);
   1458 	dns_db_detachnode(db, &node);
   1459 	if (result == ISC_R_NOTFOUND) {
   1460 		goto success;
   1461 	}
   1462 	if (result != ISC_R_SUCCESS) {
   1463 		goto failure;
   1464 	}
   1465 
   1466 	/*
   1467 	 * If we find a existing NSEC3 for this chain then save the
   1468 	 * next field.
   1469 	 */
   1470 	result = find_nsec3(&nsec3, &rdataset, nsec3param);
   1471 	if (result == ISC_R_SUCCESS) {
   1472 		next_length = nsec3.next_length;
   1473 		INSIST(next_length <= sizeof(nexthash));
   1474 		memmove(nexthash, nsec3.next, next_length);
   1475 	}
   1476 	dns_rdataset_disassociate(&rdataset);
   1477 	if (result == ISC_R_NOMORE) {
   1478 		goto success;
   1479 	}
   1480 	if (result != ISC_R_SUCCESS) {
   1481 		goto failure;
   1482 	}
   1483 
   1484 	/*
   1485 	 * Find the previous NSEC3 and update it.
   1486 	 */
   1487 	pass = 0;
   1488 	do {
   1489 		result = dns_dbiterator_prev(dbit);
   1490 		if (result == ISC_R_NOMORE) {
   1491 			pass++;
   1492 			CHECK(dns_dbiterator_last(dbit));
   1493 		}
   1494 		CHECK(dns_dbiterator_current(dbit, &node, prev));
   1495 		CHECK(dns_dbiterator_pause(dbit));
   1496 		result = dns_db_findrdataset(db, node, version,
   1497 					     dns_rdatatype_nsec3, 0,
   1498 					     (isc_stdtime_t)0, &rdataset, NULL);
   1499 		dns_db_detachnode(db, &node);
   1500 		if (result != ISC_R_SUCCESS) {
   1501 			continue;
   1502 		}
   1503 		result = find_nsec3(&nsec3, &rdataset, nsec3param);
   1504 		if (result == ISC_R_NOMORE) {
   1505 			dns_rdataset_disassociate(&rdataset);
   1506 			continue;
   1507 		}
   1508 		if (result != ISC_R_SUCCESS) {
   1509 			goto failure;
   1510 		}
   1511 
   1512 		/*
   1513 		 * Delete the old previous NSEC3.
   1514 		 */
   1515 		CHECK(delnsec3(db, version, prev, nsec3param, diff));
   1516 
   1517 		/*
   1518 		 * Fixup the previous NSEC3.
   1519 		 */
   1520 		nsec3.next = nexthash;
   1521 		nsec3.next_length = (unsigned char)next_length;
   1522 		if (CREATE(nsec3param->flags)) {
   1523 			nsec3.flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
   1524 		}
   1525 		isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
   1526 		CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
   1527 					   dns_rdatatype_nsec3, &nsec3,
   1528 					   &buffer));
   1529 		CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
   1530 					   rdataset.ttl, &rdata, &tuple));
   1531 		CHECK(do_one_tuple(&tuple, db, version, diff));
   1532 		dns_rdata_reset(&rdata);
   1533 		dns_rdataset_disassociate(&rdataset);
   1534 		break;
   1535 	} while (pass < 2);
   1536 
   1537 	/*
   1538 	 * Delete the old NSEC3 and record the change.
   1539 	 */
   1540 	CHECK(delnsec3(db, version, hashname, nsec3param, diff));
   1541 
   1542 	/*
   1543 	 *  Delete NSEC3 records for now non active nodes.
   1544 	 */
   1545 	dns_name_init(&empty, NULL);
   1546 	dns_name_clone(name, &empty);
   1547 	do {
   1548 		labels = dns_name_countlabels(&empty) - 1;
   1549 		if (labels <= dns_name_countlabels(origin)) {
   1550 			break;
   1551 		}
   1552 		dns_name_getlabelsequence(&empty, 1, labels, &empty);
   1553 		CHECK(deleteit(db, version, &empty, &yesno));
   1554 		if (!yesno) {
   1555 			break;
   1556 		}
   1557 
   1558 		CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length, &empty,
   1559 					 origin, hash, iterations, salt,
   1560 					 salt_length));
   1561 		result = dns_dbiterator_seek(dbit, hashname);
   1562 		if (result == ISC_R_NOTFOUND || result == DNS_R_PARTIALMATCH) {
   1563 			goto success;
   1564 		}
   1565 		if (result != ISC_R_SUCCESS) {
   1566 			goto failure;
   1567 		}
   1568 
   1569 		CHECK(dns_dbiterator_current(dbit, &node, NULL));
   1570 		CHECK(dns_dbiterator_pause(dbit));
   1571 		result = dns_db_findrdataset(db, node, version,
   1572 					     dns_rdatatype_nsec3, 0,
   1573 					     (isc_stdtime_t)0, &rdataset, NULL);
   1574 		dns_db_detachnode(db, &node);
   1575 		if (result == ISC_R_NOTFOUND) {
   1576 			goto success;
   1577 		}
   1578 		if (result != ISC_R_SUCCESS) {
   1579 			goto failure;
   1580 		}
   1581 
   1582 		result = find_nsec3(&nsec3, &rdataset, nsec3param);
   1583 		if (result == ISC_R_SUCCESS) {
   1584 			next_length = nsec3.next_length;
   1585 			INSIST(next_length <= sizeof(nexthash));
   1586 			memmove(nexthash, nsec3.next, next_length);
   1587 		}
   1588 		dns_rdataset_disassociate(&rdataset);
   1589 		if (result == ISC_R_NOMORE) {
   1590 			goto success;
   1591 		}
   1592 		if (result != ISC_R_SUCCESS) {
   1593 			goto failure;
   1594 		}
   1595 
   1596 		pass = 0;
   1597 		do {
   1598 			result = dns_dbiterator_prev(dbit);
   1599 			if (result == ISC_R_NOMORE) {
   1600 				pass++;
   1601 				CHECK(dns_dbiterator_last(dbit));
   1602 			}
   1603 			CHECK(dns_dbiterator_current(dbit, &node, prev));
   1604 			CHECK(dns_dbiterator_pause(dbit));
   1605 			result = dns_db_findrdataset(
   1606 				db, node, version, dns_rdatatype_nsec3, 0,
   1607 				(isc_stdtime_t)0, &rdataset, NULL);
   1608 			dns_db_detachnode(db, &node);
   1609 			if (result != ISC_R_SUCCESS) {
   1610 				continue;
   1611 			}
   1612 			result = find_nsec3(&nsec3, &rdataset, nsec3param);
   1613 			if (result == ISC_R_NOMORE) {
   1614 				dns_rdataset_disassociate(&rdataset);
   1615 				continue;
   1616 			}
   1617 			if (result != ISC_R_SUCCESS) {
   1618 				goto failure;
   1619 			}
   1620 
   1621 			/*
   1622 			 * Delete the old previous NSEC3.
   1623 			 */
   1624 			CHECK(delnsec3(db, version, prev, nsec3param, diff));
   1625 
   1626 			/*
   1627 			 * Fixup the previous NSEC3.
   1628 			 */
   1629 			nsec3.next = nexthash;
   1630 			nsec3.next_length = (unsigned char)next_length;
   1631 			isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
   1632 			CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
   1633 						   dns_rdatatype_nsec3, &nsec3,
   1634 						   &buffer));
   1635 			CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
   1636 						   prev, rdataset.ttl, &rdata,
   1637 						   &tuple));
   1638 			CHECK(do_one_tuple(&tuple, db, version, diff));
   1639 			dns_rdata_reset(&rdata);
   1640 			dns_rdataset_disassociate(&rdataset);
   1641 			break;
   1642 		} while (pass < 2);
   1643 
   1644 		INSIST(pass < 2);
   1645 
   1646 		/*
   1647 		 * Delete the old NSEC3 and record the change.
   1648 		 */
   1649 		CHECK(delnsec3(db, version, hashname, nsec3param, diff));
   1650 	} while (1);
   1651 
   1652 success:
   1653 	result = ISC_R_SUCCESS;
   1654 
   1655 failure:
   1656 	if (dbit != NULL) {
   1657 		dns_dbiterator_destroy(&dbit);
   1658 	}
   1659 	if (dns_rdataset_isassociated(&rdataset)) {
   1660 		dns_rdataset_disassociate(&rdataset);
   1661 	}
   1662 	if (node != NULL) {
   1663 		dns_db_detachnode(db, &node);
   1664 	}
   1665 	return (result);
   1666 }
   1667 
   1668 isc_result_t
   1669 dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version,
   1670 		    const dns_name_t *name, dns_diff_t *diff) {
   1671 	return (dns_nsec3_delnsec3sx(db, version, name, 0, diff));
   1672 }
   1673 
   1674 isc_result_t
   1675 dns_nsec3_delnsec3sx(dns_db_t *db, dns_dbversion_t *version,
   1676 		     const dns_name_t *name, dns_rdatatype_t privatetype,
   1677 		     dns_diff_t *diff) {
   1678 	dns_dbnode_t *node = NULL;
   1679 	dns_rdata_nsec3param_t nsec3param;
   1680 	dns_rdataset_t rdataset;
   1681 	isc_result_t result;
   1682 
   1683 	dns_rdataset_init(&rdataset);
   1684 
   1685 	/*
   1686 	 * Find the NSEC3 parameters for this zone.
   1687 	 */
   1688 	result = dns_db_getoriginnode(db, &node);
   1689 	if (result != ISC_R_SUCCESS) {
   1690 		return (result);
   1691 	}
   1692 
   1693 	result = dns_db_findrdataset(db, node, version,
   1694 				     dns_rdatatype_nsec3param, 0, 0, &rdataset,
   1695 				     NULL);
   1696 	if (result == ISC_R_NOTFOUND) {
   1697 		goto try_private;
   1698 	}
   1699 	if (result != ISC_R_SUCCESS) {
   1700 		goto failure;
   1701 	}
   1702 
   1703 	/*
   1704 	 * Update each active NSEC3 chain.
   1705 	 */
   1706 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   1707 	     result = dns_rdataset_next(&rdataset))
   1708 	{
   1709 		dns_rdata_t rdata = DNS_RDATA_INIT;
   1710 
   1711 		dns_rdataset_current(&rdataset, &rdata);
   1712 		CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
   1713 
   1714 		if (nsec3param.flags != 0) {
   1715 			continue;
   1716 		}
   1717 		/*
   1718 		 * We have a active chain.  Update it.
   1719 		 */
   1720 		CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
   1721 	}
   1722 	dns_rdataset_disassociate(&rdataset);
   1723 
   1724 try_private:
   1725 	if (privatetype == 0) {
   1726 		goto success;
   1727 	}
   1728 	result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
   1729 				     &rdataset, NULL);
   1730 	if (result == ISC_R_NOTFOUND) {
   1731 		goto success;
   1732 	}
   1733 	if (result != ISC_R_SUCCESS) {
   1734 		goto failure;
   1735 	}
   1736 
   1737 	/*
   1738 	 * Update each NSEC3 chain being built.
   1739 	 */
   1740 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   1741 	     result = dns_rdataset_next(&rdataset))
   1742 	{
   1743 		dns_rdata_t rdata1 = DNS_RDATA_INIT;
   1744 		dns_rdata_t rdata2 = DNS_RDATA_INIT;
   1745 		unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   1746 
   1747 		dns_rdataset_current(&rdataset, &rdata1);
   1748 		if (!dns_nsec3param_fromprivate(&rdata1, &rdata2, buf,
   1749 						sizeof(buf)))
   1750 		{
   1751 			continue;
   1752 		}
   1753 		CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
   1754 
   1755 		if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
   1756 			continue;
   1757 		}
   1758 		if (better_param(&rdataset, &rdata2)) {
   1759 			continue;
   1760 		}
   1761 
   1762 		/*
   1763 		 * We have a active chain.  Update it.
   1764 		 */
   1765 		CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
   1766 	}
   1767 	if (result == ISC_R_NOMORE) {
   1768 	success:
   1769 		result = ISC_R_SUCCESS;
   1770 	}
   1771 
   1772 failure:
   1773 	if (dns_rdataset_isassociated(&rdataset)) {
   1774 		dns_rdataset_disassociate(&rdataset);
   1775 	}
   1776 	if (node != NULL) {
   1777 		dns_db_detachnode(db, &node);
   1778 	}
   1779 
   1780 	return (result);
   1781 }
   1782 
   1783 isc_result_t
   1784 dns_nsec3_active(dns_db_t *db, dns_dbversion_t *version, bool complete,
   1785 		 bool *answer) {
   1786 	return (dns_nsec3_activex(db, version, complete, 0, answer));
   1787 }
   1788 
   1789 isc_result_t
   1790 dns_nsec3_activex(dns_db_t *db, dns_dbversion_t *version, bool complete,
   1791 		  dns_rdatatype_t privatetype, bool *answer) {
   1792 	dns_dbnode_t *node = NULL;
   1793 	dns_rdataset_t rdataset;
   1794 	dns_rdata_nsec3param_t nsec3param;
   1795 	isc_result_t result;
   1796 
   1797 	REQUIRE(answer != NULL);
   1798 
   1799 	dns_rdataset_init(&rdataset);
   1800 
   1801 	result = dns_db_getoriginnode(db, &node);
   1802 	if (result != ISC_R_SUCCESS) {
   1803 		return (result);
   1804 	}
   1805 
   1806 	result = dns_db_findrdataset(db, node, version,
   1807 				     dns_rdatatype_nsec3param, 0, 0, &rdataset,
   1808 				     NULL);
   1809 
   1810 	if (result == ISC_R_NOTFOUND) {
   1811 		goto try_private;
   1812 	}
   1813 
   1814 	if (result != ISC_R_SUCCESS) {
   1815 		dns_db_detachnode(db, &node);
   1816 		return (result);
   1817 	}
   1818 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   1819 	     result = dns_rdataset_next(&rdataset))
   1820 	{
   1821 		dns_rdata_t rdata = DNS_RDATA_INIT;
   1822 
   1823 		dns_rdataset_current(&rdataset, &rdata);
   1824 		result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
   1825 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   1826 
   1827 		if (nsec3param.flags == 0) {
   1828 			break;
   1829 		}
   1830 	}
   1831 	dns_rdataset_disassociate(&rdataset);
   1832 	if (result == ISC_R_SUCCESS) {
   1833 		dns_db_detachnode(db, &node);
   1834 		*answer = true;
   1835 		return (ISC_R_SUCCESS);
   1836 	}
   1837 	if (result == ISC_R_NOMORE) {
   1838 		*answer = false;
   1839 	}
   1840 
   1841 try_private:
   1842 	if (privatetype == 0 || complete) {
   1843 		dns_db_detachnode(db, &node);
   1844 		*answer = false;
   1845 		return (ISC_R_SUCCESS);
   1846 	}
   1847 	result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
   1848 				     &rdataset, NULL);
   1849 
   1850 	dns_db_detachnode(db, &node);
   1851 	if (result == ISC_R_NOTFOUND) {
   1852 		*answer = false;
   1853 		return (ISC_R_SUCCESS);
   1854 	}
   1855 	if (result != ISC_R_SUCCESS) {
   1856 		return (result);
   1857 	}
   1858 
   1859 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   1860 	     result = dns_rdataset_next(&rdataset))
   1861 	{
   1862 		dns_rdata_t rdata1 = DNS_RDATA_INIT;
   1863 		dns_rdata_t rdata2 = DNS_RDATA_INIT;
   1864 		unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   1865 
   1866 		dns_rdataset_current(&rdataset, &rdata1);
   1867 		if (!dns_nsec3param_fromprivate(&rdata1, &rdata2, buf,
   1868 						sizeof(buf)))
   1869 		{
   1870 			continue;
   1871 		}
   1872 		result = dns_rdata_tostruct(&rdata2, &nsec3param, NULL);
   1873 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   1874 
   1875 		if (!complete && CREATE(nsec3param.flags)) {
   1876 			break;
   1877 		}
   1878 	}
   1879 	dns_rdataset_disassociate(&rdataset);
   1880 	if (result == ISC_R_SUCCESS) {
   1881 		*answer = true;
   1882 		result = ISC_R_SUCCESS;
   1883 	}
   1884 	if (result == ISC_R_NOMORE) {
   1885 		*answer = false;
   1886 		result = ISC_R_SUCCESS;
   1887 	}
   1888 
   1889 	return (result);
   1890 }
   1891 
   1892 unsigned int
   1893 dns_nsec3_maxiterations(void) {
   1894 	return (DNS_NSEC3_MAXITERATIONS);
   1895 }
   1896 
   1897 isc_result_t
   1898 dns_nsec3_noexistnodata(dns_rdatatype_t type, const dns_name_t *name,
   1899 			const dns_name_t *nsec3name, dns_rdataset_t *nsec3set,
   1900 			dns_name_t *zonename, bool *exists, bool *data,
   1901 			bool *optout, bool *unknown, bool *setclosest,
   1902 			bool *setnearest, dns_name_t *closest,
   1903 			dns_name_t *nearest, dns_nseclog_t logit, void *arg) {
   1904 	char namebuf[DNS_NAME_FORMATSIZE];
   1905 	dns_fixedname_t fzone;
   1906 	dns_fixedname_t qfixed;
   1907 	dns_label_t hashlabel;
   1908 	dns_name_t *qname;
   1909 	dns_name_t *zone;
   1910 	dns_rdata_nsec3_t nsec3;
   1911 	dns_rdata_t rdata = DNS_RDATA_INIT;
   1912 	int order;
   1913 	int scope;
   1914 	bool atparent;
   1915 	bool first;
   1916 	bool ns;
   1917 	bool soa;
   1918 	isc_buffer_t buffer;
   1919 	isc_result_t answer = ISC_R_IGNORE;
   1920 	isc_result_t result;
   1921 	unsigned char hash[NSEC3_MAX_HASH_LENGTH];
   1922 	unsigned char owner[NSEC3_MAX_HASH_LENGTH];
   1923 	unsigned int length;
   1924 	unsigned int qlabels;
   1925 	unsigned int zlabels;
   1926 
   1927 	REQUIRE((exists == NULL && data == NULL) ||
   1928 		(exists != NULL && data != NULL));
   1929 	REQUIRE(nsec3set != NULL && nsec3set->type == dns_rdatatype_nsec3);
   1930 	REQUIRE((setclosest == NULL && closest == NULL) ||
   1931 		(setclosest != NULL && closest != NULL));
   1932 	REQUIRE((setnearest == NULL && nearest == NULL) ||
   1933 		(setnearest != NULL && nearest != NULL));
   1934 
   1935 	result = dns_rdataset_first(nsec3set);
   1936 	if (result != ISC_R_SUCCESS) {
   1937 		(*logit)(arg, ISC_LOG_DEBUG(3), "failure processing NSEC3 set");
   1938 		return (result);
   1939 	}
   1940 
   1941 	dns_rdataset_current(nsec3set, &rdata);
   1942 
   1943 	result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
   1944 	if (result != ISC_R_SUCCESS) {
   1945 		return (result);
   1946 	}
   1947 
   1948 	(*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant NSEC3");
   1949 
   1950 	zone = dns_fixedname_initname(&fzone);
   1951 	zlabels = dns_name_countlabels(nsec3name);
   1952 
   1953 	/*
   1954 	 * NSEC3 records must have two or more labels to be valid.
   1955 	 */
   1956 	if (zlabels < 2) {
   1957 		return (ISC_R_IGNORE);
   1958 	}
   1959 
   1960 	/*
   1961 	 * Strip off the NSEC3 hash to get the zone.
   1962 	 */
   1963 	zlabels--;
   1964 	dns_name_split(nsec3name, zlabels, NULL, zone);
   1965 
   1966 	/*
   1967 	 * If not below the zone name we can ignore this record.
   1968 	 */
   1969 	if (!dns_name_issubdomain(name, zone)) {
   1970 		return (ISC_R_IGNORE);
   1971 	}
   1972 
   1973 	/*
   1974 	 * Is this zone the same or deeper than the current zone?
   1975 	 */
   1976 	if (dns_name_countlabels(zonename) == 0 ||
   1977 	    dns_name_issubdomain(zone, zonename))
   1978 	{
   1979 		dns_name_copynf(zone, zonename);
   1980 	}
   1981 
   1982 	if (!dns_name_equal(zone, zonename)) {
   1983 		return (ISC_R_IGNORE);
   1984 	}
   1985 
   1986 	/*
   1987 	 * Are we only looking for the most enclosing zone?
   1988 	 */
   1989 	if (exists == NULL || data == NULL) {
   1990 		return (ISC_R_SUCCESS);
   1991 	}
   1992 
   1993 	/*
   1994 	 * Only set unknown once we are sure that this NSEC3 is from
   1995 	 * the deepest covering zone.
   1996 	 */
   1997 	if (!dns_nsec3_supportedhash(nsec3.hash)) {
   1998 		if (unknown != NULL) {
   1999 			*unknown = true;
   2000 		}
   2001 		return (ISC_R_IGNORE);
   2002 	}
   2003 
   2004 	/*
   2005 	 * Recover the hash from the first label.
   2006 	 */
   2007 	dns_name_getlabel(nsec3name, 0, &hashlabel);
   2008 	isc_region_consume(&hashlabel, 1);
   2009 	isc_buffer_init(&buffer, owner, sizeof(owner));
   2010 	result = isc_base32hex_decoderegion(&hashlabel, &buffer);
   2011 	if (result != ISC_R_SUCCESS) {
   2012 		return (result);
   2013 	}
   2014 
   2015 	/*
   2016 	 * The hash lengths should match.  If not ignore the record.
   2017 	 */
   2018 	if (isc_buffer_usedlength(&buffer) != nsec3.next_length) {
   2019 		return (ISC_R_IGNORE);
   2020 	}
   2021 
   2022 	/*
   2023 	 * Work out what this NSEC3 covers.
   2024 	 * Inside (<0) or outside (>=0).
   2025 	 */
   2026 	scope = memcmp(owner, nsec3.next, nsec3.next_length);
   2027 
   2028 	/*
   2029 	 * Prepare to compute all the hashes.
   2030 	 */
   2031 	qname = dns_fixedname_initname(&qfixed);
   2032 	dns_name_downcase(name, qname, NULL);
   2033 	qlabels = dns_name_countlabels(qname);
   2034 	first = true;
   2035 
   2036 	while (qlabels >= zlabels) {
   2037 		/*
   2038 		 * If there are too many iterations reject the NSEC3 record.
   2039 		 */
   2040 		if (nsec3.iterations > DNS_NSEC3_MAXITERATIONS) {
   2041 			return (DNS_R_NSEC3ITERRANGE);
   2042 		}
   2043 
   2044 		length = isc_iterated_hash(hash, nsec3.hash, nsec3.iterations,
   2045 					   nsec3.salt, nsec3.salt_length,
   2046 					   qname->ndata, qname->length);
   2047 		/*
   2048 		 * The computed hash length should match.
   2049 		 */
   2050 		if (length != nsec3.next_length) {
   2051 			(*logit)(arg, ISC_LOG_DEBUG(3),
   2052 				 "ignoring NSEC bad length %u vs %u", length,
   2053 				 nsec3.next_length);
   2054 			return (ISC_R_IGNORE);
   2055 		}
   2056 
   2057 		order = memcmp(hash, owner, length);
   2058 		if (first && order == 0) {
   2059 			/*
   2060 			 * The hashes are the same.
   2061 			 */
   2062 			atparent = dns_rdatatype_atparent(type);
   2063 			ns = dns_nsec3_typepresent(&rdata, dns_rdatatype_ns);
   2064 			soa = dns_nsec3_typepresent(&rdata, dns_rdatatype_soa);
   2065 			if (ns && !soa) {
   2066 				if (!atparent) {
   2067 					/*
   2068 					 * This NSEC3 record is from somewhere
   2069 					 * higher in the DNS, and at the
   2070 					 * parent of a delegation. It can not
   2071 					 * be legitimately used here.
   2072 					 */
   2073 					(*logit)(arg, ISC_LOG_DEBUG(3),
   2074 						 "ignoring parent NSEC3");
   2075 					return (ISC_R_IGNORE);
   2076 				}
   2077 			} else if (atparent && ns && soa) {
   2078 				/*
   2079 				 * This NSEC3 record is from the child.
   2080 				 * It can not be legitimately used here.
   2081 				 */
   2082 				(*logit)(arg, ISC_LOG_DEBUG(3),
   2083 					 "ignoring child NSEC3");
   2084 				return (ISC_R_IGNORE);
   2085 			}
   2086 			if (type == dns_rdatatype_cname ||
   2087 			    type == dns_rdatatype_nxt ||
   2088 			    type == dns_rdatatype_nsec ||
   2089 			    type == dns_rdatatype_key ||
   2090 			    !dns_nsec3_typepresent(&rdata, dns_rdatatype_cname))
   2091 			{
   2092 				*exists = true;
   2093 				*data = dns_nsec3_typepresent(&rdata, type);
   2094 				(*logit)(arg, ISC_LOG_DEBUG(3),
   2095 					 "NSEC3 proves name exists (owner) "
   2096 					 "data=%d",
   2097 					 *data);
   2098 				return (ISC_R_SUCCESS);
   2099 			}
   2100 			(*logit)(arg, ISC_LOG_DEBUG(3),
   2101 				 "NSEC3 proves CNAME exists");
   2102 			return (ISC_R_IGNORE);
   2103 		}
   2104 
   2105 		if (order == 0 &&
   2106 		    dns_nsec3_typepresent(&rdata, dns_rdatatype_ns) &&
   2107 		    !dns_nsec3_typepresent(&rdata, dns_rdatatype_soa))
   2108 		{
   2109 			/*
   2110 			 * This NSEC3 record is from somewhere higher in
   2111 			 * the DNS, and at the parent of a delegation.
   2112 			 * It can not be legitimately used here.
   2113 			 */
   2114 			(*logit)(arg, ISC_LOG_DEBUG(3),
   2115 				 "ignoring parent NSEC3");
   2116 			return (ISC_R_IGNORE);
   2117 		}
   2118 
   2119 		/*
   2120 		 * Potential closest encloser.
   2121 		 */
   2122 		if (order == 0) {
   2123 			if (closest != NULL &&
   2124 			    (dns_name_countlabels(closest) == 0 ||
   2125 			     dns_name_issubdomain(qname, closest)) &&
   2126 			    !dns_nsec3_typepresent(&rdata, dns_rdatatype_ds) &&
   2127 			    !dns_nsec3_typepresent(&rdata,
   2128 						   dns_rdatatype_dname) &&
   2129 			    (dns_nsec3_typepresent(&rdata, dns_rdatatype_soa) ||
   2130 			     !dns_nsec3_typepresent(&rdata, dns_rdatatype_ns)))
   2131 			{
   2132 				dns_name_format(qname, namebuf,
   2133 						sizeof(namebuf));
   2134 				(*logit)(arg, ISC_LOG_DEBUG(3),
   2135 					 "NSEC3 indicates potential closest "
   2136 					 "encloser: '%s'",
   2137 					 namebuf);
   2138 				dns_name_copynf(qname, closest);
   2139 				*setclosest = true;
   2140 			}
   2141 			dns_name_format(qname, namebuf, sizeof(namebuf));
   2142 			(*logit)(arg, ISC_LOG_DEBUG(3),
   2143 				 "NSEC3 at super-domain %s", namebuf);
   2144 			return (answer);
   2145 		}
   2146 
   2147 		/*
   2148 		 * Find if the name does not exist.
   2149 		 *
   2150 		 * We continue as we need to find the name closest to the
   2151 		 * closest encloser that doesn't exist.
   2152 		 *
   2153 		 * We also need to continue to ensure that we are not
   2154 		 * proving the non-existence of a record in a sub-zone.
   2155 		 * If that would be the case we will return ISC_R_IGNORE
   2156 		 * above.
   2157 		 */
   2158 		if ((scope < 0 && order > 0 &&
   2159 		     memcmp(hash, nsec3.next, length) < 0) ||
   2160 		    (scope >= 0 &&
   2161 		     (order > 0 || memcmp(hash, nsec3.next, length) < 0)))
   2162 		{
   2163 			dns_name_format(qname, namebuf, sizeof(namebuf));
   2164 			(*logit)(arg, ISC_LOG_DEBUG(3),
   2165 				 "NSEC3 proves "
   2166 				 "name does not exist: '%s'",
   2167 				 namebuf);
   2168 			if (nearest != NULL &&
   2169 			    (dns_name_countlabels(nearest) == 0 ||
   2170 			     dns_name_issubdomain(nearest, qname)))
   2171 			{
   2172 				dns_name_copynf(qname, nearest);
   2173 				*setnearest = true;
   2174 			}
   2175 
   2176 			*exists = false;
   2177 			*data = false;
   2178 			if (optout != NULL) {
   2179 				*optout = ((nsec3.flags &
   2180 					    DNS_NSEC3FLAG_OPTOUT) != 0);
   2181 				(*logit)(arg, ISC_LOG_DEBUG(3),
   2182 					 (*optout ? "NSEC3 indicates optout"
   2183 						  : "NSEC3 indicates secure "
   2184 						    "range"));
   2185 			}
   2186 			answer = ISC_R_SUCCESS;
   2187 		}
   2188 
   2189 		qlabels--;
   2190 		if (qlabels > 0) {
   2191 			dns_name_split(qname, qlabels, NULL, qname);
   2192 		}
   2193 		first = false;
   2194 	}
   2195 	return (answer);
   2196 }
   2197