resolved: rework trust anchor revoke checking

Instead of first iterating through all DNSKEYs in the DnsAnswer in
dns_transaction_check_revoked_trust_anchors(), and
then doing that a second time in dns_trust_anchor_check_revoked(), do so
only once in the former, and pass the dnskey we found directly to the
latter.
This commit is contained in:
Lennart Poettering 2016-01-07 17:03:31 +01:00
parent 0f87f3e8e7
commit d424da2ae0
3 changed files with 36 additions and 43 deletions

View File

@ -2239,10 +2239,7 @@ static int dns_transaction_check_revoked_trust_anchors(DnsTransaction *t) {
* sufficient if it is self-signed. */ * sufficient if it is self-signed. */
DNS_ANSWER_FOREACH(rr, t->answer) { DNS_ANSWER_FOREACH(rr, t->answer) {
if (rr->key->type != DNS_TYPE_DNSKEY) r = dns_trust_anchor_check_revoked(&t->scope->manager->trust_anchor, rr, t->answer);
continue;
r = dns_trust_anchor_check_revoked(&t->scope->manager->trust_anchor, t->answer, rr->key);
if (r < 0) if (r < 0)
return r; return r;
} }

View File

@ -643,61 +643,57 @@ static int dns_trust_anchor_check_revoked_one(DnsTrustAnchor *d, DnsResourceReco
return 0; return 0;
} }
int dns_trust_anchor_check_revoked(DnsTrustAnchor *d, DnsAnswer *rrs, const DnsResourceKey *key) { int dns_trust_anchor_check_revoked(DnsTrustAnchor *d, DnsResourceRecord *dnskey, DnsAnswer *rrs) {
DnsResourceRecord *dnskey; DnsResourceRecord *rrsig;
int r; int r;
assert(d); assert(d);
assert(key); assert(dnskey);
/* Looks for self-signed DNSKEY RRs in "rrs" that have been revoked. */ /* Looks if "dnskey" is a self-signed RR that has been revoked
* and matches one of our trust anchor entries. If so, removes
* it from the trust anchor and returns > 0. */
if (key->type != DNS_TYPE_DNSKEY) if (dnskey->key->type != DNS_TYPE_DNSKEY)
return 0; return 0;
DNS_ANSWER_FOREACH(dnskey, rrs) { /* Is this DNSKEY revoked? */
DnsResourceRecord *rrsig; if ((dnskey->dnskey.flags & DNSKEY_FLAG_REVOKE) == 0)
return 0;
/* Could this be interesting to us at all? If not,
* there's no point in looking for and verifying a
* self-signed RRSIG. */
if (!dns_trust_anchor_knows_domain_positive(d, DNS_RESOURCE_KEY_NAME(dnskey->key)))
return 0;
/* Look for a self-signed RRSIG in the other rrs belonging to this DNSKEY */
DNS_ANSWER_FOREACH(rrsig, rrs) {
DnssecResult result; DnssecResult result;
r = dns_resource_key_equal(key, dnskey->key); if (rrsig->key->type != DNS_TYPE_RRSIG)
continue;
r = dnssec_rrsig_match_dnskey(rrsig, dnskey, true);
if (r < 0) if (r < 0)
return r; return r;
if (r == 0) if (r == 0)
continue; continue;
/* Is this DNSKEY revoked? */ r = dnssec_verify_rrset(rrs, dnskey->key, rrsig, dnskey, USEC_INFINITY, &result);
if ((dnskey->dnskey.flags & DNSKEY_FLAG_REVOKE) == 0) if (r < 0)
return r;
if (result != DNSSEC_VALIDATED)
continue; continue;
/* Could this be interesting to us at all? If not, /* Bingo! This is a revoked self-signed DNSKEY. Let's
* there's no point in looking for and verifying a * see if this precise one exists in our trust anchor
* self-signed RRSIG. */ * database, too. */
if (!dns_trust_anchor_knows_domain_positive(d, DNS_RESOURCE_KEY_NAME(dnskey->key))) r = dns_trust_anchor_check_revoked_one(d, dnskey);
continue; if (r < 0)
return r;
/* Look for a self-signed RRSIG */ return 1;
DNS_ANSWER_FOREACH(rrsig, rrs) {
if (rrsig->key->type != DNS_TYPE_RRSIG)
continue;
r = dnssec_rrsig_match_dnskey(rrsig, dnskey, true);
if (r < 0)
return r;
if (r == 0)
continue;
r = dnssec_verify_rrset(rrs, key, rrsig, dnskey, USEC_INFINITY, &result);
if (r < 0)
return r;
if (result != DNSSEC_VALIDATED)
continue;
/* Bingo! Now, act! */
r = dns_trust_anchor_check_revoked_one(d, dnskey);
if (r < 0)
return r;
}
} }
return 0; return 0;

View File

@ -40,4 +40,4 @@ void dns_trust_anchor_flush(DnsTrustAnchor *d);
int dns_trust_anchor_lookup_positive(DnsTrustAnchor *d, const DnsResourceKey* key, DnsAnswer **answer); int dns_trust_anchor_lookup_positive(DnsTrustAnchor *d, const DnsResourceKey* key, DnsAnswer **answer);
int dns_trust_anchor_lookup_negative(DnsTrustAnchor *d, const char *name); int dns_trust_anchor_lookup_negative(DnsTrustAnchor *d, const char *name);
int dns_trust_anchor_check_revoked(DnsTrustAnchor *d, DnsAnswer *rrs, const DnsResourceKey *key); int dns_trust_anchor_check_revoked(DnsTrustAnchor *d, DnsResourceRecord *dnskey, DnsAnswer *rrs);