2 * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000-2003 Internet Software Consortium.
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.
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.155.52.14 2009/03/17 23:46:41 tbox Exp $ */
23 #include <isc/print.h>
24 #include <isc/string.h>
31 #include <dns/dnssec.h>
32 #include <dns/events.h>
33 #include <dns/keytable.h>
35 #include <dns/message.h>
36 #include <dns/ncache.h>
38 #include <dns/rdata.h>
39 #include <dns/rdatastruct.h>
40 #include <dns/rdataset.h>
41 #include <dns/rdatatype.h>
42 #include <dns/resolver.h>
43 #include <dns/result.h>
44 #include <dns/validator.h>
49 * Basic processing sequences.
51 * \li When called with rdataset and sigrdataset:
52 * validator_start -> validate -> proveunsecure -> startfinddlvsep ->
53 * dlv_validator_start -> validator_start -> validate -> proveunsecure
55 * validator_start -> validate -> nsecvalidate (secure wildcard answer)
57 * \li When called with rdataset, sigrdataset and with DNS_VALIDATOR_DLV:
58 * validator_start -> startfinddlvsep -> dlv_validator_start ->
59 * validator_start -> validate -> proveunsecure
61 * \li When called with rdataset:
62 * validator_start -> proveunsecure -> startfinddlvsep ->
63 * dlv_validator_start -> validator_start -> proveunsecure
65 * \li When called with rdataset and with DNS_VALIDATOR_DLV:
66 * validator_start -> startfinddlvsep -> dlv_validator_start ->
67 * validator_start -> proveunsecure
69 * \li When called without a rdataset:
70 * validator_start -> nsecvalidate -> proveunsecure -> startfinddlvsep ->
71 * dlv_validator_start -> validator_start -> nsecvalidate -> proveunsecure
73 * Note: there isn't a case for DNS_VALIDATOR_DLV here as we want nsecvalidate()
74 * to always validate the authority section even when it does not contain
77 * validator_start: determines what type of validation to do.
78 * validate: attempts to perform a positive validation.
79 * proveunsecure: attempts to prove the answer comes from a unsecure zone.
80 * nsecvalidate: attempts to prove a negative response.
81 * startfinddlvsep: starts the DLV record lookup.
82 * dlv_validator_start: resets state and restarts the lookup using the
83 * DLV RRset found by startfinddlvsep.
86 #define VALIDATOR_MAGIC ISC_MAGIC('V', 'a', 'l', '?')
87 #define VALID_VALIDATOR(v) ISC_MAGIC_VALID(v, VALIDATOR_MAGIC)
89 #define VALATTR_SHUTDOWN 0x0001 /*%< Shutting down. */
90 #define VALATTR_CANCELED 0x0002 /*%< Canceled. */
91 #define VALATTR_TRIEDVERIFY 0x0004 /*%< We have found a key and
92 * have attempted a verify. */
93 #define VALATTR_INSECURITY 0x0010 /*%< Attempting proveunsecure. */
94 #define VALATTR_DLVTRIED 0x0020 /*%< Looked for a DLV record. */
97 * NSEC proofs to be looked for.
99 #define VALATTR_NEEDNOQNAME 0x0100
100 #define VALATTR_NEEDNOWILDCARD 0x0200
101 #define VALATTR_NEEDNODATA 0x0400
104 * NSEC proofs that have been found.
106 #define VALATTR_FOUNDNOQNAME 0x1000
107 #define VALATTR_FOUNDNOWILDCARD 0x2000
108 #define VALATTR_FOUNDNODATA 0x4000
110 #define NEEDNODATA(val) ((val->attributes & VALATTR_NEEDNODATA) != 0)
111 #define NEEDNOQNAME(val) ((val->attributes & VALATTR_NEEDNOQNAME) != 0)
112 #define NEEDNOWILDCARD(val) ((val->attributes & VALATTR_NEEDNOWILDCARD) != 0)
113 #define DLVTRIED(val) ((val->attributes & VALATTR_DLVTRIED) != 0)
115 #define SHUTDOWN(v) (((v)->attributes & VALATTR_SHUTDOWN) != 0)
116 #define CANCELED(v) (((v)->attributes & VALATTR_CANCELED) != 0)
119 destroy(dns_validator_t
*val
);
122 get_dst_key(dns_validator_t
*val
, dns_rdata_rrsig_t
*siginfo
,
123 dns_rdataset_t
*rdataset
);
126 validate(dns_validator_t
*val
, isc_boolean_t resume
);
129 validatezonekey(dns_validator_t
*val
);
132 nsecvalidate(dns_validator_t
*val
, isc_boolean_t resume
);
135 proveunsecure(dns_validator_t
*val
, isc_boolean_t have_ds
,
136 isc_boolean_t resume
);
139 validator_logv(dns_validator_t
*val
, isc_logcategory_t
*category
,
140 isc_logmodule_t
*module
, int level
, const char *fmt
, va_list ap
)
141 ISC_FORMAT_PRINTF(5, 0);
144 validator_log(dns_validator_t
*val
, int level
, const char *fmt
, ...)
145 ISC_FORMAT_PRINTF(3, 4);
148 validator_logcreate(dns_validator_t
*val
,
149 dns_name_t
*name
, dns_rdatatype_t type
,
150 const char *caller
, const char *operation
);
153 dlv_validatezonekey(dns_validator_t
*val
);
156 dlv_validator_start(dns_validator_t
*val
);
159 finddlvsep(dns_validator_t
*val
, isc_boolean_t resume
);
162 startfinddlvsep(dns_validator_t
*val
, dns_name_t
*unsecure
);
165 * Mark the RRsets as a answer.
168 markanswer(dns_validator_t
*val
) {
169 validator_log(val
, ISC_LOG_DEBUG(3), "marking as answer");
170 if (val
->event
->rdataset
!= NULL
)
171 val
->event
->rdataset
->trust
= dns_trust_answer
;
172 if (val
->event
->sigrdataset
!= NULL
)
173 val
->event
->sigrdataset
->trust
= dns_trust_answer
;
177 validator_done(dns_validator_t
*val
, isc_result_t result
) {
180 if (val
->event
== NULL
)
184 * Caller must be holding the lock.
187 val
->event
->result
= result
;
188 task
= val
->event
->ev_sender
;
189 val
->event
->ev_sender
= val
;
190 val
->event
->ev_type
= DNS_EVENT_VALIDATORDONE
;
191 val
->event
->ev_action
= val
->action
;
192 val
->event
->ev_arg
= val
->arg
;
193 isc_task_sendanddetach(&task
, (isc_event_t
**)&val
->event
);
196 static inline isc_boolean_t
197 exit_check(dns_validator_t
*val
) {
199 * Caller must be holding the lock.
204 INSIST(val
->event
== NULL
);
206 if (val
->fetch
!= NULL
|| val
->subvalidator
!= NULL
)
213 * Check that we have atleast one supported algorithm in the DLV RRset.
215 static inline isc_boolean_t
216 dlv_algorithm_supported(dns_validator_t
*val
) {
217 dns_rdata_t rdata
= DNS_RDATA_INIT
;
221 for (result
= dns_rdataset_first(&val
->dlv
);
222 result
== ISC_R_SUCCESS
;
223 result
= dns_rdataset_next(&val
->dlv
)) {
224 dns_rdata_reset(&rdata
);
225 dns_rdataset_current(&val
->dlv
, &rdata
);
226 result
= dns_rdata_tostruct(&rdata
, &dlv
, NULL
);
227 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
229 if (!dns_resolver_algorithm_supported(val
->view
->resolver
,
234 if (dlv
.digest_type
!= DNS_DSDIGEST_SHA256
&&
235 dlv
.digest_type
!= DNS_DSDIGEST_SHA1
)
244 * Look in the NSEC record returned from a DS query to see if there is
245 * a NS RRset at this name. If it is found we are at a delegation point.
248 isdelegation(dns_name_t
*name
, dns_rdataset_t
*rdataset
,
249 isc_result_t dbresult
)
252 dns_rdata_t rdata
= DNS_RDATA_INIT
;
256 REQUIRE(dbresult
== DNS_R_NXRRSET
|| dbresult
== DNS_R_NCACHENXRRSET
);
258 dns_rdataset_init(&set
);
259 if (dbresult
== DNS_R_NXRRSET
)
260 dns_rdataset_clone(rdataset
, &set
);
262 result
= dns_ncache_getrdataset(rdataset
, name
,
263 dns_rdatatype_nsec
, &set
);
264 if (result
!= ISC_R_SUCCESS
)
268 INSIST(set
.type
== dns_rdatatype_nsec
);
271 result
= dns_rdataset_first(&set
);
272 if (result
== ISC_R_SUCCESS
) {
273 dns_rdataset_current(&set
, &rdata
);
274 found
= dns_nsec_typepresent(&rdata
, dns_rdatatype_ns
);
276 dns_rdataset_disassociate(&set
);
281 * We have been asked to to look for a key.
282 * If found resume the validation process.
283 * If not found fail the validation process.
286 fetch_callback_validator(isc_task_t
*task
, isc_event_t
*event
) {
287 dns_fetchevent_t
*devent
;
288 dns_validator_t
*val
;
289 dns_rdataset_t
*rdataset
;
290 isc_boolean_t want_destroy
;
292 isc_result_t eresult
;
295 INSIST(event
->ev_type
== DNS_EVENT_FETCHDONE
);
296 devent
= (dns_fetchevent_t
*)event
;
297 val
= devent
->ev_arg
;
298 rdataset
= &val
->frdataset
;
299 eresult
= devent
->result
;
301 /* Free resources which are not of interest. */
302 if (devent
->node
!= NULL
)
303 dns_db_detachnode(devent
->db
, &devent
->node
);
304 if (devent
->db
!= NULL
)
305 dns_db_detach(&devent
->db
);
306 if (dns_rdataset_isassociated(&val
->fsigrdataset
))
307 dns_rdataset_disassociate(&val
->fsigrdataset
);
308 isc_event_free(&event
);
309 dns_resolver_destroyfetch(&val
->fetch
);
311 INSIST(val
->event
!= NULL
);
313 validator_log(val
, ISC_LOG_DEBUG(3), "in fetch_callback_validator");
316 validator_done(val
, ISC_R_CANCELED
);
317 } else if (eresult
== ISC_R_SUCCESS
) {
318 validator_log(val
, ISC_LOG_DEBUG(3),
319 "keyset with trust %d", rdataset
->trust
);
321 * Only extract the dst key if the keyset is secure.
323 if (rdataset
->trust
>= dns_trust_secure
) {
324 result
= get_dst_key(val
, val
->siginfo
, rdataset
);
325 if (result
== ISC_R_SUCCESS
)
326 val
->keyset
= &val
->frdataset
;
328 result
= validate(val
, ISC_TRUE
);
329 if (result
!= DNS_R_WAIT
)
330 validator_done(val
, result
);
332 validator_log(val
, ISC_LOG_DEBUG(3),
333 "fetch_callback_validator: got %s",
334 isc_result_totext(eresult
));
335 if (eresult
== ISC_R_CANCELED
)
336 validator_done(val
, eresult
);
338 validator_done(val
, DNS_R_NOVALIDKEY
);
340 want_destroy
= exit_check(val
);
347 * We were asked to look for a DS record as part of following a key chain
348 * upwards. If found resume the validation process. If not found fail the
349 * validation process.
352 dsfetched(isc_task_t
*task
, isc_event_t
*event
) {
353 dns_fetchevent_t
*devent
;
354 dns_validator_t
*val
;
355 dns_rdataset_t
*rdataset
;
356 isc_boolean_t want_destroy
;
358 isc_result_t eresult
;
361 INSIST(event
->ev_type
== DNS_EVENT_FETCHDONE
);
362 devent
= (dns_fetchevent_t
*)event
;
363 val
= devent
->ev_arg
;
364 rdataset
= &val
->frdataset
;
365 eresult
= devent
->result
;
367 /* Free resources which are not of interest. */
368 if (devent
->node
!= NULL
)
369 dns_db_detachnode(devent
->db
, &devent
->node
);
370 if (devent
->db
!= NULL
)
371 dns_db_detach(&devent
->db
);
372 if (dns_rdataset_isassociated(&val
->fsigrdataset
))
373 dns_rdataset_disassociate(&val
->fsigrdataset
);
374 isc_event_free(&event
);
375 dns_resolver_destroyfetch(&val
->fetch
);
377 INSIST(val
->event
!= NULL
);
379 validator_log(val
, ISC_LOG_DEBUG(3), "in dsfetched");
382 validator_done(val
, ISC_R_CANCELED
);
383 } else if (eresult
== ISC_R_SUCCESS
) {
384 validator_log(val
, ISC_LOG_DEBUG(3),
385 "dsset with trust %d", rdataset
->trust
);
386 val
->dsset
= &val
->frdataset
;
387 result
= validatezonekey(val
);
388 if (result
!= DNS_R_WAIT
)
389 validator_done(val
, result
);
390 } else if (eresult
== DNS_R_NXRRSET
||
391 eresult
== DNS_R_NCACHENXRRSET
||
392 eresult
== DNS_R_SERVFAIL
) /* RFC 1034 parent? */
394 validator_log(val
, ISC_LOG_DEBUG(3),
395 "falling back to insecurity proof (%s)",
396 dns_result_totext(eresult
));
397 val
->attributes
|= VALATTR_INSECURITY
;
398 result
= proveunsecure(val
, ISC_FALSE
, ISC_FALSE
);
399 if (result
!= DNS_R_WAIT
)
400 validator_done(val
, result
);
402 validator_log(val
, ISC_LOG_DEBUG(3),
404 isc_result_totext(eresult
));
405 if (eresult
== ISC_R_CANCELED
)
406 validator_done(val
, eresult
);
408 validator_done(val
, DNS_R_NOVALIDDS
);
410 want_destroy
= exit_check(val
);
417 * We were asked to look for the DS record as part of proving that a
420 * If the DS record doesn't exist and the query name corresponds to
421 * a delegation point we are transitioning from a secure zone to a
424 * If the DS record exists it will be secure. We can continue looking
425 * for the break point in the chain of trust.
428 dsfetched2(isc_task_t
*task
, isc_event_t
*event
) {
429 dns_fetchevent_t
*devent
;
430 dns_validator_t
*val
;
432 isc_boolean_t want_destroy
;
434 isc_result_t eresult
;
437 INSIST(event
->ev_type
== DNS_EVENT_FETCHDONE
);
438 devent
= (dns_fetchevent_t
*)event
;
439 val
= devent
->ev_arg
;
440 eresult
= devent
->result
;
442 /* Free resources which are not of interest. */
443 if (devent
->node
!= NULL
)
444 dns_db_detachnode(devent
->db
, &devent
->node
);
445 if (devent
->db
!= NULL
)
446 dns_db_detach(&devent
->db
);
447 if (dns_rdataset_isassociated(&val
->fsigrdataset
))
448 dns_rdataset_disassociate(&val
->fsigrdataset
);
449 dns_resolver_destroyfetch(&val
->fetch
);
451 INSIST(val
->event
!= NULL
);
453 validator_log(val
, ISC_LOG_DEBUG(3), "in dsfetched2: %s",
454 dns_result_totext(eresult
));
457 validator_done(val
, ISC_R_CANCELED
);
458 } else if (eresult
== DNS_R_NXRRSET
|| eresult
== DNS_R_NCACHENXRRSET
) {
460 * There is no DS. If this is a delegation, we're done.
462 tname
= dns_fixedname_name(&devent
->foundname
);
463 if (isdelegation(tname
, &val
->frdataset
, eresult
)) {
464 if (val
->mustbesecure
) {
465 validator_log(val
, ISC_LOG_WARNING
,
466 "must be secure failure");
467 validator_done(val
, DNS_R_MUSTBESECURE
);
468 } else if (val
->view
->dlv
== NULL
|| DLVTRIED(val
)) {
470 validator_done(val
, ISC_R_SUCCESS
);
472 result
= startfinddlvsep(val
, tname
);
473 if (result
!= DNS_R_WAIT
)
474 validator_done(val
, result
);
477 result
= proveunsecure(val
, ISC_FALSE
, ISC_TRUE
);
478 if (result
!= DNS_R_WAIT
)
479 validator_done(val
, result
);
481 } else if (eresult
== ISC_R_SUCCESS
||
482 eresult
== DNS_R_NXDOMAIN
||
483 eresult
== DNS_R_NCACHENXDOMAIN
)
486 * There is a DS which may or may not be a zone cut.
487 * In either case we are still in a secure zone resume
490 result
= proveunsecure(val
, ISC_TF(eresult
== ISC_R_SUCCESS
),
492 if (result
!= DNS_R_WAIT
)
493 validator_done(val
, result
);
495 if (eresult
== ISC_R_CANCELED
)
496 validator_done(val
, eresult
);
498 validator_done(val
, DNS_R_NOVALIDDS
);
500 isc_event_free(&event
);
501 want_destroy
= exit_check(val
);
508 * Callback from when a DNSKEY RRset has been validated.
510 * Resumes the stalled validation process.
513 keyvalidated(isc_task_t
*task
, isc_event_t
*event
) {
514 dns_validatorevent_t
*devent
;
515 dns_validator_t
*val
;
516 isc_boolean_t want_destroy
;
518 isc_result_t eresult
;
521 INSIST(event
->ev_type
== DNS_EVENT_VALIDATORDONE
);
523 devent
= (dns_validatorevent_t
*)event
;
524 val
= devent
->ev_arg
;
525 eresult
= devent
->result
;
527 isc_event_free(&event
);
528 dns_validator_destroy(&val
->subvalidator
);
530 INSIST(val
->event
!= NULL
);
532 validator_log(val
, ISC_LOG_DEBUG(3), "in keyvalidated");
535 validator_done(val
, ISC_R_CANCELED
);
536 } else if (eresult
== ISC_R_SUCCESS
) {
537 validator_log(val
, ISC_LOG_DEBUG(3),
538 "keyset with trust %d", val
->frdataset
.trust
);
540 * Only extract the dst key if the keyset is secure.
542 if (val
->frdataset
.trust
>= dns_trust_secure
)
543 (void) get_dst_key(val
, val
->siginfo
, &val
->frdataset
);
544 result
= validate(val
, ISC_TRUE
);
545 if (result
!= DNS_R_WAIT
)
546 validator_done(val
, result
);
548 validator_log(val
, ISC_LOG_DEBUG(3),
549 "keyvalidated: got %s",
550 isc_result_totext(eresult
));
551 validator_done(val
, eresult
);
553 want_destroy
= exit_check(val
);
560 * Callback when the DS record has been validated.
562 * Resumes validation of the zone key or the unsecure zone proof.
565 dsvalidated(isc_task_t
*task
, isc_event_t
*event
) {
566 dns_validatorevent_t
*devent
;
567 dns_validator_t
*val
;
568 isc_boolean_t want_destroy
;
570 isc_result_t eresult
;
573 INSIST(event
->ev_type
== DNS_EVENT_VALIDATORDONE
);
575 devent
= (dns_validatorevent_t
*)event
;
576 val
= devent
->ev_arg
;
577 eresult
= devent
->result
;
579 isc_event_free(&event
);
580 dns_validator_destroy(&val
->subvalidator
);
582 INSIST(val
->event
!= NULL
);
584 validator_log(val
, ISC_LOG_DEBUG(3), "in dsvalidated");
587 validator_done(val
, ISC_R_CANCELED
);
588 } else if (eresult
== ISC_R_SUCCESS
) {
589 validator_log(val
, ISC_LOG_DEBUG(3),
590 "dsset with trust %d", val
->frdataset
.trust
);
591 if ((val
->attributes
& VALATTR_INSECURITY
) != 0)
592 result
= proveunsecure(val
, ISC_TRUE
, ISC_TRUE
);
594 result
= validatezonekey(val
);
595 if (result
!= DNS_R_WAIT
)
596 validator_done(val
, result
);
598 validator_log(val
, ISC_LOG_DEBUG(3),
599 "dsvalidated: got %s",
600 isc_result_totext(eresult
));
601 validator_done(val
, eresult
);
603 want_destroy
= exit_check(val
);
610 * Return ISC_R_SUCCESS if we can determine that the name doesn't exist
611 * or we can determine whether there is data or not at the name.
612 * If the name does not exist return the wildcard name.
614 * Return ISC_R_IGNORE when the NSEC is not the appropriate one.
617 nsecnoexistnodata(dns_validator_t
*val
, dns_name_t
* name
, dns_name_t
*nsecname
,
618 dns_rdataset_t
*nsecset
, isc_boolean_t
*exists
,
619 isc_boolean_t
*data
, dns_name_t
*wild
)
622 dns_rdata_t rdata
= DNS_RDATA_INIT
;
624 dns_namereln_t relation
;
625 unsigned int olabels
, nlabels
, labels
;
626 dns_rdata_nsec_t nsec
;
627 isc_boolean_t atparent
;
631 REQUIRE(exists
!= NULL
);
632 REQUIRE(data
!= NULL
);
633 REQUIRE(nsecset
!= NULL
&&
634 nsecset
->type
== dns_rdatatype_nsec
);
636 result
= dns_rdataset_first(nsecset
);
637 if (result
!= ISC_R_SUCCESS
) {
638 validator_log(val
, ISC_LOG_DEBUG(3),
639 "failure processing NSEC set");
642 dns_rdataset_current(nsecset
, &rdata
);
644 validator_log(val
, ISC_LOG_DEBUG(3), "looking for relevant nsec");
645 relation
= dns_name_fullcompare(name
, nsecname
, &order
, &olabels
);
649 * The name is not within the NSEC range.
651 validator_log(val
, ISC_LOG_DEBUG(3),
652 "NSEC does not cover name, before NSEC");
653 return (ISC_R_IGNORE
);
658 * The names are the same.
660 atparent
= dns_rdatatype_atparent(val
->event
->type
);
661 ns
= dns_nsec_typepresent(&rdata
, dns_rdatatype_ns
);
662 soa
= dns_nsec_typepresent(&rdata
, dns_rdatatype_soa
);
666 * This NSEC record is from somewhere higher in
667 * the DNS, and at the parent of a delegation.
668 * It can not be legitimately used here.
670 validator_log(val
, ISC_LOG_DEBUG(3),
671 "ignoring parent nsec");
672 return (ISC_R_IGNORE
);
674 } else if (atparent
&& ns
&& soa
) {
676 * This NSEC record is from the child.
677 * It can not be legitimately used here.
679 validator_log(val
, ISC_LOG_DEBUG(3),
680 "ignoring child nsec");
681 return (ISC_R_IGNORE
);
683 if (val
->event
->type
== dns_rdatatype_cname
||
684 val
->event
->type
== dns_rdatatype_nxt
||
685 val
->event
->type
== dns_rdatatype_nsec
||
686 val
->event
->type
== dns_rdatatype_key
||
687 !dns_nsec_typepresent(&rdata
, dns_rdatatype_cname
)) {
689 *data
= dns_nsec_typepresent(&rdata
, val
->event
->type
);
690 validator_log(val
, ISC_LOG_DEBUG(3),
691 "nsec proves name exists (owner) data=%d",
693 return (ISC_R_SUCCESS
);
695 validator_log(val
, ISC_LOG_DEBUG(3), "NSEC proves CNAME exists");
696 return (ISC_R_IGNORE
);
699 if (relation
== dns_namereln_subdomain
&&
700 dns_nsec_typepresent(&rdata
, dns_rdatatype_ns
) &&
701 !dns_nsec_typepresent(&rdata
, dns_rdatatype_soa
))
704 * This NSEC record is from somewhere higher in
705 * the DNS, and at the parent of a delegation.
706 * It can not be legitimately used here.
708 validator_log(val
, ISC_LOG_DEBUG(3), "ignoring parent nsec");
709 return (ISC_R_IGNORE
);
712 result
= dns_rdata_tostruct(&rdata
, &nsec
, NULL
);
713 if (result
!= ISC_R_SUCCESS
)
715 relation
= dns_name_fullcompare(&nsec
.next
, name
, &order
, &nlabels
);
717 dns_rdata_freestruct(&nsec
);
718 validator_log(val
, ISC_LOG_DEBUG(3),
719 "ignoring nsec matches next name");
720 return (ISC_R_IGNORE
);
723 if (order
< 0 && !dns_name_issubdomain(nsecname
, &nsec
.next
)) {
725 * The name is not within the NSEC range.
727 dns_rdata_freestruct(&nsec
);
728 validator_log(val
, ISC_LOG_DEBUG(3),
729 "ignoring nsec because name is past end of range");
730 return (ISC_R_IGNORE
);
733 if (order
> 0 && relation
== dns_namereln_subdomain
) {
734 validator_log(val
, ISC_LOG_DEBUG(3),
735 "nsec proves name exist (empty)");
736 dns_rdata_freestruct(&nsec
);
739 return (ISC_R_SUCCESS
);
743 dns_name_init(&common
, NULL
);
744 if (olabels
> nlabels
) {
745 labels
= dns_name_countlabels(nsecname
);
746 dns_name_getlabelsequence(nsecname
, labels
- olabels
,
749 labels
= dns_name_countlabels(&nsec
.next
);
750 dns_name_getlabelsequence(&nsec
.next
, labels
- nlabels
,
753 result
= dns_name_concatenate(dns_wildcardname
, &common
,
755 if (result
!= ISC_R_SUCCESS
) {
756 dns_rdata_freestruct(&nsec
);
757 validator_log(val
, ISC_LOG_DEBUG(3),
758 "failure generating wildcard name");
762 dns_rdata_freestruct(&nsec
);
763 validator_log(val
, ISC_LOG_DEBUG(3), "nsec range ok");
765 return (ISC_R_SUCCESS
);
769 * Callback for when NSEC records have been validated.
771 * Looks for NOQNAME and NODATA proofs.
773 * Resumes nsecvalidate.
776 authvalidated(isc_task_t
*task
, isc_event_t
*event
) {
777 dns_validatorevent_t
*devent
;
778 dns_validator_t
*val
;
779 dns_rdataset_t
*rdataset
;
780 isc_boolean_t want_destroy
;
782 isc_boolean_t exists
, data
;
785 INSIST(event
->ev_type
== DNS_EVENT_VALIDATORDONE
);
787 devent
= (dns_validatorevent_t
*)event
;
788 rdataset
= devent
->rdataset
;
789 val
= devent
->ev_arg
;
790 result
= devent
->result
;
791 dns_validator_destroy(&val
->subvalidator
);
793 INSIST(val
->event
!= NULL
);
795 validator_log(val
, ISC_LOG_DEBUG(3), "in authvalidated");
798 validator_done(val
, ISC_R_CANCELED
);
799 } else if (result
!= ISC_R_SUCCESS
) {
800 validator_log(val
, ISC_LOG_DEBUG(3),
801 "authvalidated: got %s",
802 isc_result_totext(result
));
803 if (result
== ISC_R_CANCELED
)
804 validator_done(val
, result
);
806 result
= nsecvalidate(val
, ISC_TRUE
);
807 if (result
!= DNS_R_WAIT
)
808 validator_done(val
, result
);
811 dns_name_t
**proofs
= val
->event
->proofs
;
812 dns_name_t
*wild
= dns_fixedname_name(&val
->wild
);
814 if (rdataset
->trust
== dns_trust_secure
)
815 val
->seensig
= ISC_TRUE
;
817 if (rdataset
->type
== dns_rdatatype_nsec
&&
818 rdataset
->trust
== dns_trust_secure
&&
819 ((val
->attributes
& VALATTR_NEEDNODATA
) != 0 ||
820 (val
->attributes
& VALATTR_NEEDNOQNAME
) != 0) &&
821 (val
->attributes
& VALATTR_FOUNDNODATA
) == 0 &&
822 (val
->attributes
& VALATTR_FOUNDNOQNAME
) == 0 &&
823 nsecnoexistnodata(val
, val
->event
->name
, devent
->name
,
824 rdataset
, &exists
, &data
, wild
)
827 if (exists
&& !data
) {
828 val
->attributes
|= VALATTR_FOUNDNODATA
;
830 proofs
[DNS_VALIDATOR_NODATAPROOF
] =
834 val
->attributes
|= VALATTR_FOUNDNOQNAME
;
835 if (NEEDNOQNAME(val
))
836 proofs
[DNS_VALIDATOR_NOQNAMEPROOF
] =
840 result
= nsecvalidate(val
, ISC_TRUE
);
841 if (result
!= DNS_R_WAIT
)
842 validator_done(val
, result
);
844 want_destroy
= exit_check(val
);
850 * Free stuff from the event.
852 isc_event_free(&event
);
856 * Looks for the requested name and type in the view (zones and cache).
858 * When looking for a DLV record also checks to make sure the NSEC record
859 * returns covers the query name as part of aggressive negative caching.
864 * \li DNS_R_NCACHENXDOMAIN
865 * \li DNS_R_NCACHENXRRSET
869 static inline isc_result_t
870 view_find(dns_validator_t
*val
, dns_name_t
*name
, dns_rdatatype_t type
) {
871 dns_fixedname_t fixedname
;
872 dns_name_t
*foundname
;
873 dns_rdata_nsec_t nsec
;
874 dns_rdata_t rdata
= DNS_RDATA_INIT
;
876 unsigned int options
;
877 char buf1
[DNS_NAME_FORMATSIZE
];
878 char buf2
[DNS_NAME_FORMATSIZE
];
879 char buf3
[DNS_NAME_FORMATSIZE
];
881 if (dns_rdataset_isassociated(&val
->frdataset
))
882 dns_rdataset_disassociate(&val
->frdataset
);
883 if (dns_rdataset_isassociated(&val
->fsigrdataset
))
884 dns_rdataset_disassociate(&val
->fsigrdataset
);
886 if (val
->view
->zonetable
== NULL
)
887 return (ISC_R_CANCELED
);
889 options
= DNS_DBFIND_PENDINGOK
;
890 if (type
== dns_rdatatype_dlv
)
891 options
|= DNS_DBFIND_COVERINGNSEC
;
892 dns_fixedname_init(&fixedname
);
893 foundname
= dns_fixedname_name(&fixedname
);
894 result
= dns_view_find(val
->view
, name
, type
, 0, options
,
895 ISC_FALSE
, NULL
, NULL
, foundname
,
896 &val
->frdataset
, &val
->fsigrdataset
);
897 if (result
== DNS_R_NXDOMAIN
) {
898 if (dns_rdataset_isassociated(&val
->frdataset
))
899 dns_rdataset_disassociate(&val
->frdataset
);
900 if (dns_rdataset_isassociated(&val
->fsigrdataset
))
901 dns_rdataset_disassociate(&val
->fsigrdataset
);
902 } else if (result
== DNS_R_COVERINGNSEC
) {
903 validator_log(val
, ISC_LOG_DEBUG(3), "DNS_R_COVERINGNSEC");
905 * Check if the returned NSEC covers the name.
907 INSIST(type
== dns_rdatatype_dlv
);
908 if (val
->frdataset
.trust
!= dns_trust_secure
) {
909 validator_log(val
, ISC_LOG_DEBUG(3),
910 "covering nsec: trust %u",
911 val
->frdataset
.trust
);
914 result
= dns_rdataset_first(&val
->frdataset
);
915 if (result
!= ISC_R_SUCCESS
)
917 dns_rdataset_current(&val
->frdataset
, &rdata
);
918 if (dns_nsec_typepresent(&rdata
, dns_rdatatype_ns
) &&
919 !dns_nsec_typepresent(&rdata
, dns_rdatatype_soa
)) {
920 /* Parent NSEC record. */
921 if (dns_name_issubdomain(name
, foundname
)) {
922 validator_log(val
, ISC_LOG_DEBUG(3),
923 "covering nsec: for parent");
927 result
= dns_rdata_tostruct(&rdata
, &nsec
, NULL
);
928 if (result
!= ISC_R_SUCCESS
)
930 if (dns_name_compare(foundname
, &nsec
.next
) >= 0) {
931 /* End of zone chain. */
932 if (!dns_name_issubdomain(name
, &nsec
.next
)) {
934 * XXXMPA We could look for a parent NSEC
935 * at nsec.next and if found retest with
938 dns_rdata_freestruct(&nsec
);
939 validator_log(val
, ISC_LOG_DEBUG(3),
940 "covering nsec: not in zone");
943 } else if (dns_name_compare(name
, &nsec
.next
) >= 0) {
945 * XXXMPA We could check if this NSEC is at a zone
946 * apex and if the qname is not below it and look for
947 * a parent NSEC with the same name. This requires
948 * that we can cache both NSEC records which we
949 * currently don't support.
951 dns_rdata_freestruct(&nsec
);
952 validator_log(val
, ISC_LOG_DEBUG(3),
953 "covering nsec: not in range");
956 if (isc_log_wouldlog(dns_lctx
,ISC_LOG_DEBUG(3))) {
957 dns_name_format(name
, buf1
, sizeof buf1
);
958 dns_name_format(foundname
, buf2
, sizeof buf2
);
959 dns_name_format(&nsec
.next
, buf3
, sizeof buf3
);
960 validator_log(val
, ISC_LOG_DEBUG(3),
961 "covering nsec found: '%s' '%s' '%s'",
964 if (dns_rdataset_isassociated(&val
->frdataset
))
965 dns_rdataset_disassociate(&val
->frdataset
);
966 if (dns_rdataset_isassociated(&val
->fsigrdataset
))
967 dns_rdataset_disassociate(&val
->fsigrdataset
);
968 dns_rdata_freestruct(&nsec
);
969 result
= DNS_R_NCACHENXDOMAIN
;
970 } else if (result
!= ISC_R_SUCCESS
&&
971 result
!= DNS_R_NCACHENXDOMAIN
&&
972 result
!= DNS_R_NCACHENXRRSET
&&
973 result
!= DNS_R_EMPTYNAME
&&
974 result
!= DNS_R_NXRRSET
&&
975 result
!= ISC_R_NOTFOUND
) {
981 if (dns_rdataset_isassociated(&val
->frdataset
))
982 dns_rdataset_disassociate(&val
->frdataset
);
983 if (dns_rdataset_isassociated(&val
->fsigrdataset
))
984 dns_rdataset_disassociate(&val
->fsigrdataset
);
985 return (ISC_R_NOTFOUND
);
989 * Checks to make sure we are not going to loop. As we use a SHARED fetch
990 * the validation process will stall if looping was to occur.
992 static inline isc_boolean_t
993 check_deadlock(dns_validator_t
*val
, dns_name_t
*name
, dns_rdatatype_t type
) {
994 dns_validator_t
*parent
;
996 for (parent
= val
; parent
!= NULL
; parent
= parent
->parent
) {
997 if (parent
->event
!= NULL
&&
998 parent
->event
->type
== type
&&
999 dns_name_equal(parent
->event
->name
, name
))
1001 validator_log(val
, ISC_LOG_DEBUG(3),
1002 "continuing validation would lead to "
1003 "deadlock: aborting validation");
1011 * Start a fetch for the requested name and type.
1013 static inline isc_result_t
1014 create_fetch(dns_validator_t
*val
, dns_name_t
*name
, dns_rdatatype_t type
,
1015 isc_taskaction_t callback
, const char *caller
)
1017 if (dns_rdataset_isassociated(&val
->frdataset
))
1018 dns_rdataset_disassociate(&val
->frdataset
);
1019 if (dns_rdataset_isassociated(&val
->fsigrdataset
))
1020 dns_rdataset_disassociate(&val
->fsigrdataset
);
1022 if (check_deadlock(val
, name
, type
))
1023 return (DNS_R_NOVALIDSIG
);
1025 validator_logcreate(val
, name
, type
, caller
, "fetch");
1026 return (dns_resolver_createfetch(val
->view
->resolver
, name
, type
,
1027 NULL
, NULL
, NULL
, 0,
1028 val
->event
->ev_sender
,
1036 * Start a subvalidation process.
1038 static inline isc_result_t
1039 create_validator(dns_validator_t
*val
, dns_name_t
*name
, dns_rdatatype_t type
,
1040 dns_rdataset_t
*rdataset
, dns_rdataset_t
*sigrdataset
,
1041 isc_taskaction_t action
, const char *caller
)
1043 isc_result_t result
;
1045 if (check_deadlock(val
, name
, type
))
1046 return (DNS_R_NOVALIDSIG
);
1048 validator_logcreate(val
, name
, type
, caller
, "validator");
1049 result
= dns_validator_create(val
->view
, name
, type
,
1050 rdataset
, sigrdataset
, NULL
, 0,
1051 val
->task
, action
, val
,
1052 &val
->subvalidator
);
1053 if (result
== ISC_R_SUCCESS
) {
1054 val
->subvalidator
->parent
= val
;
1055 val
->subvalidator
->depth
= val
->depth
+ 1;
1061 * Try to find a key that could have signed 'siginfo' among those
1062 * in 'rdataset'. If found, build a dst_key_t for it and point
1065 * If val->key is non-NULL, this returns the next matching key.
1068 get_dst_key(dns_validator_t
*val
, dns_rdata_rrsig_t
*siginfo
,
1069 dns_rdataset_t
*rdataset
)
1071 isc_result_t result
;
1073 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1074 dst_key_t
*oldkey
= val
->key
;
1075 isc_boolean_t foundold
;
1078 foundold
= ISC_TRUE
;
1080 foundold
= ISC_FALSE
;
1084 result
= dns_rdataset_first(rdataset
);
1085 if (result
!= ISC_R_SUCCESS
)
1088 dns_rdataset_current(rdataset
, &rdata
);
1090 isc_buffer_init(&b
, rdata
.data
, rdata
.length
);
1091 isc_buffer_add(&b
, rdata
.length
);
1092 INSIST(val
->key
== NULL
);
1093 result
= dst_key_fromdns(&siginfo
->signer
, rdata
.rdclass
, &b
,
1094 val
->view
->mctx
, &val
->key
);
1095 if (result
!= ISC_R_SUCCESS
)
1097 if (siginfo
->algorithm
==
1098 (dns_secalg_t
)dst_key_alg(val
->key
) &&
1100 (dns_keytag_t
)dst_key_id(val
->key
) &&
1101 dst_key_iszonekey(val
->key
))
1105 * This is the key we're looking for.
1107 return (ISC_R_SUCCESS
);
1108 else if (dst_key_compare(oldkey
, val
->key
) == ISC_TRUE
)
1110 foundold
= ISC_TRUE
;
1111 dst_key_free(&oldkey
);
1114 dst_key_free(&val
->key
);
1115 dns_rdata_reset(&rdata
);
1116 result
= dns_rdataset_next(rdataset
);
1117 } while (result
== ISC_R_SUCCESS
);
1118 if (result
== ISC_R_NOMORE
)
1119 result
= ISC_R_NOTFOUND
;
1123 dst_key_free(&oldkey
);
1129 * Get the key that generated this signature.
1132 get_key(dns_validator_t
*val
, dns_rdata_rrsig_t
*siginfo
) {
1133 isc_result_t result
;
1134 unsigned int nlabels
;
1136 dns_namereln_t namereln
;
1139 * Is the signer name appropriate for this signature?
1141 * The signer name must be at the same level as the owner name
1142 * or closer to the DNS root.
1144 namereln
= dns_name_fullcompare(val
->event
->name
, &siginfo
->signer
,
1146 if (namereln
!= dns_namereln_subdomain
&&
1147 namereln
!= dns_namereln_equal
)
1148 return (DNS_R_CONTINUE
);
1150 if (namereln
== dns_namereln_equal
) {
1152 * If this is a self-signed keyset, it must not be a zone key
1153 * (since get_key is not called from validatezonekey).
1155 if (val
->event
->rdataset
->type
== dns_rdatatype_dnskey
)
1156 return (DNS_R_CONTINUE
);
1159 * Records appearing in the parent zone at delegation
1160 * points cannot be self-signed.
1162 if (dns_rdatatype_atparent(val
->event
->rdataset
->type
))
1163 return (DNS_R_CONTINUE
);
1166 * SOA and NS RRsets can only be signed by a key with
1169 if (val
->event
->rdataset
->type
== dns_rdatatype_soa
||
1170 val
->event
->rdataset
->type
== dns_rdatatype_ns
) {
1171 const char *typename
;
1173 if (val
->event
->rdataset
->type
== dns_rdatatype_soa
)
1177 validator_log(val
, ISC_LOG_DEBUG(3),
1178 "%s signer mismatch", typename
);
1179 return (DNS_R_CONTINUE
);
1184 * Do we know about this key?
1186 result
= view_find(val
, &siginfo
->signer
, dns_rdatatype_dnskey
);
1187 if (result
== ISC_R_SUCCESS
) {
1189 * We have an rrset for the given keyname.
1191 val
->keyset
= &val
->frdataset
;
1192 if (val
->frdataset
.trust
== dns_trust_pending
&&
1193 dns_rdataset_isassociated(&val
->fsigrdataset
))
1196 * We know the key but haven't validated it yet.
1198 result
= create_validator(val
, &siginfo
->signer
,
1199 dns_rdatatype_dnskey
,
1204 if (result
!= ISC_R_SUCCESS
)
1206 return (DNS_R_WAIT
);
1207 } else if (val
->frdataset
.trust
== dns_trust_pending
) {
1209 * Having a pending key with no signature means that
1210 * something is broken.
1212 result
= DNS_R_CONTINUE
;
1213 } else if (val
->frdataset
.trust
< dns_trust_secure
) {
1215 * The key is legitimately insecure. There's no
1216 * point in even attempting verification.
1219 result
= ISC_R_SUCCESS
;
1222 * See if we've got the key used in the signature.
1224 validator_log(val
, ISC_LOG_DEBUG(3),
1225 "keyset with trust %d",
1226 val
->frdataset
.trust
);
1227 result
= get_dst_key(val
, siginfo
, val
->keyset
);
1228 if (result
!= ISC_R_SUCCESS
) {
1230 * Either the key we're looking for is not
1231 * in the rrset, or something bad happened.
1234 result
= DNS_R_CONTINUE
;
1237 } else if (result
== ISC_R_NOTFOUND
) {
1239 * We don't know anything about this key.
1241 result
= create_fetch(val
, &siginfo
->signer
, dns_rdatatype_dnskey
,
1242 fetch_callback_validator
, "get_key");
1243 if (result
!= ISC_R_SUCCESS
)
1245 return (DNS_R_WAIT
);
1246 } else if (result
== DNS_R_NCACHENXDOMAIN
||
1247 result
== DNS_R_NCACHENXRRSET
||
1248 result
== DNS_R_EMPTYNAME
||
1249 result
== DNS_R_NXDOMAIN
||
1250 result
== DNS_R_NXRRSET
)
1253 * This key doesn't exist.
1255 result
= DNS_R_CONTINUE
;
1258 if (dns_rdataset_isassociated(&val
->frdataset
) &&
1259 val
->keyset
!= &val
->frdataset
)
1260 dns_rdataset_disassociate(&val
->frdataset
);
1261 if (dns_rdataset_isassociated(&val
->fsigrdataset
))
1262 dns_rdataset_disassociate(&val
->fsigrdataset
);
1268 compute_keytag(dns_rdata_t
*rdata
, dns_rdata_dnskey_t
*key
) {
1271 dns_rdata_toregion(rdata
, &r
);
1272 return (dst_region_computeid(&r
, key
->algorithm
));
1276 * Is this keyset self-signed?
1278 static isc_boolean_t
1279 isselfsigned(dns_validator_t
*val
) {
1280 dns_rdataset_t
*rdataset
, *sigrdataset
;
1281 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1282 dns_rdata_t sigrdata
= DNS_RDATA_INIT
;
1283 dns_rdata_dnskey_t key
;
1284 dns_rdata_rrsig_t sig
;
1285 dns_keytag_t keytag
;
1286 isc_result_t result
;
1288 rdataset
= val
->event
->rdataset
;
1289 sigrdataset
= val
->event
->sigrdataset
;
1291 INSIST(rdataset
->type
== dns_rdatatype_dnskey
);
1293 for (result
= dns_rdataset_first(rdataset
);
1294 result
== ISC_R_SUCCESS
;
1295 result
= dns_rdataset_next(rdataset
))
1297 dns_rdata_reset(&rdata
);
1298 dns_rdataset_current(rdataset
, &rdata
);
1299 result
= dns_rdata_tostruct(&rdata
, &key
, NULL
);
1300 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
1301 keytag
= compute_keytag(&rdata
, &key
);
1302 for (result
= dns_rdataset_first(sigrdataset
);
1303 result
== ISC_R_SUCCESS
;
1304 result
= dns_rdataset_next(sigrdataset
))
1306 dns_rdata_reset(&sigrdata
);
1307 dns_rdataset_current(sigrdataset
, &sigrdata
);
1308 result
= dns_rdata_tostruct(&sigrdata
, &sig
, NULL
);
1309 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
1311 if (sig
.algorithm
== key
.algorithm
&&
1312 sig
.keyid
== keytag
)
1320 * Attempt to verify the rdataset using the given key and rdata (RRSIG).
1321 * The signature was good and from a wildcard record and the QNAME does
1322 * not match the wildcard we need to look for a NOQNAME proof.
1325 * \li ISC_R_SUCCESS if the verification succeeds.
1326 * \li Others if the verification fails.
1329 verify(dns_validator_t
*val
, dst_key_t
*key
, dns_rdata_t
*rdata
,
1332 isc_result_t result
;
1333 dns_fixedname_t fixed
;
1334 isc_boolean_t ignore
= ISC_FALSE
;
1336 val
->attributes
|= VALATTR_TRIEDVERIFY
;
1337 dns_fixedname_init(&fixed
);
1339 result
= dns_dnssec_verify2(val
->event
->name
, val
->event
->rdataset
,
1340 key
, ignore
, val
->view
->mctx
, rdata
,
1341 dns_fixedname_name(&fixed
));
1342 if (result
== DNS_R_SIGEXPIRED
&& val
->view
->acceptexpired
) {
1346 if (ignore
&& (result
== ISC_R_SUCCESS
|| result
== DNS_R_FROMWILDCARD
))
1347 validator_log(val
, ISC_LOG_INFO
,
1348 "accepted expired %sRRSIG (keyid=%u)",
1349 (result
== DNS_R_FROMWILDCARD
) ?
1350 "wildcard " : "", keyid
);
1352 validator_log(val
, ISC_LOG_DEBUG(3),
1353 "verify rdataset (keyid=%u): %s",
1354 keyid
, isc_result_totext(result
));
1355 if (result
== DNS_R_FROMWILDCARD
) {
1356 if (!dns_name_equal(val
->event
->name
,
1357 dns_fixedname_name(&fixed
)))
1358 val
->attributes
|= VALATTR_NEEDNOQNAME
;
1359 result
= ISC_R_SUCCESS
;
1365 * Attempts positive response validation of a normal RRset.
1368 * \li ISC_R_SUCCESS Validation completed successfully
1369 * \li DNS_R_WAIT Validation has started but is waiting
1371 * \li Other return codes are possible and all indicate failure.
1374 validate(dns_validator_t
*val
, isc_boolean_t resume
) {
1375 isc_result_t result
;
1376 dns_validatorevent_t
*event
;
1377 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1380 * Caller must be holding the validator lock.
1387 * We already have a sigrdataset.
1389 result
= ISC_R_SUCCESS
;
1390 validator_log(val
, ISC_LOG_DEBUG(3), "resuming validate");
1392 result
= dns_rdataset_first(event
->sigrdataset
);
1396 result
== ISC_R_SUCCESS
;
1397 result
= dns_rdataset_next(event
->sigrdataset
))
1399 dns_rdata_reset(&rdata
);
1400 dns_rdataset_current(event
->sigrdataset
, &rdata
);
1401 if (val
->siginfo
== NULL
) {
1402 val
->siginfo
= isc_mem_get(val
->view
->mctx
,
1403 sizeof(*val
->siginfo
));
1404 if (val
->siginfo
== NULL
)
1405 return (ISC_R_NOMEMORY
);
1407 result
= dns_rdata_tostruct(&rdata
, val
->siginfo
, NULL
);
1408 if (result
!= ISC_R_SUCCESS
)
1412 * At this point we could check that the signature algorithm
1413 * was known and "sufficiently good".
1415 if (!dns_resolver_algorithm_supported(val
->view
->resolver
,
1417 val
->siginfo
->algorithm
))
1421 result
= get_key(val
, val
->siginfo
);
1422 if (result
== DNS_R_CONTINUE
)
1423 continue; /* Try the next SIG RR. */
1424 if (result
!= ISC_R_SUCCESS
)
1429 * The key is insecure, so mark the data as insecure also.
1431 if (val
->key
== NULL
) {
1432 if (val
->mustbesecure
) {
1433 validator_log(val
, ISC_LOG_WARNING
,
1434 "must be secure failure");
1435 return (DNS_R_MUSTBESECURE
);
1438 return (ISC_R_SUCCESS
);
1442 result
= verify(val
, val
->key
, &rdata
,
1443 val
->siginfo
->keyid
);
1444 if (result
== ISC_R_SUCCESS
)
1446 if (val
->keynode
!= NULL
) {
1447 dns_keynode_t
*nextnode
= NULL
;
1448 result
= dns_keytable_findnextkeynode(
1452 dns_keytable_detachkeynode(val
->keytable
,
1454 val
->keynode
= nextnode
;
1455 if (result
!= ISC_R_SUCCESS
) {
1459 val
->key
= dns_keynode_key(val
->keynode
);
1461 if (get_dst_key(val
, val
->siginfo
, val
->keyset
)
1466 if (result
!= ISC_R_SUCCESS
)
1467 validator_log(val
, ISC_LOG_DEBUG(3),
1468 "failed to verify rdataset");
1473 isc_stdtime_get(&now
);
1474 ttl
= ISC_MIN(event
->rdataset
->ttl
,
1475 val
->siginfo
->timeexpire
- now
);
1476 if (val
->keyset
!= NULL
)
1477 ttl
= ISC_MIN(ttl
, val
->keyset
->ttl
);
1478 event
->rdataset
->ttl
= ttl
;
1479 event
->sigrdataset
->ttl
= ttl
;
1482 if (val
->keynode
!= NULL
)
1483 dns_keytable_detachkeynode(val
->keytable
,
1486 if (val
->key
!= NULL
)
1487 dst_key_free(&val
->key
);
1488 if (val
->keyset
!= NULL
) {
1489 dns_rdataset_disassociate(val
->keyset
);
1494 if ((val
->attributes
& VALATTR_NEEDNOQNAME
) != 0) {
1495 if (val
->event
->message
== NULL
) {
1496 validator_log(val
, ISC_LOG_DEBUG(3),
1497 "no message available for noqname proof");
1498 return (DNS_R_NOVALIDSIG
);
1500 validator_log(val
, ISC_LOG_DEBUG(3),
1501 "looking for noqname proof");
1502 return (nsecvalidate(val
, ISC_FALSE
));
1503 } else if (result
== ISC_R_SUCCESS
) {
1504 event
->rdataset
->trust
= dns_trust_secure
;
1505 event
->sigrdataset
->trust
= dns_trust_secure
;
1506 validator_log(val
, ISC_LOG_DEBUG(3),
1507 "marking as secure");
1510 validator_log(val
, ISC_LOG_DEBUG(3),
1511 "verify failure: %s",
1512 isc_result_totext(result
));
1516 if (result
!= ISC_R_NOMORE
) {
1517 validator_log(val
, ISC_LOG_DEBUG(3),
1518 "failed to iterate signatures: %s",
1519 isc_result_totext(result
));
1523 validator_log(val
, ISC_LOG_INFO
, "no valid signature found");
1524 return (DNS_R_NOVALIDSIG
);
1528 * Validate the DNSKEY RRset by looking for a DNSKEY that matches a
1529 * DLV record and that also verifies the DNSKEY RRset.
1532 dlv_validatezonekey(dns_validator_t
*val
) {
1533 dns_keytag_t keytag
;
1534 dns_rdata_dlv_t dlv
;
1535 dns_rdata_dnskey_t key
;
1536 dns_rdata_rrsig_t sig
;
1537 dns_rdata_t dlvrdata
= DNS_RDATA_INIT
;
1538 dns_rdata_t keyrdata
= DNS_RDATA_INIT
;
1539 dns_rdata_t newdsrdata
= DNS_RDATA_INIT
;
1540 dns_rdata_t sigrdata
= DNS_RDATA_INIT
;
1541 dns_rdataset_t trdataset
;
1543 isc_boolean_t supported_algorithm
;
1544 isc_result_t result
;
1545 unsigned char dsbuf
[DNS_DS_BUFFERSIZE
];
1546 isc_uint8_t digest_type
;
1548 validator_log(val
, ISC_LOG_DEBUG(3), "dlv_validatezonekey");
1551 * Look through the DLV record and find the keys that can sign the
1552 * key set and the matching signature. For each such key, attempt
1555 supported_algorithm
= ISC_FALSE
;
1558 * If DNS_DSDIGEST_SHA256 is present we are required to prefer
1559 * it over DNS_DSDIGEST_SHA1. This in practice means that we
1560 * need to ignore DNS_DSDIGEST_SHA1 if a DNS_DSDIGEST_SHA256
1563 digest_type
= DNS_DSDIGEST_SHA1
;
1564 for (result
= dns_rdataset_first(&val
->dlv
);
1565 result
== ISC_R_SUCCESS
;
1566 result
= dns_rdataset_next(&val
->dlv
)) {
1567 dns_rdata_reset(&dlvrdata
);
1568 dns_rdataset_current(&val
->dlv
, &dlvrdata
);
1569 result
= dns_rdata_tostruct(&dlvrdata
, &dlv
, NULL
);
1570 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
1572 if (!dns_resolver_algorithm_supported(val
->view
->resolver
,
1577 if (dlv
.digest_type
== DNS_DSDIGEST_SHA256
&&
1578 dlv
.length
== ISC_SHA256_DIGESTLENGTH
) {
1579 digest_type
= DNS_DSDIGEST_SHA256
;
1584 for (result
= dns_rdataset_first(&val
->dlv
);
1585 result
== ISC_R_SUCCESS
;
1586 result
= dns_rdataset_next(&val
->dlv
))
1588 dns_rdata_reset(&dlvrdata
);
1589 dns_rdataset_current(&val
->dlv
, &dlvrdata
);
1590 result
= dns_rdata_tostruct(&dlvrdata
, &dlv
, NULL
);
1591 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
1593 if (!dns_resolver_digest_supported(val
->view
->resolver
,
1597 if (dlv
.digest_type
!= digest_type
)
1600 if (!dns_resolver_algorithm_supported(val
->view
->resolver
,
1605 supported_algorithm
= ISC_TRUE
;
1607 dns_rdataset_init(&trdataset
);
1608 dns_rdataset_clone(val
->event
->rdataset
, &trdataset
);
1610 for (result
= dns_rdataset_first(&trdataset
);
1611 result
== ISC_R_SUCCESS
;
1612 result
= dns_rdataset_next(&trdataset
))
1614 dns_rdata_reset(&keyrdata
);
1615 dns_rdataset_current(&trdataset
, &keyrdata
);
1616 result
= dns_rdata_tostruct(&keyrdata
, &key
, NULL
);
1617 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
1618 keytag
= compute_keytag(&keyrdata
, &key
);
1619 if (dlv
.key_tag
!= keytag
||
1620 dlv
.algorithm
!= key
.algorithm
)
1622 dns_rdata_reset(&newdsrdata
);
1623 result
= dns_ds_buildrdata(val
->event
->name
,
1624 &keyrdata
, dlv
.digest_type
,
1625 dsbuf
, &newdsrdata
);
1626 if (result
!= ISC_R_SUCCESS
) {
1627 validator_log(val
, ISC_LOG_DEBUG(3),
1628 "dns_ds_buildrdata() -> %s",
1629 dns_result_totext(result
));
1633 newdsrdata
.type
= dns_rdatatype_dlv
;
1634 if (dns_rdata_compare(&dlvrdata
, &newdsrdata
) == 0)
1637 if (result
!= ISC_R_SUCCESS
) {
1638 dns_rdataset_disassociate(&trdataset
);
1639 validator_log(val
, ISC_LOG_DEBUG(3),
1640 "no DNSKEY matching DLV");
1643 validator_log(val
, ISC_LOG_DEBUG(3),
1644 "Found matching DLV record: checking for signature");
1646 for (result
= dns_rdataset_first(val
->event
->sigrdataset
);
1647 result
== ISC_R_SUCCESS
;
1648 result
= dns_rdataset_next(val
->event
->sigrdataset
))
1650 dns_rdata_reset(&sigrdata
);
1651 dns_rdataset_current(val
->event
->sigrdataset
,
1653 result
= dns_rdata_tostruct(&sigrdata
, &sig
, NULL
);
1654 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
1655 if (dlv
.key_tag
!= sig
.keyid
&&
1656 dlv
.algorithm
!= sig
.algorithm
)
1659 result
= dns_dnssec_keyfromrdata(val
->event
->name
,
1663 if (result
!= ISC_R_SUCCESS
)
1665 * This really shouldn't happen, but...
1669 result
= verify(val
, dstkey
, &sigrdata
, sig
.keyid
);
1670 dst_key_free(&dstkey
);
1671 if (result
== ISC_R_SUCCESS
)
1674 dns_rdataset_disassociate(&trdataset
);
1675 if (result
== ISC_R_SUCCESS
)
1677 validator_log(val
, ISC_LOG_DEBUG(3),
1678 "no RRSIG matching DLV key");
1680 if (result
== ISC_R_SUCCESS
) {
1681 val
->event
->rdataset
->trust
= dns_trust_secure
;
1682 val
->event
->sigrdataset
->trust
= dns_trust_secure
;
1683 validator_log(val
, ISC_LOG_DEBUG(3), "marking as secure");
1685 } else if (result
== ISC_R_NOMORE
&& !supported_algorithm
) {
1686 if (val
->mustbesecure
) {
1687 validator_log(val
, ISC_LOG_WARNING
,
1688 "must be secure failure");
1689 return (DNS_R_MUSTBESECURE
);
1691 validator_log(val
, ISC_LOG_DEBUG(3),
1692 "no supported algorithm/digest (dlv)");
1694 return (ISC_R_SUCCESS
);
1696 return (DNS_R_NOVALIDSIG
);
1700 * Attempts positive response validation of an RRset containing zone keys.
1703 * \li ISC_R_SUCCESS Validation completed successfully
1704 * \li DNS_R_WAIT Validation has started but is waiting
1706 * \li Other return codes are possible and all indicate failure.
1709 validatezonekey(dns_validator_t
*val
) {
1710 isc_result_t result
;
1711 dns_validatorevent_t
*event
;
1712 dns_rdataset_t trdataset
;
1713 dns_rdata_t dsrdata
= DNS_RDATA_INIT
;
1714 dns_rdata_t newdsrdata
= DNS_RDATA_INIT
;
1715 dns_rdata_t keyrdata
= DNS_RDATA_INIT
;
1716 dns_rdata_t sigrdata
= DNS_RDATA_INIT
;
1717 unsigned char dsbuf
[DNS_DS_BUFFERSIZE
];
1718 char namebuf
[DNS_NAME_FORMATSIZE
];
1719 dns_keytag_t keytag
;
1721 dns_rdata_dnskey_t key
;
1722 dns_rdata_rrsig_t sig
;
1724 isc_boolean_t supported_algorithm
;
1725 isc_boolean_t atsep
= ISC_FALSE
;
1726 isc_uint8_t digest_type
;
1729 * Caller must be holding the validator lock.
1734 if (val
->havedlvsep
&& val
->dlv
.trust
>= dns_trust_secure
&&
1735 dns_name_equal(event
->name
, dns_fixedname_name(&val
->dlvsep
)))
1736 return (dlv_validatezonekey(val
));
1738 if (val
->dsset
== NULL
) {
1740 * First, see if this key was signed by a trusted key.
1742 for (result
= dns_rdataset_first(val
->event
->sigrdataset
);
1743 result
== ISC_R_SUCCESS
;
1744 result
= dns_rdataset_next(val
->event
->sigrdataset
))
1746 dns_keynode_t
*keynode
= NULL
, *nextnode
= NULL
;
1748 dns_rdata_reset(&sigrdata
);
1749 dns_rdataset_current(val
->event
->sigrdataset
,
1751 result
= dns_rdata_tostruct(&sigrdata
, &sig
, NULL
);
1752 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
1754 if (!dns_name_equal(val
->event
->name
, &sig
.signer
))
1757 result
= dns_keytable_findkeynode(val
->keytable
,
1762 if (result
== DNS_R_PARTIALMATCH
||
1763 result
== ISC_R_SUCCESS
)
1765 while (result
== ISC_R_SUCCESS
) {
1766 dstkey
= dns_keynode_key(keynode
);
1767 result
= verify(val
, dstkey
, &sigrdata
,
1769 if (result
== ISC_R_SUCCESS
) {
1770 dns_keytable_detachkeynode(val
->keytable
,
1774 result
= dns_keytable_findnextkeynode(
1778 dns_keytable_detachkeynode(val
->keytable
,
1782 if (result
== ISC_R_SUCCESS
) {
1783 event
->rdataset
->trust
= dns_trust_secure
;
1784 event
->sigrdataset
->trust
= dns_trust_secure
;
1785 validator_log(val
, ISC_LOG_DEBUG(3),
1786 "signed by trusted key; "
1787 "marking as secure");
1793 * If this is the root name and there was no trusted key,
1794 * give up, since there's no DS at the root.
1796 if (dns_name_equal(event
->name
, dns_rootname
)) {
1797 if ((val
->attributes
& VALATTR_TRIEDVERIFY
) != 0)
1798 return (DNS_R_NOVALIDSIG
);
1800 return (DNS_R_NOVALIDDS
);
1805 * We have not found a key to verify this DNSKEY
1806 * RRset. As this is a SEP we have to assume that
1807 * the RRset is invalid.
1809 dns_name_format(val
->event
->name
, namebuf
,
1811 validator_log(val
, ISC_LOG_DEBUG(2),
1812 "unable to find a DNSKEY which verifies "
1813 "the DNSKEY RRset and also matches one "
1814 "of specified trusted-keys for '%s'",
1816 return (DNS_R_NOVALIDKEY
);
1820 * Otherwise, try to find the DS record.
1822 result
= view_find(val
, val
->event
->name
, dns_rdatatype_ds
);
1823 if (result
== ISC_R_SUCCESS
) {
1825 * We have DS records.
1827 val
->dsset
= &val
->frdataset
;
1828 if (val
->frdataset
.trust
== dns_trust_pending
&&
1829 dns_rdataset_isassociated(&val
->fsigrdataset
))
1831 result
= create_validator(val
,
1838 if (result
!= ISC_R_SUCCESS
)
1840 return (DNS_R_WAIT
);
1841 } else if (val
->frdataset
.trust
== dns_trust_pending
) {
1843 * There should never be an unsigned DS.
1845 dns_rdataset_disassociate(&val
->frdataset
);
1846 validator_log(val
, ISC_LOG_DEBUG(2),
1847 "unsigned DS record");
1848 return (DNS_R_NOVALIDSIG
);
1850 result
= ISC_R_SUCCESS
;
1851 } else if (result
== ISC_R_NOTFOUND
) {
1853 * We don't have the DS. Find it.
1855 result
= create_fetch(val
, val
->event
->name
,
1856 dns_rdatatype_ds
, dsfetched
,
1858 if (result
!= ISC_R_SUCCESS
)
1860 return (DNS_R_WAIT
);
1861 } else if (result
== DNS_R_NCACHENXDOMAIN
||
1862 result
== DNS_R_NCACHENXRRSET
||
1863 result
== DNS_R_EMPTYNAME
||
1864 result
== DNS_R_NXDOMAIN
||
1865 result
== DNS_R_NXRRSET
)
1868 * The DS does not exist.
1870 if (dns_rdataset_isassociated(&val
->frdataset
))
1871 dns_rdataset_disassociate(&val
->frdataset
);
1872 if (dns_rdataset_isassociated(&val
->fsigrdataset
))
1873 dns_rdataset_disassociate(&val
->fsigrdataset
);
1874 validator_log(val
, ISC_LOG_DEBUG(2), "no DS record");
1875 return (DNS_R_NOVALIDSIG
);
1882 INSIST(val
->dsset
!= NULL
);
1884 if (val
->dsset
->trust
< dns_trust_secure
) {
1885 if (val
->mustbesecure
) {
1886 validator_log(val
, ISC_LOG_WARNING
,
1887 "must be secure failure");
1888 return (DNS_R_MUSTBESECURE
);
1891 return (ISC_R_SUCCESS
);
1895 * Look through the DS record and find the keys that can sign the
1896 * key set and the matching signature. For each such key, attempt
1900 supported_algorithm
= ISC_FALSE
;
1903 * If DNS_DSDIGEST_SHA256 is present we are required to prefer
1904 * it over DNS_DSDIGEST_SHA1. This in practice means that we
1905 * need to ignore DNS_DSDIGEST_SHA1 if a DNS_DSDIGEST_SHA256
1908 digest_type
= DNS_DSDIGEST_SHA1
;
1909 for (result
= dns_rdataset_first(val
->dsset
);
1910 result
== ISC_R_SUCCESS
;
1911 result
= dns_rdataset_next(val
->dsset
)) {
1912 dns_rdata_reset(&dsrdata
);
1913 dns_rdataset_current(val
->dsset
, &dsrdata
);
1914 result
= dns_rdata_tostruct(&dsrdata
, &ds
, NULL
);
1915 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
1917 if (!dns_resolver_algorithm_supported(val
->view
->resolver
,
1922 if (ds
.digest_type
== DNS_DSDIGEST_SHA256
&&
1923 ds
.length
== ISC_SHA256_DIGESTLENGTH
) {
1924 digest_type
= DNS_DSDIGEST_SHA256
;
1929 for (result
= dns_rdataset_first(val
->dsset
);
1930 result
== ISC_R_SUCCESS
;
1931 result
= dns_rdataset_next(val
->dsset
))
1933 dns_rdata_reset(&dsrdata
);
1934 dns_rdataset_current(val
->dsset
, &dsrdata
);
1935 result
= dns_rdata_tostruct(&dsrdata
, &ds
, NULL
);
1936 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
1938 if (!dns_resolver_digest_supported(val
->view
->resolver
,
1942 if (ds
.digest_type
!= digest_type
)
1945 if (!dns_resolver_algorithm_supported(val
->view
->resolver
,
1950 supported_algorithm
= ISC_TRUE
;
1952 dns_rdataset_init(&trdataset
);
1953 dns_rdataset_clone(val
->event
->rdataset
, &trdataset
);
1956 * Look for the KEY that matches the DS record.
1958 for (result
= dns_rdataset_first(&trdataset
);
1959 result
== ISC_R_SUCCESS
;
1960 result
= dns_rdataset_next(&trdataset
))
1962 dns_rdata_reset(&keyrdata
);
1963 dns_rdataset_current(&trdataset
, &keyrdata
);
1964 result
= dns_rdata_tostruct(&keyrdata
, &key
, NULL
);
1965 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
1966 keytag
= compute_keytag(&keyrdata
, &key
);
1967 if (ds
.key_tag
!= keytag
||
1968 ds
.algorithm
!= key
.algorithm
)
1970 dns_rdata_reset(&newdsrdata
);
1971 result
= dns_ds_buildrdata(val
->event
->name
,
1972 &keyrdata
, ds
.digest_type
,
1973 dsbuf
, &newdsrdata
);
1974 if (result
!= ISC_R_SUCCESS
)
1976 if (dns_rdata_compare(&dsrdata
, &newdsrdata
) == 0)
1979 if (result
!= ISC_R_SUCCESS
) {
1980 dns_rdataset_disassociate(&trdataset
);
1981 validator_log(val
, ISC_LOG_DEBUG(3),
1982 "no DNSKEY matching DS");
1986 for (result
= dns_rdataset_first(val
->event
->sigrdataset
);
1987 result
== ISC_R_SUCCESS
;
1988 result
= dns_rdataset_next(val
->event
->sigrdataset
))
1990 dns_rdata_reset(&sigrdata
);
1991 dns_rdataset_current(val
->event
->sigrdataset
,
1993 result
= dns_rdata_tostruct(&sigrdata
, &sig
, NULL
);
1994 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
1995 if (ds
.key_tag
!= sig
.keyid
||
1996 ds
.algorithm
!= sig
.algorithm
)
1998 if (!dns_name_equal(val
->event
->name
, &sig
.signer
)) {
1999 validator_log(val
, ISC_LOG_DEBUG(3),
2000 "DNSKEY signer mismatch");
2004 result
= dns_dnssec_keyfromrdata(val
->event
->name
,
2008 if (result
!= ISC_R_SUCCESS
)
2010 * This really shouldn't happen, but...
2013 result
= verify(val
, dstkey
, &sigrdata
, sig
.keyid
);
2014 dst_key_free(&dstkey
);
2015 if (result
== ISC_R_SUCCESS
)
2018 dns_rdataset_disassociate(&trdataset
);
2019 if (result
== ISC_R_SUCCESS
)
2021 validator_log(val
, ISC_LOG_DEBUG(3),
2022 "no RRSIG matching DS key");
2024 if (result
== ISC_R_SUCCESS
) {
2025 event
->rdataset
->trust
= dns_trust_secure
;
2026 event
->sigrdataset
->trust
= dns_trust_secure
;
2027 validator_log(val
, ISC_LOG_DEBUG(3), "marking as secure");
2029 } else if (result
== ISC_R_NOMORE
&& !supported_algorithm
) {
2030 if (val
->mustbesecure
) {
2031 validator_log(val
, ISC_LOG_WARNING
,
2032 "must be secure failure");
2033 return (DNS_R_MUSTBESECURE
);
2035 validator_log(val
, ISC_LOG_DEBUG(3),
2036 "no supported algorithm/digest (DS)");
2038 return (ISC_R_SUCCESS
);
2040 return (DNS_R_NOVALIDSIG
);
2044 * Starts a positive response validation.
2047 * \li ISC_R_SUCCESS Validation completed successfully
2048 * \li DNS_R_WAIT Validation has started but is waiting
2050 * \li Other return codes are possible and all indicate failure.
2053 start_positive_validation(dns_validator_t
*val
) {
2055 * If this is not a key, go straight into validate().
2057 if (val
->event
->type
!= dns_rdatatype_dnskey
|| !isselfsigned(val
))
2058 return (validate(val
, ISC_FALSE
));
2060 return (validatezonekey(val
));
2064 * Look for NODATA at the wildcard and NOWILDCARD proofs in the
2065 * previously validated NSEC records. As these proofs are mutually
2066 * exclusive we stop when one is found.
2072 checkwildcard(dns_validator_t
*val
) {
2073 dns_name_t
*name
, *wild
;
2074 dns_message_t
*message
= val
->event
->message
;
2075 isc_result_t result
;
2076 isc_boolean_t exists
, data
;
2077 char namebuf
[DNS_NAME_FORMATSIZE
];
2079 wild
= dns_fixedname_name(&val
->wild
);
2080 dns_name_format(wild
, namebuf
, sizeof(namebuf
));
2081 validator_log(val
, ISC_LOG_DEBUG(3), "in checkwildcard: %s", namebuf
);
2083 for (result
= dns_message_firstname(message
, DNS_SECTION_AUTHORITY
);
2084 result
== ISC_R_SUCCESS
;
2085 result
= dns_message_nextname(message
, DNS_SECTION_AUTHORITY
))
2087 dns_rdataset_t
*rdataset
= NULL
, *sigrdataset
= NULL
;
2090 dns_message_currentname(message
, DNS_SECTION_AUTHORITY
, &name
);
2092 for (rdataset
= ISC_LIST_HEAD(name
->list
);
2094 rdataset
= ISC_LIST_NEXT(rdataset
, link
))
2096 if (rdataset
->type
!= dns_rdatatype_nsec
)
2098 val
->nsecset
= rdataset
;
2100 for (sigrdataset
= ISC_LIST_HEAD(name
->list
);
2101 sigrdataset
!= NULL
;
2102 sigrdataset
= ISC_LIST_NEXT(sigrdataset
, link
))
2104 if (sigrdataset
->type
== dns_rdatatype_rrsig
&&
2105 sigrdataset
->covers
== rdataset
->type
)
2108 if (sigrdataset
== NULL
)
2111 if (rdataset
->trust
!= dns_trust_secure
)
2114 if (((val
->attributes
& VALATTR_NEEDNODATA
) != 0 ||
2115 (val
->attributes
& VALATTR_NEEDNOWILDCARD
) != 0) &&
2116 (val
->attributes
& VALATTR_FOUNDNODATA
) == 0 &&
2117 (val
->attributes
& VALATTR_FOUNDNOWILDCARD
) == 0 &&
2118 nsecnoexistnodata(val
, wild
, name
, rdataset
,
2119 &exists
, &data
, NULL
)
2122 dns_name_t
**proofs
= val
->event
->proofs
;
2123 if (exists
&& !data
)
2124 val
->attributes
|= VALATTR_FOUNDNODATA
;
2125 if (exists
&& !data
&& NEEDNODATA(val
))
2126 proofs
[DNS_VALIDATOR_NODATAPROOF
] =
2130 VALATTR_FOUNDNOWILDCARD
;
2131 if (!exists
&& NEEDNOQNAME(val
))
2132 proofs
[DNS_VALIDATOR_NOWILDCARDPROOF
] =
2134 return (ISC_R_SUCCESS
);
2138 if (result
== ISC_R_NOMORE
)
2139 result
= ISC_R_SUCCESS
;
2144 * Prove a negative answer is good or that there is a NOQNAME when the
2145 * answer is from a wildcard.
2147 * Loop through the authority section looking for NODATA, NOWILDCARD
2148 * and NOQNAME proofs in the NSEC records by calling authvalidated().
2150 * If the required proofs are found we are done.
2152 * If the proofs are not found attempt to prove this is a unsecure
2156 nsecvalidate(dns_validator_t
*val
, isc_boolean_t resume
) {
2158 dns_message_t
*message
= val
->event
->message
;
2159 isc_result_t result
;
2162 result
= dns_message_firstname(message
, DNS_SECTION_AUTHORITY
);
2164 result
= ISC_R_SUCCESS
;
2165 validator_log(val
, ISC_LOG_DEBUG(3), "resuming nsecvalidate");
2169 result
== ISC_R_SUCCESS
;
2170 result
= dns_message_nextname(message
, DNS_SECTION_AUTHORITY
))
2172 dns_rdataset_t
*rdataset
= NULL
, *sigrdataset
= NULL
;
2175 dns_message_currentname(message
, DNS_SECTION_AUTHORITY
, &name
);
2177 rdataset
= ISC_LIST_NEXT(val
->currentset
, link
);
2178 val
->currentset
= NULL
;
2181 rdataset
= ISC_LIST_HEAD(name
->list
);
2185 rdataset
= ISC_LIST_NEXT(rdataset
, link
))
2187 if (rdataset
->type
== dns_rdatatype_rrsig
)
2190 for (sigrdataset
= ISC_LIST_HEAD(name
->list
);
2191 sigrdataset
!= NULL
;
2192 sigrdataset
= ISC_LIST_NEXT(sigrdataset
,
2195 if (sigrdataset
->type
== dns_rdatatype_rrsig
&&
2196 sigrdataset
->covers
== rdataset
->type
)
2200 * If a signed zone is missing the zone key, bad
2201 * things could happen. A query for data in the zone
2202 * would lead to a query for the zone key, which
2203 * would return a negative answer, which would contain
2204 * an SOA and an NSEC signed by the missing key, which
2205 * would trigger another query for the DNSKEY (since
2206 * the first one is still in progress), and go into an
2207 * infinite loop. Avoid that.
2209 if (val
->event
->type
== dns_rdatatype_dnskey
&&
2210 dns_name_equal(name
, val
->event
->name
))
2212 dns_rdata_t nsec
= DNS_RDATA_INIT
;
2214 if (rdataset
->type
!= dns_rdatatype_nsec
)
2217 result
= dns_rdataset_first(rdataset
);
2218 if (result
!= ISC_R_SUCCESS
)
2220 dns_rdataset_current(rdataset
, &nsec
);
2221 if (dns_nsec_typepresent(&nsec
,
2225 val
->currentset
= rdataset
;
2226 result
= create_validator(val
, name
, rdataset
->type
,
2227 rdataset
, sigrdataset
,
2230 if (result
!= ISC_R_SUCCESS
)
2232 return (DNS_R_WAIT
);
2236 if (result
== ISC_R_NOMORE
)
2237 result
= ISC_R_SUCCESS
;
2238 if (result
!= ISC_R_SUCCESS
)
2242 * Do we only need to check for NOQNAME? To get here we must have
2243 * had a secure wildcard answer.
2245 if ((val
->attributes
& VALATTR_NEEDNODATA
) == 0 &&
2246 (val
->attributes
& VALATTR_NEEDNOWILDCARD
) == 0 &&
2247 (val
->attributes
& VALATTR_NEEDNOQNAME
) != 0) {
2248 if ((val
->attributes
& VALATTR_FOUNDNOQNAME
) != 0) {
2249 validator_log(val
, ISC_LOG_DEBUG(3),
2250 "noqname proof found");
2251 validator_log(val
, ISC_LOG_DEBUG(3),
2252 "marking as secure");
2253 val
->event
->rdataset
->trust
= dns_trust_secure
;
2254 val
->event
->sigrdataset
->trust
= dns_trust_secure
;
2255 return (ISC_R_SUCCESS
);
2257 validator_log(val
, ISC_LOG_DEBUG(3),
2258 "noqname proof not found");
2259 return (DNS_R_NOVALIDNSEC
);
2263 * Do we need to check for the wildcard?
2265 if ((val
->attributes
& VALATTR_FOUNDNOQNAME
) != 0 &&
2266 (((val
->attributes
& VALATTR_NEEDNODATA
) != 0 &&
2267 (val
->attributes
& VALATTR_FOUNDNODATA
) == 0) ||
2268 (val
->attributes
& VALATTR_NEEDNOWILDCARD
) != 0)) {
2269 result
= checkwildcard(val
);
2270 if (result
!= ISC_R_SUCCESS
)
2274 if (((val
->attributes
& VALATTR_NEEDNODATA
) != 0 &&
2275 (val
->attributes
& VALATTR_FOUNDNODATA
) != 0) ||
2276 ((val
->attributes
& VALATTR_NEEDNOQNAME
) != 0 &&
2277 (val
->attributes
& VALATTR_FOUNDNOQNAME
) != 0 &&
2278 (val
->attributes
& VALATTR_NEEDNOWILDCARD
) != 0 &&
2279 (val
->attributes
& VALATTR_FOUNDNOWILDCARD
) != 0)) {
2280 validator_log(val
, ISC_LOG_DEBUG(3),
2281 "nonexistence proof(s) found");
2282 return (ISC_R_SUCCESS
);
2285 validator_log(val
, ISC_LOG_DEBUG(3),
2286 "nonexistence proof(s) not found");
2287 val
->attributes
|= VALATTR_INSECURITY
;
2288 return (proveunsecure(val
, ISC_FALSE
, ISC_FALSE
));
2291 static isc_boolean_t
2292 check_ds(dns_validator_t
*val
, dns_name_t
*name
, dns_rdataset_t
*rdataset
) {
2293 dns_rdata_t dsrdata
= DNS_RDATA_INIT
;
2295 isc_result_t result
;
2297 for (result
= dns_rdataset_first(rdataset
);
2298 result
== ISC_R_SUCCESS
;
2299 result
= dns_rdataset_next(rdataset
)) {
2300 dns_rdataset_current(rdataset
, &dsrdata
);
2301 result
= dns_rdata_tostruct(&dsrdata
, &ds
, NULL
);
2302 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
2304 if (dns_resolver_digest_supported(val
->view
->resolver
,
2306 dns_resolver_algorithm_supported(val
->view
->resolver
,
2307 name
, ds
.algorithm
)) {
2308 dns_rdata_reset(&dsrdata
);
2311 dns_rdata_reset(&dsrdata
);
2317 * Callback from fetching a DLV record.
2319 * Resumes the DLV lookup process.
2322 dlvfetched(isc_task_t
*task
, isc_event_t
*event
) {
2323 char namebuf
[DNS_NAME_FORMATSIZE
];
2324 dns_fetchevent_t
*devent
;
2325 dns_validator_t
*val
;
2326 isc_boolean_t want_destroy
;
2327 isc_result_t eresult
;
2328 isc_result_t result
;
2331 INSIST(event
->ev_type
== DNS_EVENT_FETCHDONE
);
2332 devent
= (dns_fetchevent_t
*)event
;
2333 val
= devent
->ev_arg
;
2334 eresult
= devent
->result
;
2336 /* Free resources which are not of interest. */
2337 if (devent
->node
!= NULL
)
2338 dns_db_detachnode(devent
->db
, &devent
->node
);
2339 if (devent
->db
!= NULL
)
2340 dns_db_detach(&devent
->db
);
2341 if (dns_rdataset_isassociated(&val
->fsigrdataset
))
2342 dns_rdataset_disassociate(&val
->fsigrdataset
);
2343 isc_event_free(&event
);
2344 dns_resolver_destroyfetch(&val
->fetch
);
2346 INSIST(val
->event
!= NULL
);
2347 validator_log(val
, ISC_LOG_DEBUG(3), "in dlvfetched: %s",
2348 dns_result_totext(eresult
));
2351 if (eresult
== ISC_R_SUCCESS
) {
2352 dns_name_format(dns_fixedname_name(&val
->dlvsep
), namebuf
,
2354 dns_rdataset_clone(&val
->frdataset
, &val
->dlv
);
2355 val
->havedlvsep
= ISC_TRUE
;
2356 if (dlv_algorithm_supported(val
)) {
2357 validator_log(val
, ISC_LOG_DEBUG(3), "DLV %s found",
2359 dlv_validator_start(val
);
2361 validator_log(val
, ISC_LOG_DEBUG(3),
2362 "DLV %s found with no supported algorithms",
2365 validator_done(val
, ISC_R_SUCCESS
);
2367 } else if (eresult
== DNS_R_NXRRSET
||
2368 eresult
== DNS_R_NXDOMAIN
||
2369 eresult
== DNS_R_NCACHENXRRSET
||
2370 eresult
== DNS_R_NCACHENXDOMAIN
) {
2371 result
= finddlvsep(val
, ISC_TRUE
);
2372 if (result
== ISC_R_SUCCESS
) {
2373 if (dlv_algorithm_supported(val
)) {
2374 dns_name_format(dns_fixedname_name(&val
->dlvsep
),
2375 namebuf
, sizeof(namebuf
));
2376 validator_log(val
, ISC_LOG_DEBUG(3),
2377 "DLV %s found", namebuf
);
2378 dlv_validator_start(val
);
2380 validator_log(val
, ISC_LOG_DEBUG(3),
2381 "DLV %s found with no supported "
2382 "algorithms", namebuf
);
2384 validator_done(val
, ISC_R_SUCCESS
);
2386 } else if (result
== ISC_R_NOTFOUND
) {
2387 validator_log(val
, ISC_LOG_DEBUG(3), "DLV not found");
2389 validator_done(val
, ISC_R_SUCCESS
);
2391 validator_log(val
, ISC_LOG_DEBUG(3), "DLV lookup: %s",
2392 dns_result_totext(result
));
2393 if (result
!= DNS_R_WAIT
)
2394 validator_done(val
, result
);
2397 validator_log(val
, ISC_LOG_DEBUG(3), "DLV lookup: %s",
2398 dns_result_totext(eresult
));
2399 validator_done(val
, eresult
);
2401 want_destroy
= exit_check(val
);
2408 * Start the DLV lookup process.
2413 * \li Others on validation failures.
2416 startfinddlvsep(dns_validator_t
*val
, dns_name_t
*unsecure
) {
2417 char namebuf
[DNS_NAME_FORMATSIZE
];
2418 isc_result_t result
;
2420 INSIST(!DLVTRIED(val
));
2422 val
->attributes
|= VALATTR_DLVTRIED
;
2424 dns_name_format(unsecure
, namebuf
, sizeof(namebuf
));
2425 validator_log(val
, ISC_LOG_DEBUG(3),
2426 "plain DNSSEC returns unsecure (%s): looking for DLV",
2429 if (dns_name_issubdomain(val
->event
->name
, val
->view
->dlv
)) {
2430 validator_log(val
, ISC_LOG_WARNING
, "must be secure failure");
2431 return (DNS_R_MUSTBESECURE
);
2434 val
->dlvlabels
= dns_name_countlabels(unsecure
) - 1;
2435 result
= finddlvsep(val
, ISC_FALSE
);
2436 if (result
== ISC_R_NOTFOUND
) {
2437 validator_log(val
, ISC_LOG_DEBUG(3), "DLV not found");
2439 return (ISC_R_SUCCESS
);
2441 if (result
!= ISC_R_SUCCESS
) {
2442 validator_log(val
, ISC_LOG_DEBUG(3), "DLV lookup: %s",
2443 dns_result_totext(result
));
2446 dns_name_format(dns_fixedname_name(&val
->dlvsep
), namebuf
,
2448 if (dlv_algorithm_supported(val
)) {
2449 validator_log(val
, ISC_LOG_DEBUG(3), "DLV %s found", namebuf
);
2450 dlv_validator_start(val
);
2451 return (DNS_R_WAIT
);
2453 validator_log(val
, ISC_LOG_DEBUG(3), "DLV %s found with no supported "
2454 "algorithms", namebuf
);
2456 validator_done(val
, ISC_R_SUCCESS
);
2457 return (ISC_R_SUCCESS
);
2461 * Continue the DLV lookup process.
2465 * \li ISC_R_NOTFOUND
2467 * \li Others on validation failure.
2470 finddlvsep(dns_validator_t
*val
, isc_boolean_t resume
) {
2471 char namebuf
[DNS_NAME_FORMATSIZE
];
2472 dns_fixedname_t dlvfixed
;
2473 dns_name_t
*dlvname
;
2476 isc_result_t result
;
2477 unsigned int labels
;
2479 INSIST(val
->view
->dlv
!= NULL
);
2483 if (dns_name_issubdomain(val
->event
->name
, val
->view
->dlv
)) {
2484 validator_log(val
, ISC_LOG_WARNING
,
2485 "must be secure failure");
2486 return (DNS_R_MUSTBESECURE
);
2489 dns_fixedname_init(&val
->dlvsep
);
2490 dlvsep
= dns_fixedname_name(&val
->dlvsep
);
2491 dns_name_copy(val
->event
->name
, dlvsep
, NULL
);
2493 * If this is a response to a DS query, we need to look in
2494 * the parent zone for the trust anchor.
2496 if (val
->event
->type
== dns_rdatatype_ds
) {
2497 labels
= dns_name_countlabels(dlvsep
);
2499 return (ISC_R_NOTFOUND
);
2500 dns_name_getlabelsequence(dlvsep
, 1, labels
- 1,
2504 dlvsep
= dns_fixedname_name(&val
->dlvsep
);
2505 labels
= dns_name_countlabels(dlvsep
);
2506 dns_name_getlabelsequence(dlvsep
, 1, labels
- 1, dlvsep
);
2508 dns_name_init(&noroot
, NULL
);
2509 dns_fixedname_init(&dlvfixed
);
2510 dlvname
= dns_fixedname_name(&dlvfixed
);
2511 labels
= dns_name_countlabels(dlvsep
);
2513 return (ISC_R_NOTFOUND
);
2514 dns_name_getlabelsequence(dlvsep
, 0, labels
- 1, &noroot
);
2515 result
= dns_name_concatenate(&noroot
, val
->view
->dlv
, dlvname
, NULL
);
2516 while (result
== ISC_R_NOSPACE
) {
2517 labels
= dns_name_countlabels(dlvsep
);
2518 dns_name_getlabelsequence(dlvsep
, 1, labels
- 1, dlvsep
);
2519 dns_name_getlabelsequence(dlvsep
, 0, labels
- 2, &noroot
);
2520 result
= dns_name_concatenate(&noroot
, val
->view
->dlv
,
2523 if (result
!= ISC_R_SUCCESS
) {
2524 validator_log(val
, ISC_LOG_DEBUG(2), "DLV concatenate failed");
2525 return (DNS_R_NOVALIDSIG
);
2528 while (dns_name_countlabels(dlvname
) >=
2529 dns_name_countlabels(val
->view
->dlv
) + val
->dlvlabels
) {
2530 dns_name_format(dlvname
, namebuf
, sizeof(namebuf
));
2531 validator_log(val
, ISC_LOG_DEBUG(3), "looking for DLV %s",
2533 result
= view_find(val
, dlvname
, dns_rdatatype_dlv
);
2534 if (result
== ISC_R_SUCCESS
) {
2535 if (val
->frdataset
.trust
< dns_trust_secure
)
2536 return (DNS_R_NOVALIDSIG
);
2537 val
->havedlvsep
= ISC_TRUE
;
2538 dns_rdataset_clone(&val
->frdataset
, &val
->dlv
);
2539 return (ISC_R_SUCCESS
);
2541 if (result
== ISC_R_NOTFOUND
) {
2542 result
= create_fetch(val
, dlvname
, dns_rdatatype_dlv
,
2543 dlvfetched
, "finddlvsep");
2544 if (result
!= ISC_R_SUCCESS
)
2546 return (DNS_R_WAIT
);
2548 if (result
!= DNS_R_NXRRSET
&&
2549 result
!= DNS_R_NXDOMAIN
&&
2550 result
!= DNS_R_EMPTYNAME
&&
2551 result
!= DNS_R_NCACHENXRRSET
&&
2552 result
!= DNS_R_NCACHENXDOMAIN
)
2555 * Strip first labels from both dlvsep and dlvname.
2557 labels
= dns_name_countlabels(dlvsep
);
2560 dns_name_getlabelsequence(dlvsep
, 1, labels
- 1, dlvsep
);
2561 labels
= dns_name_countlabels(dlvname
);
2562 dns_name_getlabelsequence(dlvname
, 1, labels
- 1, dlvname
);
2564 return (ISC_R_NOTFOUND
);
2568 * proveunsecure walks down from the SEP looking for a break in the
2569 * chain of trust. That occurs when we can prove the DS record does
2570 * not exist at a delegation point or the DS exists at a delegation
2571 * but we don't support the algorithm/digest.
2573 * If DLV is active and we look for a DLV record at or below the
2574 * point we go insecure. If found we restart the validation process.
2575 * If not found or DLV isn't active we mark the response as a answer.
2578 * \li ISC_R_SUCCESS val->event->name is in a unsecure zone
2579 * \li DNS_R_WAIT validation is in progress.
2580 * \li DNS_R_MUSTBESECURE val->event->name is supposed to be secure
2581 * (policy) but we proved that it is unsecure.
2582 * \li DNS_R_NOVALIDSIG
2583 * \li DNS_R_NOVALIDNSEC
2584 * \li DNS_R_NOTINSECURE
2587 proveunsecure(dns_validator_t
*val
, isc_boolean_t have_ds
, isc_boolean_t resume
)
2589 isc_result_t result
;
2590 dns_fixedname_t fixedsecroot
;
2591 dns_name_t
*secroot
;
2593 char namebuf
[DNS_NAME_FORMATSIZE
];
2595 dns_fixedname_init(&fixedsecroot
);
2596 secroot
= dns_fixedname_name(&fixedsecroot
);
2597 if (val
->havedlvsep
)
2598 dns_name_copy(dns_fixedname_name(&val
->dlvsep
), secroot
, NULL
);
2600 dns_name_copy(val
->event
->name
, secroot
, NULL
);
2602 * If this is a response to a DS query, we need to look in
2603 * the parent zone for the trust anchor.
2605 if (val
->event
->type
== dns_rdatatype_ds
&&
2606 dns_name_countlabels(secroot
) > 1U)
2607 dns_name_split(secroot
, 1, NULL
, secroot
);
2608 result
= dns_keytable_finddeepestmatch(val
->keytable
,
2611 if (result
== ISC_R_NOTFOUND
) {
2612 validator_log(val
, ISC_LOG_DEBUG(3),
2613 "not beneath secure root");
2614 if (val
->mustbesecure
) {
2615 validator_log(val
, ISC_LOG_WARNING
,
2616 "must be secure failure");
2617 result
= DNS_R_MUSTBESECURE
;
2620 if (val
->view
->dlv
== NULL
|| DLVTRIED(val
)) {
2622 return (ISC_R_SUCCESS
);
2624 return (startfinddlvsep(val
, dns_rootname
));
2625 } else if (result
!= ISC_R_SUCCESS
)
2631 * We are looking for breaks below the SEP so add a label.
2633 val
->labels
= dns_name_countlabels(secroot
) + 1;
2635 validator_log(val
, ISC_LOG_DEBUG(3), "resuming proveunsecure");
2637 * If we have a DS rdataset and it is secure then check if
2638 * the DS rdataset has a supported algorithm combination.
2639 * If not this is a insecure delegation as far as this
2640 * resolver is concerned. Fall back to DLV if available.
2642 if (have_ds
&& val
->frdataset
.trust
>= dns_trust_secure
&&
2643 !check_ds(val
, dns_fixedname_name(&val
->fname
),
2645 dns_name_format(dns_fixedname_name(&val
->fname
),
2646 namebuf
, sizeof(namebuf
));
2647 if ((val
->view
->dlv
== NULL
|| DLVTRIED(val
)) &&
2648 val
->mustbesecure
) {
2649 validator_log(val
, ISC_LOG_WARNING
,
2650 "must be secure failure at '%s'",
2652 result
= DNS_R_MUSTBESECURE
;
2655 validator_log(val
, ISC_LOG_DEBUG(3),
2656 "no supported algorithm/digest (%s/DS)",
2658 if (val
->view
->dlv
== NULL
|| DLVTRIED(val
)) {
2660 result
= ISC_R_SUCCESS
;
2663 result
= startfinddlvsep(val
,
2664 dns_fixedname_name(&val
->fname
));
2671 val
->labels
<= dns_name_countlabels(val
->event
->name
);
2675 dns_fixedname_init(&val
->fname
);
2676 tname
= dns_fixedname_name(&val
->fname
);
2677 if (val
->labels
== dns_name_countlabels(val
->event
->name
))
2678 dns_name_copy(val
->event
->name
, tname
, NULL
);
2680 dns_name_split(val
->event
->name
, val
->labels
,
2683 dns_name_format(tname
, namebuf
, sizeof(namebuf
));
2684 validator_log(val
, ISC_LOG_DEBUG(3),
2685 "checking existence of DS at '%s'",
2688 result
= view_find(val
, tname
, dns_rdatatype_ds
);
2690 if (result
== DNS_R_NXRRSET
|| result
== DNS_R_NCACHENXRRSET
) {
2692 * There is no DS. If this is a delegation,
2695 if (val
->frdataset
.trust
== dns_trust_pending
) {
2696 result
= create_fetch(val
, tname
,
2700 if (result
!= ISC_R_SUCCESS
)
2702 return (DNS_R_WAIT
);
2704 if (val
->frdataset
.trust
< dns_trust_secure
) {
2706 * This shouldn't happen, since the negative
2707 * response should have been validated. Since
2708 * there's no way of validating existing
2709 * negative response blobs, give up.
2711 result
= DNS_R_NOVALIDSIG
;
2714 if (isdelegation(tname
, &val
->frdataset
, result
)) {
2715 if (val
->mustbesecure
) {
2716 validator_log(val
, ISC_LOG_WARNING
,
2717 "must be secure failure");
2718 return (DNS_R_MUSTBESECURE
);
2720 if (val
->view
->dlv
== NULL
|| DLVTRIED(val
)) {
2722 return (ISC_R_SUCCESS
);
2724 return (startfinddlvsep(val
, tname
));
2727 } else if (result
== ISC_R_SUCCESS
) {
2729 * There is a DS here. Verify that it's secure and
2732 if (val
->frdataset
.trust
>= dns_trust_secure
) {
2733 if (!check_ds(val
, tname
, &val
->frdataset
)) {
2734 validator_log(val
, ISC_LOG_DEBUG(3),
2735 "no supported algorithm/"
2736 "digest (%s/DS)", namebuf
);
2737 if (val
->mustbesecure
) {
2740 "must be secure failure");
2741 result
= DNS_R_MUSTBESECURE
;
2744 if (val
->view
->dlv
== NULL
||
2747 result
= ISC_R_SUCCESS
;
2750 result
= startfinddlvsep(val
, tname
);
2755 else if (!dns_rdataset_isassociated(&val
->fsigrdataset
))
2757 result
= DNS_R_NOVALIDSIG
;
2760 result
= create_validator(val
, tname
, dns_rdatatype_ds
,
2765 if (result
!= ISC_R_SUCCESS
)
2767 return (DNS_R_WAIT
);
2768 } else if (result
== DNS_R_NXDOMAIN
||
2769 result
== DNS_R_NCACHENXDOMAIN
) {
2771 * This is not a zone cut. Assuming things are
2772 * as expected, continue.
2774 if (!dns_rdataset_isassociated(&val
->frdataset
)) {
2776 * There should be an NSEC here, since we
2777 * are still in a secure zone.
2779 result
= DNS_R_NOVALIDNSEC
;
2781 } else if (val
->frdataset
.trust
< dns_trust_secure
) {
2783 * This shouldn't happen, since the negative
2784 * response should have been validated. Since
2785 * there's no way of validating existing
2786 * negative response blobs, give up.
2788 result
= DNS_R_NOVALIDSIG
;
2792 } else if (result
== ISC_R_NOTFOUND
) {
2794 * We don't know anything about the DS. Find it.
2796 result
= create_fetch(val
, tname
, dns_rdatatype_ds
,
2797 dsfetched2
, "proveunsecure");
2798 if (result
!= ISC_R_SUCCESS
)
2800 return (DNS_R_WAIT
);
2803 validator_log(val
, ISC_LOG_DEBUG(3), "insecurity proof failed");
2804 return (DNS_R_NOTINSECURE
); /* Couldn't complete insecurity proof */
2807 if (dns_rdataset_isassociated(&val
->frdataset
))
2808 dns_rdataset_disassociate(&val
->frdataset
);
2809 if (dns_rdataset_isassociated(&val
->fsigrdataset
))
2810 dns_rdataset_disassociate(&val
->fsigrdataset
);
2815 * Reset state and revalidate the answer using DLV.
2818 dlv_validator_start(dns_validator_t
*val
) {
2821 validator_log(val
, ISC_LOG_DEBUG(3), "dlv_validator_start");
2824 * Reset state and try again.
2826 val
->attributes
&= VALATTR_DLVTRIED
;
2827 val
->options
&= ~DNS_VALIDATOR_DLV
;
2829 event
= (isc_event_t
*)val
->event
;
2830 isc_task_send(val
->task
, &event
);
2834 * Start the validation process.
2836 * Attempt to validate the answer based on the category it appears to
2838 * \li 1. secure positive answer.
2839 * \li 2. unsecure positive answer.
2840 * \li 3. a negative answer (secure or unsecure).
2842 * Note a answer that appears to be a secure positive answer may actually
2843 * be a unsecure positive answer.
2846 validator_start(isc_task_t
*task
, isc_event_t
*event
) {
2847 dns_validator_t
*val
;
2848 dns_validatorevent_t
*vevent
;
2849 isc_boolean_t want_destroy
= ISC_FALSE
;
2850 isc_result_t result
= ISC_R_FAILURE
;
2853 REQUIRE(event
->ev_type
== DNS_EVENT_VALIDATORSTART
);
2854 vevent
= (dns_validatorevent_t
*)event
;
2855 val
= vevent
->validator
;
2857 /* If the validator has been canceled, val->event == NULL */
2858 if (val
->event
== NULL
)
2862 validator_log(val
, ISC_LOG_DEBUG(3), "restarting using DLV");
2864 validator_log(val
, ISC_LOG_DEBUG(3), "starting");
2868 if ((val
->options
& DNS_VALIDATOR_DLV
) != 0 &&
2869 val
->event
->rdataset
!= NULL
) {
2870 validator_log(val
, ISC_LOG_DEBUG(3), "looking for DLV");
2871 result
= startfinddlvsep(val
, dns_rootname
);
2872 } else if (val
->event
->rdataset
!= NULL
&&
2873 val
->event
->sigrdataset
!= NULL
) {
2874 isc_result_t saved_result
;
2877 * This looks like a simple validation. We say "looks like"
2878 * because it might end up requiring an insecurity proof.
2880 validator_log(val
, ISC_LOG_DEBUG(3),
2881 "attempting positive response validation");
2883 INSIST(dns_rdataset_isassociated(val
->event
->rdataset
));
2884 INSIST(dns_rdataset_isassociated(val
->event
->sigrdataset
));
2885 result
= start_positive_validation(val
);
2886 if (result
== DNS_R_NOVALIDSIG
&&
2887 (val
->attributes
& VALATTR_TRIEDVERIFY
) == 0)
2889 saved_result
= result
;
2890 validator_log(val
, ISC_LOG_DEBUG(3),
2891 "falling back to insecurity proof");
2892 val
->attributes
|= VALATTR_INSECURITY
;
2893 result
= proveunsecure(val
, ISC_FALSE
, ISC_FALSE
);
2894 if (result
== DNS_R_NOTINSECURE
)
2895 result
= saved_result
;
2897 } else if (val
->event
->rdataset
!= NULL
) {
2899 * This is either an unsecure subdomain or a response from
2902 INSIST(dns_rdataset_isassociated(val
->event
->rdataset
));
2903 validator_log(val
, ISC_LOG_DEBUG(3),
2904 "attempting insecurity proof");
2906 val
->attributes
|= VALATTR_INSECURITY
;
2907 result
= proveunsecure(val
, ISC_FALSE
, ISC_FALSE
);
2908 } else if (val
->event
->rdataset
== NULL
&&
2909 val
->event
->sigrdataset
== NULL
)
2912 * This is a nonexistence validation.
2914 validator_log(val
, ISC_LOG_DEBUG(3),
2915 "attempting negative response validation");
2917 if (val
->event
->message
->rcode
== dns_rcode_nxdomain
) {
2918 val
->attributes
|= VALATTR_NEEDNOQNAME
;
2919 val
->attributes
|= VALATTR_NEEDNOWILDCARD
;
2921 val
->attributes
|= VALATTR_NEEDNODATA
;
2922 result
= nsecvalidate(val
, ISC_FALSE
);
2925 * This shouldn't happen.
2930 if (result
!= DNS_R_WAIT
) {
2931 want_destroy
= exit_check(val
);
2932 validator_done(val
, result
);
2941 dns_validator_create(dns_view_t
*view
, dns_name_t
*name
, dns_rdatatype_t type
,
2942 dns_rdataset_t
*rdataset
, dns_rdataset_t
*sigrdataset
,
2943 dns_message_t
*message
, unsigned int options
,
2944 isc_task_t
*task
, isc_taskaction_t action
, void *arg
,
2945 dns_validator_t
**validatorp
)
2947 isc_result_t result
;
2948 dns_validator_t
*val
;
2950 dns_validatorevent_t
*event
;
2952 REQUIRE(name
!= NULL
);
2953 REQUIRE(rdataset
!= NULL
||
2954 (rdataset
== NULL
&& sigrdataset
== NULL
&& message
!= NULL
));
2955 REQUIRE(validatorp
!= NULL
&& *validatorp
== NULL
);
2958 result
= ISC_R_FAILURE
;
2960 val
= isc_mem_get(view
->mctx
, sizeof(*val
));
2962 return (ISC_R_NOMEMORY
);
2964 dns_view_weakattach(view
, &val
->view
);
2965 event
= (dns_validatorevent_t
*)
2966 isc_event_allocate(view
->mctx
, task
,
2967 DNS_EVENT_VALIDATORSTART
,
2968 validator_start
, NULL
,
2969 sizeof(dns_validatorevent_t
));
2970 if (event
== NULL
) {
2971 result
= ISC_R_NOMEMORY
;
2974 isc_task_attach(task
, &tclone
);
2975 event
->validator
= val
;
2976 event
->result
= ISC_R_FAILURE
;
2979 event
->rdataset
= rdataset
;
2980 event
->sigrdataset
= sigrdataset
;
2981 event
->message
= message
;
2982 memset(event
->proofs
, 0, sizeof(event
->proofs
));
2983 result
= isc_mutex_init(&val
->lock
);
2984 if (result
!= ISC_R_SUCCESS
)
2987 val
->options
= options
;
2988 val
->attributes
= 0;
2990 val
->subvalidator
= NULL
;
2992 val
->keytable
= NULL
;
2993 dns_keytable_attach(val
->view
->secroots
, &val
->keytable
);
2994 val
->keynode
= NULL
;
2996 val
->siginfo
= NULL
;
2998 val
->action
= action
;
3001 val
->currentset
= NULL
;
3004 dns_rdataset_init(&val
->dlv
);
3005 val
->seensig
= ISC_FALSE
;
3006 val
->havedlvsep
= ISC_FALSE
;
3008 val
->mustbesecure
= dns_resolver_getmustbesecure(view
->resolver
, name
);
3009 dns_rdataset_init(&val
->frdataset
);
3010 dns_rdataset_init(&val
->fsigrdataset
);
3011 dns_fixedname_init(&val
->wild
);
3012 ISC_LINK_INIT(val
, link
);
3013 val
->magic
= VALIDATOR_MAGIC
;
3015 if ((options
& DNS_VALIDATOR_DEFER
) == 0)
3016 isc_task_send(task
, ISC_EVENT_PTR(&event
));
3020 return (ISC_R_SUCCESS
);
3023 isc_task_detach(&tclone
);
3024 isc_event_free(ISC_EVENT_PTR(&event
));
3027 dns_view_weakdetach(&val
->view
);
3028 isc_mem_put(view
->mctx
, val
, sizeof(*val
));
3034 dns_validator_send(dns_validator_t
*validator
) {
3036 REQUIRE(VALID_VALIDATOR(validator
));
3038 LOCK(&validator
->lock
);
3040 INSIST((validator
->options
& DNS_VALIDATOR_DEFER
) != 0);
3041 event
= (isc_event_t
*)validator
->event
;
3042 validator
->options
&= ~DNS_VALIDATOR_DEFER
;
3043 UNLOCK(&validator
->lock
);
3045 isc_task_send(validator
->task
, ISC_EVENT_PTR(&event
));
3049 dns_validator_cancel(dns_validator_t
*validator
) {
3050 REQUIRE(VALID_VALIDATOR(validator
));
3052 LOCK(&validator
->lock
);
3054 validator_log(validator
, ISC_LOG_DEBUG(3), "dns_validator_cancel");
3056 if (validator
->event
!= NULL
) {
3057 if (validator
->fetch
!= NULL
)
3058 dns_resolver_cancelfetch(validator
->fetch
);
3060 if (validator
->subvalidator
!= NULL
)
3061 dns_validator_cancel(validator
->subvalidator
);
3062 if ((validator
->options
& DNS_VALIDATOR_DEFER
) != 0) {
3063 isc_task_t
*task
= validator
->event
->ev_sender
;
3064 validator
->options
&= ~DNS_VALIDATOR_DEFER
;
3065 isc_event_free((isc_event_t
**)&validator
->event
);
3066 isc_task_detach(&task
);
3068 validator
->attributes
|= VALATTR_CANCELED
;
3070 UNLOCK(&validator
->lock
);
3074 destroy(dns_validator_t
*val
) {
3077 REQUIRE(SHUTDOWN(val
));
3078 REQUIRE(val
->event
== NULL
);
3079 REQUIRE(val
->fetch
== NULL
);
3081 if (val
->keynode
!= NULL
)
3082 dns_keytable_detachkeynode(val
->keytable
, &val
->keynode
);
3083 else if (val
->key
!= NULL
)
3084 dst_key_free(&val
->key
);
3085 if (val
->keytable
!= NULL
)
3086 dns_keytable_detach(&val
->keytable
);
3087 if (val
->subvalidator
!= NULL
)
3088 dns_validator_destroy(&val
->subvalidator
);
3089 if (val
->havedlvsep
)
3090 dns_rdataset_disassociate(&val
->dlv
);
3091 if (dns_rdataset_isassociated(&val
->frdataset
))
3092 dns_rdataset_disassociate(&val
->frdataset
);
3093 if (dns_rdataset_isassociated(&val
->fsigrdataset
))
3094 dns_rdataset_disassociate(&val
->fsigrdataset
);
3095 mctx
= val
->view
->mctx
;
3096 if (val
->siginfo
!= NULL
)
3097 isc_mem_put(mctx
, val
->siginfo
, sizeof(*val
->siginfo
));
3098 DESTROYLOCK(&val
->lock
);
3099 dns_view_weakdetach(&val
->view
);
3101 isc_mem_put(mctx
, val
, sizeof(*val
));
3105 dns_validator_destroy(dns_validator_t
**validatorp
) {
3106 dns_validator_t
*val
;
3107 isc_boolean_t want_destroy
= ISC_FALSE
;
3109 REQUIRE(validatorp
!= NULL
);
3111 REQUIRE(VALID_VALIDATOR(val
));
3115 val
->attributes
|= VALATTR_SHUTDOWN
;
3116 validator_log(val
, ISC_LOG_DEBUG(3), "dns_validator_destroy");
3118 want_destroy
= exit_check(val
);
3129 validator_logv(dns_validator_t
*val
, isc_logcategory_t
*category
,
3130 isc_logmodule_t
*module
, int level
, const char *fmt
, va_list ap
)
3133 static const char spaces
[] = " *";
3134 int depth
= val
->depth
* 2;
3136 vsnprintf(msgbuf
, sizeof(msgbuf
), fmt
, ap
);
3138 if ((unsigned int) depth
>= sizeof spaces
)
3139 depth
= sizeof spaces
- 1;
3141 if (val
->event
!= NULL
&& val
->event
->name
!= NULL
) {
3142 char namebuf
[DNS_NAME_FORMATSIZE
];
3143 char typebuf
[DNS_RDATATYPE_FORMATSIZE
];
3145 dns_name_format(val
->event
->name
, namebuf
, sizeof(namebuf
));
3146 dns_rdatatype_format(val
->event
->type
, typebuf
,
3148 isc_log_write(dns_lctx
, category
, module
, level
,
3149 "%.*svalidating @%p: %s %s: %s", depth
, spaces
,
3150 val
, namebuf
, typebuf
, msgbuf
);
3152 isc_log_write(dns_lctx
, category
, module
, level
,
3153 "%.*svalidator @%p: %s", depth
, spaces
,
3159 validator_log(dns_validator_t
*val
, int level
, const char *fmt
, ...) {
3162 if (! isc_log_wouldlog(dns_lctx
, level
))
3167 validator_logv(val
, DNS_LOGCATEGORY_DNSSEC
,
3168 DNS_LOGMODULE_VALIDATOR
, level
, fmt
, ap
);
3173 validator_logcreate(dns_validator_t
*val
,
3174 dns_name_t
*name
, dns_rdatatype_t type
,
3175 const char *caller
, const char *operation
)
3177 char namestr
[DNS_NAME_FORMATSIZE
];
3178 char typestr
[DNS_RDATATYPE_FORMATSIZE
];
3180 dns_name_format(name
, namestr
, sizeof(namestr
));
3181 dns_rdatatype_format(type
, typestr
, sizeof(typestr
));
3182 validator_log(val
, ISC_LOG_DEBUG(9), "%s: creating %s for %s %s",
3183 caller
, operation
, namestr
, typestr
);