Help us shape the future of Go! Take the 2026 Go Developer Survey

skynetca

package
v1.3.104 Latest Latest
Warning

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

Go to latest
Published: Oct 31, 2026 License: AGPL-3.0 Imports: 20 Imported by: 0

Documentation

Overview

Package skynetca pkg/skynetca/ca.go c4-app-skynet authority used by the skywire resolver to terminate TLS for `*.skynet`, `*.dmsg` and `*.skysocks` hostnames in the visitor's browser.

The CA is generated on the visitor's machine, name-constrained via the X.509 nameConstraints extension to the resolver TLDs, and installed into the OS trust store. Cross-wire authentication is already provided by the underlying skywire transport (Noise + secp256k1 visor pubkey); the locally-issued leaf cert exists only to satisfy the browser's secure-context requirements.

The package exports three primitives:

  • CA lifecycle on disk: GenerateCA / SaveCA / LoadCA / Fingerprint.
  • LeafMinter: on-demand leaf cert minting and caching, signed by the CA.
  • MITMTerminate: TLS-termination splice that wraps an upstream net.Conn and returns a net.Conn the resolver's SOCKS5 server can splice against.

pkg/skynetweb and pkg/dmsgweb both consume this package; neither imports the other.

Package skynetca pkg/skynetca/leaf.go c4-app-skynet

Package skynetca pkg/skynetca/mitm.go c4-app-skynet

Index

Constants

View Source
const PermittedIPRange = "198.18.0.0/15"

PermittedIPRange is the only range a constrained CA may name by IP. It is SkyDNS's range (skydns.Range), which holds the resolver's DoH address.

Variables

View Source
var DefaultPermittedDomains = []string{".skynet", ".dmsg", ".skysocks"}

DefaultPermittedDomains is the set of TLDs the resolver CA is allowed to issue leaf certs for. The leading dot means "any subdomain of"; bare TLDs themselves are not matched.

Functions

func Fingerprint

func Fingerprint(cert *x509.Certificate) string

Fingerprint returns the SHA-256 fingerprint of cert in the conventional colon-separated lowercase hex format.

func GenerateCA

func GenerateCA(opts CAOptions) (*x509.Certificate, *ecdsa.PrivateKey, error)

GenerateCA returns a fresh ECDSA P-256 CA suitable for signing leaf certs. Name constraints are applied per opts.PermittedDomains, unless opts.Unconstrained is set (no nameConstraints at all).

func LoadCA

func LoadCA(certPath, keyPath string) (*x509.Certificate, *ecdsa.PrivateKey, error)

LoadCA reads a CA cert + key pair previously written by SaveCA.

func MITMTerminate

func MITMTerminate(upstream net.Conn, leaf *tls.Certificate) net.Conn

MITMTerminate accepts an upstream net.Conn (the skywire transport to a merchant visor's plaintext HTTP server) and returns a net.Conn the caller (typically a SOCKS5 server's Dial callback) can splice against the browser.

Internally:

  1. A net.Pipe is created.
  2. One end is returned to the caller.
  3. The other end is wrapped in tls.Server with leaf and the TLS handshake is run with the browser via the pipe.
  4. After handshake, plaintext is spliced bidirectionally between the tls.Conn and upstream.

On any failure (handshake error, splice error, upstream close) all resources are released. The function returns immediately; the splice runs on a background goroutine. The caller must close the returned net.Conn when done; this triggers teardown of the goroutine and the upstream conn.

func Permits

func Permits(m LeafMinter, host string) bool

Permits reports whether m can mint a leaf for host. A LeafMinter that implements HostPermitter is asked directly; any other implementation is treated optimistically (the mint itself still enforces its constraints). This keeps the check non-breaking — LeafMinter itself is unchanged.

func SaveCA

func SaveCA(cert *x509.Certificate, key *ecdsa.PrivateKey, certPath, keyPath string) error

SaveCA writes cert and key to the given paths in PEM format. The key file is written 0600; the cert file 0644. The parent directory is created with 0700 if missing.

Types

type CAOptions

type CAOptions struct {
	CommonName       string
	Validity         time.Duration
	PermittedDomains []string
	// Unconstrained omits the X.509 nameConstraints extension entirely, so the CA
	// can sign a leaf for ANY dnsName. This is the "forge any host" root a real
	// clearnet HTTPS MITM (e.g. the skysocks-client HTTPS range-splitter) needs,
	// and is a deliberate security decision: such a root must be created
	// explicitly, never defaulted. PermittedDomains is ignored when this is set.
	Unconstrained bool
}

CAOptions configures GenerateCA.

type CachedMinter

type CachedMinter struct {
	// contains filtered or unexported fields
}

CachedMinter is the default LeafMinter implementation. Leaves are regenerated on cache miss and when the cached cert's remaining lifetime falls below opts.RenewBefore.

func NewMinter

func NewMinter(ca *x509.Certificate, caKey *ecdsa.PrivateKey, opts LeafOptions) *CachedMinter

NewMinter constructs a CachedMinter that signs leaves with the given CA. The CA must have been generated by GenerateCA (or be otherwise compatible — IsCA, KeyUsage with CertSign, name constraints set).

func (*CachedMinter) For

func (m *CachedMinter) For(host string) (*tls.Certificate, error)

For returns a leaf cert valid for host. The returned cert is shared with other callers via the cache; do not mutate.

func (*CachedMinter) ForIP

func (m *CachedMinter) ForIP(ip netip.Addr) (*tls.Certificate, error)

ForIP returns a leaf whose only name is ip, which must be in the CA's permitted IP ranges (RFC 5280 section 4.2.1.10).

func (*CachedMinter) Permits

func (m *CachedMinter) Permits(host string) bool

Permits implements HostPermitter: it reports whether host falls under one of this minter's permitted suffixes, without minting or caching anything.

type HostPermitter

type HostPermitter interface {
	Permits(host string) bool
}

HostPermitter is optionally implemented by a LeafMinter to report — WITHOUT attempting a mint — whether it can issue a leaf for host. Callers that decide whether to route a request down the TLS-MITM path (e.g. the resolving proxies' HTTPS interstitial) use this to skip hosts the name-constrained CA can't cover (arbitrary clearnet HTTPS), rather than calling For and logging its expected "does not match any permitted suffix" failure on every such request.

type IPMinter

type IPMinter interface {
	ForIP(ip netip.Addr) (*tls.Certificate, error)
}

IPMinter is optionally implemented by a LeafMinter that can also issue a leaf for an IP address, such as the one SkyDNS serves DNS over HTTPS on.

type LeafMinter

type LeafMinter interface {
	For(host string) (*tls.Certificate, error)
}

LeafMinter mints (and typically caches) leaf TLS certs signed by a local CA. Implementations must be safe for concurrent use.

func NewStaticMinter

func NewStaticMinter(leaf *tls.Certificate) LeafMinter

NewStaticMinter returns a LeafMinter that always returns leaf. Intended for tests; production callers should use NewMinter.

type LeafOptions

type LeafOptions struct {
	Validity          time.Duration
	RenewBefore       time.Duration
	PermittedSuffixes []string
}

LeafOptions configures a CachedMinter.

Jump to

Keyboard shortcuts

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