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