summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authormenakite <29005531+menakite@users.noreply.github.com>2024-08-13 18:52:45 +0200
committerVladimír Čunát <vladimir.cunat@nic.cz>2024-09-06 12:26:40 +0200
commitfd7066d0033a45ecf58108e64a8c1865e5aaff3a (patch)
treedfd12133d0552e2325e3f121b4764c376657e9ea /lib
parentresolver,validator: provide more EDE codes. (diff)
downloadknot-resolver-fd7066d0033a45ecf58108e64a8c1865e5aaff3a.tar.xz
knot-resolver-fd7066d0033a45ecf58108e64a8c1865e5aaff3a.zip
validator: set EDE code if SEP does not match or DNSKEY is revoked.
If the tag and algorithm of DS and DNSKEY do not correspond, or in case the DNSKEY is revoked, set EDE code "DNSKEY Missing". If both match, but the algorithm is not supported, set EDE code "Unsupported DNSKEY Algorithm". In case RRSIGs for DNSKEY exist, but can't be validated due to a key error, set EDE code "RRSIGs Missing".
Diffstat (limited to 'lib')
-rw-r--r--lib/layer/validate.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/lib/layer/validate.c b/lib/layer/validate.c
index d6840a52..1a871b44 100644
--- a/lib/layer/validate.c
+++ b/lib/layer/validate.c
@@ -12,6 +12,7 @@
#include <libknot/rrtype/rdname.h>
#include <libknot/rrtype/rrsig.h>
#include <libdnssec/error.h>
+#include <libdnssec/key.h>
#include "lib/dnssec/nsec.h"
#include "lib/dnssec/nsec3.h"
@@ -403,8 +404,37 @@ static int validate_keyset(struct kr_request *req, knot_pkt_t *answer, bool has_
ret == 0 ? KR_RANK_SECURE : KR_RANK_BOGUS);
if (ret != 0) {
- if (!kr_dnssec_key_zonekey_flag(qry->zone_cut.key->rrs.rdata->data))
+ const knot_rdataset_t *ds = &qry->zone_cut.trust_anchor->rrs;
+ int sep_keytag = kr_dnssec_key_tag(KNOT_RRTYPE_DS, ds->rdata->data, ds->rdata->len);
+ int dnskey_keytag = -1;
+ bool have_zone_key_bit = true, dnskey_algo_supported = true;
+ knot_rdata_t *rdata_sep = NULL, *rdata_i = qry->zone_cut.key->rrs.rdata;
+ for (uint8_t i = 0; i < qry->zone_cut.key->rrs.count;
+ ++i, rdata_i = knot_rdataset_next(rdata_i)) {
+ if (dnskey_keytag != sep_keytag) {
+ dnskey_keytag = kr_dnssec_key_tag(KNOT_RRTYPE_DNSKEY, rdata_i->data, rdata_i->len);
+ rdata_sep = rdata_i;
+ }
+
+ if (!kr_dnssec_key_zonekey_flag(rdata_i->data))
+ have_zone_key_bit = false;
+
+ if (!dnssec_algorithm_key_support(knot_dnskey_alg(rdata_i)))
+ dnskey_algo_supported = false;
+ }
+ bool sep_matches_tag_algo = rdata_sep && sep_keytag == dnskey_keytag &&
+ knot_ds_alg(ds->rdata) == knot_dnskey_alg(rdata_sep);
+
+ if (!have_zone_key_bit)
kr_request_set_extended_error(req, KNOT_EDNS_EDE_DNSKEY_BIT, "CYNG");
+ else if (!sep_matches_tag_algo)
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_DNSKEY_MISS, "NMJZ: no matching SEP");
+ else if (kr_dnssec_key_revoked(rdata_sep->data))
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_DNSKEY_MISS, "DGVI: DNSKEY matching SEP has the Revoke bit set");
+ else if (!dnskey_algo_supported)
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_DNSKEY_ALG, "H6OO");
+ else if (vctx.rrs_counters.matching_name_type == 0 && vctx.rrs_counters.key_invalid > 0)
+ kr_request_set_extended_error(req, KNOT_EDNS_EDE_RRSIG_MISS, "7N4Z: no valid RRSIGs for DNSKEY");
else if (vctx.rrs_counters.expired_before_inception > 0)
kr_request_set_extended_error(req, KNOT_EDNS_EDE_EXPIRED_INV, "4UBF");
else if (vctx.rrs_counters.expired > 0)
@@ -1394,10 +1424,8 @@ static int validate_finalize(kr_layer_t *ctx) {
case KNOT_EDNS_EDE_DNSKEY_BIT:
case KNOT_EDNS_EDE_DNSKEY_ALG:
case KNOT_EDNS_EDE_DS_DIGEST:
- kr_request_set_extended_error(ctx->req, KNOT_EDNS_EDE_NONE, NULL);
- break;
case KNOT_EDNS_EDE_DNSKEY_MISS:
- kr_assert(false); /* These EDE codes aren't used. */
+ kr_request_set_extended_error(ctx->req, KNOT_EDNS_EDE_NONE, NULL);
break;
default: break; /* Remaining codes don't indicate hard DNSSEC failure. */
}