Skip to content

DNSSEC Record Type Parsing (RRSIG, DNSKEY, DS, NSEC) #30

@stephbu

Description

@stephbu

Overview

Implement RData parsers for DNSSEC record types to enable the server to correctly parse and serialize DNSSEC responses. This is Phase 1B of DNSSEC support.

Parent Issue

Prerequisites

  • EDNS(0) support must be in place to request DNSSEC records via DO bit

Background

DNSSEC introduces several new record types that must be parsed correctly:

  • RRSIG (type 46): Signatures over RRsets
  • DNSKEY (type 48): Public keys for a zone
  • DS (type 43): Delegation signer linking parent to child zone
  • NSEC (type 47): Authenticated denial of existence
  • NSEC3 (type 50): Hashed authenticated denial (optional, per RFC 5155)

The record types are already defined in ResourceType.cs; this issue adds the RData parsing logic.

Implementation Tasks

RRSIG Record (RFC 4034 §3)

  • Create RrsigRData class with fields:
    • Type Covered (16 bits)
    • Algorithm (8 bits)
    • Labels (8 bits)
    • Original TTL (32 bits)
    • Signature Expiration (32 bits, Unix timestamp)
    • Signature Inception (32 bits, Unix timestamp)
    • Key Tag (16 bits)
    • Signer's Name (domain name)
    • Signature (variable length, base64 in presentation)
  • Implement Parse() and WriteToStream()
  • Add to ResourceList.LoadFrom() switch

DNSKEY Record (RFC 4034 §2)

  • Create DnskeyRData class with fields:
    • Flags (16 bits) — includes Zone Key (bit 7) and SEP (bit 15)
    • Protocol (8 bits) — must be 3
    • Algorithm (8 bits)
    • Public Key (variable length)
  • Helper properties: IsZoneKey, IsSecureEntryPoint
  • Implement Parse() and WriteToStream()

DS Record (RFC 4034 §5)

  • Create DsRData class with fields:
    • Key Tag (16 bits)
    • Algorithm (8 bits)
    • Digest Type (8 bits) — SHA-1 (1), SHA-256 (2), SHA-384 (4)
    • Digest (variable length)
  • Implement Parse() and WriteToStream()

NSEC Record (RFC 4034 §4)

  • Create NsecRData class with fields:
    • Next Domain Name (domain name)
    • Type Bit Maps (variable, bitmap of record types present)
  • Implement type bitmap parsing/serialization
  • Implement Parse() and WriteToStream()

NSEC3 Record (RFC 5155) — Optional

  • Create Nsec3RData class with fields:
    • Hash Algorithm (8 bits)
    • Flags (8 bits)
    • Iterations (16 bits)
    • Salt Length + Salt
    • Hash Length + Next Hashed Owner Name
    • Type Bit Maps
  • Implement Parse() and WriteToStream()

Algorithm Constants

  • Create DnssecAlgorithm enum:
    public enum DnssecAlgorithm : byte
    {
        RSAMD5 = 1,           // Deprecated
        DSA = 3,              // Deprecated  
        RSASHA1 = 5,
        RSASHA256 = 8,
        RSASHA512 = 10,
        ECDSAP256SHA256 = 13,
        ECDSAP384SHA384 = 14,
        ED25519 = 15,
        ED448 = 16
    }

Digest Type Constants

  • Create DigestType enum for DS records

Testing

  • Unit tests parsing real DNSSEC responses (capture from dig +dnssec)
  • Round-trip tests: parse → serialize → parse yields identical data
  • Test each record type with multiple algorithm variants
  • Test NSEC type bitmap with various record type combinations
  • Fuzz testing with malformed DNSSEC records

Test Data Sources

# Capture real DNSSEC records for test fixtures
dig +dnssec example.com DNSKEY
dig +dnssec example.com A
dig +dnssec nonexistent.example.com A  # For NSEC

Technical References

Acceptance Criteria

  • All DNSSEC record types parse without errors
  • Serialization produces wire-format compliant output
  • Algorithm and digest type enums defined
  • Unit tests cover all record types
  • Existing non-DNSSEC functionality unaffected

Related Issues

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions