DNSSEC16 (dnssec16)
Status: Final
Purpose
- Validate CDS RRsets against DNSKEY data and CDS signatures, including delete semantics and signature/keytag consistency checks.
Preconditions And Inputs
- Preconditions:
- A
zone.Zoneobject is available.
- A
- Required inputs:
- Child nameserver sets from
methods.Method4andmethods.Method5. - CDS and DNSKEY responses with DNSSEC enabled.
- CDS and DNSKEY answer-section RRSIG records.
- Child nameserver sets from
- Profile/config knobs that affect behavior:
net.ipv4andnet.ipv6: disabled transports are skipped with transport debug tags.resolver.defaults.parallel: parallel nameserver query and validation fanout.
Algorithm And Decision Flow
- Emit
TEST_CASE_START. - Build child nameserver set from Method4+Method5 and deduplicate by IP.
- For each unique nameserver IP (parallelized):
- If transport is disabled, emit
IPV4_DISABLEDorIPV6_DISABLEDfor rrtypesCDSandDNSKEYand skip. - Query
CDSwith DNSSEC enabled; require authoritativeNOERRORand at least one CDS record to continue. - Collect CDS records and answer-section RRSIG records.
- Query
DNSKEYwith DNSSEC enabled; collect DNSKEY and answer-section RRSIG records when authoritativeNOERRORwith DNSKEY answers.
- If transport is disabled, emit
- If no nameserver produced CDS records, emit no DS16 findings.
- For each nameserver with CDS records (parallelized validation):
- Detect delete semantics:
- Mixed delete/non-delete CDS =>
DS16_MIXED_DELETE_CDS. - Only delete CDS =>
DS16_DELETE_CDS. - In both delete cases, remaining CDS validations are skipped for that nameserver.
- Mixed delete/non-delete CDS =>
- If no DNSKEY RRset for nameserver =>
DS16_CDS_WITHOUT_DNSKEY. - For each non-delete CDS:
- If no matching DNSKEY keytag =>
DS16_CDS_MATCHES_NO_DNSKEY. - Else if any matching DNSKEY has zone bit unset =>
DS16_CDS_MATCHES_NON_ZONE_DNSKEY. - Else:
- If DNSKEY RRSIG set lacks CDS keytag =>
DS16_DNSKEY_NOT_SIGNED_BY_CDS. - If CDS RRSIG set lacks CDS keytag =>
DS16_CDS_NOT_SIGNED_BY_CDS. - If any matching DNSKEY has SEP bit unset =>
DS16_CDS_MATCHES_NON_SEP_DNSKEY.
- If DNSKEY RRSIG set lacks CDS keytag =>
- If no matching DNSKEY keytag =>
- If CDS RRset has no RRSIG records =>
DS16_CDS_UNSIGNED. - Else for each CDS RRSIG:
- If keytag has no matching DNSKEY =>
DS16_CDS_SIGNED_BY_UNKNOWN_DNSKEY. - Else if cryptographic verification fails for all matching DNSKEY records =>
DS16_CDS_INVALID_RRSIG.
- If keytag has no matching DNSKEY =>
- Detect delete semantics:
- Emit accumulated DS16 findings grouped by keytag or nameserver list as applicable.
- Emit
TEST_CASE_END.
Emitted Tags (Possible Set)
| Tag | Emitted when |
|---|---|
DS16_CDS_INVALID_RRSIG | CDS RRSIG keytag matches DNSKEY keytag(s), but signature verification fails. |
DS16_CDS_MATCHES_NON_SEP_DNSKEY | CDS points to a DNSKEY with SEP bit unset. |
DS16_CDS_MATCHES_NON_ZONE_DNSKEY | CDS points to a DNSKEY with zone bit unset. |
DS16_CDS_MATCHES_NO_DNSKEY | CDS keytag matches no DNSKEY keytag. |
DS16_CDS_NOT_SIGNED_BY_CDS | CDS RRset has no RRSIG with CDS keytag. |
DS16_CDS_SIGNED_BY_UNKNOWN_DNSKEY | CDS RRset has RRSIG keytag not present in DNSKEY RRset. |
DS16_CDS_UNSIGNED | CDS RRset has no RRSIG records. |
DS16_CDS_WITHOUT_DNSKEY | CDS RRset exists but DNSKEY RRset is missing. |
DS16_DELETE_CDS | Nameserver CDS RRset consists only of delete CDS record(s). |
DS16_DNSKEY_NOT_SIGNED_BY_CDS | DNSKEY RRset has no RRSIG with CDS keytag. |
DS16_MIXED_DELETE_CDS | Delete CDS record is mixed with non-delete CDS record(s). |
IPV4_DISABLED | IPv4 transport is disabled for a queried nameserver (CDS, DNSKEY). |
IPV6_DISABLED | IPv6 transport is disabled for a queried nameserver (CDS, DNSKEY). |
TEST_CASE_END | Testcase completion marker is emitted. |
TEST_CASE_START | Testcase start marker is emitted. |
Tag Arguments
| Tag | Argument key | Type | Meaning |
|---|---|---|---|
DS16_CDS_INVALID_RRSIG | keytag | int | RRSIG keytag with invalid signature. |
DS16_CDS_INVALID_RRSIG | addresses | array<string> | Structured child nameserver IP list. |
DS16_CDS_MATCHES_NON_SEP_DNSKEY | keytag | int | CDS keytag referencing non-SEP DNSKEY. |
DS16_CDS_MATCHES_NON_SEP_DNSKEY | addresses | array<string> | Structured child nameserver IP list. |
DS16_CDS_MATCHES_NON_ZONE_DNSKEY | keytag | int | CDS keytag referencing non-zone DNSKEY. |
DS16_CDS_MATCHES_NON_ZONE_DNSKEY | addresses | array<string> | Structured child nameserver IP list. |
DS16_CDS_MATCHES_NO_DNSKEY | keytag | int | CDS keytag not found in DNSKEY RRset. |
DS16_CDS_MATCHES_NO_DNSKEY | addresses | array<string> | Structured child nameserver IP list. |
DS16_CDS_NOT_SIGNED_BY_CDS | keytag | int | CDS keytag missing from CDS RRset RRSIG keytags. |
DS16_CDS_NOT_SIGNED_BY_CDS | addresses | array<string> | Structured child nameserver IP list. |
DS16_CDS_SIGNED_BY_UNKNOWN_DNSKEY | keytag | int | CDS RRSIG keytag with no DNSKEY match. |
DS16_CDS_SIGNED_BY_UNKNOWN_DNSKEY | addresses | array<string> | Structured child nameserver IP list. |
DS16_CDS_UNSIGNED | addresses | array<string> | Structured child nameserver IP list. |
DS16_CDS_WITHOUT_DNSKEY | addresses | array<string> | Structured child nameserver IP list. |
DS16_DELETE_CDS | addresses | array<string> | Structured child nameserver IP list. |
DS16_DNSKEY_NOT_SIGNED_BY_CDS | keytag | int | CDS keytag missing from DNSKEY RRset RRSIG keytags. |
DS16_DNSKEY_NOT_SIGNED_BY_CDS | addresses | array<string> | Structured child nameserver IP list. |
DS16_MIXED_DELETE_CDS | addresses | array<string> | Structured child nameserver IP list. |
IPV4_DISABLED | ns | string | Nameserver identity (ns name only; use address for IP) skipped on IPv4. |
IPV4_DISABLED | address | string | Nameserver IP address for the same endpoint. |
IPV4_DISABLED | rrtype | string | rrtype skipped (CDS or DNSKEY). |
IPV6_DISABLED | ns | string | Nameserver identity (ns name only; use address for IP) skipped on IPv6. |
IPV6_DISABLED | address | string | Nameserver IP address for the same endpoint. |
IPV6_DISABLED | rrtype | string | rrtype skipped (CDS or DNSKEY). |
TEST_CASE_END | testcase | string | Testcase display name (DNSSEC16). |
TEST_CASE_START | testcase | string | Testcase display name (DNSSEC16). |
Severity Levels Per Tag
| Tag | Level | Notes |
|---|---|---|
DS16_CDS_INVALID_RRSIG | ERROR | Default from share/profile.json (test_levels.DNSSEC). |
DS16_CDS_MATCHES_NON_SEP_DNSKEY | NOTICE | Default from share/profile.json (test_levels.DNSSEC). |
DS16_CDS_MATCHES_NON_ZONE_DNSKEY | ERROR | Default from share/profile.json (test_levels.DNSSEC). |
DS16_CDS_MATCHES_NO_DNSKEY | WARNING | Default from share/profile.json (test_levels.DNSSEC). |
DS16_CDS_NOT_SIGNED_BY_CDS | NOTICE | Default from share/profile.json (test_levels.DNSSEC). |
DS16_CDS_SIGNED_BY_UNKNOWN_DNSKEY | ERROR | Default from share/profile.json (test_levels.DNSSEC). |
DS16_CDS_UNSIGNED | ERROR | Default from share/profile.json (test_levels.DNSSEC). |
DS16_CDS_WITHOUT_DNSKEY | ERROR | Default from share/profile.json (test_levels.DNSSEC). |
DS16_DELETE_CDS | INFO | Default from share/profile.json (test_levels.DNSSEC). |
DS16_DNSKEY_NOT_SIGNED_BY_CDS | WARNING | Default from share/profile.json (test_levels.DNSSEC). |
DS16_MIXED_DELETE_CDS | ERROR | Default from share/profile.json (test_levels.DNSSEC). |
IPV4_DISABLED | DEBUG | Default from share/profile.json (test_levels.DNSSEC). |
IPV6_DISABLED | DEBUG | Default from share/profile.json (test_levels.DNSSEC). |
TEST_CASE_END | DEBUG | Default from share/profile.json (test_levels.DNSSEC). |
TEST_CASE_START | DEBUG | Default from share/profile.json (test_levels.DNSSEC). |
Differences From Upstream
- Upstream reference:
dnssec16.md - Differences (Upstream vs Gonemaster):
- Upstream: describes this testcase as producing no output when no CDS is found. Gonemaster: emits only
TEST_CASE_START,TEST_CASE_END, and, if any transport is disabled,IPV4_DISABLEDand/orIPV6_DISABLEDin that case. - Upstream: signature checks are described at RRset/signature level. Gonemaster: the checks for
DS16_DNSKEY_NOT_SIGNED_BY_CDSandDS16_CDS_NOT_SIGNED_BY_CDSare implemented as keytag-presence checks in RRSIG sets, not full per-signature validation. - Upstream: does not explicitly specify testcase boundary and transport-disabled debug emissions in this testcase summary. Gonemaster: emits
TEST_CASE_START,TEST_CASE_END,IPV4_DISABLED, andIPV6_DISABLED.
- Upstream: describes this testcase as producing no output when no CDS is found. Gonemaster: emits only
- Potential upstream report:
no
Edge Cases And Limitations
- Delete semantics short-circuit further CDS validation for that nameserver.
DS16_CDS_MATCHES_NON_ZONE_DNSKEYis emitted if any matching-keytag DNSKEY has zone bit unset.- Nameserver evaluation is deduplicated by IP.