mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-11 05:39:59 -04:00
2892. [bug] Handle REVOKED keys better. [RT #20961]
This commit is contained in:
parent
d2dd525033
commit
44f175a90a
6 changed files with 242 additions and 207 deletions
2
CHANGES
2
CHANGES
|
|
@ -1,3 +1,5 @@
|
|||
2892. [bug] Handle REVOKED keys better. [RT #20961]
|
||||
|
||||
2891. [maint] Update empty-zones list to match
|
||||
draft-ietf-dnsop-default-local-zones-13. [RT# 21099]
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# $Id: tests.sh,v 1.7 2010/01/18 23:48:39 tbox Exp $
|
||||
# $Id: tests.sh,v 1.8 2010/05/14 04:38:52 marka Exp $
|
||||
|
||||
SYSTEMTESTTOP=..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
|
|
@ -530,10 +530,11 @@ status=`expr $status + $ret`
|
|||
# Try validating with a revoked trusted key.
|
||||
# This should fail.
|
||||
|
||||
echo "I:checking that validation fails due to revoked trusted key ($n)"
|
||||
echo "I:checking that validation returns insecure due to revoked trusted key ($n)"
|
||||
ret=0
|
||||
$DIG $DIGOPTS example. soa @10.53.0.5 > dig.out.ns5.test$n || ret=1
|
||||
grep "SERVFAIL" dig.out.ns5.test$n > /dev/null || ret=1
|
||||
grep "flags:.*; QUERY" dig.out.ns5.test$n > /dev/null || ret=1
|
||||
grep "flags:.* ad.*; QUERY" dig.out.ns5.test$n > /dev/null && ret=1
|
||||
n=`expr $n + 1`
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: view.h,v 1.120 2009/11/28 15:57:37 vjs Exp $ */
|
||||
/* $Id: view.h,v 1.121 2010/05/14 04:38:52 marka Exp $ */
|
||||
|
||||
#ifndef DNS_VIEW_H
|
||||
#define DNS_VIEW_H 1
|
||||
|
|
@ -73,6 +73,7 @@
|
|||
|
||||
#include <dns/acl.h>
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/rdatastruct.h>
|
||||
#include <dns/types.h>
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
|
@ -962,4 +963,19 @@ dns_view_issecuredomain(dns_view_t *view, dns_name_t *name,
|
|||
*\li ISC_R_SUCCESS
|
||||
*\li Any other value indicates failure
|
||||
*/
|
||||
|
||||
void
|
||||
dns_view_untrust(dns_view_t *view, dns_name_t *keyname,
|
||||
dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx);
|
||||
/*%<
|
||||
* Remove keys that match 'keyname' and 'dnskey' from the views trust
|
||||
* anchors.
|
||||
*
|
||||
* Requires:
|
||||
* \li 'view' is valid.
|
||||
* \li 'keyname' is valid.
|
||||
* \li 'mctx' is valid.
|
||||
* \li 'dnskey' is valid.
|
||||
*/
|
||||
|
||||
#endif /* DNS_VIEW_H */
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: validator.c,v 1.191 2010/05/14 00:13:43 marka Exp $ */
|
||||
/* $Id: validator.c,v 1.192 2010/05/14 04:38:51 marka 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>
|
||||
|
|
@ -1746,16 +1746,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);
|
||||
|
||||
|
|
@ -1777,12 +1784,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,8 +1972,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;
|
||||
}
|
||||
|
|
@ -1997,25 +2021,102 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
|
|||
return (DNS_R_NOVALIDSIG);
|
||||
}
|
||||
|
||||
/*%
|
||||
* 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;
|
||||
|
||||
validator_log(val, ISC_LOG_DEBUG(3), "dlv_validatezonekey");
|
||||
|
|
@ -2080,70 +2181,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;
|
||||
|
|
@ -2185,14 +2243,10 @@ 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;
|
||||
|
|
@ -2235,8 +2289,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) {
|
||||
|
|
@ -2466,29 +2519,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),
|
||||
|
|
@ -2496,38 +2530,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;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: view.c,v 1.161 2010/02/25 05:08:01 tbox Exp $ */
|
||||
/* $Id: view.c,v 1.162 2010/05/14 04:38:51 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
|
|
@ -33,9 +33,11 @@
|
|||
#include <dns/cache.h>
|
||||
#include <dns/db.h>
|
||||
#include <dns/dlz.h>
|
||||
#include <dns/dnssec.h>
|
||||
#include <dns/events.h>
|
||||
#include <dns/forward.h>
|
||||
#include <dns/keytable.h>
|
||||
#include <dns/keyvalues.h>
|
||||
#include <dns/master.h>
|
||||
#include <dns/masterdump.h>
|
||||
#include <dns/order.h>
|
||||
|
|
@ -1566,3 +1568,36 @@ dns_view_issecuredomain(dns_view_t *view, dns_name_t *name,
|
|||
return (dns_keytable_issecuredomain(view->secroots_priv, name,
|
||||
secure_domain));
|
||||
}
|
||||
|
||||
void
|
||||
dns_view_untrust(dns_view_t *view, dns_name_t *keyname,
|
||||
dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx)
|
||||
{
|
||||
isc_result_t result;
|
||||
unsigned char data[4096];
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
isc_buffer_t buffer;
|
||||
dst_key_t *key = NULL;
|
||||
dns_keytable_t *sr = NULL;
|
||||
|
||||
/*
|
||||
* Clear the revoke bit, if set, so that the key will match what's
|
||||
* in secroots now.
|
||||
*/
|
||||
dnskey->flags &= ~DNS_KEYFLAG_REVOKE;
|
||||
|
||||
/* Convert dnskey to DST key. */
|
||||
isc_buffer_init(&buffer, data, sizeof(data));
|
||||
dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
|
||||
dns_rdatatype_dnskey, dnskey, &buffer);
|
||||
result = dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &key);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return;
|
||||
result = dns_view_getsecroots(view, &sr);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
dns_keytable_deletekeynode(sr, key);
|
||||
dns_keytable_detach(&sr);
|
||||
}
|
||||
dst_key_free(&key);
|
||||
}
|
||||
|
||||
|
|
|
|||
116
lib/dns/zone.c
116
lib/dns/zone.c
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: zone.c,v 1.561 2010/04/28 23:50:51 tbox Exp $ */
|
||||
/* $Id: zone.c,v 1.562 2010/05/14 04:38:51 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
|
|
@ -2855,39 +2855,11 @@ static void
|
|||
untrust_key(dns_viewlist_t *viewlist, dns_name_t *keyname, isc_mem_t *mctx,
|
||||
dns_rdata_dnskey_t *dnskey)
|
||||
{
|
||||
isc_result_t result;
|
||||
unsigned char data[4096];
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
isc_buffer_t buffer;
|
||||
dns_view_t *view;
|
||||
dst_key_t *key = NULL;
|
||||
|
||||
/*
|
||||
* Clear the revoke bit, if set, so that the key will match what's
|
||||
* in secroots now.
|
||||
*/
|
||||
dnskey->flags &= ~DNS_KEYFLAG_REVOKE;
|
||||
|
||||
/* Convert dnskey to DST key. */
|
||||
isc_buffer_init(&buffer, data, sizeof(data));
|
||||
dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
|
||||
dns_rdatatype_dnskey, dnskey, &buffer);
|
||||
result = dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &key);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return;
|
||||
|
||||
for (view = ISC_LIST_HEAD(*viewlist); view != NULL;
|
||||
view = ISC_LIST_NEXT(view, link)) {
|
||||
dns_keytable_t *sr = NULL;
|
||||
result = dns_view_getsecroots(view, &sr);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
continue;
|
||||
|
||||
dns_keytable_deletekeynode(sr, key);
|
||||
dns_keytable_detach(&sr);
|
||||
}
|
||||
|
||||
dst_key_free(&key);
|
||||
view = ISC_LIST_NEXT(view, link))
|
||||
dns_view_untrust(view, keyname, dnskey, mctx);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -7201,6 +7173,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
dst_key_t *dstkey;
|
||||
isc_stdtime_t now;
|
||||
int pending = 0;
|
||||
isc_boolean_t secure;
|
||||
|
||||
UNUSED(task);
|
||||
INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
|
||||
|
|
@ -7253,8 +7226,6 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
|
||||
/*
|
||||
* Validate the dnskeyset against the current trusted keys.
|
||||
* (Note, if a key has been revoked and isn't RSAMD5, then
|
||||
* its key ID will have changed.)
|
||||
*/
|
||||
for (result = dns_rdataset_first(&kfetch->dnskeysigset);
|
||||
result == ISC_R_SUCCESS;
|
||||
|
|
@ -7277,9 +7248,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
break;
|
||||
|
||||
if (dst_key_alg(dstkey) == sig.algorithm &&
|
||||
(dst_key_id(dstkey) == sig.keyid ||
|
||||
(sig.algorithm != 1 && sig.keyid ==
|
||||
((dst_key_id(dstkey) + 128) & 0xffff)))) {
|
||||
dst_key_id(dstkey) == sig.keyid) {
|
||||
result = dns_dnssec_verify2(keyname,
|
||||
&kfetch->dnskeyset,
|
||||
dstkey, ISC_FALSE,
|
||||
|
|
@ -7312,15 +7281,11 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
break;
|
||||
}
|
||||
|
||||
/* Failed to validate? Let's go home. */
|
||||
if (kfetch->dnskeyset.trust != dns_trust_secure) {
|
||||
dns_zone_log(zone, ISC_LOG_WARNING,
|
||||
"DNSKEY set for zone '%s' failed to validate",
|
||||
namebuf);
|
||||
CHECK(minimal_update(kfetch, ver, &diff));
|
||||
changed = ISC_TRUE;
|
||||
goto failure;
|
||||
}
|
||||
/*
|
||||
* If we were not able to verify the answer using the current
|
||||
* trusted keys then all we can do is look at any revoked keys.
|
||||
*/
|
||||
secure = ISC_TF(kfetch->dnskeyset.trust == dns_trust_secure);
|
||||
|
||||
/*
|
||||
* First scan keydataset to find keys that are not in dnskeyset
|
||||
|
|
@ -7354,7 +7319,10 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
if (! matchkey(&kfetch->dnskeyset, &keydatarr)) {
|
||||
isc_boolean_t deletekey = ISC_FALSE;
|
||||
|
||||
if (now < keydata.addhd) {
|
||||
if (!secure) {
|
||||
if (now > keydata.removehd)
|
||||
deletekey = ISC_TRUE;
|
||||
} else if (now < keydata.addhd) {
|
||||
dns_zone_log(zone, ISC_LOG_WARNING,
|
||||
"Pending key unexpectedly missing "
|
||||
"from %s; restarting acceptance "
|
||||
|
|
@ -7374,13 +7342,15 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
keydata.refresh = refresh_time(kfetch);
|
||||
}
|
||||
|
||||
/* Delete old version */
|
||||
CHECK(update_one_rr(kfetch->db, ver, &diff,
|
||||
DNS_DIFFOP_DEL, keyname, 0,
|
||||
&keydatarr));
|
||||
changed = ISC_TRUE;
|
||||
if (secure || deletekey) {
|
||||
/* Delete old version */
|
||||
CHECK(update_one_rr(kfetch->db, ver, &diff,
|
||||
DNS_DIFFOP_DEL, keyname, 0,
|
||||
&keydatarr));
|
||||
changed = ISC_TRUE;
|
||||
}
|
||||
|
||||
if (deletekey)
|
||||
if (!secure || deletekey)
|
||||
continue;
|
||||
|
||||
dns_rdata_reset(&keydatarr);
|
||||
|
|
@ -7439,7 +7409,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
dns_rdataset_current(&kfetch->keydataset, &keydatarr);
|
||||
dns_rdata_tostruct(&keydatarr, &keydata, NULL);
|
||||
|
||||
if (revoked) {
|
||||
if (revoked && revocable(kfetch, &keydata)) {
|
||||
if (keydata.addhd > now) {
|
||||
/*
|
||||
* Key wasn't trusted yet, and now
|
||||
|
|
@ -7447,20 +7417,6 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
*/
|
||||
deletekey = ISC_TRUE;
|
||||
} else if (keydata.removehd == 0) {
|
||||
/*
|
||||
* Newly revoked key? Make sure
|
||||
* it signed itself
|
||||
*/
|
||||
if(! revocable(kfetch, &keydata)) {
|
||||
dns_zone_log(zone,
|
||||
ISC_LOG_WARNING,
|
||||
"Active key for zone "
|
||||
"'%s' is revoked but "
|
||||
"did not self-sign; "
|
||||
"ignoring.", namebuf);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Remove from secroots */
|
||||
untrust_key(zone->view->viewlist,
|
||||
keyname, mctx, &dnskey);
|
||||
|
|
@ -7474,7 +7430,16 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
/* Scheduled for removal */
|
||||
deletekey = ISC_TRUE;
|
||||
}
|
||||
} else {
|
||||
} else if (revoked) {
|
||||
if (secure && keydata.removehd == 0) {
|
||||
dns_zone_log(zone, ISC_LOG_WARNING,
|
||||
"Active key for zone "
|
||||
"'%s' is revoked but "
|
||||
"did not self-sign; "
|
||||
"ignoring.", namebuf);
|
||||
continue;
|
||||
}
|
||||
} else if (secure) {
|
||||
if (keydata.removehd != 0) {
|
||||
/*
|
||||
* Key isn't revoked--but it
|
||||
|
|
@ -7495,7 +7460,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
|
||||
if (!deletekey && !newkey)
|
||||
updatekey = ISC_TRUE;
|
||||
} else {
|
||||
} else if (secure) {
|
||||
/*
|
||||
* Key wasn't in the key zone but it's
|
||||
* revoked now anyway, so just skip it
|
||||
|
|
@ -7641,6 +7606,7 @@ zone_refreshkeys(dns_zone_t *zone) {
|
|||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_rdata_keydata_t kd;
|
||||
isc_stdtime_t now;
|
||||
isc_boolean_t commit = ISC_FALSE;
|
||||
|
||||
ENTER;
|
||||
REQUIRE(zone->db != NULL);
|
||||
|
|
@ -7732,12 +7698,19 @@ zone_refreshkeys(dns_zone_t *zone) {
|
|||
&kfetch->dnskeysigset,
|
||||
&kfetch->fetch);
|
||||
}
|
||||
if (!ISC_LIST_EMPTY(diff.tuples)) {
|
||||
CHECK(increment_soa_serial(db, ver, &diff, zone->mctx));
|
||||
commit = ISC_TRUE;
|
||||
zone_journal(zone, &diff, "sync_keyzone");
|
||||
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
|
||||
zone_needdump(zone, 30);
|
||||
}
|
||||
failure:
|
||||
UNLOCK_ZONE(zone);
|
||||
|
||||
dns_rriterator_destroy(&rrit);
|
||||
dns_diff_clear(&diff);
|
||||
dns_db_closeversion(db, &ver, ISC_FALSE);
|
||||
dns_db_closeversion(db, &ver, commit);
|
||||
dns_db_detach(&db);
|
||||
}
|
||||
|
||||
|
|
@ -11147,7 +11120,8 @@ zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
|
|||
vsnprintf(message, sizeof(message), fmt, ap);
|
||||
va_end(ap);
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
|
||||
level, "%s: zone %s: %s", me, zone->strnamerd, message);
|
||||
level, "%s: %s %s: %s", me, zone->type != dns_zone_key ?
|
||||
"zone" : "managed-keys-zone", zone->strnamerd, message);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
|||
Loading…
Reference in a new issue