From 334ea1269fc04b764be8e8ebf33d8c9c0036026c Mon Sep 17 00:00:00 2001 From: Colin Vidal Date: Wed, 12 Mar 2025 10:53:11 +0100 Subject: [PATCH 1/2] add support for EDE 7 and 8 Extended DNS Error messages EDE 7 (expired key) and EDE 8 (validity period of the key not yet started) are now sent in case of such DNSSEC validation failures. Refactor the existing validator extended error APIs in order to make it easy to have a consisdent extra info (with domain/type) in the various use case (i.e. when the EDE depends on validator state, validate_extendederror or when the EDE doesn't depend of any state but can be called directly in a specific flow). --- lib/dns/validator.c | 58 +++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/lib/dns/validator.c b/lib/dns/validator.c index 806d20da8e..a9ea045463 100644 --- a/lib/dns/validator.c +++ b/lib/dns/validator.c @@ -182,6 +182,9 @@ expire_rdatasets(dns_validator_t *val) { static void validate_extendederror(dns_validator_t *val); +static void +validator_addede(dns_validator_t *val, uint16_t code, const char *extra); + /*% * Ensure the validator's rdatasets are disassociated. */ @@ -1474,6 +1477,11 @@ again: * Temporal errors don't count towards max validations nor max * fails. */ + validator_addede(val, + result == DNS_R_SIGEXPIRED + ? DNS_EDE_SIGNATUREEXPIRED + : DNS_EDE_SIGNATURENOTYETVALID, + NULL); break; case ISC_R_SUCCESS: consume_validation(val); @@ -3627,44 +3635,54 @@ validator_logcreate(dns_validator_t *val, dns_name_t *name, } static void -validate_extendederror(dns_validator_t *val) { +validator_addede(dns_validator_t *val, uint16_t code, const char *extra) { REQUIRE(VALID_VALIDATOR(val)); - char extra[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + + char bdata[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + DNS_EDE_EXTRATEXT_LEN]; isc_buffer_t b; + + isc_buffer_init(&b, bdata, sizeof(bdata)); + + if (extra != NULL) { + isc_buffer_putstr(&b, extra); + isc_buffer_putuint8(&b, ' '); + } + + dns_name_totext(val->name, DNS_NAME_OMITFINALDOT, &b); + isc_buffer_putuint8(&b, '/'); + dns_rdatatype_totext(val->type, &b); + isc_buffer_putuint8(&b, '\0'); + + dns_ede_add(val->edectx, code, bdata); +} + +static void +validate_extendederror(dns_validator_t *val) { dns_validator_t *edeval = val; + char bdata[DNS_EDE_EXTRATEXT_LEN]; + isc_buffer_t b; + + REQUIRE(VALID_VALIDATOR(edeval)); + + isc_buffer_init(&b, bdata, sizeof(bdata)); while (edeval->parent != NULL) { edeval = edeval->parent; } if (val->unsupported_algorithm != 0) { - isc_buffer_init(&b, extra, sizeof(extra)); + isc_buffer_clear(&b); dns_secalg_totext(val->unsupported_algorithm, &b); - - isc_buffer_putuint8(&b, ' '); - dns_name_totext(val->name, DNS_NAME_OMITFINALDOT, &b); - isc_buffer_putuint8(&b, '/'); - dns_rdatatype_totext(val->type, &b); isc_buffer_putuint8(&b, '\0'); - - dns_ede_add(val->edectx, DNS_EDE_DNSKEYALG, extra); + validator_addede(val, DNS_EDE_DNSKEYALG, bdata); } if (val->unsupported_digest != 0) { - isc_buffer_init(&b, extra, sizeof(extra)); - + isc_buffer_clear(&b); dns_dsdigest_totext(val->unsupported_digest, &b); - isc_buffer_putuint8(&b, ' '); - dns_name_totext(val->name, DNS_NAME_OMITFINALDOT, &b); - isc_buffer_putuint8(&b, '/'); - dns_rdatatype_totext(val->type, &b); isc_buffer_putuint8(&b, '\0'); - - dns_ede_add(val->edectx, DNS_EDE_DSDIGESTTYPE, extra); - - isc_buffer_invalidate(&b); + validator_addede(val, DNS_EDE_DSDIGESTTYPE, bdata); } } From e763d6637f54fcd079f4ab17120c0c53aa4adecc Mon Sep 17 00:00:00 2001 From: Colin Vidal Date: Wed, 12 Mar 2025 10:53:33 +0100 Subject: [PATCH 2/2] add system tests covering EDE 7 and 8 Add DNSSEC system tests to cover extended DNS error 7 (Signature Expired) and 8 (Signature Not Yet Valid). --- bin/tests/system/dnssec/ns2/sign.sh | 2 +- bin/tests/system/dnssec/tests.sh | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/bin/tests/system/dnssec/ns2/sign.sh b/bin/tests/system/dnssec/ns2/sign.sh index 6d10c7f8a5..917da71e4b 100644 --- a/bin/tests/system/dnssec/ns2/sign.sh +++ b/bin/tests/system/dnssec/ns2/sign.sh @@ -64,7 +64,7 @@ for subdomain in digest-alg-unsupported ds-unsupported secure badds \ kskonly update-nsec3 auto-nsec auto-nsec3 secure.below-cname \ ttlpatch split-dnssec split-smart expired expiring upper lower \ dnskey-unknown dnskey-unsupported dnskey-unsupported-2 \ - dnskey-nsec3-unknown managed-future revkey \ + dnskey-nsec3-unknown managed-future future revkey \ dname-at-apex-nsec3 occluded rsasha1 rsasha1-1024; do cp "../ns3/dsset-$subdomain.example." . done diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index 953a310d46..d3ee1bc8b4 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -2859,6 +2859,19 @@ dig_with_opts +noauth expired.example. +dnssec @10.53.0.4 soa >dig.out.ns4.test$ grep "SERVFAIL" dig.out.ns4.test$n >/dev/null || ret=1 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n >/dev/null && ret=1 grep "expired.example/.*: RRSIG has expired" ns4/named.run >/dev/null || ret=1 +grep "; EDE: 7 (Signature Expired): (expired.example/DNSKEY)" dig.out.ns4.test$n >/dev/null || ret=1 +n=$((n + 1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status + ret)) + +status=$((status + ret)) +echo_i "checking signatures in the future do not validate ($n)" +ret=0 +dig_with_opts +noauth future.example. +dnssec @10.53.0.4 soa >dig.out.ns4.test$n || ret=1 +grep "SERVFAIL" dig.out.ns4.test$n >/dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns4.test$n >/dev/null && ret=1 +grep "future.example/.*: RRSIG validity period has not begun" ns4/named.run >/dev/null || ret=1 +grep "; EDE: 8 (Signature Not Yet Valid): (future.example/DNSKEY)" dig.out.ns4.test$n >/dev/null || ret=1 n=$((n + 1)) test "$ret" -eq 0 || echo_i "failed" status=$((status + ret))