checker-dane/checker/rules_pkix.go

61 lines
1.8 KiB
Go

package checker
import (
"context"
sdk "git.happydns.org/checker-sdk-go/checker"
)
// pkixChainValidRule reports whether endpoints that publish PKIX-dependent
// TLSA usages (0 or 1) also present a certificate chain that validates
// against the system trust store. DANE usages 2/3 are unaffected and
// skipped entirely by this rule.
type pkixChainValidRule struct{}
func (r *pkixChainValidRule) Name() string { return "dane.pkix_chain_valid" }
func (r *pkixChainValidRule) Description() string {
return "When TLSA usages 0 or 1 are published, verifies the certificate chain also validates against system trust roots."
}
func (r *pkixChainValidRule) Evaluate(ctx context.Context, obs sdk.ObservationGetter, _ sdk.CheckerOptions) []sdk.CheckState {
rc := loadRuleContext(ctx, obs)
if rc.err != nil {
return []sdk.CheckState{observationErrorState(rc.err)}
}
var out []sdk.CheckState
tested := 0
for _, t := range rc.data.Targets {
probe := rc.probes[t.Ref]
if !probeUsable(probe) {
continue
}
if !hasPKIXUsage(t) {
continue
}
tested++
if probe.ChainValid == nil || !*probe.ChainValid {
out = append(out, sdk.CheckState{
Status: sdk.StatusCrit,
Code: "dane_pkix_chain_invalid",
Subject: targetSubject(t),
Message: "Usage 0/1 requires a publicly-trusted chain, but the certificate chain did not validate against system roots.",
Meta: targetMeta(t),
})
}
}
if len(out) == 0 {
if tested == 0 {
return []sdk.CheckState{{
Status: sdk.StatusUnknown,
Code: "dane_pkix_chain_valid_skipped",
Message: "No endpoint publishes PKIX-dependent TLSA usages (0/1).",
}}
}
return []sdk.CheckState{{
Status: sdk.StatusOK,
Code: "dane_pkix_chain_valid_ok",
Message: "Every endpoint with PKIX-dependent usages presents a publicly-trusted chain.",
}}
}
return out
}