cert

package
v1.7.11 Latest Latest
Warning

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

Go to latest
Published: Aug 23, 2026 License: AGPL-3.0 Imports: 19 Imported by: 0

Documentation

Overview

Package cert manages the daemon's self-signed TLS certificate.

We generate a fresh ECDSA P-256 keypair + cert on first daemon startup and persist them to ~/.local/share/mtroamd/. The certificate is identified by the SHA-256 fingerprint of its DER encoding — that fingerprint travels through the SSH bootstrap to the iOS client, which pins it via Network.framework's verify block. There is no public-CA trust involved.

P-256 (rather than Ed25519) because iOS Network.framework's QUIC ClientHello does not advertise `ed25519` in its TLS 1.3 `signature_algorithms` extension, so an Ed25519 server cert triggers `CRYPTO_ERROR 0x128 (peer doesn't support any of the certificate's signature algorithms)` before the client's verify block is ever invoked. ECDSA P-256 with SHA-256 is universally supported in modern TLS 1.3 stacks (`ecdsa_secp256r1_sha256`, 0x0403). Security properties are equivalent — both ~128-bit classical strength, both forward-secret in TLS 1.3.

All cryptographic operations use Go's standard library; this package introduces no new primitives.

Index

Constants

View Source
const DefaultValidity = 365 * 24 * time.Hour

Default validity for a freshly minted cert. Rotation is automatic: LoadOrGenerate regenerates if the on-disk cert is within RenewalWindow of expiry (or already expired).

View Source
const RenewalWindow = 30 * 24 * time.Hour

RenewalWindow is how close to NotAfter we trigger a regenerate during LoadOrGenerate. iOS clients pin the SHA-256 fingerprint, so rotation is silent from the client's perspective: the next bootstrap line carries the new fingerprint and the client re-pins. There's no continuity guarantee for clients holding a stale bootstrap line, but bootstrap tokens have a 30-second TTL anyway so the window where a stale fingerprint matters is narrow.

Variables

This section is empty.

Functions

func DefaultDir

func DefaultDir() (string, error)

DefaultDir returns the conventional state directory: $XDG_DATA_HOME/mtroamd, falling back to $HOME/.local/share/mtroamd.

Returns an error only if both XDG_DATA_HOME is unset and the user has no home directory — pathological enough to surface rather than silently picking some other location.

Types

type Fingerprint

type Fingerprint [sha256.Size]byte

Fingerprint is the SHA-256 of the certificate's DER encoding — the value that travels through the SSH bootstrap line and is pinned by the iOS client.

func (Fingerprint) String

func (f Fingerprint) String() string

String returns the lowercase hex encoding (no separators), which is the format docs/mtroam-protocol.md mandates for the bootstrap line's <cert_fp> field.

type Manager

type Manager struct {
	// Dir is where {cert,key}.pem live. Defaults via DefaultDir().
	Dir string

	// Validity, the duration freshly generated certs are valid for.
	// Defaults to DefaultValidity when zero.
	Validity time.Duration
}

Manager owns the on-disk cert + key files and exposes them as a tls.Certificate ready to drop into a tls.Config.

func (*Manager) LoadOrGenerate

func (m *Manager) LoadOrGenerate() (tls.Certificate, Fingerprint, error)

LoadOrGenerate reads an existing cert+key from m.Dir, or generates a fresh pair if either file is missing or unreadable. Returns the loaded tls.Certificate and the cert's SHA-256 fingerprint (the value that goes into the bootstrap line).

The key file is always written with mode 0600. The cert file is written with mode 0644 (it's safe to read; only the private key is sensitive). Both writes are atomic via tempfile-then-rename.

Mismatched cert/key pairs are not silently regenerated — they return an error. A mismatched pair on disk is a sign of corruption or external tampering, and silently overwriting it would mask both.

Jump to

Keyboard shortcuts

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