diff --git a/lib/dns/validator.c b/lib/dns/validator.c index dcc98bd8f6..617f03124e 100644 --- a/lib/dns/validator.c +++ b/lib/dns/validator.c @@ -1287,26 +1287,50 @@ selfsigned_dnskey(dns_validator_t *val) { continue; } + /* + * If the REVOKE bit is not set we have a + * theoretically self signed DNSKEY RRset. + * This will be verified later. + */ + if ((key.flags & DNS_KEYFLAG_REVOKE) == 0) { + answer = true; + continue; + } + result = dns_dnssec_keyfromrdata(name, &keyrdata, mctx, &dstkey); if (result != ISC_R_SUCCESS) { continue; } - result = dns_dnssec_verify(name, rdataset, dstkey, true, - val->view->maxbits, mctx, - &sigrdata, NULL); + /* + * If this RRset is pending and it is trusted, + * see if it was self signed by this DNSKEY. + */ + if (DNS_TRUST_PENDING(rdataset->trust) && + dns_view_istrusted(val->view, name, &key)) + { + result = dns_dnssec_verify( + name, rdataset, dstkey, true, + val->view->maxbits, mctx, &sigrdata, + NULL); + if (result == ISC_R_SUCCESS) { + /* + * The key with the REVOKE flag has + * self signed the RRset so it is no + * good. + */ + dns_view_untrust(val->view, name, &key); + } + } else if (rdataset->trust >= dns_trust_secure) { + /* + * We trust this RRset so if the key is + * marked revoked remove it. + */ + dns_view_untrust(val->view, name, &key); + } + dst_key_free(&dstkey); - if (result != ISC_R_SUCCESS) { - continue; - } - - if ((key.flags & DNS_KEYFLAG_REVOKE) == 0) { - answer = true; - continue; - } - - dns_view_untrust(val->view, name, &key); } }