DNSSEC01

Status: Final

Purpose

  • Validate DS digest algorithm usage for the child delegation and classify each observed DS digest type.
  • Classify the algorithm field of each observed DS record (the DNSKEY algorithm the DS references), so every value including private-use algorithms is visible and severity-rated.

Preconditions And Inputs

  • Preconditions:
    • A zone.Zone object is available.
  • Required inputs:
    • Parent nameserver names/IPs from ParentNameservers .
    • Optional undelegated DS records exposed via parent nameserver FakeDSRecords.
    • DS query responses for child zone name from parent nameservers.
  • Profile/config knobs that affect behavior:
    • net.ipv4 and net.ipv6: disabled transports are skipped with transport debug tags.
    • resolver.defaults.parallel: parallel parent-query execution fanout.

Algorithm And Decision Flow

  1. Emit TEST_CASE_START.
  2. Initialize classification sets for DS digest classes and DS algorithm field classes, plus tracking sets for:
    • parent nameservers ignored due to invalid response shape,
    • parent nameservers responding without valid DS owner,
    • parent nameservers responding with DS,
    • keytags seen with digest algorithm 2 vs non-2.
  3. Resolve parent nameserver names/IPs.
  4. Check undelegated DS input path:
    • If parent fake DS records are present, classify those DS records immediately with source servers value -.
    • Mark parent-NS query list empty so external parent DS queries are skipped.
  5. For each unique parent nameserver IP (parallelized):
    • If transport is disabled, emit IPV4_DISABLED or IPV6_DISABLED for rrtype DS and skip.
    • Send DS query with DNSSEC enabled.
    • If response is absent or fails required shape checks (NOERROR, OPT, DO, AA), mark nameserver as ignored.
    • If response has no DS record with owner matching child zone name, mark nameserver in Responds Without Valid DS.
    • Else mark nameserver in Responds With DS and classify each DS digest algorithm and each DS algorithm field value into the corresponding DS01 tag sets.
  6. Emit DS classification tags (DS01_DS_ALGO_*) grouped by (digest, keytag) with merged servers, and DS algorithm field classification tags (DS01_KEY_ALGO_*) grouped by (algorithm, keytag) with merged servers. The algorithm-to-class mapping mirrors the DNSKEY algorithm classification of DNSSEC05 (dnssec01TagForKeyAlgorithm reuses the ranges of dnssec05TagForAlgorithm; 253 and 254 map to _PRIVATE).
  7. Emit DS01_DS_ALGO_2_MISSING for keytags that have non-2 DS but no digest-2 DS on the same source nameservers.
  8. If no valid/non-valid DS responders exist and ignored responders exist, emit DS01_NO_RESPONSE.
  9. Emit informational tags based on zone type and undelegated DS status:
    • If zone is root (.), emit DS01_ROOT_N_NO_UNDEL_DS when no undelegated DS records were provided.
    • If zone is undelegated and non-root, emit DS01_UNDEL_N_NO_UNDEL_DS when no undelegated DS records were provided.
  10. If Responds Without Valid DS is non-empty:
    • Emit DS01_PARENT_ZONE_NO_DS when no nameserver responded with DS.
    • Otherwise emit DS01_PARENT_SERVER_NO_DS.
  11. Emit TEST_CASE_END.

Per-Parent-NS DS Query (steps 4-5)

parentNS = ParentNameservers

undelegated DS path (any parent NS has FakeDSRecords for z):
   for each DS record in fake set:
     classify by digest    -> sets[<tag>][digest][keytag] += "-"
     classify by algorithm -> keyAlgoSets[<tag>][algorithm][keytag] += "-"
     digest == 2 -> algo2DS[keytag] += "-"
     else        -> nonAlgo2DS[keytag] += "-"
   respondsWithDS += "-"
   skip live parent queries (parentNS = nil)

Otherwise, per unique parent NS IP (parallel; fan-out = resolver.defaults.parallel):

   transport disabled for DS -> IPV4_DISABLED / IPV6_DISABLED, skip
   query DS at z.Name, DNSSEC=on
    +- resp.Msg == nil / RCODE != NOERROR / no EDNS / !DO / !AA
                                         -> ignoredParentNS += matching ns/ip
    +- no DS with owner == z.Name        -> respondsWithoutValidDS += matching ns/ip
    +- DS present
                                         -> respondsWithDS += matching ns/ip
        for each DS:
          tag = dnssec01TagForDigest(digest)
            ({DEPRECATED, RESERVED, UNASSIGNED, PRIVATE, NOT_DS, OK})
          sets[tag][digest][keytag] += ns/ip
          keyTag = dnssec01TagForKeyAlgorithm(algorithm)
            ({OK, NOT_RECOMMENDED, DEPRECATED, NOT_ZONE_SIGN,
              PRIVATE, RESERVED, UNASSIGNED})
          keyAlgoSets[keyTag][algorithm][keytag] += ns/ip
          digest == 2 -> algo2DS[keytag]    += ns/ip
          else        -> nonAlgo2DS[keytag] += ns/ip

Aggregation and Summary Emission (steps 6-10)

emit per-digest classification tags:
   for each tag in sorted DS01_DS_ALGO_* keys:
     for each digest in sorted digest keys:
       for each keytag in sorted keytag keys:
         -> <tag> (keytag, ds_algo_num, ds_algo_descr, servers)

emit per-algorithm-field classification tags:
   for each tag in sorted DS01_KEY_ALGO_* keys:
     for each algorithm in sorted algorithm keys:
       for each keytag in sorted keytag keys:
         -> <tag> (keytag, ds_key_algo_num, ds_key_algo_descr, servers)

algo-2 coverage:
   for each keytag in nonAlgo2DS:
     missing = nonAlgo2DS[keytag] minus algo2DS[keytag]
     missing non-empty -> DS01_DS_ALGO_2_MISSING (keytag, servers=missing)

no usable responders:
   respondsWithoutValidDS empty AND respondsWithDS empty AND ignoredParentNS non-empty
     -> DS01_NO_RESPONSE (servers = ignoredParentNS)

zone-type info tags:
   z.Name == "." AND no undelegated DS              -> DS01_ROOT_N_NO_UNDEL_DS
   z.Name != "." AND hasFakeAddresses AND no undel DS -> DS01_UNDEL_N_NO_UNDEL_DS

without-valid-DS responders:
   respondsWithoutValidDS non-empty:
     respondsWithDS empty -> DS01_PARENT_ZONE_NO_DS  (servers)
     otherwise            -> DS01_PARENT_SERVER_NO_DS (servers)

emit TEST_CASE_END

Emitted Tags (Possible Set)

TagEmitted when
DS01_DS_ALGO_2_MISSINGA keytag has non-2 DS entries but no digest algorithm 2 DS entry on the same source nameservers.
DS01_DS_ALGO_DEPRECATEDA DS digest algorithm value maps to deprecated class.
DS01_DS_ALGO_NOT_DSA DS digest algorithm value is reserved as “not DS”.
DS01_DS_ALGO_OKA DS digest algorithm value maps to acceptable class.
DS01_DS_ALGO_PRIVATEA DS digest algorithm value maps to private-use class.
DS01_DS_ALGO_RESERVEDA DS digest algorithm value maps to reserved class.
DS01_DS_ALGO_UNASSIGNEDA DS digest algorithm value maps to unassigned class.
DS01_KEY_ALGO_OKA DS algorithm field value maps to acceptable class.
DS01_KEY_ALGO_NOT_RECOMMENDEDA DS algorithm field value maps to not-recommended class.
DS01_KEY_ALGO_DEPRECATEDA DS algorithm field value maps to deprecated class.
DS01_KEY_ALGO_NOT_ZONE_SIGNA DS algorithm field value is not meant for zone signing.
DS01_KEY_ALGO_PRIVATEA DS algorithm field value maps to private-use class (253, 254).
DS01_KEY_ALGO_RESERVEDA DS algorithm field value maps to reserved class.
DS01_KEY_ALGO_UNASSIGNEDA DS algorithm field value maps to unassigned class.
DS01_NO_RESPONSEAll queried parent nameservers were ignored for invalid/no response shape and no DS/non-DS responder set was produced.
DS01_PARENT_SERVER_NO_DSAt least one parent nameserver returned a valid DS and at least one returned no valid DS.
DS01_PARENT_ZONE_NO_DSParent nameservers returned no valid DS and none returned DS.
DS01_ROOT_N_NO_UNDEL_DSTested zone is root and no undelegated DS records were provided.
DS01_UNDEL_N_NO_UNDEL_DSTested zone is undelegated and no undelegated DS records were provided.
IPV4_DISABLEDIPv4 transport is disabled for a queried parent nameserver (DS).
IPV6_DISABLEDIPv6 transport is disabled for a queried parent nameserver (DS).
TEST_CASE_ENDTestcase completion marker is emitted.
TEST_CASE_STARTTestcase start marker is emitted.

Tag Arguments

TagArgument keyTypeMeaning
DS01_DS_ALGO_2_MISSINGserversarray<object>Structured nameserver identities ({ns,address} object) where digest-2 DS is missing, or - for undelegated DS source.
DS01_DS_ALGO_2_MISSINGkeytagintDNSKEY key tag referenced by DS records.
DS01_DS_ALGO_DEPRECATEDserversarray<object>Structured nameserver identities ({ns,address} object), or - for undelegated DS source.
DS01_DS_ALGO_DEPRECATEDkeytagintDNSKEY key tag referenced by DS record.
DS01_DS_ALGO_DEPRECATEDds_algo_numintDS digest algorithm number from DS RDATA.
DS01_DS_ALGO_DEPRECATEDds_algo_descrstringText description of DS digest algorithm number.
DS01_DS_ALGO_NOT_DSserversarray<object>Structured nameserver identities ({ns,address} object), or - for undelegated DS source.
DS01_DS_ALGO_NOT_DSkeytagintDNSKEY key tag referenced by DS record.
DS01_DS_ALGO_NOT_DSds_algo_numintDS digest algorithm number from DS RDATA.
DS01_DS_ALGO_NOT_DSds_algo_descrstringText description of DS digest algorithm number.
DS01_DS_ALGO_OKserversarray<object>Structured nameserver identities ({ns,address} object), or - for undelegated DS source.
DS01_DS_ALGO_OKkeytagintDNSKEY key tag referenced by DS record.
DS01_DS_ALGO_OKds_algo_numintDS digest algorithm number from DS RDATA.
DS01_DS_ALGO_OKds_algo_descrstringText description of DS digest algorithm number.
DS01_DS_ALGO_PRIVATEserversarray<object>Structured nameserver identities ({ns,address} object), or - for undelegated DS source.
DS01_DS_ALGO_PRIVATEkeytagintDNSKEY key tag referenced by DS record.
DS01_DS_ALGO_PRIVATEds_algo_numintDS digest algorithm number from DS RDATA.
DS01_DS_ALGO_PRIVATEds_algo_descrstringText description of DS digest algorithm number.
DS01_DS_ALGO_RESERVEDserversarray<object>Structured nameserver identities ({ns,address} object), or - for undelegated DS source.
DS01_DS_ALGO_RESERVEDkeytagintDNSKEY key tag referenced by DS record.
DS01_DS_ALGO_RESERVEDds_algo_numintDS digest algorithm number from DS RDATA.
DS01_DS_ALGO_RESERVEDds_algo_descrstringText description of DS digest algorithm number.
DS01_DS_ALGO_UNASSIGNEDserversarray<object>Structured nameserver identities ({ns,address} object), or - for undelegated DS source.
DS01_DS_ALGO_UNASSIGNEDkeytagintDNSKEY key tag referenced by DS record.
DS01_DS_ALGO_UNASSIGNEDds_algo_numintDS digest algorithm number from DS RDATA.
DS01_DS_ALGO_UNASSIGNEDds_algo_descrstringText description of DS digest algorithm number.
DS01_KEY_ALGO_OKserversarray<object>Structured nameserver identities ({ns,address} object), or - for undelegated DS source.
DS01_KEY_ALGO_OKkeytagintDNSKEY key tag referenced by DS record.
DS01_KEY_ALGO_OKds_key_algo_numintDS algorithm field value from DS RDATA.
DS01_KEY_ALGO_OKds_key_algo_descrstringText description of DS algorithm field value.
DS01_KEY_ALGO_NOT_RECOMMENDEDserversarray<object>Structured nameserver identities ({ns,address} object), or - for undelegated DS source.
DS01_KEY_ALGO_NOT_RECOMMENDEDkeytagintDNSKEY key tag referenced by DS record.
DS01_KEY_ALGO_NOT_RECOMMENDEDds_key_algo_numintDS algorithm field value from DS RDATA.
DS01_KEY_ALGO_NOT_RECOMMENDEDds_key_algo_descrstringText description of DS algorithm field value.
DS01_KEY_ALGO_DEPRECATEDserversarray<object>Structured nameserver identities ({ns,address} object), or - for undelegated DS source.
DS01_KEY_ALGO_DEPRECATEDkeytagintDNSKEY key tag referenced by DS record.
DS01_KEY_ALGO_DEPRECATEDds_key_algo_numintDS algorithm field value from DS RDATA.
DS01_KEY_ALGO_DEPRECATEDds_key_algo_descrstringText description of DS algorithm field value.
DS01_KEY_ALGO_NOT_ZONE_SIGNserversarray<object>Structured nameserver identities ({ns,address} object), or - for undelegated DS source.
DS01_KEY_ALGO_NOT_ZONE_SIGNkeytagintDNSKEY key tag referenced by DS record.
DS01_KEY_ALGO_NOT_ZONE_SIGNds_key_algo_numintDS algorithm field value from DS RDATA.
DS01_KEY_ALGO_NOT_ZONE_SIGNds_key_algo_descrstringText description of DS algorithm field value.
DS01_KEY_ALGO_PRIVATEserversarray<object>Structured nameserver identities ({ns,address} object), or - for undelegated DS source.
DS01_KEY_ALGO_PRIVATEkeytagintDNSKEY key tag referenced by DS record.
DS01_KEY_ALGO_PRIVATEds_key_algo_numintDS algorithm field value from DS RDATA.
DS01_KEY_ALGO_PRIVATEds_key_algo_descrstringText description of DS algorithm field value.
DS01_KEY_ALGO_RESERVEDserversarray<object>Structured nameserver identities ({ns,address} object), or - for undelegated DS source.
DS01_KEY_ALGO_RESERVEDkeytagintDNSKEY key tag referenced by DS record.
DS01_KEY_ALGO_RESERVEDds_key_algo_numintDS algorithm field value from DS RDATA.
DS01_KEY_ALGO_RESERVEDds_key_algo_descrstringText description of DS algorithm field value.
DS01_KEY_ALGO_UNASSIGNEDserversarray<object>Structured nameserver identities ({ns,address} object), or - for undelegated DS source.
DS01_KEY_ALGO_UNASSIGNEDkeytagintDNSKEY key tag referenced by DS record.
DS01_KEY_ALGO_UNASSIGNEDds_key_algo_numintDS algorithm field value from DS RDATA.
DS01_KEY_ALGO_UNASSIGNEDds_key_algo_descrstringText description of DS algorithm field value.
DS01_NO_RESPONSEserversarray<object>Structured nameserver identities ({ns,address} object) ignored due to invalid/no DS response shape.
DS01_PARENT_SERVER_NO_DSserversarray<object>Structured nameserver identities ({ns,address} object) that returned no valid DS owner.
DS01_PARENT_ZONE_NO_DSserversarray<object>Structured nameserver identities ({ns,address} object) that returned no valid DS owner.
DS01_ROOT_N_NO_UNDEL_DS--No arguments.
DS01_UNDEL_N_NO_UNDEL_DS--No arguments.
IPV4_DISABLEDnsstringNameserver identity (ns name only; use address for IP) skipped on IPv4.
IPV4_DISABLEDaddressstringNameserver IP address for the same endpoint.
IPV4_DISABLEDrrtypestringrrtype skipped (DS).
IPV6_DISABLEDnsstringNameserver identity (ns name only; use address for IP) skipped on IPv6.
IPV6_DISABLEDaddressstringNameserver IP address for the same endpoint.
IPV6_DISABLEDrrtypestringrrtype skipped (DS).
TEST_CASE_ENDtestcasestringTestcase display name (DNSSEC01).
TEST_CASE_STARTtestcasestringTestcase display name (DNSSEC01).

Severity Levels Per Tag

TagLevelNotes
DS01_DS_ALGO_2_MISSINGNOTICEDefault from share/profile.json (test_levels.DNSSEC).
DS01_DS_ALGO_DEPRECATEDERRORDefault from share/profile.json (test_levels.DNSSEC).
DS01_DS_ALGO_NOT_DSERRORDefault from share/profile.json (test_levels.DNSSEC).
DS01_DS_ALGO_OKINFODefault from share/profile.json (test_levels.DNSSEC).
DS01_DS_ALGO_PRIVATEERRORDefault from share/profile.json (test_levels.DNSSEC).
DS01_DS_ALGO_RESERVEDERRORDefault from share/profile.json (test_levels.DNSSEC).
DS01_DS_ALGO_UNASSIGNEDERRORDefault from share/profile.json (test_levels.DNSSEC).
DS01_KEY_ALGO_OKINFODefault from share/profile.json (test_levels.DNSSEC).
DS01_KEY_ALGO_NOT_RECOMMENDEDWARNINGDefault from share/profile.json (test_levels.DNSSEC).
DS01_KEY_ALGO_DEPRECATEDERRORDefault from share/profile.json (test_levels.DNSSEC).
DS01_KEY_ALGO_NOT_ZONE_SIGNERRORDefault from share/profile.json (test_levels.DNSSEC).
DS01_KEY_ALGO_PRIVATEERRORDefault from share/profile.json (test_levels.DNSSEC).
DS01_KEY_ALGO_RESERVEDERRORDefault from share/profile.json (test_levels.DNSSEC).
DS01_KEY_ALGO_UNASSIGNEDERRORDefault from share/profile.json (test_levels.DNSSEC).
DS01_NO_RESPONSEWARNINGDefault from share/profile.json (test_levels.DNSSEC).
DS01_PARENT_SERVER_NO_DSERRORDefault from share/profile.json (test_levels.DNSSEC).
DS01_PARENT_ZONE_NO_DSNOTICEDefault from share/profile.json (test_levels.DNSSEC).
DS01_ROOT_N_NO_UNDEL_DSINFODefault from share/profile.json (test_levels.DNSSEC).
DS01_UNDEL_N_NO_UNDEL_DSINFODefault 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

  • Differences (Upstream vs Gonemaster):
    • 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.
    • Upstream: Summary argument list omits ds_algo_descr for some DS01 tags. Gonemaster: includes ds_algo_descr for all emitted DS01_DS_ALGO_* classification tags.
    • Upstream: does not classify the DS algorithm field. Gonemaster: emits DS01_KEY_ALGO_* classification tags for every observed DS algorithm field value.
  • Potential upstream report:
    • no

Edge Cases And Limitations

  • If no parent nameservers are available and no undelegated DS data exists, only the applicable root/undelegated informational tags and testcase boundary tags are emitted.
  • For undelegated DS input, servers uses the sentinel source value -.
  • DS answer processing requires at least one DS with owner matching child zone, but once accepted the testcase classifies all DS records in that answer section.