2 * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and 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.
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.
18 /* $Id: validator.c,v 1.91.2.5.8.21 2005/11/02 02:07:47 marka Exp $ */
23 #include <isc/print.h>
24 #include <isc/string.h>
30 #include <dns/dnssec.h>
31 #include <dns/events.h>
32 #include <dns/keytable.h>
34 #include <dns/message.h>
35 #include <dns/ncache.h>
37 #include <dns/rdata.h>
38 #include <dns/rdatastruct.h>
39 #include <dns/rdataset.h>
40 #include <dns/rdatatype.h>
41 #include <dns/resolver.h>
42 #include <dns/result.h>
43 #include <dns/validator.h>
46 #define VALIDATOR_MAGIC ISC_MAGIC('V', 'a', 'l', '?')
47 #define VALID_VALIDATOR(v) ISC_MAGIC_VALID(v, VALIDATOR_MAGIC)
49 #define VALATTR_SHUTDOWN 0x0001
50 #define VALATTR_FOUNDNONEXISTENCE 0x0002
51 #define VALATTR_TRIEDVERIFY 0x0004
52 #define VALATTR_NEGATIVE 0x0008
53 #define VALATTR_INSECURITY 0x0010
54 #define VALATTR_DLVTRIED 0x0020
56 #define VALATTR_NEEDNOQNAME 0x0100
57 #define VALATTR_NEEDNOWILDCARD 0x0200
58 #define VALATTR_NEEDNODATA 0x0400
60 #define VALATTR_FOUNDNOQNAME 0x1000
61 #define VALATTR_FOUNDNOWILDCARD 0x2000
62 #define VALATTR_FOUNDNODATA 0x4000
64 #define NEEDNODATA(val) ((val->attributes & VALATTR_NEEDNODATA) != 0)
65 #define NEEDNOQNAME(val) ((val->attributes & VALATTR_NEEDNOQNAME) != 0)
66 #define NEEDNOWILDCARD(val) ((val->attributes & VALATTR_NEEDNOWILDCARD) != 0)
67 #define DLVTRIED(val) ((val->attributes & VALATTR_DLVTRIED) != 0)
69 #define SHUTDOWN(v) (((v)->attributes & VALATTR_SHUTDOWN) != 0)
72 destroy(dns_validator_t *val);
75 get_dst_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo,
76 dns_rdataset_t *rdataset);
79 validate(dns_validator_t *val, isc_boolean_t resume);
82 validatezonekey(dns_validator_t *val);
85 nsecvalidate(dns_validator_t *val, isc_boolean_t resume);
88 proveunsecure(dns_validator_t *val, isc_boolean_t resume);
91 validator_logv(dns_validator_t *val, isc_logcategory_t *category,
92 isc_logmodule_t *module, int level, const char *fmt, va_list ap)
93 ISC_FORMAT_PRINTF(5, 0);
96 validator_log(dns_validator_t *val, int level, const char *fmt, ...)
97 ISC_FORMAT_PRINTF(3, 4);
100 validator_logcreate(dns_validator_t *val,
101 dns_name_t *name, dns_rdatatype_t type,
102 const char *caller, const char *operation);
105 dlv_validatezonekey(dns_validator_t *val);
108 dlv_validator_start(dns_validator_t *val);
111 finddlvsep(dns_validator_t *val, isc_boolean_t resume);
114 markanswer(dns_validator_t *val) {
115 validator_log(val, ISC_LOG_DEBUG(3), "marking as answer");
116 if (val->event->rdataset)
117 val->event->rdataset->trust = dns_trust_answer;
118 if (val->event->sigrdataset)
119 val->event->sigrdataset->trust = dns_trust_answer;
123 validator_done(dns_validator_t *val, isc_result_t result) {
126 if (val->event == NULL)
130 * Caller must be holding the lock.
133 val->event->result = result;
134 task = val->event->ev_sender;
135 val->event->ev_sender = val;
136 val->event->ev_type = DNS_EVENT_VALIDATORDONE;
137 val->event->ev_action = val->action;
138 val->event->ev_arg = val->arg;
139 isc_task_sendanddetach(&task, (isc_event_t **)&val->event);
142 static inline isc_boolean_t
143 exit_check(dns_validator_t *val) {
145 * Caller must be holding the lock.
150 INSIST(val->event == NULL);
152 if (val->fetch != NULL || val->subvalidator != NULL)
159 auth_nonpending(dns_message_t *message) {
162 dns_rdataset_t *rdataset;
164 for (result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
165 result == ISC_R_SUCCESS;
166 result = dns_message_nextname(message, DNS_SECTION_AUTHORITY))
169 dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
170 for (rdataset = ISC_LIST_HEAD(name->list);
172 rdataset = ISC_LIST_NEXT(rdataset, link))
174 if (rdataset->trust == dns_trust_pending)
175 rdataset->trust = dns_trust_authauthority;
181 isdelegation(dns_name_t *name, dns_rdataset_t *rdataset,
182 isc_result_t dbresult)
185 dns_rdata_t rdata = DNS_RDATA_INIT;
189 REQUIRE(dbresult == DNS_R_NXRRSET || dbresult == DNS_R_NCACHENXRRSET);
191 dns_rdataset_init(&set);
192 if (dbresult == DNS_R_NXRRSET)
193 dns_rdataset_clone(rdataset, &set);
195 result = dns_ncache_getrdataset(rdataset, name,
196 dns_rdatatype_nsec, &set);
197 if (result != ISC_R_SUCCESS)
201 INSIST(set.type == dns_rdatatype_nsec);
204 result = dns_rdataset_first(&set);
205 if (result == ISC_R_SUCCESS) {
206 dns_rdataset_current(&set, &rdata);
207 found = dns_nsec_typepresent(&rdata, dns_rdatatype_ns);
209 dns_rdataset_disassociate(&set);
214 fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
215 dns_fetchevent_t *devent;
216 dns_validator_t *val;
217 dns_rdataset_t *rdataset;
218 isc_boolean_t want_destroy;
220 isc_result_t eresult;
223 INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
224 devent = (dns_fetchevent_t *)event;
225 val = devent->ev_arg;
226 rdataset = &val->frdataset;
227 eresult = devent->result;
229 /* Free resources which are not of interest. */
230 if (devent->node != NULL)
231 dns_db_detachnode(devent->db, &devent->node);
232 if (devent->db != NULL)
233 dns_db_detach(&devent->db);
234 if (dns_rdataset_isassociated(&val->fsigrdataset))
235 dns_rdataset_disassociate(&val->fsigrdataset);
236 isc_event_free(&event);
237 dns_resolver_destroyfetch(&val->fetch);
239 INSIST(val->event != NULL);
241 validator_log(val, ISC_LOG_DEBUG(3), "in fetch_callback_validator");
243 if (eresult == ISC_R_SUCCESS) {
244 validator_log(val, ISC_LOG_DEBUG(3),
245 "keyset with trust %d", rdataset->trust);
247 * Only extract the dst key if the keyset is secure.
249 if (rdataset->trust >= dns_trust_secure) {
250 result = get_dst_key(val, val->siginfo, rdataset);
251 if (result == ISC_R_SUCCESS)
252 val->keyset = &val->frdataset;
254 result = validate(val, ISC_TRUE);
255 if (result != DNS_R_WAIT)
256 validator_done(val, result);
258 validator_log(val, ISC_LOG_DEBUG(3),
259 "fetch_callback_validator: got %s",
260 isc_result_totext(eresult));
261 if (eresult == ISC_R_CANCELED)
262 validator_done(val, eresult);
264 validator_done(val, DNS_R_NOVALIDKEY);
266 want_destroy = exit_check(val);
273 dsfetched(isc_task_t *task, isc_event_t *event) {
274 dns_fetchevent_t *devent;
275 dns_validator_t *val;
276 dns_rdataset_t *rdataset;
277 isc_boolean_t want_destroy;
279 isc_result_t eresult;
282 INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
283 devent = (dns_fetchevent_t *)event;
284 val = devent->ev_arg;
285 rdataset = &val->frdataset;
286 eresult = devent->result;
288 /* Free resources which are not of interest. */
289 if (devent->node != NULL)
290 dns_db_detachnode(devent->db, &devent->node);
291 if (devent->db != NULL)
292 dns_db_detach(&devent->db);
293 if (dns_rdataset_isassociated(&val->fsigrdataset))
294 dns_rdataset_disassociate(&val->fsigrdataset);
295 isc_event_free(&event);
296 dns_resolver_destroyfetch(&val->fetch);
298 INSIST(val->event != NULL);
300 validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched");
302 if (eresult == ISC_R_SUCCESS) {
303 validator_log(val, ISC_LOG_DEBUG(3),
304 "dsset with trust %d", rdataset->trust);
305 val->dsset = &val->frdataset;
306 result = validatezonekey(val);
307 if (result != DNS_R_WAIT)
308 validator_done(val, result);
309 } else if (eresult == DNS_R_NXRRSET ||
310 eresult == DNS_R_NCACHENXRRSET)
312 validator_log(val, ISC_LOG_DEBUG(3),
313 "falling back to insecurity proof");
314 val->attributes |= VALATTR_INSECURITY;
315 result = proveunsecure(val, ISC_FALSE);
316 if (result != DNS_R_WAIT)
317 validator_done(val, result);
319 validator_log(val, ISC_LOG_DEBUG(3),
321 isc_result_totext(eresult));
322 if (eresult == ISC_R_CANCELED)
323 validator_done(val, eresult);
325 validator_done(val, DNS_R_NOVALIDDS);
327 want_destroy = exit_check(val);
334 * XXX there's too much duplicated code here.
337 dsfetched2(isc_task_t *task, isc_event_t *event) {
338 dns_fetchevent_t *devent;
339 dns_validator_t *val;
341 isc_boolean_t want_destroy;
343 isc_result_t eresult;
346 INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
347 devent = (dns_fetchevent_t *)event;
348 val = devent->ev_arg;
349 eresult = devent->result;
351 /* Free resources which are not of interest. */
352 if (devent->node != NULL)
353 dns_db_detachnode(devent->db, &devent->node);
354 if (devent->db != NULL)
355 dns_db_detach(&devent->db);
356 if (dns_rdataset_isassociated(&val->fsigrdataset))
357 dns_rdataset_disassociate(&val->fsigrdataset);
358 dns_resolver_destroyfetch(&val->fetch);
360 INSIST(val->event != NULL);
362 validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched2");
364 if (eresult == DNS_R_NXRRSET || eresult == DNS_R_NCACHENXRRSET) {
366 * There is no DS. If this is a delegation, we're done.
368 tname = dns_fixedname_name(&devent->foundname);
369 if (isdelegation(tname, &val->frdataset, eresult)) {
370 if (val->mustbesecure) {
371 validator_log(val, ISC_LOG_WARNING,
372 "must be secure failure");
373 validator_done(val, DNS_R_MUSTBESECURE);
376 validator_done(val, ISC_R_SUCCESS);
379 result = proveunsecure(val, ISC_TRUE);
380 if (result != DNS_R_WAIT)
381 validator_done(val, result);
383 } else if (eresult == ISC_R_SUCCESS ||
384 eresult == DNS_R_NXDOMAIN ||
385 eresult == DNS_R_NCACHENXDOMAIN)
388 * Either there is a DS or this is not a zone cut. Continue.
390 result = proveunsecure(val, ISC_TRUE);
391 if (result != DNS_R_WAIT)
392 validator_done(val, result);
394 if (eresult == ISC_R_CANCELED)
395 validator_done(val, eresult);
397 validator_done(val, DNS_R_NOVALIDDS);
399 isc_event_free(&event);
400 want_destroy = exit_check(val);
407 keyvalidated(isc_task_t *task, isc_event_t *event) {
408 dns_validatorevent_t *devent;
409 dns_validator_t *val;
410 isc_boolean_t want_destroy;
412 isc_result_t eresult;
415 INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
417 devent = (dns_validatorevent_t *)event;
418 val = devent->ev_arg;
419 eresult = devent->result;
421 isc_event_free(&event);
422 dns_validator_destroy(&val->subvalidator);
424 INSIST(val->event != NULL);
426 validator_log(val, ISC_LOG_DEBUG(3), "in keyvalidated");
428 if (eresult == ISC_R_SUCCESS) {
429 validator_log(val, ISC_LOG_DEBUG(3),
430 "keyset with trust %d", val->frdataset.trust);
432 * Only extract the dst key if the keyset is secure.
434 if (val->frdataset.trust >= dns_trust_secure)
435 (void) get_dst_key(val, val->siginfo, &val->frdataset);
436 result = validate(val, ISC_TRUE);
437 if (result != DNS_R_WAIT)
438 validator_done(val, result);
440 validator_log(val, ISC_LOG_DEBUG(3),
441 "keyvalidated: got %s",
442 isc_result_totext(eresult));
443 validator_done(val, eresult);
445 want_destroy = exit_check(val);
452 dsvalidated(isc_task_t *task, isc_event_t *event) {
453 dns_validatorevent_t *devent;
454 dns_validator_t *val;
455 isc_boolean_t want_destroy;
457 isc_result_t eresult;
460 INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
462 devent = (dns_validatorevent_t *)event;
463 val = devent->ev_arg;
464 eresult = devent->result;
466 isc_event_free(&event);
467 dns_validator_destroy(&val->subvalidator);
469 INSIST(val->event != NULL);
471 validator_log(val, ISC_LOG_DEBUG(3), "in dsvalidated");
473 if (eresult == ISC_R_SUCCESS) {
474 validator_log(val, ISC_LOG_DEBUG(3),
475 "dsset with trust %d", val->frdataset.trust);
476 if ((val->attributes & VALATTR_INSECURITY) != 0)
477 result = proveunsecure(val, ISC_TRUE);
479 result = validatezonekey(val);
480 if (result != DNS_R_WAIT)
481 validator_done(val, result);
483 validator_log(val, ISC_LOG_DEBUG(3),
484 "dsvalidated: got %s",
485 isc_result_totext(eresult));
486 validator_done(val, eresult);
488 want_destroy = exit_check(val);
495 * Return ISC_R_SUCCESS if we can determine that the name doesn't exist
496 * or we can determine whether there is data or not at the name.
497 * If the name does not exist return the wildcard name.
500 nsecnoexistnodata(dns_validator_t *val, dns_name_t* name, dns_name_t *nsecname,
501 dns_rdataset_t *nsecset, isc_boolean_t *exists,
502 isc_boolean_t *data, dns_name_t *wild)
505 dns_rdata_t rdata = DNS_RDATA_INIT;
507 dns_namereln_t relation;
508 unsigned int olabels, nlabels, labels;
509 dns_rdata_nsec_t nsec;
510 isc_boolean_t atparent;
512 REQUIRE(exists != NULL);
513 REQUIRE(data != NULL);
514 REQUIRE(nsecset != NULL &&
515 nsecset->type == dns_rdatatype_nsec);
517 result = dns_rdataset_first(nsecset);
518 if (result != ISC_R_SUCCESS) {
519 validator_log(val, ISC_LOG_DEBUG(3),
520 "failure processing NSEC set");
523 dns_rdataset_current(nsecset, &rdata);
525 validator_log(val, ISC_LOG_DEBUG(3), "looking for relevant nsec");
526 relation = dns_name_fullcompare(name, nsecname, &order, &olabels);
530 * The name is not within the NSEC range.
532 validator_log(val, ISC_LOG_DEBUG(3),
533 "NSEC does not cover name, before NSEC");
534 return (ISC_R_IGNORE);
539 * The names are the same.
541 atparent = dns_rdatatype_atparent(val->event->type);
542 if (dns_nsec_typepresent(&rdata, dns_rdatatype_ns) &&
543 !dns_nsec_typepresent(&rdata, dns_rdatatype_soa))
547 * This NSEC record is from somewhere higher in
548 * the DNS, and at the parent of a delegation.
549 * It can not be legitimately used here.
551 validator_log(val, ISC_LOG_DEBUG(3),
552 "ignoring parent nsec");
553 return (ISC_R_IGNORE);
555 } else if (atparent) {
557 * This NSEC record is from the child.
558 * It can not be legitimately used here.
560 validator_log(val, ISC_LOG_DEBUG(3),
561 "ignoring child nsec");
562 return (ISC_R_IGNORE);
565 *data = dns_nsec_typepresent(&rdata, val->event->type);
566 validator_log(val, ISC_LOG_DEBUG(3),
567 "nsec proves name exists (owner) data=%d",
569 return (ISC_R_SUCCESS);
572 if (relation == dns_namereln_subdomain &&
573 dns_nsec_typepresent(&rdata, dns_rdatatype_ns) &&
574 !dns_nsec_typepresent(&rdata, dns_rdatatype_soa))
577 * This NSEC record is from somewhere higher in
578 * the DNS, and at the parent of a delegation.
579 * It can not be legitimately used here.
581 validator_log(val, ISC_LOG_DEBUG(3), "ignoring parent nsec");
582 return (ISC_R_IGNORE);
585 result = dns_rdata_tostruct(&rdata, &nsec, NULL);
586 if (result != ISC_R_SUCCESS)
588 relation = dns_name_fullcompare(&nsec.next, name, &order, &nlabels);
590 dns_rdata_freestruct(&nsec);
591 validator_log(val, ISC_LOG_DEBUG(3),
592 "ignoring nsec matches next name");
593 return (ISC_R_IGNORE);
596 if (order < 0 && !dns_name_issubdomain(nsecname, &nsec.next)) {
598 * The name is not within the NSEC range.
600 dns_rdata_freestruct(&nsec);
601 validator_log(val, ISC_LOG_DEBUG(3),
602 "ignoring nsec because name is past end of range");
603 return (ISC_R_IGNORE);
606 if (order > 0 && relation == dns_namereln_subdomain) {
607 validator_log(val, ISC_LOG_DEBUG(3),
608 "nsec proves name exist (empty)");
609 dns_rdata_freestruct(&nsec);
612 return (ISC_R_SUCCESS);
616 dns_name_init(&common, NULL);
617 if (olabels > nlabels) {
618 labels = dns_name_countlabels(nsecname);
619 dns_name_getlabelsequence(nsecname, labels - olabels,
622 labels = dns_name_countlabels(&nsec.next);
623 dns_name_getlabelsequence(&nsec.next, labels - nlabels,
626 result = dns_name_concatenate(dns_wildcardname, &common,
628 if (result != ISC_R_SUCCESS) {
629 validator_log(val, ISC_LOG_DEBUG(3),
630 "failure generating wilcard name");
634 dns_rdata_freestruct(&nsec);
635 validator_log(val, ISC_LOG_DEBUG(3), "nsec range ok");
637 return (ISC_R_SUCCESS);
641 authvalidated(isc_task_t *task, isc_event_t *event) {
642 dns_validatorevent_t *devent;
643 dns_validator_t *val;
644 dns_rdataset_t *rdataset;
645 isc_boolean_t want_destroy;
647 isc_boolean_t exists, data;
650 INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
652 devent = (dns_validatorevent_t *)event;
653 rdataset = devent->rdataset;
654 val = devent->ev_arg;
655 result = devent->result;
656 dns_validator_destroy(&val->subvalidator);
658 INSIST(val->event != NULL);
660 validator_log(val, ISC_LOG_DEBUG(3), "in authvalidated");
662 if (result != ISC_R_SUCCESS) {
663 validator_log(val, ISC_LOG_DEBUG(3),
664 "authvalidated: got %s",
665 isc_result_totext(result));
666 if (result == ISC_R_CANCELED)
667 validator_done(val, result);
669 result = nsecvalidate(val, ISC_TRUE);
670 if (result != DNS_R_WAIT)
671 validator_done(val, result);
674 dns_name_t **proofs = val->event->proofs;
676 if (rdataset->trust == dns_trust_secure)
677 val->seensig = ISC_TRUE;
679 if (rdataset->type == dns_rdatatype_nsec &&
680 rdataset->trust == dns_trust_secure &&
681 ((val->attributes & VALATTR_NEEDNODATA) != 0 ||
682 (val->attributes & VALATTR_NEEDNOQNAME) != 0) &&
683 (val->attributes & VALATTR_FOUNDNODATA) == 0 &&
684 (val->attributes & VALATTR_FOUNDNOQNAME) == 0 &&
685 nsecnoexistnodata(val, val->event->name, devent->name,
686 rdataset, &exists, &data,
687 dns_fixedname_name(&val->wild))
690 if (exists && !data) {
691 val->attributes |= VALATTR_FOUNDNODATA;
693 proofs[DNS_VALIDATOR_NODATAPROOF] =
697 val->attributes |= VALATTR_FOUNDNOQNAME;
698 if (NEEDNOQNAME(val))
699 proofs[DNS_VALIDATOR_NOQNAMEPROOF] =
703 result = nsecvalidate(val, ISC_TRUE);
704 if (result != DNS_R_WAIT)
705 validator_done(val, result);
707 want_destroy = exit_check(val);
713 * Free stuff from the event.
715 isc_event_free(&event);
719 negauthvalidated(isc_task_t *task, isc_event_t *event) {
720 dns_validatorevent_t *devent;
721 dns_validator_t *val;
722 isc_boolean_t want_destroy;
723 isc_result_t eresult;
726 INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
728 devent = (dns_validatorevent_t *)event;
729 val = devent->ev_arg;
730 eresult = devent->result;
731 isc_event_free(&event);
732 dns_validator_destroy(&val->subvalidator);
734 INSIST(val->event != NULL);
736 validator_log(val, ISC_LOG_DEBUG(3), "in negauthvalidated");
738 if (eresult == ISC_R_SUCCESS) {
739 val->attributes |= VALATTR_FOUNDNONEXISTENCE;
740 validator_log(val, ISC_LOG_DEBUG(3),
741 "nonexistence proof found");
742 auth_nonpending(val->event->message);
743 validator_done(val, ISC_R_SUCCESS);
745 validator_log(val, ISC_LOG_DEBUG(3),
746 "negauthvalidated: got %s",
747 isc_result_totext(eresult));
748 validator_done(val, eresult);
750 want_destroy = exit_check(val);
756 static inline isc_result_t
757 view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
758 dns_fixedname_t fixedname;
759 dns_name_t *foundname;
760 dns_rdata_nsec_t nsec;
761 dns_rdata_t rdata = DNS_RDATA_INIT;
763 unsigned int options;
764 char buf1[DNS_NAME_FORMATSIZE];
765 char buf2[DNS_NAME_FORMATSIZE];
766 char buf3[DNS_NAME_FORMATSIZE];
768 if (dns_rdataset_isassociated(&val->frdataset))
769 dns_rdataset_disassociate(&val->frdataset);
770 if (dns_rdataset_isassociated(&val->fsigrdataset))
771 dns_rdataset_disassociate(&val->fsigrdataset);
773 if (val->view->zonetable == NULL)
774 return (ISC_R_CANCELED);
776 options = DNS_DBFIND_PENDINGOK;
777 if (type == dns_rdatatype_dlv)
778 options |= DNS_DBFIND_COVERINGNSEC;
779 dns_fixedname_init(&fixedname);
780 foundname = dns_fixedname_name(&fixedname);
781 result = dns_view_find(val->view, name, type, 0, options,
782 ISC_FALSE, NULL, NULL, foundname,
783 &val->frdataset, &val->fsigrdataset);
784 if (result == DNS_R_NXDOMAIN) {
785 if (dns_rdataset_isassociated(&val->frdataset))
786 dns_rdataset_disassociate(&val->frdataset);
787 if (dns_rdataset_isassociated(&val->fsigrdataset))
788 dns_rdataset_disassociate(&val->fsigrdataset);
789 } else if (result == DNS_R_COVERINGNSEC) {
790 validator_log(val, ISC_LOG_DEBUG(3), "DNS_R_COVERINGNSEC");
792 * Check if the returned NSEC covers the name.
794 INSIST(type == dns_rdatatype_dlv);
795 if (val->frdataset.trust != dns_trust_secure) {
796 validator_log(val, ISC_LOG_DEBUG(3),
797 "covering nsec: trust %u",
798 val->frdataset.trust);
801 result = dns_rdataset_first(&val->frdataset);
802 if (result != ISC_R_SUCCESS)
804 dns_rdataset_current(&val->frdataset, &rdata);
805 if (dns_nsec_typepresent(&rdata, dns_rdatatype_ns) &&
806 !dns_nsec_typepresent(&rdata, dns_rdatatype_soa)) {
807 /* Parent NSEC record. */
808 if (dns_name_issubdomain(name, foundname)) {
809 validator_log(val, ISC_LOG_DEBUG(3),
810 "covering nsec: for parent");
814 result = dns_rdata_tostruct(&rdata, &nsec, NULL);
815 if (result != ISC_R_SUCCESS)
817 if (dns_name_compare(foundname, &nsec.next) >= 0) {
818 /* End of zone chain. */
819 if (!dns_name_issubdomain(name, &nsec.next)) {
821 * XXXMPA We could look for a parent NSEC
822 * at nsec.next and if found retest with
825 dns_rdata_freestruct(&nsec);
826 validator_log(val, ISC_LOG_DEBUG(3),
827 "covering nsec: not in zone");
830 } else if (dns_name_compare(name, &nsec.next) >= 0) {
832 * XXXMPA We could check if this NSEC is at a zone
833 * apex and if the qname is not below it and look for
834 * a parent NSEC with the same name. This requires
835 * that we can cache both NSEC records which we
836 * currently don't support.
838 dns_rdata_freestruct(&nsec);
839 validator_log(val, ISC_LOG_DEBUG(3),
840 "covering nsec: not in range");
843 if (isc_log_wouldlog(dns_lctx,ISC_LOG_DEBUG(3))) {
844 dns_name_format(name, buf1, sizeof buf1);
845 dns_name_format(foundname, buf2, sizeof buf2);
846 dns_name_format(&nsec.next, buf3, sizeof buf3);
847 validator_log(val, ISC_LOG_DEBUG(3),
848 "covering nsec found: '%s' '%s' '%s'",
851 if (dns_rdataset_isassociated(&val->frdataset))
852 dns_rdataset_disassociate(&val->frdataset);
853 if (dns_rdataset_isassociated(&val->fsigrdataset))
854 dns_rdataset_disassociate(&val->fsigrdataset);
855 dns_rdata_freestruct(&nsec);
856 result = DNS_R_NCACHENXDOMAIN;
857 } else if (result != ISC_R_SUCCESS &&
858 result != DNS_R_GLUE &&
859 result != DNS_R_HINT &&
860 result != DNS_R_NCACHENXDOMAIN &&
861 result != DNS_R_NCACHENXRRSET &&
862 result != DNS_R_NXRRSET &&
863 result != DNS_R_HINTNXRRSET &&
864 result != ISC_R_NOTFOUND) {
870 if (dns_rdataset_isassociated(&val->frdataset))
871 dns_rdataset_disassociate(&val->frdataset);
872 if (dns_rdataset_isassociated(&val->fsigrdataset))
873 dns_rdataset_disassociate(&val->fsigrdataset);
874 return (ISC_R_NOTFOUND);
877 static inline isc_boolean_t
878 check_deadlock(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
879 dns_validator_t *parent;
881 for (parent = val->parent; parent != NULL; parent = parent->parent) {
882 if (parent->event != NULL &&
883 parent->event->type == type &&
884 dns_name_equal(parent->event->name, name))
886 validator_log(val, ISC_LOG_DEBUG(3),
887 "continuing validation would lead to "
888 "deadlock: aborting validation");
895 static inline isc_result_t
896 create_fetch(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
897 isc_taskaction_t callback, const char *caller)
899 if (dns_rdataset_isassociated(&val->frdataset))
900 dns_rdataset_disassociate(&val->frdataset);
901 if (dns_rdataset_isassociated(&val->fsigrdataset))
902 dns_rdataset_disassociate(&val->fsigrdataset);
904 if (check_deadlock(val, name, type))
905 return (DNS_R_NOVALIDSIG);
907 validator_logcreate(val, name, type, caller, "fetch");
908 return (dns_resolver_createfetch(val->view->resolver, name, type,
910 val->event->ev_sender,
917 static inline isc_result_t
918 create_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
919 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
920 isc_taskaction_t action, const char *caller)
924 if (check_deadlock(val, name, type))
925 return (DNS_R_NOVALIDSIG);
927 validator_logcreate(val, name, type, caller, "validator");
928 result = dns_validator_create(val->view, name, type,
929 rdataset, sigrdataset, NULL, 0,
930 val->task, action, val,
932 if (result == ISC_R_SUCCESS) {
933 val->subvalidator->parent = val;
934 val->subvalidator->depth = val->depth + 1;
940 * Try to find a key that could have signed 'siginfo' among those
941 * in 'rdataset'. If found, build a dst_key_t for it and point
944 * If val->key is non-NULL, this returns the next matching key.
947 get_dst_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo,
948 dns_rdataset_t *rdataset)
952 dns_rdata_t rdata = DNS_RDATA_INIT;
953 dst_key_t *oldkey = val->key;
954 isc_boolean_t foundold;
959 foundold = ISC_FALSE;
963 result = dns_rdataset_first(rdataset);
964 if (result != ISC_R_SUCCESS)
967 dns_rdataset_current(rdataset, &rdata);
969 isc_buffer_init(&b, rdata.data, rdata.length);
970 isc_buffer_add(&b, rdata.length);
971 INSIST(val->key == NULL);
972 result = dst_key_fromdns(&siginfo->signer, rdata.rdclass, &b,
973 val->view->mctx, &val->key);
974 if (result != ISC_R_SUCCESS)
976 if (siginfo->algorithm ==
977 (dns_secalg_t)dst_key_alg(val->key) &&
979 (dns_keytag_t)dst_key_id(val->key) &&
980 dst_key_iszonekey(val->key))
984 * This is the key we're looking for.
986 return (ISC_R_SUCCESS);
987 else if (dst_key_compare(oldkey, val->key) == ISC_TRUE)
990 dst_key_free(&oldkey);
993 dst_key_free(&val->key);
994 dns_rdata_reset(&rdata);
995 result = dns_rdataset_next(rdataset);
996 } while (result == ISC_R_SUCCESS);
997 if (result == ISC_R_NOMORE)
998 result = ISC_R_NOTFOUND;
1002 dst_key_free(&oldkey);
1008 get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) {
1009 isc_result_t result;
1010 unsigned int nlabels;
1012 dns_namereln_t namereln;
1015 * Is the signer name appropriate for this signature?
1017 * The signer name must be at the same level as the owner name
1018 * or closer to the the DNS root.
1020 namereln = dns_name_fullcompare(val->event->name, &siginfo->signer,
1022 if (namereln != dns_namereln_subdomain &&
1023 namereln != dns_namereln_equal)
1024 return (DNS_R_CONTINUE);
1026 if (namereln == dns_namereln_equal) {
1028 * If this is a self-signed keyset, it must not be a zone key
1029 * (since get_key is not called from validatezonekey).
1031 if (val->event->rdataset->type == dns_rdatatype_dnskey)
1032 return (DNS_R_CONTINUE);
1035 * Records appearing in the parent zone at delegation
1036 * points cannot be self-signed.
1038 if (dns_rdatatype_atparent(val->event->rdataset->type))
1039 return (DNS_R_CONTINUE);
1043 * Do we know about this key?
1045 result = view_find(val, &siginfo->signer, dns_rdatatype_dnskey);
1046 if (result == ISC_R_SUCCESS) {
1048 * We have an rrset for the given keyname.
1050 val->keyset = &val->frdataset;
1051 if (val->frdataset.trust == dns_trust_pending &&
1052 dns_rdataset_isassociated(&val->fsigrdataset))
1055 * We know the key but haven't validated it yet.
1057 result = create_validator(val, &siginfo->signer,
1058 dns_rdatatype_dnskey,
1063 if (result != ISC_R_SUCCESS)
1065 return (DNS_R_WAIT);
1066 } else if (val->frdataset.trust == dns_trust_pending) {
1068 * Having a pending key with no signature means that
1069 * something is broken.
1071 result = DNS_R_CONTINUE;
1072 } else if (val->frdataset.trust < dns_trust_secure) {
1074 * The key is legitimately insecure. There's no
1075 * point in even attempting verification.
1078 result = ISC_R_SUCCESS;
1081 * See if we've got the key used in the signature.
1083 validator_log(val, ISC_LOG_DEBUG(3),
1084 "keyset with trust %d",
1085 val->frdataset.trust);
1086 result = get_dst_key(val, siginfo, val->keyset);
1087 if (result != ISC_R_SUCCESS) {
1089 * Either the key we're looking for is not
1090 * in the rrset, or something bad happened.
1093 result = DNS_R_CONTINUE;
1096 } else if (result == ISC_R_NOTFOUND) {
1098 * We don't know anything about this key.
1100 result = create_fetch(val, &siginfo->signer, dns_rdatatype_dnskey,
1101 fetch_callback_validator, "get_key");
1102 if (result != ISC_R_SUCCESS)
1104 return (DNS_R_WAIT);
1105 } else if (result == DNS_R_NCACHENXDOMAIN ||
1106 result == DNS_R_NCACHENXRRSET ||
1107 result == DNS_R_NXDOMAIN ||
1108 result == DNS_R_NXRRSET)
1111 * This key doesn't exist.
1113 result = DNS_R_CONTINUE;
1116 if (dns_rdataset_isassociated(&val->frdataset) &&
1117 val->keyset != &val->frdataset)
1118 dns_rdataset_disassociate(&val->frdataset);
1119 if (dns_rdataset_isassociated(&val->fsigrdataset))
1120 dns_rdataset_disassociate(&val->fsigrdataset);
1126 compute_keytag(dns_rdata_t *rdata, dns_rdata_dnskey_t *key) {
1129 dns_rdata_toregion(rdata, &r);
1130 return (dst_region_computeid(&r, key->algorithm));
1134 * Is this keyset self-signed?
1136 static isc_boolean_t
1137 isselfsigned(dns_validator_t *val) {
1138 dns_rdataset_t *rdataset, *sigrdataset;
1139 dns_rdata_t rdata = DNS_RDATA_INIT;
1140 dns_rdata_t sigrdata = DNS_RDATA_INIT;
1141 dns_rdata_dnskey_t key;
1142 dns_rdata_rrsig_t sig;
1143 dns_keytag_t keytag;
1144 isc_result_t result;
1146 rdataset = val->event->rdataset;
1147 sigrdataset = val->event->sigrdataset;
1149 INSIST(rdataset->type == dns_rdatatype_dnskey);
1151 for (result = dns_rdataset_first(rdataset);
1152 result == ISC_R_SUCCESS;
1153 result = dns_rdataset_next(rdataset))
1155 dns_rdata_reset(&rdata);
1156 dns_rdataset_current(rdataset, &rdata);
1157 (void)dns_rdata_tostruct(&rdata, &key, NULL);
1158 keytag = compute_keytag(&rdata, &key);
1159 for (result = dns_rdataset_first(sigrdataset);
1160 result == ISC_R_SUCCESS;
1161 result = dns_rdataset_next(sigrdataset))
1163 dns_rdata_reset(&sigrdata);
1164 dns_rdataset_current(sigrdataset, &sigrdata);
1165 (void)dns_rdata_tostruct(&sigrdata, &sig, NULL);
1167 if (sig.algorithm == key.algorithm &&
1168 sig.keyid == keytag)
1176 verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata) {
1177 isc_result_t result;
1178 dns_fixedname_t fixed;
1180 val->attributes |= VALATTR_TRIEDVERIFY;
1181 dns_fixedname_init(&fixed);
1182 result = dns_dnssec_verify2(val->event->name, val->event->rdataset,
1183 key, ISC_FALSE, val->view->mctx, rdata,
1184 dns_fixedname_name(&fixed));
1185 validator_log(val, ISC_LOG_DEBUG(3),
1186 "verify rdataset: %s",
1187 isc_result_totext(result));
1188 if (result == DNS_R_FROMWILDCARD) {
1189 if (!dns_name_equal(val->event->name,
1190 dns_fixedname_name(&fixed)))
1191 val->attributes |= VALATTR_NEEDNOQNAME;
1192 result = ISC_R_SUCCESS;
1198 * Attempts positive response validation of a normal RRset.
1201 * ISC_R_SUCCESS Validation completed successfully
1202 * DNS_R_WAIT Validation has started but is waiting
1204 * Other return codes are possible and all indicate failure.
1207 validate(dns_validator_t *val, isc_boolean_t resume) {
1208 isc_result_t result;
1209 dns_validatorevent_t *event;
1210 dns_rdata_t rdata = DNS_RDATA_INIT;
1213 * Caller must be holding the validator lock.
1220 * We already have a sigrdataset.
1222 result = ISC_R_SUCCESS;
1223 validator_log(val, ISC_LOG_DEBUG(3), "resuming validate");
1225 result = dns_rdataset_first(event->sigrdataset);
1229 result == ISC_R_SUCCESS;
1230 result = dns_rdataset_next(event->sigrdataset))
1232 dns_rdata_reset(&rdata);
1233 dns_rdataset_current(event->sigrdataset, &rdata);
1234 if (val->siginfo == NULL) {
1235 val->siginfo = isc_mem_get(val->view->mctx,
1236 sizeof(*val->siginfo));
1237 if (val->siginfo == NULL)
1238 return (ISC_R_NOMEMORY);
1240 result = dns_rdata_tostruct(&rdata, val->siginfo, NULL);
1241 if (result != ISC_R_SUCCESS)
1245 * At this point we could check that the signature algorithm
1246 * was known and "sufficiently good".
1248 if (!dns_resolver_algorithm_supported(val->view->resolver,
1250 val->siginfo->algorithm))
1254 result = get_key(val, val->siginfo);
1255 if (result == DNS_R_CONTINUE)
1256 continue; /* Try the next SIG RR. */
1257 if (result != ISC_R_SUCCESS)
1262 * The key is insecure, so mark the data as insecure also.
1264 if (val->key == NULL) {
1265 if (val->mustbesecure) {
1266 validator_log(val, ISC_LOG_WARNING,
1267 "must be secure failure");
1268 return (DNS_R_MUSTBESECURE);
1271 return (ISC_R_SUCCESS);
1275 result = verify(val, val->key, &rdata);
1276 if (result == ISC_R_SUCCESS)
1278 if (val->keynode != NULL) {
1279 dns_keynode_t *nextnode = NULL;
1280 result = dns_keytable_findnextkeynode(
1284 dns_keytable_detachkeynode(val->keytable,
1286 val->keynode = nextnode;
1287 if (result != ISC_R_SUCCESS) {
1291 val->key = dns_keynode_key(val->keynode);
1293 if (get_dst_key(val, val->siginfo, val->keyset)
1298 if (result != ISC_R_SUCCESS)
1299 validator_log(val, ISC_LOG_DEBUG(3),
1300 "failed to verify rdataset");
1305 isc_stdtime_get(&now);
1306 ttl = ISC_MIN(event->rdataset->ttl,
1307 val->siginfo->timeexpire - now);
1308 if (val->keyset != NULL)
1309 ttl = ISC_MIN(ttl, val->keyset->ttl);
1310 event->rdataset->ttl = ttl;
1311 event->sigrdataset->ttl = ttl;
1314 if (val->keynode != NULL)
1315 dns_keytable_detachkeynode(val->keytable,
1318 if (val->key != NULL)
1319 dst_key_free(&val->key);
1320 if (val->keyset != NULL) {
1321 dns_rdataset_disassociate(val->keyset);
1326 if ((val->attributes & VALATTR_NEEDNOQNAME) != 0) {
1327 if (val->event->message == NULL) {
1328 validator_log(val, ISC_LOG_DEBUG(3),
1329 "no message available for noqname proof");
1330 return (DNS_R_NOVALIDSIG);
1332 validator_log(val, ISC_LOG_DEBUG(3),
1333 "looking for noqname proof");
1334 return (nsecvalidate(val, ISC_FALSE));
1335 } else if (result == ISC_R_SUCCESS) {
1336 event->rdataset->trust = dns_trust_secure;
1337 event->sigrdataset->trust = dns_trust_secure;
1338 validator_log(val, ISC_LOG_DEBUG(3),
1339 "marking as secure");
1342 validator_log(val, ISC_LOG_DEBUG(3),
1343 "verify failure: %s",
1344 isc_result_totext(result));
1348 if (result != ISC_R_NOMORE) {
1349 validator_log(val, ISC_LOG_DEBUG(3),
1350 "failed to iterate signatures: %s",
1351 isc_result_totext(result));
1355 validator_log(val, ISC_LOG_INFO, "no valid signature found");
1356 return (DNS_R_NOVALIDSIG);
1360 dlv_validatezonekey(dns_validator_t *val) {
1361 dns_keytag_t keytag;
1362 dns_rdata_dlv_t dlv;
1363 dns_rdata_dnskey_t key;
1364 dns_rdata_rrsig_t sig;
1365 dns_rdata_t dlvrdata = DNS_RDATA_INIT;
1366 dns_rdata_t keyrdata = DNS_RDATA_INIT;
1367 dns_rdata_t newdsrdata = DNS_RDATA_INIT;
1368 dns_rdata_t sigrdata = DNS_RDATA_INIT;
1369 dns_rdataset_t trdataset;
1371 isc_boolean_t supported_algorithm;
1372 isc_result_t result;
1373 unsigned char dsbuf[DNS_DS_BUFFERSIZE];
1375 validator_log(val, ISC_LOG_DEBUG(3), "dlv_validatezonekey");
1377 * Look through the DLV record and find the keys that can sign the
1378 * key set and the matching signature. For each such key, attempt
1382 supported_algorithm = ISC_FALSE;
1384 for (result = dns_rdataset_first(&val->dlv);
1385 result == ISC_R_SUCCESS;
1386 result = dns_rdataset_next(&val->dlv))
1388 dns_rdata_reset(&dlvrdata);
1389 dns_rdataset_current(&val->dlv, &dlvrdata);
1390 (void)dns_rdata_tostruct(&dlvrdata, &dlv, NULL);
1392 if (dlv.digest_type != DNS_DSDIGEST_SHA1 ||
1393 !dns_resolver_algorithm_supported(val->view->resolver,
1398 supported_algorithm = ISC_TRUE;
1400 dns_rdataset_init(&trdataset);
1401 dns_rdataset_clone(val->event->rdataset, &trdataset);
1403 for (result = dns_rdataset_first(&trdataset);
1404 result == ISC_R_SUCCESS;
1405 result = dns_rdataset_next(&trdataset))
1407 dns_rdata_reset(&keyrdata);
1408 dns_rdataset_current(&trdataset, &keyrdata);
1409 (void)dns_rdata_tostruct(&keyrdata, &key, NULL);
1410 keytag = compute_keytag(&keyrdata, &key);
1411 if (dlv.key_tag != keytag ||
1412 dlv.algorithm != key.algorithm)
1414 dns_rdata_reset(&newdsrdata);
1415 result = dns_ds_buildrdata(val->event->name,
1416 &keyrdata, dlv.digest_type,
1417 dsbuf, &newdsrdata);
1418 if (result != ISC_R_SUCCESS) {
1419 validator_log(val, ISC_LOG_DEBUG(3),
1420 "dns_ds_buildrdata() -> %s",
1421 dns_result_totext(result));
1425 newdsrdata.type = dns_rdatatype_dlv;
1426 if (dns_rdata_compare(&dlvrdata, &newdsrdata) == 0)
1429 if (result != ISC_R_SUCCESS) {
1430 validator_log(val, ISC_LOG_DEBUG(3),
1431 "no DNSKEY matching DLV");
1434 validator_log(val, ISC_LOG_DEBUG(3),
1435 "Found matching DLV record: checking for signature");
1437 for (result = dns_rdataset_first(val->event->sigrdataset);
1438 result == ISC_R_SUCCESS;
1439 result = dns_rdataset_next(val->event->sigrdataset))
1441 dns_rdata_reset(&sigrdata);
1442 dns_rdataset_current(val->event->sigrdataset,
1444 (void)dns_rdata_tostruct(&sigrdata, &sig, NULL);
1445 if (dlv.key_tag != sig.keyid &&
1446 dlv.algorithm != sig.algorithm)
1449 result = dns_dnssec_keyfromrdata(val->event->name,
1453 if (result != ISC_R_SUCCESS)
1455 * This really shouldn't happen, but...
1459 result = verify(val, dstkey, &sigrdata);
1460 dst_key_free(&dstkey);
1461 if (result == ISC_R_SUCCESS)
1464 dns_rdataset_disassociate(&trdataset);
1465 if (result == ISC_R_SUCCESS)
1467 validator_log(val, ISC_LOG_DEBUG(3),
1468 "no RRSIG matching DLV key");
1470 if (result == ISC_R_SUCCESS) {
1471 val->event->rdataset->trust = dns_trust_secure;
1472 val->event->sigrdataset->trust = dns_trust_secure;
1473 validator_log(val, ISC_LOG_DEBUG(3), "marking as secure");
1475 } else if (result == ISC_R_NOMORE && !supported_algorithm) {
1476 if (val->mustbesecure) {
1477 validator_log(val, ISC_LOG_WARNING,
1478 "must be secure failure");
1479 return (DNS_R_MUSTBESECURE);
1481 validator_log(val, ISC_LOG_DEBUG(3),
1482 "no supported algorithm/digest (dlv)");
1484 return (ISC_R_SUCCESS);
1486 return (DNS_R_NOVALIDSIG);
1490 * Attempts positive response validation of an RRset containing zone keys.
1493 * ISC_R_SUCCESS Validation completed successfully
1494 * DNS_R_WAIT Validation has started but is waiting
1496 * Other return codes are possible and all indicate failure.
1499 validatezonekey(dns_validator_t *val) {
1500 isc_result_t result;
1501 dns_validatorevent_t *event;
1502 dns_rdataset_t trdataset;
1503 dns_rdata_t dsrdata = DNS_RDATA_INIT;
1504 dns_rdata_t newdsrdata = DNS_RDATA_INIT;
1505 dns_rdata_t keyrdata = DNS_RDATA_INIT;
1506 dns_rdata_t sigrdata = DNS_RDATA_INIT;
1507 unsigned char dsbuf[DNS_DS_BUFFERSIZE];
1508 dns_keytag_t keytag;
1510 dns_rdata_dnskey_t key;
1511 dns_rdata_rrsig_t sig;
1513 isc_boolean_t supported_algorithm;
1516 * Caller must be holding the validator lock.
1521 if (val->havedlvsep && val->dlv.trust >= dns_trust_secure &&
1522 dns_name_equal(event->name, dns_fixedname_name(&val->dlvsep)))
1523 return (dlv_validatezonekey(val));
1525 if (val->dsset == NULL) {
1527 * First, see if this key was signed by a trusted key.
1529 for (result = dns_rdataset_first(val->event->sigrdataset);
1530 result == ISC_R_SUCCESS;
1531 result = dns_rdataset_next(val->event->sigrdataset))
1533 dns_keynode_t *keynode = NULL, *nextnode = NULL;
1535 dns_rdata_reset(&sigrdata);
1536 dns_rdataset_current(val->event->sigrdataset,
1538 (void)dns_rdata_tostruct(&sigrdata, &sig, NULL);
1539 result = dns_keytable_findkeynode(val->keytable,
1544 while (result == ISC_R_SUCCESS) {
1545 dstkey = dns_keynode_key(keynode);
1546 result = verify(val, dstkey, &sigrdata);
1547 if (result == ISC_R_SUCCESS) {
1548 dns_keytable_detachkeynode(val->keytable,
1552 result = dns_keytable_findnextkeynode(
1556 dns_keytable_detachkeynode(val->keytable,
1560 if (result == ISC_R_SUCCESS) {
1561 event->rdataset->trust = dns_trust_secure;
1562 event->sigrdataset->trust = dns_trust_secure;
1563 validator_log(val, ISC_LOG_DEBUG(3),
1564 "signed by trusted key; "
1565 "marking as secure");
1571 * If this is the root name and there was no trusted key,
1572 * give up, since there's no DS at the root.
1574 if (dns_name_equal(event->name, dns_rootname)) {
1575 if ((val->attributes & VALATTR_TRIEDVERIFY) != 0)
1576 return (DNS_R_NOVALIDSIG);
1578 return (DNS_R_NOVALIDDS);
1582 * Otherwise, try to find the DS record.
1584 result = view_find(val, val->event->name, dns_rdatatype_ds);
1585 if (result == ISC_R_SUCCESS) {
1587 * We have DS records.
1589 val->dsset = &val->frdataset;
1590 if (val->frdataset.trust == dns_trust_pending &&
1591 dns_rdataset_isassociated(&val->fsigrdataset))
1593 result = create_validator(val,
1600 if (result != ISC_R_SUCCESS)
1602 return (DNS_R_WAIT);
1603 } else if (val->frdataset.trust == dns_trust_pending) {
1605 * There should never be an unsigned DS.
1607 dns_rdataset_disassociate(&val->frdataset);
1608 validator_log(val, ISC_LOG_DEBUG(2),
1609 "unsigned DS record");
1610 return (DNS_R_NOVALIDSIG);
1612 result = ISC_R_SUCCESS;
1613 } else if (result == ISC_R_NOTFOUND) {
1615 * We don't have the DS. Find it.
1617 result = create_fetch(val, val->event->name,
1618 dns_rdatatype_ds, dsfetched,
1620 if (result != ISC_R_SUCCESS)
1622 return (DNS_R_WAIT);
1623 } else if (result == DNS_R_NCACHENXDOMAIN ||
1624 result == DNS_R_NCACHENXRRSET ||
1625 result == DNS_R_NXDOMAIN ||
1626 result == DNS_R_NXRRSET)
1629 * The DS does not exist.
1631 if (dns_rdataset_isassociated(&val->frdataset))
1632 dns_rdataset_disassociate(&val->frdataset);
1633 if (dns_rdataset_isassociated(&val->fsigrdataset))
1634 dns_rdataset_disassociate(&val->fsigrdataset);
1635 validator_log(val, ISC_LOG_DEBUG(2), "no DS record");
1636 return (DNS_R_NOVALIDSIG);
1643 INSIST(val->dsset != NULL);
1645 if (val->dsset->trust < dns_trust_secure) {
1646 if (val->mustbesecure) {
1647 validator_log(val, ISC_LOG_WARNING,
1648 "must be secure failure");
1649 return (DNS_R_MUSTBESECURE);
1652 return (ISC_R_SUCCESS);
1656 * Look through the DS record and find the keys that can sign the
1657 * key set and the matching signature. For each such key, attempt
1661 supported_algorithm = ISC_FALSE;
1663 for (result = dns_rdataset_first(val->dsset);
1664 result == ISC_R_SUCCESS;
1665 result = dns_rdataset_next(val->dsset))
1667 dns_rdata_reset(&dsrdata);
1668 dns_rdataset_current(val->dsset, &dsrdata);
1669 (void)dns_rdata_tostruct(&dsrdata, &ds, NULL);
1671 if (ds.digest_type != DNS_DSDIGEST_SHA1)
1673 if (!dns_resolver_algorithm_supported(val->view->resolver,
1678 supported_algorithm = ISC_TRUE;
1680 dns_rdataset_init(&trdataset);
1681 dns_rdataset_clone(val->event->rdataset, &trdataset);
1683 for (result = dns_rdataset_first(&trdataset);
1684 result == ISC_R_SUCCESS;
1685 result = dns_rdataset_next(&trdataset))
1687 dns_rdata_reset(&keyrdata);
1688 dns_rdataset_current(&trdataset, &keyrdata);
1689 (void)dns_rdata_tostruct(&keyrdata, &key, NULL);
1690 keytag = compute_keytag(&keyrdata, &key);
1691 if (ds.key_tag != keytag ||
1692 ds.algorithm != key.algorithm)
1694 dns_rdata_reset(&newdsrdata);
1695 result = dns_ds_buildrdata(val->event->name,
1696 &keyrdata, ds.digest_type,
1697 dsbuf, &newdsrdata);
1698 if (result != ISC_R_SUCCESS)
1700 if (dns_rdata_compare(&dsrdata, &newdsrdata) == 0)
1703 if (result != ISC_R_SUCCESS) {
1704 validator_log(val, ISC_LOG_DEBUG(3),
1705 "no DNSKEY matching DS");
1709 for (result = dns_rdataset_first(val->event->sigrdataset);
1710 result == ISC_R_SUCCESS;
1711 result = dns_rdataset_next(val->event->sigrdataset))
1713 dns_rdata_reset(&sigrdata);
1714 dns_rdataset_current(val->event->sigrdataset,
1716 (void)dns_rdata_tostruct(&sigrdata, &sig, NULL);
1717 if (ds.key_tag != sig.keyid &&
1718 ds.algorithm != sig.algorithm)
1722 result = dns_dnssec_keyfromrdata(val->event->name,
1726 if (result != ISC_R_SUCCESS)
1728 * This really shouldn't happen, but...
1732 result = verify(val, dstkey, &sigrdata);
1733 dst_key_free(&dstkey);
1734 if (result == ISC_R_SUCCESS)
1737 dns_rdataset_disassociate(&trdataset);
1738 if (result == ISC_R_SUCCESS)
1740 validator_log(val, ISC_LOG_DEBUG(3),
1741 "no RRSIG matching DS key");
1743 if (result == ISC_R_SUCCESS) {
1744 event->rdataset->trust = dns_trust_secure;
1745 event->sigrdataset->trust = dns_trust_secure;
1746 validator_log(val, ISC_LOG_DEBUG(3), "marking as secure");
1748 } else if (result == ISC_R_NOMORE && !supported_algorithm) {
1749 if (val->mustbesecure) {
1750 validator_log(val, ISC_LOG_WARNING,
1751 "must be secure failure");
1752 return (DNS_R_MUSTBESECURE);
1754 validator_log(val, ISC_LOG_DEBUG(3),
1755 "no supported algorithm/digest (DS)");
1757 return (ISC_R_SUCCESS);
1759 return (DNS_R_NOVALIDSIG);
1763 * Starts a positive response validation.
1766 * ISC_R_SUCCESS Validation completed successfully
1767 * DNS_R_WAIT Validation has started but is waiting
1769 * Other return codes are possible and all indicate failure.
1772 start_positive_validation(dns_validator_t *val) {
1774 * If this is not a key, go straight into validate().
1776 if (val->event->type != dns_rdatatype_dnskey || !isselfsigned(val))
1777 return (validate(val, ISC_FALSE));
1779 return (validatezonekey(val));
1783 checkwildcard(dns_validator_t *val) {
1784 dns_name_t *name, *wild;
1785 dns_message_t *message = val->event->message;
1786 isc_result_t result;
1787 isc_boolean_t exists, data;
1788 char namebuf[DNS_NAME_FORMATSIZE];
1790 wild = dns_fixedname_name(&val->wild);
1791 dns_name_format(wild, namebuf, sizeof(namebuf));
1792 validator_log(val, ISC_LOG_DEBUG(3), "in checkwildcard: %s", namebuf);
1794 for (result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
1795 result == ISC_R_SUCCESS;
1796 result = dns_message_nextname(message, DNS_SECTION_AUTHORITY))
1798 dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
1801 dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
1803 for (rdataset = ISC_LIST_HEAD(name->list);
1805 rdataset = ISC_LIST_NEXT(rdataset, link))
1807 if (rdataset->type != dns_rdatatype_nsec)
1809 val->nsecset = rdataset;
1811 for (sigrdataset = ISC_LIST_HEAD(name->list);
1812 sigrdataset != NULL;
1813 sigrdataset = ISC_LIST_NEXT(sigrdataset, link))
1815 if (sigrdataset->type == dns_rdatatype_rrsig &&
1816 sigrdataset->covers == rdataset->type)
1819 if (sigrdataset == NULL)
1822 if (rdataset->trust != dns_trust_secure)
1825 if (((val->attributes & VALATTR_NEEDNODATA) != 0 ||
1826 (val->attributes & VALATTR_NEEDNOWILDCARD) != 0) &&
1827 (val->attributes & VALATTR_FOUNDNODATA) == 0 &&
1828 (val->attributes & VALATTR_FOUNDNOWILDCARD) == 0 &&
1829 nsecnoexistnodata(val, wild, name, rdataset,
1830 &exists, &data, NULL)
1833 dns_name_t **proofs = val->event->proofs;
1834 if (exists && !data)
1835 val->attributes |= VALATTR_FOUNDNODATA;
1836 if (exists && !data && NEEDNODATA(val))
1837 proofs[DNS_VALIDATOR_NODATAPROOF] =
1841 VALATTR_FOUNDNOWILDCARD;
1842 if (!exists && NEEDNOQNAME(val))
1843 proofs[DNS_VALIDATOR_NOWILDCARDPROOF] =
1845 return (ISC_R_SUCCESS);
1849 if (result == ISC_R_NOMORE)
1850 result = ISC_R_SUCCESS;
1855 nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
1857 dns_message_t *message = val->event->message;
1858 isc_result_t result;
1861 result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
1863 result = ISC_R_SUCCESS;
1864 validator_log(val, ISC_LOG_DEBUG(3), "resuming nsecvalidate");
1868 result == ISC_R_SUCCESS;
1869 result = dns_message_nextname(message, DNS_SECTION_AUTHORITY))
1871 dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
1874 dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
1876 rdataset = ISC_LIST_NEXT(val->currentset, link);
1877 val->currentset = NULL;
1880 rdataset = ISC_LIST_HEAD(name->list);
1884 rdataset = ISC_LIST_NEXT(rdataset, link))
1886 if (rdataset->type == dns_rdatatype_rrsig)
1889 if (rdataset->type == dns_rdatatype_soa) {
1890 val->soaset = rdataset;
1891 val->soaname = name;
1892 } else if (rdataset->type == dns_rdatatype_nsec)
1893 val->nsecset = rdataset;
1895 for (sigrdataset = ISC_LIST_HEAD(name->list);
1896 sigrdataset != NULL;
1897 sigrdataset = ISC_LIST_NEXT(sigrdataset,
1900 if (sigrdataset->type == dns_rdatatype_rrsig &&
1901 sigrdataset->covers == rdataset->type)
1904 if (sigrdataset == NULL)
1907 * If a signed zone is missing the zone key, bad
1908 * things could happen. A query for data in the zone
1909 * would lead to a query for the zone key, which
1910 * would return a negative answer, which would contain
1911 * an SOA and an NSEC signed by the missing key, which
1912 * would trigger another query for the DNSKEY (since
1913 * the first one is still in progress), and go into an
1914 * infinite loop. Avoid that.
1916 if (val->event->type == dns_rdatatype_dnskey &&
1917 dns_name_equal(name, val->event->name))
1919 dns_rdata_t nsec = DNS_RDATA_INIT;
1921 if (rdataset->type != dns_rdatatype_nsec)
1924 result = dns_rdataset_first(rdataset);
1925 if (result != ISC_R_SUCCESS)
1927 dns_rdataset_current(rdataset, &nsec);
1928 if (dns_nsec_typepresent(&nsec,
1932 val->currentset = rdataset;
1933 result = create_validator(val, name, rdataset->type,
1934 rdataset, sigrdataset,
1937 if (result != ISC_R_SUCCESS)
1939 return (DNS_R_WAIT);
1943 if (result == ISC_R_NOMORE)
1944 result = ISC_R_SUCCESS;
1945 if (result != ISC_R_SUCCESS)
1949 * Do we only need to check for NOQNAME?
1951 if ((val->attributes & VALATTR_NEEDNODATA) == 0 &&
1952 (val->attributes & VALATTR_NEEDNOWILDCARD) == 0 &&
1953 (val->attributes & VALATTR_NEEDNOQNAME) != 0) {
1954 if ((val->attributes & VALATTR_FOUNDNOQNAME) != 0) {
1955 validator_log(val, ISC_LOG_DEBUG(3),
1956 "noqname proof found");
1957 validator_log(val, ISC_LOG_DEBUG(3),
1958 "marking as secure");
1959 val->event->rdataset->trust = dns_trust_secure;
1960 val->event->sigrdataset->trust = dns_trust_secure;
1961 return (ISC_R_SUCCESS);
1963 validator_log(val, ISC_LOG_DEBUG(3),
1964 "noqname proof not found");
1965 return (DNS_R_NOVALIDNSEC);
1969 * Do we need to check for the wildcard?
1971 if ((val->attributes & VALATTR_FOUNDNOQNAME) != 0 &&
1972 (((val->attributes & VALATTR_NEEDNODATA) != 0 &&
1973 (val->attributes & VALATTR_FOUNDNODATA) == 0) ||
1974 (val->attributes & VALATTR_NEEDNOWILDCARD) != 0)) {
1975 result = checkwildcard(val);
1976 if (result != ISC_R_SUCCESS)
1980 if (((val->attributes & VALATTR_NEEDNODATA) != 0 &&
1981 (val->attributes & VALATTR_FOUNDNODATA) != 0) ||
1982 ((val->attributes & VALATTR_NEEDNOQNAME) != 0 &&
1983 (val->attributes & VALATTR_FOUNDNOQNAME) != 0 &&
1984 (val->attributes & VALATTR_NEEDNOWILDCARD) != 0 &&
1985 (val->attributes & VALATTR_FOUNDNOWILDCARD) != 0))
1986 val->attributes |= VALATTR_FOUNDNONEXISTENCE;
1988 if ((val->attributes & VALATTR_FOUNDNONEXISTENCE) == 0) {
1989 if (!val->seensig && val->soaset != NULL) {
1990 result = create_validator(val, val->soaname,
1995 if (result != ISC_R_SUCCESS)
1997 return (DNS_R_WAIT);
1999 validator_log(val, ISC_LOG_DEBUG(3),
2000 "nonexistence proof not found");
2001 return (DNS_R_NOVALIDNSEC);
2003 validator_log(val, ISC_LOG_DEBUG(3),
2004 "nonexistence proof found");
2005 return (ISC_R_SUCCESS);
2009 static isc_boolean_t
2010 check_ds(dns_validator_t *val, dns_name_t *name, dns_rdataset_t *rdataset) {
2011 dns_rdata_t dsrdata = DNS_RDATA_INIT;
2013 isc_result_t result;
2015 for (result = dns_rdataset_first(rdataset);
2016 result == ISC_R_SUCCESS;
2017 result = dns_rdataset_next(rdataset)) {
2018 dns_rdataset_current(rdataset, &dsrdata);
2019 (void)dns_rdata_tostruct(&dsrdata, &ds, NULL);
2021 if (ds.digest_type == DNS_DSDIGEST_SHA1 &&
2022 dns_resolver_algorithm_supported(val->view->resolver,
2023 name, ds.algorithm)) {
2024 dns_rdata_reset(&dsrdata);
2027 dns_rdata_reset(&dsrdata);
2033 dlvfetched(isc_task_t *task, isc_event_t *event) {
2034 char namebuf[DNS_NAME_FORMATSIZE];
2035 dns_fetchevent_t *devent;
2036 dns_validator_t *val;
2037 isc_boolean_t want_destroy;
2038 isc_result_t eresult;
2039 isc_result_t result;
2042 INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
2043 devent = (dns_fetchevent_t *)event;
2044 val = devent->ev_arg;
2045 eresult = devent->result;
2047 /* Free resources which are not of interest. */
2048 if (devent->node != NULL)
2049 dns_db_detachnode(devent->db, &devent->node);
2050 if (devent->db != NULL)
2051 dns_db_detach(&devent->db);
2052 if (dns_rdataset_isassociated(&val->fsigrdataset))
2053 dns_rdataset_disassociate(&val->fsigrdataset);
2054 isc_event_free(&event);
2055 dns_resolver_destroyfetch(&val->fetch);
2057 INSIST(val->event != NULL);
2058 validator_log(val, ISC_LOG_DEBUG(3), "in dlvfetched: %s",
2059 dns_result_totext(eresult));
2062 if (eresult == ISC_R_SUCCESS) {
2063 dns_name_format(dns_fixedname_name(&val->dlvsep), namebuf,
2065 dns_rdataset_clone(&val->frdataset, &val->dlv);
2066 val->havedlvsep = ISC_TRUE;
2067 validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found", namebuf);
2068 result = dlv_validator_start(val);
2069 if (result != DNS_R_WAIT)
2070 validator_done(val, result);
2071 } else if (eresult == DNS_R_NXRRSET ||
2072 eresult == DNS_R_NXDOMAIN ||
2073 eresult == DNS_R_NCACHENXRRSET ||
2074 eresult == DNS_R_NCACHENXDOMAIN) {
2075 result = finddlvsep(val, ISC_TRUE);
2076 if (result == ISC_R_SUCCESS) {
2077 dns_name_format(dns_fixedname_name(&val->dlvsep),
2078 namebuf, sizeof(namebuf));
2079 validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found",
2081 result = dlv_validator_start(val);
2082 if (result != DNS_R_WAIT)
2083 validator_done(val, result);
2084 } else if (result == ISC_R_NOTFOUND) {
2085 validator_log(val, ISC_LOG_DEBUG(3), "DLV not found");
2087 validator_done(val, ISC_R_SUCCESS);
2089 validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s",
2090 dns_result_totext(result));
2091 if (result != DNS_R_WAIT)
2092 validator_done(val, result);
2095 validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s",
2096 dns_result_totext(eresult));
2098 want_destroy = exit_check(val);
2105 startfinddlvsep(dns_validator_t *val, dns_name_t *unsecure) {
2106 char namebuf[DNS_NAME_FORMATSIZE];
2107 isc_result_t result;
2109 INSIST(!DLVTRIED(val));
2111 val->attributes |= VALATTR_DLVTRIED;
2113 dns_name_format(unsecure, namebuf, sizeof(namebuf));
2114 validator_log(val, ISC_LOG_DEBUG(3),
2115 "plain DNSSEC returns unsecure (%s): looking for DLV",
2118 if (dns_name_issubdomain(val->event->name, val->view->dlv)) {
2119 validator_log(val, ISC_LOG_WARNING, "must be secure failure");
2120 return (DNS_R_MUSTBESECURE);
2123 val->dlvlabels = dns_name_countlabels(unsecure) - 1;
2124 result = finddlvsep(val, ISC_FALSE);
2125 if (result == ISC_R_NOTFOUND) {
2126 validator_log(val, ISC_LOG_DEBUG(3), "DLV not found");
2128 return (ISC_R_SUCCESS);
2130 if (result != ISC_R_SUCCESS) {
2131 validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s",
2132 dns_result_totext(result));
2135 dns_name_format(dns_fixedname_name(&val->dlvsep), namebuf,
2137 validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found", namebuf);
2138 return (dlv_validator_start(val));
2142 finddlvsep(dns_validator_t *val, isc_boolean_t resume) {
2143 char namebuf[DNS_NAME_FORMATSIZE];
2144 dns_fixedname_t dlvfixed;
2145 dns_name_t *dlvname;
2148 isc_result_t result;
2149 unsigned int labels;
2151 INSIST(val->view->dlv != NULL);
2155 if (dns_name_issubdomain(val->event->name, val->view->dlv)) {
2156 validator_log(val, ISC_LOG_WARNING,
2157 "must be secure failure");
2158 return (DNS_R_MUSTBESECURE);
2161 dns_fixedname_init(&val->dlvsep);
2162 dlvsep = dns_fixedname_name(&val->dlvsep);
2163 dns_name_copy(val->event->name, dlvsep, NULL);
2164 if (val->event->type == dns_rdatatype_ds) {
2165 labels = dns_name_countlabels(dlvsep);
2167 return (ISC_R_NOTFOUND);
2168 dns_name_getlabelsequence(dlvsep, 1, labels - 1,
2172 dlvsep = dns_fixedname_name(&val->dlvsep);
2173 labels = dns_name_countlabels(dlvsep);
2174 dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep);
2176 dns_name_init(&noroot, NULL);
2177 dns_fixedname_init(&dlvfixed);
2178 dlvname = dns_fixedname_name(&dlvfixed);
2179 labels = dns_name_countlabels(dlvsep);
2181 return (ISC_R_NOTFOUND);
2182 dns_name_getlabelsequence(dlvsep, 0, labels - 1, &noroot);
2183 result = dns_name_concatenate(&noroot, val->view->dlv, dlvname, NULL);
2184 while (result == ISC_R_NOSPACE) {
2185 labels = dns_name_countlabels(dlvsep);
2186 dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep);
2187 dns_name_getlabelsequence(dlvsep, 0, labels - 2, &noroot);
2188 result = dns_name_concatenate(&noroot, val->view->dlv,
2191 if (result != ISC_R_SUCCESS) {
2192 validator_log(val, ISC_LOG_DEBUG(2), "DLV concatenate failed");
2193 return (DNS_R_NOVALIDSIG);
2196 while (dns_name_countlabels(dlvname) >=
2197 dns_name_countlabels(val->view->dlv) + val->dlvlabels) {
2198 dns_name_format(dlvname, namebuf, sizeof(namebuf));
2199 validator_log(val, ISC_LOG_DEBUG(3), "looking for DLV %s",
2201 result = view_find(val, dlvname, dns_rdatatype_dlv);
2202 if (result == ISC_R_SUCCESS) {
2203 if (val->frdataset.trust < dns_trust_secure)
2204 return (DNS_R_NOVALIDSIG);
2205 val->havedlvsep = ISC_TRUE;
2206 dns_rdataset_clone(&val->frdataset, &val->dlv);
2207 return (ISC_R_SUCCESS);
2209 if (result == ISC_R_NOTFOUND) {
2210 result = create_fetch(val, dlvname, dns_rdatatype_dlv,
2211 dlvfetched, "finddlvsep");
2212 if (result != ISC_R_SUCCESS)
2214 return (DNS_R_WAIT);
2216 if (result != DNS_R_NXRRSET &&
2217 result != DNS_R_NXDOMAIN &&
2218 result != DNS_R_NCACHENXRRSET &&
2219 result != DNS_R_NCACHENXDOMAIN)
2222 * Strip first labels from both dlvsep and dlvname.
2224 labels = dns_name_countlabels(dlvsep);
2227 dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep);
2228 labels = dns_name_countlabels(dlvname);
2229 dns_name_getlabelsequence(dlvname, 1, labels - 1, dlvname);
2231 return (ISC_R_NOTFOUND);
2235 * proveunsecure walks down from the SEP looking for a break in the
2236 * chain of trust. That occurs when we can prove the DS record does
2237 * not exist at a delegation point or the DS exists at a delegation
2238 * but we don't support the algorithm/digest.
2241 proveunsecure(dns_validator_t *val, isc_boolean_t resume) {
2242 isc_result_t result;
2243 dns_fixedname_t fixedsecroot;
2244 dns_name_t *secroot;
2246 char namebuf[DNS_NAME_FORMATSIZE];
2248 dns_fixedname_init(&fixedsecroot);
2249 secroot = dns_fixedname_name(&fixedsecroot);
2250 if (val->havedlvsep)
2251 dns_name_copy(dns_fixedname_name(&val->dlvsep), secroot, NULL);
2253 result = dns_keytable_finddeepestmatch(val->keytable,
2257 if (result == ISC_R_NOTFOUND) {
2258 validator_log(val, ISC_LOG_DEBUG(3),
2259 "not beneath secure root");
2260 if (val->mustbesecure) {
2261 validator_log(val, ISC_LOG_WARNING,
2262 "must be secure failure");
2263 result = DNS_R_MUSTBESECURE;
2266 if (val->view->dlv == NULL || DLVTRIED(val)) {
2268 return (ISC_R_SUCCESS);
2270 return (startfinddlvsep(val, dns_rootname));
2271 } else if (result != ISC_R_SUCCESS)
2277 * We are looking for breaks below the SEP so add a label.
2279 val->labels = dns_name_countlabels(secroot) + 1;
2281 validator_log(val, ISC_LOG_DEBUG(3), "resuming proveunsecure");
2282 if (val->frdataset.trust >= dns_trust_secure &&
2283 !check_ds(val, dns_fixedname_name(&val->fname),
2285 dns_name_format(dns_fixedname_name(&val->fname),
2286 namebuf, sizeof(namebuf));
2287 if (val->mustbesecure) {
2288 validator_log(val, ISC_LOG_WARNING,
2289 "must be secure failure at '%s'",
2291 result = DNS_R_MUSTBESECURE;
2294 validator_log(val, ISC_LOG_DEBUG(3),
2295 "no supported algorithm/digest (%s/DS)",
2297 if (val->view->dlv == NULL || DLVTRIED(val)) {
2299 result = ISC_R_SUCCESS;
2302 result = startfinddlvsep(val,
2303 dns_fixedname_name(&val->fname));
2310 val->labels <= dns_name_countlabels(val->event->name);
2314 dns_fixedname_init(&val->fname);
2315 tname = dns_fixedname_name(&val->fname);
2316 if (val->labels == dns_name_countlabels(val->event->name))
2317 dns_name_copy(val->event->name, tname, NULL);
2319 dns_name_split(val->event->name, val->labels,
2322 dns_name_format(tname, namebuf, sizeof(namebuf));
2323 validator_log(val, ISC_LOG_DEBUG(3),
2324 "checking existence of DS at '%s'",
2327 result = view_find(val, tname, dns_rdatatype_ds);
2328 if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) {
2330 * There is no DS. If this is a delegation,
2333 if (val->frdataset.trust < dns_trust_secure) {
2335 * This shouldn't happen, since the negative
2336 * response should have been validated. Since
2337 * there's no way of validating existing
2338 * negative response blobs, give up.
2340 result = DNS_R_NOVALIDSIG;
2343 if (isdelegation(tname, &val->frdataset, result)) {
2344 if (val->mustbesecure) {
2345 validator_log(val, ISC_LOG_WARNING,
2346 "must be secure failure");
2347 return (DNS_R_MUSTBESECURE);
2349 if (val->view->dlv == NULL || DLVTRIED(val)) {
2351 return (ISC_R_SUCCESS);
2353 return (startfinddlvsep(val, tname));
2356 } else if (result == ISC_R_SUCCESS) {
2358 * There is a DS here. Verify that it's secure and
2361 if (val->frdataset.trust >= dns_trust_secure) {
2362 if (!check_ds(val, tname, &val->frdataset)) {
2363 validator_log(val, ISC_LOG_DEBUG(3),
2364 "no supported algorithm/"
2365 "digest (%s/DS)", namebuf);
2366 if (val->mustbesecure) {
2369 "must be secure failure");
2370 result = DNS_R_MUSTBESECURE;
2373 if (val->view->dlv == NULL ||
2376 result = ISC_R_SUCCESS;
2379 result = startfinddlvsep(val, tname);
2384 else if (!dns_rdataset_isassociated(&val->fsigrdataset))
2386 result = DNS_R_NOVALIDSIG;
2389 result = create_validator(val, tname, dns_rdatatype_ds,
2394 if (result != ISC_R_SUCCESS)
2396 return (DNS_R_WAIT);
2397 } else if (result == DNS_R_NXDOMAIN ||
2398 result == DNS_R_NCACHENXDOMAIN)
2401 * This is not a zone cut. Assuming things are
2402 * as expected, continue.
2404 if (!dns_rdataset_isassociated(&val->frdataset)) {
2406 * There should be an NSEC here, since we
2407 * are still in a secure zone.
2409 result = DNS_R_NOVALIDNSEC;
2411 } else if (val->frdataset.trust < dns_trust_secure) {
2413 * This shouldn't happen, since the negative
2414 * response should have been validated. Since
2415 * there's no way of validating existing
2416 * negative response blobs, give up.
2418 result = DNS_R_NOVALIDSIG;
2422 } else if (result == ISC_R_NOTFOUND) {
2424 * We don't know anything about the DS. Find it.
2426 result = create_fetch(val, tname, dns_rdatatype_ds,
2427 dsfetched2, "proveunsecure");
2428 if (result != ISC_R_SUCCESS)
2430 return (DNS_R_WAIT);
2433 validator_log(val, ISC_LOG_DEBUG(3), "insecurity proof failed");
2434 return (DNS_R_NOTINSECURE); /* Couldn't complete insecurity proof */
2437 if (dns_rdataset_isassociated(&val->frdataset))
2438 dns_rdataset_disassociate(&val->frdataset);
2439 if (dns_rdataset_isassociated(&val->fsigrdataset))
2440 dns_rdataset_disassociate(&val->fsigrdataset);
2445 dlv_validator_start(dns_validator_t *val) {
2448 validator_log(val, ISC_LOG_DEBUG(3), "dlv_validator_start");
2451 * Reset state and try again.
2453 val->attributes &= VALATTR_DLVTRIED;
2454 val->options &= ~DNS_VALIDATOR_DLV;
2456 event = (isc_event_t *)val->event;
2457 isc_task_send(val->task, &event);
2458 return (DNS_R_WAIT);
2462 validator_start(isc_task_t *task, isc_event_t *event) {
2463 dns_validator_t *val;
2464 dns_validatorevent_t *vevent;
2465 isc_boolean_t want_destroy = ISC_FALSE;
2466 isc_result_t result = ISC_R_FAILURE;
2469 REQUIRE(event->ev_type == DNS_EVENT_VALIDATORSTART);
2470 vevent = (dns_validatorevent_t *)event;
2471 val = vevent->validator;
2473 /* If the validator has been cancelled, val->event == NULL */
2474 if (val->event == NULL)
2478 validator_log(val, ISC_LOG_DEBUG(3), "restarting using DLV");
2480 validator_log(val, ISC_LOG_DEBUG(3), "starting");
2484 if ((val->options & DNS_VALIDATOR_DLV) != 0) {
2485 validator_log(val, ISC_LOG_DEBUG(3), "looking for DLV");
2486 result = startfinddlvsep(val, dns_rootname);
2487 } else if (val->event->rdataset != NULL &&
2488 val->event->sigrdataset != NULL) {
2489 isc_result_t saved_result;
2492 * This looks like a simple validation. We say "looks like"
2493 * because it might end up requiring an insecurity proof.
2495 validator_log(val, ISC_LOG_DEBUG(3),
2496 "attempting positive response validation");
2498 INSIST(dns_rdataset_isassociated(val->event->rdataset));
2499 INSIST(dns_rdataset_isassociated(val->event->sigrdataset));
2500 result = start_positive_validation(val);
2501 if (result == DNS_R_NOVALIDSIG &&
2502 (val->attributes & VALATTR_TRIEDVERIFY) == 0)
2504 saved_result = result;
2505 validator_log(val, ISC_LOG_DEBUG(3),
2506 "falling back to insecurity proof");
2507 val->attributes |= VALATTR_INSECURITY;
2508 result = proveunsecure(val, ISC_FALSE);
2509 if (result == DNS_R_NOTINSECURE)
2510 result = saved_result;
2512 } else if (val->event->rdataset != NULL) {
2514 * This is either an unsecure subdomain or a response from
2517 INSIST(dns_rdataset_isassociated(val->event->rdataset));
2518 validator_log(val, ISC_LOG_DEBUG(3),
2519 "attempting insecurity proof");
2521 val->attributes |= VALATTR_INSECURITY;
2522 result = proveunsecure(val, ISC_FALSE);
2523 } else if (val->event->rdataset == NULL &&
2524 val->event->sigrdataset == NULL)
2527 * This is a nonexistence validation.
2529 validator_log(val, ISC_LOG_DEBUG(3),
2530 "attempting negative response validation");
2532 val->attributes |= VALATTR_NEGATIVE;
2533 if (val->event->message->rcode == dns_rcode_nxdomain) {
2534 val->attributes |= VALATTR_NEEDNOQNAME;
2535 val->attributes |= VALATTR_NEEDNOWILDCARD;
2537 val->attributes |= VALATTR_NEEDNODATA;
2538 result = nsecvalidate(val, ISC_FALSE);
2541 * This shouldn't happen.
2546 if (result != DNS_R_WAIT) {
2547 want_destroy = exit_check(val);
2548 validator_done(val, result);
2557 dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
2558 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
2559 dns_message_t *message, unsigned int options,
2560 isc_task_t *task, isc_taskaction_t action, void *arg,
2561 dns_validator_t **validatorp)
2563 isc_result_t result;
2564 dns_validator_t *val;
2566 dns_validatorevent_t *event;
2568 REQUIRE(name != NULL);
2570 REQUIRE(rdataset != NULL ||
2571 (rdataset == NULL && sigrdataset == NULL && message != NULL));
2572 REQUIRE(validatorp != NULL && *validatorp == NULL);
2575 result = ISC_R_FAILURE;
2577 val = isc_mem_get(view->mctx, sizeof(*val));
2579 return (ISC_R_NOMEMORY);
2581 dns_view_weakattach(view, &val->view);
2582 event = (dns_validatorevent_t *)
2583 isc_event_allocate(view->mctx, task,
2584 DNS_EVENT_VALIDATORSTART,
2585 validator_start, NULL,
2586 sizeof(dns_validatorevent_t));
2587 if (event == NULL) {
2588 result = ISC_R_NOMEMORY;
2591 isc_task_attach(task, &tclone);
2592 event->validator = val;
2593 event->result = ISC_R_FAILURE;
2596 event->rdataset = rdataset;
2597 event->sigrdataset = sigrdataset;
2598 event->message = message;
2599 memset(event->proofs, 0, sizeof(event->proofs));
2600 result = isc_mutex_init(&val->lock);
2601 if (result != ISC_R_SUCCESS)
2604 val->options = options;
2605 val->attributes = 0;
2607 val->subvalidator = NULL;
2609 val->keytable = NULL;
2610 dns_keytable_attach(val->view->secroots, &val->keytable);
2611 val->keynode = NULL;
2613 val->siginfo = NULL;
2615 val->action = action;
2618 val->currentset = NULL;
2621 dns_rdataset_init(&val->dlv);
2623 val->nsecset = NULL;
2624 val->soaname = NULL;
2625 val->seensig = ISC_FALSE;
2626 val->havedlvsep = ISC_FALSE;
2628 val->mustbesecure = dns_resolver_getmustbesecure(view->resolver, name);
2629 dns_rdataset_init(&val->frdataset);
2630 dns_rdataset_init(&val->fsigrdataset);
2631 dns_fixedname_init(&val->wild);
2632 ISC_LINK_INIT(val, link);
2633 val->magic = VALIDATOR_MAGIC;
2635 isc_task_send(task, ISC_EVENT_PTR(&event));
2639 return (ISC_R_SUCCESS);
2642 isc_task_detach(&tclone);
2643 isc_event_free((isc_event_t **)&val->event);
2646 dns_view_weakdetach(&val->view);
2647 isc_mem_put(view->mctx, val, sizeof(*val));
2653 dns_validator_cancel(dns_validator_t *validator) {
2654 REQUIRE(VALID_VALIDATOR(validator));
2656 LOCK(&validator->lock);
2658 validator_log(validator, ISC_LOG_DEBUG(3), "dns_validator_cancel");
2660 if (validator->event != NULL) {
2661 if (validator->fetch != NULL)
2662 dns_resolver_cancelfetch(validator->fetch);
2664 if (validator->subvalidator != NULL)
2665 dns_validator_cancel(validator->subvalidator);
2667 UNLOCK(&validator->lock);
2671 destroy(dns_validator_t *val) {
2674 REQUIRE(SHUTDOWN(val));
2675 REQUIRE(val->event == NULL);
2676 REQUIRE(val->fetch == NULL);
2678 if (val->keynode != NULL)
2679 dns_keytable_detachkeynode(val->keytable, &val->keynode);
2680 else if (val->key != NULL)
2681 dst_key_free(&val->key);
2682 if (val->keytable != NULL)
2683 dns_keytable_detach(&val->keytable);
2684 if (val->subvalidator != NULL)
2685 dns_validator_destroy(&val->subvalidator);
2686 if (val->havedlvsep)
2687 dns_rdataset_disassociate(&val->dlv);
2688 if (dns_rdataset_isassociated(&val->frdataset))
2689 dns_rdataset_disassociate(&val->frdataset);
2690 if (dns_rdataset_isassociated(&val->fsigrdataset))
2691 dns_rdataset_disassociate(&val->fsigrdataset);
2692 mctx = val->view->mctx;
2693 if (val->siginfo != NULL)
2694 isc_mem_put(mctx, val->siginfo, sizeof(*val->siginfo));
2695 DESTROYLOCK(&val->lock);
2696 dns_view_weakdetach(&val->view);
2698 isc_mem_put(mctx, val, sizeof(*val));
2702 dns_validator_destroy(dns_validator_t **validatorp) {
2703 dns_validator_t *val;
2704 isc_boolean_t want_destroy = ISC_FALSE;
2706 REQUIRE(validatorp != NULL);
2708 REQUIRE(VALID_VALIDATOR(val));
2712 val->attributes |= VALATTR_SHUTDOWN;
2713 validator_log(val, ISC_LOG_DEBUG(3), "dns_validator_destroy");
2715 want_destroy = exit_check(val);
2726 validator_logv(dns_validator_t *val, isc_logcategory_t *category,
2727 isc_logmodule_t *module, int level, const char *fmt, va_list ap)
2730 static const char spaces[] = " *";
2731 int depth = val->depth * 2;
2733 vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
2735 if ((unsigned int) depth >= sizeof spaces)
2736 depth = sizeof spaces - 1;
2738 if (val->event != NULL && val->event->name != NULL) {
2739 char namebuf[DNS_NAME_FORMATSIZE];
2740 char typebuf[DNS_RDATATYPE_FORMATSIZE];
2742 dns_name_format(val->event->name, namebuf, sizeof(namebuf));
2743 dns_rdatatype_format(val->event->type, typebuf,
2745 isc_log_write(dns_lctx, category, module, level,
2746 "%.*svalidating @%p: %s %s: %s", depth, spaces,
2747 val, namebuf, typebuf, msgbuf);
2749 isc_log_write(dns_lctx, category, module, level,
2750 "%.*svalidator @%p: %s", depth, spaces,
2756 validator_log(dns_validator_t *val, int level, const char *fmt, ...) {
2759 if (! isc_log_wouldlog(dns_lctx, level))
2764 validator_logv(val, DNS_LOGCATEGORY_DNSSEC,
2765 DNS_LOGMODULE_VALIDATOR, level, fmt, ap);
2770 validator_logcreate(dns_validator_t *val,
2771 dns_name_t *name, dns_rdatatype_t type,
2772 const char *caller, const char *operation)
2774 char namestr[DNS_NAME_FORMATSIZE];
2775 char typestr[DNS_RDATATYPE_FORMATSIZE];
2777 dns_name_format(name, namestr, sizeof(namestr));
2778 dns_rdatatype_format(type, typestr, sizeof(typestr));
2779 validator_log(val, ISC_LOG_DEBUG(9), "%s: creating %s for %s %s",
2780 caller, operation, namestr, typestr);