certproxy

package
v2.20.1 Latest Latest
Warning

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

Go to latest
Published: Oct 14, 2026 License: GPL-3.0 Imports: 44 Imported by: 0

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

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

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

func Main(ctx context.Context, stdin io.Reader, stdout io.WriteCloser) error

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.

func Serve

func Serve(ctx context.Context, cfg Config, ready func(Ready)) error

Serve runs the proxy until ctx ends or the browser at cfg.CDPURL is gone. It calls ready once the proxy accepts connections, before serving them.

func Verified

func Verified(ctx context.Context, handleURL, host string) (bool, error)

Verified reports whether the proxy at handleURL verified the server certificate of host on a route it still carries. An error means the proxy no longer answers.

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.

func Events

func Events(ctx context.Context, handleURL string, after int64) ([]Event, error)

Events returns the events the proxy at handleURL recorded after seq. An error means the proxy no longer answers.

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

func Start(ctx context.Context, executable string, cfg Config) (*Handle, error)

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

func (h Handle) ChromeArgs() []string

ChromeArgs returns the browser flags that send the certificate hosts to the proxy and accept the certificates it shows.

func (Handle) Kill

func (h Handle) Kill() error

Kill ends the proxy process if it is still the one h records. A process already gone is not an error.

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.

func PendingConnections

func PendingConnections(ctx context.Context, handleURL string) ([]Pending, error)

PendingConnections returns the connections the proxy at handleURL has not yet heard a site answer on, the longest waiting first. An error means the proxy no longer answers.

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.

Jump to

Keyboard shortcuts

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