Documentation
¶
Overview ¶
Package certproxy presents TLS client certificates on behalf of a browser. The browser sends its connections to the certificate hosts through a local proxy, which ends the browser's TLS with a certificate the browser is told to accept and opens TLS to the site with the client certificate, routed the way the device routes its own traffic.
browser ── PAC ──┬─ https: certificate host ── proxy ── TLS + client cert ── site
└─ anything else ───────────── the device's own proxy setup
The proxy runs as a process of its own, because the browser outlives the process that launched it, and exits once that browser is gone.
Index ¶
- Constants
- func Main(ctx context.Context, stdin io.Reader, stdout io.WriteCloser) error
- func Serve(ctx context.Context, cfg Config, ready func(Ready)) error
- func Verified(ctx context.Context, handleURL, host string) (bool, error)
- type Config
- type Entry
- type Event
- type Handle
- type Pending
- type Ready
- type TrustedCA
Constants ¶
const ( // EventConnect reports the first connection to a host an entry or an // authority names, once its server certificate was verified. EventConnect = "connect" // EventClientCertificateRejected reports a server that refused the // client certificate. EventClientCertificateRejected = "client_certificate_rejected" // EventServerCertificate reports a server whose certificate is not // trusted. EventServerCertificate = "server_certificate" // EventProxyAuth reports an upstream proxy that asks for credentials. EventProxyAuth = "proxy_auth" // EventUpstream reports a server the proxy could not reach. EventUpstream = "upstream" // EventRefused reports a connection to a host no entry names. EventRefused = "refused" // EventClientCertificateMissing reports a server that asked for a // client certificate when no entry names its host. EventClientCertificateMissing = "client_certificate_missing" // EventGuardOff reports that the guard stopped, because the device's // proxy asks for credentials the proxy cannot give. EventGuardOff = "guard_off" )
Kinds of Event.
const ( PhaseReaching = "reaching the site" PhaseHandshake = "TLS handshake with the site" PhaseAnswer = "waiting for the site's answer" )
Phases of a pending connection.
Variables ¶
This section is empty.
Functions ¶
func Main ¶
Main is the cert-proxy command. It reads a Config as JSON from stdin, writes one line to stdout once the proxy accepts connections, closes stdout, and serves until the browser is gone or the process is told to stop.
Types ¶
type Config ¶
type Config struct {
// Token is a random value that prefixes the proxy's control paths.
Token string `json:"token"`
// CDPURL is the DevTools address of the browser the proxy serves, such
// as http://127.0.0.1:9333.
CDPURL string `json:"cdp_url"`
// SystemPAC is a PAC script for the device's own routing. Empty routes
// everything directly.
SystemPAC string `json:"system_pac"`
// Entries are the certificates; the first whose hosts match a host is
// presented to it.
Entries []Entry `json:"entries"`
// TrustedCAs add server trust to the hosts each names. Every matching
// authority applies, beside the entry presented there, if any.
TrustedCAs []TrustedCA `json:"trusted_cas,omitempty"`
// GraceSeconds is how long the proxy waits for the browser to answer
// for the first time; zero means five minutes.
GraceSeconds int `json:"grace_seconds,omitempty"`
// Guard sends the browser's other https: requests through the proxy too,
// so the browser never answers a site's request for a client
// certificate itself; a host no entry names gets none.
Guard bool `json:"guard,omitempty"`
}
Config is what the proxy serves, and for which browser.
type Entry ¶
type Entry struct {
// Label names the entry in messages, such as
// with.browser.client_certificates[0].
Label string `json:"label"`
// Hosts are host patterns, as the hostpattern package matches them.
Hosts []string `json:"hosts"`
// ChainPEM holds the certificate, then its intermediates.
ChainPEM string `json:"chain_pem"`
// KeyPEM holds the certificate's private key as PKCS#8.
KeyPEM string `json:"key_pem"`
// CAPEM holds certificates trusted, beside the system's, for the hosts'
// servers.
CAPEM string `json:"ca_pem,omitempty"`
}
Entry is a client certificate ready for the proxy, and the hosts it is presented to.
func Load ¶
func Load(label string, c cmnconfig.BrowserClientCertificate, baseDir string, now time.Time) (Entry, []string, error)
Load reads one certificate. Relative files resolve against baseDir. Warnings report a certificate that is expired or not yet valid at now. Errors name label and the file involved, never the passphrase.
type Event ¶
type Event struct {
Seq int64 `json:"seq"`
Time time.Time `json:"time"`
Kind string `json:"kind"`
Host string `json:"host"`
// Entry is the label of the entry involved, if any.
Entry string `json:"entry,omitempty"`
// Message explains the event in a sentence of its own.
Message string `json:"message,omitempty"`
// Presented is set on a connection on which the entry's certificate
// was presented.
Presented bool `json:"presented,omitempty"`
}
Event is something the proxy reports about a connection.
type Handle ¶
type Handle struct {
// URL is the base of the proxy's control paths.
URL string `json:"url"`
PID int `json:"pid"`
// StartedAt is the process's start time in Unix milliseconds, which
// tells it apart from a later process reusing PID.
StartedAt int64 `json:"started_at"`
PACURL string `json:"pac_url"`
SPKI string `json:"spki"`
}
Handle locates a running proxy process.
func Start ¶
Start runs executable's browser cert-proxy command with cfg and returns once the proxy accepts connections. The proxy outlives the caller and exits once the browser at cfg.CDPURL is gone.
func (Handle) ChromeArgs ¶
ChromeArgs returns the browser flags that send the certificate hosts to the proxy and accept the certificates it shows.
type Pending ¶
type Pending struct {
Host string `json:"host"`
Phase string `json:"phase"`
Since time.Time `json:"since"`
}
Pending is a connection the proxy has not yet heard the site answer on.
type Ready ¶
type Ready struct {
Port int `json:"port"`
// SPKI is the base64 SHA-256 hash of the public key of every
// certificate the proxy shows the browser, in the form Chrome's
// --ignore-certificate-errors-spki-list takes.
SPKI string `json:"spki"`
// PACURL is the PAC script the browser uses: a data: URL, or one the
// proxy serves when the script is too large for a command line.
PACURL string `json:"pac_url"`
// GuardPort is the port of the guard, or zero without one.
GuardPort int `json:"guard_port,omitempty"`
}
Ready describes a proxy that accepts connections.
type TrustedCA ¶
type TrustedCA struct {
// Label names the authority in messages, such as browser.trusted_cas[0].
Label string `json:"label"`
// Hosts are host patterns, as the hostpattern package matches them.
Hosts []string `json:"hosts"`
// CAPEM holds the authority's certificates.
CAPEM string `json:"ca_pem"`
}
TrustedCA is a server certificate authority trusted only for the hosts it names.
func LoadTrustedCA ¶
func LoadTrustedCA(label string, c cmnconfig.BrowserTrustedCA) (TrustedCA, error)
LoadTrustedCA reads a scoped server authority without a client identity.