2892. [bug] Handle REVOKED keys better. [RT #20961]

This commit is contained in:
Mark Andrews 2010-05-14 04:38:52 +00:00
parent d2dd525033
commit 44f175a90a
6 changed files with 242 additions and 207 deletions

View file

@ -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]

View file

@ -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`

View file

@ -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 */

View file

@ -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;

View file

@ -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);
}

View file

@ -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