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.Zone object is available.
  • Required inputs:
    • Child nameserver sets from methods.Method4 and methods.Method5.
    • CDS and DNSKEY responses with DNSSEC enabled.
    • CDS and DNSKEY answer-section RRSIG records.
  • Profile/config knobs that affect behavior:
    • net.ipv4 and net.ipv6: disabled transports are skipped with transport debug tags.
    • resolver.defaults.parallel: parallel nameserver query and validation fanout.

Algorithm And Decision Flow

  1. Emit TEST_CASE_START.
  2. Build child nameserver set from Method4+Method5 and deduplicate by IP.
  3. For each unique nameserver IP (parallelized):
    • If transport is disabled, emit IPV4_DISABLED or IPV6_DISABLED for rrtypes CDS and DNSKEY and skip.
    • Query CDS with DNSSEC enabled; require authoritative NOERROR and at least one CDS record to continue.
    • Collect CDS records and answer-section RRSIG records.
    • Query DNSKEY with DNSSEC enabled; collect DNSKEY and answer-section RRSIG records when authoritative NOERROR with DNSKEY answers.
  4. If no nameserver produced CDS records, emit no DS16 findings.
  5. 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.
    • 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 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.
  6. Emit accumulated DS16 findings grouped by keytag or nameserver list as applicable.
  7. Emit TEST_CASE_END.

Emitted Tags (Possible Set)

TagEmitted when
DS16_CDS_INVALID_RRSIGCDS RRSIG keytag matches DNSKEY keytag(s), but signature verification fails.
DS16_CDS_MATCHES_NON_SEP_DNSKEYCDS points to a DNSKEY with SEP bit unset.
DS16_CDS_MATCHES_NON_ZONE_DNSKEYCDS points to a DNSKEY with zone bit unset.
DS16_CDS_MATCHES_NO_DNSKEYCDS keytag matches no DNSKEY keytag.
DS16_CDS_NOT_SIGNED_BY_CDSCDS RRset has no RRSIG with CDS keytag.
DS16_CDS_SIGNED_BY_UNKNOWN_DNSKEYCDS RRset has RRSIG keytag not present in DNSKEY RRset.
DS16_CDS_UNSIGNEDCDS RRset has no RRSIG records.
DS16_CDS_WITHOUT_DNSKEYCDS RRset exists but DNSKEY RRset is missing.
DS16_DELETE_CDSNameserver CDS RRset consists only of delete CDS record(s).
DS16_DNSKEY_NOT_SIGNED_BY_CDSDNSKEY RRset has no RRSIG with CDS keytag.
DS16_MIXED_DELETE_CDSDelete CDS record is mixed with non-delete CDS record(s).
IPV4_DISABLEDIPv4 transport is disabled for a queried nameserver (CDS, DNSKEY).
IPV6_DISABLEDIPv6 transport is disabled for a queried nameserver (CDS, DNSKEY).
TEST_CASE_ENDTestcase completion marker is emitted.
TEST_CASE_STARTTestcase start marker is emitted.

Tag Arguments

TagArgument keyTypeMeaning
DS16_CDS_INVALID_RRSIGkeytagintRRSIG keytag with invalid signature.
DS16_CDS_INVALID_RRSIGaddressesarray<string>Structured child nameserver IP list.
DS16_CDS_MATCHES_NON_SEP_DNSKEYkeytagintCDS keytag referencing non-SEP DNSKEY.
DS16_CDS_MATCHES_NON_SEP_DNSKEYaddressesarray<string>Structured child nameserver IP list.
DS16_CDS_MATCHES_NON_ZONE_DNSKEYkeytagintCDS keytag referencing non-zone DNSKEY.
DS16_CDS_MATCHES_NON_ZONE_DNSKEYaddressesarray<string>Structured child nameserver IP list.
DS16_CDS_MATCHES_NO_DNSKEYkeytagintCDS keytag not found in DNSKEY RRset.
DS16_CDS_MATCHES_NO_DNSKEYaddressesarray<string>Structured child nameserver IP list.
DS16_CDS_NOT_SIGNED_BY_CDSkeytagintCDS keytag missing from CDS RRset RRSIG keytags.
DS16_CDS_NOT_SIGNED_BY_CDSaddressesarray<string>Structured child nameserver IP list.
DS16_CDS_SIGNED_BY_UNKNOWN_DNSKEYkeytagintCDS RRSIG keytag with no DNSKEY match.
DS16_CDS_SIGNED_BY_UNKNOWN_DNSKEYaddressesarray<string>Structured child nameserver IP list.
DS16_CDS_UNSIGNEDaddressesarray<string>Structured child nameserver IP list.
DS16_CDS_WITHOUT_DNSKEYaddressesarray<string>Structured child nameserver IP list.
DS16_DELETE_CDSaddressesarray<string>Structured child nameserver IP list.
DS16_DNSKEY_NOT_SIGNED_BY_CDSkeytagintCDS keytag missing from DNSKEY RRset RRSIG keytags.
DS16_DNSKEY_NOT_SIGNED_BY_CDSaddressesarray<string>Structured child nameserver IP list.
DS16_MIXED_DELETE_CDSaddressesarray<string>Structured child nameserver IP list.
IPV4_DISABLEDnsstringNameserver identity (ns name only; use address for IP) skipped on IPv4.
IPV4_DISABLEDaddressstringNameserver IP address for the same endpoint.
IPV4_DISABLEDrrtypestringrrtype skipped (CDS or DNSKEY).
IPV6_DISABLEDnsstringNameserver identity (ns name only; use address for IP) skipped on IPv6.
IPV6_DISABLEDaddressstringNameserver IP address for the same endpoint.
IPV6_DISABLEDrrtypestringrrtype skipped (CDS or DNSKEY).
TEST_CASE_ENDtestcasestringTestcase display name (DNSSEC16).
TEST_CASE_STARTtestcasestringTestcase display name (DNSSEC16).

Severity Levels Per Tag

TagLevelNotes
DS16_CDS_INVALID_RRSIGERRORDefault from share/profile.json (test_levels.DNSSEC).
DS16_CDS_MATCHES_NON_SEP_DNSKEYNOTICEDefault from share/profile.json (test_levels.DNSSEC).
DS16_CDS_MATCHES_NON_ZONE_DNSKEYERRORDefault from share/profile.json (test_levels.DNSSEC).
DS16_CDS_MATCHES_NO_DNSKEYWARNINGDefault from share/profile.json (test_levels.DNSSEC).
DS16_CDS_NOT_SIGNED_BY_CDSNOTICEDefault from share/profile.json (test_levels.DNSSEC).
DS16_CDS_SIGNED_BY_UNKNOWN_DNSKEYERRORDefault from share/profile.json (test_levels.DNSSEC).
DS16_CDS_UNSIGNEDERRORDefault from share/profile.json (test_levels.DNSSEC).
DS16_CDS_WITHOUT_DNSKEYERRORDefault from share/profile.json (test_levels.DNSSEC).
DS16_DELETE_CDSINFODefault from share/profile.json (test_levels.DNSSEC).
DS16_DNSKEY_NOT_SIGNED_BY_CDSWARNINGDefault from share/profile.json (test_levels.DNSSEC).
DS16_MIXED_DELETE_CDSERRORDefault from share/profile.json (test_levels.DNSSEC).
IPV4_DISABLEDDEBUGDefault from share/profile.json (test_levels.DNSSEC).
IPV6_DISABLEDDEBUGDefault from share/profile.json (test_levels.DNSSEC).
TEST_CASE_ENDDEBUGDefault from share/profile.json (test_levels.DNSSEC).
TEST_CASE_STARTDEBUGDefault 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_DISABLED and/or IPV6_DISABLED in that case.
    • Upstream: signature checks are described at RRset/signature level. Gonemaster: the checks for DS16_DNSKEY_NOT_SIGNED_BY_CDS and DS16_CDS_NOT_SIGNED_BY_CDS are 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, and IPV6_DISABLED.
  • Potential upstream report:
    • no

Edge Cases And Limitations

  • Delete semantics short-circuit further CDS validation for that nameserver.
  • DS16_CDS_MATCHES_NON_ZONE_DNSKEY is emitted if any matching-keytag DNSKEY has zone bit unset.
  • Nameserver evaluation is deduplicated by IP.