kamune

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Feb 26, 2026 License: MIT Imports: 31 Imported by: 0

README

Kamune

Communication over untrusted networks.

Kamune provides Ed25519_ML-KEM-768_HKDF_SHA512_ChaCha20-Poly1305X security suite. Optionally, ML-DSA can be used for full quantum safety.

demo

[!NOTE] This is an experimental project. All suggestions and feedbacks are welcome and greatly appreciated.

Features

  • Message signing and verification using Ed25519, with support for quantum safe ML-DSA-65
  • Ephemeral, quantum-resistant key encapsulation with ML-KEM-768
  • Key derivation via HKDF-SHA512 (HMAC-based extract-and-expand)
  • End-to-End, bidirectional symmetric encryption using ChaCha20-Poly1305X
  • Forward secrecy with Double Ratchet and ECDH exchange
  • Lightweight, custom protocol implemented in both TCP and UDP for minimal overhead and latency
  • Real-time, instant messaging over socket-based connection
  • Direct peer-to-peer communication, no intermediary server required
  • Protobuf for fast, compact binary message encoding

Roadmap

The following is a list of features that are currently planned or have been conceived of. It is by no means exhaustive, and does not imply a commitment to fully implement any or all of them. It will be updated as the project progresses.

Items marked with * are subject to edits, changes, and even partial or total removal.

  • Settle on the cipher suite
  • Write the core functionality
  • Implement a minimal TUI
  • Stabilize the package API
  • Bind ciphers to session-specific info
  • Network protocols support
    • TCP
    • UDP
    • QUIC, WebRTC, or others? *
  • Better timeout and deadline management
  • Double Ratchet
  • Routes and session reconnection
  • Relay server
    • IP discovery
    • Message conveying
    • Queue persistence
  • Handling remotes, connection retries, and session management
    • QR code generation
    • Peer name
    • Remote's public key expiration
    • Key rotation
  • Saving and restoring chat history
  • Daemon server
  • Native clients via Fyne
  • Provide NAT traversal and/or hole punching strategies
  • Messaging Layer Security (MLS) and group chats *
  • Replace Protobuf with a custom encoding\decoding protocol *

How does it work?

There are three stages. In the following terminology, server is the party who is accepting connections, and the client is the party who is trying to establish a connection to the server.

Introduction

Client sends its public key (think of it like an ID card) to the server and server, in return, responds with its own public key (ID card). If both parties verify the other one's identity, handshake process gets started.

Handshake

Client creates a new, ephemeral (one-time use) ml-kem key. Its public key, alongside randomly generated salt and ID prefix are sent to the server.

Server uses the received public key to derive a secret (also called shared secret; as well as a ciphertext that we'll get to in a minute). With that secret, a decryption cipher is created to decrypt incoming messages. By deriving another key from the shared secret, an encryption cipher is also created to encrypt outgoing messages. The ciphertext plus newly generated ID suffix and salt are sent back to the client.

Client uses the received ciphertext and their private key (that was previously generated), to derive the same exact shared secret. Then, encryption and decryption ciphers are created likewise.

To make sure everyone are on the same page, each party performs a challenge to verify that the other party (them) can decipher our messages, and if we can decipher their messages as well.
A random text is created by driving a new key from the shared secret and the agreed upon session ID (which was created by concatenating the ID prefix and suffix). It is encrypted and sent to the other party. They should decrypt the message, encrypt it again with their own encryption cipher, and send it back.
If each side receive and successfully verify their text, the handshake is deemed successful!

Communication

Imagine a post office. When a cargo is accepted, A unique signature is generated based on its content and the sender's identity. Everyone can verify the signature, but only the sender can issue a new one.
The cargo, the signature, and some other info such as timestamp and a number (sequence) are placed inside a box. Then, the box will be locked and sealed. Shipment will be done via a custom gateway specifically designed for this, and it will deliver the package straight to the recipient.

At destination, the parcel will be checked for any kind of temperaments or changes. Using pre-established keys from the handshake phase, smallest modifications will be detected and the package is rejected. If all checks pass successfully, the cargo will be delivered and opened.

Documentation

Overview

Package kamune provides secure communication over untrusted networks.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrResumptionNotSupported = errors.New("session resumption not supported")
	ErrResumptionFailed       = errors.New("session resumption failed")
	ErrChallengeVerifyFailed  = errors.New("challenge verification failed")
	ErrSequenceMismatch       = errors.New("sequence number mismatch")
	ErrSessionTooOld          = errors.New("session is too old to resume")
)
View Source
var (
	ErrNoHandler      = errors.New("no handler registered for route")
	ErrHandlerExists  = errors.New("handler already registered for route")
	ErrRouterClosed   = errors.New("router is closed")
	ErrInvalidHandler = errors.New("handler cannot be nil")
	ErrRouteMismatch  = errors.New("received route does not match expected")
)
View Source
var (
	ErrSessionNotResumable = errors.New("session cannot be resumed")
	ErrSessionMismatch     = errors.New("session state mismatch")
	ErrHandshakeInProgress = errors.New("handshake already in progress")
	ErrHandshakeNotFound   = errors.New("handshake state not found")
)
View Source
var (
	ErrConnClosed         = errors.New("connection has been closed")
	ErrInvalidSignature   = errors.New("invalid signature")
	ErrVerificationFailed = errors.New("verification failed")
	ErrMessageTooLarge    = errors.New("message is too large")
	ErrOutOfSync          = errors.New("peers are out of sync")
	ErrUnexpectedRoute    = errors.New("unexpected route received")
	ErrInvalidRoute       = errors.New("invalid route")
	ErrSessionNotFound    = errors.New("session not found")
	ErrSessionExpired     = errors.New("session has expired")
)
View Source
var (
	ErrMissingChatBucket = errors.New("chat bucket not found")
)
View Source
var (
	ErrPeerExpired = errors.New("peer has been expired")
)

Functions

func Bytes

func Bytes(b []byte) *wrapperspb.BytesValue

Bytes creates a BytesValue wrapper for sending raw bytes.

func DecodeSequences added in v0.2.0

func DecodeSequences(data []byte) (send, recv uint64, err error)

DecodeSequences decodes sequence numbers from received data.

func HandleReconnect added in v0.2.0

func HandleReconnect(
	t *Transport, req *pb.ReconnectRequest,
) (*pb.ReconnectResponse, error)

HandleReconnect processes a reconnection request and attempts to resume an existing session.

func RequestReconnect added in v0.2.0

func RequestReconnect(t *Transport) (*pb.ReconnectResponse, error)

RequestReconnect sends a reconnection request to resume an existing session.

func SaveSessionForResumption added in v0.2.0

func SaveSessionForResumption(t *Transport, sm *SessionManager) error

SaveSessionForResumption saves a transport's state for future resumption.

Types

type ChatEntry

type ChatEntry struct {
	Timestamp time.Time
	Data      []byte
	Sender    Sender
}

ChatEntry represents a decrypted chat message stored in the DB.

type Conn

type Conn interface {
	net.Conn
	ReadBytes() ([]byte, error)
	WriteBytes(data []byte) error
}

type ConnOption

type ConnOption func(*conn)

func ConnWithReadTimeout

func ConnWithReadTimeout(timeout time.Duration) ConnOption

func ConnWithWriteTimeout

func ConnWithWriteTimeout(timeout time.Duration) ConnOption

type DialOption

type DialOption func(*Dialer)

DialOption configures the dialer.

func DialWithAlgorithm

func DialWithAlgorithm(a attest.Algorithm) DialOption

DialWithAlgorithm sets the cryptographic algorithm for identity.

func DialWithClientName

func DialWithClientName(name string) DialOption

DialWithClientName sets the client's advertised name.

func DialWithDialTimeout

func DialWithDialTimeout(timeout time.Duration) DialOption

DialWithDialTimeout sets the timeout for establishing connections.

func DialWithExistingConn

func DialWithExistingConn(conn Conn) DialOption

DialWithExistingConn uses an existing connection instead of dialing.

func DialWithRatchetThreshold added in v0.2.0

func DialWithRatchetThreshold(threshold uint64) DialOption

DialWithRatchetThreshold sets the message threshold for DH ratchet rotation.

func DialWithReadTimeout

func DialWithReadTimeout(timeout time.Duration) DialOption

DialWithReadTimeout sets the read timeout for connections.

func DialWithRemoteVerifier

func DialWithRemoteVerifier(verifier RemoteVerifier) DialOption

DialWithRemoteVerifier sets a custom remote verifier function.

func DialWithResumption added in v0.2.0

func DialWithResumption(config ResumptionConfig) DialOption

DialWithResumption configures session resumption settings.

func DialWithResumptionEnabled added in v0.2.0

func DialWithResumptionEnabled(enabled bool) DialOption

DialWithResumptionEnabled enables or disables session resumption.

func DialWithSessionTimeout added in v0.2.0

func DialWithSessionTimeout(timeout time.Duration) DialOption

DialWithSessionTimeout sets the maximum age for resumable sessions.

func DialWithStorageOpts

func DialWithStorageOpts(opts ...StorageOption) DialOption

DialWithStorageOpts sets storage options.

func DialWithTCPConn

func DialWithTCPConn(opts ...ConnOption) DialOption

DialWithTCPConn configures the dialer to use TCP connections.

func DialWithUDPConn

func DialWithUDPConn(opts ...ConnOption) DialOption

DialWithUDPConn configures the dialer to use UDP/KCP connections.

func DialWithWriteTimeout

func DialWithWriteTimeout(timeout time.Duration) DialOption

DialWithWriteTimeout sets the write timeout for connections.

type Dialer

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

Dialer handles outgoing connections and initiates handshakes.

func NewDialer

func NewDialer(addr string, opts ...DialOption) (*Dialer, error)

NewDialer creates a new dialer with the given address and options.

func (*Dialer) Close added in v0.2.0

func (d *Dialer) Close() error

Close closes the dialer's storage.

func (*Dialer) Dial

func (d *Dialer) Dial() (*Transport, error)

Dial establishes a connection and performs the handshake.

func (*Dialer) DialWithReconnect added in v0.2.0

func (d *Dialer) DialWithReconnect(
	sessionState *SessionState,
) (*Transport, error)

DialWithReconnect attempts to resume an existing session or establishes a new one if resumption fails.

func (*Dialer) DialWithResume added in v0.2.0

func (d *Dialer) DialWithResume(
	remotePublicKey []byte,
) (*Transport, bool, error)

DialWithResume attempts to resume an existing session with the given peer, falling back to a fresh handshake if resumption fails.

func (*Dialer) PublicKey

func (d *Dialer) PublicKey() PublicKey

PublicKey returns the dialer's public key.

func (*Dialer) SessionManager added in v0.2.0

func (d *Dialer) SessionManager() *SessionManager

SessionManager returns the dialer's session manager.

type HandlerFunc

type HandlerFunc func(t *Transport) error

type HandshakeState added in v0.2.0

type HandshakeState struct {
	CreatedAt       time.Time
	UpdatedAt       time.Time
	SessionID       string
	RemotePublicKey []byte
	LocalPublicKey  []byte
	SharedSecret    []byte
	LocalSalt       []byte
	RemoteSalt      []byte
	Phase           SessionPhase
	IsInitiator     bool
}

HandshakeState tracks an in-progress handshake identified by the remote peer's public key.

type HandshakeTracker added in v0.2.0

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

HandshakeTracker manages in-progress handshakes using public keys as identifiers. This allows handshakes to be resumed after connection resets.

func NewHandshakeTracker added in v0.2.0

func NewHandshakeTracker(
	storage *Storage, timeout time.Duration,
) *HandshakeTracker

NewHandshakeTracker creates a new handshake tracker.

func (*HandshakeTracker) ActiveHandshakes added in v0.2.0

func (ht *HandshakeTracker) ActiveHandshakes() int

ActiveHandshakes returns the number of in-progress handshakes.

func (*HandshakeTracker) CanResumeHandshake added in v0.2.0

func (ht *HandshakeTracker) CanResumeHandshake(
	remotePublicKey []byte,
) (bool, SessionPhase, error)

CanResumeHandshake checks if there's a resumable handshake with the peer.

func (*HandshakeTracker) CancelHandshake added in v0.2.0

func (ht *HandshakeTracker) CancelHandshake(remotePublicKey []byte)

CancelHandshake removes a handshake from tracking.

func (*HandshakeTracker) CleanupExpired added in v0.2.0

func (ht *HandshakeTracker) CleanupExpired() int

CleanupExpired removes all expired handshakes.

func (*HandshakeTracker) CompleteHandshake added in v0.2.0

func (ht *HandshakeTracker) CompleteHandshake(
	remotePublicKey []byte,
) (*HandshakeState, error)

CompleteHandshake marks a handshake as complete and removes it from tracking. Returns the final state for session creation.

func (*HandshakeTracker) DeletePersistedHandshake added in v0.2.0

func (ht *HandshakeTracker) DeletePersistedHandshake(
	remotePublicKey []byte,
) error

DeletePersistedHandshake removes a persisted handshake from storage.

func (*HandshakeTracker) GetHandshake added in v0.2.0

func (ht *HandshakeTracker) GetHandshake(
	remotePublicKey []byte,
) (*HandshakeState, error)

GetHandshake retrieves an in-progress handshake by remote public key.

func (*HandshakeTracker) LoadHandshake added in v0.2.0

func (ht *HandshakeTracker) LoadHandshake(
	remotePublicKey []byte,
) (*HandshakeState, error)

LoadHandshake loads a persisted handshake state from storage. If the handshake has not expired, it is added to the in-memory cache with its UpdatedAt refreshed to the current time so that the expiry window restarts from the moment of loading.

func (*HandshakeTracker) PersistHandshake added in v0.2.0

func (ht *HandshakeTracker) PersistHandshake(remotePublicKey []byte) error

PersistHandshake saves the handshake state to storage for resumption after process restart.

func (*HandshakeTracker) StartHandshake added in v0.2.0

func (ht *HandshakeTracker) StartHandshake(
	remotePublicKey, localPublicKey []byte,
	isInitiator bool,
) (*HandshakeState, error)

StartHandshake begins tracking a new handshake with the given remote public key.

func (*HandshakeTracker) UpdateHandshake added in v0.2.0

func (ht *HandshakeTracker) UpdateHandshake(
	remotePublicKey []byte,
	phase SessionPhase,
	sessionID string,
	sharedSecret, localSalt, remoteSalt []byte,
) error

UpdateHandshake updates the state of an in-progress handshake.

type Metadata

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

Metadata contains metadata about a received message.

func (Metadata) ID

func (m Metadata) ID() string

ID returns the unique message ID.

func (Metadata) SequenceNum

func (m Metadata) SequenceNum() uint64

SequenceNum returns the message sequence number.

func (Metadata) Timestamp

func (m Metadata) Timestamp() time.Time

Timestamp returns the time the message was sent.

type Middleware added in v0.2.0

type Middleware func(next RouteHandler) RouteHandler

Middleware is a function that wraps a RouteHandler to provide cross-cutting concerns like logging, metrics, or authentication.

func LoggingMiddleware added in v0.2.0

func LoggingMiddleware(logger func(route Route, err error)) Middleware

LoggingMiddleware logs route dispatch events.

Note: Middleware does not receive the route as an argument, so the best available signal is the route embedded in the received message metadata.

func RecoveryMiddleware added in v0.2.0

func RecoveryMiddleware(onPanic func(r any)) Middleware

RecoveryMiddleware recovers from panics in handlers.

func SessionPhaseMiddleware added in v0.2.0

func SessionPhaseMiddleware(requiredPhase SessionPhase) Middleware

SessionPhaseMiddleware ensures the session is in the required phase.

type PassphraseHandler

type PassphraseHandler func() ([]byte, error)

type Peer

type Peer struct {
	FirstSeen time.Time
	LastSeen  time.Time
	PublicKey PublicKey
	Name      string
	Algorithm attest.Algorithm
}

type PublicKey

type PublicKey = attest.PublicKey

type RemoteVerifier

type RemoteVerifier func(store *Storage, peer *Peer) (err error)

type ResumableSession added in v0.2.0

type ResumableSession struct {
	UpdatedAt       time.Time
	CreatedAt       time.Time
	SessionID       string
	RatchetState    []byte
	RemotePublicKey []byte
	LocalPublicKey  []byte
	SharedSecret    []byte
	LocalSalt       []byte
	RemoteSalt      []byte
	SendSequence    uint64
	Phase           SessionPhase
	RecvSequence    uint64
	IsInitiator     bool
}

ResumableSession contains all the information needed to resume a session.

type ResumptionConfig added in v0.2.0

type ResumptionConfig struct {
	MaxSessionAge   time.Duration
	Enabled         bool
	PersistSessions bool
}

ResumptionConfig contains configuration for session resumption.

func DefaultResumptionConfig added in v0.2.0

func DefaultResumptionConfig() ResumptionConfig

DefaultResumptionConfig returns the default resumption configuration.

type Route added in v0.2.0

type Route int32

Route represents a communication route identifier used for message dispatch.

const (
	RouteInvalid Route = iota
	RouteIdentity
	RouteRequestHandshake
	RouteAcceptHandshake
	RouteFinalizeHandshake
	RouteSendChallenge
	RouteVerifyChallenge
	RouteInitializeDoubleRatchet
	RouteConfirmDoubleRatchet
	RouteExchangeMessages
	RouteCloseTransport
	RouteReconnect
)

func ExpectedRoutes added in v0.2.0

func ExpectedRoutes(isInitiator bool) []Route

ExpectedRoutes returns the sequence of routes expected during handshake.

func RouteFromProto added in v0.2.0

func RouteFromProto(r pb.Route) Route

RouteFromProto converts a protobuf Route enum to the local Route type.

func (Route) IsHandshakeRoute added in v0.2.0

func (r Route) IsHandshakeRoute() bool

IsHandshakeRoute returns true if the route is part of the handshake process.

func (Route) IsSessionRoute added in v0.2.0

func (r Route) IsSessionRoute() bool

IsSessionRoute returns true if the route is part of an established session.

func (Route) IsValid added in v0.2.0

func (r Route) IsValid() bool

IsValid returns true if the route is a valid, non-invalid route.

func (Route) String added in v0.2.0

func (r Route) String() string

String returns the string representation of the route.

func (Route) ToProto added in v0.2.0

func (r Route) ToProto() pb.Route

ToProto converts the Route to its protobuf enum representation.

type RouteDispatcher added in v0.2.0

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

RouteDispatcher provides a simple interface for handling route-based communication.

func NewRouteDispatcher added in v0.2.0

func NewRouteDispatcher(t *Transport) *RouteDispatcher

NewRouteDispatcher creates a new route dispatcher for a transport.

func (*RouteDispatcher) Close added in v0.2.0

func (rd *RouteDispatcher) Close() error

Close closes the dispatcher and its underlying transport.

func (*RouteDispatcher) On added in v0.2.0

func (rd *RouteDispatcher) On(route Route, handler RouteHandler) error

On registers a handler for a route.

func (*RouteDispatcher) Router added in v0.2.0

func (rd *RouteDispatcher) Router() *Router

Router returns the underlying router.

func (*RouteDispatcher) SendAndExpect added in v0.2.0

func (rd *RouteDispatcher) SendAndExpect(
	msg Transferable, sendRoute Route,
	dst Transferable, expectRoute Route,
) (*Metadata, error)

SendAndExpect sends a message and waits for a response on the expected route.

func (*RouteDispatcher) Serve added in v0.2.0

func (rd *RouteDispatcher) Serve(msgFactory func() Transferable) error

Serve starts serving incoming messages until the transport is closed.

func (*RouteDispatcher) Transport added in v0.2.0

func (rd *RouteDispatcher) Transport() *Transport

Transport returns the underlying transport.

type RouteGroup added in v0.2.0

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

RouteGroup allows grouping routes with shared middleware.

func (*RouteGroup) Handle added in v0.2.0

func (g *RouteGroup) Handle(route Route, handler RouteHandler) error

Handle registers a handler for a route within the group.

func (*RouteGroup) Use added in v0.2.0

func (g *RouteGroup) Use(mw ...Middleware) *RouteGroup

Use adds middleware to the group.

type RouteHandler added in v0.2.0

type RouteHandler func(t *Transport, msg Transferable, md *Metadata) error

RouteHandler is a function that processes a message for a specific route.

type Router added in v0.2.0

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

Router dispatches incoming messages to registered handlers based on their route.

func NewRouter added in v0.2.0

func NewRouter() *Router

NewRouter creates a new message router.

func (*Router) Clone added in v0.2.0

func (r *Router) Clone() *Router

Clone creates a copy of the router with the same handlers and middleware.

func (*Router) Close added in v0.2.0

func (r *Router) Close()

Close closes the router and prevents further dispatch operations.

func (*Router) Dispatch added in v0.2.0

func (r *Router) Dispatch(
	t *Transport, route Route, msg Transferable, md *Metadata,
) error

Dispatch processes an incoming message by routing it to the appropriate handler.

func (*Router) DispatchNext added in v0.2.0

func (r *Router) DispatchNext(t *Transport, dst Transferable) error

DispatchNext reads the next message from the transport and dispatches it.

func (*Router) Group added in v0.2.0

func (r *Router) Group(mw ...Middleware) *RouteGroup

Group creates a new route group with the specified middleware.

func (*Router) Handle added in v0.2.0

func (r *Router) Handle(route Route, handler RouteHandler) error

Handle registers a handler for a specific route.

func (*Router) HandleFunc added in v0.2.0

func (r *Router) HandleFunc(route Route, handler RouteHandler) error

HandleFunc is a convenience method that registers a handler function.

func (*Router) HasHandler added in v0.2.0

func (r *Router) HasHandler(route Route) bool

HasHandler returns true if a handler is registered for the route.

func (*Router) Remove added in v0.2.0

func (r *Router) Remove(route Route) bool

Remove removes the handler for a specific route.

func (*Router) Routes added in v0.2.0

func (r *Router) Routes() []Route

Routes returns a list of all registered routes.

func (*Router) SetDefault added in v0.2.0

func (r *Router) SetDefault(handler RouteHandler)

SetDefault sets the default handler for unregistered routes.

func (*Router) SetErrorHandler added in v0.2.0

func (r *Router) SetErrorHandler(handler func(route Route, err error))

SetErrorHandler sets the error handler for route processing errors.

func (*Router) Use added in v0.2.0

func (r *Router) Use(mw ...Middleware)

Use adds middleware to the router. Middleware is applied in the order it is added.

type Sender

type Sender uint16
const (
	SenderLocal Sender = 0 + iota
	SenderPeer
)

type SequenceTracker added in v0.2.0

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

SequenceTracker helps maintain message ordering across reconnections. It is safe for concurrent use.

func NewSequenceTracker added in v0.2.0

func NewSequenceTracker(state *SessionState) *SequenceTracker

NewSequenceTracker creates a new sequence tracker from a session state.

func (*SequenceTracker) EncodeSequences added in v0.2.0

func (st *SequenceTracker) EncodeSequences() []byte

EncodeSequences encodes the sequence numbers for transmission.

func (*SequenceTracker) NextRecv added in v0.2.0

func (st *SequenceTracker) NextRecv() uint64

NextRecv returns the next expected receive sequence number.

func (*SequenceTracker) NextSend added in v0.2.0

func (st *SequenceTracker) NextSend() uint64

NextSend returns the next send sequence number.

func (*SequenceTracker) Sequences added in v0.2.0

func (st *SequenceTracker) Sequences() (send, recv uint64)

Sequences returns the current send and receive sequence numbers.

func (*SequenceTracker) ValidateRecv added in v0.2.0

func (st *SequenceTracker) ValidateRecv(seq uint64) error

ValidateRecv checks if a received sequence number is valid.

type Server

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

Server handles incoming connections and manages the handshake process.

func NewServer

func NewServer(
	addr string, handler HandlerFunc, opts ...ServerOptions,
) (*Server, error)

NewServer creates a new server with the given address and handler.

func (*Server) Close added in v0.2.0

func (s *Server) Close() error

Close gracefully shuts down the server by closing the underlying listener, causing Server.ListenAndServe to return. It is safe to call multiple times and concurrently.

func (*Server) ListenAndServe

func (s *Server) ListenAndServe() error

ListenAndServe starts the server and listens for incoming connections. It blocks until the listener is closed via Server.Close or an unrecoverable error occurs.

func (*Server) PublicKey

func (s *Server) PublicKey() PublicKey

PublicKey returns the server's public key.

func (*Server) SessionManager added in v0.2.0

func (s *Server) SessionManager() *SessionManager

SessionManager returns the server's session manager.

type ServerOptions

type ServerOptions func(*Server)

ServerOptions configures the server.

func ServeWithAlgorithm

func ServeWithAlgorithm(a attest.Algorithm) ServerOptions

ServeWithAlgorithm sets the cryptographic algorithm for identity.

func ServeWithName

func ServeWithName(name string) ServerOptions

ServeWithName sets the server's advertised name.

func ServeWithRatchetThreshold added in v0.2.0

func ServeWithRatchetThreshold(threshold uint64) ServerOptions

ServeWithRatchetThreshold sets the message threshold for DH ratchet rotation.

func ServeWithRemoteVerifier

func ServeWithRemoteVerifier(remote RemoteVerifier) ServerOptions

ServeWithRemoteVerifier sets a custom remote verifier function.

func ServeWithResumption added in v0.2.0

func ServeWithResumption(config ResumptionConfig) ServerOptions

ServeWithResumption configures session resumption settings.

func ServeWithResumptionEnabled added in v0.2.0

func ServeWithResumptionEnabled(enabled bool) ServerOptions

ServeWithResumptionEnabled enables or disables session resumption.

func ServeWithSessionTimeout added in v0.2.0

func ServeWithSessionTimeout(timeout time.Duration) ServerOptions

ServeWithSessionTimeout sets the maximum age for resumable sessions.

func ServeWithStorageOpts

func ServeWithStorageOpts(opts ...StorageOption) ServerOptions

ServeWithStorageOpts sets storage options.

func ServeWithTCP

func ServeWithTCP(opts ...ConnOption) ServerOptions

ServeWithTCP configures the server to use TCP connections.

func ServeWithUDP

func ServeWithUDP(opts ...ConnOption) ServerOptions

ServeWithUDP configures the server to use UDP/KCP connections.

type SessionInfo added in v0.2.0

type SessionInfo struct {
	CreatedAt    time.Time
	UpdatedAt    time.Time
	SessionID    string
	Phase        SessionPhase
	SendSequence uint64
	RecvSequence uint64
	IsInitiator  bool
	IsExpired    bool
}

SessionInfo contains summary information about a session.

type SessionManager added in v0.2.0

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

SessionManager handles persistence and resumption of session states. Sessions are identified by both session ID and the remote peer's public key.

The public-key → session-ID mapping is persisted in a dedicated BoltDB bucket so that it survives process restarts. An in-memory cache (sessionsByPubKey) is populated on first access via rebuildIndex (guarded by sync.Once) and kept in sync by RegisterSession / UnregisterSession.

func NewSessionManager added in v0.2.0

func NewSessionManager(storage *Storage, timeout time.Duration) *SessionManager

NewSessionManager creates a new session manager.

func (*SessionManager) CanResume added in v0.2.0

func (sm *SessionManager) CanResume(
	sessionID string,
) (bool, SessionPhase, error)

CanResume checks if a session can be resumed based on its state.

func (*SessionManager) CleanupExpiredSessions added in v0.2.0

func (sm *SessionManager) CleanupExpiredSessions() (int, error)

CleanupExpiredSessions removes all expired sessions and their pubkey index entries from storage. Session deletions are batched into a single transaction for efficiency; index entries are cleaned up afterwards.

func (*SessionManager) DeleteSession added in v0.2.0

func (sm *SessionManager) DeleteSession(sessionID string) error

DeleteSession removes a persisted session state and its pubkey index entry.

func (*SessionManager) GetSessionByPublicKey added in v0.2.0

func (sm *SessionManager) GetSessionByPublicKey(
	remotePublicKey []byte,
) (string, bool)

GetSessionByPublicKey retrieves a session ID by the remote peer's public key.

func (*SessionManager) GetSessionInfo added in v0.2.0

func (sm *SessionManager) GetSessionInfo(
	sessionID string,
) (*SessionInfo, error)

GetSessionInfo returns summary information about a session.

func (*SessionManager) HandshakeTracker added in v0.2.0

func (sm *SessionManager) HandshakeTracker() *HandshakeTracker

HandshakeTracker returns the handshake tracker for managing in-progress handshakes.

func (*SessionManager) ListActiveSessions added in v0.2.0

func (sm *SessionManager) ListActiveSessions() ([]string, error)

ListActiveSessions returns all non-expired session IDs.

func (*SessionManager) LoadSession added in v0.2.0

func (sm *SessionManager) LoadSession(sessionID string) (*SessionState, error)

LoadSession retrieves a persisted session state.

func (*SessionManager) LoadSessionByPublicKey added in v0.2.0

func (sm *SessionManager) LoadSessionByPublicKey(
	remotePublicKey []byte,
) (*SessionState, error)

LoadSessionByPublicKey retrieves a session state by the remote peer's public key.

func (*SessionManager) RegisterSession added in v0.2.0

func (sm *SessionManager) RegisterSession(
	sessionID string, remotePublicKey []byte,
)

RegisterSession associates a session ID with a remote public key. The mapping is persisted so it survives process restarts.

func (*SessionManager) SaveSession added in v0.2.0

func (sm *SessionManager) SaveSession(state *SessionState) error

SaveSession persists the session state for potential resumption.

CreatedAt is preserved across updates: if an existing record is found in the same transaction, its CreatedAt value is reused. This avoids a separate read transaction and eliminates the race between read and write.

func (*SessionManager) SaveTransportState added in v0.2.0

func (sm *SessionManager) SaveTransportState(t *Transport) error

SaveTransportState extracts and saves the current state from a transport.

func (*SessionManager) Stats added in v0.2.0

func (sm *SessionManager) Stats() (*SessionStats, error)

Stats returns statistics about the stored sessions.

func (*SessionManager) UnregisterSession added in v0.2.0

func (sm *SessionManager) UnregisterSession(remotePublicKey []byte)

UnregisterSession removes the association between a session ID and public key.

func (*SessionManager) UpdateSessionPhase added in v0.2.0

func (sm *SessionManager) UpdateSessionPhase(
	sessionID string, phase SessionPhase,
) error

UpdateSessionPhase atomically updates the phase of a persisted session.

The read-modify-write is performed inside a single BoltDB read-write transaction so concurrent callers cannot overwrite each other's changes.

func (*SessionManager) UpdateSessionPhaseByPublicKey added in v0.2.0

func (sm *SessionManager) UpdateSessionPhaseByPublicKey(
	remotePublicKey []byte, phase SessionPhase,
) error

UpdateSessionPhaseByPublicKey updates the phase of a session by public key.

func (*SessionManager) UpdateSessionSequences added in v0.2.0

func (sm *SessionManager) UpdateSessionSequences(
	sessionID string, sendSeq, recvSeq uint64,
) error

UpdateSessionSequences atomically updates the sequence numbers of a persisted session.

The read-modify-write is performed inside a single BoltDB read-write transaction so concurrent callers cannot overwrite each other's changes.

type SessionPhase added in v0.2.0

type SessionPhase int

SessionPhase represents the current phase of a session.

const (
	PhaseInvalid SessionPhase = iota
	PhaseIntroduction
	PhaseHandshakeRequested
	PhaseHandshakeAccepted
	PhaseChallengeSent
	PhaseChallengeVerified
	PhaseRatchetInitialized
	PhaseEstablished
	PhaseClosed
)

func PhaseFromProto added in v0.2.0

func PhaseFromProto(p pb.SessionPhase) SessionPhase

PhaseFromProto converts a protobuf SessionPhase enum to the local type.

func (SessionPhase) String added in v0.2.0

func (p SessionPhase) String() string

String returns the string representation of the session phase.

func (SessionPhase) ToProto added in v0.2.0

func (p SessionPhase) ToProto() pb.SessionPhase

ToProto converts the SessionPhase to its protobuf enum representation.

type SessionResumer added in v0.2.0

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

SessionResumer handles session resumption for both client and server.

func NewSessionResumer added in v0.2.0

func NewSessionResumer(
	storage *Storage,
	sessionManager *SessionManager,
	attester attest.Attester,
	maxAge time.Duration,
) *SessionResumer

NewSessionResumer creates a new session resumer.

func (*SessionResumer) CanResume added in v0.2.0

func (sr *SessionResumer) CanResume(
	remotePublicKey []byte,
) (bool, *SessionState, error)

CanResume checks if a session can be resumed with the given peer.

func (*SessionResumer) HandleResumption added in v0.2.0

func (sr *SessionResumer) HandleResumption(
	conn Conn, req *pb.ReconnectRequest,
) (*Transport, error)

HandleResumption handles an incoming resumption request as a server.

func (*SessionResumer) InitiateResumption added in v0.2.0

func (sr *SessionResumer) InitiateResumption(
	conn Conn, state *SessionState,
) (*Transport, error)

InitiateResumption starts the resumption process as a client.

type SessionState added in v0.2.0

type SessionState struct {
	SessionID       string
	SharedSecret    []byte
	LocalSalt       []byte
	RemoteSalt      []byte
	RatchetState    []byte
	RemotePublicKey []byte
	Phase           SessionPhase
	SendSequence    uint64
	RecvSequence    uint64
	IsInitiator     bool
}

SessionState holds the current state of a session for potential resumption.

type SessionStats added in v0.2.0

type SessionStats struct {
	ByPhase         map[SessionPhase]int
	TotalSessions   int
	ActiveSessions  int
	ExpiredSessions int
}

SessionStats returns statistics about stored sessions.

type Storage

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

func OpenStorage

func OpenStorage(opts ...StorageOption) (*Storage, error)

func (*Storage) AddChatEntry

func (s *Storage) AddChatEntry(
	sessionID string, payload []byte, ts time.Time, sender Sender,
) error

func (*Storage) Close

func (s *Storage) Close() error

func (*Storage) DeletePeer added in v0.2.0

func (s *Storage) DeletePeer(claim []byte) error

DeletePeer removes a peer from storage by its public key claim.

func (*Storage) FindPeer

func (s *Storage) FindPeer(claim []byte) (*Peer, error)

func (*Storage) GetChatHistory

func (s *Storage) GetChatHistory(sessionID string) ([]ChatEntry, error)

GetChatHistory returns decrypted chat entries stored under a bucket specific to the session ID. The bucket name used is "chat_<sessionID>" and keys are expected to be 14 bytes total, composed of:

  • 8 bytes: UnixNano timestamp (big-endian)
  • 2 bytes: sender ID (big-endian; 0 means local user, 1 means remote user)
  • 4 bytes: random suffix to avoid collision

func (*Storage) ListPeers added in v0.2.0

func (s *Storage) ListPeers() ([]*Peer, error)

ListPeers returns all non-expired peers stored in the database. Expired peers are silently removed during iteration.

func (*Storage) ListSessions added in v0.2.0

func (s *Storage) ListSessions() ([]string, error)

AddChatEntry stores a chat message for the given session ID. The message is stored in a bucket named "chat_<sessionID>" and the key begins with an 8-byte big-endian uint64 representation of the timestamp's UnixNano value. 2 bytes are used for the sender identity. Currently, 0 means local user, 1 means remote user. To avoid collisions when two messages have the same timestamp, a 4-byte random suffix is appended to the key to avoid collision. The session ID is used as the bucket name, which scopes entries per session. If the provided timestamp is zero, the current time is used. ListSessions returns a list of session IDs that have chat history stored. Session IDs are extracted from bucket names with the "chat_" prefix.

func (*Storage) StorePeer

func (s *Storage) StorePeer(peer *Peer) error

func (*Storage) UpdatePeerLastSeen added in v0.2.0

func (s *Storage) UpdatePeerLastSeen(claim []byte, t time.Time) error

UpdatePeerLastSeen updates the LastSeen timestamp for a peer identified by its public key claim. If the peer does not exist, the call is a no-op and returns nil.

type StorageOption

type StorageOption func(*Storage)

func StorageWithAlgorithm

func StorageWithAlgorithm(algorithm attest.Algorithm) StorageOption

func StorageWithDBPath

func StorageWithDBPath(path string) StorageOption

func StorageWithExpiryDuration

func StorageWithExpiryDuration(duration time.Duration) StorageOption

func StorageWithNoPassphrase

func StorageWithNoPassphrase() StorageOption

func StorageWithPassphraseHandler

func StorageWithPassphraseHandler(fn PassphraseHandler) StorageOption

type Transferable

type Transferable interface {
	proto.Message
}

Transferable is the interface for messages that can be sent over a transport.

type Transport

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

Transport handles encrypted message exchange with route-based dispatch.

func ResumeOrDial added in v0.2.0

func ResumeOrDial(
	dialer *Dialer,
	remotePublicKey []byte,
	sm *SessionManager,
) (*Transport, bool, error)

ResumeOrDial attempts to resume an existing session, falling back to fresh dial.

func (*Transport) Close

func (t *Transport) Close() error

Close closes the transport connection.

func (*Transport) IsEstablished added in v0.2.0

func (t *Transport) IsEstablished() bool

IsEstablished returns true if the session is fully established.

func (*Transport) Phase added in v0.2.0

func (t *Transport) Phase() SessionPhase

Phase returns the current session phase.

func (*Transport) Receive

func (t *Transport) Receive(dst Transferable) (*Metadata, error)

Receive reads and decrypts the next message from the connection. It returns the metadata, the route of the received message, and any error.

func (*Transport) ReceiveExpecting added in v0.2.0

func (t *Transport) ReceiveExpecting(
	dst Transferable, expected Route,
) (*Metadata, error)

ReceiveExpecting reads a message and validates that it matches the expected route.

func (*Transport) ReceiveWithRoute added in v0.2.0

func (t *Transport) ReceiveWithRoute(
	dst Transferable,
) (*Metadata, Route, error)

ReceiveWithRoute reads and decrypts the next message, returning both the metadata and the route of the received message.

func (*Transport) RemotePublicKey added in v0.2.0

func (t *Transport) RemotePublicKey() []byte

RemotePublicKey returns the remote peer's public key.

func (*Transport) Send

func (t *Transport) Send(message Transferable, route Route) (*Metadata, error)

Send encrypts and sends a message with the specified route.

func (*Transport) SessionID

func (t *Transport) SessionID() string

SessionID returns the unique identifier for this session.

func (*Transport) SetInitiator added in v0.2.0

func (t *Transport) SetInitiator(isInitiator bool)

SetInitiator marks whether this transport is the initiator.

func (*Transport) SetPhase added in v0.2.0

func (t *Transport) SetPhase(phase SessionPhase)

SetPhase updates the session phase.

func (*Transport) SetRemotePublicKey added in v0.2.0

func (t *Transport) SetRemotePublicKey(key []byte)

SetRemotePublicKey sets the remote peer's public key for session tracking.

func (*Transport) SetSecrets added in v0.2.0

func (t *Transport) SetSecrets(sharedSecret, localSalt, remoteSalt []byte)

SetSecrets stores the cryptographic secrets for potential session resumption.

func (*Transport) State added in v0.2.0

func (t *Transport) State() *SessionState

State returns the current session state for potential resumption.

It includes the serialized Double Ratchet state when available so that an established session can be resumed without re-handshaking.

func (*Transport) Store

func (t *Transport) Store() *Storage

Store returns the storage associated with this transport.

Directories

Path Synopsis
cmd
daemon command
Package main implements a daemon wrapper for the kamune library.
Package main implements a daemon wrapper for the kamune library.
internal
pkg

Jump to

Keyboard shortcuts

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