diff --git a/lib/dnssec/ta.c b/lib/dnssec/ta.c index fe3c0d5c07f660a79ad2b1103b0a5a6c53eb58f1..f9fd2bd9630d26900cf64ecc09b0aaefda66e5d6 100644 --- a/lib/dnssec/ta.c +++ b/lib/dnssec/ta.c @@ -26,6 +26,7 @@ #include <libknot/rdataset.h> #include <libknot/rrset.h> #include <libknot/rrtype/rdname.h> +#include <libknot/packet/wire.h> #include "lib/defines.h" #include "lib/dnssec/ta.h" @@ -644,6 +645,20 @@ int kr_ta_contains(struct trust_anchors *tas, const knot_dname_t *name) return ta_find(&tas->locked, name) != NULL; } +int kr_ta_covers(struct trust_anchors *tas, const knot_dname_t *name) +{ + while(name) { + if (kr_ta_contains(tas, name)) { + return true; + } + if (name[0] == '\0') { + return false; + } + name = knot_wire_next_label(name, NULL); + } + return false; +} + int kr_ta_get(knot_rrset_t **ta, struct trust_anchors *tas, const knot_dname_t *name, mm_ctx_t *pool) { if (!ta || !tas || !name) { diff --git a/lib/dnssec/ta.h b/lib/dnssec/ta.h index 7d57d932c5992dfe59d6699c27d9abf7439ddaea..3900044373bc2a11c80ba6a216f86d1e9d07a135 100644 --- a/lib/dnssec/ta.h +++ b/lib/dnssec/ta.h @@ -50,6 +50,8 @@ int kr_ta_add(struct trust_anchors *tas, const char *ta_str); int kr_ta_contains(struct trust_anchors *tas, const knot_dname_t *name); +int kr_ta_covers(struct trust_anchors *tas, const knot_dname_t *name); + int kr_ta_get(knot_rrset_t **ta, struct trust_anchors *tas, const knot_dname_t *name, mm_ctx_t *pool); int kr_ta_rdlock(struct trust_anchors *tas); diff --git a/lib/resolve.c b/lib/resolve.c index ae623568de2947767b15208390abad847d4369b1..94084ce1730d26940d214cbb0806ae6ba871d6b6 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -344,17 +344,14 @@ static int zone_cut_check(struct kr_request *request, struct kr_query *qry, knot { struct kr_rplan *rplan = &request->rplan; - /* Always try with DNSSEC if it finds an island of trust. */ - if (!(request->options & QUERY_DNSSEC_WANT) && - kr_ta_contains(&global_trust_anchors, qry->zone_cut.name)) { - request->options |= QUERY_DNSSEC_WANT; - DEBUG_MSG(">< entered island of trust\n"); - } /* The query wasn't resolved from cache, * now it's the time to look up closest zone cut from cache. */ - bool want_secured = (request->options & QUERY_DNSSEC_WANT); if (qry->flags & QUERY_AWAIT_CUT) { - int ret = ns_fetch_cut(qry, request, want_secured); + /* Want DNSSEC if it's posible to secure this name (e.g. is covered by any TA) */ + if (kr_ta_covers(&global_trust_anchors, qry->zone_cut.name)) { + qry->flags |= QUERY_DNSSEC_WANT; + } + int ret = ns_fetch_cut(qry, request, (qry->flags & QUERY_DNSSEC_WANT)); if (ret != 0) { return KNOT_STATE_FAIL; } @@ -366,10 +363,22 @@ static int zone_cut_check(struct kr_request *request, struct kr_query *qry, knot } qry->flags &= ~QUERY_AWAIT_CUT; } - - /* Missing delegation signature, fetch it first. */ - if ((qry->flags & QUERY_AWAIT_DS) && (qry->zone_cut.missing_name)) { - int ret = zone_cut_subreq(rplan, qry, qry->zone_cut.missing_name, KNOT_RRTYPE_DS); + /* Enable DNSSEC if enters a new island of trust. */ + bool want_secured = (qry->flags & QUERY_DNSSEC_WANT); + if (!want_secured && kr_ta_contains(&global_trust_anchors, qry->zone_cut.name)) { + qry->flags |= QUERY_DNSSEC_WANT; + want_secured = true; + WITH_DEBUG { + char qname_str[KNOT_DNAME_MAXLEN]; + knot_dname_to_str(qname_str, qry->zone_cut.name, sizeof(qname_str)); + DEBUG_MSG(">< TA: using '%s'\n", qname_str); + } + } + /* @todo Disable DNSSEC if it encounters NTA */ + if (want_secured && !qry->zone_cut.trust_anchor) { + kr_ta_get(&qry->zone_cut.trust_anchor, &global_trust_anchors, + qry->zone_cut.name, qry->zone_cut.pool); + } if (ret != 0) { return KNOT_STATE_FAIL; } diff --git a/lib/zonecut.c b/lib/zonecut.c index c0bb394a99169954fa113e42d725af370749a4f1..3a3baa41fb05fd84cc4cacc49988ceadb72f2259 100644 --- a/lib/zonecut.c +++ b/lib/zonecut.c @@ -24,7 +24,6 @@ #include "lib/rplan.h" #include "lib/defines.h" #include "lib/layer.h" -#include "lib/dnssec/ta.h" // kr_ta_parse() #include "lib/generic/pack.h" /* Root hint descriptor. */ @@ -291,13 +290,6 @@ int kr_zonecut_set_sbelt(struct kr_context *ctx, struct kr_zonecut *cut) /* Set trust anchor. */ knot_rrset_free(&cut->trust_anchor, cut->pool); - /* The root trust anchor can be changed via the validator layer - * (interactive) interface. - */ - int ret = kr_ta_get(&cut->trust_anchor, &global_trust_anchors, ROOT_NAME, cut->pool); - if (ret != 0) { - return ret; - } return kr_ok(); }