From b87d82157059c72fca58c9882dfabdddbfbfc354 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Vladim=C3=ADr=20=C4=8Cun=C3=A1t?= <vladimir.cunat@nic.cz>
Date: Mon, 7 Jan 2019 11:30:03 +0100
Subject: [PATCH] trust anchors: improvements around DNSKEY refusal

- also refuse revoked DNSKEY (explicitly configured as TA)
- typo in message that confused the meaning
- explicit message when DNSKEY is refused, even without --verbose
- code rewrite, handle flags in a better way than "== 257"
---
 daemon/lua/trust_anchors.lua.in |  2 +-
 lib/dnssec/ta.c                 | 37 +++++++++++++++++----------------
 2 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/daemon/lua/trust_anchors.lua.in b/daemon/lua/trust_anchors.lua.in
index 76f5139cd..49109361a 100644
--- a/daemon/lua/trust_anchors.lua.in
+++ b/daemon/lua/trust_anchors.lua.in
@@ -430,7 +430,7 @@ local add_file = function (path, unmanaged)
 
 	-- Parse new keys, refresh eventually
 	if keyset_publish(keyset) == 0 then
-		warn('[ ta ] ERROR: anchors are trusted for ' .. owner_str .. ' !')
+		warn('[ ta ] ERROR: no anchors are trusted for ' .. owner_str .. ' !')
 		-- TODO: try to rebootstrap?
 	end
 	refresh_plan(keyset, 10 * sec, false)
diff --git a/lib/dnssec/ta.c b/lib/dnssec/ta.c
index 323d89b47..f3560b8c6 100644
--- a/lib/dnssec/ta.c
+++ b/lib/dnssec/ta.c
@@ -23,6 +23,7 @@
 #include <libdnssec/error.h>
 
 #include "lib/defines.h"
+#include "lib/dnssec.h"
 #include "lib/dnssec/ta.h"
 #include "lib/resolve.h"
 #include "lib/utils.h"
@@ -51,29 +52,29 @@ static int dnskey2ds(dnssec_binary_t *dst, const knot_dname_t *owner, const uint
 {
 	dnssec_key_t *key = NULL;
 	int ret = dnssec_key_new(&key);
-	if (ret != DNSSEC_EOK) {
-		return kr_error(ENOMEM);
-	}
+	if (ret) goto cleanup;
 	/* Create DS from DNSKEY and reinsert */
 	const dnssec_binary_t key_data = { .size = rdlen, .data = (uint8_t *)rdata };
 	ret = dnssec_key_set_rdata(key, &key_data);
-	if (ret == DNSSEC_EOK) {
-		/* Accept only KSK (257) to TA store */
-		if (dnssec_key_get_flags(key) == 257)  {
-			ret = dnssec_key_set_dname(key, owner);
-		} else {
-			ret = DNSSEC_EINVAL;
-		}
-		if (ret == DNSSEC_EOK) {
-			ret = dnssec_key_create_ds(key, DNSSEC_KEY_DIGEST_SHA256, dst);
-		}
+	if (ret) goto cleanup;
+	/* Accept only keys with Zone and SEP flags that aren't revoked,
+	 * as a precaution.  RFC 5011 also utilizes these flags.
+	 * TODO: kr_dnssec_key_* names are confusing. */
+	const bool flags_ok = kr_dnssec_key_zsk(rdata) && kr_dnssec_key_ksk(rdata)
+	    && !kr_dnssec_key_revoked(rdata);
+	if (!flags_ok) {
+		auto_free char *owner_str = kr_dname_text(owner);
+		kr_log_error("[ ta ] refusing to trust %s DNSKEY because of flags %d\n",
+			owner_str, dnssec_key_get_flags(key));
+		ret = kr_error(EILSEQ);
+		goto cleanup;
 	}
+	ret = dnssec_key_set_dname(key, owner);
+	if (ret) goto cleanup;
+	ret = dnssec_key_create_ds(key, DNSSEC_KEY_DIGEST_SHA256, dst);
+cleanup:
 	dnssec_key_free(key);
-	/* Pick some sane error code */
-	if (ret != DNSSEC_EOK) {
-		return kr_error(ENOMEM);
-	}
-	return kr_ok();
+	return kr_error(ret);
 }
 
 /* @internal Insert new TA to trust anchor set, rdata MUST be of DS type. */
-- 
GitLab