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