DNSSEC03 (dnssec03)

Status: Final

Purpose

  • Verify NSEC3 parameter consistency and policy compliance across child nameservers when DNSKEY support is present.

Preconditions And Inputs

  • Preconditions:
    • A zone.Zone object is available.
  • Required inputs:
    • Child nameserver list from methods.Method4and5.
    • DNSKEY and NSEC query responses from child nameservers.
  • 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 execution fanout.

Algorithm And Decision Flow

  1. Emit TEST_CASE_START.
  2. Resolve nameservers 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 DNSKEY and NSEC and skip.
    • Query DNSKEY:
      • If response is absent, non-NOERROR, or non-AA, skip nameserver without DS03 findings.
      • If no apex DNSKEY is present, mark nameserver in Responds Without DNSKEY.
      • Else mark nameserver in Responds With DNSKEY and continue.
    • Query NSEC:
      • No response -> mark No Response NSEC Query.
      • Non-NOERROR or non-AA -> mark Error Response NSEC Query.
      • No NSEC3 in authority -> mark Responds Without NSEC3.
      • Otherwise mark Responds With NSEC3; if multiple NSEC3 RRs exist, also mark Multiple NSEC3.
      • Use the first NSEC3 RR to extract hash algorithm, flags, iterations, and salt-length value.
  4. Emit DNSSEC-support summary tags:
    • DS03_NO_DNSSEC_SUPPORT if no nameserver had DNSKEY but at least one lacked DNSKEY.
    • DS03_SERVER_NO_DNSSEC_SUPPORT if mixed DNSKEY support exists.
  5. Emit NSEC3-availability summary tags:
    • DS03_NO_NSEC3 if no nameserver had NSEC3 but at least one lacked NSEC3.
    • DS03_SERVER_NO_NSEC3 if mixed NSEC3 support exists.
  6. Emit DS03_ERR_MULT_NSEC3 for nameservers that returned more than one NSEC3 RR.
  7. Hash algorithm checks:
    • Emit DS03_INCONSISTENT_HASH_ALGO when more than one hash value appears.
    • Emit DS03_LEGAL_HASH_ALGO for value 1; otherwise emit DS03_ILLEGAL_HASH_ALGO with algo_num.
  8. NSEC3 flags checks:
    • Emit DS03_INCONSISTENT_NSEC3_FLAGS when more than one flags value appears.
    • For each flags value, emit DS03_UNASSIGNED_FLAG_USED for set bits 0..6.
    • Determine opt-out from bit 7:
      • Emit DS03_NSEC3_OPT_OUT_ENABLED_TLD when bit 7 is set and tested zone is root or single-label TLD.
      • Emit DS03_NSEC3_OPT_OUT_ENABLED_NON_TLD when bit 7 is set and zone is not root/single-label TLD.
      • Emit DS03_NSEC3_OPT_OUT_DISABLED when bit 7 is unset.
  9. Iteration checks:
    • Emit DS03_INCONSISTENT_ITERATION when multiple values appear.
    • Emit DS03_LEGAL_ITERATION_VALUE for value 0; otherwise DS03_ILLEGAL_ITERATION_VALUE with int.
  10. Salt-length checks:
    • Emit DS03_INCONSISTENT_SALT_LENGTH when multiple lengths appear.
    • Emit DS03_LEGAL_EMPTY_SALT for length 0; otherwise DS03_ILLEGAL_SALT_LENGTH with int.
  11. Emit per-nameserver NSEC query-error tags:
    • DS03_NO_RESPONSE_NSEC_QUERY for each nameserver that returned no NSEC query response.
    • DS03_ERROR_RESPONSE_NSEC_QUERY for each nameserver that returned a non-NOERROR or non-AA NSEC response.
  12. Emit TEST_CASE_END.

Emitted Tags (Possible Set)

TagEmitted when
DS03_ERROR_RESPONSE_NSEC_QUERYNSEC query response exists but is non-NOERROR or non-AA.
DS03_ERR_MULT_NSEC3Authority section contains more than one NSEC3 record.
DS03_ILLEGAL_HASH_ALGONSEC3 hash algorithm is not 1 (SHA-1).
DS03_ILLEGAL_ITERATION_VALUENSEC3 iterations value is non-zero.
DS03_ILLEGAL_SALT_LENGTHNSEC3 salt length is non-zero.
DS03_INCONSISTENT_HASH_ALGODifferent hash algorithm values are observed across nameservers.
DS03_INCONSISTENT_ITERATIONDifferent iteration values are observed across nameservers.
DS03_INCONSISTENT_NSEC3_FLAGSDifferent NSEC3 flags values are observed across nameservers.
DS03_INCONSISTENT_SALT_LENGTHDifferent NSEC3 salt lengths are observed across nameservers.
DS03_LEGAL_EMPTY_SALTNSEC3 salt length is zero.
DS03_LEGAL_HASH_ALGONSEC3 hash algorithm is 1.
DS03_LEGAL_ITERATION_VALUENSEC3 iterations value is 0.
DS03_NO_DNSSEC_SUPPORTNo queried nameserver returned usable apex DNSKEY data.
DS03_NO_NSEC3No queried nameserver returned NSEC3 after usable DNSKEY support was present.
DS03_NO_RESPONSE_NSEC_QUERYNSEC query had no response message.
DS03_NSEC3_OPT_OUT_DISABLEDNSEC3 flags have opt-out bit unset.
DS03_NSEC3_OPT_OUT_ENABLED_NON_TLDNSEC3 flags have opt-out bit set for a non-root/non-single-label-TLD zone.
DS03_NSEC3_OPT_OUT_ENABLED_TLDNSEC3 flags have opt-out bit set for root or single-label TLD zone.
DS03_SERVER_NO_DNSSEC_SUPPORTMixed DNSKEY support exists across nameservers.
DS03_SERVER_NO_NSEC3Mixed NSEC3 support exists across nameservers.
DS03_UNASSIGNED_FLAG_USEDOne or more unassigned NSEC3 flag bits (0..6) are set.
IPV4_DISABLEDIPv4 transport is disabled for a queried nameserver (DNSKEY/NSEC).
IPV6_DISABLEDIPv6 transport is disabled for a queried nameserver (DNSKEY/NSEC).
TEST_CASE_ENDTestcase completion marker is emitted.
TEST_CASE_STARTTestcase start marker is emitted.

Tag Arguments

TagArgument keyTypeMeaning
DS03_ERROR_RESPONSE_NSEC_QUERYserversarray<object>Structured nameserver identities ({ns,address} object) with erroneous NSEC response.
DS03_ERR_MULT_NSEC3serversarray<object>Structured nameserver identities ({ns,address} object) returning multiple NSEC3 RRs.
DS03_ILLEGAL_HASH_ALGOserversarray<object>Structured nameserver identities ({ns,address} object) using non-1 NSEC3 hash.
DS03_ILLEGAL_HASH_ALGOalgo_numintNSEC3 hash algorithm number.
DS03_ILLEGAL_ITERATION_VALUEserversarray<object>Structured nameserver identities ({ns,address} object) with non-zero NSEC3 iterations.
DS03_ILLEGAL_ITERATION_VALUEintintNSEC3 iteration value.
DS03_ILLEGAL_SALT_LENGTHserversarray<object>Structured nameserver identities ({ns,address} object) with non-zero salt length.
DS03_ILLEGAL_SALT_LENGTHintintNSEC3 salt length value used by implementation.
DS03_INCONSISTENT_HASH_ALGO--No arguments.
DS03_INCONSISTENT_ITERATION--No arguments.
DS03_INCONSISTENT_NSEC3_FLAGS--No arguments.
DS03_INCONSISTENT_SALT_LENGTH--No arguments.
DS03_LEGAL_EMPTY_SALTserversarray<object>Structured nameserver identities ({ns,address} object) with zero salt length.
DS03_LEGAL_HASH_ALGOserversarray<object>Structured nameserver identities ({ns,address} object) using hash algorithm 1.
DS03_LEGAL_ITERATION_VALUEserversarray<object>Structured nameserver identities ({ns,address} object) using iteration 0.
DS03_NO_DNSSEC_SUPPORTserversarray<object>Structured nameserver identities ({ns,address} object) without usable DNSKEY support.
DS03_NO_NSEC3serversarray<object>Structured nameserver identities ({ns,address} object) without NSEC3.
DS03_NO_RESPONSE_NSEC_QUERYserversarray<object>Structured nameserver identities ({ns,address} object) with no NSEC response.
DS03_NSEC3_OPT_OUT_DISABLEDserversarray<object>Structured nameserver identities ({ns,address} object) with opt-out bit unset.
DS03_NSEC3_OPT_OUT_ENABLED_NON_TLDserversarray<object>Structured nameserver identities ({ns,address} object) with opt-out bit set for non-root/non-single-label-TLD zone.
DS03_NSEC3_OPT_OUT_ENABLED_TLDserversarray<object>Structured nameserver identities ({ns,address} object) with opt-out bit set for root/single-label-TLD zone.
DS03_SERVER_NO_DNSSEC_SUPPORTserversarray<object>Structured nameserver identities ({ns,address} object) lacking DNSKEY support while others support it.
DS03_SERVER_NO_NSEC3serversarray<object>Structured nameserver identities ({ns,address} object) lacking NSEC3 while others provide it.
DS03_UNASSIGNED_FLAG_USEDserversarray<object>Structured nameserver identities ({ns,address} object) where the unassigned bit is set.
DS03_UNASSIGNED_FLAG_USEDintintNSEC3 flag bit index (0..6) treated as unassigned.
IPV4_DISABLEDnsstringNameserver identity (ns name only; use address for IP) skipped on IPv4.
IPV4_DISABLEDaddressstringNameserver IP address for the same endpoint.
IPV4_DISABLEDrrtypestringrrtype skipped (DNSKEY or NSEC).
IPV6_DISABLEDnsstringNameserver identity (ns name only; use address for IP) skipped on IPv6.
IPV6_DISABLEDaddressstringNameserver IP address for the same endpoint.
IPV6_DISABLEDrrtypestringrrtype skipped (DNSKEY or NSEC).
TEST_CASE_ENDtestcasestringTestcase display name (DNSSEC03).
TEST_CASE_STARTtestcasestringTestcase display name (DNSSEC03).

Severity Levels Per Tag

TagLevelNotes
DS03_ERROR_RESPONSE_NSEC_QUERYERRORDefault from share/profile.json (test_levels.DNSSEC).
DS03_ERR_MULT_NSEC3ERRORDefault from share/profile.json (test_levels.DNSSEC).
DS03_ILLEGAL_HASH_ALGOERRORDefault from share/profile.json (test_levels.DNSSEC).
DS03_ILLEGAL_ITERATION_VALUEWARNINGDefault from share/profile.json (test_levels.DNSSEC).
DS03_ILLEGAL_SALT_LENGTHWARNINGDefault from share/profile.json (test_levels.DNSSEC).
DS03_INCONSISTENT_HASH_ALGOERRORDefault from share/profile.json (test_levels.DNSSEC).
DS03_INCONSISTENT_ITERATIONERRORDefault from share/profile.json (test_levels.DNSSEC).
DS03_INCONSISTENT_NSEC3_FLAGSERRORDefault from share/profile.json (test_levels.DNSSEC).
DS03_INCONSISTENT_SALT_LENGTHERRORDefault from share/profile.json (test_levels.DNSSEC).
DS03_LEGAL_EMPTY_SALTINFODefault from share/profile.json (test_levels.DNSSEC).
DS03_LEGAL_HASH_ALGOINFODefault from share/profile.json (test_levels.DNSSEC).
DS03_LEGAL_ITERATION_VALUEINFODefault from share/profile.json (test_levels.DNSSEC).
DS03_NO_DNSSEC_SUPPORTNOTICEDefault from share/profile.json (test_levels.DNSSEC).
DS03_NO_NSEC3INFODefault from share/profile.json (test_levels.DNSSEC).
DS03_NO_RESPONSE_NSEC_QUERYERRORDefault from share/profile.json (test_levels.DNSSEC).
DS03_NSEC3_OPT_OUT_DISABLEDINFODefault from share/profile.json (test_levels.DNSSEC).
DS03_NSEC3_OPT_OUT_ENABLED_NON_TLDNOTICEDefault from share/profile.json (test_levels.DNSSEC).
DS03_NSEC3_OPT_OUT_ENABLED_TLDINFODefault from share/profile.json (test_levels.DNSSEC).
DS03_SERVER_NO_DNSSEC_SUPPORTERRORDefault from share/profile.json (test_levels.DNSSEC).
DS03_SERVER_NO_NSEC3ERRORDefault from share/profile.json (test_levels.DNSSEC).
DS03_UNASSIGNED_FLAG_USEDERRORDefault 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: dnssec03.md
  • Differences (Upstream vs Gonemaster):
    • Upstream: allows TLD-like classification based on Public Suffix List data for opt-out interpretation. Gonemaster: treats TLD context as only root (.) or a direct single-label TLD (no PSL-based classification in this testcase).
    • Upstream: does not explicitly specify testcase boundary and per-query transport 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

  • When multiple NSEC3 records are present, only the first NSEC3 RR is used for parameter extraction (hash, flags, iterations, salt length).
  • Nameservers whose DNSKEY response fails shape checks (NOERROR and AA) are silently skipped for DS03 finding sets.
  • Salt length is derived from the NSEC3 Salt string length used by the implementation, not a decoded-octet length conversion step.