Documentation
¶
Overview ¶
Package tlspolicy builds explicit, application-controlled TLS trust policies.
The package is intended for applications that have several TLS clients or servers operating in different network contexts, such as a direct route, an HTTP CONNECT proxy, a SOCKS tunnel, or an isolated test network. It keeps two concerns separate:
- a network route decides how sockets and DNS requests leave the process;
- a compiled policy decides which certificate chains and pins are accepted.
ServerPolicy is used by a TLS client to verify remote servers. It supports an explicit set of trust anchors, DNS- and IP-scoped trust anchors, constraints on intermediate certificate authorities, and leaf certificate or leaf SPKI pins. ClientPolicy is used by a TLS server to verify mTLS clients with an explicit set of client trust anchors and optional leaf pins.
Both policy types compile their trust anchors into an ordinary pool created by x509.NewCertPool. An empty policy therefore means “trust no certificate”, not “fall back to the operating-system trust store”. The package never calls x509.SystemCertPool and never installs process-wide fallback roots.
No implicit certificate-network traffic ¶
The package contains no AIA, OCSP, or CRL downloader. Verification uses the certificates supplied by the peer and the explicitly configured pools. A peer that omits a required intermediate certificate fails verification. Standard crypto/x509 verification does not perform revocation checking.
Additional verifier hooks are available for application-specific checks, including validation of a stapled OCSP response. Those hooks execute inside the TLS handshake. If a hook performs network I/O, the application is solely responsible for binding that I/O to the correct route and for preventing recursion, SSRF, direct-network fallback, and unbounded waits. A verifier that must preserve the package's no-network property should inspect only the supplied ConnectionState and local data.
Operating-system authority discovery ¶
AuthorityFetcher is deliberately only an interface. Platform-specific code may implement it by enumerating local certificate stores and exporting DER certificates. x509.CertPool.Subjects is not a certificate-export API and must not be used to obtain those DER values. FetchAuthorityCatalog validates and deduplicates the candidates for presentation to a user. This package contains no Windows, macOS, Linux, or other platform-specific store-enumeration implementation.
A DER certificate discovered in an OS store is only a candidate. Importing it into an application pool does not reproduce every OS trust decision, distrust list, usage restriction, enterprise policy, automatic root-update rule, or application-specific exception. User interfaces should preserve AuthoritySource information and require an explicit application-policy decision before promoting a discovered certificate to a trust anchor.
Typical client use ¶
A client that talks to a fixed server can build a configuration whose ServerName is fixed by policy:
ca, err := tlspolicy.ParseAuthorityDER(rootDER)
if err != nil {
return err
}
scope, err := tlspolicy.NewDNSDomainScope("gov.example", true)
if err != nil {
return err
}
policy, err := tlspolicy.CompileServerPolicy(tlspolicy.ServerPolicySpec{
TrustAnchors: []tlspolicy.ScopedAuthority{{
Authority: ca,
Scope: scope,
}},
})
if err != nil {
return err
}
tlsConfig, err := policy.TLSClientConfigForServer(
"service.gov.example",
tlspolicy.ClientTLSOptions{},
)
if err != nil {
return err
}
For net/http clients that can contact several hosts, use TLSClientConfig. The shared configuration form requires a DNS hostname. For an IP-literal server, use TLSClientConfigForServer because crypto/tls intentionally omits IP literals from SNI and does not expose the expected IP through ConnectionState.ServerName.
Typical server use ¶
CompileClientPolicy builds the trust policy for mTLS client certificates. ServerTLSConfig then combines that policy with the server's certificate and a ClientAuthMode. Even when the policy contains no roots, ClientCAs remains a non-nil empty pool, so verification fails closed instead of using host roots.
Immutability and sharing ¶
Compiled policies are immutable and safe for concurrent use. The returned tls.Config and http.Transport values must be completely configured before first use and must not be mutated afterward. In particular, callers must not replace RootCAs, ClientCAs, ServerName, VerifyConnection, DialContext, Proxy, or the TLS dial hooks installed by this package.
A ClientTLSOptions session cache is created per generated configuration. Do not manually share a tls.ClientSessionCache between trust policies. The package uses VerifyConnection rather than VerifyPeerCertificate, so scoped authority and pin checks also run on resumed TLS sessions.
DNS names ¶
Policy DNS names must be ASCII DNS A-labels, such as xn--bcher-kva.example, not Unicode U-labels. Names are lowercased and a final root dot is removed. Wildcards are not accepted in policy rules. Subdomain matching is expressed explicitly with DNSRule.IncludeSubdomains and always respects label boundaries.
Index ¶
- Variables
- type Authority
- func (a Authority) Certificate() (*x509.Certificate, error)
- func (a Authority) DER() []byte
- func (a Authority) Equal(other Authority) bool
- func (a Authority) Fingerprint() Fingerprint
- func (a Authority) MarshalBinary() ([]byte, error)
- func (a Authority) SPKIFingerprint() Fingerprint
- func (a *Authority) UnmarshalBinary(data []byte) error
- func (a Authority) Valid() bool
- type AuthorityCandidate
- type AuthorityCatalog
- type AuthorityConstraint
- type AuthorityFetcher
- type AuthorityFetcherFunc
- type AuthorityMatch
- type AuthorityRecord
- type AuthoritySource
- type ClientAuthMode
- type ClientConnectionVerifier
- type ClientConnectionVerifierFunc
- type ClientPolicy
- type ClientPolicySpec
- type ClientTLSOptions
- type ClientVerification
- type DNSRule
- type Fingerprint
- type IdentityKind
- type Pin
- type PinKind
- type Scope
- type ScopedAuthority
- type ScopedPin
- type ServerConnectionVerifier
- type ServerConnectionVerifierFunc
- type ServerIdentity
- func (id ServerIdentity) DNSName() (string, bool)
- func (id ServerIdentity) IP() (netip.Addr, bool)
- func (id ServerIdentity) Kind() IdentityKind
- func (id ServerIdentity) MarshalText() ([]byte, error)
- func (id ServerIdentity) String() string
- func (id *ServerIdentity) UnmarshalText(text []byte) error
- func (id ServerIdentity) Valid() bool
- type ServerPolicy
- func (p *ServerPolicy) PinCount() int
- func (p *ServerPolicy) TLSClientConfig(options ClientTLSOptions) (*tls.Config, error)
- func (p *ServerPolicy) TLSClientConfigForServer(serverName string, options ClientTLSOptions) (*tls.Config, error)
- func (p *ServerPolicy) TrustAnchorCount() int
- func (p *ServerPolicy) VerifyServer(identity ServerIdentity, state tls.ConnectionState) (ServerVerification, error)
- type ServerPolicySpec
- type ServerTLSOptions
- type ServerVerification
- type TrustHint
Constants ¶
This section is empty.
Variables ¶
var ( // ErrMissingServerIdentity is returned when a shared TLS client // configuration reaches verification without a ServerName. This usually // means the caller used tls.Client directly without setting Config.ServerName // or used a transport that did not populate it. ErrMissingServerIdentity = errors.New( "tlspolicy: missing remote server identity", ) // ErrNoVerifiedChains is returned when a policy is asked to inspect a // connection for which normal crypto/tls certificate verification did not // produce any chain. Policy-generated configurations keep normal // verification enabled, so this generally indicates manual misuse. ErrNoVerifiedChains = errors.New( "tlspolicy: normal TLS verification produced no certificate chain", ) // ErrServerIdentityMismatch is returned when the leaf certificate in an // otherwise verified chain is not valid for the ServerIdentity supplied to // ServerPolicy.VerifyServer. Policy-generated TLS configurations already ask // crypto/tls to perform this check; VerifyServer repeats it so direct callers // cannot accidentally apply domain-scoped trust to a chain verified for a // different name or IP address. ErrServerIdentityMismatch = errors.New( "tlspolicy: server certificate does not match the policy identity", ) // but every verified chain violates a scoped trust-anchor or authority rule. ErrUnauthorizedChain = errors.New( "tlspolicy: no verified certificate chain is authorized by policy", ) // ErrPinMismatch is returned when at least one pin applies to the peer but // none of the applicable pins matches the leaf certificate. ErrPinMismatch = errors.New("tlspolicy: peer certificate pin mismatch") )
Functions ¶
This section is empty.
Types ¶
type Authority ¶
type Authority struct {
// contains filtered or unexported fields
}
Authority is an immutable, parsed X.509 certificate that can be selected as a trust anchor or used to constrain a certificate authority in a chain.
Authority does not assert that the certificate is trusted, self-signed, or a CA. Trust is granted only by placing it in a policy's trust-anchor list. The zero value is invalid; create values with ParseAuthorityDER, ParseAuthoritiesPEM, or AuthorityFromCertificate.
func AuthorityFromCertificate ¶
func AuthorityFromCertificate(cert *x509.Certificate) (Authority, error)
AuthorityFromCertificate copies cert.Raw and returns it as an immutable Authority value.
The function reparses the DER so that malformed or manually constructed x509.Certificate values are rejected.
func ParseAuthoritiesPEM ¶
ParseAuthoritiesPEM parses every CERTIFICATE block in pemData.
Non-certificate PEM blocks are ignored. The function returns an error if a CERTIFICATE block is malformed, if non-PEM non-whitespace data remains, or if no certificate block is present. Each returned Authority owns its DER bytes.
func ParseAuthorityDER ¶
ParseAuthorityDER parses exactly one DER-encoded X.509 certificate and returns an immutable Authority value.
func (Authority) Certificate ¶
func (a Authority) Certificate() (*x509.Certificate, error)
Certificate returns a newly parsed certificate whose backing byte slices do not alias the Authority value.
func (Authority) Fingerprint ¶
func (a Authority) Fingerprint() Fingerprint
Fingerprint returns the SHA-256 digest of the complete DER certificate.
func (Authority) MarshalBinary ¶
MarshalBinary implements encoding.BinaryMarshaler by returning a copy of the complete DER certificate.
func (Authority) SPKIFingerprint ¶
func (a Authority) SPKIFingerprint() Fingerprint
SPKIFingerprint returns the SHA-256 digest of the certificate's DER-encoded SubjectPublicKeyInfo value.
func (*Authority) UnmarshalBinary ¶
UnmarshalBinary implements encoding.BinaryUnmarshaler.
type AuthorityCandidate ¶
type AuthorityCandidate struct {
// DER is one complete DER-encoded X.509 certificate.
DER []byte
// Source describes where DER was discovered.
Source AuthoritySource
}
AuthorityCandidate is one DER certificate and the local source that exposed it. AuthorityFetcher implementations may return the same DER certificate more than once with different AuthoritySource values; AuthorityCatalog deduplicates the certificate and preserves all distinct sources.
type AuthorityCatalog ¶
type AuthorityCatalog struct {
// contains filtered or unexported fields
}
AuthorityCatalog is an immutable, fingerprint-deduplicated snapshot of authority candidates.
Catalog methods return copies. An AuthorityCatalog is safe for concurrent use after construction.
func FetchAuthorityCatalog ¶
func FetchAuthorityCatalog( ctx context.Context, fetcher AuthorityFetcher, ) (*AuthorityCatalog, error)
FetchAuthorityCatalog invokes fetcher and validates its results with NewAuthorityCatalog.
func NewAuthorityCatalog ¶
func NewAuthorityCatalog( candidates []AuthorityCandidate, ) (*AuthorityCatalog, error)
NewAuthorityCatalog validates candidates, deduplicates them by exact certificate fingerprint, and returns a stable, subject-sorted catalog.
The function copies all DER bytes and source metadata. It rejects malformed certificates. Exact duplicate source entries for the same certificate are stored once.
func (*AuthorityCatalog) Len ¶
func (c *AuthorityCatalog) Len() int
Len returns the number of distinct DER certificates in c. A nil catalog has length zero.
func (*AuthorityCatalog) Lookup ¶
func (c *AuthorityCatalog) Lookup(id Fingerprint) (AuthorityRecord, bool)
Lookup returns a copy of the record with the exact certificate fingerprint id. The boolean result is false when id is absent or c is nil.
func (*AuthorityCatalog) Records ¶
func (c *AuthorityCatalog) Records() []AuthorityRecord
Records returns all catalog entries in stable subject, issuer, and fingerprint order. The returned slice and source metadata are copies.
func (*AuthorityCatalog) Select ¶
func (c *AuthorityCatalog) Select(ids []Fingerprint) ([]Authority, error)
Select resolves ids to immutable Authority values in the requested order. It returns an error for an unknown fingerprint or a duplicate selection.
type AuthorityConstraint ¶
type AuthorityConstraint struct {
// Authority supplies the exact certificate or SPKI to recognize.
Authority Authority
// Match chooses exact-certificate or SPKI recognition.
Match AuthorityMatch
// Scope selects the servers for which the matched CA is permitted.
Scope Scope
}
AuthorityConstraint restricts where a CA certificate may appear in a verified server chain.
Constraints are evaluated for every non-leaf certificate, including the terminal trust anchor. They do not add Authority to the root pool. A typical use is to restrict a government or enterprise intermediate CA even when it chains to a more generally trusted root.
type AuthorityFetcher ¶
type AuthorityFetcher interface {
// FetchAuthorities returns a snapshot of locally discoverable certificate
// candidates. It should honor ctx cancellation, copy DER bytes out of any
// platform-owned buffers, and describe each source precisely enough for user
// display and audit logging. Returning a candidate does not select it as a
// trust anchor.
FetchAuthorities(ctx context.Context) ([]AuthorityCandidate, error)
}
AuthorityFetcher enumerates certificate-authority candidates from a local source such as an operating-system certificate store.
Implementations belong in platform-specific code. They should enumerate and export local certificate objects only. They should not build certificate paths, validate arbitrary remote certificates, follow AIA URLs, contact OCSP responders, download CRLs, or otherwise perform network I/O as a side effect of discovery.
The configured fetcher decides which user, machine, service, enterprise, or other store views are included. Returning a candidate does not grant trust.
type AuthorityFetcherFunc ¶
type AuthorityFetcherFunc func(context.Context) ([]AuthorityCandidate, error)
AuthorityFetcherFunc adapts a function to AuthorityFetcher.
func (AuthorityFetcherFunc) FetchAuthorities ¶
func (f AuthorityFetcherFunc) FetchAuthorities( ctx context.Context, ) ([]AuthorityCandidate, error)
FetchAuthorities calls f(ctx).
type AuthorityMatch ¶
type AuthorityMatch uint8
AuthorityMatch selects how an AuthorityConstraint recognizes a certificate authority in a verified chain.
const ( // MatchCertificate matches the exact DER certificate. This is the default // zero value and distinguishes cross-signed certificate variants. MatchCertificate AuthorityMatch = iota // MatchSPKI matches SHA-256 over SubjectPublicKeyInfo. Use it when every // certificate variant sharing a CA key should receive the same restriction. // This is broader than exact-certificate matching and should be selected // deliberately. MatchSPKI )
func (AuthorityMatch) String ¶
func (m AuthorityMatch) String() string
String returns a stable human-readable name for m.
type AuthorityRecord ¶
type AuthorityRecord struct {
// Authority is the immutable certificate value accepted by policy specs.
Authority Authority
// CertificateFingerprint is SHA-256 over the complete certificate DER.
CertificateFingerprint Fingerprint
// SPKIFingerprint is SHA-256 over DER SubjectPublicKeyInfo.
SPKIFingerprint Fingerprint
// Subject is the certificate subject formatted by pkix.Name.String.
Subject string
// Issuer is the certificate issuer formatted by pkix.Name.String.
Issuer string
// SerialNumber is the certificate serial number in hexadecimal.
SerialNumber string
// NotBefore is the beginning of the certificate validity interval.
NotBefore time.Time
// NotAfter is the end of the certificate validity interval.
NotAfter time.Time
// IsCA reports the parsed BasicConstraints CA value.
IsCA bool
// PublicKeyAlgorithm identifies the certificate subject's public-key type.
PublicKeyAlgorithm x509.PublicKeyAlgorithm
// SignatureAlgorithm identifies the algorithm that signed the certificate.
SignatureAlgorithm x509.SignatureAlgorithm
// Sources lists the local stores or files that reported this certificate.
Sources []AuthoritySource
}
AuthorityRecord is a validated, display-ready certificate-authority candidate in an AuthorityCatalog.
Authority contains the immutable DER value to use when building a policy. CertificateFingerprint identifies the exact certificate, while SPKIFingerprint can group cross-signed certificate variants that share a public key. Sources contains every distinct discovery source reported for the exact DER certificate.
type AuthoritySource ¶
type AuthoritySource struct {
// Name identifies the store, file, domain, or other local source.
Name string
// Trust is the source's informational trust classification.
Trust TrustHint
// Metadata carries optional platform-specific, non-secret attributes.
Metadata map[string]string
}
AuthoritySource identifies one local source from which an authority candidate was discovered.
Name should be stable and suitable for display or audit logs, for example "windows:CurrentUser\\Root", "macos:system", or a certificate-bundle path. Metadata may contain platform-specific details. FetchAuthorityCatalog copies the map, and callers should treat values returned by Records and Lookup as snapshots.
type ClientAuthMode ¶
type ClientAuthMode uint8
ClientAuthMode selects the mTLS client-certificate requirement installed by ClientPolicy.ServerTLSConfig.
const ( // ClientAuthNone does not request a client certificate. ClientAuthNone ClientAuthMode = iota // ClientAuthVerifyIfGiven requests a client certificate and verifies it when // the client supplies one, but also permits clients without a certificate. ClientAuthVerifyIfGiven // ClientAuthRequireAndVerify requires a client certificate and verifies it. ClientAuthRequireAndVerify )
func (ClientAuthMode) String ¶
func (m ClientAuthMode) String() string
String returns a stable human-readable name for m.
type ClientConnectionVerifier ¶
type ClientConnectionVerifier interface {
// VerifyClient inspects an mTLS client connection already accepted by the
// compiled client policy. Returning a non-nil error aborts the TLS handshake.
// The supplied state and certificates are read-only.
VerifyClient(connection ClientVerification) error
}
ClientConnectionVerifier performs an additional local check after normal mTLS verification and client pins have succeeded.
Implementations can enforce application-specific certificate identities or extensions. The method may be called concurrently and on resumed sessions. Network I/O has the same routing and leakage caveats described for ServerConnectionVerifier.
type ClientConnectionVerifierFunc ¶
type ClientConnectionVerifierFunc func(ClientVerification) error
ClientConnectionVerifierFunc adapts a function to ClientConnectionVerifier.
func (ClientConnectionVerifierFunc) VerifyClient ¶
func (f ClientConnectionVerifierFunc) VerifyClient( connection ClientVerification, ) error
VerifyClient calls f(connection).
type ClientPolicy ¶
type ClientPolicy struct {
// contains filtered or unexported fields
}
ClientPolicy is an immutable policy used by TLS servers to authenticate mTLS clients.
A ClientPolicy is safe for concurrent use. Create one with CompileClientPolicy and attach it with ServerTLSConfig.
func CompileClientPolicy ¶
func CompileClientPolicy(spec ClientPolicySpec) (*ClientPolicy, error)
CompileClientPolicy validates spec and returns an immutable policy.
Every trust anchor is added to an x509.NewCertPool pool. An empty TrustAnchors slice is valid and creates a fail-closed policy. Duplicate trust anchors and duplicate pins are rejected.
func (*ClientPolicy) PinCount ¶
func (p *ClientPolicy) PinCount() int
PinCount returns the number of client pins in p. A nil policy has count zero.
func (*ClientPolicy) ServerTLSConfig ¶
func (p *ClientPolicy) ServerTLSConfig( options ServerTLSOptions, ) (*tls.Config, error)
ServerTLSConfig combines p with options and returns a TLS server configuration.
The configuration always has a non-nil ClientCAs pool. For verification modes, an empty ClientPolicy therefore rejects every client chain rather than falling back to operating-system roots. At least one server certificate or a GetCertificate callback must be configured.
func (*ClientPolicy) TrustAnchorCount ¶
func (p *ClientPolicy) TrustAnchorCount() int
TrustAnchorCount returns the number of exact client trust anchors in p. A nil policy has count zero.
func (*ClientPolicy) VerifyClient ¶
func (p *ClientPolicy) VerifyClient( state tls.ConnectionState, ) (ClientVerification, error)
VerifyClient applies the explicit-root and pin checks to a normally verified mTLS client state.
Normal crypto/tls client-certificate verification must already have succeeded and populated state.VerifiedChains. The method does not build chains or perform network access.
type ClientPolicySpec ¶
type ClientPolicySpec struct {
// TrustAnchors is the explicit set of accepted client-certificate roots.
TrustAnchors []Authority
// Pins contains optional global leaf certificate or leaf SPKI pins.
Pins []Pin
}
ClientPolicySpec describes how a TLS server authenticates mTLS client certificates.
TrustAnchors is the complete client-root set; there is no implicit system fallback. If Pins is non-empty, every presented and otherwise valid client certificate must match at least one pin. Multiple pins are alternatives, allowing overlap during certificate or key rotation.
type ClientTLSOptions ¶
type ClientTLSOptions struct {
// Certificates contains optional client certificates for mTLS. The slice and
// certificate byte slices are copied. PrivateKey objects are shared and must
// be safe for concurrent use as required by crypto/tls.
Certificates []tls.Certificate
// GetClientCertificate, when non-nil, selects an mTLS client certificate.
// Returned chains should contain the leaf followed by all required
// intermediates. The callback may be called concurrently and must not mutate
// policy data.
GetClientCertificate func(*tls.CertificateRequestInfo) (*tls.Certificate, error)
// MinVersion is the minimum permitted TLS version. Zero means TLS 1.2, which
// is the package default rather than a request to inherit a future library
// default.
MinVersion uint16
// MaxVersion is the maximum permitted TLS version. Zero lets crypto/tls use
// its current maximum.
MaxVersion uint16
// CipherSuites optionally limits TLS 1.0 through TLS 1.2 cipher suites. TLS
// 1.3 cipher suites are selected by crypto/tls and are not configurable.
CipherSuites []uint16
// CurvePreferences optionally limits key-exchange groups.
CurvePreferences []tls.CurveID
// NextProtos lists application protocols for ALPN negotiation.
NextProtos []string
// SessionCacheSize enables a new, policy-local LRU TLS client session cache
// with this capacity. Zero disables client session resumption. Negative
// values are invalid. The cache is never shared with another generated
// configuration.
SessionCacheSize int
// Time optionally supplies the current time to crypto/tls. It must be safe
// for concurrent use. Nil uses time.Now.
Time func() time.Time
// Verifiers contains additional checks run after normal verification,
// authority scoping, and pins. They run in order and the first error aborts
// the handshake.
Verifiers []ServerConnectionVerifier
}
ClientTLSOptions contains non-trust settings for a TLS client configuration.
RootCAs, ServerName, InsecureSkipVerify, and VerifyConnection are deliberately absent because the policy owns them. The returned tls.Config must not be modified after first use.
type ClientVerification ¶
type ClientVerification struct {
// ConnectionState is the TLS state supplied to VerifyConnection.
ConnectionState tls.ConnectionState
// AuthorizedChains is the non-empty subset of normally verified client
// chains accepted by the explicit root set.
AuthorizedChains [][]*x509.Certificate
}
ClientVerification is the result of applying a ClientPolicy to a normally verified mTLS client connection.
AuthorizedChains contains only chains whose terminal certificate was an explicit ClientPolicy trust anchor. ConnectionState.VerifiedChains is replaced with the same filtered chain set. ConnectionState and certificates must be treated as read-only.
type DNSRule ¶
type DNSRule struct {
// Domain is the DNS domain to match.
Domain string
// IncludeSubdomains extends the match to names below Domain.
IncludeSubdomains bool
}
DNSRule matches one DNS domain in a Scope.
Domain must be an ASCII DNS A-label name and must not contain a wildcard. If IncludeSubdomains is false, only the exact domain matches. If true, both the domain and names below it match. For example, a rule for example.test with IncludeSubdomains set matches example.test and a.b.example.test, but not badexample.test.
type Fingerprint ¶
Fingerprint is a SHA-256 digest used to identify a complete certificate or a certificate's SubjectPublicKeyInfo value.
Fingerprints compare by value and are safe to use as map keys. String returns 64 lowercase hexadecimal characters without separators. ParseFingerprint also accepts colon-separated hexadecimal input commonly shown by certificate inspection tools.
func ParseFingerprint ¶
func ParseFingerprint(value string) (Fingerprint, error)
ParseFingerprint parses a SHA-256 fingerprint.
The accepted representation is hexadecimal, with optional colon separators. Leading and trailing whitespace is ignored. Other separators and algorithms are rejected.
func (Fingerprint) MarshalText ¶
func (f Fingerprint) MarshalText() ([]byte, error)
MarshalText implements encoding.TextMarshaler.
func (Fingerprint) String ¶
func (f Fingerprint) String() string
String returns f as 64 lowercase hexadecimal characters without separators.
func (*Fingerprint) UnmarshalText ¶
func (f *Fingerprint) UnmarshalText(text []byte) error
UnmarshalText implements encoding.TextUnmarshaler.
type IdentityKind ¶
type IdentityKind uint8
IdentityKind identifies the representation used by a ServerIdentity.
const ( // IdentityInvalid is the kind of the zero ServerIdentity value. IdentityInvalid IdentityKind = iota // IdentityDNS identifies a canonical ASCII DNS name. IdentityDNS // IdentityIP identifies an IPv4 or IPv6 address. IdentityIP )
func (IdentityKind) String ¶
func (k IdentityKind) String() string
String returns a stable human-readable name for k.
type Pin ¶
type Pin struct {
// contains filtered or unexported fields
}
Pin is an immutable SHA-256 leaf-certificate or leaf-SPKI pin.
A Pin is an additional condition after normal certificate-chain and hostname verification. It never replaces PKI validation. The zero value is invalid.
func NewCertificatePin ¶
NewCertificatePin parses certificateDER and returns a pin for the complete leaf certificate DER.
func NewPin ¶
func NewPin(kind PinKind, digest Fingerprint) (Pin, error)
NewPin constructs a Pin from kind and digest.
func NewSPKIPin ¶
NewSPKIPin parses certificateDER and returns a pin for the leaf certificate's DER SubjectPublicKeyInfo value.
func (Pin) MarshalText ¶
MarshalText implements encoding.TextMarshaler.
func (Pin) Matches ¶
func (p Pin) Matches(cert *x509.Certificate) bool
Matches reports whether p matches cert. A nil certificate or invalid pin returns false.
func (Pin) String ¶
String returns p in the form "certificate:<hex>" or "spki:<hex>". An invalid pin is rendered as "invalid:<hex>".
func (*Pin) UnmarshalText ¶
UnmarshalText implements encoding.TextUnmarshaler. It accepts the format produced by String.
type PinKind ¶
type PinKind uint8
PinKind selects which part of a leaf certificate a Pin authenticates.
const ( // PinInvalid is the kind of the zero Pin value. PinInvalid PinKind = iota // PinLeafCertificate matches SHA-256 over the complete DER leaf certificate. // It changes whenever the certificate is renewed or reissued. PinLeafCertificate // PinLeafSPKI matches SHA-256 over the leaf certificate's DER-encoded // SubjectPublicKeyInfo. It can survive certificate renewal when the same key // is retained. PinLeafSPKI )
type Scope ¶
type Scope struct {
// Any matches every valid server identity.
Any bool
// DNS contains exact-domain or domain-subtree rules.
DNS []DNSRule
// IPPrefixes contains IPv4 or IPv6 network prefixes. An exact address uses a
// /32 IPv4 prefix or a /128 IPv6 prefix.
IPPrefixes []netip.Prefix
}
Scope is a set of remote-server identities for which a rule is active.
The entries in DNS and IPPrefixes are alternatives. Any makes the scope unrestricted and cannot be combined with other entries. The zero value matches nothing and is rejected when used in a compiled policy rule.
func AnyServerScope ¶
func AnyServerScope() Scope
AnyServerScope returns a scope that matches every valid server identity.
func NewDNSDomainScope ¶
NewDNSDomainScope returns a scope for domain. When includeSubdomains is true, the scope also matches every DNS name below domain.
func NewExactServerScope ¶
NewExactServerScope returns a scope that matches exactly identity.
func NewIPPrefixScope ¶
NewIPPrefixScope returns a scope containing prefix.
IPv4-mapped IPv6 prefixes and prefixes with a zone identifier are rejected; callers should normalize them to ordinary IPv4 or unzoned IPv6 values.
type ScopedAuthority ¶
type ScopedAuthority struct {
// Authority is the exact certificate to add as a trust anchor.
Authority Authority
// Scope selects the DNS names or IP addresses for which the anchor is valid.
Scope Scope
}
ScopedAuthority is a certificate selected as a trust anchor only for remote servers in Scope.
The certificate is placed in an explicit application-owned x509.CertPool. Scope is enforced after normal chain and hostname verification. A zero Scope is rejected because it would make the anchor unusable.
type ScopedPin ¶
type ScopedPin struct {
// Pin is the certificate or SPKI digest to require.
Pin Pin
// Scope selects the servers for which Pin is active.
Scope Scope
}
ScopedPin applies Pin only when Scope contains the remote server identity. If several pins apply to one server, they are alternatives: at least one matching pin is sufficient. This supports overlap during key rotation.
type ServerConnectionVerifier ¶
type ServerConnectionVerifier interface {
// VerifyServer inspects a connection already accepted by the compiled server
// policy. Returning a non-nil error aborts the TLS handshake. The supplied
// state and certificates are read-only.
VerifyServer(connection ServerVerification) error
}
ServerConnectionVerifier performs an additional local check after normal TLS verification, scoped-authority checks, and pins have succeeded.
Implementations may validate a stapled OCSP response, enforce application certificate extensions, or consult local policy data. Implementations should not perform network I/O unless the application explicitly routes and bounds that traffic. The method may be called concurrently and on resumed sessions.
type ServerConnectionVerifierFunc ¶
type ServerConnectionVerifierFunc func(ServerVerification) error
ServerConnectionVerifierFunc adapts a function to ServerConnectionVerifier.
func (ServerConnectionVerifierFunc) VerifyServer ¶
func (f ServerConnectionVerifierFunc) VerifyServer( connection ServerVerification, ) error
VerifyServer calls f(connection).
type ServerIdentity ¶
type ServerIdentity struct {
// contains filtered or unexported fields
}
ServerIdentity is the expected DNS name or IP address of a remote TLS server. It is used for scoped trust-anchor, authority-constraint, and pin matching.
Values are immutable and comparable. The zero value is invalid. Use ParseServerIdentity to construct one.
func ParseServerIdentity ¶
func ParseServerIdentity(value string) (ServerIdentity, error)
ParseServerIdentity parses a DNS name or IP address without a port.
DNS names must be ASCII A-labels. They are lowercased and one final root dot is removed. IPv6 addresses may be bracketed. IPv6 zone identifiers are rejected because they are routing details, not certificate identities.
func (ServerIdentity) DNSName ¶
func (id ServerIdentity) DNSName() (string, bool)
DNSName returns the canonical DNS name and true when id is a DNS identity.
func (ServerIdentity) IP ¶
func (id ServerIdentity) IP() (netip.Addr, bool)
IP returns the address and true when id is an IP identity.
func (ServerIdentity) Kind ¶
func (id ServerIdentity) Kind() IdentityKind
Kind returns whether id contains a DNS name or an IP address.
func (ServerIdentity) MarshalText ¶
func (id ServerIdentity) MarshalText() ([]byte, error)
MarshalText implements encoding.TextMarshaler.
func (ServerIdentity) String ¶
func (id ServerIdentity) String() string
String returns the canonical DNS name or IP address. It returns an empty string for the zero value.
func (*ServerIdentity) UnmarshalText ¶
func (id *ServerIdentity) UnmarshalText(text []byte) error
UnmarshalText implements encoding.TextUnmarshaler.
func (ServerIdentity) Valid ¶
func (id ServerIdentity) Valid() bool
Valid reports whether id contains a parsed DNS name or IP address.
type ServerPolicy ¶
type ServerPolicy struct {
// contains filtered or unexported fields
}
ServerPolicy is an immutable policy used by TLS clients to authenticate remote servers.
A ServerPolicy is safe for concurrent use. Create one with CompileServerPolicy. Use TLSClientConfig, TLSClientConfigForServer, or NewHTTPTransport to attach it to TLS connections.
func CompileServerPolicy ¶
func CompileServerPolicy(spec ServerPolicySpec) (*ServerPolicy, error)
CompileServerPolicy validates spec and returns an immutable policy.
Every trust anchor is added to a pool created with x509.NewCertPool. An empty TrustAnchors slice is valid and creates a fail-closed policy that trusts no server chain. Duplicate exact trust anchors and duplicate constraint keys are rejected to make policy mistakes visible.
func (*ServerPolicy) PinCount ¶
func (p *ServerPolicy) PinCount() int
PinCount returns the number of scoped pins in p. A nil policy has count zero.
func (*ServerPolicy) TLSClientConfig ¶
func (p *ServerPolicy) TLSClientConfig( options ClientTLSOptions, ) (*tls.Config, error)
TLSClientConfig returns a TLS client configuration for a transport that sets tls.Config.ServerName separately for every connection.
This form is appropriate for net/http.Transport and similar multiplexing transports that clone the configuration and set ServerName for each connection. For direct tls.Client or tls.Dial use, call TLSClientConfigForServer instead. Verification fails with ErrMissingServerIdentity when no name is available.
The dynamic form supports DNS hostnames, but not IP-literal destinations. crypto/tls uses an IP-valued Config.ServerName for SAN verification while intentionally omitting it from SNI; ConnectionState.ServerName is therefore empty and does not provide this callback with the expected IP. Use TLSClientConfigForServer for an IP-literal resource.
func (*ServerPolicy) TLSClientConfigForServer ¶
func (p *ServerPolicy) TLSClientConfigForServer( serverName string, options ClientTLSOptions, ) (*tls.Config, error)
TLSClientConfigForServer returns a TLS client configuration fixed to serverName.
serverName may be an ASCII DNS A-label or an IP address without a port. The returned config sets tls.Config.ServerName, so crypto/tls performs normal DNS or IP SAN verification before the policy callback runs.
func (*ServerPolicy) TrustAnchorCount ¶
func (p *ServerPolicy) TrustAnchorCount() int
TrustAnchorCount returns the number of exact trust-anchor certificates in p. A nil policy has count zero.
func (*ServerPolicy) VerifyServer ¶
func (p *ServerPolicy) VerifyServer( identity ServerIdentity, state tls.ConnectionState, ) (ServerVerification, error)
VerifyServer applies scoped-authority and pin checks to state for identity.
Normal crypto/tls verification must already have succeeded and populated state.VerifiedChains. The method does not build chains or perform any network access. It does repeat leaf hostname or IP verification against identity so a direct caller cannot accidentally apply a scoped policy to a chain verified for another resource. Policy-generated TLS configurations call this method from tls.Config.VerifyConnection.
type ServerPolicySpec ¶
type ServerPolicySpec struct {
// TrustAnchors is the explicit, server-scoped root CA set.
TrustAnchors []ScopedAuthority
// Constraints restrict recognized CA certificates wherever they occur above
// the leaf in an otherwise verified chain.
Constraints []AuthorityConstraint
// Pins contains resource-scoped leaf certificate or SPKI pins.
Pins []ScopedPin
}
ServerPolicySpec describes how TLS clients authenticate remote servers.
TrustAnchors is the complete root set; there is never an implicit system-root fallback. Constraints can further restrict roots and intermediates. Pins are additional leaf requirements after PKI and hostname verification.
type ServerTLSOptions ¶
type ServerTLSOptions struct {
// Certificates contains the server certificate chains. The first certificate
// in each chain must be the leaf, followed by all required intermediates; the
// root should normally be omitted. Certificate byte slices are copied.
Certificates []tls.Certificate
// GetCertificate optionally selects a server certificate from ClientHello.
// Returned chains should contain the leaf followed by all required
// intermediates and normally omit the root.
GetCertificate func(*tls.ClientHelloInfo) (*tls.Certificate, error)
// ClientAuth selects whether an mTLS client certificate is optional,
// required, or not requested.
ClientAuth ClientAuthMode
// MinVersion is the minimum permitted TLS version. Zero means TLS 1.2.
MinVersion uint16
// MaxVersion is the maximum permitted TLS version. Zero lets crypto/tls use
// its current maximum.
MaxVersion uint16
// CipherSuites optionally limits TLS 1.0 through TLS 1.2 cipher suites.
CipherSuites []uint16
// CurvePreferences optionally limits key-exchange groups.
CurvePreferences []tls.CurveID
// NextProtos lists application protocols for ALPN negotiation.
NextProtos []string
// SessionTicketsDisabled disables server-side TLS session tickets and PSK
// resumption. VerifyConnection runs on resumptions, so disabling tickets is
// not required for policy enforcement, but may be appropriate operationally.
SessionTicketsDisabled bool
// Time optionally supplies the current time to crypto/tls. Nil uses time.Now.
Time func() time.Time
// Verifiers contains additional checks for a presented and normally verified
// client certificate. Verifiers are not called when ClientAuthVerifyIfGiven
// permits a connection without a certificate.
Verifiers []ClientConnectionVerifier
}
ServerTLSOptions contains non-trust settings for a TLS server configuration.
ClientCAs, ClientAuth, and VerifyConnection are owned by ClientPolicy and ClientAuthMode. The returned tls.Config must not be modified after first use.
type ServerVerification ¶
type ServerVerification struct {
// Identity is the canonical remote-server identity used for policy matching.
Identity ServerIdentity
// ConnectionState is the TLS state supplied to VerifyConnection.
ConnectionState tls.ConnectionState
// AuthorizedChains is the non-empty subset of normally verified chains
// permitted by the policy.
AuthorizedChains [][]*x509.Certificate
}
ServerVerification is the result of applying a ServerPolicy to a normally verified TLS connection.
AuthorizedChains contains only the chains that satisfy all scoped authority rules. ConnectionState.VerifiedChains is replaced with the same filtered chain set. ConnectionState and the certificates in AuthorizedChains must be treated as read-only. The outer and inner chain slices are copies, but the x509.Certificate objects are owned by crypto/tls.
type TrustHint ¶
type TrustHint uint8
TrustHint describes how the source store characterized a discovered certificate.
A TrustHint is informational. CompileServerPolicy and CompileClientPolicy do not consult it. Selecting a discovered certificate as an application trust anchor must always be an explicit policy decision.
const ( // TrustHintUnknown means the fetcher could not express the source store's // trust semantics as one of the other hints. TrustHintUnknown TrustHint = iota // TrustHintAnchor means the source presented the certificate as a candidate // trust anchor. Platform-specific restrictions may still apply and are not // represented by this value alone. TrustHintAnchor // TrustHintDistrusted means the source explicitly distrusted the certificate. // User interfaces should not preselect such a certificate as an anchor. TrustHintDistrusted // TrustHintRestricted means trust depends on usage, policy, hostname, // application, key usage, or other source-specific constraints. TrustHintRestricted )