/contrib/bind9/lib/dns/validator.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 4369 lines · 3257 code · 378 blank · 734 comment · 1178 complexity · a9e623957e291c360bd8b11e4018b46b MD5 · raw file

Large files are truncated click here to view the full file

  1. /*
  2. * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
  3. * Copyright (C) 2000-2003 Internet Software Consortium.
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  10. * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  11. * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  12. * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  13. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  14. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  15. * PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. /* $Id$ */
  18. #include <config.h>
  19. #include <isc/base32.h>
  20. #include <isc/mem.h>
  21. #include <isc/print.h>
  22. #include <isc/sha2.h>
  23. #include <isc/string.h>
  24. #include <isc/task.h>
  25. #include <isc/util.h>
  26. #include <dns/db.h>
  27. #include <dns/dnssec.h>
  28. #include <dns/ds.h>
  29. #include <dns/events.h>
  30. #include <dns/keytable.h>
  31. #include <dns/keyvalues.h>
  32. #include <dns/log.h>
  33. #include <dns/message.h>
  34. #include <dns/ncache.h>
  35. #include <dns/nsec.h>
  36. #include <dns/nsec3.h>
  37. #include <dns/rdata.h>
  38. #include <dns/rdataset.h>
  39. #include <dns/rdatatype.h>
  40. #include <dns/resolver.h>
  41. #include <dns/result.h>
  42. #include <dns/validator.h>
  43. #include <dns/view.h>
  44. /*! \file
  45. * \brief
  46. * Basic processing sequences.
  47. *
  48. * \li When called with rdataset and sigrdataset:
  49. * validator_start -> validate -> proveunsecure -> startfinddlvsep ->
  50. * dlv_validator_start -> validator_start -> validate -> proveunsecure
  51. *
  52. * validator_start -> validate -> nsecvalidate (secure wildcard answer)
  53. *
  54. * \li When called with rdataset, sigrdataset and with DNS_VALIDATOR_DLV:
  55. * validator_start -> startfinddlvsep -> dlv_validator_start ->
  56. * validator_start -> validate -> proveunsecure
  57. *
  58. * \li When called with rdataset:
  59. * validator_start -> proveunsecure -> startfinddlvsep ->
  60. * dlv_validator_start -> validator_start -> proveunsecure
  61. *
  62. * \li When called with rdataset and with DNS_VALIDATOR_DLV:
  63. * validator_start -> startfinddlvsep -> dlv_validator_start ->
  64. * validator_start -> proveunsecure
  65. *
  66. * \li When called without a rdataset:
  67. * validator_start -> nsecvalidate -> proveunsecure -> startfinddlvsep ->
  68. * dlv_validator_start -> validator_start -> nsecvalidate -> proveunsecure
  69. *
  70. * Note: there isn't a case for DNS_VALIDATOR_DLV here as we want nsecvalidate()
  71. * to always validate the authority section even when it does not contain
  72. * signatures.
  73. *
  74. * validator_start: determines what type of validation to do.
  75. * validate: attempts to perform a positive validation.
  76. * proveunsecure: attempts to prove the answer comes from a unsecure zone.
  77. * nsecvalidate: attempts to prove a negative response.
  78. * startfinddlvsep: starts the DLV record lookup.
  79. * dlv_validator_start: resets state and restarts the lookup using the
  80. * DLV RRset found by startfinddlvsep.
  81. */
  82. #define VALIDATOR_MAGIC ISC_MAGIC('V', 'a', 'l', '?')
  83. #define VALID_VALIDATOR(v) ISC_MAGIC_VALID(v, VALIDATOR_MAGIC)
  84. #define VALATTR_SHUTDOWN 0x0001 /*%< Shutting down. */
  85. #define VALATTR_CANCELED 0x0002 /*%< Canceled. */
  86. #define VALATTR_TRIEDVERIFY 0x0004 /*%< We have found a key and
  87. * have attempted a verify. */
  88. #define VALATTR_INSECURITY 0x0010 /*%< Attempting proveunsecure. */
  89. #define VALATTR_DLVTRIED 0x0020 /*%< Looked for a DLV record. */
  90. /*!
  91. * NSEC proofs to be looked for.
  92. */
  93. #define VALATTR_NEEDNOQNAME 0x00000100
  94. #define VALATTR_NEEDNOWILDCARD 0x00000200
  95. #define VALATTR_NEEDNODATA 0x00000400
  96. /*!
  97. * NSEC proofs that have been found.
  98. */
  99. #define VALATTR_FOUNDNOQNAME 0x00001000
  100. #define VALATTR_FOUNDNOWILDCARD 0x00002000
  101. #define VALATTR_FOUNDNODATA 0x00004000
  102. #define VALATTR_FOUNDCLOSEST 0x00008000
  103. /*
  104. *
  105. */
  106. #define VALATTR_FOUNDOPTOUT 0x00010000
  107. #define VALATTR_FOUNDUNKNOWN 0x00020000
  108. #define NEEDNODATA(val) ((val->attributes & VALATTR_NEEDNODATA) != 0)
  109. #define NEEDNOQNAME(val) ((val->attributes & VALATTR_NEEDNOQNAME) != 0)
  110. #define NEEDNOWILDCARD(val) ((val->attributes & VALATTR_NEEDNOWILDCARD) != 0)
  111. #define DLVTRIED(val) ((val->attributes & VALATTR_DLVTRIED) != 0)
  112. #define FOUNDNODATA(val) ((val->attributes & VALATTR_FOUNDNODATA) != 0)
  113. #define FOUNDNOQNAME(val) ((val->attributes & VALATTR_FOUNDNOQNAME) != 0)
  114. #define FOUNDNOWILDCARD(val) ((val->attributes & VALATTR_FOUNDNOWILDCARD) != 0)
  115. #define FOUNDCLOSEST(val) ((val->attributes & VALATTR_FOUNDCLOSEST) != 0)
  116. #define FOUNDOPTOUT(val) ((val->attributes & VALATTR_FOUNDOPTOUT) != 0)
  117. #define SHUTDOWN(v) (((v)->attributes & VALATTR_SHUTDOWN) != 0)
  118. #define CANCELED(v) (((v)->attributes & VALATTR_CANCELED) != 0)
  119. #define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
  120. static void
  121. destroy(dns_validator_t *val);
  122. static isc_result_t
  123. get_dst_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo,
  124. dns_rdataset_t *rdataset);
  125. static isc_result_t
  126. validate(dns_validator_t *val, isc_boolean_t resume);
  127. static isc_result_t
  128. validatezonekey(dns_validator_t *val);
  129. static isc_result_t
  130. nsecvalidate(dns_validator_t *val, isc_boolean_t resume);
  131. static isc_result_t
  132. proveunsecure(dns_validator_t *val, isc_boolean_t have_ds,
  133. isc_boolean_t resume);
  134. static void
  135. validator_logv(dns_validator_t *val, isc_logcategory_t *category,
  136. isc_logmodule_t *module, int level, const char *fmt, va_list ap)
  137. ISC_FORMAT_PRINTF(5, 0);
  138. static void
  139. validator_log(dns_validator_t *val, int level, const char *fmt, ...)
  140. ISC_FORMAT_PRINTF(3, 4);
  141. static void
  142. validator_logcreate(dns_validator_t *val,
  143. dns_name_t *name, dns_rdatatype_t type,
  144. const char *caller, const char *operation);
  145. static isc_result_t
  146. dlv_validatezonekey(dns_validator_t *val);
  147. static void
  148. dlv_validator_start(dns_validator_t *val);
  149. static isc_result_t
  150. finddlvsep(dns_validator_t *val, isc_boolean_t resume);
  151. static isc_result_t
  152. startfinddlvsep(dns_validator_t *val, dns_name_t *unsecure);
  153. /*%
  154. * Mark the RRsets as a answer.
  155. */
  156. static inline void
  157. markanswer(dns_validator_t *val, const char *where) {
  158. validator_log(val, ISC_LOG_DEBUG(3), "marking as answer (%s)", where);
  159. if (val->event->rdataset != NULL)
  160. dns_rdataset_settrust(val->event->rdataset, dns_trust_answer);
  161. if (val->event->sigrdataset != NULL)
  162. dns_rdataset_settrust(val->event->sigrdataset,
  163. dns_trust_answer);
  164. }
  165. static inline void
  166. marksecure(dns_validatorevent_t *event) {
  167. dns_rdataset_settrust(event->rdataset, dns_trust_secure);
  168. if (event->sigrdataset != NULL)
  169. dns_rdataset_settrust(event->sigrdataset, dns_trust_secure);
  170. }
  171. static void
  172. validator_done(dns_validator_t *val, isc_result_t result) {
  173. isc_task_t *task;
  174. if (val->event == NULL)
  175. return;
  176. /*
  177. * Caller must be holding the lock.
  178. */
  179. val->event->result = result;
  180. task = val->event->ev_sender;
  181. val->event->ev_sender = val;
  182. val->event->ev_type = DNS_EVENT_VALIDATORDONE;
  183. val->event->ev_action = val->action;
  184. val->event->ev_arg = val->arg;
  185. isc_task_sendanddetach(&task, (isc_event_t **)&val->event);
  186. }
  187. static inline isc_boolean_t
  188. exit_check(dns_validator_t *val) {
  189. /*
  190. * Caller must be holding the lock.
  191. */
  192. if (!SHUTDOWN(val))
  193. return (ISC_FALSE);
  194. INSIST(val->event == NULL);
  195. if (val->fetch != NULL || val->subvalidator != NULL)
  196. return (ISC_FALSE);
  197. return (ISC_TRUE);
  198. }
  199. /*
  200. * Check that we have atleast one supported algorithm in the DLV RRset.
  201. */
  202. static inline isc_boolean_t
  203. dlv_algorithm_supported(dns_validator_t *val) {
  204. dns_rdata_t rdata = DNS_RDATA_INIT;
  205. dns_rdata_dlv_t dlv;
  206. isc_result_t result;
  207. for (result = dns_rdataset_first(&val->dlv);
  208. result == ISC_R_SUCCESS;
  209. result = dns_rdataset_next(&val->dlv)) {
  210. dns_rdata_reset(&rdata);
  211. dns_rdataset_current(&val->dlv, &rdata);
  212. result = dns_rdata_tostruct(&rdata, &dlv, NULL);
  213. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  214. if (!dns_resolver_algorithm_supported(val->view->resolver,
  215. val->event->name,
  216. dlv.algorithm))
  217. continue;
  218. #ifdef HAVE_OPENSSL_GOST
  219. if (dlv.digest_type != DNS_DSDIGEST_SHA256 &&
  220. dlv.digest_type != DNS_DSDIGEST_SHA1 &&
  221. dlv.digest_type != DNS_DSDIGEST_GOST)
  222. continue;
  223. #else
  224. if (dlv.digest_type != DNS_DSDIGEST_SHA256 &&
  225. dlv.digest_type != DNS_DSDIGEST_SHA1)
  226. continue;
  227. #endif
  228. return (ISC_TRUE);
  229. }
  230. return (ISC_FALSE);
  231. }
  232. /*%
  233. * Look in the NSEC record returned from a DS query to see if there is
  234. * a NS RRset at this name. If it is found we are at a delegation point.
  235. */
  236. static isc_boolean_t
  237. isdelegation(dns_name_t *name, dns_rdataset_t *rdataset,
  238. isc_result_t dbresult)
  239. {
  240. dns_fixedname_t fixed;
  241. dns_label_t hashlabel;
  242. dns_name_t nsec3name;
  243. dns_rdata_nsec3_t nsec3;
  244. dns_rdata_t rdata = DNS_RDATA_INIT;
  245. dns_rdataset_t set;
  246. int order;
  247. int scope;
  248. isc_boolean_t found;
  249. isc_buffer_t buffer;
  250. isc_result_t result;
  251. unsigned char hash[NSEC3_MAX_HASH_LENGTH];
  252. unsigned char owner[NSEC3_MAX_HASH_LENGTH];
  253. unsigned int length;
  254. REQUIRE(dbresult == DNS_R_NXRRSET || dbresult == DNS_R_NCACHENXRRSET);
  255. dns_rdataset_init(&set);
  256. if (dbresult == DNS_R_NXRRSET)
  257. dns_rdataset_clone(rdataset, &set);
  258. else {
  259. result = dns_ncache_getrdataset(rdataset, name,
  260. dns_rdatatype_nsec, &set);
  261. if (result == ISC_R_NOTFOUND)
  262. goto trynsec3;
  263. if (result != ISC_R_SUCCESS)
  264. return (ISC_FALSE);
  265. }
  266. INSIST(set.type == dns_rdatatype_nsec);
  267. found = ISC_FALSE;
  268. result = dns_rdataset_first(&set);
  269. if (result == ISC_R_SUCCESS) {
  270. dns_rdataset_current(&set, &rdata);
  271. found = dns_nsec_typepresent(&rdata, dns_rdatatype_ns);
  272. dns_rdata_reset(&rdata);
  273. }
  274. dns_rdataset_disassociate(&set);
  275. return (found);
  276. trynsec3:
  277. /*
  278. * Iterate over the ncache entry.
  279. */
  280. found = ISC_FALSE;
  281. dns_name_init(&nsec3name, NULL);
  282. dns_fixedname_init(&fixed);
  283. dns_name_downcase(name, dns_fixedname_name(&fixed), NULL);
  284. name = dns_fixedname_name(&fixed);
  285. for (result = dns_rdataset_first(rdataset);
  286. result == ISC_R_SUCCESS;
  287. result = dns_rdataset_next(rdataset))
  288. {
  289. dns_ncache_current(rdataset, &nsec3name, &set);
  290. if (set.type != dns_rdatatype_nsec3) {
  291. dns_rdataset_disassociate(&set);
  292. continue;
  293. }
  294. dns_name_getlabel(&nsec3name, 0, &hashlabel);
  295. isc_region_consume(&hashlabel, 1);
  296. isc_buffer_init(&buffer, owner, sizeof(owner));
  297. result = isc_base32hex_decoderegion(&hashlabel, &buffer);
  298. if (result != ISC_R_SUCCESS) {
  299. dns_rdataset_disassociate(&set);
  300. continue;
  301. }
  302. for (result = dns_rdataset_first(&set);
  303. result == ISC_R_SUCCESS;
  304. result = dns_rdataset_next(&set))
  305. {
  306. dns_rdata_reset(&rdata);
  307. dns_rdataset_current(&set, &rdata);
  308. (void)dns_rdata_tostruct(&rdata, &nsec3, NULL);
  309. if (nsec3.hash != 1)
  310. continue;
  311. length = isc_iterated_hash(hash, nsec3.hash,
  312. nsec3.iterations, nsec3.salt,
  313. nsec3.salt_length,
  314. name->ndata, name->length);
  315. if (length != isc_buffer_usedlength(&buffer))
  316. continue;
  317. order = memcmp(hash, owner, length);
  318. if (order == 0) {
  319. found = dns_nsec3_typepresent(&rdata,
  320. dns_rdatatype_ns);
  321. dns_rdataset_disassociate(&set);
  322. return (found);
  323. }
  324. if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) == 0)
  325. continue;
  326. /*
  327. * Does this optout span cover the name?
  328. */
  329. scope = memcmp(owner, nsec3.next, nsec3.next_length);
  330. if ((scope < 0 && order > 0 &&
  331. memcmp(hash, nsec3.next, length) < 0) ||
  332. (scope >= 0 && (order > 0 ||
  333. memcmp(hash, nsec3.next, length) < 0)))
  334. {
  335. dns_rdataset_disassociate(&set);
  336. return (ISC_TRUE);
  337. }
  338. }
  339. dns_rdataset_disassociate(&set);
  340. }
  341. return (found);
  342. }
  343. /*%
  344. * We have been asked to look for a key.
  345. * If found resume the validation process.
  346. * If not found fail the validation process.
  347. */
  348. static void
  349. fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
  350. dns_fetchevent_t *devent;
  351. dns_validator_t *val;
  352. dns_rdataset_t *rdataset;
  353. isc_boolean_t want_destroy;
  354. isc_result_t result;
  355. isc_result_t eresult;
  356. isc_result_t saved_result;
  357. UNUSED(task);
  358. INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
  359. devent = (dns_fetchevent_t *)event;
  360. val = devent->ev_arg;
  361. rdataset = &val->frdataset;
  362. eresult = devent->result;
  363. /* Free resources which are not of interest. */
  364. if (devent->node != NULL)
  365. dns_db_detachnode(devent->db, &devent->node);
  366. if (devent->db != NULL)
  367. dns_db_detach(&devent->db);
  368. if (dns_rdataset_isassociated(&val->fsigrdataset))
  369. dns_rdataset_disassociate(&val->fsigrdataset);
  370. isc_event_free(&event);
  371. dns_resolver_destroyfetch(&val->fetch);
  372. INSIST(val->event != NULL);
  373. validator_log(val, ISC_LOG_DEBUG(3), "in fetch_callback_validator");
  374. LOCK(&val->lock);
  375. if (CANCELED(val)) {
  376. validator_done(val, ISC_R_CANCELED);
  377. } else if (eresult == ISC_R_SUCCESS) {
  378. validator_log(val, ISC_LOG_DEBUG(3),
  379. "keyset with trust %s",
  380. dns_trust_totext(rdataset->trust));
  381. /*
  382. * Only extract the dst key if the keyset is secure.
  383. */
  384. if (rdataset->trust >= dns_trust_secure) {
  385. result = get_dst_key(val, val->siginfo, rdataset);
  386. if (result == ISC_R_SUCCESS)
  387. val->keyset = &val->frdataset;
  388. }
  389. result = validate(val, ISC_TRUE);
  390. if (result == DNS_R_NOVALIDSIG &&
  391. (val->attributes & VALATTR_TRIEDVERIFY) == 0)
  392. {
  393. saved_result = result;
  394. validator_log(val, ISC_LOG_DEBUG(3),
  395. "falling back to insecurity proof");
  396. val->attributes |= VALATTR_INSECURITY;
  397. result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
  398. if (result == DNS_R_NOTINSECURE)
  399. result = saved_result;
  400. }
  401. if (result != DNS_R_WAIT)
  402. validator_done(val, result);
  403. } else {
  404. validator_log(val, ISC_LOG_DEBUG(3),
  405. "fetch_callback_validator: got %s",
  406. isc_result_totext(eresult));
  407. if (eresult == ISC_R_CANCELED)
  408. validator_done(val, eresult);
  409. else
  410. validator_done(val, DNS_R_BROKENCHAIN);
  411. }
  412. want_destroy = exit_check(val);
  413. UNLOCK(&val->lock);
  414. if (want_destroy)
  415. destroy(val);
  416. }
  417. /*%
  418. * We were asked to look for a DS record as part of following a key chain
  419. * upwards. If found resume the validation process. If not found fail the
  420. * validation process.
  421. */
  422. static void
  423. dsfetched(isc_task_t *task, isc_event_t *event) {
  424. dns_fetchevent_t *devent;
  425. dns_validator_t *val;
  426. dns_rdataset_t *rdataset;
  427. isc_boolean_t want_destroy;
  428. isc_result_t result;
  429. isc_result_t eresult;
  430. UNUSED(task);
  431. INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
  432. devent = (dns_fetchevent_t *)event;
  433. val = devent->ev_arg;
  434. rdataset = &val->frdataset;
  435. eresult = devent->result;
  436. /* Free resources which are not of interest. */
  437. if (devent->node != NULL)
  438. dns_db_detachnode(devent->db, &devent->node);
  439. if (devent->db != NULL)
  440. dns_db_detach(&devent->db);
  441. if (dns_rdataset_isassociated(&val->fsigrdataset))
  442. dns_rdataset_disassociate(&val->fsigrdataset);
  443. isc_event_free(&event);
  444. dns_resolver_destroyfetch(&val->fetch);
  445. INSIST(val->event != NULL);
  446. validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched");
  447. LOCK(&val->lock);
  448. if (CANCELED(val)) {
  449. validator_done(val, ISC_R_CANCELED);
  450. } else if (eresult == ISC_R_SUCCESS) {
  451. validator_log(val, ISC_LOG_DEBUG(3),
  452. "dsset with trust %s",
  453. dns_trust_totext(rdataset->trust));
  454. val->dsset = &val->frdataset;
  455. result = validatezonekey(val);
  456. if (result != DNS_R_WAIT)
  457. validator_done(val, result);
  458. } else if (eresult == DNS_R_CNAME ||
  459. eresult == DNS_R_NXRRSET ||
  460. eresult == DNS_R_NCACHENXRRSET ||
  461. eresult == DNS_R_SERVFAIL) /* RFC 1034 parent? */
  462. {
  463. validator_log(val, ISC_LOG_DEBUG(3),
  464. "falling back to insecurity proof (%s)",
  465. dns_result_totext(eresult));
  466. val->attributes |= VALATTR_INSECURITY;
  467. result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
  468. if (result != DNS_R_WAIT)
  469. validator_done(val, result);
  470. } else {
  471. validator_log(val, ISC_LOG_DEBUG(3),
  472. "dsfetched: got %s",
  473. isc_result_totext(eresult));
  474. if (eresult == ISC_R_CANCELED)
  475. validator_done(val, eresult);
  476. else
  477. validator_done(val, DNS_R_BROKENCHAIN);
  478. }
  479. want_destroy = exit_check(val);
  480. UNLOCK(&val->lock);
  481. if (want_destroy)
  482. destroy(val);
  483. }
  484. /*%
  485. * We were asked to look for the DS record as part of proving that a
  486. * name is unsecure.
  487. *
  488. * If the DS record doesn't exist and the query name corresponds to
  489. * a delegation point we are transitioning from a secure zone to a
  490. * unsecure zone.
  491. *
  492. * If the DS record exists it will be secure. We can continue looking
  493. * for the break point in the chain of trust.
  494. */
  495. static void
  496. dsfetched2(isc_task_t *task, isc_event_t *event) {
  497. dns_fetchevent_t *devent;
  498. dns_validator_t *val;
  499. dns_name_t *tname;
  500. isc_boolean_t want_destroy;
  501. isc_result_t result;
  502. isc_result_t eresult;
  503. UNUSED(task);
  504. INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
  505. devent = (dns_fetchevent_t *)event;
  506. val = devent->ev_arg;
  507. eresult = devent->result;
  508. /* Free resources which are not of interest. */
  509. if (devent->node != NULL)
  510. dns_db_detachnode(devent->db, &devent->node);
  511. if (devent->db != NULL)
  512. dns_db_detach(&devent->db);
  513. if (dns_rdataset_isassociated(&val->fsigrdataset))
  514. dns_rdataset_disassociate(&val->fsigrdataset);
  515. dns_resolver_destroyfetch(&val->fetch);
  516. INSIST(val->event != NULL);
  517. validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched2: %s",
  518. dns_result_totext(eresult));
  519. LOCK(&val->lock);
  520. if (CANCELED(val)) {
  521. validator_done(val, ISC_R_CANCELED);
  522. } else if (eresult == DNS_R_CNAME ||
  523. eresult == DNS_R_NXRRSET ||
  524. eresult == DNS_R_NCACHENXRRSET)
  525. {
  526. /*
  527. * There is no DS. If this is a delegation, we're done.
  528. */
  529. tname = dns_fixedname_name(&devent->foundname);
  530. if (eresult != DNS_R_CNAME &&
  531. isdelegation(tname, &val->frdataset, eresult)) {
  532. if (val->mustbesecure) {
  533. validator_log(val, ISC_LOG_WARNING,
  534. "must be secure failure, no DS"
  535. " and this is a delegation");
  536. validator_done(val, DNS_R_MUSTBESECURE);
  537. } else if (val->view->dlv == NULL || DLVTRIED(val)) {
  538. markanswer(val, "dsfetched2");
  539. validator_done(val, ISC_R_SUCCESS);
  540. } else {
  541. result = startfinddlvsep(val, tname);
  542. if (result != DNS_R_WAIT)
  543. validator_done(val, result);
  544. }
  545. } else {
  546. result = proveunsecure(val, ISC_FALSE, ISC_TRUE);
  547. if (result != DNS_R_WAIT)
  548. validator_done(val, result);
  549. }
  550. } else if (eresult == ISC_R_SUCCESS ||
  551. eresult == DNS_R_NXDOMAIN ||
  552. eresult == DNS_R_NCACHENXDOMAIN)
  553. {
  554. /*
  555. * There is a DS which may or may not be a zone cut.
  556. * In either case we are still in a secure zone resume
  557. * validation.
  558. */
  559. result = proveunsecure(val, ISC_TF(eresult == ISC_R_SUCCESS),
  560. ISC_TRUE);
  561. if (result != DNS_R_WAIT)
  562. validator_done(val, result);
  563. } else {
  564. if (eresult == ISC_R_CANCELED)
  565. validator_done(val, eresult);
  566. else
  567. validator_done(val, DNS_R_NOVALIDDS);
  568. }
  569. isc_event_free(&event);
  570. want_destroy = exit_check(val);
  571. UNLOCK(&val->lock);
  572. if (want_destroy)
  573. destroy(val);
  574. }
  575. /*%
  576. * Callback from when a DNSKEY RRset has been validated.
  577. *
  578. * Resumes the stalled validation process.
  579. */
  580. static void
  581. keyvalidated(isc_task_t *task, isc_event_t *event) {
  582. dns_validatorevent_t *devent;
  583. dns_validator_t *val;
  584. isc_boolean_t want_destroy;
  585. isc_result_t result;
  586. isc_result_t eresult;
  587. isc_result_t saved_result;
  588. UNUSED(task);
  589. INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
  590. devent = (dns_validatorevent_t *)event;
  591. val = devent->ev_arg;
  592. eresult = devent->result;
  593. isc_event_free(&event);
  594. dns_validator_destroy(&val->subvalidator);
  595. INSIST(val->event != NULL);
  596. validator_log(val, ISC_LOG_DEBUG(3), "in keyvalidated");
  597. LOCK(&val->lock);
  598. if (CANCELED(val)) {
  599. validator_done(val, ISC_R_CANCELED);
  600. } else if (eresult == ISC_R_SUCCESS) {
  601. validator_log(val, ISC_LOG_DEBUG(3),
  602. "keyset with trust %s",
  603. dns_trust_totext(val->frdataset.trust));
  604. /*
  605. * Only extract the dst key if the keyset is secure.
  606. */
  607. if (val->frdataset.trust >= dns_trust_secure)
  608. (void) get_dst_key(val, val->siginfo, &val->frdataset);
  609. result = validate(val, ISC_TRUE);
  610. if (result == DNS_R_NOVALIDSIG &&
  611. (val->attributes & VALATTR_TRIEDVERIFY) == 0)
  612. {
  613. saved_result = result;
  614. validator_log(val, ISC_LOG_DEBUG(3),
  615. "falling back to insecurity proof");
  616. val->attributes |= VALATTR_INSECURITY;
  617. result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
  618. if (result == DNS_R_NOTINSECURE)
  619. result = saved_result;
  620. }
  621. if (result != DNS_R_WAIT)
  622. validator_done(val, result);
  623. } else {
  624. if (eresult != DNS_R_BROKENCHAIN) {
  625. if (dns_rdataset_isassociated(&val->frdataset))
  626. dns_rdataset_expire(&val->frdataset);
  627. if (dns_rdataset_isassociated(&val->fsigrdataset))
  628. dns_rdataset_expire(&val->fsigrdataset);
  629. }
  630. validator_log(val, ISC_LOG_DEBUG(3),
  631. "keyvalidated: got %s",
  632. isc_result_totext(eresult));
  633. validator_done(val, DNS_R_BROKENCHAIN);
  634. }
  635. want_destroy = exit_check(val);
  636. UNLOCK(&val->lock);
  637. if (want_destroy)
  638. destroy(val);
  639. }
  640. /*%
  641. * Callback when the DS record has been validated.
  642. *
  643. * Resumes validation of the zone key or the unsecure zone proof.
  644. */
  645. static void
  646. dsvalidated(isc_task_t *task, isc_event_t *event) {
  647. dns_validatorevent_t *devent;
  648. dns_validator_t *val;
  649. isc_boolean_t want_destroy;
  650. isc_result_t result;
  651. isc_result_t eresult;
  652. UNUSED(task);
  653. INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
  654. devent = (dns_validatorevent_t *)event;
  655. val = devent->ev_arg;
  656. eresult = devent->result;
  657. isc_event_free(&event);
  658. dns_validator_destroy(&val->subvalidator);
  659. INSIST(val->event != NULL);
  660. validator_log(val, ISC_LOG_DEBUG(3), "in dsvalidated");
  661. LOCK(&val->lock);
  662. if (CANCELED(val)) {
  663. validator_done(val, ISC_R_CANCELED);
  664. } else if (eresult == ISC_R_SUCCESS) {
  665. isc_boolean_t have_dsset;
  666. dns_name_t *name;
  667. validator_log(val, ISC_LOG_DEBUG(3),
  668. "%s with trust %s",
  669. val->frdataset.type == dns_rdatatype_ds ?
  670. "dsset" : "ds non-existance",
  671. dns_trust_totext(val->frdataset.trust));
  672. have_dsset = ISC_TF(val->frdataset.type == dns_rdatatype_ds);
  673. name = dns_fixedname_name(&val->fname);
  674. if ((val->attributes & VALATTR_INSECURITY) != 0 &&
  675. val->frdataset.covers == dns_rdatatype_ds &&
  676. NEGATIVE(&val->frdataset) &&
  677. isdelegation(name, &val->frdataset, DNS_R_NCACHENXRRSET)) {
  678. if (val->mustbesecure) {
  679. validator_log(val, ISC_LOG_WARNING,
  680. "must be secure failure, no DS "
  681. "and this is a delegation");
  682. result = DNS_R_MUSTBESECURE;
  683. } else if (val->view->dlv == NULL || DLVTRIED(val)) {
  684. markanswer(val, "dsvalidated");
  685. result = ISC_R_SUCCESS;;
  686. } else
  687. result = startfinddlvsep(val, name);
  688. } else if ((val->attributes & VALATTR_INSECURITY) != 0) {
  689. result = proveunsecure(val, have_dsset, ISC_TRUE);
  690. } else
  691. result = validatezonekey(val);
  692. if (result != DNS_R_WAIT)
  693. validator_done(val, result);
  694. } else {
  695. if (eresult != DNS_R_BROKENCHAIN) {
  696. if (dns_rdataset_isassociated(&val->frdataset))
  697. dns_rdataset_expire(&val->frdataset);
  698. if (dns_rdataset_isassociated(&val->fsigrdataset))
  699. dns_rdataset_expire(&val->fsigrdataset);
  700. }
  701. validator_log(val, ISC_LOG_DEBUG(3),
  702. "dsvalidated: got %s",
  703. isc_result_totext(eresult));
  704. validator_done(val, DNS_R_BROKENCHAIN);
  705. }
  706. want_destroy = exit_check(val);
  707. UNLOCK(&val->lock);
  708. if (want_destroy)
  709. destroy(val);
  710. }
  711. /*%
  712. * Callback when the CNAME record has been validated.
  713. *
  714. * Resumes validation of the unsecure zone proof.
  715. */
  716. static void
  717. cnamevalidated(isc_task_t *task, isc_event_t *event) {
  718. dns_validatorevent_t *devent;
  719. dns_validator_t *val;
  720. isc_boolean_t want_destroy;
  721. isc_result_t result;
  722. isc_result_t eresult;
  723. UNUSED(task);
  724. INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
  725. devent = (dns_validatorevent_t *)event;
  726. val = devent->ev_arg;
  727. eresult = devent->result;
  728. isc_event_free(&event);
  729. dns_validator_destroy(&val->subvalidator);
  730. INSIST(val->event != NULL);
  731. INSIST((val->attributes & VALATTR_INSECURITY) != 0);
  732. validator_log(val, ISC_LOG_DEBUG(3), "in cnamevalidated");
  733. LOCK(&val->lock);
  734. if (CANCELED(val)) {
  735. validator_done(val, ISC_R_CANCELED);
  736. } else if (eresult == ISC_R_SUCCESS) {
  737. validator_log(val, ISC_LOG_DEBUG(3), "cname with trust %s",
  738. dns_trust_totext(val->frdataset.trust));
  739. result = proveunsecure(val, ISC_FALSE, ISC_TRUE);
  740. if (result != DNS_R_WAIT)
  741. validator_done(val, result);
  742. } else {
  743. if (eresult != DNS_R_BROKENCHAIN) {
  744. if (dns_rdataset_isassociated(&val->frdataset))
  745. dns_rdataset_expire(&val->frdataset);
  746. if (dns_rdataset_isassociated(&val->fsigrdataset))
  747. dns_rdataset_expire(&val->fsigrdataset);
  748. }
  749. validator_log(val, ISC_LOG_DEBUG(3),
  750. "cnamevalidated: got %s",
  751. isc_result_totext(eresult));
  752. validator_done(val, DNS_R_BROKENCHAIN);
  753. }
  754. want_destroy = exit_check(val);
  755. UNLOCK(&val->lock);
  756. if (want_destroy)
  757. destroy(val);
  758. }
  759. /*%
  760. * Return ISC_R_SUCCESS if we can determine that the name doesn't exist
  761. * or we can determine whether there is data or not at the name.
  762. * If the name does not exist return the wildcard name.
  763. *
  764. * Return ISC_R_IGNORE when the NSEC is not the appropriate one.
  765. */
  766. static isc_result_t
  767. nsecnoexistnodata(dns_validator_t *val, dns_name_t *name, dns_name_t *nsecname,
  768. dns_rdataset_t *nsecset, isc_boolean_t *exists,
  769. isc_boolean_t *data, dns_name_t *wild)
  770. {
  771. int order;
  772. dns_rdata_t rdata = DNS_RDATA_INIT;
  773. isc_result_t result;
  774. dns_namereln_t relation;
  775. unsigned int olabels, nlabels, labels;
  776. dns_rdata_nsec_t nsec;
  777. isc_boolean_t atparent;
  778. isc_boolean_t ns;
  779. isc_boolean_t soa;
  780. REQUIRE(exists != NULL);
  781. REQUIRE(data != NULL);
  782. REQUIRE(nsecset != NULL &&
  783. nsecset->type == dns_rdatatype_nsec);
  784. result = dns_rdataset_first(nsecset);
  785. if (result != ISC_R_SUCCESS) {
  786. validator_log(val, ISC_LOG_DEBUG(3),
  787. "failure processing NSEC set");
  788. return (result);
  789. }
  790. dns_rdataset_current(nsecset, &rdata);
  791. validator_log(val, ISC_LOG_DEBUG(3), "looking for relevant nsec");
  792. relation = dns_name_fullcompare(name, nsecname, &order, &olabels);
  793. if (order < 0) {
  794. /*
  795. * The name is not within the NSEC range.
  796. */
  797. validator_log(val, ISC_LOG_DEBUG(3),
  798. "NSEC does not cover name, before NSEC");
  799. return (ISC_R_IGNORE);
  800. }
  801. if (order == 0) {
  802. /*
  803. * The names are the same. If we are validating "."
  804. * then atparent should not be set as there is no parent.
  805. */
  806. atparent = (olabels != 1) &&
  807. dns_rdatatype_atparent(val->event->type);
  808. ns = dns_nsec_typepresent(&rdata, dns_rdatatype_ns);
  809. soa = dns_nsec_typepresent(&rdata, dns_rdatatype_soa);
  810. if (ns && !soa) {
  811. if (!atparent) {
  812. /*
  813. * This NSEC record is from somewhere higher in
  814. * the DNS, and at the parent of a delegation.
  815. * It can not be legitimately used here.
  816. */
  817. validator_log(val, ISC_LOG_DEBUG(3),
  818. "ignoring parent nsec");
  819. return (ISC_R_IGNORE);
  820. }
  821. } else if (atparent && ns && soa) {
  822. /*
  823. * This NSEC record is from the child.
  824. * It can not be legitimately used here.
  825. */
  826. validator_log(val, ISC_LOG_DEBUG(3),
  827. "ignoring child nsec");
  828. return (ISC_R_IGNORE);
  829. }
  830. if (val->event->type == dns_rdatatype_cname ||
  831. val->event->type == dns_rdatatype_nxt ||
  832. val->event->type == dns_rdatatype_nsec ||
  833. val->event->type == dns_rdatatype_key ||
  834. !dns_nsec_typepresent(&rdata, dns_rdatatype_cname)) {
  835. *exists = ISC_TRUE;
  836. *data = dns_nsec_typepresent(&rdata, val->event->type);
  837. validator_log(val, ISC_LOG_DEBUG(3),
  838. "nsec proves name exists (owner) data=%d",
  839. *data);
  840. return (ISC_R_SUCCESS);
  841. }
  842. validator_log(val, ISC_LOG_DEBUG(3), "NSEC proves CNAME exists");
  843. return (ISC_R_IGNORE);
  844. }
  845. if (relation == dns_namereln_subdomain &&
  846. dns_nsec_typepresent(&rdata, dns_rdatatype_ns) &&
  847. !dns_nsec_typepresent(&rdata, dns_rdatatype_soa))
  848. {
  849. /*
  850. * This NSEC record is from somewhere higher in
  851. * the DNS, and at the parent of a delegation.
  852. * It can not be legitimately used here.
  853. */
  854. validator_log(val, ISC_LOG_DEBUG(3), "ignoring parent nsec");
  855. return (ISC_R_IGNORE);
  856. }
  857. result = dns_rdata_tostruct(&rdata, &nsec, NULL);
  858. if (result != ISC_R_SUCCESS)
  859. return (result);
  860. relation = dns_name_fullcompare(&nsec.next, name, &order, &nlabels);
  861. if (order == 0) {
  862. dns_rdata_freestruct(&nsec);
  863. validator_log(val, ISC_LOG_DEBUG(3),
  864. "ignoring nsec matches next name");
  865. return (ISC_R_IGNORE);
  866. }
  867. if (order < 0 && !dns_name_issubdomain(nsecname, &nsec.next)) {
  868. /*
  869. * The name is not within the NSEC range.
  870. */
  871. dns_rdata_freestruct(&nsec);
  872. validator_log(val, ISC_LOG_DEBUG(3),
  873. "ignoring nsec because name is past end of range");
  874. return (ISC_R_IGNORE);
  875. }
  876. if (order > 0 && relation == dns_namereln_subdomain) {
  877. validator_log(val, ISC_LOG_DEBUG(3),
  878. "nsec proves name exist (empty)");
  879. dns_rdata_freestruct(&nsec);
  880. *exists = ISC_TRUE;
  881. *data = ISC_FALSE;
  882. return (ISC_R_SUCCESS);
  883. }
  884. if (wild != NULL) {
  885. dns_name_t common;
  886. dns_name_init(&common, NULL);
  887. if (olabels > nlabels) {
  888. labels = dns_name_countlabels(nsecname);
  889. dns_name_getlabelsequence(nsecname, labels - olabels,
  890. olabels, &common);
  891. } else {
  892. labels = dns_name_countlabels(&nsec.next);
  893. dns_name_getlabelsequence(&nsec.next, labels - nlabels,
  894. nlabels, &common);
  895. }
  896. result = dns_name_concatenate(dns_wildcardname, &common,
  897. wild, NULL);
  898. if (result != ISC_R_SUCCESS) {
  899. dns_rdata_freestruct(&nsec);
  900. validator_log(val, ISC_LOG_DEBUG(3),
  901. "failure generating wildcard name");
  902. return (result);
  903. }
  904. }
  905. dns_rdata_freestruct(&nsec);
  906. validator_log(val, ISC_LOG_DEBUG(3), "nsec range ok");
  907. *exists = ISC_FALSE;
  908. return (ISC_R_SUCCESS);
  909. }
  910. static isc_result_t
  911. nsec3noexistnodata(dns_validator_t *val, dns_name_t* name,
  912. dns_name_t *nsec3name, dns_rdataset_t *nsec3set,
  913. dns_name_t *zonename, isc_boolean_t *exists,
  914. isc_boolean_t *data, isc_boolean_t *optout,
  915. isc_boolean_t *unknown, isc_boolean_t *setclosest,
  916. isc_boolean_t *setnearest, dns_name_t *closest,
  917. dns_name_t *nearest)
  918. {
  919. char namebuf[DNS_NAME_FORMATSIZE];
  920. dns_fixedname_t fzone;
  921. dns_fixedname_t qfixed;
  922. dns_label_t hashlabel;
  923. dns_name_t *qname;
  924. dns_name_t *zone;
  925. dns_rdata_nsec3_t nsec3;
  926. dns_rdata_t rdata = DNS_RDATA_INIT;
  927. int order;
  928. int scope;
  929. isc_boolean_t atparent;
  930. isc_boolean_t first;
  931. isc_boolean_t ns;
  932. isc_boolean_t soa;
  933. isc_buffer_t buffer;
  934. isc_result_t answer = ISC_R_IGNORE;
  935. isc_result_t result;
  936. unsigned char hash[NSEC3_MAX_HASH_LENGTH];
  937. unsigned char owner[NSEC3_MAX_HASH_LENGTH];
  938. unsigned int length;
  939. unsigned int qlabels;
  940. unsigned int zlabels;
  941. REQUIRE((exists == NULL && data == NULL) ||
  942. (exists != NULL && data != NULL));
  943. REQUIRE(nsec3set != NULL && nsec3set->type == dns_rdatatype_nsec3);
  944. REQUIRE((setclosest == NULL && closest == NULL) ||
  945. (setclosest != NULL && closest != NULL));
  946. REQUIRE((setnearest == NULL && nearest == NULL) ||
  947. (setnearest != NULL && nearest != NULL));
  948. result = dns_rdataset_first(nsec3set);
  949. if (result != ISC_R_SUCCESS) {
  950. validator_log(val, ISC_LOG_DEBUG(3),
  951. "failure processing NSEC3 set");
  952. return (result);
  953. }
  954. dns_rdataset_current(nsec3set, &rdata);
  955. result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
  956. if (result != ISC_R_SUCCESS)
  957. return (result);
  958. validator_log(val, ISC_LOG_DEBUG(3), "looking for relevant NSEC3");
  959. dns_fixedname_init(&fzone);
  960. zone = dns_fixedname_name(&fzone);
  961. zlabels = dns_name_countlabels(nsec3name);
  962. /*
  963. * NSEC3 records must have two or more labels to be valid.
  964. */
  965. if (zlabels < 2)
  966. return (ISC_R_IGNORE);
  967. /*
  968. * Strip off the NSEC3 hash to get the zone.
  969. */
  970. zlabels--;
  971. dns_name_split(nsec3name, zlabels, NULL, zone);
  972. /*
  973. * If not below the zone name we can ignore this record.
  974. */
  975. if (!dns_name_issubdomain(name, zone))
  976. return (ISC_R_IGNORE);
  977. /*
  978. * Is this zone the same or deeper than the current zone?
  979. */
  980. if (dns_name_countlabels(zonename) == 0 ||
  981. dns_name_issubdomain(zone, zonename))
  982. dns_name_copy(zone, zonename, NULL);
  983. if (!dns_name_equal(zone, zonename))
  984. return (ISC_R_IGNORE);
  985. /*
  986. * Are we only looking for the most enclosing zone?
  987. */
  988. if (exists == NULL || data == NULL)
  989. return (ISC_R_SUCCESS);
  990. /*
  991. * Only set unknown once we are sure that this NSEC3 is from
  992. * the deepest covering zone.
  993. */
  994. if (!dns_nsec3_supportedhash(nsec3.hash)) {
  995. if (unknown != NULL)
  996. *unknown = ISC_TRUE;
  997. return (ISC_R_IGNORE);
  998. }
  999. /*
  1000. * Recover the hash from the first label.
  1001. */
  1002. dns_name_getlabel(nsec3name, 0, &hashlabel);
  1003. isc_region_consume(&hashlabel, 1);
  1004. isc_buffer_init(&buffer, owner, sizeof(owner));
  1005. result = isc_base32hex_decoderegion(&hashlabel, &buffer);
  1006. if (result != ISC_R_SUCCESS)
  1007. return (result);
  1008. /*
  1009. * The hash lengths should match. If not ignore the record.
  1010. */
  1011. if (isc_buffer_usedlength(&buffer) != nsec3.next_length)
  1012. return (ISC_R_IGNORE);
  1013. /*
  1014. * Work out what this NSEC3 covers.
  1015. * Inside (<0) or outside (>=0).
  1016. */
  1017. scope = memcmp(owner, nsec3.next, nsec3.next_length);
  1018. /*
  1019. * Prepare to compute all the hashes.
  1020. */
  1021. dns_fixedname_init(&qfixed);
  1022. qname = dns_fixedname_name(&qfixed);
  1023. dns_name_downcase(name, qname, NULL);
  1024. qlabels = dns_name_countlabels(qname);
  1025. first = ISC_TRUE;
  1026. while (qlabels >= zlabels) {
  1027. length = isc_iterated_hash(hash, nsec3.hash, nsec3.iterations,
  1028. nsec3.salt, nsec3.salt_length,
  1029. qname->ndata, qname->length);
  1030. /*
  1031. * The computed hash length should match.
  1032. */
  1033. if (length != nsec3.next_length) {
  1034. validator_log(val, ISC_LOG_DEBUG(3),
  1035. "ignoring NSEC bad length %u vs %u",
  1036. length, nsec3.next_length);
  1037. return (ISC_R_IGNORE);
  1038. }
  1039. order = memcmp(hash, owner, length);
  1040. if (first && order == 0) {
  1041. /*
  1042. * The hashes are the same.
  1043. */
  1044. atparent = dns_rdatatype_atparent(val->event->type);
  1045. ns = dns_nsec3_typepresent(&rdata, dns_rdatatype_ns);
  1046. soa = dns_nsec3_typepresent(&rdata, dns_rdatatype_soa);
  1047. if (ns && !soa) {
  1048. if (!atparent) {
  1049. /*
  1050. * This NSEC3 record is from somewhere
  1051. * higher in the DNS, and at the
  1052. * parent of a delegation. It can not
  1053. * be legitimately used here.
  1054. */
  1055. validator_log(val, ISC_LOG_DEBUG(3),
  1056. "ignoring parent NSEC3");
  1057. return (ISC_R_IGNORE);
  1058. }
  1059. } else if (atparent && ns && soa) {
  1060. /*
  1061. * This NSEC3 record is from the child.
  1062. * It can not be legitimately used here.
  1063. */
  1064. validator_log(val, ISC_LOG_DEBUG(3),
  1065. "ignoring child NSEC3");
  1066. return (ISC_R_IGNORE);
  1067. }
  1068. if (val->event->type == dns_rdatatype_cname ||
  1069. val->event->type == dns_rdatatype_nxt ||
  1070. val->event->type == dns_rdatatype_nsec ||
  1071. val->event->type == dns_rdatatype_key ||
  1072. !dns_nsec3_typepresent(&rdata, dns_rdatatype_cname)) {
  1073. *exists = ISC_TRUE;
  1074. *data = dns_nsec3_typepresent(&rdata,
  1075. val->event->type);
  1076. validator_log(val, ISC_LOG_DEBUG(3),
  1077. "NSEC3 proves name exists (owner) "
  1078. "data=%d", *data);
  1079. return (ISC_R_SUCCESS);
  1080. }
  1081. validator_log(val, ISC_LOG_DEBUG(3),
  1082. "NSEC3 proves CNAME exists");
  1083. return (ISC_R_IGNORE);
  1084. }
  1085. if (order == 0 &&
  1086. dns_nsec3_typepresent(&rdata, dns_rdatatype_ns) &&
  1087. !dns_nsec3_typepresent(&rdata, dns_rdatatype_soa))
  1088. {
  1089. /*
  1090. * This NSEC3 record is from somewhere higher in
  1091. * the DNS, and at the parent of a delegation.
  1092. * It can not be legitimately used here.
  1093. */
  1094. validator_log(val, ISC_LOG_DEBUG(3),
  1095. "ignoring parent NSEC3");
  1096. return (ISC_R_IGNORE);
  1097. }
  1098. /*
  1099. * Potential closest encloser.
  1100. */
  1101. if (order == 0) {
  1102. if (closest != NULL &&
  1103. (dns_name_countlabels(closest) == 0 ||
  1104. dns_name_issubdomain(qname, closest)) &&
  1105. !dns_nsec3_typepresent(&rdata, dns_rdatatype_ds) &&
  1106. !dns_nsec3_typepresent(&rdata, dns_rdatatype_dname) &&
  1107. (dns_nsec3_typepresent(&rdata, dns_rdatatype_soa) ||
  1108. !dns_nsec3_typepresent(&rdata, dns_rdatatype_ns)))
  1109. {
  1110. dns_name_format(qname, namebuf,
  1111. sizeof(namebuf));
  1112. validator_log(val, ISC_LOG_DEBUG(3),
  1113. "NSEC3 indicates potential "
  1114. "closest encloser: '%s'",
  1115. namebuf);
  1116. dns_name_copy(qname, closest, NULL);
  1117. *setclosest = ISC_TRUE;
  1118. }
  1119. dns_name_format(qname, namebuf, sizeof(namebuf));
  1120. validator_log(val, ISC_LOG_DEBUG(3),
  1121. "NSEC3 at super-domain %s", namebuf);
  1122. return (answer);
  1123. }
  1124. /*
  1125. * Find if the name does not exist.
  1126. *
  1127. * We continue as we need to find the name closest to the
  1128. * closest encloser that doesn't exist.
  1129. *
  1130. * We also need to continue to ensure that we are not
  1131. * proving the non-existence of a record in a sub-zone.
  1132. * If that would be the case we will return ISC_R_IGNORE
  1133. * above.
  1134. */
  1135. if ((scope < 0 && order > 0 &&
  1136. memcmp(hash, nsec3.next, length) < 0) ||
  1137. (scope >= 0 && (order > 0 ||
  1138. memcmp(hash, nsec3.next, length) < 0)))
  1139. {
  1140. char namebuf[DNS_NAME_FORMATSIZE];
  1141. dns_name_format(qname, namebuf, sizeof(namebuf));
  1142. validator_log(val, ISC_LOG_DEBUG(3), "NSEC3 proves "
  1143. "name does not exist: '%s'", namebuf);
  1144. if (nearest != NULL &&
  1145. (dns_name_countlabels(nearest) == 0 ||
  1146. dns_name_issubdomain(nearest, qname))) {
  1147. dns_name_copy(qname, nearest, NULL);
  1148. *setnearest = ISC_TRUE;
  1149. }
  1150. *exists = ISC_FALSE;
  1151. *data = ISC_FALSE;
  1152. if (optout != NULL) {
  1153. if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0)
  1154. validator_log(val, ISC_LOG_DEBUG(3),
  1155. "NSEC3 indicates optout");
  1156. *optout =
  1157. ISC_TF(nsec3.flags & DNS_NSEC3FLAG_OPTOUT);
  1158. }
  1159. answer = ISC_R_SUCCESS;
  1160. }
  1161. qlabels--;
  1162. if (qlabels > 0)
  1163. dns_name_split(qname, qlabels, NULL, qname);
  1164. first = ISC_FALSE;
  1165. }
  1166. return (answer);
  1167. }
  1168. /*%
  1169. * Callback for when NSEC records have been validated.
  1170. *
  1171. * Looks for NOQNAME, NODATA and OPTOUT proofs.
  1172. *
  1173. * Resumes nsecvalidate.
  1174. */
  1175. static void
  1176. authvalidated(isc_task_t *task, isc_event_t *event) {
  1177. dns_validatorevent_t *devent;
  1178. dns_validator_t *val;
  1179. dns_rdataset_t *rdataset;
  1180. isc_boolean_t want_destroy;
  1181. isc_result_t result;
  1182. isc_boolean_t exists, data;
  1183. UNUSED(task);
  1184. INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
  1185. devent = (dns_validatorevent_t *)event;
  1186. rdataset = devent->rdataset;
  1187. val = devent->ev_arg;
  1188. result = devent->result;
  1189. dns_validator_destroy(&val->subvalidator);
  1190. INSIST(val->event != NULL);
  1191. validator_log(val, ISC_LOG_DEBUG(3), "in authvalidated");
  1192. LOCK(&val->lock);
  1193. if (CANCELED(val)) {
  1194. validator_done(val, ISC_R_CANCELED);
  1195. } else if (result != ISC_R_SUCCESS) {
  1196. validator_log(val, ISC_LOG_DEBUG(3),
  1197. "authvalidated: got %s",
  1198. isc_result_totext(result));
  1199. if (result == DNS_R_BROKENCHAIN)
  1200. val->authfail++;
  1201. if (result == ISC_R_CANCELED)
  1202. validator_done(val, result);
  1203. else {
  1204. result = nsecvalidate(val, ISC_TRUE);
  1205. if (result != DNS_R_WAIT)
  1206. validator_done(val, result);
  1207. }
  1208. } else {
  1209. dns_name_t **proofs = val->event->proofs;
  1210. dns_name_t *wild = dns_fixedname_name(&val->wild);
  1211. if (rdataset->trust == dns_trust_secure)
  1212. val->seensig = ISC_TRUE;
  1213. if (rdataset->type == dns_rdatatype_nsec &&
  1214. rdataset->trust == dns_trust_secure &&
  1215. (NEEDNODATA(val) || NEEDNOQNAME(val)) &&
  1216. !FOUNDNODATA(val) && !FOUNDNOQNAME(val) &&
  1217. nsecnoexistnodata(val, val->event->name, devent->name,
  1218. rdataset, &exists, &data, wild)
  1219. == ISC_R_SUCCESS)
  1220. {
  1221. if (exists && !data) {
  1222. val->attributes |= VALATTR_FOUNDNODATA;
  1223. if (NEEDNODATA(val))
  1224. proofs[DNS_VALIDATOR_NODATAPROOF] =
  1225. devent->name;
  1226. }
  1227. if (!exists) {
  1228. val->attributes |= VALATTR_FOUNDNOQNAME;
  1229. val->attributes |= VALATTR_FOUNDCLOSEST;
  1230. /*
  1231. * The NSEC noqname proof also contains
  1232. * the closest encloser.
  1233. */
  1234. if (NEEDNOQNAME(val))
  1235. proofs[DNS_VALIDATOR_NOQNAMEPROOF] =
  1236. devent->name;
  1237. }
  1238. }
  1239. result = nsecvalidate(val, ISC_TRUE);
  1240. if (result != DNS_R_WAIT)
  1241. validator_done(val, result);
  1242. }
  1243. want_destroy = exit_check(val);
  1244. UNLOCK(&val->lock);
  1245. if (want_destroy)
  1246. destroy(val);
  1247. /*
  1248. * Free stuff from the event.
  1249. */
  1250. isc_event_free(&event);
  1251. }
  1252. /*%
  1253. * Looks for the requested name and type in the view (zones and cache).
  1254. *
  1255. * When looking for a DLV record also checks to make sure the NSEC record
  1256. * returns covers the query name as part of aggressive negative caching.
  1257. *
  1258. * Returns:
  1259. * \li ISC_R_SUCCESS
  1260. * \li ISC_R_NOTFOUND
  1261. * \li DNS_R_NCACHENXDOMAIN
  1262. * \li DNS_R_NCACHENXRRSET
  1263. * \li DNS_R_NXRRSET
  1264. * \li DNS_R_NXDOMAIN
  1265. * \li DNS_R_BROKENCHAIN
  1266. */
  1267. static inline isc_result_t
  1268. view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
  1269. dns_fixedname_t fixedname;
  1270. dns_name_t *foundname;
  1271. dns_rdata_nsec_t nsec;
  1272. dns_rdata_t rdata = DNS_RDATA_INIT;
  1273. isc_result_t result;
  1274. unsigned int options;
  1275. isc_time_t now;
  1276. char buf1[DNS_NAME_FORMATSIZE];
  1277. char buf2[DNS_NAME_FORMATSIZE];
  1278. char buf3[DNS_NAME_FORMATSIZE];
  1279. char namebuf[DNS_NAME_FORMATSIZE];
  1280. char typebuf[DNS_RDATATYPE_FORMATSIZE];
  1281. if (dns_rdataset_isassociated(&val->frdataset))
  1282. dns_rdataset_disassociate(&val->frdataset);
  1283. if (dns_rdataset_isassociated(&val->fsigrdataset))
  1284. dns_rdataset_disassociate(&val->fsigrdataset);
  1285. if (val->view->zonetable == NULL)
  1286. return (ISC_R_CANCELED);
  1287. if (isc_time_now(&now) == ISC_R_SUCCESS &&
  1288. dns_resolver_getbadcache(val->view->resolver, name, type, &now)) {
  1289. dns_name_format(name, namebuf, sizeof(namebuf));
  1290. dns_rdatatype_format(type, typebuf, sizeof(typebuf));
  1291. validator_log(val, ISC_LOG_INFO, "bad cache hit (%s/%s)",
  1292. namebuf, typebuf);
  1293. return (DNS_R_BROKENCHAIN);
  1294. }
  1295. options = DNS_DBFIND_PENDINGOK;
  1296. if (type == dns_rdatatype_dlv)
  1297. options |= DNS_DBFIND_COVERINGNSEC;
  1298. dns_fixedname_init(&fixedname);
  1299. foundname = dns_fixedname_name(&fixedname);
  1300. result = dns_view_find(val->view, name, type, 0, options,
  1301. ISC_FALSE, NULL, NULL, foundname,
  1302. &val->frdataset, &val->fsigrdataset);
  1303. if (result == DNS_R_NXDOMAIN) {
  1304. if (dns_rdataset_isassociated(&val->frdataset))
  1305. dns_rdataset_disassociate(&val->frdataset);
  1306. if (dns_rdataset_isassociated(&val->fsigrdataset))
  1307. dns_rdataset_disassociate(&val->fsigrdataset);
  1308. } else if (result == DNS_R_COVERINGNSEC) {
  1309. validator_log(val, ISC_LOG_DEBUG(3), "DNS_R_COVERINGNSEC");
  1310. /*
  1311. * Check if the returned NSEC covers the name.
  1312. */
  1313. INSIST(type == dns_rdatatype_dlv);
  1314. if (val->frdataset.trust != dns_trust_secure) {
  1315. validator_log(val, ISC_LOG_DEBUG(3),
  1316. "covering nsec: trust %s",
  1317. dns_trust_totext(val->frdataset.trust));
  1318. goto notfound;
  1319. }
  1320. result = dns_rdataset_first(&val->frdataset);
  1321. if (result != ISC_R_SUCCESS)
  1322. goto notfound;
  1323. dns_rdataset_current(&val->frdataset, &rdata);
  1324. if (dns_nsec_typepresent(&rdata, dns_rdatatype_ns) &&
  1325. !dns_nsec_typepresent(&rdata, dns_rdatatype_soa)) {
  1326. /* Parent NSEC record. */
  1327. if (dns_name_issubdomain(name, foundname)) {
  1328. validator_log(val, ISC_LOG_DEBUG(3),
  1329. "covering nsec: for parent");
  1330. goto notfound;
  1331. }
  1332. }
  1333. result = dns_rdata_tostruct(&rdata, &nsec, NULL);
  1334. if (result != ISC_R_SUCCESS)
  1335. goto notfound;
  1336. if (dns_name_compare(foundname, &nsec.next) >= 0) {
  1337. /* End of zone chain. */
  1338. if (!dns_name_issubdomain(name, &nsec.next)) {
  1339. /*
  1340. * XXXMPA We could look for a parent NSEC
  1341. * at nsec.next and if found retest with
  1342. * this NSEC.
  1343. */
  1344. dns_rdata_freestruct(&nsec);
  1345. validator_log(val, ISC_LOG_DEBUG(3),
  1346. "covering nsec: not in zone");
  1347. goto notfound;
  1348. }
  1349. } else if (dns_name_compare(name, &nsec.next) >= 0) {
  1350. /*
  1351. * XXXMPA We could check if this NSEC is at a zone
  1352. * apex and if the qname is not below it and look for
  1353. * a parent NSEC with the same name. This requires
  1354. * that we can cache both NSEC records which we
  1355. * currently don't support.
  1356. */
  1357. dns_rdata_freestruct(&nsec);
  1358. validator_log(val, ISC_LOG_DEBUG(3),
  1359. "covering nsec: not in range");
  1360. goto notfound;
  1361. }
  1362. if (isc_log_wouldlog(dns_lctx,ISC_LOG_DEBUG(3))) {
  1363. dns_name_format(name, buf1, sizeof buf1);
  1364. dns_name_format(foundname, buf2, sizeof buf2);
  1365. dns_name_format(&nsec.next, buf3, sizeof buf3);
  1366. validator_log(val, ISC_LOG_DEBUG(3),
  1367. "covering nsec found: '%s' '%s' '%s'",
  1368. buf1, buf2, buf3);
  1369. }
  1370. if (dns_rdataset_isassociated(&val->frdataset))
  1371. dns_rdataset_disassociate(&val->frdataset);
  1372. if (dns_rdataset_isassociated(&val->fsigrdataset))
  1373. dns_rdataset_disassociate(&val->fsigrdataset);
  1374. dns_rdata_freestruct(&nsec);
  1375. result = DNS_R_NCACHENXDOMAIN;
  1376. } else if (result != ISC_R_SUCCESS &&
  1377. result != DNS_R_NCACHENXDOMAIN &&
  1378. result != DNS_R_NCACHENXRRSET &&
  1379. result != DNS_R_EMPTYNAME &&
  1380. result != DNS_R_NXRRSET &&
  1381. result != ISC_R_NOTFOUND) {
  1382. goto notfound;
  1383. }
  1384. return (result);
  1385. notfound:
  1386. if (dns_rdataset_isassociated(&val->frdataset))
  1387. dns_rdataset_disassociate(&val->frdataset);
  1388. if (dns_rdataset_isassociated(&val->fsigrdataset))
  1389. dns_rdataset_disassociate(&val->fsigrdataset);
  1390. return (ISC_R_NOTFOUND);
  1391. }
  1392. /*%
  1393. * Checks to make sure we are not going to loop. As we use a SHARED fetch
  1394. * the validation process will stall if looping was to occur.
  1395. */
  1396. static inline isc_boolean_t
  1397. check_deadlock(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
  1398. dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
  1399. {
  1400. dns_validator_t *parent;
  1401. for (parent = val; parent != NULL; parent = parent->parent) {
  1402. if (parent->event != NULL &&
  1403. parent->event->type == type &&
  1404. dns_name_equal(parent->event->name, name) &&
  1405. /*
  1406. * As NSEC3 records are meta data you sometimes
  1407. * need to prove a NSEC3 record which says that
  1408. * itself doesn't exist.
  1409. */
  1410. (parent->event->type != dns_rdatatype_nsec3 ||
  1411. rdataset == NULL || sigrdataset == NULL ||
  1412. parent->event->message == NULL ||
  1413. parent->event->rdataset != NULL ||
  1414. parent->event->sigrdataset != NULL))
  1415. {
  1416. validator_log(val, ISC_LOG_DEBUG(3),
  1417. "continuing validation would lead to "
  1418. "deadlock: aborting validation");
  1419. return (ISC_TRUE);
  1420. }
  1421. }
  1422. return (ISC_FALSE);
  1423. }
  1424. /*%
  1425. * Start a fetch for the requested name and type.
  1426. */
  1427. static inline isc_result_t
  1428. create_fetch(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
  1429. isc_taskaction_t callback, const char *caller)
  1430. {
  1431. if (dns_rdataset_isassociated(&val->frdataset))
  1432. dns_rdataset_disassociate(&val->frdataset);
  1433. if (dns_rdataset_isassociated(&val->fsigrdataset))
  1434. dns_rdataset_disassociate(&val->fsigrdataset);
  1435. if (check_deadlock(val, name, type, NULL, NULL)) {
  1436. validator_log(val, ISC_LOG_DEBUG(3),
  1437. "deadlock found (create_fetch)");
  1438. return (DNS_R_NOVALIDSIG);
  1439. }
  1440. validator_logcreate(val, name, type, caller, "fetch");
  1441. return (dns_resolver_createfetch(val->view->resolver, name, type,
  1442. NULL, NULL, NULL, 0,
  1443. val->event->ev_sender,
  1444. callback, val,
  1445. &val->frdataset,
  1446. &val->fsigrdataset,
  1447. &val->fetch));
  1448. }
  1449. /*%
  1450. * Start a subvalidation process.
  1451. */
  1452. static inline isc_result_t
  1453. create_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
  1454. dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
  1455. isc_taskaction_t action, const char *caller)
  1456. {
  1457. isc_result_t result;
  1458. if (check_deadlock(val, name, type, rdataset, sigrdataset)) {
  1459. validator_log(val, ISC_LOG_DEBUG(3),
  1460. "deadlock found (create_validator)");
  1461. return (DNS_R_NOVALIDSIG);
  1462. }
  1463. validator_logcreate(val, name, type, caller, "validator");
  1464. result = dns_validator_create(val->view, name, type,
  1465. rdataset, sigrdataset, NULL, 0,
  1466. val->task, action, val,
  1467. &val->subvalidator);
  1468. if (result == ISC_R_SUCCESS) {
  1469. val->subvalidator->parent = val;
  1470. val->subvalidator->depth = val->depth + 1;
  1471. }
  1472. return (result);
  1473. }
  1474. /*%
  1475. * Try to find a key that could have signed 'siginfo' among those
  1476. * in 'rdataset'. If found, build a dst_key_t for it and point
  1477. * val->key at it.
  1478. *
  1479. * If val->key is non-NULL, this returns the next matching key.
  1480. */
  1481. static isc_result_t
  1482. get_dst_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo,
  1483. dns_rdataset_t *rdataset)
  1484. {
  1485. isc_result_t result;
  1486. isc_buffer_t b;
  1487. dns_rdata_t rdata = DNS_RDATA_INIT;
  1488. dst_key_t *oldkey = val->key;
  1489. isc_boolean_t foundold;
  1490. if (oldkey == NULL)
  1491. foundold = ISC_TRUE;
  1492. else {
  1493. foundold = ISC_FALSE;
  1494. val->key = NULL;
  1495. }
  1496. result = dns_rdataset_first(rdataset);
  1497. if (result != ISC_R_SUCCESS)
  1498. goto failure;
  1499. do {
  1500. dns_rdataset_current(rdataset, &rdata);
  1501. isc_buffer_init(&b, rdata.data, rdata.length);
  1502. isc_buffer_add(&b, rdata.length);
  1503. INSIST(val->key == NULL);
  1504. result = dst_key_fromdns(&siginfo->signer, rdata.rdclass, &b,
  1505. val->view->mctx, &val->key);
  1506. if (result != ISC_R_SUCCESS)
  1507. goto failure;
  1508. if (siginfo->algorithm ==
  1509. (dns_secalg_t)dst_key_alg(val->key) &&
  1510. siginfo->keyid ==
  1511. (dns_keytag_t)dst_key_id(val->key) &&
  1512. dst_key_iszonekey(val->key))
  1513. {
  1514. if (foundold)
  1515. /*
  1516. * This is the key we're looking for.
  1517. */
  1518. return (ISC_R_SUCCESS);
  1519. else if (dst_key_compare(oldkey, val->key) == ISC_TRUE)
  1520. {
  1521. foundold = ISC_TRUE;
  1522. dst_key_free(&oldkey);
  1523. }
  1524. }
  1525. dst_key_free(&val->key);
  1526. dns_rdata_reset(&rdata);
  1527. result = dns_rdataset_next(rdataset);
  1528. } while (result == ISC_R_SUCCESS);
  1529. if (result == ISC_R_NOMORE)
  1530. result = ISC_R_NOTFOUND;
  1531. failure:
  1532. if (oldkey != NULL)
  1533. dst_key_free(&oldkey);
  1534. return (result);
  1535. }
  1536. /*%
  1537. * Get the key that generated this signature.
  1538. */
  1539. static isc_result_t
  1540. get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) {
  1541. isc_result_t result;
  1542. unsigned int nlabels;
  1543. int order;
  1544. dns_namereln_t namereln;
  1545. /*
  1546. * Is the signer name appropriate for this signature?
  1547. *
  1548. * The signer name must be at the same level as the owner name
  1549. * or closer to the DNS root.
  1550. */
  1551. namereln = dns_name_fullcompare(val->event->name, &siginfo->signer,
  1552. &order, &nlabels);
  1553. if (namereln != dns_namereln_subdomain &&
  1554. namereln != dns