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