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