diff options
-rw-r--r-- | daemon/lua/kres-gen-30.lua | 2 | ||||
-rw-r--r-- | daemon/lua/kres-gen-31.lua | 2 | ||||
-rw-r--r-- | daemon/lua/kres-gen-32.lua | 2 | ||||
-rwxr-xr-x | daemon/lua/kres-gen.sh | 2 | ||||
-rw-r--r-- | lib/dnssec.c | 36 | ||||
-rw-r--r-- | lib/dnssec.h | 28 | ||||
-rw-r--r-- | lib/dnssec/ta.c | 5 | ||||
-rw-r--r-- | modules/ta_update/ta_update.lua | 4 |
8 files changed, 43 insertions, 38 deletions
diff --git a/daemon/lua/kres-gen-30.lua b/daemon/lua/kres-gen-30.lua index 48ea7a90..ae182a37 100644 --- a/daemon/lua/kres-gen-30.lua +++ b/daemon/lua/kres-gen-30.lua @@ -486,7 +486,7 @@ knot_rrset_t *kr_ta_get(trie_t *, const knot_dname_t *); int kr_ta_add(trie_t *, const knot_dname_t *, uint16_t, uint32_t, const uint8_t *, uint16_t); int kr_ta_del(trie_t *, const knot_dname_t *); void kr_ta_clear(trie_t *); -_Bool kr_dnssec_key_ksk(const uint8_t *); +_Bool kr_dnssec_key_sep_flag(const uint8_t *); _Bool kr_dnssec_key_revoked(const uint8_t *); int kr_dnssec_key_tag(uint16_t, const uint8_t *, size_t); int kr_dnssec_key_match(const uint8_t *, size_t, const uint8_t *, size_t); diff --git a/daemon/lua/kres-gen-31.lua b/daemon/lua/kres-gen-31.lua index 0bc50931..1033e104 100644 --- a/daemon/lua/kres-gen-31.lua +++ b/daemon/lua/kres-gen-31.lua @@ -486,7 +486,7 @@ knot_rrset_t *kr_ta_get(trie_t *, const knot_dname_t *); int kr_ta_add(trie_t *, const knot_dname_t *, uint16_t, uint32_t, const uint8_t *, uint16_t); int kr_ta_del(trie_t *, const knot_dname_t *); void kr_ta_clear(trie_t *); -_Bool kr_dnssec_key_ksk(const uint8_t *); +_Bool kr_dnssec_key_sep_flag(const uint8_t *); _Bool kr_dnssec_key_revoked(const uint8_t *); int kr_dnssec_key_tag(uint16_t, const uint8_t *, size_t); int kr_dnssec_key_match(const uint8_t *, size_t, const uint8_t *, size_t); diff --git a/daemon/lua/kres-gen-32.lua b/daemon/lua/kres-gen-32.lua index 88d9511f..23a338f0 100644 --- a/daemon/lua/kres-gen-32.lua +++ b/daemon/lua/kres-gen-32.lua @@ -487,7 +487,7 @@ knot_rrset_t *kr_ta_get(trie_t *, const knot_dname_t *); int kr_ta_add(trie_t *, const knot_dname_t *, uint16_t, uint32_t, const uint8_t *, uint16_t); int kr_ta_del(trie_t *, const knot_dname_t *); void kr_ta_clear(trie_t *); -_Bool kr_dnssec_key_ksk(const uint8_t *); +_Bool kr_dnssec_key_sep_flag(const uint8_t *); _Bool kr_dnssec_key_revoked(const uint8_t *); int kr_dnssec_key_tag(uint16_t, const uint8_t *, size_t); int kr_dnssec_key_match(const uint8_t *, size_t, const uint8_t *, size_t); diff --git a/daemon/lua/kres-gen.sh b/daemon/lua/kres-gen.sh index cd9a52cf..5939dc65 100755 --- a/daemon/lua/kres-gen.sh +++ b/daemon/lua/kres-gen.sh @@ -281,7 +281,7 @@ ${CDEFS} ${LIBKRES} functions <<-EOF kr_ta_del kr_ta_clear # DNSSEC - kr_dnssec_key_ksk + kr_dnssec_key_sep_flag kr_dnssec_key_revoked kr_dnssec_key_tag kr_dnssec_key_match diff --git a/lib/dnssec.c b/lib/dnssec.c index 262570c4..646ec828 100644 --- a/lib/dnssec.c +++ b/lib/dnssec.c @@ -225,7 +225,7 @@ struct kr_svldr_ctx * kr_svldr_new_ctx(const knot_rrset_t *ds, knot_rrset_t *dns array_reserve(ctx->keys, dnskey->rrs.count); knot_rdata_t *krr = dnskey->rrs.rdata; for (int i = 0; i < dnskey->rrs.count; ++i, krr = knot_rdataset_next(krr)) { - if (!kr_dnssec_key_zsk(krr->data) || kr_dnssec_key_revoked(krr->data)) + if (!kr_dnssec_key_usable(krr->data)) continue; // key not usable for this kr_svldr_key_t key; if (unlikely(svldr_key_new(krr, NULL/*seems OK here*/, &key) != 0)) @@ -448,6 +448,12 @@ bool kr_ds_algo_support(const knot_rrset_t *ta) return false; } +// Now we instantiate these two as non-inline externally linkable code here (for lua). +KR_EXPORT extern inline KR_PURE +bool kr_dnssec_key_sep_flag(const uint8_t *dnskey_rdata); +KR_EXPORT extern inline KR_PURE +bool kr_dnssec_key_revoked(const uint8_t *dnskey_rdata); + int kr_dnskeys_trusted(kr_rrset_validation_ctx_t *vctx, const knot_rdataset_t *sigs, const knot_rrset_t *ta) { @@ -461,11 +467,15 @@ int kr_dnskeys_trusted(kr_rrset_validation_ctx_t *vctx, const knot_rdataset_t *s /* RFC4035 5.2, bullet 1 * The supplied DS record has been authenticated. * It has been validated or is part of a configured trust anchor. + * + * We iterate backwards. That way we try keys with the SEP flag + * before those without it - and thus likely succeed faster. */ - knot_rdata_t *krr = keys->rrs.rdata; - for (int i = 0; i < keys->rrs.count; ++i, krr = knot_rdataset_next(krr)) { - /* RFC4035 5.3.1, bullet 8 */ /* ZSK */ - if (!kr_dnssec_key_zsk(krr->data) || kr_dnssec_key_revoked(krr->data)) + for (int i = keys->rrs.count; --i >= 0; ) { + const knot_rdata_t *krr = knot_rdataset_at(&keys->rrs, i); + + /* RFC4035 5.3.1, bullet 8 requires the Zone Flag bit */ + if (!kr_dnssec_key_usable(krr->data)) continue; kr_svldr_key_t key; @@ -487,22 +497,6 @@ int kr_dnskeys_trusted(kr_rrset_validation_ctx_t *vctx, const knot_rdataset_t *s return vctx->result; } -bool kr_dnssec_key_zsk(const uint8_t *dnskey_rdata) -{ - return knot_wire_read_u16(dnskey_rdata) & 0x0100; -} - -bool kr_dnssec_key_ksk(const uint8_t *dnskey_rdata) -{ - return knot_wire_read_u16(dnskey_rdata) & 0x0001; -} - -/** Return true if the DNSKEY is revoked. */ -bool kr_dnssec_key_revoked(const uint8_t *dnskey_rdata) -{ - return knot_wire_read_u16(dnskey_rdata) & 0x0080; -} - int kr_dnssec_key_tag(uint16_t rrtype, const uint8_t *rdata, size_t rdlen) { if (!rdata || rdlen == 0 || (rrtype != KNOT_RRTYPE_DS && rrtype != KNOT_RRTYPE_DNSKEY)) { diff --git a/lib/dnssec.h b/lib/dnssec.h index ca737cfe..52465042 100644 --- a/lib/dnssec.h +++ b/lib/dnssec.h @@ -94,17 +94,29 @@ bool kr_ds_algo_support(const knot_rrset_t *ta); int kr_dnskeys_trusted(kr_rrset_validation_ctx_t *vctx, const knot_rdataset_t *sigs, const knot_rrset_t *ta); -/** Return true if the DNSKEY can be used as a ZSK. */ -KR_EXPORT KR_PURE -bool kr_dnssec_key_zsk(const uint8_t *dnskey_rdata); +// flags: https://www.iana.org/assignments/dnskey-flags/dnskey-flags.xhtml +// https://datatracker.ietf.org/doc/html/rfc4034#section-2.1 -/** Return true if the DNSKEY indicates being KSK (=> has SEP). */ -KR_EXPORT KR_PURE -bool kr_dnssec_key_ksk(const uint8_t *dnskey_rdata); +/** Return true if the DNSKEY has the SEP flag (normally ignored). */ +KR_EXPORT inline KR_PURE +bool kr_dnssec_key_sep_flag(const uint8_t *dnskey_rdata) +{ + return dnskey_rdata[1] & 0x01; +} /** Return true if the DNSKEY is revoked. */ -KR_EXPORT KR_PURE -bool kr_dnssec_key_revoked(const uint8_t *dnskey_rdata); +KR_EXPORT inline KR_PURE +bool kr_dnssec_key_revoked(const uint8_t *dnskey_rdata) +{ + return dnskey_rdata[1] & 0x80; +} + +/** Return true if the DNSKEY could be used to validate zone records. */ +static inline KR_PURE +bool kr_dnssec_key_usable(const uint8_t *dnskey_rdata) +{ + return (dnskey_rdata[0] & 0x01) && !kr_dnssec_key_revoked(dnskey_rdata); +} /** Return DNSKEY tag. * @param rrtype RR type (either DS or DNSKEY are supported) diff --git a/lib/dnssec/ta.c b/lib/dnssec/ta.c index becf7d81..67f0a206 100644 --- a/lib/dnssec/ta.c +++ b/lib/dnssec/ta.c @@ -56,14 +56,13 @@ static int dnskey2ds(dnssec_binary_t *dst, const knot_dname_t *owner, const uint /* 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_revoked(rdata); - if (!flags_ok) { + if (!kr_dnssec_key_usable(rdata)) { 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; - } else if (!kr_dnssec_key_ksk(rdata)) { + } else if (!kr_dnssec_key_sep_flag(rdata)) { auto_free char *owner_str = kr_dname_text(owner); int flags = dnssec_key_get_flags(key); kr_log_warning(TA, "warning: %s DNSKEY is missing the SEP bit; " diff --git a/modules/ta_update/ta_update.lua b/modules/ta_update/ta_update.lua index 2361e167..3c059f85 100644 --- a/modules/ta_update/ta_update.lua +++ b/modules/ta_update/ta_update.lua @@ -58,7 +58,7 @@ end -- Evaluate TA status of a RR according to RFC5011. The time is in seconds. local function ta_present(keyset, rr, hold_down_time) - if rr.type == kres.type.DNSKEY and not C.kr_dnssec_key_ksk(rr.rdata) then + if rr.type == kres.type.DNSKEY and not C.kr_dnssec_key_sep_flag(rr.rdata) then return false -- Ignore end -- Attempt to extract key_tag @@ -212,7 +212,7 @@ local function check_upstream(keyset, new_keys) local ta = ta_find(keyset, rr) table.insert(process_keys, ta) - if rr.type == kres.type.DNSKEY and not C.kr_dnssec_key_ksk(rr.rdata) then + if rr.type == kres.type.DNSKEY and not C.kr_dnssec_key_sep_flag(rr.rdata) then goto continue -- Ignore end |