verify

package
v0.1.17 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 23, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package verify provides ANS trust verification functionality.

Index

Constants

This section is empty.

Variables

View Source
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

func ParseAnsName(uri string) (*AnsName, error)

ParseAnsName parses an ANS name from a URI string. Format: ans://v<major>.<minor>.<patch>.<fqdn>

func (*AnsName) String

func (a *AnsName) String() string

String returns the raw ANS name URI.

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) Prefetch

func (v *AnsVerifier) Prefetch(ctx context.Context, fqdnStr string) (*models.Badge, error)

Prefetch fetches and caches a badge for an FQDN string.

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) Clear

func (c *BadgeCache) Clear()

Clear removes all entries from the cache.

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

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.

func (*DANEError) Error

func (e *DANEError) Error() string

Error implements the error interface.

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.

func (*DNSError) Error

func (e *DNSError) Error() string

Error implements the error interface.

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

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

WithBadge adds a badge for a URL.

func (*MockTransparencyLogClient) WithError

WithError configures an error for a URL.

type Option

type Option func(*verifierConfig)

Option configures a verifier.

func WithCache

func WithCache(cache *BadgeCache) Option

WithCache sets a badge cache.

func WithCacheConfig

func WithCacheConfig(cfg CacheConfig) Option

WithCacheConfig creates and sets a badge cache with the given configuration.

func WithClockSkewTolerance

func WithClockSkewTolerance(d time.Duration) Option

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

func WithLogger(l *slog.Logger) Option

WithLogger sets a structured logger for verification operations. When nil, slog.Default() is used.

func WithScittKeyLookup

func WithScittKeyLookup(kl scitt.KeyLookup) Option

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

func WithTrustedRADomains(domains []string) Option

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

type RefreshFunc func(ctx context.Context, fqdn string) (*models.Badge, error)

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

func (v *ServerVerifier) Prefetch(ctx context.Context, fqdn models.Fqdn) (*models.Badge, error)

Prefetch fetches and caches a badge for an FQDN. Returns immediately if a fresh cached entry exists.

func (*ServerVerifier) Verify

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.

func (*TlogError) Error

func (e *TlogError) Error() string

Error implements the error interface.

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 indicates the service is unavailable.
	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.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL