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