summaryrefslogtreecommitdiff
path: root/src/resolve/resolved-dns-transaction.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-01-07 20:33:31 +0100
committerLennart Poettering <lennart@poettering.net>2016-01-11 19:39:59 +0100
commitc9c72065419e6595131a6fe1e663e2184a843f7c (patch)
tree1706d1d0ab0ea9cc4c960af9977c5e4235fa0661 /src/resolve/resolved-dns-transaction.c
parentd12315a4c883af968ec5ffb36a5aed3dc43b7ce7 (diff)
resolved: when validating, first strip revoked trust anchor keys from validated keys list
When validating a transaction we initially collect DNSKEY, DS, SOA RRs in the "validated_keys" list, that we need for the proofs. This includes DNSKEY and DS data from our trust anchor database. Quite possibly we learn that some of these DNSKEY/DS RRs have been revoked between the time we request and collect those additional RRs and we begin the validation step. In this case we need to make sure that the respective DS/DNSKEY RRs are removed again from our list. This patch adds that, and strips known revoked trust anchor RRs from the validated list before we begin the actual validation proof, and each time we add more DNSKEY material to it while we are doing the proof.
Diffstat (limited to 'src/resolve/resolved-dns-transaction.c')
-rw-r--r--src/resolve/resolved-dns-transaction.c55
1 files changed, 53 insertions, 2 deletions
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index 62075f2ef3..23378ce4f1 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -2247,6 +2247,39 @@ static int dns_transaction_check_revoked_trust_anchors(DnsTransaction *t) {
return 0;
}
+static int dns_transaction_invalidate_revoked_keys(DnsTransaction *t) {
+ bool changed;
+ int r;
+
+ assert(t);
+
+ /* Removes all DNSKEY/DS objects from t->validated_keys that
+ * our trust anchors database considers revoked. */
+
+ do {
+ DnsResourceRecord *rr;
+
+ changed = false;
+
+ DNS_ANSWER_FOREACH(rr, t->validated_keys) {
+ r = dns_trust_anchor_is_revoked(&t->scope->manager->trust_anchor, rr);
+ if (r < 0)
+ return r;
+ if (r > 0) {
+ r = dns_answer_remove_by_rr(&t->validated_keys, rr);
+ if (r < 0)
+ return r;
+
+ assert(r > 0);
+ changed = true;
+ break;
+ }
+ }
+ } while (changed);
+
+ return 0;
+}
+
int dns_transaction_validate_dnssec(DnsTransaction *t) {
_cleanup_(dns_answer_unrefp) DnsAnswer *validated = NULL;
bool dnskeys_finalized = false;
@@ -2287,16 +2320,26 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) {
log_debug("Validating response from transaction %" PRIu16 " (%s).", t->id, dns_transaction_key_string(t));
- /* First, see if this response contains any revoked trust anchors we care about */
+ /* First, see if this response contains any revoked trust
+ * anchors we care about */
r = dns_transaction_check_revoked_trust_anchors(t);
if (r < 0)
return r;
- /* Second see if there are DNSKEYs we already know a validated DS for. */
+ /* Second, see if there are DNSKEYs we already know a
+ * validated DS for. */
r = dns_transaction_validate_dnskey_by_ds(t);
if (r < 0)
return r;
+ /* Third, remove all DNSKEY and DS RRs again that our trust
+ * anchor says are revoked. After all we might have marked
+ * some keys revoked above, but they might still be lingering
+ * in our validated_keys list. */
+ r = dns_transaction_invalidate_revoked_keys(t);
+ if (r < 0)
+ return r;
+
for (;;) {
bool changed = false;
@@ -2324,6 +2367,14 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) {
r = dns_answer_copy_by_key(&t->validated_keys, t->answer, rr->key, DNS_ANSWER_AUTHENTICATED);
if (r < 0)
return r;
+
+ /* some of the DNSKEYs we just
+ * added might already have
+ * been revoked, remove them
+ * again in that case. */
+ r = dns_transaction_invalidate_revoked_keys(t);
+ if (r < 0)
+ return r;
}
/* Add the validated RRset to the new