crypto

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 9, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package crypto owns flue's Noise IK handshake, the secure channel framing, and the key material on the daemon side. Pure: no HTTP, no WebSockets, no knowledge of sessions or transports.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DeviceID

func DeviceID(publicKey []byte) string

DeviceID derives the identity from the key itself, so an entry cannot claim to be a key it does not hold.

func LoadOrCreateStaticKey

func LoadOrCreateStaticKey(configDir string) (noise.DHKey, error)

LoadOrCreateStaticKey returns the daemon's static keypair, creating it on first run. A file that exists but cannot be parsed is an error, never a regenerate: a fresh key would silently invalidate every pairing.

func Suite

func Suite() noise.CipherSuite

Suite is the one cipher suite flue speaks: Noise_IK_25519_ChaChaPoly_SHA256.

Types

type Channel

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

Channel is one authenticated, ordered, end-to-end encrypted pipe. Nonces are the CipherStates' own strictly incrementing counters; the transport underneath is a WebSocket, which is ordered and reliable, so any Open failure means tampering or replay and the caller must tear the connection down — there is no recovery path by design.

func InitiatorHandshake

func InitiatorHandshake(static noise.DHKey, peerStatic []byte, rng io.Reader, recv func() ([]byte, error), send func([]byte) error) (*Channel, error)

InitiatorHandshake runs the browser side of the handshake. It exists in Go for tests and the vector generator; production initiators are TypeScript. rng == nil means crypto/rand.

func ResponderHandshake

func ResponderHandshake(static noise.DHKey, rng io.Reader, recv func() ([]byte, error), send func([]byte) error) (*Channel, []byte, error)

ResponderHandshake runs the daemon side. The returned public key is the initiator's static — the device identity the caller authorizes against the device store. Callers must treat an error as fatal to the connection and process no frames before the handshake completes.

func (*Channel) Open

func (c *Channel) Open(ciphertext []byte) ([]byte, error)

Open decrypts one frame. An error is fatal to the connection.

func (*Channel) Seal

func (c *Channel) Seal(plaintext []byte) ([]byte, error)

Seal encrypts one frame.

type Device

type Device struct {
	ID        string    `json:"id"`
	Label     string    `json:"label"`
	PublicKey []byte    `json:"publicKey"`
	PairedAt  time.Time `json:"pairedAt"`
	LastSeen  time.Time `json:"lastSeen"`
}

type DeviceStore

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

DeviceStore is the paired-device registry: devices.json in the config dir, 0600, re-read under the lock on every call so concurrent daemon paths (pairing, revocation, the devices op) serialize on the file's truth.

func NewDeviceStore

func NewDeviceStore(configDir string) *DeviceStore

func (*DeviceStore) Add

func (s *DeviceStore) Add(label string, publicKey []byte) (Device, error)

func (*DeviceStore) FindByKey

func (s *DeviceStore) FindByKey(publicKey []byte) (Device, bool, error)

func (*DeviceStore) List

func (s *DeviceStore) List() ([]Device, error)

func (*DeviceStore) Remove

func (s *DeviceStore) Remove(id string) (Device, bool, error)

func (*DeviceStore) UpdateLastSeen

func (s *DeviceStore) UpdateLastSeen(id string, now time.Time) (bool, error)

UpdateLastSeen stamps the device's LastSeen to now, reporting whether the device exists. Missing devices are not an error: a connection may race its own revocation, and the registry is the truth either way — a device that was unpaired a moment ago is not brought back by having connected.

The whole file is rewritten, like every other mutation here, because that is what makes a concurrent revoke and a concurrent stamp serialise on the same lock rather than on two partial views of the same JSON.

Jump to

Keyboard shortcuts

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