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