package checker import "time" const ObservationKeyDNSSEC = "dnssec" // DenialKind describes the negative-answer scheme observed on a NXDOMAIN probe. type DenialKind string const ( DenialNone DenialKind = "NONE" // zone unsigned or no NSEC/NSEC3 records returned DenialNSEC DenialKind = "NSEC" // walkable DenialNSEC3 DenialKind = "NSEC3" // hashed denial of existence DenialOptOut DenialKind = "OPT-OUT" // NSEC3 with the OPT-OUT flag set ) // DNSSECData carries raw facts only; judgement is delegated to the rules. type DNSSECData struct { Domain string `json:"domain"` NameServers []string `json:"name_servers,omitempty"` Servers map[string]PerServerView `json:"servers,omitempty"` // key: "host:port" Errors []string `json:"errors,omitempty"` // global errors (NS resolution, …) CollectedAt time.Time `json:"collected_at"` // HasDS is whether the parent advertises a DS for this zone (best effort, // resolved through the bootstrap resolver). Used by dnssec_zone_signed. HasDS bool `json:"has_ds,omitempty"` } type PerServerView struct { Server string `json:"server"` UDPError string `json:"udp_error,omitempty"` TCPError string `json:"tcp_error,omitempty"` DNSKEYs []DNSKEYRecord `json:"dnskeys,omitempty"` DNSKEYTTL uint32 `json:"dnskey_ttl,omitempty"` DNSKEYRRSIGs []RRSIGObservation `json:"dnskey_rrsigs,omitempty"` SOA *SOAObservation `json:"soa,omitempty"` SOARRSIGs []RRSIGObservation `json:"soa_rrsigs,omitempty"` NSEC3PARAM *NSEC3ParamObservation `json:"nsec3param,omitempty"` DenialKind DenialKind `json:"denial_kind,omitempty"` DenialRecords []string `json:"denial_records,omitempty"` // textual dump for the report ProbeName string `json:"probe_name,omitempty"` // random NXDOMAIN probe used CDS []DSRecord `json:"cds,omitempty"` CDNSKEY []DNSKEYRecord `json:"cdnskey,omitempty"` } // AllRRSIGs returns DNSKEY and SOA RRSIGs concatenated into a fresh slice, so // callers can iterate every signature observed on this server without mutating // the underlying fields. func (v *PerServerView) AllRRSIGs() []RRSIGObservation { out := make([]RRSIGObservation, 0, len(v.DNSKEYRRSIGs)+len(v.SOARRSIGs)) out = append(out, v.DNSKEYRRSIGs...) out = append(out, v.SOARRSIGs...) return out } type DNSKEYRecord struct { Flags uint16 `json:"flags"` Protocol uint8 `json:"protocol"` Algorithm uint8 `json:"algorithm"` PublicKey string `json:"public_key"` KeyTag uint16 `json:"keytag"` KeySize int `json:"key_size,omitempty"` // computed at collect time IsKSK bool `json:"is_ksk,omitempty"` // derived from the SEP flag } type RRSIGObservation struct { TypeCovered uint16 `json:"type_covered"` Algorithm uint8 `json:"algorithm"` Labels uint8 `json:"labels"` OrigTTL uint32 `json:"orig_ttl"` Inception uint32 `json:"inception"` Expiration uint32 `json:"expiration"` KeyTag uint16 `json:"keytag"` SignerName string `json:"signer_name"` } type SOAObservation struct { Serial uint32 `json:"serial"` Minimum uint32 `json:"minimum"` MName string `json:"mname"` TTL uint32 `json:"ttl"` } type NSEC3ParamObservation struct { HashAlgorithm uint8 `json:"hash_algorithm"` Flags uint8 `json:"flags"` // OPT-OUT bit = 0x01 Iterations uint16 `json:"iterations"` SaltLength uint8 `json:"salt_length"` Salt string `json:"salt,omitempty"` // hex } type DSRecord struct { KeyTag uint16 `json:"keytag"` Algorithm uint8 `json:"algorithm"` DigestType uint8 `json:"digest_type"` Digest string `json:"digest"` }