]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: rework trust anchor revoke checking
authorLennart Poettering <lennart@poettering.net>
Thu, 7 Jan 2016 16:03:31 +0000 (17:03 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 11 Jan 2016 18:39:59 +0000 (19:39 +0100)
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.

src/resolve/resolved-dns-transaction.c
src/resolve/resolved-dns-trust-anchor.c
src/resolve/resolved-dns-trust-anchor.h

index b393c5238aa21de796d2032efbed08095a984537..62075f2ef3fd85c1359178eb8b62651d880940f7 100644 (file)
@@ -2239,10 +2239,7 @@ static int dns_transaction_check_revoked_trust_anchors(DnsTransaction *t) {
          * sufficient if it is self-signed. */
 
         DNS_ANSWER_FOREACH(rr, t->answer) {
-                if (rr->key->type != DNS_TYPE_DNSKEY)
-                        continue;
-
-                r = dns_trust_anchor_check_revoked(&t->scope->manager->trust_anchor, t->answer, rr->key);
+                r = dns_trust_anchor_check_revoked(&t->scope->manager->trust_anchor, rr, t->answer);
                 if (r < 0)
                         return r;
         }
index 9f8b76ebe2f69f9a672612d417392e6d985bd088..d2a9c3635b6a0ae0c92bcd8fe299464c1bd8a6a5 100644 (file)
@@ -643,61 +643,57 @@ static int dns_trust_anchor_check_revoked_one(DnsTrustAnchor *d, DnsResourceReco
         return 0;
 }
 
-int dns_trust_anchor_check_revoked(DnsTrustAnchor *d, DnsAnswer *rrs, const DnsResourceKey *key) {
-        DnsResourceRecord *dnskey;
+int dns_trust_anchor_check_revoked(DnsTrustAnchor *d, DnsResourceRecord *dnskey, DnsAnswer *rrs) {
+        DnsResourceRecord *rrsig;
         int r;
 
         assert(d);
-        assert(key);
+        assert(dnskey);
+
+        /* 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. */
 
-        /* Looks for self-signed DNSKEY RRs in "rrs" that have been revoked. */
+        if (dnskey->key->type != DNS_TYPE_DNSKEY)
+                return 0;
 
-        if (key->type != DNS_TYPE_DNSKEY)
+        /* Is this DNSKEY revoked? */
+        if ((dnskey->dnskey.flags & DNSKEY_FLAG_REVOKE) == 0)
                 return 0;
 
-        DNS_ANSWER_FOREACH(dnskey, rrs) {
-                DnsResourceRecord *rrsig;
+        /* 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;
 
-                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)
                         return r;
                 if (r == 0)
                         continue;
 
-                /* Is this DNSKEY revoked? */
-                if ((dnskey->dnskey.flags & DNSKEY_FLAG_REVOKE) == 0)
-                        continue;
-
-                /* 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)))
+                r = dnssec_verify_rrset(rrs, dnskey->key, rrsig, dnskey, USEC_INFINITY, &result);
+                if (r < 0)
+                        return r;
+                if (result != DNSSEC_VALIDATED)
                         continue;
 
-                /* Look for a self-signed RRSIG */
-                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! This is a revoked self-signed DNSKEY. Let's
+                 * see if this precise one exists in our trust anchor
+                 * database, too. */
+                r = dns_trust_anchor_check_revoked_one(d, dnskey);
+                if (r < 0)
+                        return r;
 
-                        /* Bingo! Now, act! */
-                        r = dns_trust_anchor_check_revoked_one(d, dnskey);
-                        if (r < 0)
-                                return r;
-                }
+                return 1;
         }
 
         return 0;
index 303c4088d17290cfec5efba303bd3e8365180bb0..054c98da70163904312bf36252977a969f7b442c 100644 (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_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);