package checker import ( "context" "fmt" "sort" sdk "git.happydns.org/checker-sdk-go/checker" ) const ( hintKey = "hint" codeKey = "code" ) // defaults centralised so Definition's docs and runtime reads cannot drift. const ( defaultNSEC3IterationsMax = 0 // RFC 9276 ยง3.1 defaultNSEC3IterationsSeverityWarn = "warn" defaultSignatureFreshnessDays = 7 defaultSignatureFreshnessCrit = 1 defaultMinRSAKeySize = 2048 defaultRequireSEP = true defaultDNSKEYTTLMinSec = 3600 ) func defaultAllowedAlgorithms() []uint8 { return []uint8{8, 13, 14, 15, 16} } func defaultForbiddenAlgorithms() []uint8 { return []uint8{1, 3, 5, 6, 7, 12} } func loadDNSSEC(ctx context.Context, obs sdk.ObservationGetter) (*DNSSECData, []sdk.CheckState) { var data DNSSECData if err := obs.Get(ctx, ObservationKeyDNSSEC, &data); err != nil { return nil, []sdk.CheckState{{ Status: sdk.StatusError, Message: fmt.Sprintf("failed to read dnssec observation: %v", err), }} } return &data, nil } func skipped(reason string) []sdk.CheckState { return []sdk.CheckState{{ Status: sdk.StatusUnknown, Message: "skipped: " + reason, }} } func okState(subject, message string) []sdk.CheckState { return []sdk.CheckState{{ Status: sdk.StatusOK, Subject: subject, Message: message, }} } func withMeta(s sdk.CheckState, hint, code string) sdk.CheckState { if hint == "" && code == "" { return s } if s.Meta == nil { s.Meta = map[string]any{} } if hint != "" { s.Meta[hintKey] = hint } if code != "" { s.Meta[codeKey] = code s.Code = code } return s } // sortedServers returns the servers map keys in stable order so per-server // rule output is reproducible across runs. func sortedServers(d *DNSSECData) []string { keys := make([]string, 0, len(d.Servers)) for k := range d.Servers { keys = append(keys, k) } sort.Strings(keys) return keys } // hasAnyDNSKEY returns true when at least one server returned at least one // DNSKEY: a coarse "is the zone signed at all" probe. func hasAnyDNSKEY(d *DNSSECData) bool { for _, v := range d.Servers { if len(v.DNSKEYs) > 0 { return true } } return false } func optionUint(opts sdk.CheckerOptions, key string, def uint) uint { return uint(sdk.GetIntOption(opts, key, int(def))) }