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