Leaf X.509 certificate fetching and CA/Browser Forum validation-level classification from policy OIDs. Source: internal/cert/cert.go.
Reserved policy OIDs: 2.23.140.1.1 (EV), 2.23.140.1.2.1 (DV), 2.23.140.1.2.2 (OV), 2.23.140.1.2.3 (IV). Priority order is EV > OV > IV > DV.
type Details struct {
Issuer string // Organization, or fallback issuer string
Class string // EV, OV, IV, DV, or Unknown
SANs []string // DNS SANs (CN fallback), empty when unavailable
OIDs []string // raw policy OIDs found
Subject string
IssuerStr string
Fingerprint string // SHA-256 of the raw leaf, hex-encoded
NotBefore time.Time
NotAfter time.Time
HasCert bool
} |
Extracted leaf-certificate fields. Issuer prefers the Organization attribute and falls back to Common Name, then the full issuer string. SANs falls back to the subject Common Name.
func Classify(oids []string) string |
Maps a set of policy OID strings to a validation class using the ordered priority table (EV first). Returns "Unknown" when none match.
cert.Classify([]string{"2.23.140.1.2.1"}) // => "DV" |
func InspectDomain(ctx context.Context, domain string, perCall time.Duration) (*Details, error) |
Dials domain:443 with tls.Dialer (InsecureSkipVerify, since the peer is untrusted by definition) and returns the parsed leaf via FromLeaf. Transient failures are retried up to 3 times with a 1 second delay.
| Parameter | Description |
|---|---|
| ctx | Parent context; the global 15 second budget. |
| domain | Already-normalized domain to dial. |
| perCall | Per-attempt deadline (5 seconds in the CLI). |
func InspectAddr(ctx context.Context, ip net.IP, domain string, perCall time.Duration) (*Details, error) |
Dials ip:443 directly (bypassing the system resolver) while presenting domain as SNI, capturing the TLS identity served at one resolution-path endpoint. The CLI fetches one Details per path (system-resolved IP vs public-resolved IP) so ComparePaths can diff them. Same 3-attempt retry posture as InspectDomain.
func ComparePaths(sys, pub *Details) (match, complete bool, detail string) |
Pure comparison of the TLS identities served at the system-resolved and public-resolved endpoints: issuer organization, validation class, SAN set (order/case-insensitive), and leaf SHA-256 fingerprint. Reports whether both endpoints were interrogated (complete), whether the identities agree (match), and a human-readable mismatch description. Missing certificates fail open — incomplete, never a mismatch. Safe to unit test.
func FromLeaf(leaf *x509.Certificate) *Details |
Pure constructor: builds Details from an already-parsed leaf certificate. Preferred entry point for tests.
func (d *Details) SANsString() string |
Joins SANs with ", " for display, or returns "Unknown" when empty. Nil-receiver safe.