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

keysource

package
v0.0.0-...-39204c4 Latest Latest
Warning

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

Go to latest
Published: Sep 28, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Asset: keysource Purpose: Interface and wrapped-blob format for retrieving unseal key shares. Threats: Defines an AEAD envelope that binds every wrapped share to a specific configured node context and share index, preventing accidental relabeling and index substitution. The node label is not hardware identity. Does NOT protect a share once unwrapped in memory (see secure.Wipe) and does NOT prevent an attacker with live HSM access from unwrapping legitimately. Deps: none (stdlib only) Example: src, _ := keysource.OpenPKCS11(cfg); share, _ := src.Unwrap(ctx, blob, aad) Status: tested License: MIT Provenance: original

Asset: keysource-pkcs11 Purpose: HSM-backed key source — unwraps unseal shares with an AES-256-GCM key that never leaves the token. Threats: Ensures unseal key shares are unrecoverable from stolen disks, backups, or filesystem snapshots: the wrapped blobs are inert without the token, and the wrapping key is non-extractable. Binds each share to configured node context+index via GCM AAD, preventing accidental relabeling. Gives the HSM an audit point and a revocation lever (destroy the key). Does NOT defend against an attacker executing code on this host while the session is open — they can ask the HSM to unwrap exactly as the daemon does. Auto-unseal inherently trades some of Vault's sealed-at-rest guarantee for availability. Deps: github.com/miekg/pkcs11 Example: src, err := keysource.OpenPKCS11(keysource.PKCS11Options{...}); defer src.Close() Status: tested — PKCS#11 v2.40 AES-GCM interface, exercised against SoftHSM 2.6/2.7 by the integration test and scripts/e2e.sh; NOT yet exercised against production hardware, so run `autohsm selftest` on the real token before trusting a deployment. License: MIT Provenance: original

Asset: keysource-software Purpose: AES-256-GCM software key source — development and test only, never production. Threats: Exercises the exact envelope and AAD binding the HSM path uses, so the authentication properties can be tested without a token present. Provides NO hardware protection: the wrapping key lives in process memory and (typically) in an environment variable, so anyone who can read the host can unwrap every share. It is gated behind an explicit opt-in in config for exactly this reason. Deps: none (stdlib only) Example: src, _ := keysource.NewSoftware(key); share, _ := src.Unwrap(ctx, blob, aad) Status: tested License: MIT Provenance: original

Index

Constants

This section is empty.

Variables

View Source
var ErrHSMMisconfigured = errors.New("HSM configuration or key is unusable")

ErrHSMMisconfigured reports a failure that retrying cannot fix: the module cannot be loaded, the token lacks AES-GCM, the key is missing, ambiguous or unsafe, or the PIN source is unusable. It is terminal.

View Source
var ErrHSMUnavailable = errors.New("HSM unavailable")

ErrHSMUnavailable reports that the token or its session is gone (removed, unreachable, session invalidated) and could not be re-established. It is transient: a later call retries the connection.

View Source
var ErrPINRejected = errors.New("HSM rejected the PIN")

ErrPINRejected reports that the token refused the PIN (incorrect, locked, expired, or invalid). It is terminal: the source never logs in again after seeing it, because repeated wrong-PIN attempts count down a hardware token's retry counter and can lock or zeroise it.

Functions

func AAD

func AAD(nodeID string, shareIndex int) []byte

AAD builds the additional authenticated data binding a share to one node and index. Changing node or index changes the AAD, so the AEAD tag check fails. NodeID is a configuration label, not proof that code runs on a physical host.

func MarshalEnvelope

func MarshalEnvelope(e Envelope) string

MarshalEnvelope renders an envelope to its on-disk text form.

func Wrap

func Wrap(src Source, nonce, plaintext, aad []byte) (string, error)

Wrap produces an envelope using the token's key. Exposed via the CLI so that provisioning never requires the wrapping key to leave the HSM.

func WrapSoftware

func WrapSoftware(key, plaintext, aad []byte) (string, error)

WrapSoftware produces an envelope for provisioning in development. The nonce comes from crypto/rand: never a counter, never time-derived.

Types

type Envelope

type Envelope struct {
	Nonce      []byte
	Ciphertext []byte
}

Envelope is the on-disk representation of a wrapped share:

autohsm-v1.<base64(nonce)>.<base64(ciphertext||tag)>

It carries no secret material of its own; without the HSM key it is inert.

func ParseEnvelope

func ParseEnvelope(raw []byte) (Envelope, error)

ParseEnvelope parses the on-disk form, failing closed on anything malformed.

type HealthChecker

type HealthChecker interface {
	Health(ctx context.Context) error
}

HealthChecker is implemented by sources whose backing device can go away (an HSM). Health re-establishes a lost session when it can and reports whether the source is usable.

type PKCS11Options

type PKCS11Options struct {
	ModulePath string
	TokenLabel string // optional; if empty, the first token with the key is used
	KeyLabel   string
	// ReadPIN supplies the user PIN for every login: the initial one and each
	// re-login after a lost session. The source wipes the returned slice
	// immediately after C_Login, so the PIN is not held between logins.
	ReadPIN func() ([]byte, error)
	// DeferUnavailable lets OpenPKCS11 return a disconnected source when the
	// only startup failure is ErrHSMUnavailable (token absent, module cannot
	// initialise, session cannot open). The first Health/Unwrap call then
	// reconnects, so a daemon can start before its HSM and use the same
	// backoff-and-alarm path as a mid-run outage. PIN and configuration
	// failures are still returned.
	DeferUnavailable bool
}

PKCS11Options describes how to reach the token and which key to use.

type Source

type Source interface {
	// Unwrap decrypts blob, authenticating it against aad. It must return an
	// error (never partial or unauthenticated plaintext) if authentication fails.
	Unwrap(ctx context.Context, blob []byte, aad []byte) ([]byte, error)
	// Close releases any HSM session.
	Close() error
}

Source unwraps a stored share into plaintext key material.

Implementations must never log, cache, or copy the plaintext beyond what the caller receives. Callers must wipe the returned buffer.

func NewSoftware

func NewSoftware(key []byte) (Source, error)

NewSoftware builds a development key source from a 32-byte key.

func OpenPKCS11

func OpenPKCS11(opts PKCS11Options) (Source, error)

OpenPKCS11 initialises the module, logs in, and locates the wrapping key. Every failure is classified as ErrPINRejected, ErrHSMMisconfigured (both terminal) or ErrHSMUnavailable (retryable). There is deliberately no fallback to software.

Jump to

Keyboard shortcuts

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