new: usr: Add support for EDE 7 and EDE 8

Support was added for EDE codes 7 (Signature Expired) and 8 (Signature Not Yet Valid) which might occur during DNSSEC validation.

See #2715

Merge branch '2715-expired-future-keys' into 'main'

See merge request isc-projects/bind9!10225
This commit is contained in:
Colin Vidal 2025-03-13 10:13:36 +00:00
commit e66dc07c68
3 changed files with 52 additions and 21 deletions

View file

@ -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

View file

@ -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))

View file

@ -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);
}
}