validator.c revision 93d6dfaf66258337985427c86181f01fc51f0bb4
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley/*
a7038d1a0513c8e804937ebc95fc9cb3a46c04f5Mark Andrews * Copyright (C) 2000-2002 Internet Software Consortium.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley * Permission to use, copy, modify, and distribute this software for any
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley * purpose with or without fee is hereby granted, provided that the above
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley * copyright notice and this permission notice appear in all copies.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
15a44745412679c30a6d022733925af70a38b715David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
15a44745412679c30a6d022733925af70a38b715David Lawrence * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
15a44745412679c30a6d022733925af70a38b715David Lawrence * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
15a44745412679c30a6d022733925af70a38b715David Lawrence * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
15a44745412679c30a6d022733925af70a38b715David Lawrence * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
15a44745412679c30a6d022733925af70a38b715David Lawrence * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15a44745412679c30a6d022733925af70a38b715David Lawrence * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
15a44745412679c30a6d022733925af70a38b715David Lawrence * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley */
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews/* $Id: validator.c,v 1.113 2003/09/30 05:56:14 marka Exp $ */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <config.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/mem.h>
fca5f81ad69098ea8abba130c7f841c951ef91c2Bob Halley#include <isc/print.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <isc/task.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <isc/util.h>
9695ae1c24b168996e3a267855dc754971ccb32cBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#include <dns/db.h>
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews#include <dns/ds.h>
1c776a2909632bc755f3fddd3b53addd792ab4d0Brian Wellington#include <dns/dnssec.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <dns/events.h>
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#include <dns/keytable.h>
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson#include <dns/log.h>
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington#include <dns/message.h>
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews#include <dns/ncache.h>
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews#include <dns/nsec.h>
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#include <dns/rdata.h>
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington#include <dns/rdatastruct.h>
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#include <dns/rdataset.h>
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence#include <dns/rdatatype.h>
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington#include <dns/resolver.h>
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence#include <dns/result.h>
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence#include <dns/validator.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <dns/view.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley
92ef1a9b9dbd48ecb507b42ac62c15afefdaf838David Lawrence#define VALIDATOR_MAGIC ISC_MAGIC('V', 'a', 'l', '?')
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews#define VALID_VALIDATOR(v) ISC_MAGIC_VALID(v, VALIDATOR_MAGIC)
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#define VALATTR_SHUTDOWN 0x01
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington#define VALATTR_FOUNDNONEXISTENCE 0x02
6bc1a645619a14707da68b130dafe41721fd2f25Brian Wellington#define VALATTR_TRIEDVERIFY 0x04
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews#define VALATTR_NEGATIVE 0x08
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews#define VALATTR_INSECURITY 0x10
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#define SHUTDOWN(v) (((v)->attributes & VALATTR_SHUTDOWN) != 0)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrencestatic void
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsdestroy(dns_validator_t *val);
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrence
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic isc_result_t
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrewsget_dst_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo,
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrence dns_rdataset_t *rdataset);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic isc_result_t
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrencevalidate(dns_validator_t *val, isc_boolean_t resume);
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrence
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic isc_result_t
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsvalidatezonekey(dns_validator_t *val, isc_boolean_t resume);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic isc_result_t
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrewsnsecvalidate(dns_validator_t *val, isc_boolean_t resume);
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrence
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic isc_result_t
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrenceproveunsecure(dns_validator_t *val, isc_boolean_t resume);
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrence
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic void
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonvalidator_logv(dns_validator_t *val, isc_logcategory_t *category,
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington isc_logmodule_t *module, int level, const char *fmt, va_list ap)
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington ISC_FORMAT_PRINTF(5, 0);
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrencestatic void
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafssonvalidator_log(dns_validator_t *val, int level, const char *fmt, ...)
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafsson ISC_FORMAT_PRINTF(3, 4);
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic void
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsvalidator_logcreate(dns_validator_t *val,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_name_t *name, dns_rdatatype_t type,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews const char *caller, const char *operation);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleystatic void
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleyvalidator_done(dns_validator_t *val, isc_result_t result) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_task_t *task;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington if (val->event == NULL)
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington return;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /*
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * Caller must be holding the lock.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington val->event->result = result;
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff task = val->event->ev_sender;
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff val->event->ev_sender = val;
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff val->event->ev_type = DNS_EVENT_VALIDATORDONE;
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff val->event->ev_action = val->action;
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff val->event->ev_arg = val->arg;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_task_sendanddetach(&task, (isc_event_t **)&val->event);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley}
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic inline isc_boolean_t
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsexit_check(dns_validator_t *val) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Caller must be holding the lock.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (!SHUTDOWN(val))
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (ISC_FALSE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews INSIST(val->event == NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (val->fetch != NULL || val->subvalidator != NULL)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (ISC_FALSE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (ISC_TRUE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellingtonstatic void
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellingtonauth_nonpending(dns_message_t *message) {
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington isc_result_t result;
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington dns_name_t *name;
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington dns_rdataset_t *rdataset;
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington for (result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington result == ISC_R_SUCCESS;
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington result = dns_message_nextname(message, DNS_SECTION_AUTHORITY))
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington {
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington name = NULL;
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington for (rdataset = ISC_LIST_HEAD(name->list);
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington rdataset != NULL;
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington rdataset = ISC_LIST_NEXT(rdataset, link))
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington {
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington if (rdataset->trust == dns_trust_pending)
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington rdataset->trust = dns_trust_authauthority;
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington }
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington }
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington}
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsstatic isc_boolean_t
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsisdelegation(dns_name_t *name, dns_rdataset_t *rdataset,
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews isc_result_t dbresult)
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews{
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews dns_rdataset_t set;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews isc_boolean_t found;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews isc_result_t result;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews REQUIRE(dbresult == DNS_R_NXRRSET || dbresult == DNS_R_NCACHENXRRSET);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews dns_rdataset_init(&set);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews if (dbresult == DNS_R_NXRRSET)
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews dns_rdataset_clone(rdataset, &set);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews else {
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews result = dns_ncache_getrdataset(rdataset, name,
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_rdatatype_nsec, &set);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews if (result != ISC_R_SUCCESS)
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews return (ISC_FALSE);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews }
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews INSIST(set.type == dns_rdatatype_nsec);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews found = ISC_FALSE;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews result = dns_rdataset_first(&set);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews if (result == ISC_R_SUCCESS) {
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews dns_rdataset_current(&set, &rdata);
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews found = dns_nsec_typepresent(&rdata, dns_rdatatype_ns);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews }
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews dns_rdataset_disassociate(&set);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews return (found);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews}
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellingtonstatic void
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellingtonfetch_callback_validator(isc_task_t *task, isc_event_t *event) {
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington dns_fetchevent_t *devent;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington dns_validator_t *val;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington dns_rdataset_t *rdataset;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_boolean_t want_destroy;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington isc_result_t result;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington isc_result_t eresult;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington UNUSED(task);
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington devent = (dns_fetchevent_t *)event;
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff val = devent->ev_arg;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington rdataset = &val->frdataset;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington eresult = devent->result;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington isc_event_free(&event);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_resolver_destroyfetch(&val->fetch);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington INSIST(val->event != NULL);
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3), "in fetch_callback_validator");
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington LOCK(&val->lock);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (eresult == ISC_R_SUCCESS) {
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington "keyset with trust %d", rdataset->trust);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington /*
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * Only extract the dst key if the keyset is secure.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington */
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (rdataset->trust >= dns_trust_secure) {
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington result = get_dst_key(val, val->siginfo, rdataset);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (result == ISC_R_SUCCESS)
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington val->keyset = &val->frdataset;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington }
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington result = validate(val, ISC_TRUE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result != DNS_R_WAIT)
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington validator_done(val, result);
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington } else {
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson "fetch_callback_validator: got %s",
18b7133679efa8f60fd4e396c628576f3f416b3eBrian Wellington isc_result_totext(eresult));
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington if (eresult == ISC_R_CANCELED)
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington validator_done(val, eresult);
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington else
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington validator_done(val, DNS_R_NOVALIDKEY);
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews want_destroy = exit_check(val);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington UNLOCK(&val->lock);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (want_destroy)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews destroy(val);
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington}
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellingtonstatic void
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsdsfetched(isc_task_t *task, isc_event_t *event) {
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington dns_fetchevent_t *devent;
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington dns_validator_t *val;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_t *rdataset;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_boolean_t want_destroy;
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington isc_result_t result;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington isc_result_t eresult;
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington UNUSED(task);
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington devent = (dns_fetchevent_t *)event;
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington val = devent->ev_arg;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington rdataset = &val->frdataset;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington eresult = devent->result;
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_event_free(&event);
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington dns_resolver_destroyfetch(&val->fetch);
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington INSIST(val->event != NULL);
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched");
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington LOCK(&val->lock);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (eresult == ISC_R_SUCCESS) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews "dsset with trust %d", rdataset->trust);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->dsset = &val->frdataset;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = validatezonekey(val, ISC_TRUE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result != DNS_R_WAIT)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_done(val, result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews } else if (eresult == DNS_R_NXRRSET ||
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews eresult == DNS_R_NCACHENXRRSET)
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews "falling back to insecurity proof");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->attributes |= VALATTR_INSECURITY;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = proveunsecure(val, ISC_FALSE);
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington if (result != DNS_R_WAIT)
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington validator_done(val, result);
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington } else {
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews "dsfetched: got %s",
18b7133679efa8f60fd4e396c628576f3f416b3eBrian Wellington isc_result_totext(eresult));
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington if (eresult == ISC_R_CANCELED)
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington validator_done(val, eresult);
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington else
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_done(val, DNS_R_NOVALIDDS);
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews want_destroy = exit_check(val);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington UNLOCK(&val->lock);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (want_destroy)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews destroy(val);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews/*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * XXX there's too much duplicated code here.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic void
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsdsfetched2(isc_task_t *task, isc_event_t *event) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_fetchevent_t *devent;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_validator_t *val;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_t *rdataset;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews dns_name_t *tname;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_boolean_t want_destroy;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_result_t result;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_result_t eresult;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews UNUSED(task);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews devent = (dns_fetchevent_t *)event;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val = devent->ev_arg;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews rdataset = &val->frdataset;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews eresult = devent->result;
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_resolver_destroyfetch(&val->fetch);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews INSIST(val->event != NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched2");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews LOCK(&val->lock);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (eresult == DNS_R_NXRRSET || eresult == DNS_R_NCACHENXRRSET) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews * There is no DS. If this is a delegation, we're done.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews tname = dns_fixedname_name(&devent->foundname);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews if (isdelegation(tname, &val->frdataset, eresult)) {
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews val->event->rdataset->trust = dns_trust_answer;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews validator_done(val, ISC_R_SUCCESS);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews } else {
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews result = proveunsecure(val, ISC_TRUE);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews if (result != DNS_R_WAIT)
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews validator_done(val, result);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews } else if (eresult == ISC_R_SUCCESS ||
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews eresult == DNS_R_NXDOMAIN ||
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews eresult == DNS_R_NCACHENXDOMAIN)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Either there is a DS or this is not a zone cut. Continue.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = proveunsecure(val, ISC_TRUE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result != DNS_R_WAIT)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_done(val, result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews } else {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (eresult == ISC_R_CANCELED)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_done(val, eresult);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews else
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_done(val, DNS_R_NOVALIDDS);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews isc_event_free(&event);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews want_destroy = exit_check(val);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews UNLOCK(&val->lock);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (want_destroy)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews destroy(val);
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington}
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellingtonstatic void
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellingtonkeyvalidated(isc_task_t *task, isc_event_t *event) {
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington dns_validatorevent_t *devent;
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington dns_validator_t *val;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_boolean_t want_destroy;
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington isc_result_t result;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington isc_result_t eresult;
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington UNUSED(task);
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington devent = (dns_validatorevent_t *)event;
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington val = devent->ev_arg;
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington eresult = devent->result;
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington isc_event_free(&event);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_validator_destroy(&val->subvalidator);
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington INSIST(val->event != NULL);
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3), "in keyvalidated");
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington LOCK(&val->lock);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (eresult == ISC_R_SUCCESS) {
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafsson "keyset with trust %d", val->frdataset.trust);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington /*
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * Only extract the dst key if the keyset is secure.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington */
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (val->frdataset.trust >= dns_trust_secure)
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington (void) get_dst_key(val, val->siginfo, &val->frdataset);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington result = validate(val, ISC_TRUE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result != DNS_R_WAIT)
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington validator_done(val, result);
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington } else {
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson "keyvalidated: got %s",
18b7133679efa8f60fd4e396c628576f3f416b3eBrian Wellington isc_result_totext(eresult));
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington validator_done(val, eresult);
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews want_destroy = exit_check(val);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews UNLOCK(&val->lock);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (want_destroy)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews destroy(val);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic void
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsdsvalidated(isc_task_t *task, isc_event_t *event) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_validatorevent_t *devent;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_validator_t *val;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_boolean_t want_destroy;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_result_t result;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_result_t eresult;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews UNUSED(task);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews devent = (dns_validatorevent_t *)event;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val = devent->ev_arg;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews eresult = devent->result;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_event_free(&event);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_validator_destroy(&val->subvalidator);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews INSIST(val->event != NULL);
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(3), "in dsvalidated");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews LOCK(&val->lock);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (eresult == ISC_R_SUCCESS) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews "dsset with trust %d", val->frdataset.trust);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if ((val->attributes & VALATTR_INSECURITY) != 0)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = proveunsecure(val, ISC_TRUE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews else
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = validatezonekey(val, ISC_TRUE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result != DNS_R_WAIT)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_done(val, result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews } else {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews "dsvalidated: got %s",
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_result_totext(eresult));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_done(val, eresult);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews want_destroy = exit_check(val);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington UNLOCK(&val->lock);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (want_destroy)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews destroy(val);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington}
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellingtonstatic isc_boolean_t
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrewsnsecprovesnonexistence(dns_validator_t *val, dns_name_t *nsecname,
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_rdataset_t *nsecset)
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington{
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington int order;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
c99d9017ba00099bfa89e1ed53e63a5cb07d28d5Mark Andrews isc_boolean_t isnxdomain;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington isc_result_t result;
421e4cf66e4cba0b0751a34a9c027e39fe0474f9Mark Andrews dns_namereln_t relation;
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews unsigned int olabels, nlabels, labels, bits;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
c99d9017ba00099bfa89e1ed53e63a5cb07d28d5Mark Andrews INSIST(DNS_MESSAGE_VALID(val->event->message));
c99d9017ba00099bfa89e1ed53e63a5cb07d28d5Mark Andrews
c99d9017ba00099bfa89e1ed53e63a5cb07d28d5Mark Andrews if (val->event->message->rcode == dns_rcode_nxdomain)
c99d9017ba00099bfa89e1ed53e63a5cb07d28d5Mark Andrews isnxdomain = ISC_TRUE;
c99d9017ba00099bfa89e1ed53e63a5cb07d28d5Mark Andrews else
c99d9017ba00099bfa89e1ed53e63a5cb07d28d5Mark Andrews isnxdomain = ISC_FALSE;
c99d9017ba00099bfa89e1ed53e63a5cb07d28d5Mark Andrews
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews result = dns_rdataset_first(nsecset);
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington if (result != ISC_R_SUCCESS) {
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews "failure processing NSEC set");
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington return (ISC_FALSE);
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington }
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_rdataset_current(nsecset, &rdata);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews validator_log(val, ISC_LOG_DEBUG(3), "looking for relevant nsec");
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews relation = dns_name_fullcompare(val->event->name, nsecname,
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews &order, &olabels, &bits);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (order == 0) {
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington /*
c99d9017ba00099bfa89e1ed53e63a5cb07d28d5Mark Andrews * The names are the same. Look for the type present bit.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington */
c99d9017ba00099bfa89e1ed53e63a5cb07d28d5Mark Andrews if (isnxdomain) {
c99d9017ba00099bfa89e1ed53e63a5cb07d28d5Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews "NSEC record seen at nonexistent name");
c99d9017ba00099bfa89e1ed53e63a5cb07d28d5Mark Andrews return (ISC_FALSE);
c99d9017ba00099bfa89e1ed53e63a5cb07d28d5Mark Andrews }
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (val->event->type >= 128) {
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3), "invalid type %d",
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson val->event->type);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington return (ISC_FALSE);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington }
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (dns_nsec_typepresent(&rdata, val->event->type)) {
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington "type should not be present");
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington return (ISC_FALSE);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington }
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews validator_log(val, ISC_LOG_DEBUG(3), "nsec bitmask ok");
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington } else if (order > 0) {
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_rdata_nsec_t nsec;
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington /*
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews * The NSEC owner name is less than the nonexistent name.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington */
c99d9017ba00099bfa89e1ed53e63a5cb07d28d5Mark Andrews if (!isnxdomain) {
421e4cf66e4cba0b0751a34a9c027e39fe0474f9Mark Andrews /*
421e4cf66e4cba0b0751a34a9c027e39fe0474f9Mark Andrews * Is this a empty node?
421e4cf66e4cba0b0751a34a9c027e39fe0474f9Mark Andrews */
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews result = dns_rdata_tostruct(&rdata, &nsec, NULL);
421e4cf66e4cba0b0751a34a9c027e39fe0474f9Mark Andrews RUNTIME_CHECK(result == ISC_R_SUCCESS);
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews relation = dns_name_fullcompare(&nsec.next,
421e4cf66e4cba0b0751a34a9c027e39fe0474f9Mark Andrews val->event->name,
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews &order, &nlabels,
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews &bits);
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews if (order > 0 && relation == dns_namereln_subdomain) {
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_rdata_freestruct(&nsec);
421e4cf66e4cba0b0751a34a9c027e39fe0474f9Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews "nsec proves empty node, ok");
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews return (ISC_TRUE);
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews }
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews /*
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews * Look for empty wildcard matches.
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews */
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews labels = dns_name_countlabels(&nsec.next);
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews if (nlabels >= olabels && nlabels + 1 < labels) {
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews dns_name_t wild;
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews dns_name_init(&wild, NULL);
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_name_getlabelsequence(&nsec.next,
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews labels - 1 - nlabels,
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews nlabels + 1,
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews &wild);
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews if (dns_name_iswildcard(&wild)) {
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_rdata_freestruct(&nsec);
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews validator_log(val, ISC_LOG_DEBUG(3),
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews "nsec proves empty wildcard, ok");
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews return (ISC_TRUE);
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews }
421e4cf66e4cba0b0751a34a9c027e39fe0474f9Mark Andrews }
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews /*
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews * We are not a empty name.
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews */
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_rdata_freestruct(&nsec);
c99d9017ba00099bfa89e1ed53e63a5cb07d28d5Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews "missing NSEC record at name");
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews return (ISC_FALSE);
c99d9017ba00099bfa89e1ed53e63a5cb07d28d5Mark Andrews }
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (dns_name_issubdomain(val->event->name, nsecname) &&
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_nsec_typepresent(&rdata, dns_rdatatype_ns) &&
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews !dns_nsec_typepresent(&rdata, dns_rdatatype_soa))
638fe804a524ee0c028863c0301b999c79de7651Mark Andrews {
638fe804a524ee0c028863c0301b999c79de7651Mark Andrews /*
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews * This NSEC record is from somewhere higher in
638fe804a524ee0c028863c0301b999c79de7651Mark Andrews * the DNS, and at the parent of a delegation.
638fe804a524ee0c028863c0301b999c79de7651Mark Andrews * It can not be legitimately used here.
638fe804a524ee0c028863c0301b999c79de7651Mark Andrews */
638fe804a524ee0c028863c0301b999c79de7651Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews "ignoring parent nsec");
638fe804a524ee0c028863c0301b999c79de7651Mark Andrews return (ISC_FALSE);
638fe804a524ee0c028863c0301b999c79de7651Mark Andrews }
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews result = dns_rdata_tostruct(&rdata, &nsec, NULL);
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington if (result != ISC_R_SUCCESS)
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington return (ISC_FALSE);
368b37b616234fce3d23099eb180f1dd38e1fb62Mark Andrews dns_rdata_reset(&rdata);
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews relation = dns_name_fullcompare(&nsec.next, val->event->name,
8b5de9701428e2b5eb50aba96af23dc1186124ddMark Andrews &order, &nlabels, &bits);
421e4cf66e4cba0b0751a34a9c027e39fe0474f9Mark Andrews if (order <= 0) {
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington /*
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews * The NSEC next name is less than the nonexistent
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * name. This is only ok if the next name is the zone
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * name.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington */
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (!dns_name_equal(val->soaname, &nsec.next)) {
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington "next name is not greater");
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_rdata_freestruct(&nsec);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington return (ISC_FALSE);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington }
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews "nsec points to zone apex, ok");
421e4cf66e4cba0b0751a34a9c027e39fe0474f9Mark Andrews } else if (relation == dns_namereln_subdomain) {
421e4cf66e4cba0b0751a34a9c027e39fe0474f9Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews "nsec proves empty node, bad");
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_rdata_freestruct(&nsec);
421e4cf66e4cba0b0751a34a9c027e39fe0474f9Mark Andrews return (ISC_FALSE);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington }
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_rdata_freestruct(&nsec);
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews validator_log(val, ISC_LOG_DEBUG(3), "nsec range ok");
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington } else {
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews "nsec owner name is not less");
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington /*
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews * The NSEC owner name is greater than the supposedly
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews * nonexistent name. This NSEC is irrelevant.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington */
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington return (ISC_FALSE);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington }
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington return (ISC_TRUE);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington}
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellingtonstatic void
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellingtonauthvalidated(isc_task_t *task, isc_event_t *event) {
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington dns_validatorevent_t *devent;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington dns_validator_t *val;
e27021ee1f37185ab839a7a3b6bc078c24255e62Brian Wellington dns_rdataset_t *rdataset, *sigrdataset;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_boolean_t want_destroy;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington isc_result_t result;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington UNUSED(task);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington devent = (dns_validatorevent_t *)event;
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington rdataset = devent->rdataset;
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington sigrdataset = devent->sigrdataset;
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington val = devent->ev_arg;
b0d31c78bc24080d4c470a8bd98862375f6e3055Mark Andrews result = devent->result;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_validator_destroy(&val->subvalidator);
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington INSIST(val->event != NULL);
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3), "in authvalidated");
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington LOCK(&val->lock);
b0d31c78bc24080d4c470a8bd98862375f6e3055Mark Andrews if (result != ISC_R_SUCCESS) {
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington "authvalidated: got %s",
b0d31c78bc24080d4c470a8bd98862375f6e3055Mark Andrews isc_result_totext(result));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result == ISC_R_CANCELED)
f15af68028adc665d3bdddf955fc52bad83f0514Brian Wellington validator_done(val, result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews else {
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews result = nsecvalidate(val, ISC_TRUE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result != DNS_R_WAIT)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_done(val, result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington } else {
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (val->soaname != NULL && val->nsecset != NULL &&
86f6b92e35c7bdb5fc1fd1021af75b981863313eMark Andrews (val->attributes & VALATTR_FOUNDNONEXISTENCE) == 0 &&
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews nsecprovesnonexistence(val, devent->name, rdataset))
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington val->attributes |= VALATTR_FOUNDNONEXISTENCE;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews result = nsecvalidate(val, ISC_TRUE);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (result != DNS_R_WAIT)
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington validator_done(val, result);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews want_destroy = exit_check(val);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington UNLOCK(&val->lock);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (want_destroy)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews destroy(val);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington /*
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * Free stuff from the event.
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington */
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington isc_event_free(&event);
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington}
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellingtonstatic void
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellingtonnegauthvalidated(isc_task_t *task, isc_event_t *event) {
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington dns_validatorevent_t *devent;
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington dns_validator_t *val;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_boolean_t want_destroy;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington isc_result_t eresult;
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington UNUSED(task);
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington devent = (dns_validatorevent_t *)event;
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington val = devent->ev_arg;
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington eresult = devent->result;
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington isc_event_free(&event);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_validator_destroy(&val->subvalidator);
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington INSIST(val->event != NULL);
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3), "in negauthvalidated");
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington LOCK(&val->lock);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (eresult == ISC_R_SUCCESS) {
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington val->attributes |= VALATTR_FOUNDNONEXISTENCE;
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington "nonexistence proof found");
98d010a24a9f1b4b45ce9791845941ef90426d0cBrian Wellington auth_nonpending(val->event->message);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington validator_done(val, ISC_R_SUCCESS);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington } else {
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington "negauthvalidated: got %s",
18b7133679efa8f60fd4e396c628576f3f416b3eBrian Wellington isc_result_totext(eresult));
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington validator_done(val, eresult);
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews want_destroy = exit_check(val);
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington UNLOCK(&val->lock);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (want_destroy)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews destroy(val);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic inline isc_result_t
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsview_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (dns_rdataset_isassociated(&val->frdataset))
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_rdataset_disassociate(&val->frdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (dns_rdataset_isassociated(&val->fsigrdataset))
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_disassociate(&val->fsigrdataset);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (val->view->zonetable == NULL)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (ISC_R_CANCELED);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (dns_view_simplefind(val->view, name, type, 0,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews DNS_DBFIND_PENDINGOK, ISC_FALSE,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &val->frdataset, &val->fsigrdataset));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic inline isc_boolean_t
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewscheck_deadlock(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_validator_t *parent;
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews for (parent = val->parent; parent != NULL; parent = parent->parent) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (parent->event != NULL &&
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews parent->event->type == type &&
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_name_equal(parent->event->name, name))
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews "continuing validation would lead to "
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews "deadlock: aborting validation");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (ISC_TRUE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (ISC_FALSE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic inline isc_result_t
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewscreate_fetch(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_taskaction_t callback, const char *caller)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews{
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (dns_rdataset_isassociated(&val->frdataset))
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_rdataset_disassociate(&val->frdataset);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (dns_rdataset_isassociated(&val->fsigrdataset))
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_rdataset_disassociate(&val->fsigrdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (check_deadlock(val, name, type))
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (DNS_R_NOVALIDSIG);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_logcreate(val, name, type, caller, "fetch");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (dns_resolver_createfetch(val->view->resolver, name, type,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews NULL, NULL, NULL, 0,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->event->ev_sender,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews callback, val,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &val->frdataset,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &val->fsigrdataset,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &val->fetch));
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington}
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic inline isc_result_t
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewscreate_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_taskaction_t action, const char *caller)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews{
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington isc_result_t result;
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (check_deadlock(val, name, type))
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (DNS_R_NOVALIDSIG);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_logcreate(val, name, type, caller, "validator");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = dns_validator_create(val->view, name, type,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews rdataset, sigrdataset, NULL, 0,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->task, action, val,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &val->subvalidator);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result == ISC_R_SUCCESS)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->subvalidator->parent = val;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (result);
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington}
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson/*
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson * Try to find a key that could have signed 'siginfo' among those
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson * in 'rdataset'. If found, build a dst_key_t for it and point
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson * val->key at it.
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson *
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington * If val->key is non-NULL, this returns the next matching key.
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson */
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic isc_result_t
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrewsget_dst_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley dns_rdataset_t *rdataset)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley{
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_result_t result;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_buffer_t b;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington dst_key_t *oldkey = val->key;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington isc_boolean_t foundold;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington if (oldkey == NULL)
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington foundold = ISC_TRUE;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington else {
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington foundold = ISC_FALSE;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington val->key = NULL;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley result = dns_rdataset_first(rdataset);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (result != ISC_R_SUCCESS)
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington goto failure;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley do {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley dns_rdataset_current(rdataset, &rdata);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_init(&b, rdata.data, rdata.length);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_buffer_add(&b, rdata.length);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley INSIST(val->key == NULL);
5c29047792191d6141f69b2684314d0b762fedebBrian Wellington result = dst_key_fromdns(&siginfo->signer, rdata.rdclass, &b,
5c29047792191d6141f69b2684314d0b762fedebBrian Wellington val->view->mctx, &val->key);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (result != ISC_R_SUCCESS)
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington goto failure;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (siginfo->algorithm ==
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley (dns_secalg_t)dst_key_alg(val->key) &&
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington siginfo->keyid ==
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley (dns_keytag_t)dst_key_id(val->key) &&
63bf060be4ff2a7ade02fd86abb98694a5afc250Brian Wellington dst_key_iszonekey(val->key))
63bf060be4ff2a7ade02fd86abb98694a5afc250Brian Wellington {
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington if (foundold)
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington /*
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington * This is the key we're looking for.
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington */
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington return (ISC_R_SUCCESS);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington else if (dst_key_compare(oldkey, val->key) == ISC_TRUE)
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington {
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington foundold = ISC_TRUE;
c50936eb40263b65ebf6afe4e6556e2dc67c10e4Brian Wellington dst_key_free(&oldkey);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
c50936eb40263b65ebf6afe4e6556e2dc67c10e4Brian Wellington dst_key_free(&val->key);
368b37b616234fce3d23099eb180f1dd38e1fb62Mark Andrews dns_rdata_reset(&rdata);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley result = dns_rdataset_next(rdataset);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley } while (result == ISC_R_SUCCESS);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (result == ISC_R_NOMORE)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley result = ISC_R_NOTFOUND;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington failure:
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington if (oldkey != NULL)
c50936eb40263b65ebf6afe4e6556e2dc67c10e4Brian Wellington dst_key_free(&oldkey);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (result);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley}
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic isc_result_t
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrewsget_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_result_t result;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley unsigned int nbits, nlabels;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley int order;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley dns_namereln_t namereln;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /*
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington * Is the signer name appropriate for this signature?
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington *
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington * The signer name must be at the same level as the owner name
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington * or closer to the the DNS root.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington namereln = dns_name_fullcompare(val->event->name, &siginfo->signer,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley &order, &nlabels, &nbits);
a9ba7e65644c50e1549b38150ba8d4787e1fe643Brian Wellington if (namereln != dns_namereln_subdomain &&
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington namereln != dns_namereln_equal)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (DNS_R_CONTINUE);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (namereln == dns_namereln_equal) {
78951552dccf0d0004d61072bbc71fa4b1aab30fAndreas Gustafsson /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * If this is a self-signed keyset, it must not be a zone key
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * (since get_key is not called from validatezonekey).
78951552dccf0d0004d61072bbc71fa4b1aab30fAndreas Gustafsson */
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (val->event->rdataset->type == dns_rdatatype_dnskey)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (DNS_R_CONTINUE);
78951552dccf0d0004d61072bbc71fa4b1aab30fAndreas Gustafsson
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Records appearing in the parent zone at delegation
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * points cannot be self-signed.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (dns_rdatatype_atparent(val->event->rdataset->type))
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (DNS_R_CONTINUE);
a9ba7e65644c50e1549b38150ba8d4787e1fe643Brian Wellington }
a9ba7e65644c50e1549b38150ba8d4787e1fe643Brian Wellington
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /*
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * Do we know about this key?
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews result = view_find(val, &siginfo->signer, dns_rdatatype_dnskey);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (result == ISC_R_SUCCESS) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /*
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * We have an rrset for the given keyname.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
77c67dfb2607618f5e7940486daebafd42a502abBrian Wellington val->keyset = &val->frdataset;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (val->frdataset.trust == dns_trust_pending &&
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_rdataset_isassociated(&val->fsigrdataset))
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /*
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * We know the key but haven't validated it yet.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = create_validator(val, &siginfo->signer,
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_rdatatype_dnskey,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &val->frdataset,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &val->fsigrdataset,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews keyvalidated,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews "get_key");
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington if (result != ISC_R_SUCCESS)
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington return (result);
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington return (DNS_R_WAIT);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington } else if (val->frdataset.trust == dns_trust_pending) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /*
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington * Having a pending key with no signature means that
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington * something is broken.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington result = DNS_R_CONTINUE;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington } else if (val->frdataset.trust < dns_trust_secure) {
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington /*
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington * The key is legitimately insecure. There's no
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington * point in even attempting verification.
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington */
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington val->key = NULL;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington result = ISC_R_SUCCESS;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington } else {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /*
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * See if we've got the key used in the signature.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington "keyset with trust %d",
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington val->frdataset.trust);
77c67dfb2607618f5e7940486daebafd42a502abBrian Wellington result = get_dst_key(val, siginfo, val->keyset);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (result != ISC_R_SUCCESS) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /*
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * Either the key we're looking for is not
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * in the rrset, or something bad happened.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * Give up.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley result = DNS_R_CONTINUE;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley } else if (result == ISC_R_NOTFOUND) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /*
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * We don't know anything about this key.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews result = create_fetch(val, &siginfo->signer, dns_rdatatype_dnskey,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews fetch_callback_validator, "get_key");
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington if (result != ISC_R_SUCCESS)
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington return (result);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington return (DNS_R_WAIT);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley } else if (result == DNS_R_NCACHENXDOMAIN ||
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley result == DNS_R_NCACHENXRRSET ||
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley result == DNS_R_NXDOMAIN ||
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington result == DNS_R_NXRRSET)
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /*
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * This key doesn't exist.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley result = DNS_R_CONTINUE;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
77c67dfb2607618f5e7940486daebafd42a502abBrian Wellington if (dns_rdataset_isassociated(&val->frdataset) &&
77c67dfb2607618f5e7940486daebafd42a502abBrian Wellington val->keyset != &val->frdataset)
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_rdataset_disassociate(&val->frdataset);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (dns_rdataset_isassociated(&val->fsigrdataset))
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_rdataset_disassociate(&val->fsigrdataset);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (result);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley}
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic dns_keytag_t
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrewscompute_keytag(dns_rdata_t *rdata, dns_rdata_dnskey_t *key) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_region_t r;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdata_toregion(rdata, &r);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (dst_region_computeid(&r, key->algorithm));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington/*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Is this keyset self-signed?
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington */
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellingtonstatic isc_boolean_t
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsisselfsigned(dns_validator_t *val) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_t *rdataset, *sigrdataset;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdata_t sigrdata = DNS_RDATA_INIT;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_rdata_dnskey_t key;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_rdata_rrsig_t sig;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_keytag_t keytag;
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington isc_result_t result;
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington rdataset = val->event->rdataset;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews sigrdataset = val->event->sigrdataset;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews INSIST(rdataset->type == dns_rdatatype_dnskey);
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington for (result = dns_rdataset_first(rdataset);
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington result == ISC_R_SUCCESS;
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington result = dns_rdataset_next(rdataset))
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington {
368b37b616234fce3d23099eb180f1dd38e1fb62Mark Andrews dns_rdata_reset(&rdata);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_current(rdataset, &rdata);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews (void)dns_rdata_tostruct(&rdata, &key, NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews keytag = compute_keytag(&rdata, &key);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews for (result = dns_rdataset_first(sigrdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result == ISC_R_SUCCESS;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = dns_rdataset_next(sigrdataset))
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdata_reset(&sigrdata);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_current(sigrdataset, &sigrdata);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews (void)dns_rdata_tostruct(&sigrdata, &sig, NULL);
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (sig.algorithm == key.algorithm &&
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews sig.keyid == keytag)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (ISC_TRUE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (ISC_FALSE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic isc_result_t
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsverify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_result_t result;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->attributes |= VALATTR_TRIEDVERIFY;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = dns_dnssec_verify(val->event->name, val->event->rdataset,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews key, ISC_FALSE, val->view->mctx, rdata);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews "verify rdataset: %s",
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_result_totext(result));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (result);
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington}
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington
3ce4b8b03ebd017c1d1b320429219ba91e705ea4Andreas Gustafsson/*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Attempts positive response validation of a normal RRset.
3ce4b8b03ebd017c1d1b320429219ba91e705ea4Andreas Gustafsson *
3ce4b8b03ebd017c1d1b320429219ba91e705ea4Andreas Gustafsson * Returns:
3ce4b8b03ebd017c1d1b320429219ba91e705ea4Andreas Gustafsson * ISC_R_SUCCESS Validation completed successfully
3ce4b8b03ebd017c1d1b320429219ba91e705ea4Andreas Gustafsson * DNS_R_WAIT Validation has started but is waiting
3ce4b8b03ebd017c1d1b320429219ba91e705ea4Andreas Gustafsson * for an event.
3ce4b8b03ebd017c1d1b320429219ba91e705ea4Andreas Gustafsson * Other return codes are possible and all indicate failure.
3ce4b8b03ebd017c1d1b320429219ba91e705ea4Andreas Gustafsson */
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic isc_result_t
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleyvalidate(dns_validator_t *val, isc_boolean_t resume) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_result_t result;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley dns_validatorevent_t *event;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /*
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * Caller must be holding the validator lock.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley event = val->event;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson if (resume) {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence /*
78951552dccf0d0004d61072bbc71fa4b1aab30fAndreas Gustafsson * We already have a sigrdataset.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence */
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson result = ISC_R_SUCCESS;
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3), "resuming validate");
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson } else {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley result = dns_rdataset_first(event->sigrdataset);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson for (;
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson result == ISC_R_SUCCESS;
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson result = dns_rdataset_next(event->sigrdataset))
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson {
368b37b616234fce3d23099eb180f1dd38e1fb62Mark Andrews dns_rdata_reset(&rdata);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley dns_rdataset_current(event->sigrdataset, &rdata);
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington if (val->siginfo == NULL) {
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington val->siginfo = isc_mem_get(val->view->mctx,
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington sizeof(*val->siginfo));
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington if (val->siginfo == NULL)
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington return (ISC_R_NOMEMORY);
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington }
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson result = dns_rdata_tostruct(&rdata, val->siginfo, NULL);
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson if (result != ISC_R_SUCCESS)
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson return (result);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /*
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * At this point we could check that the signature algorithm
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * was known and "sufficiently good". For now, any algorithm
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * is acceptable.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (!resume) {
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington result = get_key(val, val->siginfo);
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson if (result == DNS_R_CONTINUE)
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson continue; /* Try the next SIG RR. */
0a3e2e1d590dac7fb011e72bd3a4982c179d8e68Brian Wellington if (result != ISC_R_SUCCESS)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (result);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington /*
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington * The key is insecure, so mark the data as insecure also.
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington */
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington if (val->key == NULL) {
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington event->rdataset->trust = dns_trust_answer;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington event->sigrdataset->trust = dns_trust_answer;
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington "marking as answer");
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington return (ISC_R_SUCCESS);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington }
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellington do {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = verify(val, val->key, &rdata);
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellington if (result == ISC_R_SUCCESS)
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellington break;
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellington if (val->keynode != NULL) {
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington dns_keynode_t *nextnode = NULL;
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington result = dns_keytable_findnextkeynode(
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington val->keytable,
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington val->keynode,
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington &nextnode);
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington dns_keytable_detachkeynode(val->keytable,
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington &val->keynode);
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington val->keynode = nextnode;
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington if (result != ISC_R_SUCCESS) {
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington val->key = NULL;
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellington break;
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington }
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellington val->key = dns_keynode_key(val->keynode);
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington } else {
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington if (get_dst_key(val, val->siginfo, val->keyset)
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellington != ISC_R_SUCCESS)
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellington break;
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington }
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellington } while (1);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington if (result != ISC_R_SUCCESS)
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington "failed to verify rdataset");
75f6c57d9544aa77a3b1a04587b4702c07343c90Brian Wellington else {
75f6c57d9544aa77a3b1a04587b4702c07343c90Brian Wellington isc_uint32_t ttl;
75f6c57d9544aa77a3b1a04587b4702c07343c90Brian Wellington isc_stdtime_t now;
75f6c57d9544aa77a3b1a04587b4702c07343c90Brian Wellington
75f6c57d9544aa77a3b1a04587b4702c07343c90Brian Wellington isc_stdtime_get(&now);
75f6c57d9544aa77a3b1a04587b4702c07343c90Brian Wellington ttl = ISC_MIN(event->rdataset->ttl,
75f6c57d9544aa77a3b1a04587b4702c07343c90Brian Wellington val->siginfo->timeexpire - now);
75f6c57d9544aa77a3b1a04587b4702c07343c90Brian Wellington if (val->keyset != NULL)
75f6c57d9544aa77a3b1a04587b4702c07343c90Brian Wellington ttl = ISC_MIN(ttl, val->keyset->ttl);
75f6c57d9544aa77a3b1a04587b4702c07343c90Brian Wellington event->rdataset->ttl = ttl;
75f6c57d9544aa77a3b1a04587b4702c07343c90Brian Wellington event->sigrdataset->ttl = ttl;
75f6c57d9544aa77a3b1a04587b4702c07343c90Brian Wellington }
75f6c57d9544aa77a3b1a04587b4702c07343c90Brian Wellington
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington if (val->keynode != NULL)
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington dns_keytable_detachkeynode(val->keytable,
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington &val->keynode);
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington else {
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington if (val->key != NULL)
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington dst_key_free(&val->key);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (val->keyset != NULL) {
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_rdataset_disassociate(val->keyset);
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington val->keyset = NULL;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington }
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington }
187604c1adfe841d909d4a8453b6900e652f7f6dBrian Wellington val->key = NULL;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington if (result == ISC_R_SUCCESS) {
538fea1c91c68c0a5569c7b8552c8fd0490055efBrian Wellington event->rdataset->trust = dns_trust_secure;
538fea1c91c68c0a5569c7b8552c8fd0490055efBrian Wellington event->sigrdataset->trust = dns_trust_secure;
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington "marking as secure");
538fea1c91c68c0a5569c7b8552c8fd0490055efBrian Wellington return (result);
25276bd1ecb372b82c9235648e5defab0655dcd5Mark Andrews } else {
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
777ac454c0cdec27dc11d80b9b2a8d7239d833a8Brian Wellington "verify failure: %s",
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington isc_result_totext(result));
25276bd1ecb372b82c9235648e5defab0655dcd5Mark Andrews resume = ISC_FALSE;
25276bd1ecb372b82c9235648e5defab0655dcd5Mark Andrews }
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson }
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington if (result != ISC_R_NOMORE) {
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington "failed to iterate signatures: %s",
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington isc_result_totext(result));
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington return (result);
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington }
e1f16346db02486f751c6db683fffe53c866c186Andreas Gustafsson
e1f16346db02486f751c6db683fffe53c866c186Andreas Gustafsson validator_log(val, ISC_LOG_INFO, "no valid signature found");
e1f16346db02486f751c6db683fffe53c866c186Andreas Gustafsson return (DNS_R_NOVALIDSIG);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley}
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews/*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Attempts positive response validation of an RRset containing zone keys.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews *
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Returns:
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * ISC_R_SUCCESS Validation completed successfully
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * DNS_R_WAIT Validation has started but is waiting
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * for an event.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Other return codes are possible and all indicate failure.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic isc_result_t
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsvalidatezonekey(dns_validator_t *val, isc_boolean_t resume) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_result_t result;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_validatorevent_t *event;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_t trdataset;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdata_t dsrdata = DNS_RDATA_INIT;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdata_t newdsrdata = DNS_RDATA_INIT;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdata_t keyrdata = DNS_RDATA_INIT;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdata_t sigrdata = DNS_RDATA_INIT;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned char dsbuf[DNS_DS_BUFFERSIZE];
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_keytag_t keytag;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdata_ds_t ds;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_rdata_dnskey_t key;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_rdata_rrsig_t sig;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dst_key_t *dstkey;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews UNUSED(resume);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Caller must be holding the validator lock.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews event = val->event;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (val->dsset == NULL) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * First, see if this key was signed by a trusted key.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews for (result = dns_rdataset_first(val->event->sigrdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result == ISC_R_SUCCESS;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = dns_rdataset_next(val->event->sigrdataset))
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_keynode_t *keynode = NULL, *nextnode = NULL;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdata_reset(&sigrdata);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_current(val->event->sigrdataset,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &sigrdata);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews (void)dns_rdata_tostruct(&sigrdata, &sig, NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = dns_keytable_findkeynode(val->keytable,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->event->name,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews sig.algorithm,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews sig.keyid,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &keynode);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews while (result == ISC_R_SUCCESS) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dstkey = dns_keynode_key(keynode);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = verify(val, dstkey, &sigrdata);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result == ISC_R_SUCCESS) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_keytable_detachkeynode(val->keytable,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &keynode);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews break;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = dns_keytable_findnextkeynode(
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->keytable,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews keynode,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &nextnode);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_keytable_detachkeynode(val->keytable,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &keynode);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews keynode = nextnode;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result == ISC_R_SUCCESS) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews event->rdataset->trust = dns_trust_secure;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews event->sigrdataset->trust = dns_trust_secure;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews "signed by trusted key; "
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews "marking as secure");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * If this is the root name and there was no trusted key,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * give up, since there's no DS at the root.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (dns_name_equal(event->name, dns_rootname)) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if ((val->attributes & VALATTR_TRIEDVERIFY) != 0)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (DNS_R_NOVALIDSIG);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews else
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (DNS_R_NOVALIDDS);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Otherwise, try to find the DS record.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = view_find(val, val->event->name, dns_rdatatype_ds);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result == ISC_R_SUCCESS) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * We have DS records.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->dsset = &val->frdataset;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (val->frdataset.trust == dns_trust_pending &&
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_isassociated(&val->fsigrdataset))
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = create_validator(val,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->event->name,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdatatype_ds,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &val->frdataset,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &val->fsigrdataset,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dsvalidated,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews "validatezonekey");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result != ISC_R_SUCCESS)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (DNS_R_WAIT);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews } else if (val->frdataset.trust == dns_trust_pending) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * There should never be an unsigned DS.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_disassociate(&val->frdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(2),
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews "unsigned DS record");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (DNS_R_NOVALIDSIG);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews } else
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = ISC_R_SUCCESS;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews } else if (result == ISC_R_NOTFOUND) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * We don't have the DS. Find it.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = create_fetch(val, val->event->name,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdatatype_ds, dsfetched,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews "validatezonekey");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result != ISC_R_SUCCESS)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (DNS_R_WAIT);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews } else if (result == DNS_R_NCACHENXDOMAIN ||
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result == DNS_R_NCACHENXRRSET ||
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result == DNS_R_NXDOMAIN ||
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result == DNS_R_NXRRSET)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * The DS does not exist.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (dns_rdataset_isassociated(&val->frdataset))
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_disassociate(&val->frdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (dns_rdataset_isassociated(&val->fsigrdataset))
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_disassociate(&val->fsigrdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(2), "no DS record");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (DNS_R_NOVALIDSIG);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * We have a DS set.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews INSIST(val->dsset != NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (val->dsset->trust < dns_trust_secure) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->event->rdataset->trust = dns_trust_answer;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->event->sigrdataset->trust = dns_trust_answer;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (ISC_R_SUCCESS);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Look through the DS record and find the keys that can sign the
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * key set and the matching signature. For each such key, attempt
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * verification.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews for (result = dns_rdataset_first(val->dsset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result == ISC_R_SUCCESS;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = dns_rdataset_next(val->dsset))
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdata_reset(&dsrdata);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_current(val->dsset, &dsrdata);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews (void)dns_rdata_tostruct(&dsrdata, &ds, NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_init(&trdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_clone(val->event->rdataset, &trdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews for (result = dns_rdataset_first(&trdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result == ISC_R_SUCCESS;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = dns_rdataset_next(&trdataset))
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdata_reset(&keyrdata);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_current(&trdataset, &keyrdata);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews (void)dns_rdata_tostruct(&keyrdata, &key, NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews keytag = compute_keytag(&keyrdata, &key);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (ds.key_tag != keytag ||
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ds.algorithm != key.algorithm)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews continue;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdata_reset(&newdsrdata);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = dns_ds_buildrdata(val->event->name,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &keyrdata, ds.digest_type,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dsbuf, &newdsrdata);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result != ISC_R_SUCCESS)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews continue;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (dns_rdata_compare(&dsrdata, &newdsrdata) == 0)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews break;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result != ISC_R_SUCCESS) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews "no KEY matching DS");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews continue;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews for (result = dns_rdataset_first(val->event->sigrdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result == ISC_R_SUCCESS;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = dns_rdataset_next(val->event->sigrdataset))
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdata_reset(&sigrdata);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_current(val->event->sigrdataset,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &sigrdata);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews (void)dns_rdata_tostruct(&sigrdata, &sig, NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (ds.key_tag == sig.keyid &&
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ds.algorithm == sig.algorithm)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews break;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result != ISC_R_SUCCESS) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews "no SIG matching DS key");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews continue;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dstkey = NULL;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = dns_dnssec_keyfromrdata(val->event->name,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &keyrdata,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->view->mctx,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &dstkey);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result != ISC_R_SUCCESS)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * This really shouldn't happen, but...
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews continue;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = verify(val, dstkey, &sigrdata);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dst_key_free(&dstkey);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_disassociate(&trdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result == ISC_R_SUCCESS)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews break;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result == ISC_R_SUCCESS) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews event->rdataset->trust = dns_trust_secure;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews event->sigrdataset->trust = dns_trust_secure;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(3), "marking as secure");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews } else
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (DNS_R_NOVALIDSIG);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews/*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Starts a positive response validation.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews *
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Returns:
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * ISC_R_SUCCESS Validation completed successfully
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * DNS_R_WAIT Validation has started but is waiting
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * for an event.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Other return codes are possible and all indicate failure.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic isc_result_t
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstart_positive_validation(dns_validator_t *val) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * If this is not a key, go straight into validate().
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (val->event->type != dns_rdatatype_dnskey || !isselfsigned(val))
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (validate(val, ISC_FALSE));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (validatezonekey(val, ISC_FALSE));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic isc_result_t
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrewsnsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington dns_name_t *name;
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington dns_message_t *message = val->event->message;
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington isc_result_t result;
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (!resume)
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews else {
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington result = ISC_R_SUCCESS;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews validator_log(val, ISC_LOG_DEBUG(3), "resuming nsecvalidate");
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington }
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington for (;
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington result == ISC_R_SUCCESS;
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington result = dns_message_nextname(message, DNS_SECTION_AUTHORITY))
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington {
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington name = NULL;
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington if (resume) {
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington rdataset = ISC_LIST_NEXT(val->currentset, link);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington val->currentset = NULL;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington resume = ISC_FALSE;
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington }
f15af68028adc665d3bdddf955fc52bad83f0514Brian Wellington else
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington rdataset = ISC_LIST_HEAD(name->list);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington for (;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington rdataset != NULL;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington rdataset = ISC_LIST_NEXT(rdataset, link))
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington {
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (rdataset->type == dns_rdatatype_rrsig)
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington continue;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington
86f6b92e35c7bdb5fc1fd1021af75b981863313eMark Andrews if (rdataset->type == dns_rdatatype_soa) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->soaset = rdataset;
86f6b92e35c7bdb5fc1fd1021af75b981863313eMark Andrews val->soaname = name;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews } else if (rdataset->type == dns_rdatatype_nsec)
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews val->nsecset = rdataset;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington for (sigrdataset = ISC_LIST_HEAD(name->list);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington sigrdataset != NULL;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington sigrdataset = ISC_LIST_NEXT(sigrdataset,
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington link))
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington {
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (sigrdataset->type == dns_rdatatype_rrsig &&
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington sigrdataset->covers == rdataset->type)
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington break;
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington }
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington if (sigrdataset == NULL)
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington continue;
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington val->seensig = ISC_TRUE;
d6be55c63f83194d97a565d0fd7b632b31b52a68Brian Wellington /*
d6be55c63f83194d97a565d0fd7b632b31b52a68Brian Wellington * If a signed zone is missing the zone key, bad
d6be55c63f83194d97a565d0fd7b632b31b52a68Brian Wellington * things could happen. A query for data in the zone
d6be55c63f83194d97a565d0fd7b632b31b52a68Brian Wellington * would lead to a query for the zone key, which
d6be55c63f83194d97a565d0fd7b632b31b52a68Brian Wellington * would return a negative answer, which would contain
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews * an SOA and an NSEC signed by the missing key, which
d6be55c63f83194d97a565d0fd7b632b31b52a68Brian Wellington * would trigger another query for the KEY (since the
d6be55c63f83194d97a565d0fd7b632b31b52a68Brian Wellington * first one is still in progress), and go into an
d6be55c63f83194d97a565d0fd7b632b31b52a68Brian Wellington * infinite loop. Avoid that.
d6be55c63f83194d97a565d0fd7b632b31b52a68Brian Wellington */
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (val->event->type == dns_rdatatype_dnskey &&
32b2cdf212de957e3f9b0efca59f098ed4fb42deBrian Wellington dns_name_equal(name, val->event->name))
32b2cdf212de957e3f9b0efca59f098ed4fb42deBrian Wellington {
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_rdata_t nsec = DNS_RDATA_INIT;
32b2cdf212de957e3f9b0efca59f098ed4fb42deBrian Wellington
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (rdataset->type != dns_rdatatype_nsec)
32b2cdf212de957e3f9b0efca59f098ed4fb42deBrian Wellington continue;
32b2cdf212de957e3f9b0efca59f098ed4fb42deBrian Wellington
32b2cdf212de957e3f9b0efca59f098ed4fb42deBrian Wellington result = dns_rdataset_first(rdataset);
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington if (result != ISC_R_SUCCESS)
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington return (result);
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_rdataset_current(rdataset, &nsec);
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (dns_nsec_typepresent(&nsec,
32b2cdf212de957e3f9b0efca59f098ed4fb42deBrian Wellington dns_rdatatype_soa))
32b2cdf212de957e3f9b0efca59f098ed4fb42deBrian Wellington continue;
32b2cdf212de957e3f9b0efca59f098ed4fb42deBrian Wellington }
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington val->currentset = rdataset;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = create_validator(val, name, rdataset->type,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews rdataset, sigrdataset,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews authvalidated,
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews "nsecvalidate");
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington if (result != ISC_R_SUCCESS)
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington return (result);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington return (DNS_R_WAIT);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington }
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington }
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington if (result == ISC_R_NOMORE)
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington result = ISC_R_SUCCESS;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington if (result != ISC_R_SUCCESS)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (result);
777ac454c0cdec27dc11d80b9b2a8d7239d833a8Brian Wellington
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington if ((val->attributes & VALATTR_FOUNDNONEXISTENCE) == 0) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (!val->seensig && val->soaset != NULL) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = create_validator(val, name, dns_rdatatype_soa,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->soaset, NULL,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews negauthvalidated,
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews "nsecvalidate");
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington if (result != ISC_R_SUCCESS)
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington return (result);
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington return (DNS_R_WAIT);
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington }
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington "nonexistence proof not found");
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews return (DNS_R_NOVALIDNSEC);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington } else {
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington "nonexistence proof found");
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington return (ISC_R_SUCCESS);
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington }
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington}
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic isc_result_t
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellingtonproveunsecure(dns_validator_t *val, isc_boolean_t resume) {
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington isc_result_t result;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_fixedname_t secroot;
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington dns_name_t *tname;
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington dns_fixedname_init(&secroot);
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington result = dns_keytable_finddeepestmatch(val->keytable,
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington val->event->name,
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington dns_fixedname_name(&secroot));
e27021ee1f37185ab839a7a3b6bc078c24255e62Brian Wellington /*
e27021ee1f37185ab839a7a3b6bc078c24255e62Brian Wellington * If the name is not under a security root, it must be insecure.
e27021ee1f37185ab839a7a3b6bc078c24255e62Brian Wellington */
e27021ee1f37185ab839a7a3b6bc078c24255e62Brian Wellington if (result == ISC_R_NOTFOUND)
e27021ee1f37185ab839a7a3b6bc078c24255e62Brian Wellington return (ISC_R_SUCCESS);
e27021ee1f37185ab839a7a3b6bc078c24255e62Brian Wellington
e27021ee1f37185ab839a7a3b6bc078c24255e62Brian Wellington else if (result != ISC_R_SUCCESS)
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington return (result);
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington if (!resume)
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington val->labels = dns_name_depth(dns_fixedname_name(&secroot)) + 1;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington else {
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3), "resuming proveunsecure");
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington val->labels++;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington }
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington for (;
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington val->labels <= dns_name_depth(val->event->name);
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington val->labels++)
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington {
60e9e7065418e658c069ce91cc6f27c4a55bb4a5Brian Wellington char namebuf[DNS_NAME_FORMATSIZE];
6036112f4874637240d461c3ccbcb8dbfb1f405bAndreas Gustafsson
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington if (val->labels == dns_name_depth(val->event->name)) {
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington tname = val->event->name;
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington } else {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_fixedname_init(&val->fname);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews tname = dns_fixedname_name(&val->fname);
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington result = dns_name_splitatdepth(val->event->name,
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington val->labels,
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington NULL, tname);
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington if (result != ISC_R_SUCCESS)
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington return (result);
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington }
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
6036112f4874637240d461c3ccbcb8dbfb1f405bAndreas Gustafsson dns_name_format(tname, namebuf, sizeof(namebuf));
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews "checking existence of DS at '%s'",
6036112f4874637240d461c3ccbcb8dbfb1f405bAndreas Gustafsson namebuf);
6036112f4874637240d461c3ccbcb8dbfb1f405bAndreas Gustafsson
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = view_find(val, tname, dns_rdatatype_ds);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews * There is no DS. If this is a delegation,
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews * we're done.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (val->frdataset.trust < dns_trust_secure) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * This shouldn't happen, since the negative
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * response should have been validated. Since
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * there's no way of validating existing
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * negative response blobs, give up.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = DNS_R_NOVALIDSIG;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington goto out;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington }
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews if (isdelegation(tname, &val->frdataset, result)) {
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews val->event->rdataset->trust = dns_trust_answer;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews return (ISC_R_SUCCESS);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews }
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews continue;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews } else if (result == ISC_R_SUCCESS) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews * There is a DS here. Verify that it's secure and
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * continue.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (val->frdataset.trust >= dns_trust_secure)
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington continue;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews else if (!dns_rdataset_isassociated(&val->fsigrdataset))
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = DNS_R_NOVALIDSIG;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington goto out;
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = create_validator(val, tname, dns_rdatatype_ds,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &val->frdataset,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &val->fsigrdataset,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dsvalidated,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews "proveunsecure");
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (result != ISC_R_SUCCESS)
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington goto out;
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington return (DNS_R_WAIT);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews } else if (result == DNS_R_NXDOMAIN ||
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result == DNS_R_NCACHENXDOMAIN)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews * This is not a zone cut. Assuming things are
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * as expected, continue.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (!dns_rdataset_isassociated(&val->frdataset)) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews * There should be an NSEC here, since we
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * are still in a secure zone.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews result = DNS_R_NOVALIDNSEC;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews goto out;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews } else if (val->frdataset.trust < dns_trust_secure) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * This shouldn't happen, since the negative
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * response should have been validated. Since
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * there's no way of validating existing
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * negative response blobs, give up.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = DNS_R_NOVALIDSIG;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews goto out;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews continue;
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington } else if (result == ISC_R_NOTFOUND) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * We don't know anything about the DS. Find it.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = create_fetch(val, tname, dns_rdatatype_ds,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dsfetched2, "proveunsecure");
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington if (result != ISC_R_SUCCESS)
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington goto out;
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington return (DNS_R_WAIT);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington }
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3), "insecurity proof failed");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (DNS_R_NOTINSECURE); /* Couldn't complete insecurity proof */
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington out:
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (dns_rdataset_isassociated(&val->frdataset))
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_rdataset_disassociate(&val->frdataset);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (dns_rdataset_isassociated(&val->fsigrdataset))
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_rdataset_disassociate(&val->fsigrdataset);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington return (result);
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington}
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellingtonstatic void
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellingtonvalidator_start(isc_task_t *task, isc_event_t *event) {
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington dns_validator_t *val;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington dns_validatorevent_t *vevent;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_boolean_t want_destroy = ISC_FALSE;
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington isc_result_t result = ISC_R_FAILURE;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington UNUSED(task);
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff REQUIRE(event->ev_type == DNS_EVENT_VALIDATORSTART);
115635379a2baf2100695018109ad39e0dac349dAndreas Gustafsson vevent = (dns_validatorevent_t *)event;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington val = vevent->validator;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington /* If the validator has been cancelled, val->event == NULL */
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington if (val->event == NULL)
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington return;
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3), "starting");
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley LOCK(&val->lock);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (val->event->rdataset != NULL && val->event->sigrdataset != NULL) {
60783293cc27f74a84ec93c95c5d46edd30bd8e0Brian Wellington isc_result_t saved_result;
60783293cc27f74a84ec93c95c5d46edd30bd8e0Brian Wellington
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /*
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * This looks like a simple validation. We say "looks like"
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington * because it might end up requiring an insecurity proof.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington "attempting positive response validation");
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews INSIST(dns_rdataset_isassociated(val->event->rdataset));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews INSIST(dns_rdataset_isassociated(val->event->sigrdataset));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = start_positive_validation(val);
6bc1a645619a14707da68b130dafe41721fd2f25Brian Wellington if (result == DNS_R_NOVALIDSIG &&
6bc1a645619a14707da68b130dafe41721fd2f25Brian Wellington (val->attributes & VALATTR_TRIEDVERIFY) == 0)
6bc1a645619a14707da68b130dafe41721fd2f25Brian Wellington {
60783293cc27f74a84ec93c95c5d46edd30bd8e0Brian Wellington saved_result = result;
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
6bc1a645619a14707da68b130dafe41721fd2f25Brian Wellington "falling back to insecurity proof");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->attributes |= VALATTR_INSECURITY;
6bc1a645619a14707da68b130dafe41721fd2f25Brian Wellington result = proveunsecure(val, ISC_FALSE);
60783293cc27f74a84ec93c95c5d46edd30bd8e0Brian Wellington if (result == DNS_R_NOTINSECURE)
60783293cc27f74a84ec93c95c5d46edd30bd8e0Brian Wellington result = saved_result;
6bc1a645619a14707da68b130dafe41721fd2f25Brian Wellington }
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington } else if (val->event->rdataset != NULL) {
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington /*
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson * This is either an unsecure subdomain or a response from
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson * a broken server.
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews INSIST(dns_rdataset_isassociated(val->event->rdataset));
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington "attempting insecurity proof");
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->attributes |= VALATTR_INSECURITY;
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington result = proveunsecure(val, ISC_FALSE);
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington } else if (val->event->rdataset == NULL &&
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington val->event->sigrdataset == NULL)
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /*
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * This is a nonexistence validation.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington "attempting negative response validation");
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->attributes |= VALATTR_NEGATIVE;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews result = nsecvalidate(val, ISC_FALSE);
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington } else {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence /*
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * This shouldn't happen.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence */
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington INSIST(0);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result != DNS_R_WAIT) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews want_destroy = exit_check(val);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley validator_done(val, result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley UNLOCK(&val->lock);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (want_destroy)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews destroy(val);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley}
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halleyisc_result_t
ec371edc34e2adb9e337b774d1a6e613f5863655Brian Wellingtondns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley dns_message_t *message, unsigned int options,
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley isc_task_t *task, isc_taskaction_t action, void *arg,
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley dns_validator_t **validatorp)
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley{
e419f613d8591885df608cb73065921be07dd12eBob Halley isc_result_t result;
e419f613d8591885df608cb73065921be07dd12eBob Halley dns_validator_t *val;
e419f613d8591885df608cb73065921be07dd12eBob Halley isc_task_t *tclone;
e419f613d8591885df608cb73065921be07dd12eBob Halley dns_validatorevent_t *event;
e419f613d8591885df608cb73065921be07dd12eBob Halley
ec371edc34e2adb9e337b774d1a6e613f5863655Brian Wellington REQUIRE(name != NULL);
59e99793307eed0914f8467243d1c4ac761b1d9cAndreas Gustafsson REQUIRE(type != 0);
ec371edc34e2adb9e337b774d1a6e613f5863655Brian Wellington REQUIRE(rdataset != NULL ||
ec371edc34e2adb9e337b774d1a6e613f5863655Brian Wellington (rdataset == NULL && sigrdataset == NULL && message != NULL));
264fd373f3f6cc7f271bdff14a020385620015f1Andreas Gustafsson REQUIRE(options == 0);
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley REQUIRE(validatorp != NULL && *validatorp == NULL);
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley
e419f613d8591885df608cb73065921be07dd12eBob Halley tclone = NULL;
e419f613d8591885df608cb73065921be07dd12eBob Halley result = ISC_R_FAILURE;
e419f613d8591885df608cb73065921be07dd12eBob Halley
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson val = isc_mem_get(view->mctx, sizeof(*val));
e419f613d8591885df608cb73065921be07dd12eBob Halley if (val == NULL)
e419f613d8591885df608cb73065921be07dd12eBob Halley return (ISC_R_NOMEMORY);
62a84c4a27033bb0e7316256964a6950b1e230bdAndreas Gustafsson val->view = NULL;
ef97e09e20da2133adc731cf7e29e72d04dfc93fAndreas Gustafsson dns_view_weakattach(view, &val->view);
e419f613d8591885df608cb73065921be07dd12eBob Halley event = (dns_validatorevent_t *)
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington isc_event_allocate(view->mctx, task,
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington DNS_EVENT_VALIDATORSTART,
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington validator_start, NULL,
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson sizeof(dns_validatorevent_t));
e419f613d8591885df608cb73065921be07dd12eBob Halley if (event == NULL) {
e419f613d8591885df608cb73065921be07dd12eBob Halley result = ISC_R_NOMEMORY;
e419f613d8591885df608cb73065921be07dd12eBob Halley goto cleanup_val;
e419f613d8591885df608cb73065921be07dd12eBob Halley }
e419f613d8591885df608cb73065921be07dd12eBob Halley isc_task_attach(task, &tclone);
e419f613d8591885df608cb73065921be07dd12eBob Halley event->validator = val;
e419f613d8591885df608cb73065921be07dd12eBob Halley event->result = ISC_R_FAILURE;
e419f613d8591885df608cb73065921be07dd12eBob Halley event->name = name;
ec371edc34e2adb9e337b774d1a6e613f5863655Brian Wellington event->type = type;
e419f613d8591885df608cb73065921be07dd12eBob Halley event->rdataset = rdataset;
e419f613d8591885df608cb73065921be07dd12eBob Halley event->sigrdataset = sigrdataset;
e419f613d8591885df608cb73065921be07dd12eBob Halley event->message = message;
e419f613d8591885df608cb73065921be07dd12eBob Halley result = isc_mutex_init(&val->lock);
e419f613d8591885df608cb73065921be07dd12eBob Halley if (result != ISC_R_SUCCESS)
e419f613d8591885df608cb73065921be07dd12eBob Halley goto cleanup_event;
e419f613d8591885df608cb73065921be07dd12eBob Halley val->event = event;
e419f613d8591885df608cb73065921be07dd12eBob Halley val->options = options;
e419f613d8591885df608cb73065921be07dd12eBob Halley val->attributes = 0;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley val->fetch = NULL;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->subvalidator = NULL;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->parent = NULL;
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington val->keytable = NULL;
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington dns_keytable_attach(val->view->secroots, &val->keytable);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley val->keynode = NULL;
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington val->key = NULL;
fe5ba8ddb55b2b3ee139e13b7891817117ad4e63Brian Wellington val->siginfo = NULL;
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington val->task = task;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington val->action = action;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington val->arg = arg;
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington val->labels = 0;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington val->currentset = NULL;
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington val->keyset = NULL;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->dsset = NULL;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->soaset = NULL;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews val->nsecset = NULL;
86f6b92e35c7bdb5fc1fd1021af75b981863313eMark Andrews val->soaname = NULL;
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington val->seensig = ISC_FALSE;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_rdataset_init(&val->frdataset);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_rdataset_init(&val->fsigrdataset);
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington ISC_LINK_INIT(val, link);
e419f613d8591885df608cb73065921be07dd12eBob Halley val->magic = VALIDATOR_MAGIC;
e419f613d8591885df608cb73065921be07dd12eBob Halley
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington isc_task_send(task, (isc_event_t **)&event);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley *validatorp = val;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
e419f613d8591885df608cb73065921be07dd12eBob Halley return (ISC_R_SUCCESS);
e419f613d8591885df608cb73065921be07dd12eBob Halley
e419f613d8591885df608cb73065921be07dd12eBob Halley cleanup_event:
e419f613d8591885df608cb73065921be07dd12eBob Halley isc_task_detach(&tclone);
e419f613d8591885df608cb73065921be07dd12eBob Halley isc_event_free((isc_event_t **)&val->event);
e419f613d8591885df608cb73065921be07dd12eBob Halley
e419f613d8591885df608cb73065921be07dd12eBob Halley cleanup_val:
ef97e09e20da2133adc731cf7e29e72d04dfc93fAndreas Gustafsson dns_view_weakdetach(&val->view);
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson isc_mem_put(view->mctx, val, sizeof(*val));
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
e419f613d8591885df608cb73065921be07dd12eBob Halley return (result);
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley}
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halleyvoid
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halleydns_validator_cancel(dns_validator_t *validator) {
e419f613d8591885df608cb73065921be07dd12eBob Halley REQUIRE(VALID_VALIDATOR(validator));
e419f613d8591885df608cb73065921be07dd12eBob Halley
e419f613d8591885df608cb73065921be07dd12eBob Halley LOCK(&validator->lock);
264fd373f3f6cc7f271bdff14a020385620015f1Andreas Gustafsson
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(validator, ISC_LOG_DEBUG(3), "dns_validator_cancel");
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington
e419f613d8591885df608cb73065921be07dd12eBob Halley if (validator->event != NULL) {
264fd373f3f6cc7f271bdff14a020385620015f1Andreas Gustafsson if (validator->fetch != NULL)
264fd373f3f6cc7f271bdff14a020385620015f1Andreas Gustafsson dns_resolver_cancelfetch(validator->fetch);
264fd373f3f6cc7f271bdff14a020385620015f1Andreas Gustafsson
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (validator->subvalidator != NULL)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_validator_cancel(validator->subvalidator);
e419f613d8591885df608cb73065921be07dd12eBob Halley }
e419f613d8591885df608cb73065921be07dd12eBob Halley UNLOCK(&validator->lock);
e419f613d8591885df608cb73065921be07dd12eBob Halley}
e419f613d8591885df608cb73065921be07dd12eBob Halley
e419f613d8591885df608cb73065921be07dd12eBob Halleystatic void
e419f613d8591885df608cb73065921be07dd12eBob Halleydestroy(dns_validator_t *val) {
1872808932603066d401d3de97db11af8ffee78aAndreas Gustafsson isc_mem_t *mctx;
e419f613d8591885df608cb73065921be07dd12eBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(SHUTDOWN(val));
e419f613d8591885df608cb73065921be07dd12eBob Halley REQUIRE(val->event == NULL);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(val->fetch == NULL);
e419f613d8591885df608cb73065921be07dd12eBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (val->keynode != NULL)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley dns_keytable_detachkeynode(val->keytable, &val->keynode);
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington else if (val->key != NULL)
c50936eb40263b65ebf6afe4e6556e2dc67c10e4Brian Wellington dst_key_free(&val->key);
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington if (val->keytable != NULL)
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington dns_keytable_detach(&val->keytable);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (val->subvalidator != NULL)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_validator_destroy(&val->subvalidator);
1872808932603066d401d3de97db11af8ffee78aAndreas Gustafsson mctx = val->view->mctx;
fe5ba8ddb55b2b3ee139e13b7891817117ad4e63Brian Wellington if (val->siginfo != NULL)
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson isc_mem_put(mctx, val->siginfo, sizeof(*val->siginfo));
5e387b9ce6bafdfadedb5b34e4c33a4404e5d589Brian Wellington DESTROYLOCK(&val->lock);
ef97e09e20da2133adc731cf7e29e72d04dfc93fAndreas Gustafsson dns_view_weakdetach(&val->view);
1872808932603066d401d3de97db11af8ffee78aAndreas Gustafsson val->magic = 0;
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson isc_mem_put(mctx, val, sizeof(*val));
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley}
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halleyvoid
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halleydns_validator_destroy(dns_validator_t **validatorp) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley dns_validator_t *val;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_boolean_t want_destroy = ISC_FALSE;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(validatorp != NULL);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley val = *validatorp;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(VALID_VALIDATOR(val));
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley LOCK(&val->lock);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->attributes |= VALATTR_SHUTDOWN;
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3), "dns_validator_destroy");
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews want_destroy = exit_check(val);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley UNLOCK(&val->lock);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (want_destroy)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley destroy(val);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
e419f613d8591885df608cb73065921be07dd12eBob Halley *validatorp = NULL;
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley}
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafssonstatic void
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafssonvalidator_logv(dns_validator_t *val, isc_logcategory_t *category,
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington isc_logmodule_t *module, int level, const char *fmt, va_list ap)
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson{
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson char msgbuf[2048];
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington if (val->event != NULL && val->event->name != NULL) {
18b7133679efa8f60fd4e396c628576f3f416b3eBrian Wellington char namebuf[DNS_NAME_FORMATSIZE];
18b7133679efa8f60fd4e396c628576f3f416b3eBrian Wellington char typebuf[DNS_RDATATYPE_FORMATSIZE];
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson dns_name_format(val->event->name, namebuf, sizeof(namebuf));
18b7133679efa8f60fd4e396c628576f3f416b3eBrian Wellington dns_rdatatype_format(val->event->type, typebuf,
18b7133679efa8f60fd4e396c628576f3f416b3eBrian Wellington sizeof(typebuf));
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson isc_log_write(dns_lctx, category, module, level,
18b7133679efa8f60fd4e396c628576f3f416b3eBrian Wellington "validating %s %s: %s", namebuf, typebuf,
18b7133679efa8f60fd4e396c628576f3f416b3eBrian Wellington msgbuf);
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson } else {
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson isc_log_write(dns_lctx, category, module, level,
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson "validator @%p: %s", val, msgbuf);
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson }
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson}
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafssonstatic void
18b7133679efa8f60fd4e396c628576f3f416b3eBrian Wellingtonvalidator_log(dns_validator_t *val, int level, const char *fmt, ...) {
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington va_list ap;
5b0413f993b1c1ed837d23641e9f696cda1ee293Brian Wellington
5b0413f993b1c1ed837d23641e9f696cda1ee293Brian Wellington if (! isc_log_wouldlog(dns_lctx, level))
5b0413f993b1c1ed837d23641e9f696cda1ee293Brian Wellington return;
5b0413f993b1c1ed837d23641e9f696cda1ee293Brian Wellington
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson va_start(ap, fmt);
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson validator_logv(val, DNS_LOGCATEGORY_DNSSEC,
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson DNS_LOGMODULE_VALIDATOR, level, fmt, ap);
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson va_end(ap);
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic void
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsvalidator_logcreate(dns_validator_t *val,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_name_t *name, dns_rdatatype_t type,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews const char *caller, const char *operation)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews{
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews char namestr[DNS_NAME_FORMATSIZE];
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews char typestr[DNS_RDATATYPE_FORMATSIZE];
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_name_format(name, namestr, sizeof(namestr));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdatatype_format(type, typestr, sizeof(typestr));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(9), "%s: creating %s for %s %s",
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews caller, operation, namestr, typestr);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}