summaryrefslogtreecommitdiffstats
path: root/lib/dnssec/signature.c
diff options
context:
space:
mode:
authorVladimír Čunát <vladimir.cunat@nic.cz>2022-01-20 19:43:40 +0100
committerVladimír Čunát <vladimir.cunat@nic.cz>2022-02-04 15:31:56 +0100
commitd4e95821aecc313f7c37879b7b133a5766172032 (patch)
tree313a5df5ea75d780ca89f3680807d6334afa6715 /lib/dnssec/signature.c
parentMerge !1226: daemon/worker: add task timeouts for upstream TCP connections (diff)
downloadknot-resolver-d4e95821aecc313f7c37879b7b133a5766172032.tar.xz
knot-resolver-d4e95821aecc313f7c37879b7b133a5766172032.zip
lib/dnssec: conditionally ignore SHA1 DS, as SHOULD by RFC4509
We're a bit late with this ad-hoc rule; I think it was most useful when SHA256 support in DS algorithms wasn't wide-spread yet. (Note that DNSKEY algos have standardized no similar rule.) Usage of SHA1 as DS algorithm is highly discouraged, but even at this point it does *not* seem unsafe, in the sense of anyone publishing an attack that would come anywhere close to breaking *this* usage of SHA1.
Diffstat (limited to 'lib/dnssec/signature.c')
-rw-r--r--lib/dnssec/signature.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/lib/dnssec/signature.c b/lib/dnssec/signature.c
index 6fcf3a42..062067a0 100644
--- a/lib/dnssec/signature.c
+++ b/lib/dnssec/signature.c
@@ -47,18 +47,34 @@ int kr_authenticate_referral(const knot_rrset_t *ref, const dnssec_key_t *key)
if (ref->type != KNOT_RRTYPE_DS)
return kr_error(EINVAL);
- /* Try all possible DS records */
- int ret = 0;
+ /* Determine whether to ignore SHA1 digests, because:
+ https://datatracker.ietf.org/doc/html/rfc4509#section-3
+ * Now, the RFCs seem to only mention SHA1 and SHA256 (e.g. no SHA384),
+ * but the most natural extension is to make any other algorithm trump SHA1.
+ * (Note that the old GOST version is already unsupported by libdnssec.) */
+ bool skip_sha1 = false;
knot_rdata_t *rd = ref->rrs.rdata;
- for (uint16_t i = 0; i < ref->rrs.count; ++i) {
+ for (int i = 0; i < ref->rrs.count; ++i, rd = knot_rdataset_next(rd)) {
+ const uint8_t algo = knot_ds_digest_type(rd);
+ if (algo != DNSSEC_KEY_DIGEST_SHA1 && dnssec_algorithm_digest_support(algo)) {
+ skip_sha1 = true;
+ break;
+ }
+ }
+ /* But otherwise try all possible DS records. */
+ int ret = 0;
+ rd = ref->rrs.rdata;
+ for (int i = 0; i < ref->rrs.count; ++i, rd = knot_rdataset_next(rd)) {
+ const uint8_t algo = knot_ds_digest_type(rd);
+ if (skip_sha1 && algo == DNSSEC_KEY_DIGEST_SHA1)
+ continue;
dnssec_binary_t ds_rdata = {
.size = rd->len,
.data = rd->data
};
- ret = authenticate_ds(key, &ds_rdata, knot_ds_digest_type(rd));
+ ret = authenticate_ds(key, &ds_rdata, algo);
if (ret == 0) /* Found a good DS */
return kr_ok();
- rd = knot_rdataset_next(rd);
}
return kr_error(ret);