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