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