Documentation
¶
Overview ¶
Package verify provides ANS trust verification functionality.
Index ¶
- Variables
- func DefaultTrustedRADomains() []string
- type AnsBadgeRecord
- type AnsName
- type AnsVerifier
- func (v *AnsVerifier) Prefetch(ctx context.Context, fqdnStr string) (*models.Badge, error)
- func (v *AnsVerifier) VerifyClient(ctx context.Context, cert *CertIdentity) *VerificationOutcome
- func (v *AnsVerifier) VerifyClientWithScitt(ctx context.Context, cert *CertIdentity, headers *scitt.Headers) *VerificationOutcome
- func (v *AnsVerifier) VerifyServer(ctx context.Context, fqdnStr string, cert *CertIdentity) *VerificationOutcome
- func (v *AnsVerifier) VerifyServerWithScitt(ctx context.Context, fqdnStr string, cert *CertIdentity, ...) *VerificationOutcome
- type BadgeCache
- func (c *BadgeCache) Clear()
- func (c *BadgeCache) GetByFqdn(fqdn models.Fqdn) (*CachedBadge, bool)
- func (c *BadgeCache) GetByFqdnVersion(fqdn models.Fqdn, version models.Version) (*CachedBadge, bool)
- func (c *BadgeCache) GetStaleByFqdn(fqdn models.Fqdn, maxStaleness time.Duration) (*CachedBadge, bool)
- func (c *BadgeCache) GetStaleByFqdnVersion(fqdn models.Fqdn, version models.Version, maxStaleness time.Duration) (*CachedBadge, bool)
- func (c *BadgeCache) Insert(fqdn models.Fqdn, badge *models.Badge)
- func (c *BadgeCache) InsertForVersion(fqdn models.Fqdn, version models.Version, badge *models.Badge)
- func (c *BadgeCache) StartBackgroundRefresh(ctx context.Context, interval time.Duration, refreshFn RefreshFunc)
- type BadgeRecordSource
- type CacheConfig
- type CachedBadge
- type CertFingerprint
- type CertIdentity
- func CertIdentityFromDER(der []byte) (*CertIdentity, error)
- func CertIdentityFromFingerprintAndCN(fingerprint CertFingerprint, cn string) *CertIdentity
- func CertIdentityFromX509(cert *x509.Certificate) *CertIdentity
- func NewCertIdentity(commonName *string, dnsSANs, uriSANs []string, fingerprint CertFingerprint) *CertIdentity
- type ClientVerifier
- type DANEError
- type DANEErrorType
- type DANEOutcome
- type DANEOutcomeType
- type DANEResolver
- type DANEResolverOption
- type DANEVerifier
- type DNSError
- type DNSErrorType
- type DNSLookupResult
- type DNSResolver
- type FailurePolicy
- type FailurePolicyConfig
- type HTTPTransparencyLogClient
- type MockDANEResolver
- func (r *MockDANEResolver) LookupTLSA(_ context.Context, fqdn models.Fqdn, port uint16) (TLSALookupResult, error)
- func (r *MockDANEResolver) WithError(fqdn string, port uint16, err error) *MockDANEResolver
- func (r *MockDANEResolver) WithTLSA(fqdn string, port uint16, result TLSALookupResult) *MockDANEResolver
- type MockDNSResolver
- func (r *MockDNSResolver) FindBadgeForVersion(ctx context.Context, fqdn models.Fqdn, version models.Version) (*AnsBadgeRecord, error)
- func (r *MockDNSResolver) FindPreferredBadge(ctx context.Context, fqdn models.Fqdn) (*AnsBadgeRecord, error)
- func (r *MockDNSResolver) LookupAnsBadge(_ context.Context, fqdn models.Fqdn) (DNSLookupResult, error)
- func (r *MockDNSResolver) WithError(fqdn string, err error) *MockDNSResolver
- func (r *MockDNSResolver) WithRaBadgeRecords(fqdn string, records []AnsBadgeRecord) *MockDNSResolver
- func (r *MockDNSResolver) WithRecords(fqdn string, records []AnsBadgeRecord) *MockDNSResolver
- type MockTransparencyLogClient
- func (c *MockTransparencyLogClient) FetchBadge(_ context.Context, url string) (*models.Badge, error)
- func (c *MockTransparencyLogClient) WithBadge(url string, badge *models.Badge) *MockTransparencyLogClient
- func (c *MockTransparencyLogClient) WithError(url string, err error) *MockTransparencyLogClient
- type Option
- func WithCache(cache *BadgeCache) Option
- func WithCacheConfig(cfg CacheConfig) Option
- func WithClockSkewTolerance(d time.Duration) Option
- func WithDANEResolver(d DANEResolver) Option
- func WithDNSResolver(r DNSResolver) Option
- func WithFailurePolicy(policy FailurePolicy) Option
- func WithFailurePolicyConfig(cfg FailurePolicyConfig) Option
- func WithLogger(l *slog.Logger) Option
- func WithScittKeyLookup(kl scitt.KeyLookup) Option
- func WithTlogClient(t TransparencyLogClient) Option
- func WithTrustedRADomains(domains []string) Option
- func WithoutURLValidation() Option
- type OutcomeType
- type RefreshFunc
- type ServerVerifier
- func (v *ServerVerifier) Prefetch(ctx context.Context, fqdn models.Fqdn) (*models.Badge, error)
- func (v *ServerVerifier) Verify(ctx context.Context, fqdn models.Fqdn, cert *CertIdentity) *VerificationOutcome
- func (v *ServerVerifier) VerifyWithScitt(ctx context.Context, fqdn models.Fqdn, cert *CertIdentity, ...) *VerificationOutcome
- type StandardDANEResolver
- type StandardDNSResolver
- func (r *StandardDNSResolver) FindBadgeForVersion(ctx context.Context, fqdn models.Fqdn, version models.Version) (*AnsBadgeRecord, error)
- func (r *StandardDNSResolver) FindPreferredBadge(ctx context.Context, fqdn models.Fqdn) (*AnsBadgeRecord, error)
- func (r *StandardDNSResolver) LookupAnsBadge(ctx context.Context, fqdn models.Fqdn) (DNSLookupResult, error)
- func (r *StandardDNSResolver) WithResolver(resolver *net.Resolver) *StandardDNSResolver
- func (r *StandardDNSResolver) WithTimeout(timeout time.Duration) *StandardDNSResolver
- type TLSALookupResult
- type TLSARecord
- type TlogError
- type TlogErrorType
- type TransparencyLogClient
- type URLErrorType
- type URLValidationError
- type URLValidator
- type VerificationError
- type VerificationErrorType
- type VerificationOutcome
- func NewAnsNameMismatchOutcome(badge *models.Badge, expected, actual string) *VerificationOutcome
- func NewCertErrorOutcome(err error) *VerificationOutcome
- func NewDANERejectionOutcome(badge *models.Badge, daneOutcome *DANEOutcome) *VerificationOutcome
- func NewDNSErrorOutcome(err error) *VerificationOutcome
- func NewFailOpenOutcome(err error) *VerificationOutcome
- func NewFingerprintMismatchOutcome(badge *models.Badge, expected, actual string) *VerificationOutcome
- func NewHostnameMismatchOutcome(badge *models.Badge, expected, actual string) *VerificationOutcome
- func NewInvalidStatusOutcome(badge *models.Badge, status models.BadgeStatus) *VerificationOutcome
- func NewNotAnsAgentOutcome(host string) *VerificationOutcome
- func NewScittErrorOutcome(err error) *VerificationOutcome
- func NewTlogErrorOutcome(err error) *VerificationOutcome
- func NewURLValidationErrorOutcome(err error) *VerificationOutcome
- func NewVerifiedOutcome(badge *models.Badge, fingerprint CertFingerprint) *VerificationOutcome
- type VerificationTier
Constants ¶
This section is empty.
Variables ¶
var ErrRecordNotFound = errors.New("no matching badge record found")
ErrRecordNotFound is returned when no matching badge record is found. This is not an error condition - it means the FQDN is not an ANS agent.
Functions ¶
func DefaultTrustedRADomains ¶
func DefaultTrustedRADomains() []string
DefaultTrustedRADomains returns the default trusted Registration Authority domains.
Types ¶
type AnsBadgeRecord ¶
type AnsBadgeRecord struct {
// FormatVersion is the format version (e.g., "ans-badge1" or "ra-badge1").
FormatVersion string
// Version is the agent version this badge represents (optional).
Version *models.Version
// URL is the URL to fetch the badge from the transparency log.
URL string
// Source indicates where this record was resolved from.
Source BadgeRecordSource
}
AnsBadgeRecord represents a parsed _ans-badge or _ra-badge TXT record.
func GetAnsBadgeRecords ¶
func GetAnsBadgeRecords(ctx context.Context, resolver DNSResolver, fqdn models.Fqdn) ([]AnsBadgeRecord, error)
GetAnsBadgeRecords is a convenience method that returns records or error for not found.
func ParseAnsBadgeRecord ¶
func ParseAnsBadgeRecord(txt string) (*AnsBadgeRecord, error)
ParseAnsBadgeRecord parses an _ans-badge TXT record. Format: "v=ans-badge1; version=v1.0.0; url=https://..." or: "v=ans-badge1; url=https://..." (version optional)
type AnsName ¶
type AnsName struct {
Version models.Version
Host string
// contains filtered or unexported fields
}
AnsName represents an ANS name URI (e.g., ans://v1.0.0.agent.example.com).
func ParseAnsName ¶
ParseAnsName parses an ANS name from a URI string. Format: ans://v<major>.<minor>.<patch>.<fqdn>
type AnsVerifier ¶
type AnsVerifier struct {
// contains filtered or unexported fields
}
AnsVerifier is a high-level facade combining server and client verification.
func NewAnsVerifier ¶
func NewAnsVerifier(opts ...Option) *AnsVerifier
NewAnsVerifier creates a new ANS verifier with the given options. Both server and client verifiers share the same config (including cache).
func (*AnsVerifier) VerifyClient ¶
func (v *AnsVerifier) VerifyClient(ctx context.Context, cert *CertIdentity) *VerificationOutcome
VerifyClient verifies an mTLS client certificate.
func (*AnsVerifier) VerifyClientWithScitt ¶
func (v *AnsVerifier) VerifyClientWithScitt(ctx context.Context, cert *CertIdentity, headers *scitt.Headers) *VerificationOutcome
VerifyClientWithScitt verifies an mTLS client certificate using SCITT headers.
func (*AnsVerifier) VerifyServer ¶
func (v *AnsVerifier) VerifyServer(ctx context.Context, fqdnStr string, cert *CertIdentity) *VerificationOutcome
VerifyServer verifies a server certificate for the given FQDN string.
func (*AnsVerifier) VerifyServerWithScitt ¶
func (v *AnsVerifier) VerifyServerWithScitt(ctx context.Context, fqdnStr string, cert *CertIdentity, headers *scitt.Headers) *VerificationOutcome
VerifyServerWithScitt verifies a server certificate using SCITT headers.
type BadgeCache ¶
type BadgeCache struct {
// contains filtered or unexported fields
}
BadgeCache is a thread-safe cache for badges.
func NewBadgeCache ¶
func NewBadgeCache(config CacheConfig) *BadgeCache
NewBadgeCache creates a new badge cache with the given configuration.
func NewBadgeCacheWithDefaults ¶
func NewBadgeCacheWithDefaults() *BadgeCache
NewBadgeCacheWithDefaults creates a new badge cache with default configuration.
func (*BadgeCache) GetByFqdn ¶
func (c *BadgeCache) GetByFqdn(fqdn models.Fqdn) (*CachedBadge, bool)
GetByFqdn retrieves a cached badge by FQDN.
func (*BadgeCache) GetByFqdnVersion ¶
func (c *BadgeCache) GetByFqdnVersion(fqdn models.Fqdn, version models.Version) (*CachedBadge, bool)
GetByFqdnVersion retrieves a cached badge by FQDN and version.
func (*BadgeCache) GetStaleByFqdn ¶
func (c *BadgeCache) GetStaleByFqdn(fqdn models.Fqdn, maxStaleness time.Duration) (*CachedBadge, bool)
GetStaleByFqdn retrieves a cached badge by FQDN, even if expired, as long as it's within the given maxStaleness window.
func (*BadgeCache) GetStaleByFqdnVersion ¶
func (c *BadgeCache) GetStaleByFqdnVersion(fqdn models.Fqdn, version models.Version, maxStaleness time.Duration) (*CachedBadge, bool)
GetStaleByFqdnVersion retrieves a cached badge by FQDN and version, even if expired, as long as it's within the given maxStaleness window.
func (*BadgeCache) Insert ¶
func (c *BadgeCache) Insert(fqdn models.Fqdn, badge *models.Badge)
Insert adds a badge to the cache by FQDN.
func (*BadgeCache) InsertForVersion ¶
func (c *BadgeCache) InsertForVersion(fqdn models.Fqdn, version models.Version, badge *models.Badge)
InsertForVersion adds a badge to the cache by FQDN and version.
func (*BadgeCache) StartBackgroundRefresh ¶
func (c *BadgeCache) StartBackgroundRefresh(ctx context.Context, interval time.Duration, refreshFn RefreshFunc)
StartBackgroundRefresh spawns a goroutine that periodically refreshes cache entries approaching expiration. Stops when ctx is cancelled.
type BadgeRecordSource ¶
type BadgeRecordSource int
BadgeRecordSource indicates where a badge record was resolved from.
const ( // BadgeRecordSourceAnsBadge indicates the record came from _ans-badge. BadgeRecordSourceAnsBadge BadgeRecordSource = iota // BadgeRecordSourceRaBadge indicates the record came from _ra-badge (legacy fallback). BadgeRecordSourceRaBadge )
type CacheConfig ¶
type CacheConfig struct {
// MaxEntries is the maximum number of entries in the cache.
MaxEntries int
// DefaultTTL is the default time-to-live for cache entries.
DefaultTTL time.Duration
// RefreshThreshold is how close to expiration before refreshing.
RefreshThreshold time.Duration
// StaleRetention is how long expired entries are kept for fail-open-with-cache.
// Cleanup will not delete entries within this window past expiration.
StaleRetention time.Duration
}
CacheConfig holds configuration for the badge cache.
func DefaultCacheConfig ¶
func DefaultCacheConfig() CacheConfig
DefaultCacheConfig returns the default cache configuration.
type CachedBadge ¶
type CachedBadge struct {
// Badge is the cached badge.
Badge *models.Badge
// FetchedAt is when the badge was fetched.
FetchedAt time.Time
// ExpiresAt is when the cache entry expires.
ExpiresAt time.Time
}
CachedBadge holds a cached badge with metadata.
func (*CachedBadge) IsExpired ¶
func (c *CachedBadge) IsExpired() bool
IsExpired returns true if the cache entry has expired.
func (*CachedBadge) ShouldRefresh ¶
func (c *CachedBadge) ShouldRefresh(threshold time.Duration) bool
ShouldRefresh returns true if the entry should be refreshed.
type CertFingerprint ¶
type CertFingerprint struct {
// contains filtered or unexported fields
}
CertFingerprint represents a SHA-256 certificate fingerprint.
func CertFingerprintFromBytes ¶
func CertFingerprintFromBytes(b [32]byte) CertFingerprint
CertFingerprintFromBytes creates a fingerprint from raw bytes.
func CertFingerprintFromDER ¶
func CertFingerprintFromDER(der []byte) CertFingerprint
CertFingerprintFromDER computes the fingerprint from DER-encoded certificate bytes.
func ParseCertFingerprint ¶
func ParseCertFingerprint(s string) (CertFingerprint, error)
ParseCertFingerprint parses a fingerprint from "SHA256:<hex>" format.
func (CertFingerprint) Bytes ¶
func (f CertFingerprint) Bytes() [32]byte
Bytes returns the raw fingerprint bytes.
func (CertFingerprint) Equal ¶
func (f CertFingerprint) Equal(other CertFingerprint) bool
Equal returns true if the fingerprints are equal.
func (CertFingerprint) IsZero ¶
func (f CertFingerprint) IsZero() bool
IsZero returns true if the fingerprint has not been set.
func (CertFingerprint) Matches ¶
func (f CertFingerprint) Matches(other string) bool
Matches checks if this fingerprint matches a string representation.
func (CertFingerprint) String ¶
func (f CertFingerprint) String() string
String returns the fingerprint as "SHA256:<hex>".
func (CertFingerprint) ToHex ¶
func (f CertFingerprint) ToHex() string
ToHex returns the hex string without prefix.
type CertIdentity ¶
type CertIdentity struct {
// CommonName from the certificate subject.
CommonName *string
// DNSSANs are the DNS Subject Alternative Names.
DNSSANs []string
// URISANs are the URI Subject Alternative Names.
URISANs []string
// Fingerprint is the certificate's SHA-256 fingerprint.
Fingerprint CertFingerprint
}
CertIdentity holds the relevant identity information extracted from an X.509 certificate.
func CertIdentityFromDER ¶
func CertIdentityFromDER(der []byte) (*CertIdentity, error)
CertIdentityFromDER parses a DER-encoded certificate and extracts identity.
func CertIdentityFromFingerprintAndCN ¶
func CertIdentityFromFingerprintAndCN(fingerprint CertFingerprint, cn string) *CertIdentity
CertIdentityFromFingerprintAndCN creates a CertIdentity with just fingerprint and CN.
func CertIdentityFromX509 ¶
func CertIdentityFromX509(cert *x509.Certificate) *CertIdentity
CertIdentityFromX509 extracts identity from an x509.Certificate.
func NewCertIdentity ¶
func NewCertIdentity(commonName *string, dnsSANs, uriSANs []string, fingerprint CertFingerprint) *CertIdentity
NewCertIdentity creates a new CertIdentity from components.
func (*CertIdentity) AnsName ¶
func (c *CertIdentity) AnsName() *AnsName
AnsName extracts the ANS name from URI SANs.
func (*CertIdentity) FQDN ¶
func (c *CertIdentity) FQDN() *string
FQDN returns the FQDN from the certificate. Prefers DNS SAN (more reliable) over CN.
func (*CertIdentity) Version ¶
func (c *CertIdentity) Version() *models.Version
Version extracts the version from ANS name in URI SAN.
type ClientVerifier ¶
type ClientVerifier struct {
// contains filtered or unexported fields
}
ClientVerifier verifies mTLS client certificates against the ANS transparency log. Use this when a server wants to verify that an mTLS client is a legitimate ANS agent.
func NewClientVerifier ¶
func NewClientVerifier(opts ...Option) *ClientVerifier
NewClientVerifier creates a new client verifier with the given options.
func (*ClientVerifier) Verify ¶
func (v *ClientVerifier) Verify(ctx context.Context, cert *CertIdentity) *VerificationOutcome
Verify verifies an mTLS client certificate.
func (*ClientVerifier) VerifyWithScitt ¶
func (v *ClientVerifier) VerifyWithScitt(ctx context.Context, cert *CertIdentity, headers *scitt.Headers) *VerificationOutcome
VerifyWithScitt verifies an mTLS client certificate using SCITT receipts and status tokens. If headers are empty or nil, delegates to the standard badge-based Verify(). If SCITT verification encounters a fallback-eligible transport error, falls back to badge.
type DANEError ¶
type DANEError struct {
Type DANEErrorType
Fqdn string
Reason string
}
DANEError represents a DANE/TLSA verification error.
type DANEErrorType ¶
type DANEErrorType int
DANEErrorType represents the type of DANE verification error.
const ( // DANEErrorDNSSECFailed indicates DNSSEC validation failed. DANEErrorDNSSECFailed DANEErrorType = iota // DANEErrorLookupFailed indicates the TLSA DNS lookup failed. DANEErrorLookupFailed )
type DANEOutcome ¶
type DANEOutcome struct {
// Type is the outcome type.
Type DANEOutcomeType
// Records contains the TLSA records found (if any).
Records []TLSARecord
// Error is the underlying error (if any).
Error error
}
DANEOutcome represents the result of a DANE/TLSA verification.
func (*DANEOutcome) IsError ¶
func (o *DANEOutcome) IsError() bool
IsError returns true if a DNS lookup error prevented verification. When true, the caller should apply their failure policy (fail-open vs fail-closed).
func (*DANEOutcome) IsPass ¶
func (o *DANEOutcome) IsPass() bool
IsPass returns true if the DANE outcome does not reject the connection. Note: DANELookupError returns false for both IsPass and IsReject — use IsError() to detect it.
func (*DANEOutcome) IsReject ¶
func (o *DANEOutcome) IsReject() bool
IsReject returns true if the DANE outcome should reject the connection. Note: DANELookupError returns false for both IsPass and IsReject — use IsError() to detect it.
type DANEOutcomeType ¶
type DANEOutcomeType int
DANEOutcomeType represents the type of DANE verification outcome.
const ( // DANEVerified indicates DANE verification passed (DNSSEC valid, TLSA match). DANEVerified DANEOutcomeType = iota // DANEMismatch indicates TLSA records exist but no fingerprint matched. DANEMismatch // DANESkipped indicates DANE was skipped (records exist but no DNSSEC). DANESkipped // DANEDNSSECFailed indicates DNSSEC validation explicitly failed. DANEDNSSECFailed // DANENoRecords indicates no TLSA records were found. DANENoRecords // DANELookupError indicates a DNS lookup error occurred. DANELookupError )
func (DANEOutcomeType) String ¶
func (t DANEOutcomeType) String() string
String returns the string representation of a DANEOutcomeType.
type DANEResolver ¶
type DANEResolver interface {
// LookupTLSA queries TLSA records for the given FQDN and port.
LookupTLSA(ctx context.Context, fqdn models.Fqdn, port uint16) (TLSALookupResult, error)
}
DANEResolver is the interface for DANE/TLSA DNS resolution.
type DANEResolverOption ¶
type DANEResolverOption func(*StandardDANEResolver)
DANEResolverOption configures a StandardDANEResolver.
func WithDANEServer ¶
func WithDANEServer(server string) DANEResolverOption
WithDANEServer sets the DNS server address for TLSA lookups. The server must be a DNSSEC-validating recursive resolver (e.g., 8.8.8.8:53, 1.1.1.1:53) for the AuthenticatedData (AD) flag to be meaningful.
func WithDANETimeout ¶
func WithDANETimeout(timeout time.Duration) DANEResolverOption
WithDANETimeout sets the timeout for TLSA DNS lookups.
type DANEVerifier ¶
type DANEVerifier struct {
// contains filtered or unexported fields
}
DANEVerifier verifies certificates against DANE/TLSA records.
func NewDANEVerifier ¶
func NewDANEVerifier(resolver DANEResolver) *DANEVerifier
NewDANEVerifier creates a new DANEVerifier with the given resolver.
func (*DANEVerifier) Verify ¶
func (d *DANEVerifier) Verify(ctx context.Context, fqdn models.Fqdn, port uint16, cert *CertIdentity) *DANEOutcome
Verify performs DANE/TLSA verification for a certificate.
type DNSError ¶
type DNSError struct {
Type DNSErrorType
Fqdn string
Reason string
}
DNSError represents a DNS resolution error.
type DNSErrorType ¶
type DNSErrorType int
DNSErrorType represents the type of DNS error.
const ( // DNSErrorNotFound indicates the record does not exist (NXDOMAIN). DNSErrorNotFound DNSErrorType = iota // DNSErrorLookupFailed indicates the DNS lookup failed. DNSErrorLookupFailed // DNSErrorTimeout indicates the DNS lookup timed out. DNSErrorTimeout )
type DNSLookupResult ¶
type DNSLookupResult struct {
// Found indicates whether records were found.
Found bool
// Records contains the found records (empty if not found).
Records []AnsBadgeRecord
}
DNSLookupResult represents the result of a DNS lookup.
type DNSResolver ¶
type DNSResolver interface {
// LookupAnsBadge queries _ans-badge TXT records for an FQDN.
LookupAnsBadge(ctx context.Context, fqdn models.Fqdn) (DNSLookupResult, error)
// FindBadgeForVersion finds the badge record matching a specific version.
FindBadgeForVersion(ctx context.Context, fqdn models.Fqdn, version models.Version) (*AnsBadgeRecord, error)
// FindPreferredBadge finds the preferred badge (newest version).
FindPreferredBadge(ctx context.Context, fqdn models.Fqdn) (*AnsBadgeRecord, error)
}
DNSResolver is the interface for DNS resolution.
type FailurePolicy ¶
type FailurePolicy int
FailurePolicy defines behavior when DNS or transparency log is unavailable.
const ( // FailClosed rejects on any failure (most secure, default). FailClosed FailurePolicy = iota // FailOpenWithCache uses cached badge if available, otherwise rejects. FailOpenWithCache // FailOpen accepts without verification (not recommended). FailOpen )
type FailurePolicyConfig ¶
type FailurePolicyConfig struct {
// MaxStaleness is the maximum age of a cached badge to accept.
MaxStaleness time.Duration
}
FailurePolicyConfig holds configuration for FailOpenWithCache policy.
func DefaultFailurePolicyConfig ¶
func DefaultFailurePolicyConfig() FailurePolicyConfig
DefaultFailurePolicyConfig returns the default failure policy configuration.
type HTTPTransparencyLogClient ¶
type HTTPTransparencyLogClient struct {
// contains filtered or unexported fields
}
HTTPTransparencyLogClient is an HTTP-based implementation of TransparencyLogClient.
func NewHTTPTransparencyLogClient ¶
func NewHTTPTransparencyLogClient() *HTTPTransparencyLogClient
NewHTTPTransparencyLogClient creates a new HTTP-based transparency log client.
func (*HTTPTransparencyLogClient) FetchBadge ¶
func (c *HTTPTransparencyLogClient) FetchBadge(ctx context.Context, url string) (*models.Badge, error)
FetchBadge fetches a badge from the given URL.
func (*HTTPTransparencyLogClient) WithHTTPClient ¶
func (c *HTTPTransparencyLogClient) WithHTTPClient(client *http.Client) *HTTPTransparencyLogClient
WithHTTPClient sets a custom HTTP client.
func (*HTTPTransparencyLogClient) WithTimeout ¶
func (c *HTTPTransparencyLogClient) WithTimeout(timeout time.Duration) *HTTPTransparencyLogClient
WithTimeout sets the request timeout.
type MockDANEResolver ¶
type MockDANEResolver struct {
// contains filtered or unexported fields
}
MockDANEResolver is a mock DANE resolver for testing.
func NewMockDANEResolver ¶
func NewMockDANEResolver() *MockDANEResolver
NewMockDANEResolver creates a new MockDANEResolver.
func (*MockDANEResolver) LookupTLSA ¶
func (r *MockDANEResolver) LookupTLSA(_ context.Context, fqdn models.Fqdn, port uint16) (TLSALookupResult, error)
LookupTLSA returns the configured TLSA result or error for the given FQDN and port.
func (*MockDANEResolver) WithError ¶
func (r *MockDANEResolver) WithError(fqdn string, port uint16, err error) *MockDANEResolver
WithError configures an error for the given FQDN and port.
func (*MockDANEResolver) WithTLSA ¶
func (r *MockDANEResolver) WithTLSA(fqdn string, port uint16, result TLSALookupResult) *MockDANEResolver
WithTLSA configures a TLSA lookup result for the given FQDN and port.
type MockDNSResolver ¶
type MockDNSResolver struct {
// contains filtered or unexported fields
}
MockDNSResolver is a mock DNS resolver for testing.
func NewMockDNSResolver ¶
func NewMockDNSResolver() *MockDNSResolver
NewMockDNSResolver creates a new MockDNSResolver.
func (*MockDNSResolver) FindBadgeForVersion ¶
func (r *MockDNSResolver) FindBadgeForVersion(ctx context.Context, fqdn models.Fqdn, version models.Version) (*AnsBadgeRecord, error)
FindBadgeForVersion finds the badge record matching a specific version. Prefers an exact version match; falls back to a versionless record if no exact match exists.
func (*MockDNSResolver) FindPreferredBadge ¶
func (r *MockDNSResolver) FindPreferredBadge(ctx context.Context, fqdn models.Fqdn) (*AnsBadgeRecord, error)
FindPreferredBadge finds the preferred badge (newest version).
func (*MockDNSResolver) LookupAnsBadge ¶
func (r *MockDNSResolver) LookupAnsBadge(_ context.Context, fqdn models.Fqdn) (DNSLookupResult, error)
LookupAnsBadge queries _ans-badge TXT records for an FQDN. If _ans-badge returns no records (not found), falls back to _ra-badge. On hard errors (SERVFAIL/timeout), does NOT fallback.
func (*MockDNSResolver) WithError ¶
func (r *MockDNSResolver) WithError(fqdn string, err error) *MockDNSResolver
WithError configures an error for an FQDN.
func (*MockDNSResolver) WithRaBadgeRecords ¶
func (r *MockDNSResolver) WithRaBadgeRecords(fqdn string, records []AnsBadgeRecord) *MockDNSResolver
WithRaBadgeRecords adds _ra-badge (legacy) records for an FQDN.
func (*MockDNSResolver) WithRecords ¶
func (r *MockDNSResolver) WithRecords(fqdn string, records []AnsBadgeRecord) *MockDNSResolver
WithRecords adds _ans-badge records for an FQDN.
type MockTransparencyLogClient ¶
type MockTransparencyLogClient struct {
// contains filtered or unexported fields
}
MockTransparencyLogClient is a mock implementation of TransparencyLogClient for testing.
func NewMockTransparencyLogClient ¶
func NewMockTransparencyLogClient() *MockTransparencyLogClient
NewMockTransparencyLogClient creates a new mock transparency log client.
func (*MockTransparencyLogClient) FetchBadge ¶
func (c *MockTransparencyLogClient) FetchBadge(_ context.Context, url string) (*models.Badge, error)
FetchBadge fetches a badge from the given URL.
func (*MockTransparencyLogClient) WithBadge ¶
func (c *MockTransparencyLogClient) WithBadge(url string, badge *models.Badge) *MockTransparencyLogClient
WithBadge adds a badge for a URL.
func (*MockTransparencyLogClient) WithError ¶
func (c *MockTransparencyLogClient) WithError(url string, err error) *MockTransparencyLogClient
WithError configures an error for a URL.
type Option ¶
type Option func(*verifierConfig)
Option configures a verifier.
func WithCacheConfig ¶
func WithCacheConfig(cfg CacheConfig) Option
WithCacheConfig creates and sets a badge cache with the given configuration.
func WithClockSkewTolerance ¶
WithClockSkewTolerance sets the maximum allowed clock skew for status token expiry checks. Negative values are clamped to 0. Values exceeding 10 minutes are clamped to 10 minutes. Default is 120 seconds.
func WithDANEResolver ¶
func WithDANEResolver(d DANEResolver) Option
WithDANEResolver enables DANE/TLSA verification using the given resolver. When set, the verifier performs an additional DANE check after badge verification. DANE rejection (fingerprint mismatch or DNSSEC failure) overrides a successful badge check.
func WithDNSResolver ¶
func WithDNSResolver(r DNSResolver) Option
WithDNSResolver sets a custom DNS resolver.
func WithFailurePolicy ¶
func WithFailurePolicy(policy FailurePolicy) Option
WithFailurePolicy sets the failure policy for DNS/TLog errors.
NOTE: This policy does NOT apply to SCITT verification failures — a malformed or signature-invalid SCITT artifact is always terminal, regardless of FailOpen settings, to prevent forgery acceptance. Only DNS and TLog infrastructure failures are subject to this policy.
func WithFailurePolicyConfig ¶
func WithFailurePolicyConfig(cfg FailurePolicyConfig) Option
WithFailurePolicyConfig sets the failure policy configuration.
func WithLogger ¶
WithLogger sets a structured logger for verification operations. When nil, slog.Default() is used.
func WithScittKeyLookup ¶
WithScittKeyLookup enables SCITT verification using the given key store. When set, VerifyWithScitt methods can verify SCITT receipts and status tokens.
func WithTlogClient ¶
func WithTlogClient(t TransparencyLogClient) Option
WithTlogClient sets a custom transparency log client.
func WithTrustedRADomains ¶
WithTrustedRADomains sets custom trusted RA domains for URL validation.
func WithoutURLValidation ¶
func WithoutURLValidation() Option
WithoutURLValidation disables badge URL domain validation.
type OutcomeType ¶
type OutcomeType int
OutcomeType represents the type of verification outcome.
const ( // OutcomeVerified indicates verification passed. OutcomeVerified OutcomeType = iota // OutcomeNotAnsAgent indicates no _ans-badge record found. OutcomeNotAnsAgent // OutcomeInvalidStatus indicates badge status is invalid for connections. OutcomeInvalidStatus // OutcomeFingerprintMismatch indicates certificate fingerprint mismatch. OutcomeFingerprintMismatch // OutcomeHostnameMismatch indicates hostname mismatch. OutcomeHostnameMismatch // OutcomeAnsNameMismatch indicates ANS name mismatch. OutcomeAnsNameMismatch // OutcomeDNSError indicates DNS resolution failed. OutcomeDNSError // OutcomeTlogError indicates transparency log error. OutcomeTlogError // OutcomeCertError indicates certificate parsing error. OutcomeCertError // OutcomeFailOpen indicates verification was skipped due to fail-open policy. OutcomeFailOpen // OutcomeURLValidationError indicates the badge URL failed validation. OutcomeURLValidationError // OutcomeDANERejection indicates DANE/TLSA verification rejected the certificate. OutcomeDANERejection // OutcomeScittError indicates a SCITT verification error. OutcomeScittError )
type RefreshFunc ¶
RefreshFunc is called during background refresh for each expiring entry. It receives the FQDN key and should return a fresh badge, or an error.
type ServerVerifier ¶
type ServerVerifier struct {
// contains filtered or unexported fields
}
ServerVerifier verifies server certificates against the ANS transparency log. Use this when a client wants to verify that a server is a legitimate ANS agent.
func NewServerVerifier ¶
func NewServerVerifier(opts ...Option) *ServerVerifier
NewServerVerifier creates a new server verifier with the given options.
func (*ServerVerifier) Prefetch ¶
Prefetch fetches and caches a badge for an FQDN. Returns immediately if a fresh cached entry exists.
func (*ServerVerifier) Verify ¶
func (v *ServerVerifier) Verify(ctx context.Context, fqdn models.Fqdn, cert *CertIdentity) *VerificationOutcome
Verify verifies a server certificate for the given FQDN.
func (*ServerVerifier) VerifyWithScitt ¶
func (v *ServerVerifier) VerifyWithScitt(ctx context.Context, fqdn models.Fqdn, cert *CertIdentity, headers *scitt.Headers) *VerificationOutcome
VerifyWithScitt verifies a server certificate using SCITT receipts and status tokens. If headers are empty or nil, delegates to the standard badge-based Verify(). If SCITT verification encounters a fallback-eligible transport error, falls back to badge.
type StandardDANEResolver ¶
type StandardDANEResolver struct {
// contains filtered or unexported fields
}
StandardDANEResolver performs real DNSSEC-aware TLSA lookups using miekg/dns.
func NewStandardDANEResolver ¶
func NewStandardDANEResolver(opts ...DANEResolverOption) *StandardDANEResolver
NewStandardDANEResolver creates a new StandardDANEResolver with the given options.
func (*StandardDANEResolver) LookupTLSA ¶
func (r *StandardDANEResolver) LookupTLSA(ctx context.Context, fqdn models.Fqdn, port uint16) (TLSALookupResult, error)
LookupTLSA queries TLSA records for the given FQDN and port.
type StandardDNSResolver ¶
type StandardDNSResolver struct {
// contains filtered or unexported fields
}
StandardDNSResolver implements DNSResolver using Go's net.Resolver.
func NewStandardDNSResolver ¶
func NewStandardDNSResolver() *StandardDNSResolver
NewStandardDNSResolver creates a new StandardDNSResolver with default settings.
func (*StandardDNSResolver) FindBadgeForVersion ¶
func (r *StandardDNSResolver) FindBadgeForVersion(ctx context.Context, fqdn models.Fqdn, version models.Version) (*AnsBadgeRecord, error)
FindBadgeForVersion finds the badge record matching a specific version. Prefers an exact version match; falls back to a versionless record if no exact match exists.
func (*StandardDNSResolver) FindPreferredBadge ¶
func (r *StandardDNSResolver) FindPreferredBadge(ctx context.Context, fqdn models.Fqdn) (*AnsBadgeRecord, error)
FindPreferredBadge finds the preferred badge (newest version).
func (*StandardDNSResolver) LookupAnsBadge ¶
func (r *StandardDNSResolver) LookupAnsBadge(ctx context.Context, fqdn models.Fqdn) (DNSLookupResult, error)
LookupAnsBadge queries _ans-badge TXT records for an FQDN. If _ans-badge returns NXDOMAIN/NotFound, falls back to _ra-badge. On hard errors (SERVFAIL/timeout), does NOT fallback.
func (*StandardDNSResolver) WithResolver ¶
func (r *StandardDNSResolver) WithResolver(resolver *net.Resolver) *StandardDNSResolver
WithResolver sets a custom net.Resolver.
func (*StandardDNSResolver) WithTimeout ¶
func (r *StandardDNSResolver) WithTimeout(timeout time.Duration) *StandardDNSResolver
WithTimeout sets the lookup timeout.
type TLSALookupResult ¶
type TLSALookupResult struct {
// Found indicates whether any TLSA records were found.
Found bool
// Records contains the found TLSA records.
Records []TLSARecord
// DNSSECValid indicates whether the response was DNSSEC-validated.
DNSSECValid bool
}
TLSALookupResult represents the result of a TLSA DNS lookup.
type TLSARecord ¶
type TLSARecord struct {
// Usage is the certificate usage field (DANE-TA=2, DANE-EE=3).
Usage uint8
// Selector is the selector field (full cert=0, SubjectPublicKeyInfo=1).
Selector uint8
// MatchingType is the matching type (exact=0, SHA-256=1, SHA-512=2).
MatchingType uint8
// CertHash is the hex-encoded, lowercase certificate association data.
CertHash string
}
TLSARecord represents a parsed TLSA DNS record.
type TlogError ¶
type TlogError struct {
Type TlogErrorType
URL string
Reason string
HTTPCode int
}
TlogError represents a transparency log error.
type TlogErrorType ¶
type TlogErrorType int
TlogErrorType represents the type of transparency log error.
const ( // TlogErrorNotFound indicates the badge was not found. TlogErrorNotFound TlogErrorType = iota TlogErrorServiceUnavailable // TlogErrorInvalidResponse indicates an invalid response was received. TlogErrorInvalidResponse )
type TransparencyLogClient ¶
type TransparencyLogClient interface {
// FetchBadge fetches a badge from the given URL.
FetchBadge(ctx context.Context, url string) (*models.Badge, error)
}
TransparencyLogClient is the interface for fetching badges from the transparency log.
type URLErrorType ¶
type URLErrorType int
URLErrorType represents the type of URL validation failure.
const ( // URLErrorHTTPScheme indicates the URL uses HTTP instead of HTTPS. URLErrorHTTPScheme URLErrorType = iota // URLErrorUntrustedDomain indicates the URL domain is not a trusted RA. URLErrorUntrustedDomain // URLErrorNonStandardPort indicates the URL uses a non-standard port. URLErrorNonStandardPort // URLErrorPathTraversal indicates the URL contains path traversal or query injection. URLErrorPathTraversal )
type URLValidationError ¶
type URLValidationError struct {
Type URLErrorType
URL string
Reason string
}
URLValidationError represents a badge URL validation failure.
func (*URLValidationError) Error ¶
func (e *URLValidationError) Error() string
Error implements the error interface.
type URLValidator ¶
type URLValidator struct {
// contains filtered or unexported fields
}
URLValidator validates badge URLs against trusted RA domains.
func NewDefaultURLValidator ¶
func NewDefaultURLValidator() *URLValidator
NewDefaultURLValidator creates a URLValidator with default trusted RA domains.
func NewURLValidator ¶
func NewURLValidator(trustedDomains []string) *URLValidator
NewURLValidator creates a new URLValidator with the given trusted domains.
func (*URLValidator) Validate ¶
func (v *URLValidator) Validate(rawURL string) error
Validate checks a badge URL against security requirements: 1. HTTPS required 2. Domain must be in trusted list (case-insensitive) 3. No non-standard port (only 443 or empty) 4. No path traversal (..) or query params
type VerificationError ¶
type VerificationError struct {
Type VerificationErrorType
Expected string
Actual string
Message string
}
VerificationError represents a verification error.
func (*VerificationError) Error ¶
func (e *VerificationError) Error() string
Error implements the error interface.
type VerificationErrorType ¶
type VerificationErrorType int
VerificationErrorType represents the type of verification error.
const ( // VerificationErrorInvalidStatus indicates the badge status is invalid. VerificationErrorInvalidStatus VerificationErrorType = iota // VerificationErrorFingerprintMismatch indicates fingerprint mismatch. VerificationErrorFingerprintMismatch // VerificationErrorHostnameMismatch indicates hostname mismatch. VerificationErrorHostnameMismatch // VerificationErrorAnsNameMismatch indicates ANS name mismatch. VerificationErrorAnsNameMismatch // VerificationErrorNoCN indicates no CN in certificate. VerificationErrorNoCN // VerificationErrorNoURISAN indicates no URI SAN in certificate. VerificationErrorNoURISAN )
type VerificationOutcome ¶
type VerificationOutcome struct {
// Type is the outcome type.
Type OutcomeType
// Tier indicates the SCITT verification level achieved (defaults to TierBadgeOnly).
Tier VerificationTier
// Badge is the badge if verification partially completed (may be nil).
Badge *models.Badge
// MatchedFingerprint is the fingerprint that matched (for successful verification).
MatchedFingerprint *CertFingerprint
// Expected is the expected value for mismatch errors.
Expected string
// Actual is the actual value for mismatch errors.
Actual string
// Status is the badge status for invalid status errors.
Status models.BadgeStatus
// Host is the hostname being verified (for error context).
Host string
// Error is the underlying error if any.
Error error
// Warnings contains non-fatal warnings (e.g., DEPRECATED badge status).
Warnings []string
// DANEOutcome contains the DANE/TLSA verification result (nil if DANE not configured).
DANEOutcome *DANEOutcome
}
VerificationOutcome represents the result of a verification operation.
func NewAnsNameMismatchOutcome ¶
func NewAnsNameMismatchOutcome(badge *models.Badge, expected, actual string) *VerificationOutcome
NewAnsNameMismatchOutcome creates an ANS name mismatch outcome.
func NewCertErrorOutcome ¶
func NewCertErrorOutcome(err error) *VerificationOutcome
NewCertErrorOutcome creates a certificate error outcome.
func NewDANERejectionOutcome ¶
func NewDANERejectionOutcome(badge *models.Badge, daneOutcome *DANEOutcome) *VerificationOutcome
NewDANERejectionOutcome creates a DANE rejection outcome.
func NewDNSErrorOutcome ¶
func NewDNSErrorOutcome(err error) *VerificationOutcome
NewDNSErrorOutcome creates a DNS error outcome.
func NewFailOpenOutcome ¶
func NewFailOpenOutcome(err error) *VerificationOutcome
NewFailOpenOutcome creates a fail-open outcome (verification skipped).
func NewFingerprintMismatchOutcome ¶
func NewFingerprintMismatchOutcome(badge *models.Badge, expected, actual string) *VerificationOutcome
NewFingerprintMismatchOutcome creates a fingerprint mismatch outcome.
func NewHostnameMismatchOutcome ¶
func NewHostnameMismatchOutcome(badge *models.Badge, expected, actual string) *VerificationOutcome
NewHostnameMismatchOutcome creates a hostname mismatch outcome.
func NewInvalidStatusOutcome ¶
func NewInvalidStatusOutcome(badge *models.Badge, status models.BadgeStatus) *VerificationOutcome
NewInvalidStatusOutcome creates an invalid status outcome.
func NewNotAnsAgentOutcome ¶
func NewNotAnsAgentOutcome(host string) *VerificationOutcome
NewNotAnsAgentOutcome creates a not-ANS-agent outcome.
func NewScittErrorOutcome ¶
func NewScittErrorOutcome(err error) *VerificationOutcome
NewScittErrorOutcome creates a SCITT error outcome.
func NewTlogErrorOutcome ¶
func NewTlogErrorOutcome(err error) *VerificationOutcome
NewTlogErrorOutcome creates a transparency log error outcome.
func NewURLValidationErrorOutcome ¶
func NewURLValidationErrorOutcome(err error) *VerificationOutcome
NewURLValidationErrorOutcome creates a URL validation error outcome.
func NewVerifiedOutcome ¶
func NewVerifiedOutcome(badge *models.Badge, fingerprint CertFingerprint) *VerificationOutcome
NewVerifiedOutcome creates a successful verification outcome.
func (*VerificationOutcome) IsFailOpen ¶
func (o *VerificationOutcome) IsFailOpen() bool
IsFailOpen returns true if verification was skipped due to fail-open policy.
func (*VerificationOutcome) IsNotAnsAgent ¶
func (o *VerificationOutcome) IsNotAnsAgent() bool
IsNotAnsAgent returns true if the agent is not registered with ANS.
func (*VerificationOutcome) IsSuccess ¶
func (o *VerificationOutcome) IsSuccess() bool
IsSuccess returns true if verification was successful or fail-open was applied.
func (*VerificationOutcome) ToError ¶
func (o *VerificationOutcome) ToError() error
ToError converts the outcome to an error if verification failed.
type VerificationTier ¶
type VerificationTier int
VerificationTier represents the level of SCITT verification achieved.
const ( // TierBadgeOnly indicates only badge-based verification was performed. TierBadgeOnly VerificationTier = iota // TierFullScitt indicates both receipt and status token were cryptographically verified. TierFullScitt )
func (VerificationTier) String ¶
func (t VerificationTier) String() string
String returns a human-readable representation of the verification tier.