PageRenderTime 64ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/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
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-3-Clause, LGPL-2.0, LGPL-2.1, BSD-2-Clause, 0BSD, JSON, AGPL-1.0, GPL-2.0
  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_namereln_equal)
  1555. return (DNS_R_CONTINUE);
  1556. if (namereln == dns_namereln_equal) {
  1557. /*
  1558. * If this is a self-signed keyset, it must not be a zone key
  1559. * (since get_key is not called from validatezonekey).
  1560. */
  1561. if (val->event->rdataset->type == dns_rdatatype_dnskey)
  1562. return (DNS_R_CONTINUE);
  1563. /*
  1564. * Records appearing in the parent zone at delegation
  1565. * points cannot be self-signed.
  1566. */
  1567. if (dns_rdatatype_atparent(val->event->rdataset->type))
  1568. return (DNS_R_CONTINUE);
  1569. } else {
  1570. /*
  1571. * SOA and NS RRsets can only be signed by a key with
  1572. * the same name.
  1573. */
  1574. if (val->event->rdataset->type == dns_rdatatype_soa ||
  1575. val->event->rdataset->type == dns_rdatatype_ns) {
  1576. const char *typename;
  1577. if (val->event->rdataset->type == dns_rdatatype_soa)
  1578. typename = "SOA";
  1579. else
  1580. typename = "NS";
  1581. validator_log(val, ISC_LOG_DEBUG(3),
  1582. "%s signer mismatch", typename);
  1583. return (DNS_R_CONTINUE);
  1584. }
  1585. }
  1586. /*
  1587. * Do we know about this key?
  1588. */
  1589. result = view_find(val, &siginfo->signer, dns_rdatatype_dnskey);
  1590. if (result == ISC_R_SUCCESS) {
  1591. /*
  1592. * We have an rrset for the given keyname.
  1593. */
  1594. val->keyset = &val->frdataset;
  1595. if ((DNS_TRUST_PENDING(val->frdataset.trust) ||
  1596. DNS_TRUST_ANSWER(val->frdataset.trust)) &&
  1597. dns_rdataset_isassociated(&val->fsigrdataset))
  1598. {
  1599. /*
  1600. * We know the key but haven't validated it yet or
  1601. * we have a key of trust answer but a DS/DLV
  1602. * record for the zone may have been added.
  1603. */
  1604. result = create_validator(val, &siginfo->signer,
  1605. dns_rdatatype_dnskey,
  1606. &val->frdataset,
  1607. &val->fsigrdataset,
  1608. keyvalidated,
  1609. "get_key");
  1610. if (result != ISC_R_SUCCESS)
  1611. return (result);
  1612. return (DNS_R_WAIT);
  1613. } else if (DNS_TRUST_PENDING(val->frdataset.trust)) {
  1614. /*
  1615. * Having a pending key with no signature means that
  1616. * something is broken.
  1617. */
  1618. result = DNS_R_CONTINUE;
  1619. } else if (val->frdataset.trust < dns_trust_secure) {
  1620. /*
  1621. * The key is legitimately insecure. There's no
  1622. * point in even attempting verification.
  1623. */
  1624. val->key = NULL;
  1625. result = ISC_R_SUCCESS;
  1626. } else {
  1627. /*
  1628. * See if we've got the key used in the signature.
  1629. */
  1630. validator_log(val, ISC_LOG_DEBUG(3),
  1631. "keyset with trust %s",
  1632. dns_trust_totext(val->frdataset.trust));
  1633. result = get_dst_key(val, siginfo, val->keyset);
  1634. if (result != ISC_R_SUCCESS) {
  1635. /*
  1636. * Either the key we're looking for is not
  1637. * in the rrset, or something bad happened.
  1638. * Give up.
  1639. */
  1640. result = DNS_R_CONTINUE;
  1641. }
  1642. }
  1643. } else if (result == ISC_R_NOTFOUND) {
  1644. /*
  1645. * We don't know anything about this key.
  1646. */
  1647. result = create_fetch(val, &siginfo->signer,
  1648. dns_rdatatype_dnskey,
  1649. fetch_callback_validator, "get_key");
  1650. if (result != ISC_R_SUCCESS)
  1651. return (result);
  1652. return (DNS_R_WAIT);
  1653. } else if (result == DNS_R_NCACHENXDOMAIN ||
  1654. result == DNS_R_NCACHENXRRSET ||
  1655. result == DNS_R_EMPTYNAME ||
  1656. result == DNS_R_NXDOMAIN ||
  1657. result == DNS_R_NXRRSET)
  1658. {
  1659. /*
  1660. * This key doesn't exist.
  1661. */
  1662. result = DNS_R_CONTINUE;
  1663. } else if (result == DNS_R_BROKENCHAIN)
  1664. return (result);
  1665. if (dns_rdataset_isassociated(&val->frdataset) &&
  1666. val->keyset != &val->frdataset)
  1667. dns_rdataset_disassociate(&val->frdataset);
  1668. if (dns_rdataset_isassociated(&val->fsigrdataset))
  1669. dns_rdataset_disassociate(&val->fsigrdataset);
  1670. return (result);
  1671. }
  1672. static dns_keytag_t
  1673. compute_keytag(dns_rdata_t *rdata, dns_rdata_dnskey_t *key) {
  1674. isc_region_t r;
  1675. dns_rdata_toregion(rdata, &r);
  1676. return (dst_region_computeid(&r, key->algorithm));
  1677. }
  1678. /*%
  1679. * Is this keyset self-signed?
  1680. */
  1681. static isc_boolean_t
  1682. isselfsigned(dns_validator_t *val) {
  1683. dns_fixedname_t fixed;
  1684. dns_rdataset_t *rdataset, *sigrdataset;
  1685. dns_rdata_t rdata = DNS_RDATA_INIT;
  1686. dns_rdata_t sigrdata = DNS_RDATA_INIT;
  1687. dns_rdata_dnskey_t key;
  1688. dns_rdata_rrsig_t sig;
  1689. dns_keytag_t keytag;
  1690. dns_name_t *name;
  1691. isc_result_t result;
  1692. dst_key_t *dstkey;
  1693. isc_mem_t *mctx;
  1694. isc_boolean_t answer = ISC_FALSE;
  1695. rdataset = val->event->rdataset;
  1696. sigrdataset = val->event->sigrdataset;
  1697. name = val->event->name;
  1698. mctx = val->view->mctx;
  1699. INSIST(rdataset->type == dns_rdatatype_dnskey);
  1700. for (result = dns_rdataset_first(rdataset);
  1701. result == ISC_R_SUCCESS;
  1702. result = dns_rdataset_next(rdataset))
  1703. {
  1704. dns_rdata_reset(&rdata);
  1705. dns_rdataset_current(rdataset, &rdata);
  1706. result = dns_rdata_tostruct(&rdata, &key, NULL);
  1707. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  1708. keytag = compute_keytag(&rdata, &key);
  1709. for (result = dns_rdataset_first(sigrdataset);
  1710. result == ISC_R_SUCCESS;
  1711. result = dns_rdataset_next(sigrdataset))
  1712. {
  1713. dns_rdata_reset(&sigrdata);
  1714. dns_rdataset_current(sigrdataset, &sigrdata);
  1715. result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
  1716. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  1717. if (sig.algorithm != key.algorithm ||
  1718. sig.keyid != keytag ||
  1719. !dns_name_equal(name, &sig.signer))
  1720. continue;
  1721. dstkey = NULL;
  1722. result = dns_dnssec_keyfromrdata(name, &rdata, mctx,
  1723. &dstkey);
  1724. if (result != ISC_R_SUCCESS)
  1725. continue;
  1726. result = dns_dnssec_verify2(name, rdataset, dstkey,
  1727. ISC_TRUE, mctx, &sigrdata,
  1728. dns_fixedname_name(&fixed));
  1729. dst_key_free(&dstkey);
  1730. if (result != ISC_R_SUCCESS)
  1731. continue;
  1732. if ((key.flags & DNS_KEYFLAG_REVOKE) == 0) {
  1733. answer = ISC_TRUE;
  1734. continue;
  1735. }
  1736. dns_view_untrust(val->view, name, &key, mctx);
  1737. }
  1738. }
  1739. return (answer);
  1740. }
  1741. /*%
  1742. * Attempt to verify the rdataset using the given key and rdata (RRSIG).
  1743. * The signature was good and from a wildcard record and the QNAME does
  1744. * not match the wildcard we need to look for a NOQNAME proof.
  1745. *
  1746. * Returns:
  1747. * \li ISC_R_SUCCESS if the verification succeeds.
  1748. * \li Others if the verification fails.
  1749. */
  1750. static isc_result_t
  1751. verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata,
  1752. isc_uint16_t keyid)
  1753. {
  1754. isc_result_t result;
  1755. dns_fixedname_t fixed;
  1756. isc_boolean_t ignore = ISC_FALSE;
  1757. dns_name_t *wild;
  1758. val->attributes |= VALATTR_TRIEDVERIFY;
  1759. dns_fixedname_init(&fixed);
  1760. wild = dns_fixedname_name(&fixed);
  1761. again:
  1762. result = dns_dnssec_verify2(val->event->name, val->event->rdataset,
  1763. key, ignore, val->view->mctx, rdata, wild);
  1764. if ((result == DNS_R_SIGEXPIRED || result == DNS_R_SIGFUTURE) &&
  1765. val->view->acceptexpired)
  1766. {
  1767. ignore = ISC_TRUE;
  1768. goto again;
  1769. }
  1770. if (ignore && (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD))
  1771. validator_log(val, ISC_LOG_INFO,
  1772. "accepted expired %sRRSIG (keyid=%u)",
  1773. (result == DNS_R_FROMWILDCARD) ?
  1774. "wildcard " : "", keyid);
  1775. else if (result == DNS_R_SIGEXPIRED || result == DNS_R_SIGFUTURE)
  1776. validator_log(val, ISC_LOG_INFO,
  1777. "verify failed due to bad signature (keyid=%u): "
  1778. "%s", keyid, isc_result_totext(result));
  1779. else
  1780. validator_log(val, ISC_LOG_DEBUG(3),
  1781. "verify rdataset (keyid=%u): %s",
  1782. keyid, isc_result_totext(result));
  1783. if (result == DNS_R_FROMWILDCARD) {
  1784. if (!dns_name_equal(val->event->name, wild)) {
  1785. dns_name_t *closest;
  1786. unsigned int labels;
  1787. /*
  1788. * Compute the closest encloser in case we need it
  1789. * for the NSEC3 NOQNAME proof.
  1790. */
  1791. closest = dns_fixedname_name(&val->closest);
  1792. dns_name_copy(wild, closest, NULL);
  1793. labels = dns_name_countlabels(closest) - 1;
  1794. dns_name_getlabelsequence(closest, 1, labels, closest);
  1795. val->attributes |= VALATTR_NEEDNOQNAME;
  1796. }
  1797. result = ISC_R_SUCCESS;
  1798. }
  1799. return (result);
  1800. }
  1801. /*%
  1802. * Attempts positive response validation of a normal RRset.
  1803. *
  1804. * Returns:
  1805. * \li ISC_R_SUCCESS Validation completed successfully
  1806. * \li DNS_R_WAIT Validation has started but is waiting
  1807. * for an event.
  1808. * \li Other return codes are possible and all indicate failure.
  1809. */
  1810. static isc_result_t
  1811. validate(dns_validator_t *val, isc_boolean_t resume) {
  1812. isc_result_t result;
  1813. dns_validatorevent_t *event;
  1814. dns_rdata_t rdata = DNS_RDATA_INIT;
  1815. /*
  1816. * Caller must be holding the validator lock.
  1817. */
  1818. event = val->event;
  1819. if (resume) {
  1820. /*
  1821. * We already have a sigrdataset.
  1822. */
  1823. result = ISC_R_SUCCESS;
  1824. validator_log(val, ISC_LOG_DEBUG(3), "resuming validate");
  1825. } else {
  1826. result = dns_rdataset_first(event->sigrdataset);
  1827. }
  1828. for (;
  1829. result == ISC_R_SUCCESS;
  1830. result = dns_rdataset_next(event->sigrdataset))
  1831. {
  1832. dns_rdata_reset(&rdata);
  1833. dns_rdataset_current(event->sigrdataset, &rdata);
  1834. if (val->siginfo == NULL) {
  1835. val->siginfo = isc_mem_get(val->view->mctx,
  1836. sizeof(*val->siginfo));
  1837. if (val->siginfo == NULL)
  1838. return (ISC_R_NOMEMORY);
  1839. }
  1840. result = dns_rdata_tostruct(&rdata, val->siginfo, NULL);
  1841. if (result != ISC_R_SUCCESS)
  1842. return (result);
  1843. /*
  1844. * At this point we could check that the signature algorithm
  1845. * was known and "sufficiently good".
  1846. */
  1847. if (!dns_resolver_algorithm_supported(val->view->resolver,
  1848. event->name,
  1849. val->siginfo->algorithm)) {
  1850. resume = ISC_FALSE;
  1851. continue;
  1852. }
  1853. if (!resume) {
  1854. result = get_key(val, val->siginfo);
  1855. if (result == DNS_R_CONTINUE)
  1856. continue; /* Try the next SIG RR. */
  1857. if (result != ISC_R_SUCCESS)
  1858. return (result);
  1859. }
  1860. /*
  1861. * There isn't a secure DNSKEY for this signature so move
  1862. * onto the next RRSIG.
  1863. */
  1864. if (val->key == NULL) {
  1865. resume = ISC_FALSE;
  1866. continue;
  1867. }
  1868. do {
  1869. result = verify(val, val->key, &rdata,
  1870. val->siginfo->keyid);
  1871. if (result == ISC_R_SUCCESS)
  1872. break;
  1873. if (val->keynode != NULL) {
  1874. dns_keynode_t *nextnode = NULL;
  1875. result = dns_keytable_findnextkeynode(
  1876. val->keytable,
  1877. val->keynode,
  1878. &nextnode);
  1879. dns_keytable_detachkeynode(val->keytable,
  1880. &val->keynode);
  1881. val->keynode = nextnode;
  1882. if (result != ISC_R_SUCCESS) {
  1883. val->key = NULL;
  1884. break;
  1885. }
  1886. val->key = dns_keynode_key(val->keynode);
  1887. if (val->key == NULL)
  1888. break;
  1889. } else {
  1890. if (get_dst_key(val, val->siginfo, val->keyset)
  1891. != ISC_R_SUCCESS)
  1892. break;
  1893. }
  1894. } while (1);
  1895. if (result != ISC_R_SUCCESS)
  1896. validator_log(val, ISC_LOG_DEBUG(3),
  1897. "failed to verify rdataset");
  1898. else {
  1899. isc_uint32_t ttl;
  1900. isc_stdtime_t now;
  1901. isc_stdtime_get(&now);
  1902. ttl = ISC_MIN(event->rdataset->ttl,
  1903. ISC_MIN(val->siginfo->originalttl,
  1904. val->siginfo->timeexpire - now));
  1905. event->rdataset->ttl = ttl;
  1906. event->sigrdataset->ttl = ttl;
  1907. }
  1908. if (val->keynode != NULL)
  1909. dns_keytable_detachkeynode(val->keytable,
  1910. &val->keynode);
  1911. else {
  1912. if (val->key != NULL)
  1913. dst_key_free(&val->key);
  1914. if (val->keyset != NULL) {
  1915. dns_rdataset_disassociate(val->keyset);
  1916. val->keyset = NULL;
  1917. }
  1918. }
  1919. val->key = NULL;
  1920. if (NEEDNOQNAME(val)) {
  1921. if (val->event->message == NULL) {
  1922. validator_log(val, ISC_LOG_DEBUG(3),
  1923. "no message available for noqname proof");
  1924. return (DNS_R_NOVALIDSIG);
  1925. }
  1926. validator_log(val, ISC_LOG_DEBUG(3),
  1927. "looking for noqname proof");
  1928. return (nsecvalidate(val, ISC_FALSE));
  1929. } else if (result == ISC_R_SUCCESS) {
  1930. marksecure(event);
  1931. validator_log(val, ISC_LOG_DEBUG(3),
  1932. "marking as secure, "
  1933. "noqname proof not needed");
  1934. return (result);
  1935. } else {
  1936. validator_log(val, ISC_LOG_DEBUG(3),
  1937. "verify failure: %s",
  1938. isc_result_totext(result));
  1939. resume = ISC_FALSE;
  1940. }
  1941. }
  1942. if (result != ISC_R_NOMORE) {
  1943. validator_log(val, ISC_LOG_DEBUG(3),
  1944. "failed to iterate signatures: %s",
  1945. isc_result_totext(result));
  1946. return (result);
  1947. }
  1948. validator_log(val, ISC_LOG_INFO, "no valid signature found");
  1949. return (DNS_R_NOVALIDSIG);
  1950. }
  1951. /*%
  1952. * Check whether this DNSKEY (keyrdata) signed the DNSKEY RRset
  1953. * (val->event->rdataset).
  1954. */
  1955. static isc_result_t
  1956. checkkey(dns_validator_t *val, dns_rdata_t *keyrdata, isc_uint16_t keyid,
  1957. dns_secalg_t algorithm)
  1958. {
  1959. dns_rdata_rrsig_t sig;
  1960. dst_key_t *dstkey = NULL;
  1961. isc_result_t result;
  1962. for (result = dns_rdataset_first(val->event->sigrdataset);
  1963. result == ISC_R_SUCCESS;
  1964. result = dns_rdataset_next(val->event->sigrdataset))
  1965. {
  1966. dns_rdata_t rdata = DNS_RDATA_INIT;
  1967. dns_rdataset_current(val->event->sigrdataset, &rdata);
  1968. result = dns_rdata_tostruct(&rdata, &sig, NULL);
  1969. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  1970. if (keyid != sig.keyid || algorithm != sig.algorithm)
  1971. continue;
  1972. if (dstkey == NULL) {
  1973. result = dns_dnssec_keyfromrdata(val->event->name,
  1974. keyrdata,
  1975. val->view->mctx,
  1976. &dstkey);
  1977. if (result != ISC_R_SUCCESS)
  1978. /*
  1979. * This really shouldn't happen, but...
  1980. */
  1981. continue;
  1982. }
  1983. result = verify(val, dstkey, &rdata, sig.keyid);
  1984. if (result == ISC_R_SUCCESS)
  1985. break;
  1986. }
  1987. if (dstkey != NULL)
  1988. dst_key_free(&dstkey);
  1989. return (result);
  1990. }
  1991. /*%
  1992. * Find the DNSKEY that corresponds to the DS.
  1993. */
  1994. static isc_result_t
  1995. keyfromds(dns_validator_t *val, dns_rdataset_t *rdataset, dns_rdata_t *dsrdata,
  1996. isc_uint8_t digest, isc_uint16_t keyid, dns_secalg_t algorithm,
  1997. dns_rdata_t *keyrdata)
  1998. {
  1999. dns_keytag_t keytag;
  2000. dns_rdata_dnskey_t key;
  2001. isc_result_t result;
  2002. unsigned char dsbuf[DNS_DS_BUFFERSIZE];
  2003. for (result = dns_rdataset_first(rdataset);
  2004. result == ISC_R_SUCCESS;
  2005. result = dns_rdataset_next(rdataset))
  2006. {
  2007. dns_rdata_t newdsrdata = DNS_RDATA_INIT;
  2008. dns_rdata_reset(keyrdata);
  2009. dns_rdataset_current(rdataset, keyrdata);
  2010. result = dns_rdata_tostruct(keyrdata, &key, NULL);
  2011. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  2012. keytag = compute_keytag(keyrdata, &key);
  2013. if (keyid != keytag || algorithm != key.algorithm)
  2014. continue;
  2015. dns_rdata_reset(&newdsrdata);
  2016. result = dns_ds_buildrdata(val->event->name, keyrdata, digest,
  2017. dsbuf, &newdsrdata);
  2018. if (result != ISC_R_SUCCESS) {
  2019. validator_log(val, ISC_LOG_DEBUG(3),
  2020. "dns_ds_buildrdata() -> %s",
  2021. dns_result_totext(result));
  2022. continue;
  2023. }
  2024. if (dns_rdata_compare(dsrdata, &newdsrdata) == 0)
  2025. break;
  2026. }
  2027. return (result);
  2028. }
  2029. /*%
  2030. * Validate the DNSKEY RRset by looking for a DNSKEY that matches a
  2031. * DLV record and that also verifies the DNSKEY RRset.
  2032. */
  2033. static isc_result_t
  2034. dlv_validatezonekey(dns_validator_t *val) {
  2035. dns_rdata_dlv_t dlv;
  2036. dns_rdata_t dlvrdata = DNS_RDATA_INIT;
  2037. dns_rdata_t keyrdata = DNS_RDATA_INIT;
  2038. dns_rdataset_t trdataset;
  2039. isc_boolean_t supported_algorithm;
  2040. isc_result_t result;
  2041. char digest_types[256];
  2042. validator_log(val, ISC_LOG_DEBUG(3), "dlv_validatezonekey");
  2043. /*
  2044. * Look through the DLV record and find the keys that can sign the
  2045. * key set and the matching signature. For each such key, attempt
  2046. * verification.
  2047. */
  2048. supported_algorithm = ISC_FALSE;
  2049. /*
  2050. * If DNS_DSDIGEST_SHA256 is present we are required to prefer
  2051. * it over DNS_DSDIGEST_SHA1. This in practice means that we
  2052. * need to ignore DNS_DSDIGEST_SHA1 if a DNS_DSDIGEST_SHA256
  2053. * is present.
  2054. */
  2055. memset(digest_types, 1, sizeof(digest_types));
  2056. for (result = dns_rdataset_first(&val->dlv);
  2057. result == ISC_R_SUCCESS;
  2058. result = dns_rdataset_next(&val->dlv)) {
  2059. dns_rdata_reset(&dlvrdata);
  2060. dns_rdataset_current(&val->dlv, &dlvrdata);
  2061. result = dns_rdata_tostruct(&dlvrdata, &dlv, NULL);
  2062. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  2063. if (!dns_resolver_algorithm_supported(val->view->resolver,
  2064. val->event->name,
  2065. dlv.algorithm))
  2066. continue;
  2067. if (dlv.digest_type == DNS_DSDIGEST_SHA256 &&
  2068. dlv.length == ISC_SHA256_DIGESTLENGTH) {
  2069. digest_types[DNS_DSDIGEST_SHA1] = 0;
  2070. break;
  2071. }
  2072. }
  2073. for (result = dns_rdataset_first(&val->dlv);
  2074. result == ISC_R_SUCCESS;
  2075. result = dns_rdataset_next(&val->dlv))
  2076. {
  2077. dns_rdata_reset(&dlvrdata);
  2078. dns_rdataset_current(&val->dlv, &dlvrdata);
  2079. result = dns_rdata_tostruct(&dlvrdata, &dlv, NULL);
  2080. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  2081. if (!dns_resolver_digest_supported(val->view->resolver,
  2082. dlv.digest_type))
  2083. continue;
  2084. if (digest_types[dlv.digest_type] == 0)
  2085. continue;
  2086. if (!dns_resolver_algorithm_supported(val->view->resolver,
  2087. val->event->name,
  2088. dlv.algorithm))
  2089. continue;
  2090. supported_algorithm = ISC_TRUE;
  2091. dns_rdataset_init(&trdataset);
  2092. dns_rdataset_clone(val->event->rdataset, &trdataset);
  2093. /*
  2094. * Convert to DLV to DS and find matching DNSKEY.
  2095. */
  2096. dlvrdata.type = dns_rdatatype_ds;
  2097. result = keyfromds(val, &trdataset, &dlvrdata,
  2098. dlv.digest_type, dlv.key_tag,
  2099. dlv.algorithm, &keyrdata);
  2100. if (result != ISC_R_SUCCESS) {
  2101. dns_rdataset_disassociate(&trdataset);
  2102. validator_log(val, ISC_LOG_DEBUG(3),
  2103. "no DNSKEY matching DLV");
  2104. continue;
  2105. }
  2106. validator_log(val, ISC_LOG_DEBUG(3),
  2107. "Found matching DLV record: checking for signature");
  2108. /*
  2109. * Check that this DNSKEY signed the DNSKEY rrset.
  2110. */
  2111. result = checkkey(val, &keyrdata, dlv.key_tag, dlv.algorithm);
  2112. dns_rdataset_disassociate(&trdataset);
  2113. if (result == ISC_R_SUCCESS)
  2114. break;
  2115. validator_log(val, ISC_LOG_DEBUG(3),
  2116. "no RRSIG matching DLV key");
  2117. }
  2118. if (result == ISC_R_SUCCESS) {
  2119. marksecure(val->event);
  2120. validator_log(val, ISC_LOG_DEBUG(3), "marking as secure (dlv)");
  2121. return (result);
  2122. } else if (result == ISC_R_NOMORE && !supported_algorithm) {
  2123. if (val->mustbesecure) {
  2124. validator_log(val, ISC_LOG_WARNING,
  2125. "must be secure failure,"
  2126. "no supported algorithm/digest (dlv)");
  2127. return (DNS_R_MUSTBESECURE);
  2128. }
  2129. validator_log(val, ISC_LOG_DEBUG(3),
  2130. "no supported algorithm/digest (dlv)");
  2131. markanswer(val, "dlv_validatezonekey (2)");
  2132. return (ISC_R_SUCCESS);
  2133. } else
  2134. return (DNS_R_NOVALIDSIG);
  2135. }
  2136. /*%
  2137. * Attempts positive response validation of an RRset containing zone keys
  2138. * (i.e. a DNSKEY rrset).
  2139. *
  2140. * Returns:
  2141. * \li ISC_R_SUCCESS Validation completed successfully
  2142. * \li DNS_R_WAIT Validation has started but is waiting
  2143. * for an event.
  2144. * \li Other return codes are possible and all indicate failure.
  2145. */
  2146. static isc_result_t
  2147. validatezonekey(dns_validator_t *val) {
  2148. isc_result_t result;
  2149. dns_validatorevent_t *event;
  2150. dns_rdataset_t trdataset;
  2151. dns_rdata_t dsrdata = DNS_RDATA_INIT;
  2152. dns_rdata_t keyrdata = DNS_RDATA_INIT;
  2153. dns_rdata_t sigrdata = DNS_RDATA_INIT;
  2154. char namebuf[DNS_NAME_FORMATSIZE];
  2155. dns_rdata_ds_t ds;
  2156. dns_rdata_rrsig_t sig;
  2157. dst_key_t *dstkey;
  2158. isc_boolean_t supported_algorithm;
  2159. isc_boolean_t atsep = ISC_FALSE;
  2160. char digest_types[256];
  2161. /*
  2162. * Caller must be holding the validator lock.
  2163. */
  2164. event = val->event;
  2165. if (val->havedlvsep && val->dlv.trust >= dns_trust_secure &&
  2166. dns_name_equal(event->name, dns_fixedname_name(&val->dlvsep)))
  2167. return (dlv_validatezonekey(val));
  2168. if (val->dsset == NULL) {
  2169. /*
  2170. * We have a dlv sep. Skip looking up the SEP from
  2171. * {trusted,managed}-keys. If the dlv sep is for the
  2172. * root then it will have been handled above so we don't
  2173. * need to check whether val->event->name is "." prior to
  2174. * looking up the DS.
  2175. */
  2176. if (val->havedlvsep)
  2177. goto find_ds;
  2178. /*
  2179. * First, see if this key was signed by a trusted key.
  2180. */
  2181. for (result = dns_rdataset_first(val->event->sigrdataset);
  2182. result == ISC_R_SUCCESS;
  2183. result = dns_rdataset_next(val->event->sigrdataset))
  2184. {
  2185. dns_keynode_t *keynode = NULL;
  2186. dns_fixedname_t fixed;
  2187. dns_name_t *found;
  2188. dns_fixedname_init(&fixed);
  2189. found = dns_fixedname_name(&fixed);
  2190. dns_rdata_reset(&sigrdata);
  2191. dns_rdataset_current(val->event->sigrdataset,
  2192. &sigrdata);
  2193. result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
  2194. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  2195. if (!dns_name_equal(val->event->name, &sig.signer))
  2196. continue;
  2197. result = dns_keytable_findkeynode(val->keytable,
  2198. val->event->name,
  2199. sig.algorithm,
  2200. sig.keyid, &keynode);
  2201. if (result == ISC_R_NOTFOUND &&
  2202. dns_keytable_finddeepestmatch(val->keytable,
  2203. val->event->name, found) != ISC_R_SUCCESS) {
  2204. if (val->mustbesecure) {
  2205. validator_log(val, ISC_LOG_WARNING,
  2206. "must be secure failure, "
  2207. "not beneath secure root");
  2208. return (DNS_R_MUSTBESECURE);
  2209. } else
  2210. validator_log(val, ISC_LOG_DEBUG(3),
  2211. "not beneath secure root");
  2212. if (val->view->dlv == NULL) {
  2213. markanswer(val, "validatezonekey (1)");
  2214. return (ISC_R_SUCCESS);
  2215. }
  2216. return (startfinddlvsep(val, dns_rootname));
  2217. }
  2218. if (result == DNS_R_PARTIALMATCH ||
  2219. result == ISC_R_SUCCESS)
  2220. atsep = ISC_TRUE;
  2221. while (result == ISC_R_SUCCESS) {
  2222. dns_keynode_t *nextnode = NULL;
  2223. dstkey = dns_keynode_key(keynode);
  2224. if (dstkey == NULL) {
  2225. dns_keytable_detachkeynode(
  2226. val->keytable,
  2227. &keynode);
  2228. break;
  2229. }
  2230. result = verify(val, dstkey, &sigrdata,
  2231. sig.keyid);
  2232. if (result == ISC_R_SUCCESS) {
  2233. dns_keytable_detachkeynode(
  2234. val->keytable,
  2235. &keynode);
  2236. break;
  2237. }
  2238. result = dns_keytable_findnextkeynode(
  2239. val->keytable,
  2240. keynode,
  2241. &nextnode);
  2242. dns_keytable_detachkeynode(val->keytable,
  2243. &keynode);
  2244. keynode = nextnode;
  2245. }
  2246. if (result == ISC_R_SUCCESS) {
  2247. marksecure(event);
  2248. validator_log(val, ISC_LOG_DEBUG(3),
  2249. "signed by trusted key; "
  2250. "marking as secure");
  2251. return (result);
  2252. }
  2253. }
  2254. if (atsep) {
  2255. /*
  2256. * We have not found a key to verify this DNSKEY
  2257. * RRset. As this is a SEP we have to assume that
  2258. * the RRset is invalid.
  2259. */
  2260. dns_name_format(val->event->name, namebuf,
  2261. sizeof(namebuf));
  2262. validator_log(val, ISC_LOG_NOTICE,
  2263. "unable to find a DNSKEY which verifies "
  2264. "the DNSKEY RRset and also matches a "
  2265. "trusted key for '%s'",
  2266. namebuf);
  2267. validator_log(val, ISC_LOG_NOTICE,
  2268. "please check the 'trusted-keys' for "
  2269. "'%s' in named.conf.", namebuf);
  2270. return (DNS_R_NOVALIDKEY);
  2271. }
  2272. /*
  2273. * If this is the root name and there was no trusted key,
  2274. * give up, since there's no DS at the root.
  2275. */
  2276. if (dns_name_equal(event->name, dns_rootname)) {
  2277. if ((val->attributes & VALATTR_TRIEDVERIFY) != 0) {
  2278. validator_log(val, ISC_LOG_DEBUG(3),
  2279. "root key failed to validate");
  2280. return (DNS_R_NOVALIDSIG);
  2281. } else {
  2282. validator_log(val, ISC_LOG_DEBUG(3),
  2283. "no trusted root key");
  2284. return (DNS_R_NOVALIDDS);
  2285. }
  2286. }
  2287. find_ds:
  2288. /*
  2289. * Otherwise, try to find the DS record.
  2290. */
  2291. result = view_find(val, val->event->name, dns_rdatatype_ds);
  2292. if (result == ISC_R_SUCCESS) {
  2293. /*
  2294. * We have DS records.
  2295. */
  2296. val->dsset = &val->frdataset;
  2297. if ((DNS_TRUST_PENDING(val->frdataset.trust) ||
  2298. DNS_TRUST_ANSWER(val->frdataset.trust)) &&
  2299. dns_rdataset_isassociated(&val->fsigrdataset))
  2300. {
  2301. result = create_validator(val,
  2302. val->event->name,
  2303. dns_rdatatype_ds,
  2304. &val->frdataset,
  2305. &val->fsigrdataset,
  2306. dsvalidated,
  2307. "validatezonekey");
  2308. if (result != ISC_R_SUCCESS)
  2309. return (result);
  2310. return (DNS_R_WAIT);
  2311. } else if (DNS_TRUST_PENDING(val->frdataset.trust)) {
  2312. /*
  2313. * There should never be an unsigned DS.
  2314. */
  2315. dns_rdataset_disassociate(&val->frdataset);
  2316. validator_log(val, ISC_LOG_DEBUG(2),
  2317. "unsigned DS record");
  2318. return (DNS_R_NOVALIDSIG);
  2319. } else {
  2320. result = ISC_R_SUCCESS;
  2321. POST(result);
  2322. }
  2323. } else if (result == ISC_R_NOTFOUND) {
  2324. /*
  2325. * We don't have the DS. Find it.
  2326. */
  2327. result = create_fetch(val, val->event->name,
  2328. dns_rdatatype_ds, dsfetched,
  2329. "validatezonekey");
  2330. if (result != ISC_R_SUCCESS)
  2331. return (result);
  2332. return (DNS_R_WAIT);
  2333. } else if (result == DNS_R_NCACHENXDOMAIN ||
  2334. result == DNS_R_NCACHENXRRSET ||
  2335. result == DNS_R_EMPTYNAME ||
  2336. result == DNS_R_NXDOMAIN ||
  2337. result == DNS_R_NXRRSET ||
  2338. result == DNS_R_CNAME)
  2339. {
  2340. /*
  2341. * The DS does not exist.
  2342. */
  2343. if (dns_rdataset_isassociated(&val->frdataset))
  2344. dns_rdataset_disassociate(&val->frdataset);
  2345. if (dns_rdataset_isassociated(&val->fsigrdataset))
  2346. dns_rdataset_disassociate(&val->fsigrdataset);
  2347. validator_log(val, ISC_LOG_DEBUG(2), "no DS record");
  2348. return (DNS_R_NOVALIDSIG);
  2349. } else if (result == DNS_R_BROKENCHAIN)
  2350. return (result);
  2351. }
  2352. /*
  2353. * We have a DS set.
  2354. */
  2355. INSIST(val->dsset != NULL);
  2356. if (val->dsset->trust < dns_trust_secure) {
  2357. if (val->mustbesecure) {
  2358. validator_log(val, ISC_LOG_WARNING,
  2359. "must be secure failure,"
  2360. " insecure DS");
  2361. return (DNS_R_MUSTBESECURE);
  2362. }
  2363. if (val->view->dlv == NULL || DLVTRIED(val)) {
  2364. markanswer(val, "validatezonekey (2)");
  2365. return (ISC_R_SUCCESS);
  2366. }
  2367. return (startfinddlvsep(val, val->event->name));
  2368. }
  2369. /*
  2370. * Look through the DS record and find the keys that can sign the
  2371. * key set and the matching signature. For each such key, attempt
  2372. * verification.
  2373. */
  2374. supported_algorithm = ISC_FALSE;
  2375. /*
  2376. * If DNS_DSDIGEST_SHA256 is present we are required to prefer
  2377. * it over DNS_DSDIGEST_SHA1. This in practice means that we
  2378. * need to ignore DNS_DSDIGEST_SHA1 if a DNS_DSDIGEST_SHA256
  2379. * is present.
  2380. */
  2381. memset(digest_types, 1, sizeof(digest_types));
  2382. for (result = dns_rdataset_first(val->dsset);
  2383. result == ISC_R_SUCCESS;
  2384. result = dns_rdataset_next(val->dsset)) {
  2385. dns_rdata_reset(&dsrdata);
  2386. dns_rdataset_current(val->dsset, &dsrdata);
  2387. result = dns_rdata_tostruct(&dsrdata, &ds, NULL);
  2388. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  2389. if (!dns_resolver_algorithm_supported(val->view->resolver,
  2390. val->event->name,
  2391. ds.algorithm))
  2392. continue;
  2393. if (ds.digest_type == DNS_DSDIGEST_SHA256 &&
  2394. ds.length == ISC_SHA256_DIGESTLENGTH) {
  2395. digest_types[DNS_DSDIGEST_SHA1] = 0;
  2396. break;
  2397. }
  2398. }
  2399. for (result = dns_rdataset_first(val->dsset);
  2400. result == ISC_R_SUCCESS;
  2401. result = dns_rdataset_next(val->dsset))
  2402. {
  2403. dns_rdata_reset(&dsrdata);
  2404. dns_rdataset_current(val->dsset, &dsrdata);
  2405. result = dns_rdata_tostruct(&dsrdata, &ds, NULL);
  2406. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  2407. if (!dns_resolver_digest_supported(val->view->resolver,
  2408. ds.digest_type))
  2409. continue;
  2410. if (digest_types[ds.digest_type] == 0)
  2411. continue;
  2412. if (!dns_resolver_algorithm_supported(val->view->resolver,
  2413. val->event->name,
  2414. ds.algorithm))
  2415. continue;
  2416. supported_algorithm = ISC_TRUE;
  2417. dns_rdataset_init(&trdataset);
  2418. dns_rdataset_clone(val->event->rdataset, &trdataset);
  2419. /*
  2420. * Find matching DNSKEY from DS.
  2421. */
  2422. result = keyfromds(val, &trdataset, &dsrdata, ds.digest_type,
  2423. ds.key_tag, ds.algorithm, &keyrdata);
  2424. if (result != ISC_R_SUCCESS) {
  2425. dns_rdataset_disassociate(&trdataset);
  2426. validator_log(val, ISC_LOG_DEBUG(3),
  2427. "no DNSKEY matching DS");
  2428. continue;
  2429. }
  2430. /*
  2431. * Check that this DNSKEY signed the DNSKEY rrset.
  2432. */
  2433. result = checkkey(val, &keyrdata, ds.key_tag, ds.algorithm);
  2434. dns_rdataset_disassociate(&trdataset);
  2435. if (result == ISC_R_SUCCESS)
  2436. break;
  2437. validator_log(val, ISC_LOG_DEBUG(3),
  2438. "no RRSIG matching DS key");
  2439. }
  2440. if (result == ISC_R_SUCCESS) {
  2441. marksecure(event);
  2442. validator_log(val, ISC_LOG_DEBUG(3), "marking as secure (DS)");
  2443. return (result);
  2444. } else if (result == ISC_R_NOMORE && !supported_algorithm) {
  2445. if (val->mustbesecure) {
  2446. validator_log(val, ISC_LOG_WARNING,
  2447. "must be secure failure, "
  2448. "no supported algorithm/digest (DS)");
  2449. return (DNS_R_MUSTBESECURE);
  2450. }
  2451. validator_log(val, ISC_LOG_DEBUG(3),
  2452. "no supported algorithm/digest (DS)");
  2453. markanswer(val, "validatezonekey (3)");
  2454. return (ISC_R_SUCCESS);
  2455. } else {
  2456. validator_log(val, ISC_LOG_INFO,
  2457. "no valid signature found (DS)");
  2458. return (DNS_R_NOVALIDSIG);
  2459. }
  2460. }
  2461. /*%
  2462. * Starts a positive response validation.
  2463. *
  2464. * Returns:
  2465. * \li ISC_R_SUCCESS Validation completed successfully
  2466. * \li DNS_R_WAIT Validation has started but is waiting
  2467. * for an event.
  2468. * \li Other return codes are possible and all indicate failure.
  2469. */
  2470. static isc_result_t
  2471. start_positive_validation(dns_validator_t *val) {
  2472. /*
  2473. * If this is not a key, go straight into validate().
  2474. */
  2475. if (val->event->type != dns_rdatatype_dnskey || !isselfsigned(val))
  2476. return (validate(val, ISC_FALSE));
  2477. return (validatezonekey(val));
  2478. }
  2479. /*%
  2480. * val_rdataset_first and val_rdataset_next provide iteration methods
  2481. * that hide whether we are iterating across a message or a negative
  2482. * cache rdataset.
  2483. */
  2484. static isc_result_t
  2485. val_rdataset_first(dns_validator_t *val, dns_name_t **namep,
  2486. dns_rdataset_t **rdatasetp)
  2487. {
  2488. dns_message_t *message = val->event->message;
  2489. isc_result_t result;
  2490. REQUIRE(rdatasetp != NULL);
  2491. REQUIRE(namep != NULL);
  2492. if (message == NULL) {
  2493. REQUIRE(*rdatasetp != NULL);
  2494. REQUIRE(*namep != NULL);
  2495. } else {
  2496. REQUIRE(*rdatasetp == NULL);
  2497. REQUIRE(*namep == NULL);
  2498. }
  2499. if (message != NULL) {
  2500. result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
  2501. if (result != ISC_R_SUCCESS)
  2502. return (result);
  2503. dns_message_currentname(message, DNS_SECTION_AUTHORITY, namep);
  2504. *rdatasetp = ISC_LIST_HEAD((*namep)->list);
  2505. INSIST(*rdatasetp != NULL);
  2506. } else {
  2507. result = dns_rdataset_first(val->event->rdataset);
  2508. if (result == ISC_R_SUCCESS)
  2509. dns_ncache_current(val->event->rdataset, *namep,
  2510. *rdatasetp);
  2511. }
  2512. return (result);
  2513. }
  2514. static isc_result_t
  2515. val_rdataset_next(dns_validator_t *val, dns_name_t **namep,
  2516. dns_rdataset_t **rdatasetp)
  2517. {
  2518. dns_message_t *message = val->event->message;
  2519. isc_result_t result = ISC_R_SUCCESS;
  2520. REQUIRE(rdatasetp != NULL && *rdatasetp != NULL);
  2521. REQUIRE(namep != NULL && *namep != NULL);
  2522. if (message != NULL) {
  2523. dns_rdataset_t *rdataset = *rdatasetp;
  2524. rdataset = ISC_LIST_NEXT(rdataset, link);
  2525. if (rdataset == NULL) {
  2526. *namep = NULL;
  2527. result = dns_message_nextname(message,
  2528. DNS_SECTION_AUTHORITY);
  2529. if (result == ISC_R_SUCCESS) {
  2530. dns_message_currentname(message,
  2531. DNS_SECTION_AUTHORITY,
  2532. namep);
  2533. rdataset = ISC_LIST_HEAD((*namep)->list);
  2534. INSIST(rdataset != NULL);
  2535. }
  2536. }
  2537. *rdatasetp = rdataset;
  2538. } else {
  2539. dns_rdataset_disassociate(*rdatasetp);
  2540. result = dns_rdataset_next(val->event->rdataset);
  2541. if (result == ISC_R_SUCCESS)
  2542. dns_ncache_current(val->event->rdataset, *namep,
  2543. *rdatasetp);
  2544. }
  2545. return (result);
  2546. }
  2547. /*%
  2548. * Look for NODATA at the wildcard and NOWILDCARD proofs in the
  2549. * previously validated NSEC records. As these proofs are mutually
  2550. * exclusive we stop when one is found.
  2551. *
  2552. * Returns
  2553. * \li ISC_R_SUCCESS
  2554. */
  2555. static isc_result_t
  2556. checkwildcard(dns_validator_t *val, dns_rdatatype_t type, dns_name_t *zonename)
  2557. {
  2558. dns_name_t *name, *wild, tname;
  2559. isc_result_t result;
  2560. isc_boolean_t exists, data;
  2561. char namebuf[DNS_NAME_FORMATSIZE];
  2562. dns_rdataset_t *rdataset, trdataset;
  2563. dns_name_init(&tname, NULL);
  2564. dns_rdataset_init(&trdataset);
  2565. wild = dns_fixedname_name(&val->wild);
  2566. if (dns_name_countlabels(wild) == 0) {
  2567. validator_log(val, ISC_LOG_DEBUG(3),
  2568. "in checkwildcard: no wildcard to check");
  2569. return (ISC_R_SUCCESS);
  2570. }
  2571. dns_name_format(wild, namebuf, sizeof(namebuf));
  2572. validator_log(val, ISC_LOG_DEBUG(3), "in checkwildcard: %s", namebuf);
  2573. if (val->event->message == NULL) {
  2574. name = &tname;
  2575. rdataset = &trdataset;
  2576. } else {
  2577. name = NULL;
  2578. rdataset = NULL;
  2579. }
  2580. for (result = val_rdataset_first(val, &name, &rdataset);
  2581. result == ISC_R_SUCCESS;
  2582. result = val_rdataset_next(val, &name, &rdataset))
  2583. {
  2584. if (rdataset->type != type ||
  2585. rdataset->trust != dns_trust_secure)
  2586. continue;
  2587. if (rdataset->type == dns_rdatatype_nsec &&
  2588. (NEEDNODATA(val) || NEEDNOWILDCARD(val)) &&
  2589. !FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) &&
  2590. nsecnoexistnodata(val, wild, name, rdataset,
  2591. &exists, &data, NULL)
  2592. == ISC_R_SUCCESS)
  2593. {
  2594. dns_name_t **proofs = val->event->proofs;
  2595. if (exists && !data)
  2596. val->attributes |= VALATTR_FOUNDNODATA;
  2597. if (exists && !data && NEEDNODATA(val))
  2598. proofs[DNS_VALIDATOR_NODATAPROOF] =
  2599. name;
  2600. if (!exists)
  2601. val->attributes |=
  2602. VALATTR_FOUNDNOWILDCARD;
  2603. if (!exists && NEEDNOQNAME(val))
  2604. proofs[DNS_VALIDATOR_NOWILDCARDPROOF] =
  2605. name;
  2606. if (dns_rdataset_isassociated(&trdataset))
  2607. dns_rdataset_disassociate(&trdataset);
  2608. return (ISC_R_SUCCESS);
  2609. }
  2610. if (rdataset->type == dns_rdatatype_nsec3 &&
  2611. (NEEDNODATA(val) || NEEDNOWILDCARD(val)) &&
  2612. !FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) &&
  2613. nsec3noexistnodata(val, wild, name, rdataset,
  2614. zonename, &exists, &data,
  2615. NULL, NULL, NULL, NULL, NULL,
  2616. NULL) == ISC_R_SUCCESS)
  2617. {
  2618. dns_name_t **proofs = val->event->proofs;
  2619. if (exists && !data)
  2620. val->attributes |= VALATTR_FOUNDNODATA;
  2621. if (exists && !data && NEEDNODATA(val))
  2622. proofs[DNS_VALIDATOR_NODATAPROOF] =
  2623. name;
  2624. if (!exists)
  2625. val->attributes |=
  2626. VALATTR_FOUNDNOWILDCARD;
  2627. if (!exists && NEEDNOQNAME(val))
  2628. proofs[DNS_VALIDATOR_NOWILDCARDPROOF] =
  2629. name;
  2630. if (dns_rdataset_isassociated(&trdataset))
  2631. dns_rdataset_disassociate(&trdataset);
  2632. return (ISC_R_SUCCESS);
  2633. }
  2634. }
  2635. if (result == ISC_R_NOMORE)
  2636. result = ISC_R_SUCCESS;
  2637. if (dns_rdataset_isassociated(&trdataset))
  2638. dns_rdataset_disassociate(&trdataset);
  2639. return (result);
  2640. }
  2641. static isc_result_t
  2642. findnsec3proofs(dns_validator_t *val) {
  2643. dns_name_t *name, tname;
  2644. isc_result_t result;
  2645. isc_boolean_t exists, data, optout, unknown;
  2646. isc_boolean_t setclosest, setnearest, *setclosestp;
  2647. dns_fixedname_t fclosest, fnearest, fzonename;
  2648. dns_name_t *closest, *nearest, *zonename, *closestp;
  2649. dns_name_t **proofs = val->event->proofs;
  2650. dns_rdataset_t *rdataset, trdataset;
  2651. dns_name_init(&tname, NULL);
  2652. dns_rdataset_init(&trdataset);
  2653. dns_fixedname_init(&fclosest);
  2654. dns_fixedname_init(&fnearest);
  2655. dns_fixedname_init(&fzonename);
  2656. closest = dns_fixedname_name(&fclosest);
  2657. nearest = dns_fixedname_name(&fnearest);
  2658. zonename = dns_fixedname_name(&fzonename);
  2659. if (val->event->message == NULL) {
  2660. name = &tname;
  2661. rdataset = &trdataset;
  2662. } else {
  2663. name = NULL;
  2664. rdataset = NULL;
  2665. }
  2666. for (result = val_rdataset_first(val, &name, &rdataset);
  2667. result == ISC_R_SUCCESS;
  2668. result = val_rdataset_next(val, &name, &rdataset))
  2669. {
  2670. if (rdataset->type != dns_rdatatype_nsec3 ||
  2671. rdataset->trust != dns_trust_secure)
  2672. continue;
  2673. result = nsec3noexistnodata(val, val->event->name,
  2674. name, rdataset,
  2675. zonename, NULL, NULL, NULL,
  2676. NULL, NULL, NULL, NULL,
  2677. NULL);
  2678. if (result != ISC_R_IGNORE && result != ISC_R_SUCCESS) {
  2679. if (dns_rdataset_isassociated(&trdataset))
  2680. dns_rdataset_disassociate(&trdataset);
  2681. return (result);
  2682. }
  2683. }
  2684. if (result != ISC_R_NOMORE)
  2685. result = ISC_R_SUCCESS;
  2686. POST(result);
  2687. if (dns_name_countlabels(zonename) == 0)
  2688. return (ISC_R_SUCCESS);
  2689. /*
  2690. * If the val->closest is set then we want to use it otherwise
  2691. * we need to discover it.
  2692. */
  2693. if (dns_name_countlabels(dns_fixedname_name(&val->closest)) != 0) {
  2694. char namebuf[DNS_NAME_FORMATSIZE];
  2695. dns_name_format(dns_fixedname_name(&val->closest),
  2696. namebuf, sizeof(namebuf));
  2697. validator_log(val, ISC_LOG_DEBUG(3), "closest encloser from "
  2698. "wildcard signature '%s'", namebuf);
  2699. dns_name_copy(dns_fixedname_name(&val->closest), closest, NULL);
  2700. closestp = NULL;
  2701. setclosestp = NULL;
  2702. } else {
  2703. closestp = closest;
  2704. setclosestp = &setclosest;
  2705. }
  2706. for (result = val_rdataset_first(val, &name, &rdataset);
  2707. result == ISC_R_SUCCESS;
  2708. result = val_rdataset_next(val, &name, &rdataset))
  2709. {
  2710. if (rdataset->type != dns_rdatatype_nsec3 ||
  2711. rdataset->trust != dns_trust_secure)
  2712. continue;
  2713. /*
  2714. * We process all NSEC3 records to find the closest
  2715. * encloser and nearest name to the closest encloser.
  2716. */
  2717. setclosest = setnearest = ISC_FALSE;
  2718. optout = ISC_FALSE;
  2719. unknown = ISC_FALSE;
  2720. (void)nsec3noexistnodata(val, val->event->name, name, rdataset,
  2721. zonename, &exists, &data, &optout,
  2722. &unknown, setclosestp, &setnearest,
  2723. closestp, nearest);
  2724. if (setclosest)
  2725. proofs[DNS_VALIDATOR_CLOSESTENCLOSER] = name;
  2726. if (unknown)
  2727. val->attributes |= VALATTR_FOUNDUNKNOWN;
  2728. if (result != ISC_R_SUCCESS)
  2729. continue;
  2730. if (exists && !data && NEEDNODATA(val)) {
  2731. val->attributes |= VALATTR_FOUNDNODATA;
  2732. proofs[DNS_VALIDATOR_NODATAPROOF] = name;
  2733. }
  2734. if (!exists && setnearest) {
  2735. val->attributes |= VALATTR_FOUNDNOQNAME;
  2736. proofs[DNS_VALIDATOR_NOQNAMEPROOF] = name;
  2737. if (optout)
  2738. val->attributes |= VALATTR_FOUNDOPTOUT;
  2739. }
  2740. }
  2741. if (result == ISC_R_NOMORE)
  2742. result = ISC_R_SUCCESS;
  2743. /*
  2744. * To know we have a valid noqname and optout proofs we need to also
  2745. * have a valid closest encloser. Otherwise we could still be looking
  2746. * at proofs from the parent zone.
  2747. */
  2748. if (dns_name_countlabels(closest) > 0 &&
  2749. dns_name_countlabels(nearest) ==
  2750. dns_name_countlabels(closest) + 1 &&
  2751. dns_name_issubdomain(nearest, closest))
  2752. {
  2753. val->attributes |= VALATTR_FOUNDCLOSEST;
  2754. result = dns_name_concatenate(dns_wildcardname, closest,
  2755. dns_fixedname_name(&val->wild),
  2756. NULL);
  2757. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  2758. } else {
  2759. val->attributes &= ~VALATTR_FOUNDNOQNAME;
  2760. val->attributes &= ~VALATTR_FOUNDOPTOUT;
  2761. proofs[DNS_VALIDATOR_NOQNAMEPROOF] = NULL;
  2762. }
  2763. /*
  2764. * Do we need to check for the wildcard?
  2765. */
  2766. if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val) &&
  2767. ((NEEDNODATA(val) && !FOUNDNODATA(val)) || NEEDNOWILDCARD(val))) {
  2768. result = checkwildcard(val, dns_rdatatype_nsec3, zonename);
  2769. if (result != ISC_R_SUCCESS)
  2770. return (result);
  2771. }
  2772. return (result);
  2773. }
  2774. /*%
  2775. * Validate the authority section records.
  2776. */
  2777. static isc_result_t
  2778. validate_authority(dns_validator_t *val, isc_boolean_t resume) {
  2779. dns_name_t *name;
  2780. dns_message_t *message = val->event->message;
  2781. isc_result_t result;
  2782. if (!resume)
  2783. result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
  2784. else
  2785. result = ISC_R_SUCCESS;
  2786. for (;
  2787. result == ISC_R_SUCCESS;
  2788. result = dns_message_nextname(message, DNS_SECTION_AUTHORITY))
  2789. {
  2790. dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
  2791. name = NULL;
  2792. dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
  2793. if (resume) {
  2794. rdataset = ISC_LIST_NEXT(val->currentset, link);
  2795. val->currentset = NULL;
  2796. resume = ISC_FALSE;
  2797. } else
  2798. rdataset = ISC_LIST_HEAD(name->list);
  2799. for (;
  2800. rdataset != NULL;
  2801. rdataset = ISC_LIST_NEXT(rdataset, link))
  2802. {
  2803. if (rdataset->type == dns_rdatatype_rrsig)
  2804. continue;
  2805. for (sigrdataset = ISC_LIST_HEAD(name->list);
  2806. sigrdataset != NULL;
  2807. sigrdataset = ISC_LIST_NEXT(sigrdataset,
  2808. link))
  2809. {
  2810. if (sigrdataset->type == dns_rdatatype_rrsig &&
  2811. sigrdataset->covers == rdataset->type)
  2812. break;
  2813. }
  2814. /*
  2815. * If a signed zone is missing the zone key, bad
  2816. * things could happen. A query for data in the zone
  2817. * would lead to a query for the zone key, which
  2818. * would return a negative answer, which would contain
  2819. * an SOA and an NSEC signed by the missing key, which
  2820. * would trigger another query for the DNSKEY (since
  2821. * the first one is still in progress), and go into an
  2822. * infinite loop. Avoid that.
  2823. */
  2824. if (val->event->type == dns_rdatatype_dnskey &&
  2825. rdataset->type == dns_rdatatype_nsec &&
  2826. dns_name_equal(name, val->event->name))
  2827. {
  2828. dns_rdata_t nsec = DNS_RDATA_INIT;
  2829. result = dns_rdataset_first(rdataset);
  2830. if (result != ISC_R_SUCCESS)
  2831. return (result);
  2832. dns_rdataset_current(rdataset, &nsec);
  2833. if (dns_nsec_typepresent(&nsec,
  2834. dns_rdatatype_soa))
  2835. continue;
  2836. }
  2837. val->currentset = rdataset;
  2838. result = create_validator(val, name, rdataset->type,
  2839. rdataset, sigrdataset,
  2840. authvalidated,
  2841. "validate_authority");
  2842. if (result != ISC_R_SUCCESS)
  2843. return (result);
  2844. val->authcount++;
  2845. return (DNS_R_WAIT);
  2846. }
  2847. }
  2848. if (result == ISC_R_NOMORE)
  2849. result = ISC_R_SUCCESS;
  2850. return (result);
  2851. }
  2852. /*%
  2853. * Validate the ncache elements.
  2854. */
  2855. static isc_result_t
  2856. validate_ncache(dns_validator_t *val, isc_boolean_t resume) {
  2857. dns_name_t *name;
  2858. isc_result_t result;
  2859. if (!resume)
  2860. result = dns_rdataset_first(val->event->rdataset);
  2861. else
  2862. result = dns_rdataset_next(val->event->rdataset);
  2863. for (;
  2864. result == ISC_R_SUCCESS;
  2865. result = dns_rdataset_next(val->event->rdataset))
  2866. {
  2867. dns_rdataset_t *rdataset, *sigrdataset = NULL;
  2868. if (dns_rdataset_isassociated(&val->frdataset))
  2869. dns_rdataset_disassociate(&val->frdataset);
  2870. if (dns_rdataset_isassociated(&val->fsigrdataset))
  2871. dns_rdataset_disassociate(&val->fsigrdataset);
  2872. dns_fixedname_init(&val->fname);
  2873. name = dns_fixedname_name(&val->fname);
  2874. rdataset = &val->frdataset;
  2875. dns_ncache_current(val->event->rdataset, name, rdataset);
  2876. if (val->frdataset.type == dns_rdatatype_rrsig)
  2877. continue;
  2878. result = dns_ncache_getsigrdataset(val->event->rdataset, name,
  2879. rdataset->type,
  2880. &val->fsigrdataset);
  2881. if (result == ISC_R_SUCCESS)
  2882. sigrdataset = &val->fsigrdataset;
  2883. /*
  2884. * If a signed zone is missing the zone key, bad
  2885. * things could happen. A query for data in the zone
  2886. * would lead to a query for the zone key, which
  2887. * would return a negative answer, which would contain
  2888. * an SOA and an NSEC signed by the missing key, which
  2889. * would trigger another query for the DNSKEY (since
  2890. * the first one is still in progress), and go into an
  2891. * infinite loop. Avoid that.
  2892. */
  2893. if (val->event->type == dns_rdatatype_dnskey &&
  2894. rdataset->type == dns_rdatatype_nsec &&
  2895. dns_name_equal(name, val->event->name))
  2896. {
  2897. dns_rdata_t nsec = DNS_RDATA_INIT;
  2898. result = dns_rdataset_first(rdataset);
  2899. if (result != ISC_R_SUCCESS)
  2900. return (result);
  2901. dns_rdataset_current(rdataset, &nsec);
  2902. if (dns_nsec_typepresent(&nsec,
  2903. dns_rdatatype_soa))
  2904. continue;
  2905. }
  2906. val->currentset = rdataset;
  2907. result = create_validator(val, name, rdataset->type,
  2908. rdataset, sigrdataset,
  2909. authvalidated,
  2910. "validate_ncache");
  2911. if (result != ISC_R_SUCCESS)
  2912. return (result);
  2913. val->authcount++;
  2914. return (DNS_R_WAIT);
  2915. }
  2916. if (result == ISC_R_NOMORE)
  2917. result = ISC_R_SUCCESS;
  2918. return (result);
  2919. }
  2920. /*%
  2921. * Prove a negative answer is good or that there is a NOQNAME when the
  2922. * answer is from a wildcard.
  2923. *
  2924. * Loop through the authority section looking for NODATA, NOWILDCARD
  2925. * and NOQNAME proofs in the NSEC records by calling authvalidated().
  2926. *
  2927. * If the required proofs are found we are done.
  2928. *
  2929. * If the proofs are not found attempt to prove this is a unsecure
  2930. * response.
  2931. */
  2932. static isc_result_t
  2933. nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
  2934. isc_result_t result;
  2935. if (resume)
  2936. validator_log(val, ISC_LOG_DEBUG(3), "resuming nsecvalidate");
  2937. if (val->event->message == NULL)
  2938. result = validate_ncache(val, resume);
  2939. else
  2940. result = validate_authority(val, resume);
  2941. if (result != ISC_R_SUCCESS)
  2942. return (result);
  2943. /*
  2944. * Do we only need to check for NOQNAME? To get here we must have
  2945. * had a secure wildcard answer.
  2946. */
  2947. if (!NEEDNODATA(val) && !NEEDNOWILDCARD(val) && NEEDNOQNAME(val)) {
  2948. if (!FOUNDNOQNAME(val))
  2949. findnsec3proofs(val);
  2950. if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val)) {
  2951. validator_log(val, ISC_LOG_DEBUG(3),
  2952. "marking as secure, noqname proof found");
  2953. marksecure(val->event);
  2954. return (ISC_R_SUCCESS);
  2955. } else if (FOUNDOPTOUT(val) &&
  2956. dns_name_countlabels(dns_fixedname_name(&val->wild))
  2957. != 0) {
  2958. validator_log(val, ISC_LOG_DEBUG(3),
  2959. "optout proof found");
  2960. val->event->optout = ISC_TRUE;
  2961. markanswer(val, "nsecvalidate (1)");
  2962. return (ISC_R_SUCCESS);
  2963. } else if ((val->attributes & VALATTR_FOUNDUNKNOWN) != 0) {
  2964. validator_log(val, ISC_LOG_DEBUG(3),
  2965. "unknown NSEC3 hash algorithm found");
  2966. markanswer(val, "nsecvalidate (2)");
  2967. return (ISC_R_SUCCESS);
  2968. }
  2969. validator_log(val, ISC_LOG_DEBUG(3),
  2970. "noqname proof not found");
  2971. return (DNS_R_NOVALIDNSEC);
  2972. }
  2973. if (!FOUNDNOQNAME(val) && !FOUNDNODATA(val))
  2974. findnsec3proofs(val);
  2975. /*
  2976. * Do we need to check for the wildcard?
  2977. */
  2978. if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val) &&
  2979. ((NEEDNODATA(val) && !FOUNDNODATA(val)) || NEEDNOWILDCARD(val))) {
  2980. result = checkwildcard(val, dns_rdatatype_nsec, NULL);
  2981. if (result != ISC_R_SUCCESS)
  2982. return (result);
  2983. }
  2984. if ((NEEDNODATA(val) && (FOUNDNODATA(val) || FOUNDOPTOUT(val))) ||
  2985. (NEEDNOQNAME(val) && FOUNDNOQNAME(val) &&
  2986. NEEDNOWILDCARD(val) && FOUNDNOWILDCARD(val) &&
  2987. FOUNDCLOSEST(val))) {
  2988. if ((val->attributes & VALATTR_FOUNDOPTOUT) != 0)
  2989. val->event->optout = ISC_TRUE;
  2990. validator_log(val, ISC_LOG_DEBUG(3),
  2991. "nonexistence proof(s) found");
  2992. if (val->event->message == NULL)
  2993. marksecure(val->event);
  2994. return (ISC_R_SUCCESS);
  2995. }
  2996. if (val->authfail != 0 && val->authcount == val->authfail)
  2997. return (DNS_R_BROKENCHAIN);
  2998. validator_log(val, ISC_LOG_DEBUG(3),
  2999. "nonexistence proof(s) not found");
  3000. val->attributes |= VALATTR_INSECURITY;
  3001. return (proveunsecure(val, ISC_FALSE, ISC_FALSE));
  3002. }
  3003. static isc_boolean_t
  3004. check_ds(dns_validator_t *val, dns_name_t *name, dns_rdataset_t *rdataset) {
  3005. dns_rdata_t dsrdata = DNS_RDATA_INIT;
  3006. dns_rdata_ds_t ds;
  3007. isc_result_t result;
  3008. for (result = dns_rdataset_first(rdataset);
  3009. result == ISC_R_SUCCESS;
  3010. result = dns_rdataset_next(rdataset)) {
  3011. dns_rdataset_current(rdataset, &dsrdata);
  3012. result = dns_rdata_tostruct(&dsrdata, &ds, NULL);
  3013. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  3014. if (dns_resolver_digest_supported(val->view->resolver,
  3015. ds.digest_type) &&
  3016. dns_resolver_algorithm_supported(val->view->resolver,
  3017. name, ds.algorithm)) {
  3018. dns_rdata_reset(&dsrdata);
  3019. return (ISC_TRUE);
  3020. }
  3021. dns_rdata_reset(&dsrdata);
  3022. }
  3023. return (ISC_FALSE);
  3024. }
  3025. static void
  3026. dlvvalidated(isc_task_t *task, isc_event_t *event) {
  3027. dns_validatorevent_t *devent;
  3028. dns_validator_t *val;
  3029. isc_result_t eresult;
  3030. isc_boolean_t want_destroy;
  3031. UNUSED(task);
  3032. INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
  3033. devent = (dns_validatorevent_t *)event;
  3034. val = devent->ev_arg;
  3035. eresult = devent->result;
  3036. isc_event_free(&event);
  3037. dns_validator_destroy(&val->subvalidator);
  3038. INSIST(val->event != NULL);
  3039. validator_log(val, ISC_LOG_DEBUG(3), "in dlvvalidated");
  3040. LOCK(&val->lock);
  3041. if (CANCELED(val)) {
  3042. validator_done(val, ISC_R_CANCELED);
  3043. } else if (eresult == ISC_R_SUCCESS) {
  3044. validator_log(val, ISC_LOG_DEBUG(3),
  3045. "dlvset with trust %s",
  3046. dns_trust_totext(val->frdataset.trust));
  3047. dns_rdataset_clone(&val->frdataset, &val->dlv);
  3048. val->havedlvsep = ISC_TRUE;
  3049. if (dlv_algorithm_supported(val))
  3050. dlv_validator_start(val);
  3051. else {
  3052. markanswer(val, "dlvvalidated");
  3053. validator_done(val, ISC_R_SUCCESS);
  3054. }
  3055. } else {
  3056. if (eresult != DNS_R_BROKENCHAIN) {
  3057. if (dns_rdataset_isassociated(&val->frdataset))
  3058. dns_rdataset_expire(&val->frdataset);
  3059. if (dns_rdataset_isassociated(&val->fsigrdataset))
  3060. dns_rdataset_expire(&val->fsigrdataset);
  3061. }
  3062. validator_log(val, ISC_LOG_DEBUG(3),
  3063. "dlvvalidated: got %s",
  3064. isc_result_totext(eresult));
  3065. validator_done(val, DNS_R_BROKENCHAIN);
  3066. }
  3067. want_destroy = exit_check(val);
  3068. UNLOCK(&val->lock);
  3069. if (want_destroy)
  3070. destroy(val);
  3071. }
  3072. /*%
  3073. * Callback from fetching a DLV record.
  3074. *
  3075. * Resumes the DLV lookup process.
  3076. */
  3077. static void
  3078. dlvfetched(isc_task_t *task, isc_event_t *event) {
  3079. char namebuf[DNS_NAME_FORMATSIZE];
  3080. dns_fetchevent_t *devent;
  3081. dns_validator_t *val;
  3082. isc_boolean_t want_destroy;
  3083. isc_result_t eresult;
  3084. isc_result_t result;
  3085. UNUSED(task);
  3086. INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
  3087. devent = (dns_fetchevent_t *)event;
  3088. val = devent->ev_arg;
  3089. eresult = devent->result;
  3090. /* Free resources which are not of interest. */
  3091. if (devent->node != NULL)
  3092. dns_db_detachnode(devent->db, &devent->node);
  3093. if (devent->db != NULL)
  3094. dns_db_detach(&devent->db);
  3095. if (dns_rdataset_isassociated(&val->fsigrdataset))
  3096. dns_rdataset_disassociate(&val->fsigrdataset);
  3097. isc_event_free(&event);
  3098. dns_resolver_destroyfetch(&val->fetch);
  3099. INSIST(val->event != NULL);
  3100. validator_log(val, ISC_LOG_DEBUG(3), "in dlvfetched: %s",
  3101. dns_result_totext(eresult));
  3102. LOCK(&val->lock);
  3103. if (eresult == ISC_R_SUCCESS) {
  3104. dns_name_format(dns_fixedname_name(&val->dlvsep), namebuf,
  3105. sizeof(namebuf));
  3106. dns_rdataset_clone(&val->frdataset, &val->dlv);
  3107. val->havedlvsep = ISC_TRUE;
  3108. if (dlv_algorithm_supported(val)) {
  3109. validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found",
  3110. namebuf);
  3111. dlv_validator_start(val);
  3112. } else {
  3113. validator_log(val, ISC_LOG_DEBUG(3),
  3114. "DLV %s found with no supported algorithms",
  3115. namebuf);
  3116. markanswer(val, "dlvfetched (1)");
  3117. validator_done(val, ISC_R_SUCCESS);
  3118. }
  3119. } else if (eresult == DNS_R_NXRRSET ||
  3120. eresult == DNS_R_NXDOMAIN ||
  3121. eresult == DNS_R_NCACHENXRRSET ||
  3122. eresult == DNS_R_NCACHENXDOMAIN) {
  3123. result = finddlvsep(val, ISC_TRUE);
  3124. if (result == ISC_R_SUCCESS) {
  3125. if (dlv_algorithm_supported(val)) {
  3126. dns_name_format(dns_fixedname_name(&val->dlvsep),
  3127. namebuf, sizeof(namebuf));
  3128. validator_log(val, ISC_LOG_DEBUG(3),
  3129. "DLV %s found", namebuf);
  3130. dlv_validator_start(val);
  3131. } else {
  3132. validator_log(val, ISC_LOG_DEBUG(3),
  3133. "DLV %s found with no supported "
  3134. "algorithms", namebuf);
  3135. markanswer(val, "dlvfetched (2)");
  3136. validator_done(val, ISC_R_SUCCESS);
  3137. }
  3138. } else if (result == ISC_R_NOTFOUND) {
  3139. validator_log(val, ISC_LOG_DEBUG(3), "DLV not found");
  3140. markanswer(val, "dlvfetched (3)");
  3141. validator_done(val, ISC_R_SUCCESS);
  3142. } else {
  3143. validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s",
  3144. dns_result_totext(result));
  3145. if (result != DNS_R_WAIT)
  3146. validator_done(val, result);
  3147. }
  3148. } else {
  3149. validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s",
  3150. dns_result_totext(eresult));
  3151. validator_done(val, eresult);
  3152. }
  3153. want_destroy = exit_check(val);
  3154. UNLOCK(&val->lock);
  3155. if (want_destroy)
  3156. destroy(val);
  3157. }
  3158. /*%
  3159. * Start the DLV lookup process.
  3160. *
  3161. * Returns
  3162. * \li ISC_R_SUCCESS
  3163. * \li DNS_R_WAIT
  3164. * \li Others on validation failures.
  3165. */
  3166. static isc_result_t
  3167. startfinddlvsep(dns_validator_t *val, dns_name_t *unsecure) {
  3168. char namebuf[DNS_NAME_FORMATSIZE];
  3169. isc_result_t result;
  3170. INSIST(!DLVTRIED(val));
  3171. val->attributes |= VALATTR_DLVTRIED;
  3172. dns_name_format(unsecure, namebuf, sizeof(namebuf));
  3173. validator_log(val, ISC_LOG_DEBUG(3),
  3174. "plain DNSSEC returns unsecure (%s): looking for DLV",
  3175. namebuf);
  3176. if (dns_name_issubdomain(val->event->name, val->view->dlv)) {
  3177. validator_log(val, ISC_LOG_WARNING, "must be secure failure, "
  3178. " %s is under DLV (startfinddlvsep)", namebuf);
  3179. return (DNS_R_MUSTBESECURE);
  3180. }
  3181. val->dlvlabels = dns_name_countlabels(unsecure) - 1;
  3182. result = finddlvsep(val, ISC_FALSE);
  3183. if (result == ISC_R_NOTFOUND) {
  3184. validator_log(val, ISC_LOG_DEBUG(3), "DLV not found");
  3185. markanswer(val, "startfinddlvsep (1)");
  3186. return (ISC_R_SUCCESS);
  3187. }
  3188. if (result != ISC_R_SUCCESS) {
  3189. validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s",
  3190. dns_result_totext(result));
  3191. return (result);
  3192. }
  3193. dns_name_format(dns_fixedname_name(&val->dlvsep), namebuf,
  3194. sizeof(namebuf));
  3195. if (dlv_algorithm_supported(val)) {
  3196. validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found", namebuf);
  3197. dlv_validator_start(val);
  3198. return (DNS_R_WAIT);
  3199. }
  3200. validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found with no supported "
  3201. "algorithms", namebuf);
  3202. markanswer(val, "startfinddlvsep (2)");
  3203. validator_done(val, ISC_R_SUCCESS);
  3204. return (ISC_R_SUCCESS);
  3205. }
  3206. /*%
  3207. * Continue the DLV lookup process.
  3208. *
  3209. * Returns
  3210. * \li ISC_R_SUCCESS
  3211. * \li ISC_R_NOTFOUND
  3212. * \li DNS_R_WAIT
  3213. * \li Others on validation failure.
  3214. */
  3215. static isc_result_t
  3216. finddlvsep(dns_validator_t *val, isc_boolean_t resume) {
  3217. char namebuf[DNS_NAME_FORMATSIZE];
  3218. dns_fixedname_t dlvfixed;
  3219. dns_name_t *dlvname;
  3220. dns_name_t *dlvsep;
  3221. dns_name_t noroot;
  3222. isc_result_t result;
  3223. unsigned int labels;
  3224. INSIST(val->view->dlv != NULL);
  3225. if (!resume) {
  3226. if (dns_name_issubdomain(val->event->name, val->view->dlv)) {
  3227. dns_name_format(val->event->name, namebuf,
  3228. sizeof(namebuf));
  3229. validator_log(val, ISC_LOG_WARNING,
  3230. "must be secure failure, "
  3231. "%s is under DLV (finddlvsep)", namebuf);
  3232. return (DNS_R_MUSTBESECURE);
  3233. }
  3234. dns_fixedname_init(&val->dlvsep);
  3235. dlvsep = dns_fixedname_name(&val->dlvsep);
  3236. dns_name_copy(val->event->name, dlvsep, NULL);
  3237. /*
  3238. * If this is a response to a DS query, we need to look in
  3239. * the parent zone for the trust anchor.
  3240. */
  3241. if (val->event->type == dns_rdatatype_ds) {
  3242. labels = dns_name_countlabels(dlvsep);
  3243. if (labels == 0)
  3244. return (ISC_R_NOTFOUND);
  3245. dns_name_getlabelsequence(dlvsep, 1, labels - 1,
  3246. dlvsep);
  3247. }
  3248. } else {
  3249. dlvsep = dns_fixedname_name(&val->dlvsep);
  3250. labels = dns_name_countlabels(dlvsep);
  3251. dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep);
  3252. }
  3253. dns_name_init(&noroot, NULL);
  3254. dns_fixedname_init(&dlvfixed);
  3255. dlvname = dns_fixedname_name(&dlvfixed);
  3256. labels = dns_name_countlabels(dlvsep);
  3257. if (labels == 0)
  3258. return (ISC_R_NOTFOUND);
  3259. dns_name_getlabelsequence(dlvsep, 0, labels - 1, &noroot);
  3260. result = dns_name_concatenate(&noroot, val->view->dlv, dlvname, NULL);
  3261. while (result == ISC_R_NOSPACE) {
  3262. labels = dns_name_countlabels(dlvsep);
  3263. dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep);
  3264. dns_name_getlabelsequence(dlvsep, 0, labels - 2, &noroot);
  3265. result = dns_name_concatenate(&noroot, val->view->dlv,
  3266. dlvname, NULL);
  3267. }
  3268. if (result != ISC_R_SUCCESS) {
  3269. validator_log(val, ISC_LOG_DEBUG(2), "DLV concatenate failed");
  3270. return (DNS_R_NOVALIDSIG);
  3271. }
  3272. while (dns_name_countlabels(dlvname) >=
  3273. dns_name_countlabels(val->view->dlv) + val->dlvlabels) {
  3274. dns_name_format(dlvname, namebuf, sizeof(namebuf));
  3275. validator_log(val, ISC_LOG_DEBUG(3), "looking for DLV %s",
  3276. namebuf);
  3277. result = view_find(val, dlvname, dns_rdatatype_dlv);
  3278. if (result == ISC_R_SUCCESS) {
  3279. if (DNS_TRUST_PENDING(val->frdataset.trust) &&
  3280. dns_rdataset_isassociated(&val->fsigrdataset))
  3281. {
  3282. dns_fixedname_init(&val->fname);
  3283. dns_name_copy(dlvname,
  3284. dns_fixedname_name(&val->fname),
  3285. NULL);
  3286. result = create_validator(val,
  3287. dns_fixedname_name(&val->fname),
  3288. dns_rdatatype_dlv,
  3289. &val->frdataset,
  3290. &val->fsigrdataset,
  3291. dlvvalidated,
  3292. "finddlvsep");
  3293. if (result != ISC_R_SUCCESS)
  3294. return (result);
  3295. return (DNS_R_WAIT);
  3296. }
  3297. if (val->frdataset.trust < dns_trust_secure) {
  3298. validator_log(val, ISC_LOG_DEBUG(3),
  3299. "DLV not validated");
  3300. return (DNS_R_NOVALIDSIG);
  3301. }
  3302. val->havedlvsep = ISC_TRUE;
  3303. dns_rdataset_clone(&val->frdataset, &val->dlv);
  3304. return (ISC_R_SUCCESS);
  3305. }
  3306. if (result == ISC_R_NOTFOUND) {
  3307. result = create_fetch(val, dlvname, dns_rdatatype_dlv,
  3308. dlvfetched, "finddlvsep");
  3309. if (result != ISC_R_SUCCESS)
  3310. return (result);
  3311. return (DNS_R_WAIT);
  3312. }
  3313. if (result != DNS_R_NXRRSET &&
  3314. result != DNS_R_NXDOMAIN &&
  3315. result != DNS_R_EMPTYNAME &&
  3316. result != DNS_R_NCACHENXRRSET &&
  3317. result != DNS_R_NCACHENXDOMAIN)
  3318. return (result);
  3319. /*
  3320. * Strip first labels from both dlvsep and dlvname.
  3321. */
  3322. labels = dns_name_countlabels(dlvsep);
  3323. if (labels == 0)
  3324. break;
  3325. dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep);
  3326. labels = dns_name_countlabels(dlvname);
  3327. dns_name_getlabelsequence(dlvname, 1, labels - 1, dlvname);
  3328. }
  3329. return (ISC_R_NOTFOUND);
  3330. }
  3331. /*%
  3332. * proveunsecure walks down from the SEP looking for a break in the
  3333. * chain of trust. That occurs when we can prove the DS record does
  3334. * not exist at a delegation point or the DS exists at a delegation
  3335. * but we don't support the algorithm/digest.
  3336. *
  3337. * If DLV is active and we look for a DLV record at or below the
  3338. * point we go insecure. If found we restart the validation process.
  3339. * If not found or DLV isn't active we mark the response as a answer.
  3340. *
  3341. * Returns:
  3342. * \li ISC_R_SUCCESS val->event->name is in a unsecure zone
  3343. * \li DNS_R_WAIT validation is in progress.
  3344. * \li DNS_R_MUSTBESECURE val->event->name is supposed to be secure
  3345. * (policy) but we proved that it is unsecure.
  3346. * \li DNS_R_NOVALIDSIG
  3347. * \li DNS_R_NOVALIDNSEC
  3348. * \li DNS_R_NOTINSECURE
  3349. * \li DNS_R_BROKENCHAIN
  3350. */
  3351. static isc_result_t
  3352. proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
  3353. {
  3354. isc_result_t result;
  3355. dns_fixedname_t fixedsecroot;
  3356. dns_name_t *secroot;
  3357. dns_name_t *tname;
  3358. char namebuf[DNS_NAME_FORMATSIZE];
  3359. dns_name_t *found;
  3360. dns_fixedname_t fixedfound;
  3361. dns_fixedname_init(&fixedsecroot);
  3362. secroot = dns_fixedname_name(&fixedsecroot);
  3363. dns_fixedname_init(&fixedfound);
  3364. found = dns_fixedname_name(&fixedfound);
  3365. if (val->havedlvsep)
  3366. dns_name_copy(dns_fixedname_name(&val->dlvsep), secroot, NULL);
  3367. else {
  3368. unsigned int labels;
  3369. dns_name_copy(val->event->name, secroot, NULL);
  3370. /*
  3371. * If this is a response to a DS query, we need to look in
  3372. * the parent zone for the trust anchor.
  3373. */
  3374. labels = dns_name_countlabels(secroot);
  3375. if (val->event->type == dns_rdatatype_ds && labels > 1U)
  3376. dns_name_getlabelsequence(secroot, 1, labels - 1,
  3377. secroot);
  3378. result = dns_keytable_finddeepestmatch(val->keytable,
  3379. secroot, secroot);
  3380. if (result == ISC_R_NOTFOUND) {
  3381. if (val->mustbesecure) {
  3382. validator_log(val, ISC_LOG_WARNING,
  3383. "must be secure failure, "
  3384. "not beneath secure root");
  3385. result = DNS_R_MUSTBESECURE;
  3386. goto out;
  3387. } else
  3388. validator_log(val, ISC_LOG_DEBUG(3),
  3389. "not beneath secure root");
  3390. if (val->view->dlv == NULL || DLVTRIED(val)) {
  3391. markanswer(val, "proveunsecure (1)");
  3392. return (ISC_R_SUCCESS);
  3393. }
  3394. return (startfinddlvsep(val, dns_rootname));
  3395. } else if (result != ISC_R_SUCCESS)
  3396. return (result);
  3397. }
  3398. if (!resume) {
  3399. /*
  3400. * We are looking for breaks below the SEP so add a label.
  3401. */
  3402. val->labels = dns_name_countlabels(secroot) + 1;
  3403. } else {
  3404. validator_log(val, ISC_LOG_DEBUG(3), "resuming proveunsecure");
  3405. /*
  3406. * If we have a DS rdataset and it is secure then check if
  3407. * the DS rdataset has a supported algorithm combination.
  3408. * If not this is an insecure delegation as far as this
  3409. * resolver is concerned. Fall back to DLV if available.
  3410. */
  3411. if (have_ds && val->frdataset.trust >= dns_trust_secure &&
  3412. !check_ds(val, dns_fixedname_name(&val->fname),
  3413. &val->frdataset)) {
  3414. dns_name_format(dns_fixedname_name(&val->fname),
  3415. namebuf, sizeof(namebuf));
  3416. if ((val->view->dlv == NULL || DLVTRIED(val)) &&
  3417. val->mustbesecure) {
  3418. validator_log(val, ISC_LOG_WARNING,
  3419. "must be secure failure at '%s', "
  3420. "can't fall back to DLV",
  3421. namebuf);
  3422. result = DNS_R_MUSTBESECURE;
  3423. goto out;
  3424. }
  3425. validator_log(val, ISC_LOG_DEBUG(3),
  3426. "no supported algorithm/digest (%s/DS)",
  3427. namebuf);
  3428. if (val->view->dlv == NULL || DLVTRIED(val)) {
  3429. markanswer(val, "proveunsecure (2)");
  3430. result = ISC_R_SUCCESS;
  3431. goto out;
  3432. }
  3433. return(startfinddlvsep(val,
  3434. dns_fixedname_name(&val->fname)));
  3435. }
  3436. val->labels++;
  3437. }
  3438. for (;
  3439. val->labels <= dns_name_countlabels(val->event->name);
  3440. val->labels++)
  3441. {
  3442. dns_fixedname_init(&val->fname);
  3443. tname = dns_fixedname_name(&val->fname);
  3444. if (val->labels == dns_name_countlabels(val->event->name))
  3445. dns_name_copy(val->event->name, tname, NULL);
  3446. else
  3447. dns_name_split(val->event->name, val->labels,
  3448. NULL, tname);
  3449. dns_name_format(tname, namebuf, sizeof(namebuf));
  3450. validator_log(val, ISC_LOG_DEBUG(3),
  3451. "checking existence of DS at '%s'",
  3452. namebuf);
  3453. result = view_find(val, tname, dns_rdatatype_ds);
  3454. if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) {
  3455. /*
  3456. * There is no DS. If this is a delegation,
  3457. * we may be done.
  3458. */
  3459. /*
  3460. * If we have "trust == answer" then this namespace
  3461. * has switched from insecure to should be secure.
  3462. */
  3463. if (DNS_TRUST_PENDING(val->frdataset.trust) ||
  3464. DNS_TRUST_ANSWER(val->frdataset.trust)) {
  3465. result = create_validator(val, tname,
  3466. dns_rdatatype_ds,
  3467. &val->frdataset,
  3468. NULL, dsvalidated,
  3469. "proveunsecure");
  3470. if (result != ISC_R_SUCCESS)
  3471. goto out;
  3472. return (DNS_R_WAIT);
  3473. }
  3474. /*
  3475. * Zones using NSEC3 don't return a NSEC RRset so
  3476. * we need to use dns_view_findzonecut2 to find
  3477. * the zone cut.
  3478. */
  3479. if (result == DNS_R_NXRRSET &&
  3480. !dns_rdataset_isassociated(&val->frdataset) &&
  3481. dns_view_findzonecut2(val->view, tname, found,
  3482. 0, 0, ISC_FALSE, ISC_FALSE,
  3483. NULL, NULL) == ISC_R_SUCCESS &&
  3484. dns_name_equal(tname, found)) {
  3485. if (val->mustbesecure) {
  3486. validator_log(val, ISC_LOG_WARNING,
  3487. "must be secure failure, "
  3488. "no DS at zone cut");
  3489. return (DNS_R_MUSTBESECURE);
  3490. }
  3491. if (val->view->dlv == NULL || DLVTRIED(val)) {
  3492. markanswer(val, "proveunsecure (3)");
  3493. return (ISC_R_SUCCESS);
  3494. }
  3495. return (startfinddlvsep(val, tname));
  3496. }
  3497. if (val->frdataset.trust < dns_trust_secure) {
  3498. /*
  3499. * This shouldn't happen, since the negative
  3500. * response should have been validated. Since
  3501. * there's no way of validating existing
  3502. * negative response blobs, give up.
  3503. */
  3504. validator_log(val, ISC_LOG_WARNING,
  3505. "can't validate existing "
  3506. "negative responses (no DS)");
  3507. result = DNS_R_NOVALIDSIG;
  3508. goto out;
  3509. }
  3510. if (isdelegation(tname, &val->frdataset, result)) {
  3511. if (val->mustbesecure) {
  3512. validator_log(val, ISC_LOG_WARNING,
  3513. "must be secure failure, "
  3514. "%s is a delegation",
  3515. namebuf);
  3516. return (DNS_R_MUSTBESECURE);
  3517. }
  3518. if (val->view->dlv == NULL || DLVTRIED(val)) {
  3519. markanswer(val, "proveunsecure (4)");
  3520. return (ISC_R_SUCCESS);
  3521. }
  3522. return (startfinddlvsep(val, tname));
  3523. }
  3524. continue;
  3525. } else if (result == DNS_R_CNAME) {
  3526. if (DNS_TRUST_PENDING(val->frdataset.trust) ||
  3527. DNS_TRUST_ANSWER(val->frdataset.trust)) {
  3528. result = create_validator(val, tname,
  3529. dns_rdatatype_cname,
  3530. &val->frdataset,
  3531. NULL, cnamevalidated,
  3532. "proveunsecure "
  3533. "(cname)");
  3534. if (result != ISC_R_SUCCESS)
  3535. goto out;
  3536. return (DNS_R_WAIT);
  3537. }
  3538. continue;
  3539. } else if (result == ISC_R_SUCCESS) {
  3540. /*
  3541. * There is a DS here. Verify that it's secure and
  3542. * continue.
  3543. */
  3544. if (val->frdataset.trust >= dns_trust_secure) {
  3545. if (!check_ds(val, tname, &val->frdataset)) {
  3546. validator_log(val, ISC_LOG_DEBUG(3),
  3547. "no supported algorithm/"
  3548. "digest (%s/DS)", namebuf);
  3549. if (val->mustbesecure) {
  3550. validator_log(val,
  3551. ISC_LOG_WARNING,
  3552. "must be secure failure, "
  3553. "no supported algorithm/"
  3554. "digest (%s/DS)",
  3555. namebuf);
  3556. result = DNS_R_MUSTBESECURE;
  3557. goto out;
  3558. }
  3559. if (val->view->dlv == NULL ||
  3560. DLVTRIED(val)) {
  3561. markanswer(val,
  3562. "proveunsecure (5)");
  3563. result = ISC_R_SUCCESS;
  3564. goto out;
  3565. }
  3566. return(startfinddlvsep(val, tname));
  3567. }
  3568. continue;
  3569. }
  3570. else if (!dns_rdataset_isassociated(&val->fsigrdataset))
  3571. {
  3572. validator_log(val, ISC_LOG_DEBUG(3),
  3573. "DS is unsigned");
  3574. result = DNS_R_NOVALIDSIG;
  3575. goto out;
  3576. }
  3577. /*
  3578. * Validate / re-validate answer.
  3579. */
  3580. result = create_validator(val, tname, dns_rdatatype_ds,
  3581. &val->frdataset,
  3582. &val->fsigrdataset,
  3583. dsvalidated,
  3584. "proveunsecure");
  3585. if (result != ISC_R_SUCCESS)
  3586. goto out;
  3587. return (DNS_R_WAIT);
  3588. } else if (result == DNS_R_NXDOMAIN ||
  3589. result == DNS_R_NCACHENXDOMAIN) {
  3590. /*
  3591. * This is not a zone cut. Assuming things are
  3592. * as expected, continue.
  3593. */
  3594. if (!dns_rdataset_isassociated(&val->frdataset)) {
  3595. /*
  3596. * There should be an NSEC here, since we
  3597. * are still in a secure zone.
  3598. */
  3599. result = DNS_R_NOVALIDNSEC;
  3600. goto out;
  3601. } else if (DNS_TRUST_PENDING(val->frdataset.trust) ||
  3602. DNS_TRUST_ANSWER(val->frdataset.trust)) {
  3603. /*
  3604. * If we have "trust == answer" then this namespace
  3605. * has switched from insecure to should be secure.
  3606. */
  3607. result = create_validator(val, tname,
  3608. dns_rdatatype_ds,
  3609. &val->frdataset,
  3610. NULL, dsvalidated,
  3611. "proveunsecure");
  3612. if (result != ISC_R_SUCCESS)
  3613. goto out;
  3614. return (DNS_R_WAIT);
  3615. } else if (val->frdataset.trust < dns_trust_secure) {
  3616. /*
  3617. * This shouldn't happen, since the negative
  3618. * response should have been validated. Since
  3619. * there's no way of validating existing
  3620. * negative response blobs, give up.
  3621. */
  3622. validator_log(val, ISC_LOG_WARNING,
  3623. "can't validate existing "
  3624. "negative responses "
  3625. "(not a zone cut)");
  3626. result = DNS_R_NOVALIDSIG;
  3627. goto out;
  3628. }
  3629. continue;
  3630. } else if (result == ISC_R_NOTFOUND) {
  3631. /*
  3632. * We don't know anything about the DS. Find it.
  3633. */
  3634. result = create_fetch(val, tname, dns_rdatatype_ds,
  3635. dsfetched2, "proveunsecure");
  3636. if (result != ISC_R_SUCCESS)
  3637. goto out;
  3638. return (DNS_R_WAIT);
  3639. } else if (result == DNS_R_BROKENCHAIN)
  3640. return (result);
  3641. }
  3642. /* Couldn't complete insecurity proof */
  3643. validator_log(val, ISC_LOG_DEBUG(3), "insecurity proof failed");
  3644. return (DNS_R_NOTINSECURE);
  3645. out:
  3646. if (dns_rdataset_isassociated(&val->frdataset))
  3647. dns_rdataset_disassociate(&val->frdataset);
  3648. if (dns_rdataset_isassociated(&val->fsigrdataset))
  3649. dns_rdataset_disassociate(&val->fsigrdataset);
  3650. return (result);
  3651. }
  3652. /*%
  3653. * Reset state and revalidate the answer using DLV.
  3654. */
  3655. static void
  3656. dlv_validator_start(dns_validator_t *val) {
  3657. isc_event_t *event;
  3658. validator_log(val, ISC_LOG_DEBUG(3), "dlv_validator_start");
  3659. /*
  3660. * Reset state and try again.
  3661. */
  3662. val->attributes &= VALATTR_DLVTRIED;
  3663. val->options &= ~DNS_VALIDATOR_DLV;
  3664. event = (isc_event_t *)val->event;
  3665. isc_task_send(val->task, &event);
  3666. }
  3667. /*%
  3668. * Start the validation process.
  3669. *
  3670. * Attempt to validate the answer based on the category it appears to
  3671. * fall in.
  3672. * \li 1. secure positive answer.
  3673. * \li 2. unsecure positive answer.
  3674. * \li 3. a negative answer (secure or unsecure).
  3675. *
  3676. * Note a answer that appears to be a secure positive answer may actually
  3677. * be an unsecure positive answer.
  3678. */
  3679. static void
  3680. validator_start(isc_task_t *task, isc_event_t *event) {
  3681. dns_validator_t *val;
  3682. dns_validatorevent_t *vevent;
  3683. isc_boolean_t want_destroy = ISC_FALSE;
  3684. isc_result_t result = ISC_R_FAILURE;
  3685. UNUSED(task);
  3686. REQUIRE(event->ev_type == DNS_EVENT_VALIDATORSTART);
  3687. vevent = (dns_validatorevent_t *)event;
  3688. val = vevent->validator;
  3689. /* If the validator has been canceled, val->event == NULL */
  3690. if (val->event == NULL)
  3691. return;
  3692. if (DLVTRIED(val))
  3693. validator_log(val, ISC_LOG_DEBUG(3), "restarting using DLV");
  3694. else
  3695. validator_log(val, ISC_LOG_DEBUG(3), "starting");
  3696. LOCK(&val->lock);
  3697. if ((val->options & DNS_VALIDATOR_DLV) != 0 &&
  3698. val->event->rdataset != NULL) {
  3699. validator_log(val, ISC_LOG_DEBUG(3), "looking for DLV");
  3700. result = startfinddlvsep(val, dns_rootname);
  3701. } else if (val->event->rdataset != NULL &&
  3702. val->event->sigrdataset != NULL) {
  3703. isc_result_t saved_result;
  3704. /*
  3705. * This looks like a simple validation. We say "looks like"
  3706. * because it might end up requiring an insecurity proof.
  3707. */
  3708. validator_log(val, ISC_LOG_DEBUG(3),
  3709. "attempting positive response validation");
  3710. INSIST(dns_rdataset_isassociated(val->event->rdataset));
  3711. INSIST(dns_rdataset_isassociated(val->event->sigrdataset));
  3712. result = start_positive_validation(val);
  3713. if (result == DNS_R_NOVALIDSIG &&
  3714. (val->attributes & VALATTR_TRIEDVERIFY) == 0)
  3715. {
  3716. saved_result = result;
  3717. validator_log(val, ISC_LOG_DEBUG(3),
  3718. "falling back to insecurity proof");
  3719. val->attributes |= VALATTR_INSECURITY;
  3720. result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
  3721. if (result == DNS_R_NOTINSECURE)
  3722. result = saved_result;
  3723. }
  3724. } else if (val->event->rdataset != NULL &&
  3725. val->event->rdataset->type != 0) {
  3726. /*
  3727. * This is either an unsecure subdomain or a response from
  3728. * a broken server.
  3729. */
  3730. INSIST(dns_rdataset_isassociated(val->event->rdataset));
  3731. validator_log(val, ISC_LOG_DEBUG(3),
  3732. "attempting insecurity proof");
  3733. val->attributes |= VALATTR_INSECURITY;
  3734. result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
  3735. if (result == DNS_R_NOTINSECURE)
  3736. validator_log(val, ISC_LOG_INFO,
  3737. "got insecure response; "
  3738. "parent indicates it should be secure");
  3739. } else if (val->event->rdataset == NULL &&
  3740. val->event->sigrdataset == NULL)
  3741. {
  3742. /*
  3743. * This is a nonexistence validation.
  3744. */
  3745. validator_log(val, ISC_LOG_DEBUG(3),
  3746. "attempting negative response validation");
  3747. if (val->event->message->rcode == dns_rcode_nxdomain) {
  3748. val->attributes |= VALATTR_NEEDNOQNAME;
  3749. val->attributes |= VALATTR_NEEDNOWILDCARD;
  3750. } else
  3751. val->attributes |= VALATTR_NEEDNODATA;
  3752. result = nsecvalidate(val, ISC_FALSE);
  3753. } else if (val->event->rdataset != NULL &&
  3754. NEGATIVE(val->event->rdataset))
  3755. {
  3756. /*
  3757. * This is a nonexistence validation.
  3758. */
  3759. validator_log(val, ISC_LOG_DEBUG(3),
  3760. "attempting negative response validation");
  3761. if (val->event->rdataset->covers == dns_rdatatype_any) {
  3762. val->attributes |= VALATTR_NEEDNOQNAME;
  3763. val->attributes |= VALATTR_NEEDNOWILDCARD;
  3764. } else
  3765. val->attributes |= VALATTR_NEEDNODATA;
  3766. result = nsecvalidate(val, ISC_FALSE);
  3767. } else {
  3768. /*
  3769. * This shouldn't happen.
  3770. */
  3771. INSIST(0);
  3772. }
  3773. if (result != DNS_R_WAIT) {
  3774. want_destroy = exit_check(val);
  3775. validator_done(val, result);
  3776. }
  3777. UNLOCK(&val->lock);
  3778. if (want_destroy)
  3779. destroy(val);
  3780. }
  3781. isc_result_t
  3782. dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
  3783. dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
  3784. dns_message_t *message, unsigned int options,
  3785. isc_task_t *task, isc_taskaction_t action, void *arg,
  3786. dns_validator_t **validatorp)
  3787. {
  3788. isc_result_t result = ISC_R_FAILURE;
  3789. dns_validator_t *val;
  3790. isc_task_t *tclone = NULL;
  3791. dns_validatorevent_t *event;
  3792. REQUIRE(name != NULL);
  3793. REQUIRE(rdataset != NULL ||
  3794. (rdataset == NULL && sigrdataset == NULL && message != NULL));
  3795. REQUIRE(validatorp != NULL && *validatorp == NULL);
  3796. val = isc_mem_get(view->mctx, sizeof(*val));
  3797. if (val == NULL)
  3798. return (ISC_R_NOMEMORY);
  3799. val->view = NULL;
  3800. dns_view_weakattach(view, &val->view);
  3801. event = (dns_validatorevent_t *)
  3802. isc_event_allocate(view->mctx, task,
  3803. DNS_EVENT_VALIDATORSTART,
  3804. validator_start, NULL,
  3805. sizeof(dns_validatorevent_t));
  3806. if (event == NULL) {
  3807. result = ISC_R_NOMEMORY;
  3808. goto cleanup_val;
  3809. }
  3810. isc_task_attach(task, &tclone);
  3811. event->validator = val;
  3812. event->result = ISC_R_FAILURE;
  3813. event->name = name;
  3814. event->type = type;
  3815. event->rdataset = rdataset;
  3816. event->sigrdataset = sigrdataset;
  3817. event->message = message;
  3818. memset(event->proofs, 0, sizeof(event->proofs));
  3819. event->optout = ISC_FALSE;
  3820. result = isc_mutex_init(&val->lock);
  3821. if (result != ISC_R_SUCCESS)
  3822. goto cleanup_event;
  3823. val->event = event;
  3824. val->options = options;
  3825. val->attributes = 0;
  3826. val->fetch = NULL;
  3827. val->subvalidator = NULL;
  3828. val->parent = NULL;
  3829. val->keytable = NULL;
  3830. result = dns_view_getsecroots(val->view, &val->keytable);
  3831. if (result != ISC_R_SUCCESS)
  3832. return (result);
  3833. val->keynode = NULL;
  3834. val->key = NULL;
  3835. val->siginfo = NULL;
  3836. val->task = task;
  3837. val->action = action;
  3838. val->arg = arg;
  3839. val->labels = 0;
  3840. val->currentset = NULL;
  3841. val->keyset = NULL;
  3842. val->dsset = NULL;
  3843. dns_rdataset_init(&val->dlv);
  3844. val->seensig = ISC_FALSE;
  3845. val->havedlvsep = ISC_FALSE;
  3846. val->depth = 0;
  3847. val->authcount = 0;
  3848. val->authfail = 0;
  3849. val->mustbesecure = dns_resolver_getmustbesecure(view->resolver, name);
  3850. dns_rdataset_init(&val->frdataset);
  3851. dns_rdataset_init(&val->fsigrdataset);
  3852. dns_fixedname_init(&val->wild);
  3853. dns_fixedname_init(&val->nearest);
  3854. dns_fixedname_init(&val->closest);
  3855. ISC_LINK_INIT(val, link);
  3856. val->magic = VALIDATOR_MAGIC;
  3857. if ((options & DNS_VALIDATOR_DEFER) == 0)
  3858. isc_task_send(task, ISC_EVENT_PTR(&event));
  3859. *validatorp = val;
  3860. return (ISC_R_SUCCESS);
  3861. cleanup_event:
  3862. isc_task_detach(&tclone);
  3863. isc_event_free(ISC_EVENT_PTR(&event));
  3864. cleanup_val:
  3865. dns_view_weakdetach(&val->view);
  3866. isc_mem_put(view->mctx, val, sizeof(*val));
  3867. return (result);
  3868. }
  3869. void
  3870. dns_validator_send(dns_validator_t *validator) {
  3871. isc_event_t *event;
  3872. REQUIRE(VALID_VALIDATOR(validator));
  3873. LOCK(&validator->lock);
  3874. INSIST((validator->options & DNS_VALIDATOR_DEFER) != 0);
  3875. event = (isc_event_t *)validator->event;
  3876. validator->options &= ~DNS_VALIDATOR_DEFER;
  3877. UNLOCK(&validator->lock);
  3878. isc_task_send(validator->task, ISC_EVENT_PTR(&event));
  3879. }
  3880. void
  3881. dns_validator_cancel(dns_validator_t *validator) {
  3882. REQUIRE(VALID_VALIDATOR(validator));
  3883. LOCK(&validator->lock);
  3884. validator_log(validator, ISC_LOG_DEBUG(3), "dns_validator_cancel");
  3885. if ((validator->attributes & VALATTR_CANCELED) == 0) {
  3886. validator->attributes |= VALATTR_CANCELED;
  3887. if (validator->event != NULL) {
  3888. if (validator->fetch != NULL)
  3889. dns_resolver_cancelfetch(validator->fetch);
  3890. if (validator->subvalidator != NULL)
  3891. dns_validator_cancel(validator->subvalidator);
  3892. if ((validator->options & DNS_VALIDATOR_DEFER) != 0) {
  3893. validator->options &= ~DNS_VALIDATOR_DEFER;
  3894. validator_done(validator, ISC_R_CANCELED);
  3895. }
  3896. }
  3897. }
  3898. UNLOCK(&validator->lock);
  3899. }
  3900. static void
  3901. destroy(dns_validator_t *val) {
  3902. isc_mem_t *mctx;
  3903. REQUIRE(SHUTDOWN(val));
  3904. REQUIRE(val->event == NULL);
  3905. REQUIRE(val->fetch == NULL);
  3906. if (val->keynode != NULL)
  3907. dns_keytable_detachkeynode(val->keytable, &val->keynode);
  3908. else if (val->key != NULL)
  3909. dst_key_free(&val->key);
  3910. if (val->keytable != NULL)
  3911. dns_keytable_detach(&val->keytable);
  3912. if (val->subvalidator != NULL)
  3913. dns_validator_destroy(&val->subvalidator);
  3914. if (val->havedlvsep)
  3915. dns_rdataset_disassociate(&val->dlv);
  3916. if (dns_rdataset_isassociated(&val->frdataset))
  3917. dns_rdataset_disassociate(&val->frdataset);
  3918. if (dns_rdataset_isassociated(&val->fsigrdataset))
  3919. dns_rdataset_disassociate(&val->fsigrdataset);
  3920. mctx = val->view->mctx;
  3921. if (val->siginfo != NULL)
  3922. isc_mem_put(mctx, val->siginfo, sizeof(*val->siginfo));
  3923. DESTROYLOCK(&val->lock);
  3924. dns_view_weakdetach(&val->view);
  3925. val->magic = 0;
  3926. isc_mem_put(mctx, val, sizeof(*val));
  3927. }
  3928. void
  3929. dns_validator_destroy(dns_validator_t **validatorp) {
  3930. dns_validator_t *val;
  3931. isc_boolean_t want_destroy = ISC_FALSE;
  3932. REQUIRE(validatorp != NULL);
  3933. val = *validatorp;
  3934. REQUIRE(VALID_VALIDATOR(val));
  3935. LOCK(&val->lock);
  3936. val->attributes |= VALATTR_SHUTDOWN;
  3937. validator_log(val, ISC_LOG_DEBUG(3), "dns_validator_destroy");
  3938. want_destroy = exit_check(val);
  3939. UNLOCK(&val->lock);
  3940. if (want_destroy)
  3941. destroy(val);
  3942. *validatorp = NULL;
  3943. }
  3944. static void
  3945. validator_logv(dns_validator_t *val, isc_logcategory_t *category,
  3946. isc_logmodule_t *module, int level, const char *fmt, va_list ap)
  3947. {
  3948. char msgbuf[2048];
  3949. static const char spaces[] = " *";
  3950. int depth = val->depth * 2;
  3951. vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
  3952. if ((unsigned int) depth >= sizeof spaces)
  3953. depth = sizeof spaces - 1;
  3954. if (val->event != NULL && val->event->name != NULL) {
  3955. char namebuf[DNS_NAME_FORMATSIZE];
  3956. char typebuf[DNS_RDATATYPE_FORMATSIZE];
  3957. dns_name_format(val->event->name, namebuf, sizeof(namebuf));
  3958. dns_rdatatype_format(val->event->type, typebuf,
  3959. sizeof(typebuf));
  3960. isc_log_write(dns_lctx, category, module, level,
  3961. "%.*svalidating @%p: %s %s: %s", depth, spaces,
  3962. val, namebuf, typebuf, msgbuf);
  3963. } else {
  3964. isc_log_write(dns_lctx, category, module, level,
  3965. "%.*svalidator @%p: %s", depth, spaces,
  3966. val, msgbuf);
  3967. }
  3968. }
  3969. static void
  3970. validator_log(dns_validator_t *val, int level, const char *fmt, ...) {
  3971. va_list ap;
  3972. if (! isc_log_wouldlog(dns_lctx, level))
  3973. return;
  3974. va_start(ap, fmt);
  3975. validator_logv(val, DNS_LOGCATEGORY_DNSSEC,
  3976. DNS_LOGMODULE_VALIDATOR, level, fmt, ap);
  3977. va_end(ap);
  3978. }
  3979. static void
  3980. validator_logcreate(dns_validator_t *val,
  3981. dns_name_t *name, dns_rdatatype_t type,
  3982. const char *caller, const char *operation)
  3983. {
  3984. char namestr[DNS_NAME_FORMATSIZE];
  3985. char typestr[DNS_RDATATYPE_FORMATSIZE];
  3986. dns_name_format(name, namestr, sizeof(namestr));
  3987. dns_rdatatype_format(type, typestr, sizeof(typestr));
  3988. validator_log(val, ISC_LOG_DEBUG(9), "%s: creating %s for %s %s",
  3989. caller, operation, namestr, typestr);
  3990. }