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