Documentation
¶
Overview ¶
Package crypto wraps age. Cipher is satisfied by PassphraseCipher (MVP) and, post-MVP, a recipients-based cipher.
Index ¶
- Constants
- Variables
- func EncryptToMasters(plaintext []byte, masters ...*MasterKey) ([]byte, error)
- func NewHeader(passphrase, slotName string) (*Header, *MasterKey, error)
- type Cipher
- type Header
- func (h *Header) AddPassphraseSlot(passphrase, name string, mk *MasterKey) error
- func (h *Header) AddRecipientSlot(recipient *age.X25519Recipient, name string, mk *MasterKey) error
- func (h *Header) Marshal() ([]byte, error)
- func (h *Header) PrimarySlot() int
- func (h *Header) RemoveSlot(i int, mk *MasterKey) error
- func (h *Header) RotateSlot(i int, newPassphrase string, slotKey *age.X25519Identity) error
- func (h *Header) Seal(mk *MasterKey) error
- func (h *Header) SetMaster(mk *MasterKey) error
- func (h *Header) SetPrimary(i int) error
- func (h *Header) Unlock(passphrase string) (*MasterKey, int, *age.X25519Identity, error)
- func (h *Header) UnlockIdentity(id *age.X25519Identity) (*MasterKey, int, error)
- func (h *Header) Verify(mk *MasterKey) error
- type MasterKey
- type PassphraseCipher
- type Slot
Constants ¶
const ( SlotPassphrase = "passphrase" SlotRecipient = "recipient" )
Slot type tags.
Variables ¶
var ErrNotRecipient = errors.New("blob was not encrypted under the current master key")
ErrNotRecipient reports that a ciphertext is valid age but was not encrypted to the key that tried to open it — the key is wrong, not the data. Callers (rotation's fallback read, the stale-cache retry) branch on it with errors.Is.
var ErrWrongPassphrase = errors.New("wrong passphrase")
ErrWrongPassphrase is returned when a passphrase does not match the ciphertext (or, for Header.Unlock, any key slot).
Functions ¶
func EncryptToMasters ¶ added in v0.2.0
EncryptToMasters seals plaintext to every master's recipient, so any of their identities can decrypt it. Rotation uses this to keep a blob readable under both the old and new master at once during the transition.
Types ¶
type Header ¶
type Header struct {
Version int `json:"version"`
Recipient string `json:"recipient"` // master public key (decorative)
Revision int `json:"revision"` // monotonic; bumped on every write (anti-rollback)
Master []byte `json:"master"` // master identity, age-encrypted to every slot's public key
Slots []Slot `json:"slots"`
Auth []byte `json:"auth,omitempty"` // HMAC over the header keyed from the master (see auth.go)
}
Header is the parsed header object.
func ParseHeader ¶
func (*Header) AddPassphraseSlot ¶ added in v0.2.0
AddPassphraseSlot creates a slot keypair, wraps its private key under the passphrase, and re-encrypts the master to include the new slot.
func (*Header) AddRecipientSlot ¶ added in v0.2.0
AddRecipientSlot adds a teammate by their age public key, which is the slot key; they hold the private key and unlock with their own age identity.
func (*Header) PrimarySlot ¶ added in v0.2.0
PrimarySlot returns the index of the primary slot, or -1 if none is marked.
func (*Header) RemoveSlot ¶ added in v0.2.0
RemoveSlot deletes slot i and re-encrypts the master to the survivors, so the removed slot can no longer decrypt the master. It refuses to remove the last slot (which would brick the header). NOTE: this does not re-key blobs, so a holder who retained the master is not revoked; true revocation re-keys via SetMaster (rotate-master). mk is the current master.
func (*Header) RotateSlot ¶ added in v0.2.0
RotateSlot re-wraps a passphrase slot's private key under a new passphrase. The master, the slot keypair, and Master are untouched, so other slots and every blob are unaffected. slotKey is the slot's private key, obtained from Unlock.
func (*Header) Seal ¶ added in v0.2.0
Seal sets the header's authentication tag over its current contents.
func (*Header) SetMaster ¶ added in v0.2.0
SetMaster installs a new master key, re-encrypting it to every slot's public key. Used by rotate-master after the blobs have been re-keyed.
func (*Header) SetPrimary ¶ added in v0.2.0
SetPrimary makes slot i the sole primary slot.
func (*Header) Unlock ¶
Unlock opens the master via a passphrase. It finds the passphrase slot whose wrapped private key the passphrase decrypts, then decrypts the master with that slot key. Returns the master, the matched slot index, and the slot private key (needed to rotate that passphrase). ErrWrongPassphrase if none opens.
func (*Header) UnlockIdentity ¶ added in v0.2.0
UnlockIdentity opens the master via a teammate's age identity (their recipient slot). Returns the master and the matched slot index (or -1 if the identity decrypts the master but matches no slot's public key). ErrWrongPassphrase if the identity is not a recipient of the master.
type MasterKey ¶
type MasterKey struct {
// contains filtered or unexported fields
}
MasterKey is the unwrapped master identity. It satisfies Cipher: Encrypt seals to the master recipient, Decrypt opens with the identity.
func GenerateMasterKey ¶ added in v0.2.0
GenerateMasterKey mints a fresh master key with no header (used by rotation).
func ParseMasterKey ¶
ParseMasterKey parses the identity string form (used by the session cache, which stores the unwrapped master key, not the passphrase).
type PassphraseCipher ¶
type PassphraseCipher struct {
// contains filtered or unexported fields
}
PassphraseCipher encrypts to an age scrypt recipient (symmetric, passphrase-derived). In the header model it wraps key-slot contents, not data blobs.
func NewPassphraseCipher ¶
func NewPassphraseCipher(passphrase string) *PassphraseCipher
type Slot ¶
type Slot struct {
Name string `json:"name,omitempty"`
Primary bool `json:"primary,omitempty"`
Type string `json:"type"` // "passphrase" | "recipient"
PublicKey string `json:"public_key"` // recipient of Master
Wrapped []byte `json:"wrapped,omitempty"` // passphrase slots: slot private key, scrypt-encrypted
}
Slot is one credential that can unlock the master. Name identifies its owner (user@host). Primary marks the slot whose owner may rotate/remove other slots; advisory until header signing exists, but tooling refuses to remove or demote it. PublicKey is the slot's age public key (a recipient of Master); for a recipient slot it is the teammate's public key.