From 30e0169787ccd24f434164add18b0509d6fb1e90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Vavru=C5=A1a?= <marek.vavrusa@nic.cz> Date: Fri, 25 Sep 2015 13:54:30 +0200 Subject: [PATCH] lib/dnssec: accept valid and unrevoked keys (SEP not required), key matching --- lib/dnssec.c | 36 +++++++++++++++++++++++++++++++++++- lib/dnssec.h | 15 +++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/lib/dnssec.c b/lib/dnssec.c index b3b576593..6efd0190d 100644 --- a/lib/dnssec.c +++ b/lib/dnssec.c @@ -249,7 +249,7 @@ int kr_dnskeys_trusted(const knot_pkt_t *pkt, knot_section_t section_id, const k /* RFC4035 5.3.1, bullet 8 */ /* ZSK */ const knot_rdata_t *krr = knot_rdataset_at(&keys->rrs, i); const uint8_t *key_data = knot_rdata_data(krr); - if (!kr_dnssec_key_ksk(key_data) && !kr_dnssec_key_revoked(key_data)) { + if (!kr_dnssec_key_zsk(key_data) || kr_dnssec_key_revoked(key_data)) { continue; } @@ -272,6 +272,11 @@ int kr_dnskeys_trusted(const knot_pkt_t *pkt, knot_section_t section_id, const k return kr_error(ENOENT); } +bool kr_dnssec_key_zsk(const uint8_t *dnskey_rdata) +{ + return wire_read_u16(dnskey_rdata) & 0x0100; +} + bool kr_dnssec_key_ksk(const uint8_t *dnskey_rdata) { return wire_read_u16(dnskey_rdata) & 0x0001; @@ -304,6 +309,35 @@ int kr_dnssec_key_tag(uint16_t rrtype, const uint8_t *rdata, size_t rdlen) } } +int kr_dnssec_key_match(const uint8_t *key_a_rdata, size_t key_a_rdlen, + const uint8_t *key_b_rdata, size_t key_b_rdlen) +{ + dnssec_key_t *key_a = NULL, *key_b = NULL; + int ret = kr_dnssec_key_from_rdata((struct dseckey **)&key_a, NULL, key_a_rdata, key_a_rdlen); + if (ret != 0) { + return ret; + } + ret = kr_dnssec_key_from_rdata((struct dseckey **)&key_b, NULL, key_b_rdata, key_b_rdlen); + if (ret != 0) { + dnssec_key_free(key_a); + return ret; + } + /* If the algorithm and the public key match, we can be sure + * that they are the same key. */ + ret = kr_error(ENOENT); + dnssec_binary_t pk_a, pk_b; + if (dnssec_key_get_algorithm(key_a) == dnssec_key_get_algorithm(key_b) && + dnssec_key_get_pubkey(key_a, &pk_a) == DNSSEC_EOK && + dnssec_key_get_pubkey(key_b, &pk_b) == DNSSEC_EOK) { + if (pk_a.size == pk_b.size && memcmp(pk_a.data, pk_b.data, pk_a.size) == 0) { + ret = 0; + } + } + dnssec_key_free(key_a); + dnssec_key_free(key_b); + return ret; +} + int kr_dnssec_key_from_rdata(struct dseckey **key, const knot_dname_t *kown, const uint8_t *rdata, size_t rdlen) { if (!key || !rdata || rdlen == 0) { diff --git a/lib/dnssec.h b/lib/dnssec.h index b7d85e214..7679f730a 100644 --- a/lib/dnssec.h +++ b/lib/dnssec.h @@ -88,6 +88,9 @@ int kr_dnskeys_trusted(const knot_pkt_t *pkt, knot_section_t section_id, const k const knot_rrset_t *ta, const knot_dname_t *zone_name, uint32_t timestamp, bool has_nsec3); +/** Return true if the DNSKEY can be used as a ZSK. */ +bool kr_dnssec_key_zsk(const uint8_t *dnskey_rdata); + /** Return true if the DNSKEY indicates being KSK (=> has SEP). */ bool kr_dnssec_key_ksk(const uint8_t *dnskey_rdata); @@ -101,6 +104,18 @@ bool kr_dnssec_key_revoked(const uint8_t *dnskey_rdata); * @return Key tag (positive number), or an error code */ int kr_dnssec_key_tag(uint16_t rrtype, const uint8_t *rdata, size_t rdlen); + +/** Return 0 if the two keys are identical. + * @note This compares RDATA only, algorithm and public key must match. + * @param key_a_rdata First key RDATA + * @param key_a_rdlen First key RDATA length + * @param key_b_rdata Second key RDATA + * @param key_b_rdlen Second key RDATA length + * @return 0 if they match or an error code + */ +int kr_dnssec_key_match(const uint8_t *key_a_rdata, size_t key_a_rdlen, + const uint8_t *key_b_rdata, size_t key_b_rdlen); + /** * Construct a DNSSEC key. * @param key Pointer to be set to newly created DNSSEC key. -- GitLab