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