/contrib/bind9/lib/dns/nsec3.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 1834 lines · 1375 code · 218 blank · 241 comment · 402 complexity · 85a8d6405af33523624c3a37ffe8279b MD5 · raw file

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