bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley/*
dc2a85bed7fcfceab0df1867fbc1d35796261dedTinderbox User * Copyright (C) 2000-2018 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley */
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <config.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#include <isc/base32.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/mem.h>
fca5f81ad69098ea8abba130c7f841c951ef91c2Bob Halley#include <isc/print.h>
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#include <isc/sha2.h>
519b239fc4ef1e070e2da182a4ea559ae0152151Mark Andrews#include <isc/string.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <isc/task.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <isc/util.h>
9695ae1c24b168996e3a267855dc754971ccb32cBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#include <dns/db.h>
1c776a2909632bc755f3fddd3b53addd792ab4d0Brian Wellington#include <dns/dnssec.h>
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews#include <dns/ds.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <dns/events.h>
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#include <dns/keytable.h>
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews#include <dns/keyvalues.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>
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#include <dns/nsec3.h>
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#include <dns/rdata.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
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*! \file
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \brief
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Basic processing sequences.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li When called with rdataset and sigrdataset:
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * validator_start -> validate -> proveunsecure -> startfinddlvsep ->
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * dlv_validator_start -> validator_start -> validate -> proveunsecure
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * validator_start -> validate -> nsecvalidate (secure wildcard answer)
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li When called with rdataset, sigrdataset and with DNS_VALIDATOR_DLV:
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * validator_start -> startfinddlvsep -> dlv_validator_start ->
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * validator_start -> validate -> proveunsecure
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li When called with rdataset:
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * validator_start -> proveunsecure -> startfinddlvsep ->
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * dlv_validator_start -> validator_start -> proveunsecure
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li When called with rdataset and with DNS_VALIDATOR_DLV:
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * validator_start -> startfinddlvsep -> dlv_validator_start ->
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * validator_start -> proveunsecure
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li When called without a rdataset:
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * validator_start -> nsecvalidate -> proveunsecure -> startfinddlvsep ->
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * dlv_validator_start -> validator_start -> nsecvalidate -> proveunsecure
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
d2ef84e07b67e72a4bd9c729c6b8228067d17584Mark Andrews * Note: there isn't a case for DNS_VALIDATOR_DLV here as we want nsecvalidate()
d2ef84e07b67e72a4bd9c729c6b8228067d17584Mark Andrews * to always validate the authority section even when it does not contain
d2ef84e07b67e72a4bd9c729c6b8228067d17584Mark Andrews * signatures.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * validator_start: determines what type of validation to do.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * validate: attempts to perform a positive validation.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * proveunsecure: attempts to prove the answer comes from a unsecure zone.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * nsecvalidate: attempts to prove a negative response.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * startfinddlvsep: starts the DLV record lookup.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * dlv_validator_start: resets state and restarts the lookup using the
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * DLV RRset found by startfinddlvsep.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
92ef1a9b9dbd48ecb507b42ac62c15afefdaf838David Lawrence#define VALIDATOR_MAGIC ISC_MAGIC('V', 'a', 'l', '?')
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews#define VALID_VALIDATOR(v) ISC_MAGIC_VALID(v, VALIDATOR_MAGIC)
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews#define VALATTR_SHUTDOWN 0x0001 /*%< Shutting down. */
708383382ff1d3fdd27527e5d63120a3c6c6d3b3Francis Dupont#define VALATTR_CANCELED 0x0002 /*%< Canceled. */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews#define VALATTR_TRIEDVERIFY 0x0004 /*%< We have found a key and
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * have attempted a verify. */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews#define VALATTR_INSECURITY 0x0010 /*%< Attempting proveunsecure. */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews#define VALATTR_DLVTRIED 0x0020 /*%< Looked for a DLV record. */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*!
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * NSEC proofs to be looked for.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define VALATTR_NEEDNOQNAME 0x00000100
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define VALATTR_NEEDNOWILDCARD 0x00000200
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define VALATTR_NEEDNODATA 0x00000400
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*!
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * NSEC proofs that have been found.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define VALATTR_FOUNDNOQNAME 0x00001000
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define VALATTR_FOUNDNOWILDCARD 0x00002000
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define VALATTR_FOUNDNODATA 0x00004000
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define VALATTR_FOUNDCLOSEST 0x00008000
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews/*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define VALATTR_FOUNDOPTOUT 0x00010000
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define VALATTR_FOUNDUNKNOWN 0x00020000
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews#define NEEDNODATA(val) ((val->attributes & VALATTR_NEEDNODATA) != 0)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews#define NEEDNOQNAME(val) ((val->attributes & VALATTR_NEEDNOQNAME) != 0)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews#define NEEDNOWILDCARD(val) ((val->attributes & VALATTR_NEEDNOWILDCARD) != 0)
50105afc551903541608b11851d73278b23579a3Mark Andrews#define DLVTRIED(val) ((val->attributes & VALATTR_DLVTRIED) != 0)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews#define FOUNDNODATA(val) ((val->attributes & VALATTR_FOUNDNODATA) != 0)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews#define FOUNDNOQNAME(val) ((val->attributes & VALATTR_FOUNDNOQNAME) != 0)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews#define FOUNDNOWILDCARD(val) ((val->attributes & VALATTR_FOUNDNOWILDCARD) != 0)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews#define FOUNDCLOSEST(val) ((val->attributes & VALATTR_FOUNDCLOSEST) != 0)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews#define FOUNDOPTOUT(val) ((val->attributes & VALATTR_FOUNDOPTOUT) != 0)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#define SHUTDOWN(v) (((v)->attributes & VALATTR_SHUTDOWN) != 0)
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews#define CANCELED(v) (((v)->attributes & VALATTR_CANCELED) != 0)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt#define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt
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
50105afc551903541608b11851d73278b23579a3Mark Andrewsvalidatezonekey(dns_validator_t *val);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic isc_result_t
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrewsnsecvalidate(dns_validator_t *val, isc_boolean_t resume);
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrence
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic isc_result_t
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrewsproveunsecure(dns_validator_t *val, isc_boolean_t have_ds,
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews 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
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrewsvalidator_log(void *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
50105afc551903541608b11851d73278b23579a3Mark Andrewsstatic isc_result_t
50105afc551903541608b11851d73278b23579a3Mark Andrewsdlv_validatezonekey(dns_validator_t *val);
50105afc551903541608b11851d73278b23579a3Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsstatic void
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrewsdlv_validator_start(dns_validator_t *val);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrewsstatic isc_result_t
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrewsfinddlvsep(dns_validator_t *val, isc_boolean_t resume);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsstatic isc_result_t
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsstartfinddlvsep(dns_validator_t *val, dns_name_t *unsecure);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Mark the RRsets as a answer.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrewsstatic inline void
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrewsmarkanswer(dns_validator_t *val, const char *where) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews validator_log(val, ISC_LOG_DEBUG(3), "marking as answer (%s)", where);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews if (val->event->rdataset != NULL)
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_rdataset_settrust(val->event->rdataset, dns_trust_answer);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews if (val->event->sigrdataset != NULL)
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_rdataset_settrust(val->event->sigrdataset,
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_trust_answer);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews}
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews
0cae66577c69c89086cd065bb297690072b471b4Mark Andrewsstatic inline void
0cae66577c69c89086cd065bb297690072b471b4Mark Andrewsmarksecure(dns_validatorevent_t *event) {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_rdataset_settrust(event->rdataset, dns_trust_secure);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (event->sigrdataset != NULL)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_settrust(event->sigrdataset, dns_trust_secure);
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrews event->secure = ISC_TRUE;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews}
5be3685b0e57677c0cc03113099cb8f99f9a070bMark 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
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews/*
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews * Check that we have atleast one supported algorithm in the DLV RRset.
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews */
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrewsstatic inline isc_boolean_t
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrewsdlv_algorithm_supported(dns_validator_t *val) {
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews dns_rdata_dlv_t dlv;
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews isc_result_t result;
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews for (result = dns_rdataset_first(&val->dlv);
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews result == ISC_R_SUCCESS;
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews result = dns_rdataset_next(&val->dlv)) {
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews dns_rdata_reset(&rdata);
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews dns_rdataset_current(&val->dlv, &rdata);
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews result = dns_rdata_tostruct(&rdata, &dlv, NULL);
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews RUNTIME_CHECK(result == ISC_R_SUCCESS);
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews if (!dns_resolver_algorithm_supported(val->view->resolver,
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews val->event->name,
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews dlv.algorithm))
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews continue;
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews if (!dns_resolver_ds_digest_supported(val->view->resolver,
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews val->event->name,
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews dlv.digest_type))
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews continue;
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews return (ISC_TRUE);
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews }
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews return (ISC_FALSE);
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews}
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Look in the NSEC record returned from a DS query to see if there is
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * a NS RRset at this name. If it is found we are at a delegation point.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsstatic isc_boolean_t
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsisdelegation(dns_name_t *name, dns_rdataset_t *rdataset,
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews isc_result_t dbresult)
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews{
7d211b458fed36326b9e125b9d74089f9dccc140Mark Andrews dns_fixedname_t fixed;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_label_t hashlabel;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_name_t nsec3name;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdata_nsec3_t nsec3;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdataset_t set;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews int order;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews int scope;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews isc_boolean_t found;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_t buffer;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews isc_result_t result;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews unsigned char hash[NSEC3_MAX_HASH_LENGTH];
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews unsigned char owner[NSEC3_MAX_HASH_LENGTH];
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews unsigned int length;
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);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result == ISC_R_NOTFOUND)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews goto trynsec3;
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);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdata_reset(&rdata);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews }
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews dns_rdataset_disassociate(&set);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews return (found);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews trynsec3:
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Iterate over the ncache entry.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews found = ISC_FALSE;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_name_init(&nsec3name, NULL);
7d211b458fed36326b9e125b9d74089f9dccc140Mark Andrews dns_fixedname_init(&fixed);
7d211b458fed36326b9e125b9d74089f9dccc140Mark Andrews dns_name_downcase(name, dns_fixedname_name(&fixed), NULL);
7d211b458fed36326b9e125b9d74089f9dccc140Mark Andrews name = dns_fixedname_name(&fixed);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews for (result = dns_rdataset_first(rdataset);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result == ISC_R_SUCCESS;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = dns_rdataset_next(rdataset))
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_ncache_current(rdataset, &nsec3name, &set);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (set.type != dns_rdatatype_nsec3) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdataset_disassociate(&set);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews continue;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_name_getlabel(&nsec3name, 0, &hashlabel);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_region_consume(&hashlabel, 1);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_init(&buffer, owner, sizeof(owner));
36e5ac00333d89001f0c518a7d381d16c38d0402Mark Andrews result = isc_base32hexnp_decoderegion(&hashlabel, &buffer);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result != ISC_R_SUCCESS) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdataset_disassociate(&set);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews continue;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews for (result = dns_rdataset_first(&set);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result == ISC_R_SUCCESS;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = dns_rdataset_next(&set))
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdata_reset(&rdata);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdataset_current(&set, &rdata);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews (void)dns_rdata_tostruct(&rdata, &nsec3, NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (nsec3.hash != 1)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews continue;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews length = isc_iterated_hash(hash, nsec3.hash,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews nsec3.iterations, nsec3.salt,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews nsec3.salt_length,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews name->ndata, name->length);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (length != isc_buffer_usedlength(&buffer))
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews continue;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews order = memcmp(hash, owner, length);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (order == 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews found = dns_nsec3_typepresent(&rdata,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdatatype_ns);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdataset_disassociate(&set);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (found);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) == 0)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews continue;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Does this optout span cover the name?
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews scope = memcmp(owner, nsec3.next, nsec3.next_length);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if ((scope < 0 && order > 0 &&
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews memcmp(hash, nsec3.next, length) < 0) ||
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews (scope >= 0 && (order > 0 ||
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews memcmp(hash, nsec3.next, length) < 0)))
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdataset_disassociate(&set);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_TRUE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdataset_disassociate(&set);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (found);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews}
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
ff380b05fec3746934c74b78bb44f641d2acb359Francis Dupont * We have been asked to look for a key.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * If found resume the validation process.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * If not found fail the validation process.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark 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;
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews isc_result_t saved_result;
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews dns_fetch_t *fetch;
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
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews /* Free resources which are not of interest. */
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews if (devent->node != NULL)
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews dns_db_detachnode(devent->db, &devent->node);
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews if (devent->db != NULL)
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews dns_db_detach(&devent->db);
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews if (dns_rdataset_isassociated(&val->fsigrdataset))
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews dns_rdataset_disassociate(&val->fsigrdataset);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington isc_event_free(&event);
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);
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews fetch = val->fetch;
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews val->fetch = NULL;
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews if (CANCELED(val)) {
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews validator_done(val, ISC_R_CANCELED);
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews } else if (eresult == ISC_R_SUCCESS) {
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews "keyset with trust %s",
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews dns_trust_totext(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);
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews if (result == DNS_R_NOVALIDSIG &&
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews (val->attributes & VALATTR_TRIEDVERIFY) == 0)
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews {
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews saved_result = result;
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews validator_log(val, ISC_LOG_DEBUG(3),
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews "falling back to insecurity proof");
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews val->attributes |= VALATTR_INSECURITY;
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews if (result == DNS_R_NOTINSECURE)
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews result = saved_result;
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews }
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
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews validator_done(val, DNS_R_BROKENCHAIN);
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews want_destroy = exit_check(val);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington UNLOCK(&val->lock);
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews if (fetch != NULL)
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews dns_resolver_destroyfetch(&fetch);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (want_destroy)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews destroy(val);
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington}
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * We were asked to look for a DS record as part of following a key chain
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * upwards. If found resume the validation process. If not found fail the
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * validation process.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
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;
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews dns_fetch_t *fetch;
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
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews /* Free resources which are not of interest. */
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews if (devent->node != NULL)
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews dns_db_detachnode(devent->db, &devent->node);
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews if (devent->db != NULL)
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews dns_db_detach(&devent->db);
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews if (dns_rdataset_isassociated(&val->fsigrdataset))
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews dns_rdataset_disassociate(&val->fsigrdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_event_free(&event);
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);
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews fetch = val->fetch;
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews val->fetch = NULL;
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews if (CANCELED(val)) {
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews validator_done(val, ISC_R_CANCELED);
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews } else if (eresult == ISC_R_SUCCESS) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews "dsset with trust %s",
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews dns_trust_totext(rdataset->trust));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->dsset = &val->frdataset;
50105afc551903541608b11851d73278b23579a3Mark Andrews result = validatezonekey(val);
50105afc551903541608b11851d73278b23579a3Mark Andrews if (result != DNS_R_WAIT)
50105afc551903541608b11851d73278b23579a3Mark Andrews validator_done(val, result);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews } else if (eresult == DNS_R_CNAME ||
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews eresult == DNS_R_NXRRSET ||
a05f23d07e1b60a1d88119678111a47014480611Mark Andrews eresult == DNS_R_NCACHENXRRSET ||
a05f23d07e1b60a1d88119678111a47014480611Mark Andrews eresult == DNS_R_SERVFAIL) /* RFC 1034 parent? */
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
a05f23d07e1b60a1d88119678111a47014480611Mark Andrews "falling back to insecurity proof (%s)",
a05f23d07e1b60a1d88119678111a47014480611Mark Andrews dns_result_totext(eresult));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->attributes |= VALATTR_INSECURITY;
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews result = proveunsecure(val, ISC_FALSE, 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
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews validator_done(val, DNS_R_BROKENCHAIN);
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews want_destroy = exit_check(val);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington UNLOCK(&val->lock);
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews if (fetch != NULL)
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews dns_resolver_destroyfetch(&fetch);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (want_destroy)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews destroy(val);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * We were asked to look for the DS record as part of proving that a
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * name is unsecure.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * If the DS record doesn't exist and the query name corresponds to
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * a delegation point we are transitioning from a secure zone to a
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * unsecure zone.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * If the DS record exists it will be secure. We can continue looking
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * for the break point in the chain of trust.
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;
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;
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews dns_fetch_t *fetch;
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 eresult = devent->result;
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews /* Free resources which are not of interest. */
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews if (devent->node != NULL)
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews dns_db_detachnode(devent->db, &devent->node);
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews if (devent->db != NULL)
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews dns_db_detach(&devent->db);
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews if (dns_rdataset_isassociated(&val->fsigrdataset))
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews dns_rdataset_disassociate(&val->fsigrdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews INSIST(val->event != NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched2: %s",
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews dns_result_totext(eresult));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews LOCK(&val->lock);
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews fetch = val->fetch;
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews val->fetch = NULL;
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews if (CANCELED(val)) {
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews validator_done(val, ISC_R_CANCELED);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews } else if (eresult == DNS_R_CNAME ||
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews eresult == DNS_R_NXRRSET ||
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews eresult == DNS_R_NCACHENXRRSET)
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews {
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);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews if (eresult != DNS_R_CNAME &&
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews isdelegation(tname, &val->frdataset, eresult)) {
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews if (val->mustbesecure) {
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews validator_log(val, ISC_LOG_WARNING,
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt "must be secure failure, no DS"
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt " and this is a delegation");
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews validator_done(val, DNS_R_MUSTBESECURE);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews } else if (val->view->dlv == NULL || DLVTRIED(val)) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews markanswer(val, "dsfetched2");
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews validator_done(val, ISC_R_SUCCESS);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews } else {
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews result = startfinddlvsep(val, tname);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews if (result != DNS_R_WAIT)
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews validator_done(val, result);
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews }
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews } else {
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews result = proveunsecure(val, ISC_FALSE, 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 /*
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater * There is a DS which may or may not be a zone cut.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * In either case we are still in a secure zone resume
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * validation.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews result = proveunsecure(val, ISC_TF(eresult == ISC_R_SUCCESS),
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews 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);
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews if (fetch != NULL)
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews dns_resolver_destroyfetch(&fetch);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (want_destroy)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews destroy(val);
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington}
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Callback from when a DNSKEY RRset has been validated.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Resumes the stalled validation process.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
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;
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews isc_result_t saved_result;
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);
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews if (CANCELED(val)) {
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews validator_done(val, ISC_R_CANCELED);
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews } else if (eresult == ISC_R_SUCCESS) {
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews "keyset with trust %s",
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews dns_trust_totext(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);
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews if (result == DNS_R_NOVALIDSIG &&
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews (val->attributes & VALATTR_TRIEDVERIFY) == 0)
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews {
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews saved_result = result;
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews validator_log(val, ISC_LOG_DEBUG(3),
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews "falling back to insecurity proof");
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews val->attributes |= VALATTR_INSECURITY;
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews if (result == DNS_R_NOTINSECURE)
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews result = saved_result;
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result != DNS_R_WAIT)
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington validator_done(val, result);
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington } else {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews if (eresult != DNS_R_BROKENCHAIN) {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews if (dns_rdataset_isassociated(&val->frdataset))
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_rdataset_expire(&val->frdataset);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews if (dns_rdataset_isassociated(&val->fsigrdataset))
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_rdataset_expire(&val->fsigrdataset);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews }
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson "keyvalidated: got %s",
18b7133679efa8f60fd4e396c628576f3f416b3eBrian Wellington isc_result_totext(eresult));
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews validator_done(val, DNS_R_BROKENCHAIN);
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
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Callback when the DS record has been validated.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Resumes validation of the zone key or the unsecure zone proof.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark 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);
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews if (CANCELED(val)) {
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews validator_done(val, ISC_R_CANCELED);
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews } else if (eresult == ISC_R_SUCCESS) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews isc_boolean_t have_dsset;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_name_t *name;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews "%s with trust %s",
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews val->frdataset.type == dns_rdatatype_ds ?
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews "dsset" : "ds non-existance",
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews dns_trust_totext(val->frdataset.trust));
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews have_dsset = ISC_TF(val->frdataset.type == dns_rdatatype_ds);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews name = dns_fixedname_name(&val->fname);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if ((val->attributes & VALATTR_INSECURITY) != 0 &&
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews val->frdataset.covers == dns_rdatatype_ds &&
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt NEGATIVE(&val->frdataset) &&
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews isdelegation(name, &val->frdataset, DNS_R_NCACHENXRRSET)) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (val->mustbesecure) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews validator_log(val, ISC_LOG_WARNING,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews "must be secure failure, no DS "
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews "and this is a delegation");
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = DNS_R_MUSTBESECURE;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews } else if (val->view->dlv == NULL || DLVTRIED(val)) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews markanswer(val, "dsvalidated");
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = ISC_R_SUCCESS;;
515c7f3c43f76d7b439905b18009105364b36100Automatic Updater } else
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = startfinddlvsep(val, name);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews } else if ((val->attributes & VALATTR_INSECURITY) != 0) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = proveunsecure(val, have_dsset, ISC_TRUE);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews } else
50105afc551903541608b11851d73278b23579a3Mark Andrews result = validatezonekey(val);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result != DNS_R_WAIT)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_done(val, result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews } else {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews if (eresult != DNS_R_BROKENCHAIN) {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews if (dns_rdataset_isassociated(&val->frdataset))
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_rdataset_expire(&val->frdataset);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews if (dns_rdataset_isassociated(&val->fsigrdataset))
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_rdataset_expire(&val->fsigrdataset);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews "dsvalidated: got %s",
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_result_totext(eresult));
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews validator_done(val, DNS_R_BROKENCHAIN);
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
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews/*%
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews * Callback when the CNAME record has been validated.
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews *
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews * Resumes validation of the unsecure zone proof.
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews */
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrewsstatic void
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrewscnamevalidated(isc_task_t *task, isc_event_t *event) {
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews dns_validatorevent_t *devent;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews dns_validator_t *val;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews isc_boolean_t want_destroy;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews isc_result_t result;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews isc_result_t eresult;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews UNUSED(task);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews devent = (dns_validatorevent_t *)event;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews val = devent->ev_arg;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews eresult = devent->result;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews isc_event_free(&event);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews dns_validator_destroy(&val->subvalidator);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews INSIST(val->event != NULL);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews INSIST((val->attributes & VALATTR_INSECURITY) != 0);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews validator_log(val, ISC_LOG_DEBUG(3), "in cnamevalidated");
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews LOCK(&val->lock);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews if (CANCELED(val)) {
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews validator_done(val, ISC_R_CANCELED);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews } else if (eresult == ISC_R_SUCCESS) {
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews validator_log(val, ISC_LOG_DEBUG(3), "cname with trust %s",
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews dns_trust_totext(val->frdataset.trust));
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews result = proveunsecure(val, ISC_FALSE, ISC_TRUE);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews if (result != DNS_R_WAIT)
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews validator_done(val, result);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews } else {
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews if (eresult != DNS_R_BROKENCHAIN) {
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews if (dns_rdataset_isassociated(&val->frdataset))
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews dns_rdataset_expire(&val->frdataset);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews if (dns_rdataset_isassociated(&val->fsigrdataset))
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews dns_rdataset_expire(&val->fsigrdataset);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews }
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews "cnamevalidated: got %s",
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews isc_result_totext(eresult));
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews validator_done(val, DNS_R_BROKENCHAIN);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews }
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews want_destroy = exit_check(val);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews UNLOCK(&val->lock);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews if (want_destroy)
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews destroy(val);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews}
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Callback for when NSEC records have been validated.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Looks for NOQNAME, NODATA and OPTOUT proofs.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Resumes nsecvalidate.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
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;
216030f2849b0812910fbc1817ca17208a112663Mark Andrews dns_rdataset_t *rdataset;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_boolean_t want_destroy;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington isc_result_t result;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews isc_boolean_t exists, data;
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 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);
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews if (CANCELED(val)) {
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews validator_done(val, ISC_R_CANCELED);
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews } else 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));
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews if (result == DNS_R_BROKENCHAIN)
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews val->authfail++;
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 {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_name_t **proofs = val->event->proofs;
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews dns_name_t *wild = dns_fixedname_name(&val->wild);
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (rdataset->trust == dns_trust_secure)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews val->seensig = ISC_TRUE;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington
4e259c5a2321e994708fb1fe04cd4da30aa3b612Mark Andrews if (rdataset->type == dns_rdatatype_nsec &&
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews rdataset->trust == dns_trust_secure &&
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews (NEEDNODATA(val) || NEEDNOQNAME(val)) &&
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews !FOUNDNODATA(val) && !FOUNDNOQNAME(val) &&
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews dns_nsec_noexistnodata(val->event->type, val->event->name,
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews devent->name, rdataset, &exists,
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews &data, wild, validator_log, val)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews == ISC_R_SUCCESS)
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (exists && !data) {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews val->attributes |= VALATTR_FOUNDNODATA;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (NEEDNODATA(val))
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews proofs[DNS_VALIDATOR_NODATAPROOF] =
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews devent->name;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (!exists) {
2fa1fc53324c0fca978c902e883c7cc011210536Mark Andrews dns_name_t *closest;
2fa1fc53324c0fca978c902e883c7cc011210536Mark Andrews unsigned int clabels;
2fa1fc53324c0fca978c902e883c7cc011210536Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews val->attributes |= VALATTR_FOUNDNOQNAME;
2fa1fc53324c0fca978c902e883c7cc011210536Mark Andrews
2fa1fc53324c0fca978c902e883c7cc011210536Mark Andrews closest = dns_fixedname_name(&val->closest);
2fa1fc53324c0fca978c902e883c7cc011210536Mark Andrews clabels = dns_name_countlabels(closest);
2fa1fc53324c0fca978c902e883c7cc011210536Mark Andrews /*
2fa1fc53324c0fca978c902e883c7cc011210536Mark Andrews * If we are validating a wildcard response
2fa1fc53324c0fca978c902e883c7cc011210536Mark Andrews * clabels will not be zero. We then need
2fa1fc53324c0fca978c902e883c7cc011210536Mark Andrews * to check if the generated wilcard from
2fa1fc53324c0fca978c902e883c7cc011210536Mark Andrews * dns_nsec_noexistnodata is consistent with
2fa1fc53324c0fca978c902e883c7cc011210536Mark Andrews * the wildcard used to generate the response.
2fa1fc53324c0fca978c902e883c7cc011210536Mark Andrews */
2fa1fc53324c0fca978c902e883c7cc011210536Mark Andrews if (clabels == 0 ||
2fa1fc53324c0fca978c902e883c7cc011210536Mark Andrews dns_name_countlabels(wild) == clabels + 1)
2fa1fc53324c0fca978c902e883c7cc011210536Mark Andrews val->attributes |= VALATTR_FOUNDCLOSEST;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * The NSEC noqname proof also contains
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * the closest encloser.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (NEEDNOQNAME(val))
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews proofs[DNS_VALIDATOR_NOQNAMEPROOF] =
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews devent->name;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
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
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Looks for the requested name and type in the view (zones and cache).
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * When looking for a DLV record also checks to make sure the NSEC record
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * returns covers the query name as part of aggressive negative caching.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Returns:
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li ISC_R_SUCCESS
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li ISC_R_NOTFOUND
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li DNS_R_NCACHENXDOMAIN
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li DNS_R_NCACHENXRRSET
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li DNS_R_NXRRSET
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li DNS_R_NXDOMAIN
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews * \li DNS_R_BROKENCHAIN
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic inline isc_result_t
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsview_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_fixedname_t fixedname;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_name_t *foundname;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_rdata_nsec_t nsec;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_result_t result;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews unsigned int options;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews isc_time_t now;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews char buf1[DNS_NAME_FORMATSIZE];
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews char buf2[DNS_NAME_FORMATSIZE];
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews char buf3[DNS_NAME_FORMATSIZE];
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews char namebuf[DNS_NAME_FORMATSIZE];
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews char typebuf[DNS_RDATATYPE_FORMATSIZE];
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
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
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews if (isc_time_now(&now) == ISC_R_SUCCESS &&
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_resolver_getbadcache(val->view->resolver, name, type, &now)) {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_name_format(name, namebuf, sizeof(namebuf));
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_rdatatype_format(type, typebuf, sizeof(typebuf));
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews validator_log(val, ISC_LOG_INFO, "bad cache hit (%s/%s)",
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews namebuf, typebuf);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews return (DNS_R_BROKENCHAIN);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews }
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews options = DNS_DBFIND_PENDINGOK;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (type == dns_rdatatype_dlv)
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews options |= DNS_DBFIND_COVERINGNSEC;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_fixedname_init(&fixedname);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews foundname = dns_fixedname_name(&fixedname);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews result = dns_view_find(val->view, name, type, 0, options,
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews ISC_FALSE, NULL, NULL, foundname,
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews &val->frdataset, &val->fsigrdataset);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (result == DNS_R_NXDOMAIN) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (dns_rdataset_isassociated(&val->frdataset))
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_rdataset_disassociate(&val->frdataset);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (dns_rdataset_isassociated(&val->fsigrdataset))
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_rdataset_disassociate(&val->fsigrdataset);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews } else if (result == DNS_R_COVERINGNSEC) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews validator_log(val, ISC_LOG_DEBUG(3), "DNS_R_COVERINGNSEC");
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews /*
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * Check if the returned NSEC covers the name.
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews */
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews INSIST(type == dns_rdatatype_dlv);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (val->frdataset.trust != dns_trust_secure) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews "covering nsec: trust %s",
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews dns_trust_totext(val->frdataset.trust));
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews goto notfound;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews result = dns_rdataset_first(&val->frdataset);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (result != ISC_R_SUCCESS)
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews goto notfound;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_rdataset_current(&val->frdataset, &rdata);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (dns_nsec_typepresent(&rdata, dns_rdatatype_ns) &&
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews !dns_nsec_typepresent(&rdata, dns_rdatatype_soa)) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews /* Parent NSEC record. */
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (dns_name_issubdomain(name, foundname)) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews "covering nsec: for parent");
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews goto notfound;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews result = dns_rdata_tostruct(&rdata, &nsec, NULL);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (result != ISC_R_SUCCESS)
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews goto notfound;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (dns_name_compare(foundname, &nsec.next) >= 0) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews /* End of zone chain. */
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (!dns_name_issubdomain(name, &nsec.next)) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews /*
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater * XXXMPA We could look for a parent NSEC
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * at nsec.next and if found retest with
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * this NSEC.
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews */
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_rdata_freestruct(&nsec);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews "covering nsec: not in zone");
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews goto notfound;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews } else if (dns_name_compare(name, &nsec.next) >= 0) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews /*
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * XXXMPA We could check if this NSEC is at a zone
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * apex and if the qname is not below it and look for
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * a parent NSEC with the same name. This requires
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * that we can cache both NSEC records which we
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * currently don't support.
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews */
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_rdata_freestruct(&nsec);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews "covering nsec: not in range");
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews goto notfound;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (isc_log_wouldlog(dns_lctx,ISC_LOG_DEBUG(3))) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_name_format(name, buf1, sizeof buf1);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_name_format(foundname, buf2, sizeof buf2);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_name_format(&nsec.next, buf3, sizeof buf3);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews "covering nsec found: '%s' '%s' '%s'",
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews buf1, buf2, buf3);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (dns_rdataset_isassociated(&val->frdataset))
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_rdataset_disassociate(&val->frdataset);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (dns_rdataset_isassociated(&val->fsigrdataset))
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_rdataset_disassociate(&val->fsigrdataset);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_rdata_freestruct(&nsec);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews result = DNS_R_NCACHENXDOMAIN;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews } else if (result != ISC_R_SUCCESS &&
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater result != DNS_R_NCACHENXDOMAIN &&
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater result != DNS_R_NCACHENXRRSET &&
1bfe8851c0a2eb1d7e15556bfa21291cd62ee2bcMark Andrews result != DNS_R_EMPTYNAME &&
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater result != DNS_R_NXRRSET &&
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater result != ISC_R_NOTFOUND) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews goto notfound;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews return (result);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews notfound:
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (dns_rdataset_isassociated(&val->frdataset))
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_rdataset_disassociate(&val->frdataset);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (dns_rdataset_isassociated(&val->fsigrdataset))
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_rdataset_disassociate(&val->fsigrdataset);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews return (ISC_R_NOTFOUND);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Checks to make sure we are not going to loop. As we use a SHARED fetch
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * the validation process will stall if looping was to occur.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic inline isc_boolean_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewscheck_deadlock(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews{
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_validator_t *parent;
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews for (parent = val; parent != NULL; parent = parent->parent) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (parent->event != NULL &&
8d1b3ceb4d491ce32572f1702f37ed585eede993Evan Hunt parent->event->type == type &&
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_name_equal(parent->event->name, name) &&
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * As NSEC3 records are meta data you sometimes
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * need to prove a NSEC3 record which says that
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * itself doesn't exist.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews (parent->event->type != dns_rdatatype_nsec3 ||
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews rdataset == NULL || sigrdataset == NULL ||
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews parent->event->message == NULL ||
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews parent->event->rdataset != NULL ||
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews parent->event->sigrdataset != NULL))
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
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Start a fetch for the requested name and type.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
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{
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt unsigned int fopts = 0;
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt
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
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt if (check_deadlock(val, name, type, NULL, NULL)) {
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt validator_log(val, ISC_LOG_DEBUG(3),
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt "deadlock found (create_fetch)");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (DNS_R_NOVALIDSIG);
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt if ((val->options & DNS_VALIDATOR_NOCDFLAG) != 0)
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt fopts |= DNS_FETCHOPT_NOCDFLAG;
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt
b8a9632333a92d73a503afe1aaa7990016c8bee9Evan Hunt if ((val->options & DNS_VALIDATOR_NONTA) != 0)
b8a9632333a92d73a503afe1aaa7990016c8bee9Evan Hunt fopts |= DNS_FETCHOPT_NONTA;
b8a9632333a92d73a503afe1aaa7990016c8bee9Evan Hunt
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_logcreate(val, name, type, caller, "fetch");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (dns_resolver_createfetch(val->view->resolver, name, type,
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt NULL, NULL, NULL, fopts,
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
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Start a subvalidation process.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
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;
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt unsigned int vopts = 0;
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt if (check_deadlock(val, name, type, rdataset, sigrdataset)) {
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt validator_log(val, ISC_LOG_DEBUG(3),
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt "deadlock found (create_validator)");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (DNS_R_NOVALIDSIG);
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
5d63868ad0d3865118ad294081cfa03df51d1de8Mark Andrews /* OK to clear other options, but preserve NOCDFLAG and NONTA. */
5d63868ad0d3865118ad294081cfa03df51d1de8Mark Andrews vopts |= (val->options & (DNS_VALIDATOR_NOCDFLAG|DNS_VALIDATOR_NONTA));
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_logcreate(val, name, type, caller, "validator");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = dns_validator_create(val->view, name, type,
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt rdataset, sigrdataset, NULL, vopts,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->task, action, val,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &val->subvalidator);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (result == ISC_R_SUCCESS) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->subvalidator->parent = val;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews val->subvalidator->depth = val->depth + 1;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (result);
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington}
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
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
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
708383382ff1d3fdd27527e5d63120a3c6c6d3b3Francis Dupont * Get the key that generated this signature.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic isc_result_t
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrewsget_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_result_t result;
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 unsigned int 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
3fb1637c9265cc593973326ae193783413f68699Tatuya JINMEI 神明達哉 * or closer to the DNS root.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington namereln = dns_name_fullcompare(val->event->name, &siginfo->signer,
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 &order, &nlabels);
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);
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews } else {
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews /*
49960a74b5d82d000c281af09d7c668bdd1671a1Automatic Updater * SOA and NS RRsets can only be signed by a key with
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews * the same name.
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews */
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews if (val->event->rdataset->type == dns_rdatatype_soa ||
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews val->event->rdataset->type == dns_rdatatype_ns) {
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews const char *typename;
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews if (val->event->rdataset->type == dns_rdatatype_soa)
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews typename = "SOA";
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews else
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews typename = "NS";
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews "%s signer mismatch", typename);
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews return (DNS_R_CONTINUE);
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews }
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;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if ((DNS_TRUST_PENDING(val->frdataset.trust) ||
515c7f3c43f76d7b439905b18009105364b36100Automatic Updater DNS_TRUST_ANSWER(val->frdataset.trust)) &&
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_rdataset_isassociated(&val->fsigrdataset))
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /*
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * We know the key but haven't validated it yet or
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * we have a key of trust answer but a DS/DLV
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * record for the zone may have been added.
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);
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews } else if (DNS_TRUST_PENDING(val->frdataset.trust)) {
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),
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews "keyset with trust %s",
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews dns_trust_totext(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 */
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews result = create_fetch(val, &siginfo->signer,
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews 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 ||
1bfe8851c0a2eb1d7e15556bfa21291cd62ee2bcMark Andrews result == DNS_R_EMPTYNAME ||
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;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews } else if (result == DNS_R_BROKENCHAIN)
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews return (result);
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
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
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;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dns_name_t *name;
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington isc_result_t result;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dst_key_t *dstkey;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews isc_mem_t *mctx;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews isc_boolean_t answer = ISC_FALSE;
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington rdataset = val->event->rdataset;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews sigrdataset = val->event->sigrdataset;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews name = val->event->name;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews mctx = val->view->mctx;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
dbf693fdfd2bb495cf6d176ecebd173331c3d94aMark Andrews if (rdataset->type == dns_rdatatype_cname ||
dbf693fdfd2bb495cf6d176ecebd173331c3d94aMark Andrews rdataset->type == dns_rdatatype_dname)
dbf693fdfd2bb495cf6d176ecebd173331c3d94aMark Andrews return (answer);
dbf693fdfd2bb495cf6d176ecebd173331c3d94aMark 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);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews result = dns_rdata_tostruct(&rdata, &key, NULL);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews RUNTIME_CHECK(result == ISC_R_SUCCESS);
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);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews RUNTIME_CHECK(result == ISC_R_SUCCESS);
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if (sig.algorithm != key.algorithm ||
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews sig.keyid != keytag ||
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews !dns_name_equal(name, &sig.signer))
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews continue;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dstkey = NULL;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews result = dns_dnssec_keyfromrdata(name, &rdata, mctx,
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews &dstkey);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if (result != ISC_R_SUCCESS)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews continue;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
7865ea9545f28f12f046b32d24c989e8441b9812Mark Andrews result = dns_dnssec_verify3(name, rdataset, dstkey,
7865ea9545f28f12f046b32d24c989e8441b9812Mark Andrews ISC_TRUE,
7865ea9545f28f12f046b32d24c989e8441b9812Mark Andrews val->view->maxbits,
a85c6b35affa7179434c41b277109dca2cbe01ecMark Andrews mctx, &sigrdata, NULL);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dst_key_free(&dstkey);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if (result != ISC_R_SUCCESS)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews continue;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if ((key.flags & DNS_KEYFLAG_REVOKE) == 0) {
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews answer = ISC_TRUE;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews continue;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews }
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dns_view_untrust(val->view, name, &key, mctx);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington }
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews return (answer);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Attempt to verify the rdataset using the given key and rdata (RRSIG).
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * The signature was good and from a wildcard record and the QNAME does
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * not match the wildcard we need to look for a NOQNAME proof.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Returns:
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li ISC_R_SUCCESS if the verification succeeds.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li Others if the verification fails.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic isc_result_t
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsverify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews isc_uint16_t keyid)
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews{
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_result_t result;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_fixedname_t fixed;
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews isc_boolean_t ignore = ISC_FALSE;
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews dns_name_t *wild;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->attributes |= VALATTR_TRIEDVERIFY;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_fixedname_init(&fixed);
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews wild = dns_fixedname_name(&fixed);
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews again:
7865ea9545f28f12f046b32d24c989e8441b9812Mark Andrews result = dns_dnssec_verify3(val->event->name, val->event->rdataset,
7865ea9545f28f12f046b32d24c989e8441b9812Mark Andrews key, ignore, val->view->maxbits,
7865ea9545f28f12f046b32d24c989e8441b9812Mark Andrews val->view->mctx, rdata, wild);
25845da41a621f35e76dc8560ca40de6859e0a11Evan Hunt if ((result == DNS_R_SIGEXPIRED || result == DNS_R_SIGFUTURE) &&
25845da41a621f35e76dc8560ca40de6859e0a11Evan Hunt val->view->acceptexpired)
25845da41a621f35e76dc8560ca40de6859e0a11Evan Hunt {
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews ignore = ISC_TRUE;
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews goto again;
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews }
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews if (ignore && (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD))
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews validator_log(val, ISC_LOG_INFO,
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews "accepted expired %sRRSIG (keyid=%u)",
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews (result == DNS_R_FROMWILDCARD) ?
cc7d91bd5c6b9be5a3c67a99112b885602c24873Mark Andrews "wildcard " : "", keyid);
25845da41a621f35e76dc8560ca40de6859e0a11Evan Hunt else if (result == DNS_R_SIGEXPIRED || result == DNS_R_SIGFUTURE)
25845da41a621f35e76dc8560ca40de6859e0a11Evan Hunt validator_log(val, ISC_LOG_INFO,
25845da41a621f35e76dc8560ca40de6859e0a11Evan Hunt "verify failed due to bad signature (keyid=%u): "
25845da41a621f35e76dc8560ca40de6859e0a11Evan Hunt "%s", keyid, isc_result_totext(result));
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews else
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews "verify rdataset (keyid=%u): %s",
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews keyid, isc_result_totext(result));
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (result == DNS_R_FROMWILDCARD) {
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews if (!dns_name_equal(val->event->name, wild)) {
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews dns_name_t *closest;
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews unsigned int labels;
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews /*
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews * Compute the closest encloser in case we need it
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews * for the NSEC3 NOQNAME proof.
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews */
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews closest = dns_fixedname_name(&val->closest);
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews dns_name_copy(wild, closest, NULL);
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews labels = dns_name_countlabels(closest) - 1;
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews dns_name_getlabelsequence(closest, 1, labels, closest);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews val->attributes |= VALATTR_NEEDNOQNAME;
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews }
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews result = ISC_R_SUCCESS;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (result);
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington}
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Attempts positive response validation of a normal RRset.
3ce4b8b03ebd017c1d1b320429219ba91e705ea4Andreas Gustafsson *
3ce4b8b03ebd017c1d1b320429219ba91e705ea4Andreas Gustafsson * Returns:
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li ISC_R_SUCCESS Validation completed successfully
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li DNS_R_WAIT Validation has started but is waiting
3ce4b8b03ebd017c1d1b320429219ba91e705ea4Andreas Gustafsson * for an event.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li 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) {
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt isc_result_t result, vresult = DNS_R_NOVALIDSIG;
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
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews * was known and "sufficiently good".
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (!dns_resolver_algorithm_supported(val->view->resolver,
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews event->name,
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews val->siginfo->algorithm)) {
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews resume = ISC_FALSE;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews continue;
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews }
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 /*
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews * There isn't a secure DNSKEY for this signature so move
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews * onto the next RRSIG.
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington */
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington if (val->key == NULL) {
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews resume = ISC_FALSE;
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews continue;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington }
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellington do {
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt vresult = verify(val, val->key, &rdata,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews val->siginfo->keyid);
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt if (vresult == 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);
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt if (val->key == NULL)
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt break;
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);
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt if (vresult != ISC_R_SUCCESS)
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington "failed to verify rdataset");
75f6c57d9544aa77a3b1a04587b4702c07343c90Brian Wellington else {
e7857b5ee05414961bb11f9e57f654163fae6acbckb dns_rdataset_trimttl(event->rdataset,
e7857b5ee05414961bb11f9e57f654163fae6acbckb event->sigrdataset,
0cfb24736841b3e98bb25853229a0efabab88bddEvan Hunt val->siginfo, val->start,
e7857b5ee05414961bb11f9e57f654163fae6acbckb val->view->acceptexpired);
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;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (NEEDNOQNAME(val)) {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (val->event->message == NULL) {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews "no message available for noqname proof");
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews return (DNS_R_NOVALIDSIG);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews "looking for noqname proof");
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews return (nsecvalidate(val, ISC_FALSE));
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt } else if (vresult == ISC_R_SUCCESS) {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews marksecure(event);
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt "marking as secure, "
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt "noqname proof not needed");
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt return (ISC_R_SUCCESS);
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");
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt return (vresult);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley}
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews/*%
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * Check whether this DNSKEY (keyrdata) signed the DNSKEY RRset
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * (val->event->rdataset).
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews */
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrewsstatic isc_result_t
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrewscheckkey(dns_validator_t *val, dns_rdata_t *keyrdata, isc_uint16_t keyid,
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dns_secalg_t algorithm)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews{
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dns_rdata_rrsig_t sig;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dst_key_t *dstkey = NULL;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews isc_result_t result;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews for (result = dns_rdataset_first(val->event->sigrdataset);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews result == ISC_R_SUCCESS;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews result = dns_rdataset_next(val->event->sigrdataset))
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews {
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dns_rdataset_current(val->event->sigrdataset, &rdata);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews result = dns_rdata_tostruct(&rdata, &sig, NULL);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews RUNTIME_CHECK(result == ISC_R_SUCCESS);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if (keyid != sig.keyid || algorithm != sig.algorithm)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews continue;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if (dstkey == NULL) {
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews result = dns_dnssec_keyfromrdata(val->event->name,
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews keyrdata,
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews val->view->mctx,
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews &dstkey);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if (result != ISC_R_SUCCESS)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews /*
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * This really shouldn't happen, but...
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews */
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews continue;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews }
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews result = verify(val, dstkey, &rdata, sig.keyid);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if (result == ISC_R_SUCCESS)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews break;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews }
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if (dstkey != NULL)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dst_key_free(&dstkey);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews return (result);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews}
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews/*%
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * Find the DNSKEY that corresponds to the DS.
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews */
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrewsstatic isc_result_t
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrewskeyfromds(dns_validator_t *val, dns_rdataset_t *rdataset, dns_rdata_t *dsrdata,
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews isc_uint8_t digest, isc_uint16_t keyid, dns_secalg_t algorithm,
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dns_rdata_t *keyrdata)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews{
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dns_keytag_t keytag;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dns_rdata_dnskey_t key;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews isc_result_t result;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews unsigned char dsbuf[DNS_DS_BUFFERSIZE];
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews for (result = dns_rdataset_first(rdataset);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews result == ISC_R_SUCCESS;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews result = dns_rdataset_next(rdataset))
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews {
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dns_rdata_t newdsrdata = DNS_RDATA_INIT;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dns_rdata_reset(keyrdata);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dns_rdataset_current(rdataset, keyrdata);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews result = dns_rdata_tostruct(keyrdata, &key, NULL);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews RUNTIME_CHECK(result == ISC_R_SUCCESS);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews keytag = compute_keytag(keyrdata, &key);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if (keyid != keytag || algorithm != key.algorithm)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews continue;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dns_rdata_reset(&newdsrdata);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews result = dns_ds_buildrdata(val->event->name, keyrdata, digest,
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dsbuf, &newdsrdata);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if (result != ISC_R_SUCCESS) {
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews validator_log(val, ISC_LOG_DEBUG(3),
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews "dns_ds_buildrdata() -> %s",
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dns_result_totext(result));
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews continue;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews }
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if (dns_rdata_compare(dsrdata, &newdsrdata) == 0)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews break;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews }
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews return (result);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews}
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Validate the DNSKEY RRset by looking for a DNSKEY that matches a
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * DLV record and that also verifies the DNSKEY RRset.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
50105afc551903541608b11851d73278b23579a3Mark Andrewsstatic isc_result_t
50105afc551903541608b11851d73278b23579a3Mark Andrewsdlv_validatezonekey(dns_validator_t *val) {
50105afc551903541608b11851d73278b23579a3Mark Andrews dns_rdata_dlv_t dlv;
50105afc551903541608b11851d73278b23579a3Mark Andrews dns_rdata_t dlvrdata = DNS_RDATA_INIT;
50105afc551903541608b11851d73278b23579a3Mark Andrews dns_rdata_t keyrdata = DNS_RDATA_INIT;
50105afc551903541608b11851d73278b23579a3Mark Andrews dns_rdataset_t trdataset;
50105afc551903541608b11851d73278b23579a3Mark Andrews isc_boolean_t supported_algorithm;
50105afc551903541608b11851d73278b23579a3Mark Andrews isc_result_t result;
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews char digest_types[256];
50105afc551903541608b11851d73278b23579a3Mark Andrews
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews validator_log(val, ISC_LOG_DEBUG(3), "dlv_validatezonekey");
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
50105afc551903541608b11851d73278b23579a3Mark Andrews /*
50105afc551903541608b11851d73278b23579a3Mark Andrews * Look through the DLV record and find the keys that can sign the
50105afc551903541608b11851d73278b23579a3Mark Andrews * key set and the matching signature. For each such key, attempt
50105afc551903541608b11851d73278b23579a3Mark Andrews * verification.
50105afc551903541608b11851d73278b23579a3Mark Andrews */
50105afc551903541608b11851d73278b23579a3Mark Andrews supported_algorithm = ISC_FALSE;
50105afc551903541608b11851d73278b23579a3Mark Andrews
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews /*
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman * If DNS_DSDIGEST_SHA256 or DNS_DSDIGEST_SHA384 is present we
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman * are required to prefer it over DNS_DSDIGEST_SHA1. This in
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman * practice means that we need to ignore DNS_DSDIGEST_SHA1 if a
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman * DNS_DSDIGEST_SHA256 or DNS_DSDIGEST_SHA384 is present.
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews */
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews memset(digest_types, 1, sizeof(digest_types));
fcbc5d2353971f65726a9e86c1f37c813f9c2176Mark Andrews for (result = dns_rdataset_first(&val->dlv);
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews result == ISC_R_SUCCESS;
fcbc5d2353971f65726a9e86c1f37c813f9c2176Mark Andrews result = dns_rdataset_next(&val->dlv)) {
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews dns_rdata_reset(&dlvrdata);
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews dns_rdataset_current(&val->dlv, &dlvrdata);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews result = dns_rdata_tostruct(&dlvrdata, &dlv, NULL);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews RUNTIME_CHECK(result == ISC_R_SUCCESS);
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman if (!dns_resolver_ds_digest_supported(val->view->resolver,
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman val->event->name,
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman dlv.digest_type))
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman continue;
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews if (!dns_resolver_algorithm_supported(val->view->resolver,
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews val->event->name,
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews dlv.algorithm))
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews continue;
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman if ((dlv.digest_type == DNS_DSDIGEST_SHA256 &&
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman dlv.length == ISC_SHA256_DIGESTLENGTH) ||
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman (dlv.digest_type == DNS_DSDIGEST_SHA384 &&
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman dlv.length == ISC_SHA384_DIGESTLENGTH))
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman {
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews digest_types[DNS_DSDIGEST_SHA1] = 0;
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews break;
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews }
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews }
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews for (result = dns_rdataset_first(&val->dlv);
50105afc551903541608b11851d73278b23579a3Mark Andrews result == ISC_R_SUCCESS;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews result = dns_rdataset_next(&val->dlv))
50105afc551903541608b11851d73278b23579a3Mark Andrews {
50105afc551903541608b11851d73278b23579a3Mark Andrews dns_rdata_reset(&dlvrdata);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_rdataset_current(&val->dlv, &dlvrdata);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews result = dns_rdata_tostruct(&dlvrdata, &dlv, NULL);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews RUNTIME_CHECK(result == ISC_R_SUCCESS);
50105afc551903541608b11851d73278b23579a3Mark Andrews
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews if (digest_types[dlv.digest_type] == 0)
c941e32d221fbb0cb760e3bc24c7f221c0cf8b97Mark Andrews continue;
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews if (!dns_resolver_ds_digest_supported(val->view->resolver,
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews val->event->name,
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews dlv.digest_type))
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews continue;
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews
50105afc551903541608b11851d73278b23579a3Mark Andrews if (!dns_resolver_algorithm_supported(val->view->resolver,
50105afc551903541608b11851d73278b23579a3Mark Andrews val->event->name,
50105afc551903541608b11851d73278b23579a3Mark Andrews dlv.algorithm))
50105afc551903541608b11851d73278b23579a3Mark Andrews continue;
50105afc551903541608b11851d73278b23579a3Mark Andrews
50105afc551903541608b11851d73278b23579a3Mark Andrews supported_algorithm = ISC_TRUE;
50105afc551903541608b11851d73278b23579a3Mark Andrews
50105afc551903541608b11851d73278b23579a3Mark Andrews dns_rdataset_init(&trdataset);
50105afc551903541608b11851d73278b23579a3Mark Andrews dns_rdataset_clone(val->event->rdataset, &trdataset);
50105afc551903541608b11851d73278b23579a3Mark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews /*
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * Convert to DLV to DS and find matching DNSKEY.
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews */
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dlvrdata.type = dns_rdatatype_ds;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews result = keyfromds(val, &trdataset, &dlvrdata,
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dlv.digest_type, dlv.key_tag,
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dlv.algorithm, &keyrdata);
50105afc551903541608b11851d73278b23579a3Mark Andrews if (result != ISC_R_SUCCESS) {
d2ef5b3c5c8e08694f8f755cf2f14f8ec2f248a6Mark Andrews dns_rdataset_disassociate(&trdataset);
50105afc551903541608b11851d73278b23579a3Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
cc3aafe737334d444781f8a34ffaf459e075bb9aMark Andrews "no DNSKEY matching DLV");
50105afc551903541608b11851d73278b23579a3Mark Andrews continue;
50105afc551903541608b11851d73278b23579a3Mark Andrews }
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews validator_log(val, ISC_LOG_DEBUG(3),
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews "Found matching DLV record: checking for signature");
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews /*
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * Check that this DNSKEY signed the DNSKEY rrset.
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews */
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews result = checkkey(val, &keyrdata, dlv.key_tag, dlv.algorithm);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
50105afc551903541608b11851d73278b23579a3Mark Andrews dns_rdataset_disassociate(&trdataset);
50105afc551903541608b11851d73278b23579a3Mark Andrews if (result == ISC_R_SUCCESS)
50105afc551903541608b11851d73278b23579a3Mark Andrews break;
cc3aafe737334d444781f8a34ffaf459e075bb9aMark Andrews validator_log(val, ISC_LOG_DEBUG(3),
cc3aafe737334d444781f8a34ffaf459e075bb9aMark Andrews "no RRSIG matching DLV key");
50105afc551903541608b11851d73278b23579a3Mark Andrews }
50105afc551903541608b11851d73278b23579a3Mark Andrews if (result == ISC_R_SUCCESS) {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews marksecure(val->event);
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt validator_log(val, ISC_LOG_DEBUG(3), "marking as secure (dlv)");
50105afc551903541608b11851d73278b23579a3Mark Andrews return (result);
50105afc551903541608b11851d73278b23579a3Mark Andrews } else if (result == ISC_R_NOMORE && !supported_algorithm) {
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews if (val->mustbesecure) {
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews validator_log(val, ISC_LOG_WARNING,
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt "must be secure failure,"
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt "no supported algorithm/digest (dlv)");
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews return (DNS_R_MUSTBESECURE);
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews }
50105afc551903541608b11851d73278b23579a3Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
c941e32d221fbb0cb760e3bc24c7f221c0cf8b97Mark Andrews "no supported algorithm/digest (dlv)");
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews markanswer(val, "dlv_validatezonekey (2)");
50105afc551903541608b11851d73278b23579a3Mark Andrews return (ISC_R_SUCCESS);
50105afc551903541608b11851d73278b23579a3Mark Andrews } else
50105afc551903541608b11851d73278b23579a3Mark Andrews return (DNS_R_NOVALIDSIG);
50105afc551903541608b11851d73278b23579a3Mark Andrews}
50105afc551903541608b11851d73278b23579a3Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt * Attempts positive response validation of an RRset containing zone keys
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt * (i.e. a DNSKEY rrset).
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews *
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Returns:
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li ISC_R_SUCCESS Validation completed successfully
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li DNS_R_WAIT Validation has started but is waiting
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * for an event.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li Other return codes are possible and all indicate failure.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsstatic isc_result_t
50105afc551903541608b11851d73278b23579a3Mark Andrewsvalidatezonekey(dns_validator_t *val) {
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 keyrdata = DNS_RDATA_INIT;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdata_t sigrdata = DNS_RDATA_INIT;
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews char namebuf[DNS_NAME_FORMATSIZE];
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdata_ds_t ds;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_rdata_rrsig_t sig;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dst_key_t *dstkey;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews isc_boolean_t supported_algorithm;
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews isc_boolean_t atsep = ISC_FALSE;
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews char digest_types[256];
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Caller must be holding the validator lock.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews event = val->event;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (val->havedlvsep && val->dlv.trust >= dns_trust_secure &&
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_name_equal(event->name, dns_fixedname_name(&val->dlvsep)))
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews return (dlv_validatezonekey(val));
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (val->dsset == NULL) {
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews /*
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews * We have a dlv sep. Skip looking up the SEP from
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews * {trusted,managed}-keys. If the dlv sep is for the
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews * root then it will have been handled above so we don't
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews * need to check whether val->event->name is "." prior to
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews * looking up the DS.
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews */
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews if (val->havedlvsep)
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews goto find_ds;
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews
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 {
b8d036c434d68e358c95bcb7268b5c310ed0579cMark Andrews dns_keynode_t *keynode = NULL;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_fixedname_t fixed;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_name_t *found;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_fixedname_init(&fixed);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews found = dns_fixedname_name(&fixed);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdata_reset(&sigrdata);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_current(val->event->sigrdataset,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews &sigrdata);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews RUNTIME_CHECK(result == ISC_R_SUCCESS);
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews if (!dns_name_equal(val->event->name, &sig.signer))
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews continue;
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = dns_keytable_findkeynode(val->keytable,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews val->event->name,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews sig.algorithm,
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews sig.keyid, &keynode);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (result == ISC_R_NOTFOUND &&
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_keytable_finddeepestmatch(val->keytable,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews val->event->name, found) != ISC_R_SUCCESS) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (val->mustbesecure) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews validator_log(val, ISC_LOG_WARNING,
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews "must be secure failure, "
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews "not beneath secure root");
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews return (DNS_R_MUSTBESECURE);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews } else
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews validator_log(val, ISC_LOG_DEBUG(3),
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews "not beneath secure root");
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews if (val->view->dlv == NULL) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews markanswer(val, "validatezonekey (1)");
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews return (ISC_R_SUCCESS);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews }
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews return (startfinddlvsep(val, dns_rootname));
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews }
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews if (result == DNS_R_PARTIALMATCH ||
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews result == ISC_R_SUCCESS)
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews atsep = ISC_TRUE;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews while (result == ISC_R_SUCCESS) {
b8d036c434d68e358c95bcb7268b5c310ed0579cMark Andrews dns_keynode_t *nextnode = NULL;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dstkey = dns_keynode_key(keynode);
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt if (dstkey == NULL) {
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt dns_keytable_detachkeynode(
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt val->keytable,
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt &keynode);
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt break;
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt }
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews result = verify(val, dstkey, &sigrdata,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews sig.keyid);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result == ISC_R_SUCCESS) {
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt dns_keytable_detachkeynode(
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt val->keytable,
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt &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) {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews marksecure(event);
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
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews if (atsep) {
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews /*
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews * We have not found a key to verify this DNSKEY
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews * RRset. As this is a SEP we have to assume that
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews * the RRset is invalid.
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews */
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews dns_name_format(val->event->name, namebuf,
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater sizeof(namebuf));
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews validator_log(val, ISC_LOG_NOTICE,
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews "unable to find a DNSKEY which verifies "
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt "the DNSKEY RRset and also matches a "
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt "trusted key for '%s'",
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews namebuf);
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews return (DNS_R_NOVALIDKEY);
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews }
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews /*
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews * If this is the root name and there was no trusted key,
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews * give up, since there's no DS at the root.
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews */
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews if (dns_name_equal(event->name, dns_rootname)) {
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews if ((val->attributes & VALATTR_TRIEDVERIFY) != 0) {
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews "root key failed to validate");
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews return (DNS_R_NOVALIDSIG);
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews } else {
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews "no trusted root key");
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews return (DNS_R_NOVALIDDS);
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews }
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews }
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews find_ds:
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;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if ((DNS_TRUST_PENDING(val->frdataset.trust) ||
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews DNS_TRUST_ANSWER(val->frdataset.trust)) &&
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);
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews } else if (DNS_TRUST_PENDING(val->frdataset.trust)) {
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);
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews } else {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = ISC_R_SUCCESS;
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews POST(result);
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews }
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);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews } else if (result == DNS_R_NCACHENXDOMAIN ||
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result == DNS_R_NCACHENXRRSET ||
1bfe8851c0a2eb1d7e15556bfa21291cd62ee2bcMark Andrews result == DNS_R_EMPTYNAME ||
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result == DNS_R_NXDOMAIN ||
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews result == DNS_R_NXRRSET ||
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews result == DNS_R_CNAME)
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);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews } else if (result == DNS_R_BROKENCHAIN)
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews return (result);
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) {
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews if (val->mustbesecure) {
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews validator_log(val, ISC_LOG_WARNING,
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt "must be secure failure,"
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt " insecure DS");
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews return (DNS_R_MUSTBESECURE);
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews }
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews if (val->view->dlv == NULL || DLVTRIED(val)) {
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews markanswer(val, "validatezonekey (2)");
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews return (ISC_R_SUCCESS);
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews }
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews return (startfinddlvsep(val, val->event->name));
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
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews supported_algorithm = ISC_FALSE;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews /*
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman * If DNS_DSDIGEST_SHA256 or DNS_DSDIGEST_SHA384 is present we
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman * are required to prefer it over DNS_DSDIGEST_SHA1. This in
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman * practice means that we need to ignore DNS_DSDIGEST_SHA1 if a
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman * DNS_DSDIGEST_SHA256 or DNS_DSDIGEST_SHA384 is present.
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews */
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews memset(digest_types, 1, sizeof(digest_types));
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews for (result = dns_rdataset_first(val->dsset);
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews result == ISC_R_SUCCESS;
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews result = dns_rdataset_next(val->dsset)) {
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews dns_rdata_reset(&dsrdata);
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews dns_rdataset_current(val->dsset, &dsrdata);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews result = dns_rdata_tostruct(&dsrdata, &ds, NULL);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews RUNTIME_CHECK(result == ISC_R_SUCCESS);
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman if (!dns_resolver_ds_digest_supported(val->view->resolver,
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman val->event->name,
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman ds.digest_type))
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman continue;
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews if (!dns_resolver_algorithm_supported(val->view->resolver,
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews val->event->name,
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews ds.algorithm))
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews continue;
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman if ((ds.digest_type == DNS_DSDIGEST_SHA256 &&
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman ds.length == ISC_SHA256_DIGESTLENGTH) ||
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman (ds.digest_type == DNS_DSDIGEST_SHA384 &&
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman ds.length == ISC_SHA384_DIGESTLENGTH))
9540b42695c15fdd5f01b4c663e21936e6c38c82Mukund Sivaraman {
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews digest_types[DNS_DSDIGEST_SHA1] = 0;
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews break;
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews }
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews }
c5387e694299c41361660e54f23e89c7da3ede1dMark 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);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews result = dns_rdata_tostruct(&dsrdata, &ds, NULL);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews RUNTIME_CHECK(result == ISC_R_SUCCESS);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews if (digest_types[ds.digest_type] == 0)
c941e32d221fbb0cb760e3bc24c7f221c0cf8b97Mark Andrews continue;
c941e32d221fbb0cb760e3bc24c7f221c0cf8b97Mark Andrews
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews if (!dns_resolver_ds_digest_supported(val->view->resolver,
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews val->event->name,
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews ds.digest_type))
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews continue;
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (!dns_resolver_algorithm_supported(val->view->resolver,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews val->event->name,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews ds.algorithm))
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews continue;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews supported_algorithm = ISC_TRUE;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_init(&trdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_clone(val->event->rdataset, &trdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews /*
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * Find matching DNSKEY from DS.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews result = keyfromds(val, &trdataset, &dsrdata, ds.digest_type,
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews ds.key_tag, ds.algorithm, &keyrdata);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result != ISC_R_SUCCESS) {
d2ef5b3c5c8e08694f8f755cf2f14f8ec2f248a6Mark Andrews dns_rdataset_disassociate(&trdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
cc3aafe737334d444781f8a34ffaf459e075bb9aMark Andrews "no DNSKEY matching DS");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews continue;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews /*
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * Check that this DNSKEY signed the DNSKEY rrset.
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews */
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews result = checkkey(val, &keyrdata, ds.key_tag, ds.algorithm);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_disassociate(&trdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result == ISC_R_SUCCESS)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews break;
cc3aafe737334d444781f8a34ffaf459e075bb9aMark Andrews validator_log(val, ISC_LOG_DEBUG(3),
cc3aafe737334d444781f8a34ffaf459e075bb9aMark Andrews "no RRSIG matching DS key");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result == ISC_R_SUCCESS) {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews marksecure(event);
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt validator_log(val, ISC_LOG_DEBUG(3), "marking as secure (DS)");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (result);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews } else if (result == ISC_R_NOMORE && !supported_algorithm) {
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews if (val->mustbesecure) {
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews validator_log(val, ISC_LOG_WARNING,
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt "must be secure failure, "
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt "no supported algorithm/digest (DS)");
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews return (DNS_R_MUSTBESECURE);
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews }
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews "no supported algorithm/digest (DS)");
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews markanswer(val, "validatezonekey (3)");
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews return (ISC_R_SUCCESS);
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt } else {
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt validator_log(val, ISC_LOG_INFO,
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt "no valid signature found (DS)");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (DNS_R_NOVALIDSIG);
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Starts a positive response validation.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews *
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Returns:
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li ISC_R_SUCCESS Validation completed successfully
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li DNS_R_WAIT Validation has started but is waiting
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * for an event.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li 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
50105afc551903541608b11851d73278b23579a3Mark Andrews return (validatezonekey(val));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews/*%
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * val_rdataset_first and val_rdataset_next provide iteration methods
515c7f3c43f76d7b439905b18009105364b36100Automatic Updater * that hide whether we are iterating across a message or a negative
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * cache rdataset.
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews */
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrewsstatic isc_result_t
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrewsval_rdataset_first(dns_validator_t *val, dns_name_t **namep,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_t **rdatasetp)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews{
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_message_t *message = val->event->message;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews isc_result_t result;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE(rdatasetp != NULL);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE(namep != NULL);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (message == NULL) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE(*rdatasetp != NULL);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE(*namep != NULL);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews } else {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE(*rdatasetp == NULL);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE(*namep == NULL);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews }
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (message != NULL) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (result != ISC_R_SUCCESS)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews return (result);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_message_currentname(message, DNS_SECTION_AUTHORITY, namep);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews *rdatasetp = ISC_LIST_HEAD((*namep)->list);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews INSIST(*rdatasetp != NULL);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews } else {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = dns_rdataset_first(val->event->rdataset);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (result == ISC_R_SUCCESS)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_ncache_current(val->event->rdataset, *namep,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews *rdatasetp);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews }
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews return (result);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews}
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrewsstatic isc_result_t
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrewsval_rdataset_next(dns_validator_t *val, dns_name_t **namep,
515c7f3c43f76d7b439905b18009105364b36100Automatic Updater dns_rdataset_t **rdatasetp)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews{
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_message_t *message = val->event->message;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews isc_result_t result = ISC_R_SUCCESS;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE(rdatasetp != NULL && *rdatasetp != NULL);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE(namep != NULL && *namep != NULL);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (message != NULL) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_t *rdataset = *rdatasetp;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset = ISC_LIST_NEXT(rdataset, link);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (rdataset == NULL) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews *namep = NULL;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = dns_message_nextname(message,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews DNS_SECTION_AUTHORITY);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (result == ISC_R_SUCCESS) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_message_currentname(message,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews DNS_SECTION_AUTHORITY,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews namep);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset = ISC_LIST_HEAD((*namep)->list);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews INSIST(rdataset != NULL);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews }
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews }
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews *rdatasetp = rdataset;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews } else {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_disassociate(*rdatasetp);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = dns_rdataset_next(val->event->rdataset);
515c7f3c43f76d7b439905b18009105364b36100Automatic Updater if (result == ISC_R_SUCCESS)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_ncache_current(val->event->rdataset, *namep,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews *rdatasetp);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews }
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews return (result);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews}
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Look for NODATA at the wildcard and NOWILDCARD proofs in the
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * previously validated NSEC records. As these proofs are mutually
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * exclusive we stop when one is found.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Returns
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater * \li ISC_R_SUCCESS
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrewsstatic isc_result_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewscheckwildcard(dns_validator_t *val, dns_rdatatype_t type, dns_name_t *zonename)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews{
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_name_t *name, *wild, tname;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews isc_result_t result;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews isc_boolean_t exists, data;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews char namebuf[DNS_NAME_FORMATSIZE];
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_t *rdataset, trdataset;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_name_init(&tname, NULL);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_init(&trdataset);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews wild = dns_fixedname_name(&val->wild);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (dns_name_countlabels(wild) == 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews validator_log(val, ISC_LOG_DEBUG(3),
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews "in checkwildcard: no wildcard to check");
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_R_SUCCESS);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_name_format(wild, namebuf, sizeof(namebuf));
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews validator_log(val, ISC_LOG_DEBUG(3), "in checkwildcard: %s", namebuf);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (val->event->message == NULL) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews name = &tname;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset = &trdataset;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews } else {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews name = NULL;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset = NULL;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews }
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews for (result = val_rdataset_first(val, &name, &rdataset);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews result == ISC_R_SUCCESS;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = val_rdataset_next(val, &name, &rdataset))
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (rdataset->type != type ||
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset->trust != dns_trust_secure)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews continue;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (rdataset->type == dns_rdatatype_nsec &&
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews (NEEDNODATA(val) || NEEDNOWILDCARD(val)) &&
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews !FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) &&
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews dns_nsec_noexistnodata(val->event->type, wild, name,
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews rdataset, &exists, &data, NULL,
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews validator_log, val)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews == ISC_R_SUCCESS)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_name_t **proofs = val->event->proofs;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (exists && !data)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews val->attributes |= VALATTR_FOUNDNODATA;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (exists && !data && NEEDNODATA(val))
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews proofs[DNS_VALIDATOR_NODATAPROOF] =
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews name;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (!exists)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews val->attributes |=
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews VALATTR_FOUNDNOWILDCARD;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (!exists && NEEDNOQNAME(val))
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews proofs[DNS_VALIDATOR_NOWILDCARDPROOF] =
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews name;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (dns_rdataset_isassociated(&trdataset))
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_disassociate(&trdataset);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews return (ISC_R_SUCCESS);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (rdataset->type == dns_rdatatype_nsec3 &&
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews (NEEDNODATA(val) || NEEDNOWILDCARD(val)) &&
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews !FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) &&
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews dns_nsec3_noexistnodata(val->event->type, wild, name,
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews rdataset, zonename, &exists, &data,
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews NULL, NULL, NULL, NULL, NULL, NULL,
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews validator_log, val)
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews == ISC_R_SUCCESS)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_name_t **proofs = val->event->proofs;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (exists && !data)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews val->attributes |= VALATTR_FOUNDNODATA;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (exists && !data && NEEDNODATA(val))
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews proofs[DNS_VALIDATOR_NODATAPROOF] =
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews name;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (!exists)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews val->attributes |=
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews VALATTR_FOUNDNOWILDCARD;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (!exists && NEEDNOQNAME(val))
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews proofs[DNS_VALIDATOR_NOWILDCARDPROOF] =
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews name;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (dns_rdataset_isassociated(&trdataset))
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_disassociate(&trdataset);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews return (ISC_R_SUCCESS);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (result == ISC_R_NOMORE)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews result = ISC_R_SUCCESS;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (dns_rdataset_isassociated(&trdataset))
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_disassociate(&trdataset);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews return (result);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews}
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsstatic isc_result_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsfindnsec3proofs(dns_validator_t *val) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_name_t *name, tname;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_result_t result;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_boolean_t exists, data, optout, unknown;
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews isc_boolean_t setclosest, setnearest, *setclosestp;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_fixedname_t fclosest, fnearest, fzonename;
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews dns_name_t *closest, *nearest, *zonename, *closestp;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_name_t **proofs = val->event->proofs;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_t *rdataset, trdataset;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_name_init(&tname, NULL);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_init(&trdataset);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_fixedname_init(&fclosest);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_fixedname_init(&fnearest);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_fixedname_init(&fzonename);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews closest = dns_fixedname_name(&fclosest);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews nearest = dns_fixedname_name(&fnearest);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews zonename = dns_fixedname_name(&fzonename);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (val->event->message == NULL) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews name = &tname;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset = &trdataset;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews } else {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews name = NULL;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset = NULL;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews for (result = val_rdataset_first(val, &name, &rdataset);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result == ISC_R_SUCCESS;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = val_rdataset_next(val, &name, &rdataset))
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (rdataset->type != dns_rdatatype_nsec3 ||
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset->trust != dns_trust_secure)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews continue;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews result = dns_nsec3_noexistnodata(val->event->type,
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews val->event->name, name,
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews rdataset, zonename, NULL,
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews NULL, NULL, NULL, NULL, NULL,
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews NULL, NULL, validator_log,
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews val);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (result != ISC_R_IGNORE && result != ISC_R_SUCCESS) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (dns_rdataset_isassociated(&trdataset))
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_disassociate(&trdataset);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews return (result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result != ISC_R_NOMORE)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = ISC_R_SUCCESS;
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews POST(result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (dns_name_countlabels(zonename) == 0)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_R_SUCCESS);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews /*
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews * If the val->closest is set then we want to use it otherwise
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews * we need to discover it.
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews */
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews if (dns_name_countlabels(dns_fixedname_name(&val->closest)) != 0) {
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews char namebuf[DNS_NAME_FORMATSIZE];
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews dns_name_format(dns_fixedname_name(&val->closest),
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews namebuf, sizeof(namebuf));
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews validator_log(val, ISC_LOG_DEBUG(3), "closest encloser from "
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews "wildcard signature '%s'", namebuf);
dfc015bc7e99019373878f8eb4527f5ebd0e0969Automatic Updater dns_name_copy(dns_fixedname_name(&val->closest), closest, NULL);
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews closestp = NULL;
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews setclosestp = NULL;
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews } else {
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews closestp = closest;
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews setclosestp = &setclosest;
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews }
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews for (result = val_rdataset_first(val, &name, &rdataset);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result == ISC_R_SUCCESS;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = val_rdataset_next(val, &name, &rdataset))
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (rdataset->type != dns_rdatatype_nsec3 ||
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset->trust != dns_trust_secure)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews continue;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews /*
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * We process all NSEC3 records to find the closest
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * encloser and nearest name to the closest encloser.
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews */
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews setclosest = setnearest = ISC_FALSE;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews optout = ISC_FALSE;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews unknown = ISC_FALSE;
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews result = dns_nsec3_noexistnodata(val->event->type,
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews val->event->name,
b16174507d1429ae4dbf7b4939f9e45ca7b76d74Tinderbox User name, rdataset, zonename,
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews &exists, &data, &optout,
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews &unknown, setclosestp,
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews &setnearest, closestp,
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrews nearest, validator_log, val);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (unknown)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews val->attributes |= VALATTR_FOUNDUNKNOWN;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (result != ISC_R_SUCCESS)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews continue;
41bbb34bc20f189af62e7047ce42822615417f15Evan Hunt if (setclosest)
41bbb34bc20f189af62e7047ce42822615417f15Evan Hunt proofs[DNS_VALIDATOR_CLOSESTENCLOSER] = name;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (exists && !data && NEEDNODATA(val)) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews val->attributes |= VALATTR_FOUNDNODATA;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews proofs[DNS_VALIDATOR_NODATAPROOF] = name;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews }
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (!exists && setnearest) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews val->attributes |= VALATTR_FOUNDNOQNAME;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews proofs[DNS_VALIDATOR_NOQNAMEPROOF] = name;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (optout)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews val->attributes |= VALATTR_FOUNDOPTOUT;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (result == ISC_R_NOMORE)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = ISC_R_SUCCESS;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * To know we have a valid noqname and optout proofs we need to also
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * have a valid closest encloser. Otherwise we could still be looking
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * at proofs from the parent zone.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (dns_name_countlabels(closest) > 0 &&
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_name_countlabels(nearest) ==
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_name_countlabels(closest) + 1 &&
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_name_issubdomain(nearest, closest))
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews val->attributes |= VALATTR_FOUNDCLOSEST;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = dns_name_concatenate(dns_wildcardname, closest,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_fixedname_name(&val->wild),
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RUNTIME_CHECK(result == ISC_R_SUCCESS);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews } else {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews val->attributes &= ~VALATTR_FOUNDNOQNAME;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews val->attributes &= ~VALATTR_FOUNDOPTOUT;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews proofs[DNS_VALIDATOR_NOQNAMEPROOF] = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Do we need to check for the wildcard?
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val) &&
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews ((NEEDNODATA(val) && !FOUNDNODATA(val)) || NEEDNOWILDCARD(val))) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = checkwildcard(val, dns_rdatatype_nsec3, zonename);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result != ISC_R_SUCCESS)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * Validate the authority section records.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic isc_result_t
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrewsvalidate_authority(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
810656a187f2c358323bbf679f792f19a46a7973Mark Andrews if (!resume)
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
810656a187f2c358323bbf679f792f19a46a7973Mark Andrews else
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington result = ISC_R_SUCCESS;
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;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews } 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
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 }
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
cc3aafe737334d444781f8a34ffaf459e075bb9aMark Andrews * would trigger another query for the DNSKEY (since
cc3aafe737334d444781f8a34ffaf459e075bb9aMark Andrews * the 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 &&
d31740ce282bcf0a27e17dec49a3ff9ddd26e814Scott Mann rdataset->type == dns_rdatatype_nsec &&
32b2cdf212de957e3f9b0efca59f098ed4fb42deBrian Wellington dns_name_equal(name, val->event->name))
32b2cdf212de957e3f9b0efca59f098ed4fb42deBrian Wellington {
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_rdata_t nsec = DNS_RDATA_INIT;
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,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews "validate_authority");
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington if (result != ISC_R_SUCCESS)
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington return (result);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews val->authcount++;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington return (DNS_R_WAIT);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews }
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews }
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (result == ISC_R_NOMORE)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = ISC_R_SUCCESS;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews return (result);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews}
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews/*%
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * Validate the ncache elements.
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews */
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrewsstatic isc_result_t
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrewsvalidate_ncache(dns_validator_t *val, isc_boolean_t resume) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_name_t *name;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews isc_result_t result;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
810656a187f2c358323bbf679f792f19a46a7973Mark Andrews if (!resume)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = dns_rdataset_first(val->event->rdataset);
810656a187f2c358323bbf679f792f19a46a7973Mark Andrews else
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = dns_rdataset_next(val->event->rdataset);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews for (;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result == ISC_R_SUCCESS;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = dns_rdataset_next(val->event->rdataset))
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_t *rdataset, *sigrdataset = NULL;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (dns_rdataset_isassociated(&val->frdataset))
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_disassociate(&val->frdataset);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (dns_rdataset_isassociated(&val->fsigrdataset))
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_disassociate(&val->fsigrdataset);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_fixedname_init(&val->fname);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews name = dns_fixedname_name(&val->fname);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset = &val->frdataset;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_ncache_current(val->event->rdataset, name, rdataset);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (val->frdataset.type == dns_rdatatype_rrsig)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews continue;
515c7f3c43f76d7b439905b18009105364b36100Automatic Updater
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = dns_ncache_getsigrdataset(val->event->rdataset, name,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset->type,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews &val->fsigrdataset);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (result == ISC_R_SUCCESS)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews sigrdataset = &val->fsigrdataset;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews /*
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * If a signed zone is missing the zone key, bad
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * things could happen. A query for data in the zone
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * would lead to a query for the zone key, which
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * would return a negative answer, which would contain
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * an SOA and an NSEC signed by the missing key, which
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * would trigger another query for the DNSKEY (since
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * the first one is still in progress), and go into an
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * infinite loop. Avoid that.
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews */
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (val->event->type == dns_rdatatype_dnskey &&
d31740ce282bcf0a27e17dec49a3ff9ddd26e814Scott Mann rdataset->type == dns_rdatatype_nsec &&
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_name_equal(name, val->event->name))
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdata_t nsec = DNS_RDATA_INIT;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = dns_rdataset_first(rdataset);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (result != ISC_R_SUCCESS)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews return (result);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_current(rdataset, &nsec);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (dns_nsec_typepresent(&nsec,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdatatype_soa))
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews continue;
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington }
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews val->currentset = rdataset;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = create_validator(val, name, rdataset->type,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset, sigrdataset,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews authvalidated,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews "validate_ncache");
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (result != ISC_R_SUCCESS)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews return (result);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews val->authcount++;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews return (DNS_R_WAIT);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington }
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington if (result == ISC_R_NOMORE)
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington result = ISC_R_SUCCESS;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews return (result);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews}
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews/*%
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * Prove a negative answer is good or that there is a NOQNAME when the
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * answer is from a wildcard.
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews *
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * Loop through the authority section looking for NODATA, NOWILDCARD
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * and NOQNAME proofs in the NSEC records by calling authvalidated().
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews *
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * If the required proofs are found we are done.
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews *
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * If the proofs are not found attempt to prove this is a unsecure
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * response.
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews */
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrewsstatic isc_result_t
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrewsnsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews isc_result_t result;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (resume)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews validator_log(val, ISC_LOG_DEBUG(3), "resuming nsecvalidate");
515c7f3c43f76d7b439905b18009105364b36100Automatic Updater
515c7f3c43f76d7b439905b18009105364b36100Automatic Updater if (val->event->message == NULL)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = validate_ncache(val, resume);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews else
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = validate_authority(val, resume);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington if (result != ISC_R_SUCCESS)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (result);
777ac454c0cdec27dc11d80b9b2a8d7239d833a8Brian Wellington
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews /*
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Do we only need to check for NOQNAME? To get here we must have
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * had a secure wildcard answer.
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews */
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (!NEEDNODATA(val) && !NEEDNOWILDCARD(val) && NEEDNOQNAME(val)) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (!FOUNDNOQNAME(val))
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews findnsec3proofs(val);
2fa1fc53324c0fca978c902e883c7cc011210536Mark Andrews if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val) &&
2fa1fc53324c0fca978c902e883c7cc011210536Mark Andrews !FOUNDOPTOUT(val)) {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt "marking as secure, noqname proof found");
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews marksecure(val->event);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews return (ISC_R_SUCCESS);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews } else if (FOUNDOPTOUT(val) &&
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_name_countlabels(dns_fixedname_name(&val->wild))
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews != 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews validator_log(val, ISC_LOG_DEBUG(3),
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews "optout proof found");
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews val->event->optout = ISC_TRUE;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews markanswer(val, "nsecvalidate (1)");
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_R_SUCCESS);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews } else if ((val->attributes & VALATTR_FOUNDUNKNOWN) != 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews validator_log(val, ISC_LOG_DEBUG(3),
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews "unknown NSEC3 hash algorithm found");
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews markanswer(val, "nsecvalidate (2)");
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_R_SUCCESS);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews "noqname proof not found");
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews return (DNS_R_NOVALIDNSEC);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (!FOUNDNOQNAME(val) && !FOUNDNODATA(val))
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews findnsec3proofs(val);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews /*
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews * Do we need to check for the wildcard?
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews */
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val) &&
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews ((NEEDNODATA(val) && !FOUNDNODATA(val)) || NEEDNOWILDCARD(val))) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = checkwildcard(val, dns_rdatatype_nsec, NULL);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (result != ISC_R_SUCCESS)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews return (result);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if ((NEEDNODATA(val) && (FOUNDNODATA(val) || FOUNDOPTOUT(val))) ||
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews (NEEDNOQNAME(val) && FOUNDNOQNAME(val) &&
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews NEEDNOWILDCARD(val) && FOUNDNOWILDCARD(val) &&
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews FOUNDCLOSEST(val))) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if ((val->attributes & VALATTR_FOUNDOPTOUT) != 0)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews val->event->optout = ISC_TRUE;
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3),
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews "nonexistence proof(s) found");
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (val->event->message == NULL)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews marksecure(val->event);
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrews else
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrews val->event->secure = ISC_TRUE;
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington return (ISC_R_SUCCESS);
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington }
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
bb6d33103e672d21429ae1837ce10d91f2419800Mark Andrews if (val->authfail != 0 && val->authcount == val->authfail)
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews return (DNS_R_BROKENCHAIN);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews validator_log(val, ISC_LOG_DEBUG(3),
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews "nonexistence proof(s) not found");
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews val->attributes |= VALATTR_INSECURITY;
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews return (proveunsecure(val, ISC_FALSE, ISC_FALSE));
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington}
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrewsstatic isc_boolean_t
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrewscheck_ds(dns_validator_t *val, dns_name_t *name, dns_rdataset_t *rdataset) {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_rdata_t dsrdata = DNS_RDATA_INIT;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_rdata_ds_t ds;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews isc_result_t result;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews for (result = dns_rdataset_first(rdataset);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews result == ISC_R_SUCCESS;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews result = dns_rdataset_next(rdataset)) {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_rdataset_current(rdataset, &dsrdata);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews result = dns_rdata_tostruct(&dsrdata, &ds, NULL);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews RUNTIME_CHECK(result == ISC_R_SUCCESS);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews if (dns_resolver_ds_digest_supported(val->view->resolver,
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews name, ds.digest_type) &&
c941e32d221fbb0cb760e3bc24c7f221c0cf8b97Mark Andrews dns_resolver_algorithm_supported(val->view->resolver,
c941e32d221fbb0cb760e3bc24c7f221c0cf8b97Mark Andrews name, ds.algorithm)) {
c941e32d221fbb0cb760e3bc24c7f221c0cf8b97Mark Andrews dns_rdata_reset(&dsrdata);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews return (ISC_TRUE);
c941e32d221fbb0cb760e3bc24c7f221c0cf8b97Mark Andrews }
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_rdata_reset(&dsrdata);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews return (ISC_FALSE);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews}
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
0cae66577c69c89086cd065bb297690072b471b4Mark Andrewsstatic void
0cae66577c69c89086cd065bb297690072b471b4Mark Andrewsdlvvalidated(isc_task_t *task, isc_event_t *event) {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_validatorevent_t *devent;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_validator_t *val;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews isc_result_t eresult;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews isc_boolean_t want_destroy;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews UNUSED(task);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews devent = (dns_validatorevent_t *)event;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews val = devent->ev_arg;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews eresult = devent->result;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews isc_event_free(&event);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_validator_destroy(&val->subvalidator);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews INSIST(val->event != NULL);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews validator_log(val, ISC_LOG_DEBUG(3), "in dlvvalidated");
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews LOCK(&val->lock);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews if (CANCELED(val)) {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews validator_done(val, ISC_R_CANCELED);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews } else if (eresult == ISC_R_SUCCESS) {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews "dlvset with trust %s",
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews dns_trust_totext(val->frdataset.trust));
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_rdataset_clone(&val->frdataset, &val->dlv);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews val->havedlvsep = ISC_TRUE;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews if (dlv_algorithm_supported(val))
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dlv_validator_start(val);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews else {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews markanswer(val, "dlvvalidated");
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews validator_done(val, ISC_R_SUCCESS);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews }
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews } else {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews if (eresult != DNS_R_BROKENCHAIN) {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews if (dns_rdataset_isassociated(&val->frdataset))
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_rdataset_expire(&val->frdataset);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews if (dns_rdataset_isassociated(&val->fsigrdataset))
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_rdataset_expire(&val->fsigrdataset);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews }
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews "dlvvalidated: got %s",
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews isc_result_totext(eresult));
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews validator_done(val, DNS_R_BROKENCHAIN);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews }
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews want_destroy = exit_check(val);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews UNLOCK(&val->lock);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews if (want_destroy)
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews destroy(val);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews}
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Callback from fetching a DLV record.
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Resumes the DLV lookup process.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrewsstatic void
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrewsdlvfetched(isc_task_t *task, isc_event_t *event) {
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews char namebuf[DNS_NAME_FORMATSIZE];
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_fetchevent_t *devent;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_validator_t *val;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_boolean_t want_destroy;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_result_t eresult;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_result_t result;
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews dns_fetch_t *fetch;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews UNUSED(task);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews devent = (dns_fetchevent_t *)event;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews val = devent->ev_arg;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews eresult = devent->result;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews /* Free resources which are not of interest. */
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews if (devent->node != NULL)
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews dns_db_detachnode(devent->db, &devent->node);
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews if (devent->db != NULL)
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews dns_db_detach(&devent->db);
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews if (dns_rdataset_isassociated(&val->fsigrdataset))
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews dns_rdataset_disassociate(&val->fsigrdataset);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_event_free(&event);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews INSIST(val->event != NULL);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews validator_log(val, ISC_LOG_DEBUG(3), "in dlvfetched: %s",
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_result_totext(eresult));
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews LOCK(&val->lock);
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews fetch = val->fetch;
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews val->fetch = NULL;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (eresult == ISC_R_SUCCESS) {
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_name_format(dns_fixedname_name(&val->dlvsep), namebuf,
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews sizeof(namebuf));
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_rdataset_clone(&val->frdataset, &val->dlv);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews val->havedlvsep = ISC_TRUE;
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews if (dlv_algorithm_supported(val)) {
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found",
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews namebuf);
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews dlv_validator_start(val);
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews } else {
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews "DLV %s found with no supported algorithms",
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews namebuf);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews markanswer(val, "dlvfetched (1)");
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews validator_done(val, ISC_R_SUCCESS);
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews } else if (eresult == DNS_R_NXRRSET ||
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews eresult == DNS_R_NXDOMAIN ||
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews eresult == DNS_R_NCACHENXRRSET ||
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews eresult == DNS_R_NCACHENXDOMAIN) {
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews result = finddlvsep(val, ISC_TRUE);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (result == ISC_R_SUCCESS) {
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews if (dlv_algorithm_supported(val)) {
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews dns_name_format(dns_fixedname_name(&val->dlvsep),
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews namebuf, sizeof(namebuf));
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews "DLV %s found", namebuf);
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews dlv_validator_start(val);
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews } else {
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews "DLV %s found with no supported "
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews "algorithms", namebuf);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews markanswer(val, "dlvfetched (2)");
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews validator_done(val, ISC_R_SUCCESS);
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews } else if (result == ISC_R_NOTFOUND) {
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews validator_log(val, ISC_LOG_DEBUG(3), "DLV not found");
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews markanswer(val, "dlvfetched (3)");
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews validator_done(val, ISC_R_SUCCESS);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews } else {
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s",
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_result_totext(result));
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (result != DNS_R_WAIT)
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews validator_done(val, result);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews }
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews } else {
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s",
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_result_totext(eresult));
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews validator_done(val, eresult);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews want_destroy = exit_check(val);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews UNLOCK(&val->lock);
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews if (fetch != NULL)
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews dns_resolver_destroyfetch(&fetch);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (want_destroy)
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews destroy(val);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews}
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
708383382ff1d3fdd27527e5d63120a3c6c6d3b3Francis Dupont * Start the DLV lookup process.
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Returns
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li ISC_R_SUCCESS
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li DNS_R_WAIT
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li Others on validation failures.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrewsstatic isc_result_t
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrewsstartfinddlvsep(dns_validator_t *val, dns_name_t *unsecure) {
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews char namebuf[DNS_NAME_FORMATSIZE];
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews isc_result_t result;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews INSIST(!DLVTRIED(val));
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews val->attributes |= VALATTR_DLVTRIED;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_name_format(unsecure, namebuf, sizeof(namebuf));
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews validator_log(val, ISC_LOG_DEBUG(3),
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews "plain DNSSEC returns unsecure (%s): looking for DLV",
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews namebuf);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (dns_name_issubdomain(val->event->name, val->view->dlv)) {
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt validator_log(val, ISC_LOG_WARNING, "must be secure failure, "
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt " %s is under DLV (startfinddlvsep)", namebuf);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews return (DNS_R_MUSTBESECURE);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews }
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews val->dlvlabels = dns_name_countlabels(unsecure) - 1;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews result = finddlvsep(val, ISC_FALSE);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (result == ISC_R_NOTFOUND) {
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews validator_log(val, ISC_LOG_DEBUG(3), "DLV not found");
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews markanswer(val, "startfinddlvsep (1)");
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews return (ISC_R_SUCCESS);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews }
0cfb24736841b3e98bb25853229a0efabab88bddEvan Hunt if (result == DNS_R_NTACOVERED) {
0cfb24736841b3e98bb25853229a0efabab88bddEvan Hunt validator_log(val, ISC_LOG_DEBUG(3), "DLV covered by NTA");
0cfb24736841b3e98bb25853229a0efabab88bddEvan Hunt validator_done(val, ISC_R_SUCCESS);
0cfb24736841b3e98bb25853229a0efabab88bddEvan Hunt return (ISC_R_SUCCESS);
0cfb24736841b3e98bb25853229a0efabab88bddEvan Hunt }
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (result != ISC_R_SUCCESS) {
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s",
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_result_totext(result));
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews return (result);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews }
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_name_format(dns_fixedname_name(&val->dlvsep), namebuf,
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews sizeof(namebuf));
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews if (dlv_algorithm_supported(val)) {
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found", namebuf);
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews dlv_validator_start(val);
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews return (DNS_R_WAIT);
8e3d340655954c2331abc46c444986d5c93d98beAutomatic Updater }
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found with no supported "
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews "algorithms", namebuf);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews markanswer(val, "startfinddlvsep (2)");
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews validator_done(val, ISC_R_SUCCESS);
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews return (ISC_R_SUCCESS);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews}
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Continue the DLV lookup process.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Returns
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li ISC_R_SUCCESS
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li ISC_R_NOTFOUND
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li DNS_R_WAIT
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li Others on validation failure.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrewsstatic isc_result_t
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrewsfinddlvsep(dns_validator_t *val, isc_boolean_t resume) {
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews char namebuf[DNS_NAME_FORMATSIZE];
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_fixedname_t dlvfixed;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_name_t *dlvname;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_name_t *dlvsep;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_name_t noroot;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_result_t result;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews unsigned int labels;
676619a22fbc760875adb00b58aaef6a22ced18aMark Andrews
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews INSIST(val->view->dlv != NULL);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (!resume) {
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (dns_name_issubdomain(val->event->name, val->view->dlv)) {
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt dns_name_format(val->event->name, namebuf,
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt sizeof(namebuf));
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews validator_log(val, ISC_LOG_WARNING,
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt "must be secure failure, "
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt "%s is under DLV (finddlvsep)", namebuf);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews return (DNS_R_MUSTBESECURE);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews }
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
676619a22fbc760875adb00b58aaef6a22ced18aMark Andrews dns_fixedname_init(&val->dlvsep);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dlvsep = dns_fixedname_name(&val->dlvsep);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_name_copy(val->event->name, dlvsep, NULL);
8bedd9647f4d6894e12a8c94d3ccc624dddcee50Mark Andrews /*
8bedd9647f4d6894e12a8c94d3ccc624dddcee50Mark Andrews * If this is a response to a DS query, we need to look in
8bedd9647f4d6894e12a8c94d3ccc624dddcee50Mark Andrews * the parent zone for the trust anchor.
8bedd9647f4d6894e12a8c94d3ccc624dddcee50Mark Andrews */
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (val->event->type == dns_rdatatype_ds) {
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews labels = dns_name_countlabels(dlvsep);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (labels == 0)
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews return (ISC_R_NOTFOUND);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_name_getlabelsequence(dlvsep, 1, labels - 1,
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dlvsep);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews } else {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dlvsep = dns_fixedname_name(&val->dlvsep);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews labels = dns_name_countlabels(dlvsep);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_name_init(&noroot, NULL);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_fixedname_init(&dlvfixed);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dlvname = dns_fixedname_name(&dlvfixed);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews labels = dns_name_countlabels(dlvsep);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (labels == 0)
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews return (ISC_R_NOTFOUND);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_name_getlabelsequence(dlvsep, 0, labels - 1, &noroot);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews result = dns_name_concatenate(&noroot, val->view->dlv, dlvname, NULL);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews while (result == ISC_R_NOSPACE) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews labels = dns_name_countlabels(dlvsep);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_name_getlabelsequence(dlvsep, 0, labels - 2, &noroot);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews result = dns_name_concatenate(&noroot, val->view->dlv,
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dlvname, NULL);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (result != ISC_R_SUCCESS) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews validator_log(val, ISC_LOG_DEBUG(2), "DLV concatenate failed");
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews return (DNS_R_NOVALIDSIG);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
b8a9632333a92d73a503afe1aaa7990016c8bee9Evan Hunt if (((val->options & DNS_VALIDATOR_NONTA) == 0) &&
b8a9632333a92d73a503afe1aaa7990016c8bee9Evan Hunt dns_view_ntacovers(val->view, val->start, dlvname, val->view->dlv))
0cfb24736841b3e98bb25853229a0efabab88bddEvan Hunt return (DNS_R_NTACOVERED);
0cfb24736841b3e98bb25853229a0efabab88bddEvan Hunt
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews while (dns_name_countlabels(dlvname) >=
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_name_countlabels(val->view->dlv) + val->dlvlabels) {
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_name_format(dlvname, namebuf, sizeof(namebuf));
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews validator_log(val, ISC_LOG_DEBUG(3), "looking for DLV %s",
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews namebuf);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews result = view_find(val, dlvname, dns_rdatatype_dlv);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (result == ISC_R_SUCCESS) {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews if (DNS_TRUST_PENDING(val->frdataset.trust) &&
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_rdataset_isassociated(&val->fsigrdataset))
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_fixedname_init(&val->fname);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_name_copy(dlvname,
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_fixedname_name(&val->fname),
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews NULL);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews result = create_validator(val,
bd2b08d5a30e61117c1218fc7dd81d700d9d30f9Automatic Updater dns_fixedname_name(&val->fname),
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dns_rdatatype_dlv,
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews &val->frdataset,
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews &val->fsigrdataset,
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews dlvvalidated,
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews "finddlvsep");
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews if (result != ISC_R_SUCCESS)
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews return (result);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews return (DNS_R_WAIT);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews }
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt if (val->frdataset.trust < dns_trust_secure) {
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt validator_log(val, ISC_LOG_DEBUG(3),
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt "DLV not validated");
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews return (DNS_R_NOVALIDSIG);
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews val->havedlvsep = ISC_TRUE;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_rdataset_clone(&val->frdataset, &val->dlv);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews return (ISC_R_SUCCESS);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (result == ISC_R_NOTFOUND) {
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews result = create_fetch(val, dlvname, dns_rdatatype_dlv,
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dlvfetched, "finddlvsep");
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (result != ISC_R_SUCCESS)
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews return (result);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews return (DNS_R_WAIT);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (result != DNS_R_NXRRSET &&
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews result != DNS_R_NXDOMAIN &&
1bfe8851c0a2eb1d7e15556bfa21291cd62ee2bcMark Andrews result != DNS_R_EMPTYNAME &&
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews result != DNS_R_NCACHENXRRSET &&
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews result != DNS_R_NCACHENXDOMAIN)
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews return (result);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews /*
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * Strip first labels from both dlvsep and dlvname.
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews */
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews labels = dns_name_countlabels(dlvsep);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (labels == 0)
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews break;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews labels = dns_name_countlabels(dlvname);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews dns_name_getlabelsequence(dlvname, 1, labels - 1, dlvname);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews return (ISC_R_NOTFOUND);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews}
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews * proveunsecure walks down from the SEP looking for a break in the
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * chain of trust. That occurs when we can prove the DS record does
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews * not exist at a delegation point or the DS exists at a delegation
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews * but we don't support the algorithm/digest.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * If DLV is active and we look for a DLV record at or below the
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * point we go insecure. If found we restart the validation process.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * If not found or DLV isn't active we mark the response as a answer.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Returns:
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li ISC_R_SUCCESS val->event->name is in a unsecure zone
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li DNS_R_WAIT validation is in progress.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li DNS_R_MUSTBESECURE val->event->name is supposed to be secure
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * (policy) but we proved that it is unsecure.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li DNS_R_NOVALIDSIG
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li DNS_R_NOVALIDNSEC
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li DNS_R_NOTINSECURE
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews * \li DNS_R_BROKENCHAIN
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews */
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic isc_result_t
e4d304b70b81ca9956c2eff7c24aacf4dd00266eEvan Huntproveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews{
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington isc_result_t result;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_fixedname_t fixedsecroot;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_name_t *secroot;
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington dns_name_t *tname;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews char namebuf[DNS_NAME_FORMATSIZE];
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews dns_name_t *found;
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews dns_fixedname_t fixedfound;
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_fixedname_init(&fixedsecroot);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews secroot = dns_fixedname_name(&fixedsecroot);
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews dns_fixedname_init(&fixedfound);
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews found = dns_fixedname_name(&fixedfound);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (val->havedlvsep)
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_name_copy(dns_fixedname_name(&val->dlvsep), secroot, NULL);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews else {
9ead684875ab0ab5fdb8b5dd837a88f7dbd0e01dEvan Hunt unsigned int labels;
8bedd9647f4d6894e12a8c94d3ccc624dddcee50Mark Andrews dns_name_copy(val->event->name, secroot, NULL);
8bedd9647f4d6894e12a8c94d3ccc624dddcee50Mark Andrews /*
8bedd9647f4d6894e12a8c94d3ccc624dddcee50Mark Andrews * If this is a response to a DS query, we need to look in
8bedd9647f4d6894e12a8c94d3ccc624dddcee50Mark Andrews * the parent zone for the trust anchor.
8bedd9647f4d6894e12a8c94d3ccc624dddcee50Mark Andrews */
9ead684875ab0ab5fdb8b5dd837a88f7dbd0e01dEvan Hunt
9ead684875ab0ab5fdb8b5dd837a88f7dbd0e01dEvan Hunt labels = dns_name_countlabels(secroot);
9ead684875ab0ab5fdb8b5dd837a88f7dbd0e01dEvan Hunt if (val->event->type == dns_rdatatype_ds && labels > 1U)
9ead684875ab0ab5fdb8b5dd837a88f7dbd0e01dEvan Hunt dns_name_getlabelsequence(secroot, 1, labels - 1,
9ead684875ab0ab5fdb8b5dd837a88f7dbd0e01dEvan Hunt secroot);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews result = dns_keytable_finddeepestmatch(val->keytable,
8bedd9647f4d6894e12a8c94d3ccc624dddcee50Mark Andrews secroot, secroot);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (result == ISC_R_NOTFOUND) {
0ad024cc4272894e877e3a7896f80a2892bc703cMark Andrews if (val->mustbesecure) {
0ad024cc4272894e877e3a7896f80a2892bc703cMark Andrews validator_log(val, ISC_LOG_WARNING,
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt "must be secure failure, "
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt "not beneath secure root");
0ad024cc4272894e877e3a7896f80a2892bc703cMark Andrews result = DNS_R_MUSTBESECURE;
0ad024cc4272894e877e3a7896f80a2892bc703cMark Andrews goto out;
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt } else
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt validator_log(val, ISC_LOG_DEBUG(3),
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt "not beneath secure root");
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (val->view->dlv == NULL || DLVTRIED(val)) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews markanswer(val, "proveunsecure (1)");
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews return (ISC_R_SUCCESS);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews }
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews return (startfinddlvsep(val, dns_rootname));
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews } else if (result != ISC_R_SUCCESS)
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews return (result);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 if (!resume) {
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews /*
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews * We are looking for breaks below the SEP so add a label.
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews */
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews val->labels = dns_name_countlabels(secroot) + 1;
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 } else {
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3), "resuming proveunsecure");
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews /*
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews * If we have a DS rdataset and it is secure then check if
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews * the DS rdataset has a supported algorithm combination.
bfe0517fdcbe1dc62fee18e460ecf467dd491d9bEvan Hunt * If not this is an insecure delegation as far as this
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews * resolver is concerned. Fall back to DLV if available.
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews */
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews if (have_ds && val->frdataset.trust >= dns_trust_secure &&
c941e32d221fbb0cb760e3bc24c7f221c0cf8b97Mark Andrews !check_ds(val, dns_fixedname_name(&val->fname),
676619a22fbc760875adb00b58aaef6a22ced18aMark Andrews &val->frdataset)) {
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_name_format(dns_fixedname_name(&val->fname),
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews namebuf, sizeof(namebuf));
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews if ((val->view->dlv == NULL || DLVTRIED(val)) &&
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews val->mustbesecure) {
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews validator_log(val, ISC_LOG_WARNING,
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt "must be secure failure at '%s', "
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt "can't fall back to DLV",
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews namebuf);
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews result = DNS_R_MUSTBESECURE;
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews goto out;
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews }
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews "no supported algorithm/digest (%s/DS)",
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews namebuf);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (val->view->dlv == NULL || DLVTRIED(val)) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews markanswer(val, "proveunsecure (2)");
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews result = ISC_R_SUCCESS;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews goto out;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews }
6d386978b3a1f20a613ae10565c855aee084e2a0Mark Andrews return(startfinddlvsep(val,
6d386978b3a1f20a613ae10565c855aee084e2a0Mark Andrews dns_fixedname_name(&val->fname)));
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington val->labels++;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington }
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington for (;
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 val->labels <= dns_name_countlabels(val->event->name);
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington val->labels++)
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington {
6036112f4874637240d461c3ccbcb8dbfb1f405bAndreas Gustafsson
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_fixedname_init(&val->fname);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews tname = dns_fixedname_name(&val->fname);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (val->labels == dns_name_countlabels(val->event->name))
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_name_copy(val->event->name, tname, NULL);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews else
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 dns_name_split(val->event->name, val->labels,
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 NULL, tname);
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,
bfe0517fdcbe1dc62fee18e460ecf467dd491d9bEvan Hunt * we may be done.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews /*
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * If we have "trust == answer" then this namespace
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * has switched from insecure to should be secure.
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews */
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (DNS_TRUST_PENDING(val->frdataset.trust) ||
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews DNS_TRUST_ANSWER(val->frdataset.trust)) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = create_validator(val, tname,
515c7f3c43f76d7b439905b18009105364b36100Automatic Updater dns_rdatatype_ds,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews &val->frdataset,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews NULL, dsvalidated,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews "proveunsecure");
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews if (result != ISC_R_SUCCESS)
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews goto out;
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews return (DNS_R_WAIT);
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews }
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews /*
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews * Zones using NSEC3 don't return a NSEC RRset so
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews * we need to use dns_view_findzonecut2 to find
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews * the zone cut.
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews */
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews if (result == DNS_R_NXRRSET &&
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews !dns_rdataset_isassociated(&val->frdataset) &&
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews dns_view_findzonecut2(val->view, tname, found,
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt 0, 0, ISC_FALSE, ISC_FALSE,
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt NULL, NULL) == ISC_R_SUCCESS &&
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews dns_name_equal(tname, found)) {
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews if (val->mustbesecure) {
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews validator_log(val, ISC_LOG_WARNING,
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt "must be secure failure, "
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt "no DS at zone cut");
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews return (DNS_R_MUSTBESECURE);
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews }
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews if (val->view->dlv == NULL || DLVTRIED(val)) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews markanswer(val, "proveunsecure (3)");
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews return (ISC_R_SUCCESS);
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews }
e7eede965dbc67842cb32591a8c2ace2620e5359Mark Andrews return (startfinddlvsep(val, tname));
e7eede965dbc67842cb32591a8c2ace2620e5359Mark 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 */
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt validator_log(val, ISC_LOG_WARNING,
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt "can't validate existing "
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt "negative responses (no DS)");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = DNS_R_NOVALIDSIG;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington goto out;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington }
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews if (isdelegation(tname, &val->frdataset, result)) {
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews if (val->mustbesecure) {
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews validator_log(val, ISC_LOG_WARNING,
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt "must be secure failure, "
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt "%s is a delegation",
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt namebuf);
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews return (DNS_R_MUSTBESECURE);
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews }
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (val->view->dlv == NULL || DLVTRIED(val)) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews markanswer(val, "proveunsecure (4)");
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews return (ISC_R_SUCCESS);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews }
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews return (startfinddlvsep(val, tname));
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews }
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews continue;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews } else if (result == DNS_R_CNAME) {
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews if (DNS_TRUST_PENDING(val->frdataset.trust) ||
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews DNS_TRUST_ANSWER(val->frdataset.trust)) {
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews result = create_validator(val, tname,
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews dns_rdatatype_cname,
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews &val->frdataset,
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews NULL, cnamevalidated,
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews "proveunsecure "
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews "(cname)");
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews if (result != ISC_R_SUCCESS)
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews goto out;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews return (DNS_R_WAIT);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews }
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark 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 */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (val->frdataset.trust >= dns_trust_secure) {
c941e32d221fbb0cb760e3bc24c7f221c0cf8b97Mark Andrews if (!check_ds(val, tname, &val->frdataset)) {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews validator_log(val, ISC_LOG_DEBUG(3),
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews "no supported algorithm/"
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews "digest (%s/DS)", namebuf);
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews if (val->mustbesecure) {
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews validator_log(val,
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews ISC_LOG_WARNING,
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt "must be secure failure, "
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt "no supported algorithm/"
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt "digest (%s/DS)",
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt namebuf);
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews result = DNS_R_MUSTBESECURE;
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews goto out;
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews }
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (val->view->dlv == NULL ||
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews DLVTRIED(val)) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews markanswer(val,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews "proveunsecure (5)");
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews result = ISC_R_SUCCESS;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews goto out;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews }
6d386978b3a1f20a613ae10565c855aee084e2a0Mark Andrews return(startfinddlvsep(val, tname));
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington continue;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews else if (!dns_rdataset_isassociated(&val->fsigrdataset))
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews {
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt validator_log(val, ISC_LOG_DEBUG(3),
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt "DS is unsigned");
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = DNS_R_NOVALIDSIG;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington goto out;
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington }
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews /*
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * Validate / re-validate answer.
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews */
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 ||
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews result == DNS_R_NCACHENXDOMAIN) {
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;
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews } else if (DNS_TRUST_PENDING(val->frdataset.trust) ||
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews DNS_TRUST_ANSWER(val->frdataset.trust)) {
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews /*
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews * If we have "trust == answer" then this namespace
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews * has switched from insecure to should be secure.
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews */
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews result = create_validator(val, tname,
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews dns_rdatatype_ds,
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews &val->frdataset,
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews NULL, dsvalidated,
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews "proveunsecure");
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews if (result != ISC_R_SUCCESS)
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews goto out;
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews return (DNS_R_WAIT);
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 */
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt validator_log(val, ISC_LOG_WARNING,
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt "can't validate existing "
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt "negative responses "
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt "(not a zone cut)");
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);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews } else if (result == DNS_R_BROKENCHAIN)
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews return (result);
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
bfe0517fdcbe1dc62fee18e460ecf467dd491d9bEvan Hunt /* Couldn't complete insecurity proof */
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson validator_log(val, ISC_LOG_DEBUG(3), "insecurity proof failed");
bfe0517fdcbe1dc62fee18e460ecf467dd491d9bEvan Hunt return (DNS_R_NOTINSECURE);
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
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Reset state and revalidate the answer using DLV.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsstatic void
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrewsdlv_validator_start(dns_validator_t *val) {
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews isc_event_t *event;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews validator_log(val, ISC_LOG_DEBUG(3), "dlv_validator_start");
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews /*
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews * Reset state and try again.
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews */
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews val->attributes &= VALATTR_DLVTRIED;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews val->options &= ~DNS_VALIDATOR_DLV;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews event = (isc_event_t *)val->event;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews isc_task_send(val->task, &event);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews}
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews/*%
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Start the validation process.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
708383382ff1d3fdd27527e5d63120a3c6c6d3b3Francis Dupont * Attempt to validate the answer based on the category it appears to
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * fall in.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li 1. secure positive answer.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li 2. unsecure positive answer.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * \li 3. a negative answer (secure or unsecure).
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Note a answer that appears to be a secure positive answer may actually
bfe0517fdcbe1dc62fee18e460ecf467dd491d9bEvan Hunt * be an unsecure positive answer.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
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
708383382ff1d3fdd27527e5d63120a3c6c6d3b3Francis Dupont /* If the validator has been canceled, val->event == NULL */
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington if (val->event == NULL)
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington return;
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (DLVTRIED(val))
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews validator_log(val, ISC_LOG_DEBUG(3), "restarting using DLV");
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews else
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews validator_log(val, ISC_LOG_DEBUG(3), "starting");
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley LOCK(&val->lock);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
d2ef84e07b67e72a4bd9c729c6b8228067d17584Mark Andrews if ((val->options & DNS_VALIDATOR_DLV) != 0 &&
d2ef84e07b67e72a4bd9c729c6b8228067d17584Mark Andrews val->event->rdataset != NULL) {
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews validator_log(val, ISC_LOG_DEBUG(3), "looking for DLV");
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews result = startfinddlvsep(val, dns_rootname);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews } else if (val->event->rdataset != NULL &&
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews 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;
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
60783293cc27f74a84ec93c95c5d46edd30bd8e0Brian Wellington if (result == DNS_R_NOTINSECURE)
60783293cc27f74a84ec93c95c5d46edd30bd8e0Brian Wellington result = saved_result;
6bc1a645619a14707da68b130dafe41721fd2f25Brian Wellington }
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews } else if (val->event->rdataset != NULL &&
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews val->event->rdataset->type != 0) {
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;
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
afbe695de3f85c3d5cfae1a555aeadf44b43a77eMark Andrews if (result == DNS_R_NOTINSECURE)
bfe0517fdcbe1dc62fee18e460ecf467dd491d9bEvan Hunt validator_log(val, ISC_LOG_INFO,
bfe0517fdcbe1dc62fee18e460ecf467dd491d9bEvan Hunt "got insecure response; "
6b9728dde7c7ca15b19ea65ae35d9425c0d340caEvan Hunt "parent indicates it should be secure");
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
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (val->event->message->rcode == dns_rcode_nxdomain) {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews val->attributes |= VALATTR_NEEDNOQNAME;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews val->attributes |= VALATTR_NEEDNOWILDCARD;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews } else
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews val->attributes |= VALATTR_NEEDNODATA;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = nsecvalidate(val, ISC_FALSE);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews } else if (val->event->rdataset != NULL &&
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt NEGATIVE(val->event->rdataset))
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews /*
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * This is a nonexistence validation.
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews */
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews validator_log(val, ISC_LOG_DEBUG(3),
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews "attempting negative response validation");
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (val->event->rdataset->covers == dns_rdatatype_any) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews val->attributes |= VALATTR_NEEDNOQNAME;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews val->attributes |= VALATTR_NEEDNOWILDCARD;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews } else
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews val->attributes |= VALATTR_NEEDNODATA;
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{
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews isc_result_t result = ISC_R_FAILURE;
e419f613d8591885df608cb73065921be07dd12eBob Halley dns_validator_t *val;
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews isc_task_t *tclone = NULL;
e419f613d8591885df608cb73065921be07dd12eBob Halley dns_validatorevent_t *event;
e419f613d8591885df608cb73065921be07dd12eBob Halley
ec371edc34e2adb9e337b774d1a6e613f5863655Brian Wellington REQUIRE(name != NULL);
ec371edc34e2adb9e337b774d1a6e613f5863655Brian Wellington REQUIRE(rdataset != NULL ||
ec371edc34e2adb9e337b774d1a6e613f5863655Brian Wellington (rdataset == NULL && sigrdataset == NULL && message != NULL));
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley REQUIRE(validatorp != NULL && *validatorp == NULL);
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob 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;
ff8ab6befe10bfa68d98969a569b773eac602d1fMark Andrews dns_view_weakattach(view, &val->view);
95f2377b4f180a564d35343c8d150e8f03c98a52Evan Hunt
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;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews memset(event->proofs, 0, sizeof(event->proofs));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews event->optout = ISC_FALSE;
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrews event->secure = ISC_FALSE;
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;
95f2377b4f180a564d35343c8d150e8f03c98a52Evan Hunt
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington val->keytable = NULL;
95f2377b4f180a564d35343c8d150e8f03c98a52Evan Hunt result = dns_view_getsecroots(val->view, &val->keytable);
95f2377b4f180a564d35343c8d150e8f03c98a52Evan Hunt if (result != ISC_R_SUCCESS)
c611465739500968dd757ccb5a8abc13b4fcf56bMark Andrews goto cleanup_mutex;
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;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_rdataset_init(&val->dlv);
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington val->seensig = ISC_FALSE;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews val->havedlvsep = ISC_FALSE;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews val->depth = 0;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews val->authcount = 0;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews val->authfail = 0;
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews val->mustbesecure = dns_resolver_getmustbesecure(view->resolver, name);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_rdataset_init(&val->frdataset);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_rdataset_init(&val->fsigrdataset);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_fixedname_init(&val->wild);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_fixedname_init(&val->nearest);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_fixedname_init(&val->closest);
0cfb24736841b3e98bb25853229a0efabab88bddEvan Hunt isc_stdtime_get(&val->start);
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington ISC_LINK_INIT(val, link);
e419f613d8591885df608cb73065921be07dd12eBob Halley val->magic = VALIDATOR_MAGIC;
e419f613d8591885df608cb73065921be07dd12eBob Halley
305227476756aecb11cebbc811dba88a2d147b34Mark Andrews if ((options & DNS_VALIDATOR_DEFER) == 0)
305227476756aecb11cebbc811dba88a2d147b34Mark Andrews isc_task_send(task, ISC_EVENT_PTR(&event));
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley *validatorp = val;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
e419f613d8591885df608cb73065921be07dd12eBob Halley return (ISC_R_SUCCESS);
e419f613d8591885df608cb73065921be07dd12eBob Halley
c611465739500968dd757ccb5a8abc13b4fcf56bMark Andrews cleanup_mutex:
c611465739500968dd757ccb5a8abc13b4fcf56bMark Andrews DESTROYLOCK(&val->lock);
c611465739500968dd757ccb5a8abc13b4fcf56bMark Andrews
e419f613d8591885df608cb73065921be07dd12eBob Halley cleanup_event:
e419f613d8591885df608cb73065921be07dd12eBob Halley isc_task_detach(&tclone);
470c726bc894b1c528cb84e7e1f7e44770ffc485Mark Andrews isc_event_free(ISC_EVENT_PTR(&event));
e419f613d8591885df608cb73065921be07dd12eBob Halley
e419f613d8591885df608cb73065921be07dd12eBob Halley cleanup_val:
ff8ab6befe10bfa68d98969a569b773eac602d1fMark Andrews 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
305227476756aecb11cebbc811dba88a2d147b34Mark Andrewsvoid
305227476756aecb11cebbc811dba88a2d147b34Mark Andrewsdns_validator_send(dns_validator_t *validator) {
305227476756aecb11cebbc811dba88a2d147b34Mark Andrews isc_event_t *event;
305227476756aecb11cebbc811dba88a2d147b34Mark Andrews REQUIRE(VALID_VALIDATOR(validator));
305227476756aecb11cebbc811dba88a2d147b34Mark Andrews
305227476756aecb11cebbc811dba88a2d147b34Mark Andrews LOCK(&validator->lock);
305227476756aecb11cebbc811dba88a2d147b34Mark Andrews
305227476756aecb11cebbc811dba88a2d147b34Mark Andrews INSIST((validator->options & DNS_VALIDATOR_DEFER) != 0);
305227476756aecb11cebbc811dba88a2d147b34Mark Andrews event = (isc_event_t *)validator->event;
305227476756aecb11cebbc811dba88a2d147b34Mark Andrews validator->options &= ~DNS_VALIDATOR_DEFER;
305227476756aecb11cebbc811dba88a2d147b34Mark Andrews UNLOCK(&validator->lock);
305227476756aecb11cebbc811dba88a2d147b34Mark Andrews
305227476756aecb11cebbc811dba88a2d147b34Mark Andrews isc_task_send(validator->task, ISC_EVENT_PTR(&event));
305227476756aecb11cebbc811dba88a2d147b34Mark Andrews}
305227476756aecb11cebbc811dba88a2d147b34Mark Andrews
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halleyvoid
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halleydns_validator_cancel(dns_validator_t *validator) {
47c5b8af920a93763c97d9a93ea1fd766961a5b3Evan Hunt dns_fetch_t *fetch = NULL;
47c5b8af920a93763c97d9a93ea1fd766961a5b3Evan Hunt
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
22c4126ba51175af1453cd2254c303c6f65a766cMark Andrews if ((validator->attributes & VALATTR_CANCELED) == 0) {
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews validator->attributes |= VALATTR_CANCELED;
4d42b714be10e6f163d23507e4e3a396a8ac0364Automatic Updater if (validator->event != NULL) {
47c5b8af920a93763c97d9a93ea1fd766961a5b3Evan Hunt fetch = validator->fetch;
47c5b8af920a93763c97d9a93ea1fd766961a5b3Evan Hunt validator->fetch = NULL;
22c4126ba51175af1453cd2254c303c6f65a766cMark Andrews
22c4126ba51175af1453cd2254c303c6f65a766cMark Andrews if (validator->subvalidator != NULL)
22c4126ba51175af1453cd2254c303c6f65a766cMark Andrews dns_validator_cancel(validator->subvalidator);
22c4126ba51175af1453cd2254c303c6f65a766cMark Andrews if ((validator->options & DNS_VALIDATOR_DEFER) != 0) {
22c4126ba51175af1453cd2254c303c6f65a766cMark Andrews validator->options &= ~DNS_VALIDATOR_DEFER;
22c4126ba51175af1453cd2254c303c6f65a766cMark Andrews validator_done(validator, ISC_R_CANCELED);
22c4126ba51175af1453cd2254c303c6f65a766cMark Andrews }
22c4126ba51175af1453cd2254c303c6f65a766cMark Andrews }
e419f613d8591885df608cb73065921be07dd12eBob Halley }
e419f613d8591885df608cb73065921be07dd12eBob Halley UNLOCK(&validator->lock);
47c5b8af920a93763c97d9a93ea1fd766961a5b3Evan Hunt
39bfdc2ff9da3c2ecdbc70d46cabfd56d66f24f6Mark Andrews /* Need to cancel and destroy the fetch outside validator lock */
39bfdc2ff9da3c2ecdbc70d46cabfd56d66f24f6Mark Andrews if (fetch != NULL) {
47c5b8af920a93763c97d9a93ea1fd766961a5b3Evan Hunt dns_resolver_cancelfetch(fetch);
39bfdc2ff9da3c2ecdbc70d46cabfd56d66f24f6Mark Andrews dns_resolver_destroyfetch(&fetch);
39bfdc2ff9da3c2ecdbc70d46cabfd56d66f24f6Mark Andrews }
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);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (val->havedlvsep)
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_rdataset_disassociate(&val->dlv);
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews if (dns_rdataset_isassociated(&val->frdataset))
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews dns_rdataset_disassociate(&val->frdataset);
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews if (dns_rdataset_isassociated(&val->fsigrdataset))
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews dns_rdataset_disassociate(&val->fsigrdataset);
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);
ff8ab6befe10bfa68d98969a569b773eac602d1fMark Andrews 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;
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt validator_log(val, ISC_LOG_DEBUG(4), "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];
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews static const char spaces[] = " *";
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews int depth = val->depth * 2;
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if ((unsigned int) depth >= sizeof spaces)
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews depth = sizeof spaces - 1;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
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,
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt "%.*svalidating %s/%s: %s", depth, spaces,
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt namebuf, typebuf, msgbuf);
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson } else {
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson isc_log_write(dns_lctx, category, module, level,
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews "%.*svalidator @%p: %s", depth, spaces,
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews val, msgbuf);
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson }
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson}
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafssonstatic void
8462dfb880040cde3a60f047ec18808737fd7e85Mark Andrewsvalidator_log(void *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}