lib/fetch: documentation

This commit is contained in:
2025-11-20 18:14:57 -08:00
parent 8518cc6e56
commit b81709cfdd

View File

@@ -22,35 +22,41 @@ import (
// Fetcher is an interface for fetching certificates from a remote source. It // Fetcher is an interface for fetching certificates from a remote source. It
// currently supports fetching from a server or a file. // currently supports fetching from a server or a file.
type Fetcher interface { type Fetcher interface {
// Get retrieves the leaf certificate from the source.
Get() (*x509.Certificate, error) Get() (*x509.Certificate, error)
// GetChain retrieves the entire chain from the Fetcher.
GetChain() ([]*x509.Certificate, error) GetChain() ([]*x509.Certificate, error)
// String returns a string representation of the Fetcher.
String() string String() string
} }
func NewFetcher(spec string, tcfg *tls.Config) (Fetcher, error) {
if fileutil.FileDoesExist(spec) || spec == "-" {
return NewFileFetcher(spec), nil
}
fetcher, err := ParseServer(spec, tcfg)
if err != nil {
return nil, err
}
fetcher.config = tcfg
return fetcher, nil
}
// ServerFetcher retrieves certificates from a TLS connection.
type ServerFetcher struct { type ServerFetcher struct {
host string host string
port int port int
insecure bool config *tls.Config
roots *x509.CertPool
}
// WithRoots sets the roots for the ServerFetcher.
func WithRoots(roots *x509.CertPool) func(*ServerFetcher) {
return func(sf *ServerFetcher) {
sf.roots = roots
}
}
// WithSkipVerify sets the insecure flag for the ServerFetcher.
func WithSkipVerify() func(*ServerFetcher) {
return func(sf *ServerFetcher) {
sf.insecure = true
}
} }
// ParseServer parses a server string into a ServerFetcher. It can be a URL or a // ParseServer parses a server string into a ServerFetcher. It can be a URL or a
// a host:port pair. // a host:port pair.
func ParseServer(host string) (*ServerFetcher, error) { func ParseServer(host string, cfg *tls.Config) (*ServerFetcher, error) {
target, err := hosts.ParseHost(host) target, err := hosts.ParseHost(host)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to parse server: %w", err) return nil, fmt.Errorf("failed to parse server: %w", err)
@@ -59,6 +65,7 @@ func ParseServer(host string) (*ServerFetcher, error) {
return &ServerFetcher{ return &ServerFetcher{
host: target.Host, host: target.Host,
port: target.Port, port: target.Port,
config: cfg,
}, nil }, nil
} }
@@ -68,10 +75,7 @@ func (sf *ServerFetcher) String() string {
func (sf *ServerFetcher) GetChain() ([]*x509.Certificate, error) { func (sf *ServerFetcher) GetChain() ([]*x509.Certificate, error) {
opts := dialer.Opts{ opts := dialer.Opts{
TLSConfig: &tls.Config{ TLSConfig: sf.config,
InsecureSkipVerify: sf.insecure, // #nosec G402 - no shit sherlock
RootCAs: sf.roots,
},
} }
conn, err := dialer.DialTLS(context.Background(), net.JoinHostPort(sf.host, lib.Itoa(sf.port, -1)), opts) conn, err := dialer.DialTLS(context.Background(), net.JoinHostPort(sf.host, lib.Itoa(sf.port, -1)), opts)
@@ -93,6 +97,7 @@ func (sf *ServerFetcher) Get() (*x509.Certificate, error) {
return certs[0], nil return certs[0], nil
} }
// FileFetcher retrieves certificates from files on disk.
type FileFetcher struct { type FileFetcher struct {
path string path string
} }
@@ -139,20 +144,11 @@ func (ff *FileFetcher) Get() (*x509.Certificate, error) {
// configuration will be used to control verification behavior (e.g., // configuration will be used to control verification behavior (e.g.,
// InsecureSkipVerify, RootCAs). // InsecureSkipVerify, RootCAs).
func GetCertificateChain(spec string, cfg *tls.Config) ([]*x509.Certificate, error) { func GetCertificateChain(spec string, cfg *tls.Config) ([]*x509.Certificate, error) {
if fileutil.FileDoesExist(spec) { fetcher, err := NewFetcher(spec, cfg)
return NewFileFetcher(spec).GetChain()
}
fetcher, err := ParseServer(spec)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if cfg != nil {
fetcher.insecure = cfg.InsecureSkipVerify
fetcher.roots = cfg.RootCAs
}
return fetcher.GetChain() return fetcher.GetChain()
} }