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