summaryrefslogtreecommitdiffstats
path: root/lib/dns/validator.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dns/validator.c')
-rw-r--r--lib/dns/validator.c428
1 files changed, 249 insertions, 179 deletions
diff --git a/lib/dns/validator.c b/lib/dns/validator.c
index 79c8798..6c0d38d 100644
--- a/lib/dns/validator.c
+++ b/lib/dns/validator.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: validator.c,v 1.164.12.23.4.3 2011-06-21 20:13:23 each Exp $ */
+/* $Id: validator.c,v 1.197.40.3 2011-06-21 20:15:54 each Exp $ */
#include <config.h>
@@ -28,17 +28,17 @@
#include <isc/util.h>
#include <dns/db.h>
-#include <dns/ds.h>
#include <dns/dnssec.h>
+#include <dns/ds.h>
#include <dns/events.h>
#include <dns/keytable.h>
+#include <dns/keyvalues.h>
#include <dns/log.h>
#include <dns/message.h>
#include <dns/ncache.h>
#include <dns/nsec.h>
#include <dns/nsec3.h>
#include <dns/rdata.h>
-#include <dns/rdatastruct.h>
#include <dns/rdataset.h>
#include <dns/rdatatype.h>
#include <dns/resolver.h>
@@ -255,9 +255,17 @@ dlv_algorithm_supported(dns_validator_t *val) {
dlv.algorithm))
continue;
+#ifdef HAVE_OPENSSL_GOST
+ if (dlv.digest_type != DNS_DSDIGEST_SHA256 &&
+ dlv.digest_type != DNS_DSDIGEST_SHA1 &&
+ dlv.digest_type != DNS_DSDIGEST_GOST)
+ continue;
+#else
if (dlv.digest_type != DNS_DSDIGEST_SHA256 &&
dlv.digest_type != DNS_DSDIGEST_SHA1)
continue;
+#endif
+
return (ISC_TRUE);
}
@@ -383,7 +391,7 @@ isdelegation(dns_name_t *name, dns_rdataset_t *rdataset,
}
/*%
- * We have been asked to to look for a key.
+ * We have been asked to look for a key.
* If found resume the validation process.
* If not found fail the validation process.
*/
@@ -582,7 +590,8 @@ dsfetched2(isc_task_t *task, isc_event_t *event) {
if (isdelegation(tname, &val->frdataset, eresult)) {
if (val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
- "must be secure failure");
+ "must be secure failure, no DS"
+ " and this is a delegation");
validator_done(val, DNS_R_MUSTBESECURE);
} else if (val->view->dlv == NULL || DLVTRIED(val)) {
markanswer(val, "dsfetched2");
@@ -1089,7 +1098,7 @@ nsec3noexistnodata(dns_validator_t *val, dns_name_t* name,
if (ns && !soa) {
if (!atparent) {
/*
- * This NSEC record is from somewhere
+ * This NSEC3 record is from somewhere
* higher in the DNS, and at the
* parent of a delegation. It can not
* be legitimately used here.
@@ -1100,7 +1109,7 @@ nsec3noexistnodata(dns_validator_t *val, dns_name_t* name,
}
} else if (atparent && ns && soa) {
/*
- * This NSEC record is from the child.
+ * This NSEC3 record is from the child.
* It can not be legitimately used here.
*/
validator_log(val, ISC_LOG_DEBUG(3),
@@ -1505,8 +1514,11 @@ create_fetch(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
if (dns_rdataset_isassociated(&val->fsigrdataset))
dns_rdataset_disassociate(&val->fsigrdataset);
- if (check_deadlock(val, name, type, NULL, NULL))
+ if (check_deadlock(val, name, type, NULL, NULL)) {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "deadlock found (create_fetch)");
return (DNS_R_NOVALIDSIG);
+ }
validator_logcreate(val, name, type, caller, "fetch");
return (dns_resolver_createfetch(val->view->resolver, name, type,
@@ -1528,8 +1540,11 @@ create_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
{
isc_result_t result;
- if (check_deadlock(val, name, type, rdataset, sigrdataset))
+ if (check_deadlock(val, name, type, rdataset, sigrdataset)) {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "deadlock found (create_validator)");
return (DNS_R_NOVALIDSIG);
+ }
validator_logcreate(val, name, type, caller, "validator");
result = dns_validator_create(val->view, name, type,
@@ -1768,16 +1783,23 @@ compute_keytag(dns_rdata_t *rdata, dns_rdata_dnskey_t *key) {
*/
static isc_boolean_t
isselfsigned(dns_validator_t *val) {
+ dns_fixedname_t fixed;
dns_rdataset_t *rdataset, *sigrdataset;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_t sigrdata = DNS_RDATA_INIT;
dns_rdata_dnskey_t key;
dns_rdata_rrsig_t sig;
dns_keytag_t keytag;
+ dns_name_t *name;
isc_result_t result;
+ dst_key_t *dstkey;
+ isc_mem_t *mctx;
+ isc_boolean_t answer = ISC_FALSE;
rdataset = val->event->rdataset;
sigrdataset = val->event->sigrdataset;
+ name = val->event->name;
+ mctx = val->view->mctx;
INSIST(rdataset->type == dns_rdatatype_dnskey);
@@ -1799,12 +1821,31 @@ isselfsigned(dns_validator_t *val) {
result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
- if (sig.algorithm == key.algorithm &&
- sig.keyid == keytag)
- return (ISC_TRUE);
+ if (sig.algorithm != key.algorithm ||
+ sig.keyid != keytag ||
+ !dns_name_equal(name, &sig.signer))
+ continue;
+
+ dstkey = NULL;
+ result = dns_dnssec_keyfromrdata(name, &rdata, mctx,
+ &dstkey);
+ if (result != ISC_R_SUCCESS)
+ continue;
+
+ result = dns_dnssec_verify2(name, rdataset, dstkey,
+ ISC_TRUE, mctx, &sigrdata,
+ dns_fixedname_name(&fixed));
+ dst_key_free(&dstkey);
+ if (result != ISC_R_SUCCESS)
+ continue;
+ if ((key.flags & DNS_KEYFLAG_REVOKE) == 0) {
+ answer = ISC_TRUE;
+ continue;
+ }
+ dns_view_untrust(val->view, name, &key, mctx);
}
}
- return (ISC_FALSE);
+ return (answer);
}
/*%
@@ -1946,6 +1987,8 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
break;
}
val->key = dns_keynode_key(val->keynode);
+ if (val->key == NULL)
+ break;
} else {
if (get_dst_key(val, val->siginfo, val->keyset)
!= ISC_R_SUCCESS)
@@ -1962,8 +2005,6 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
isc_stdtime_get(&now);
ttl = ISC_MIN(event->rdataset->ttl,
val->siginfo->timeexpire - now);
- if (val->keyset != NULL)
- ttl = ISC_MIN(ttl, val->keyset->ttl);
event->rdataset->ttl = ttl;
event->sigrdataset->ttl = ttl;
}
@@ -1992,7 +2033,8 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
} else if (result == ISC_R_SUCCESS) {
marksecure(event);
validator_log(val, ISC_LOG_DEBUG(3),
- "marking as secure");
+ "marking as secure, "
+ "noqname proof not needed");
return (result);
} else {
validator_log(val, ISC_LOG_DEBUG(3),
@@ -2013,25 +2055,102 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
}
/*%
+ * Check whether this DNSKEY (keyrdata) signed the DNSKEY RRset
+ * (val->event->rdataset).
+ */
+static isc_result_t
+checkkey(dns_validator_t *val, dns_rdata_t *keyrdata, isc_uint16_t keyid,
+ dns_secalg_t algorithm)
+{
+ dns_rdata_rrsig_t sig;
+ dst_key_t *dstkey = NULL;
+ isc_result_t result;
+
+ for (result = dns_rdataset_first(val->event->sigrdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(val->event->sigrdataset))
+ {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+
+ dns_rdataset_current(val->event->sigrdataset, &rdata);
+ result = dns_rdata_tostruct(&rdata, &sig, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ if (keyid != sig.keyid || algorithm != sig.algorithm)
+ continue;
+ if (dstkey == NULL) {
+ result = dns_dnssec_keyfromrdata(val->event->name,
+ keyrdata,
+ val->view->mctx,
+ &dstkey);
+ if (result != ISC_R_SUCCESS)
+ /*
+ * This really shouldn't happen, but...
+ */
+ continue;
+ }
+ result = verify(val, dstkey, &rdata, sig.keyid);
+ if (result == ISC_R_SUCCESS)
+ break;
+ }
+ if (dstkey != NULL)
+ dst_key_free(&dstkey);
+ return (result);
+}
+
+/*%
+ * Find the DNSKEY that corresponds to the DS.
+ */
+static isc_result_t
+keyfromds(dns_validator_t *val, dns_rdataset_t *rdataset, dns_rdata_t *dsrdata,
+ isc_uint8_t digest, isc_uint16_t keyid, dns_secalg_t algorithm,
+ dns_rdata_t *keyrdata)
+{
+ dns_keytag_t keytag;
+ dns_rdata_dnskey_t key;
+ isc_result_t result;
+ unsigned char dsbuf[DNS_DS_BUFFERSIZE];
+
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset))
+ {
+ dns_rdata_t newdsrdata = DNS_RDATA_INIT;
+
+ dns_rdata_reset(keyrdata);
+ dns_rdataset_current(rdataset, keyrdata);
+ result = dns_rdata_tostruct(keyrdata, &key, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ keytag = compute_keytag(keyrdata, &key);
+ if (keyid != keytag || algorithm != key.algorithm)
+ continue;
+ dns_rdata_reset(&newdsrdata);
+ result = dns_ds_buildrdata(val->event->name, keyrdata, digest,
+ dsbuf, &newdsrdata);
+ if (result != ISC_R_SUCCESS) {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "dns_ds_buildrdata() -> %s",
+ dns_result_totext(result));
+ continue;
+ }
+ if (dns_rdata_compare(dsrdata, &newdsrdata) == 0)
+ break;
+ }
+ return (result);
+}
+
+/*%
* Validate the DNSKEY RRset by looking for a DNSKEY that matches a
* DLV record and that also verifies the DNSKEY RRset.
*/
static isc_result_t
dlv_validatezonekey(dns_validator_t *val) {
- dns_keytag_t keytag;
dns_rdata_dlv_t dlv;
- dns_rdata_dnskey_t key;
- dns_rdata_rrsig_t sig;
dns_rdata_t dlvrdata = DNS_RDATA_INIT;
dns_rdata_t keyrdata = DNS_RDATA_INIT;
- dns_rdata_t newdsrdata = DNS_RDATA_INIT;
- dns_rdata_t sigrdata = DNS_RDATA_INIT;
dns_rdataset_t trdataset;
- dst_key_t *dstkey;
isc_boolean_t supported_algorithm;
isc_result_t result;
- unsigned char dsbuf[DNS_DS_BUFFERSIZE];
- isc_uint8_t digest_type;
+ char digest_types[256];
validator_log(val, ISC_LOG_DEBUG(3), "dlv_validatezonekey");
@@ -2048,7 +2167,7 @@ dlv_validatezonekey(dns_validator_t *val) {
* need to ignore DNS_DSDIGEST_SHA1 if a DNS_DSDIGEST_SHA256
* is present.
*/
- digest_type = DNS_DSDIGEST_SHA1;
+ memset(digest_types, 1, sizeof(digest_types));
for (result = dns_rdataset_first(&val->dlv);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(&val->dlv)) {
@@ -2064,7 +2183,7 @@ dlv_validatezonekey(dns_validator_t *val) {
if (dlv.digest_type == DNS_DSDIGEST_SHA256 &&
dlv.length == ISC_SHA256_DIGESTLENGTH) {
- digest_type = DNS_DSDIGEST_SHA256;
+ digest_types[DNS_DSDIGEST_SHA1] = 0;
break;
}
}
@@ -2082,7 +2201,7 @@ dlv_validatezonekey(dns_validator_t *val) {
dlv.digest_type))
continue;
- if (dlv.digest_type != digest_type)
+ if (digest_types[dlv.digest_type] == 0)
continue;
if (!dns_resolver_algorithm_supported(val->view->resolver,
@@ -2095,70 +2214,27 @@ dlv_validatezonekey(dns_validator_t *val) {
dns_rdataset_init(&trdataset);
dns_rdataset_clone(val->event->rdataset, &trdataset);
- for (result = dns_rdataset_first(&trdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&trdataset))
- {
- dns_rdata_reset(&keyrdata);
- dns_rdataset_current(&trdataset, &keyrdata);
- result = dns_rdata_tostruct(&keyrdata, &key, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- keytag = compute_keytag(&keyrdata, &key);
- if (dlv.key_tag != keytag ||
- dlv.algorithm != key.algorithm)
- continue;
- dns_rdata_reset(&newdsrdata);
- result = dns_ds_buildrdata(val->event->name,
- &keyrdata, dlv.digest_type,
- dsbuf, &newdsrdata);
- if (result != ISC_R_SUCCESS) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "dns_ds_buildrdata() -> %s",
- dns_result_totext(result));
- continue;
- }
- /* Covert to DLV */
- newdsrdata.type = dns_rdatatype_dlv;
- if (dns_rdata_compare(&dlvrdata, &newdsrdata) == 0)
- break;
- }
+ /*
+ * Convert to DLV to DS and find matching DNSKEY.
+ */
+ dlvrdata.type = dns_rdatatype_ds;
+ result = keyfromds(val, &trdataset, &dlvrdata,
+ dlv.digest_type, dlv.key_tag,
+ dlv.algorithm, &keyrdata);
if (result != ISC_R_SUCCESS) {
dns_rdataset_disassociate(&trdataset);
validator_log(val, ISC_LOG_DEBUG(3),
"no DNSKEY matching DLV");
continue;
}
+
validator_log(val, ISC_LOG_DEBUG(3),
"Found matching DLV record: checking for signature");
+ /*
+ * Check that this DNSKEY signed the DNSKEY rrset.
+ */
+ result = checkkey(val, &keyrdata, dlv.key_tag, dlv.algorithm);
- for (result = dns_rdataset_first(val->event->sigrdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(val->event->sigrdataset))
- {
- dns_rdata_reset(&sigrdata);
- dns_rdataset_current(val->event->sigrdataset,
- &sigrdata);
- result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- if (dlv.key_tag != sig.keyid ||
- dlv.algorithm != sig.algorithm)
- continue;
- dstkey = NULL;
- result = dns_dnssec_keyfromrdata(val->event->name,
- &keyrdata,
- val->view->mctx,
- &dstkey);
- if (result != ISC_R_SUCCESS)
- /*
- * This really shouldn't happen, but...
- */
- continue;
-
- result = verify(val, dstkey, &sigrdata, sig.keyid);
- dst_key_free(&dstkey);
- if (result == ISC_R_SUCCESS)
- break;
- }
dns_rdataset_disassociate(&trdataset);
if (result == ISC_R_SUCCESS)
break;
@@ -2167,12 +2243,13 @@ dlv_validatezonekey(dns_validator_t *val) {
}
if (result == ISC_R_SUCCESS) {
marksecure(val->event);
- validator_log(val, ISC_LOG_DEBUG(3), "marking as secure");
+ validator_log(val, ISC_LOG_DEBUG(3), "marking as secure (dlv)");
return (result);
} else if (result == ISC_R_NOMORE && !supported_algorithm) {
if (val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
- "must be secure failure");
+ "must be secure failure,"
+ "no supported algorithm/digest (dlv)");
return (DNS_R_MUSTBESECURE);
}
validator_log(val, ISC_LOG_DEBUG(3),
@@ -2184,7 +2261,8 @@ dlv_validatezonekey(dns_validator_t *val) {
}
/*%
- * Attempts positive response validation of an RRset containing zone keys.
+ * Attempts positive response validation of an RRset containing zone keys
+ * (i.e. a DNSKEY rrset).
*
* Returns:
* \li ISC_R_SUCCESS Validation completed successfully
@@ -2198,19 +2276,15 @@ validatezonekey(dns_validator_t *val) {
dns_validatorevent_t *event;
dns_rdataset_t trdataset;
dns_rdata_t dsrdata = DNS_RDATA_INIT;
- dns_rdata_t newdsrdata = DNS_RDATA_INIT;
dns_rdata_t keyrdata = DNS_RDATA_INIT;
dns_rdata_t sigrdata = DNS_RDATA_INIT;
- unsigned char dsbuf[DNS_DS_BUFFERSIZE];
char namebuf[DNS_NAME_FORMATSIZE];
- dns_keytag_t keytag;
dns_rdata_ds_t ds;
- dns_rdata_dnskey_t key;
dns_rdata_rrsig_t sig;
dst_key_t *dstkey;
isc_boolean_t supported_algorithm;
isc_boolean_t atsep = ISC_FALSE;
- isc_uint8_t digest_type;
+ char digest_types[256];
/*
* Caller must be holding the validator lock.
@@ -2259,8 +2333,7 @@ validatezonekey(dns_validator_t *val) {
result = dns_keytable_findkeynode(val->keytable,
val->event->name,
sig.algorithm,
- sig.keyid,
- &keynode);
+ sig.keyid, &keynode);
if (result == ISC_R_NOTFOUND &&
dns_keytable_finddeepestmatch(val->keytable,
val->event->name, found) != ISC_R_SUCCESS) {
@@ -2284,11 +2357,18 @@ validatezonekey(dns_validator_t *val) {
while (result == ISC_R_SUCCESS) {
dns_keynode_t *nextnode = NULL;
dstkey = dns_keynode_key(keynode);
+ if (dstkey == NULL) {
+ dns_keytable_detachkeynode(
+ val->keytable,
+ &keynode);
+ break;
+ }
result = verify(val, dstkey, &sigrdata,
sig.keyid);
if (result == ISC_R_SUCCESS) {
- dns_keytable_detachkeynode(val->keytable,
- &keynode);
+ dns_keytable_detachkeynode(
+ val->keytable,
+ &keynode);
break;
}
result = dns_keytable_findnextkeynode(
@@ -2318,8 +2398,8 @@ validatezonekey(dns_validator_t *val) {
sizeof(namebuf));
validator_log(val, ISC_LOG_NOTICE,
"unable to find a DNSKEY which verifies "
- "the DNSKEY RRset and also matches one "
- "of specified trusted-keys for '%s'",
+ "the DNSKEY RRset and also matches a "
+ "trusted key for '%s'",
namebuf);
validator_log(val, ISC_LOG_NOTICE,
"please check the 'trusted-keys' for "
@@ -2413,7 +2493,8 @@ validatezonekey(dns_validator_t *val) {
if (val->dsset->trust < dns_trust_secure) {
if (val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
- "must be secure failure");
+ "must be secure failure,"
+ " insecure DS");
return (DNS_R_MUSTBESECURE);
}
if (val->view->dlv == NULL || DLVTRIED(val)) {
@@ -2437,7 +2518,7 @@ validatezonekey(dns_validator_t *val) {
* need to ignore DNS_DSDIGEST_SHA1 if a DNS_DSDIGEST_SHA256
* is present.
*/
- digest_type = DNS_DSDIGEST_SHA1;
+ memset(digest_types, 1, sizeof(digest_types));
for (result = dns_rdataset_first(val->dsset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(val->dsset)) {
@@ -2453,7 +2534,7 @@ validatezonekey(dns_validator_t *val) {
if (ds.digest_type == DNS_DSDIGEST_SHA256 &&
ds.length == ISC_SHA256_DIGESTLENGTH) {
- digest_type = DNS_DSDIGEST_SHA256;
+ digest_types[DNS_DSDIGEST_SHA1] = 0;
break;
}
}
@@ -2471,7 +2552,7 @@ validatezonekey(dns_validator_t *val) {
ds.digest_type))
continue;
- if (ds.digest_type != digest_type)
+ if (digest_types[ds.digest_type] == 0)
continue;
if (!dns_resolver_algorithm_supported(val->view->resolver,
@@ -2485,29 +2566,10 @@ validatezonekey(dns_validator_t *val) {
dns_rdataset_clone(val->event->rdataset, &trdataset);
/*
- * Look for the KEY that matches the DS record.
+ * Find matching DNSKEY from DS.
*/
- for (result = dns_rdataset_first(&trdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&trdataset))
- {
- dns_rdata_reset(&keyrdata);
- dns_rdataset_current(&trdataset, &keyrdata);
- result = dns_rdata_tostruct(&keyrdata, &key, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- keytag = compute_keytag(&keyrdata, &key);
- if (ds.key_tag != keytag ||
- ds.algorithm != key.algorithm)
- continue;
- dns_rdata_reset(&newdsrdata);
- result = dns_ds_buildrdata(val->event->name,
- &keyrdata, ds.digest_type,
- dsbuf, &newdsrdata);
- if (result != ISC_R_SUCCESS)
- continue;
- if (dns_rdata_compare(&dsrdata, &newdsrdata) == 0)
- break;
- }
+ result = keyfromds(val, &trdataset, &dsrdata, ds.digest_type,
+ ds.key_tag, ds.algorithm, &keyrdata);
if (result != ISC_R_SUCCESS) {
dns_rdataset_disassociate(&trdataset);
validator_log(val, ISC_LOG_DEBUG(3),
@@ -2515,38 +2577,11 @@ validatezonekey(dns_validator_t *val) {
continue;
}
- for (result = dns_rdataset_first(val->event->sigrdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(val->event->sigrdataset))
- {
- dns_rdata_reset(&sigrdata);
- dns_rdataset_current(val->event->sigrdataset,
- &sigrdata);
- result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- if (ds.key_tag != sig.keyid ||
- ds.algorithm != sig.algorithm)
- continue;
- if (!dns_name_equal(val->event->name, &sig.signer)) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "DNSKEY signer mismatch");
- continue;
- }
- dstkey = NULL;
- result = dns_dnssec_keyfromrdata(val->event->name,
- &keyrdata,
- val->view->mctx,
- &dstkey);
- if (result != ISC_R_SUCCESS)
- /*
- * This really shouldn't happen, but...
- */
- continue;
- result = verify(val, dstkey, &sigrdata, sig.keyid);
- dst_key_free(&dstkey);
- if (result == ISC_R_SUCCESS)
- break;
- }
+ /*
+ * Check that this DNSKEY signed the DNSKEY rrset.
+ */
+ result = checkkey(val, &keyrdata, ds.key_tag, ds.algorithm);
+
dns_rdataset_disassociate(&trdataset);
if (result == ISC_R_SUCCESS)
break;
@@ -2555,20 +2590,24 @@ validatezonekey(dns_validator_t *val) {
}
if (result == ISC_R_SUCCESS) {
marksecure(event);
- validator_log(val, ISC_LOG_DEBUG(3), "marking as secure");
+ validator_log(val, ISC_LOG_DEBUG(3), "marking as secure (DS)");
return (result);
} else if (result == ISC_R_NOMORE && !supported_algorithm) {
if (val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
- "must be secure failure");
+ "must be secure failure, "
+ "no supported algorithm/digest (DS)");
return (DNS_R_MUSTBESECURE);
}
validator_log(val, ISC_LOG_DEBUG(3),
"no supported algorithm/digest (DS)");
markanswer(val, "validatezonekey (3)");
return (ISC_R_SUCCESS);
- } else
+ } else {
+ validator_log(val, ISC_LOG_INFO,
+ "no valid signature found (DS)");
return (DNS_R_NOVALIDSIG);
+ }
}
/*%
@@ -3094,9 +3133,7 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
findnsec3proofs(val);
if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val)) {
validator_log(val, ISC_LOG_DEBUG(3),
- "noqname proof found");
- validator_log(val, ISC_LOG_DEBUG(3),
- "marking as secure");
+ "marking as secure, noqname proof found");
marksecure(val->event);
return (ISC_R_SUCCESS);
} else if (FOUNDOPTOUT(val) &&
@@ -3143,7 +3180,6 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
marksecure(val->event);
return (ISC_R_SUCCESS);
}
- findnsec3proofs(val);
if (val->authfail != 0 && val->authcount == val->authfail)
return (DNS_R_BROKENCHAIN);
@@ -3345,7 +3381,8 @@ startfinddlvsep(dns_validator_t *val, dns_name_t *unsecure) {
namebuf);
if (dns_name_issubdomain(val->event->name, val->view->dlv)) {
- validator_log(val, ISC_LOG_WARNING, "must be secure failure");
+ validator_log(val, ISC_LOG_WARNING, "must be secure failure, "
+ " %s is under DLV (startfinddlvsep)", namebuf);
return (DNS_R_MUSTBESECURE);
}
@@ -3397,10 +3434,12 @@ finddlvsep(dns_validator_t *val, isc_boolean_t resume) {
INSIST(val->view->dlv != NULL);
if (!resume) {
-
if (dns_name_issubdomain(val->event->name, val->view->dlv)) {
+ dns_name_format(val->event->name, namebuf,
+ sizeof(namebuf));
validator_log(val, ISC_LOG_WARNING,
- "must be secure failure");
+ "must be secure failure, "
+ "%s is under DLV (finddlvsep)", namebuf);
return (DNS_R_MUSTBESECURE);
}
@@ -3468,8 +3507,11 @@ finddlvsep(dns_validator_t *val, isc_boolean_t resume) {
return (result);
return (DNS_R_WAIT);
}
- if (val->frdataset.trust < dns_trust_secure)
+ if (val->frdataset.trust < dns_trust_secure) {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "DLV not validated");
return (DNS_R_NOVALIDSIG);
+ }
val->havedlvsep = ISC_TRUE;
dns_rdataset_clone(&val->frdataset, &val->dlv);
return (ISC_R_SUCCESS);
@@ -3554,10 +3596,13 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
if (result == ISC_R_NOTFOUND) {
if (val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
- "must be secure failure");
+ "must be secure failure, "
+ "not beneath secure root");
result = DNS_R_MUSTBESECURE;
goto out;
- }
+ } else
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "not beneath secure root");
if (val->view->dlv == NULL || DLVTRIED(val)) {
markanswer(val, "proveunsecure (1)");
return (ISC_R_SUCCESS);
@@ -3577,7 +3622,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
/*
* If we have a DS rdataset and it is secure then check if
* the DS rdataset has a supported algorithm combination.
- * If not this is a insecure delegation as far as this
+ * If not this is an insecure delegation as far as this
* resolver is concerned. Fall back to DLV if available.
*/
if (have_ds && val->frdataset.trust >= dns_trust_secure &&
@@ -3588,7 +3633,8 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
if ((val->view->dlv == NULL || DLVTRIED(val)) &&
val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
- "must be secure failure at '%s'",
+ "must be secure failure at '%s', "
+ "can't fall back to DLV",
namebuf);
result = DNS_R_MUSTBESECURE;
goto out;
@@ -3630,7 +3676,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) {
/*
* There is no DS. If this is a delegation,
- * we maybe done.
+ * we may be done.
*/
/*
* If we have "trust == answer" then this namespace
@@ -3643,7 +3689,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
&val->frdataset,
NULL, dsvalidated,
"proveunsecure");
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
goto out;
return (DNS_R_WAIT);
}
@@ -3655,12 +3701,13 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
if (result == DNS_R_NXRRSET &&
!dns_rdataset_isassociated(&val->frdataset) &&
dns_view_findzonecut2(val->view, tname, found,
- 0, 0, ISC_FALSE, ISC_FALSE,
- NULL, NULL) == ISC_R_SUCCESS &&
+ 0, 0, ISC_FALSE, ISC_FALSE,
+ NULL, NULL) == ISC_R_SUCCESS &&
dns_name_equal(tname, found)) {
if (val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
- "must be secure failure");
+ "must be secure failure, "
+ "no DS at zone cut");
return (DNS_R_MUSTBESECURE);
}
if (val->view->dlv == NULL || DLVTRIED(val)) {
@@ -3676,13 +3723,18 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
* there's no way of validating existing
* negative response blobs, give up.
*/
+ validator_log(val, ISC_LOG_WARNING,
+ "can't validate existing "
+ "negative responses (no DS)");
result = DNS_R_NOVALIDSIG;
goto out;
}
if (isdelegation(tname, &val->frdataset, result)) {
if (val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
- "must be secure failure");
+ "must be secure failure, "
+ "%s is a delegation",
+ namebuf);
return (DNS_R_MUSTBESECURE);
}
if (val->view->dlv == NULL || DLVTRIED(val)) {
@@ -3705,7 +3757,10 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
if (val->mustbesecure) {
validator_log(val,
ISC_LOG_WARNING,
- "must be secure failure");
+ "must be secure failure, "
+ "no supported algorithm/"
+ "digest (%s/DS)",
+ namebuf);
result = DNS_R_MUSTBESECURE;
goto out;
}
@@ -3723,6 +3778,8 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
}
else if (!dns_rdataset_isassociated(&val->fsigrdataset))
{
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "DS is unsigned");
result = DNS_R_NOVALIDSIG;
goto out;
}
@@ -3771,6 +3828,10 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
* there's no way of validating existing
* negative response blobs, give up.
*/
+ validator_log(val, ISC_LOG_WARNING,
+ "can't validate existing "
+ "negative responses "
+ "(not a zone cut)");
result = DNS_R_NOVALIDSIG;
goto out;
}
@@ -3790,7 +3851,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
/* Couldn't complete insecurity proof */
validator_log(val, ISC_LOG_DEBUG(3), "insecurity proof failed");
- return (DNS_R_NOTINSECURE); /* Couldn't complete insecurity proof */
+ return (DNS_R_NOTINSECURE);
out:
if (dns_rdataset_isassociated(&val->frdataset))
@@ -3829,7 +3890,7 @@ dlv_validator_start(dns_validator_t *val) {
* \li 3. a negative answer (secure or unsecure).
*
* Note a answer that appears to be a secure positive answer may actually
- * be a unsecure positive answer.
+ * be an unsecure positive answer.
*/
static void
validator_start(isc_task_t *task, isc_event_t *event) {
@@ -3895,6 +3956,10 @@ validator_start(isc_task_t *task, isc_event_t *event) {
val->attributes |= VALATTR_INSECURITY;
result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
+ if (result == DNS_R_NOTINSECURE)
+ validator_log(val, ISC_LOG_INFO,
+ "got insecure response; "
+ "parent indicates it should be secure");
} else if (val->event->rdataset == NULL &&
val->event->sigrdataset == NULL)
{
@@ -3967,6 +4032,7 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
return (ISC_R_NOMEMORY);
val->view = NULL;
dns_view_weakattach(view, &val->view);
+
event = (dns_validatorevent_t *)
isc_event_allocate(view->mctx, task,
DNS_EVENT_VALIDATORSTART,
@@ -3995,8 +4061,12 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
val->fetch = NULL;
val->subvalidator = NULL;
val->parent = NULL;
+
val->keytable = NULL;
- dns_keytable_attach(val->view->secroots, &val->keytable);
+ result = dns_view_getsecroots(val->view, &val->keytable);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
val->keynode = NULL;
val->key = NULL;
val->siginfo = NULL;
OpenPOWER on IntegriCloud