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

crypto

package
v0.1.94 Latest Latest
Warning

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

Go to latest
Published: Oct 18, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Index

Constants

View Source
const KeyFileSize = 32 // 256 bits for AES-256
View Source
const LegacyKeyFileBackupSuffix = ".pre-v1"

LegacyKeyFileBackupSuffix names the pre-upgrade copy kept beside an upgraded master key, so a binary rollback has something to roll back to.

View Source
const ThreeNcrPrefix = "3ncr.org/1#"

ThreeNcrPrefix is the header of the 3ncr.org/1 encrypted-string format that all new encryptions use. Stored values without it are in the legacy format (base64url of AES-256-GCM nonce||ciphertext||tag, as written by ODDK <= 0.1.28 via cryptopasta); the daemon re-encrypts those at startup, and DecryptPassword keeps a legacy fallback for rows that pre-date the sweep.

Variables

This section is empty.

Functions

func DecryptPassword

func DecryptPassword(encryptedPassword string, masterKey []byte) (string, error)

DecryptPassword decrypts a stored value with the master key, handling both the 3ncr.org/1 format and the legacy pre-0.1.29 format.

func EncryptPassword

func EncryptPassword(password string, masterKey []byte) (string, error)

EncryptPassword encrypts a password with the master key in the 3ncr.org/1 format (AES-256-GCM with the raw 32-byte key, self-describing header).

func GetOrCreateKeyFile

func GetOrCreateKeyFile(dataDir string) ([]byte, error)

GetOrCreateKeyFile gets or creates the master key file.

A legacy headerless key is upgraded to the V1 format in place, best-effort: the upgrade is cosmetic, so a failure to rewrite (a read-only 0400 key, a read-only filesystem) is logged and the already-decoded key is returned. The upgrade lives here rather than in a separate startup sweep because this function aborts daemon startup on an unrecognised file, so a sweep running after it would never see the file it was meant to migrate.

func IsLegacyCiphertext

func IsLegacyCiphertext(stored string) bool

IsLegacyCiphertext reports whether a stored value is in the legacy format and should be re-encrypted (used by the daemon's startup sweep).

func KeyID added in v0.1.94

func KeyID(masterKey []byte) string

KeyID names a master key in messages: the checksum that already ends its key-file line (`ODDK-SECRET-MASTER-KEY;V1;<payload>;<checksum>`), so an operator can match an archive to a key file by eye. It is 32 bits of a hash of a 256-bit random key, so publishing it in an archive header reveals nothing useful about the key.

func ReadKeyFileAt added in v0.1.59

func ReadKeyFileAt(path string) ([]byte, error)

ReadKeyFileAt reads a master key from an arbitrary path, for `snapshot apply` where the operator supplies the source host's key from wherever they archived it.

Unlike GetOrCreateKeyFile this never creates a key, never rewrites it, and it does not reject loose permissions: a key restored from backup media legitimately arrives 0644, and refusing it would block a disaster recovery for a property of a file that is about to be re-written with 0600 anyway. Symlinks are still refused, and the format is still validated.

func WriteKeyFile added in v0.1.59

func WriteKeyFile(path string, key []byte) error

WriteKeyFile installs a master key at path with 0600 permissions, in the current on-disk format.

Types

type ArchiveKey added in v0.1.94

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

ArchiveKey is the age identity ODDK encrypts archives to, derived from the master key so disaster recovery stays one secret (internal-docs/archive-encryption.md).

func NewArchiveKey added in v0.1.94

func NewArchiveKey(masterKey []byte) (*ArchiveKey, error)

NewArchiveKey derives the archive key from a 32-byte master key. The derivation is HKDF-SHA256 to a 32-byte seed, which is exactly what an age post-quantum (ML-KEM-768 + X25519) identity is.

func (*ArchiveKey) AgeSecret added in v0.1.94

func (k *ArchiveKey) AgeSecret() string

AgeSecret is the identity in age's own text form (AGE-SECRET-KEY-PQ-1…), for `age -d -i`. It is a full decryption secret: print it only locally, to the data-dir owner, never over the API.

func (*ArchiveKey) ID added in v0.1.94

func (k *ArchiveKey) ID() string

ID is the key ID of the master key this archive key was derived from.

func (*ArchiveKey) Identity added in v0.1.94

func (k *ArchiveKey) Identity() age.Identity

Identity decrypts archives encrypted to this key.

func (*ArchiveKey) Recipient added in v0.1.94

func (k *ArchiveKey) Recipient() age.Recipient

Recipient encrypts to this key and records its ID in the header.

type KeyIDProbe added in v0.1.94

type KeyIDProbe struct {
	// ID is the recorded key ID, or "" when the header has none (an archive
	// not written by ODDK).
	ID string
}

KeyIDProbe is an age identity that opens nothing: it records the key ID stanza of the header it is shown. age tries native identities first and stops at the first that opens the file, so a probe listed with the real keys is consulted only when none of them could — the one case that needs to name the key. The ID is unauthenticated at that point: a hint for an error message, never an input to a decision.

func (*KeyIDProbe) Unwrap added in v0.1.94

func (p *KeyIDProbe) Unwrap(stanzas []*age.Stanza) ([]byte, error)

Jump to

Keyboard shortcuts

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