handshake

package
v1.11.0 Latest Latest
Warning

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

Go to latest
Published: Jul 23, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInitiateOnResponder     = errors.New("initiate called on responder")
	ErrInitiateAlreadyCalled   = errors.New("initiate already called")
	ErrInitiateNotCalled       = errors.New("initiate must be called before ProcessPacket for initiators")
	ErrPacketTooShort          = errors.New("packet too short")
	ErrPublicKeyMismatch       = errors.New("public key mismatch between certificate and handshake")
	ErrIncompleteHandshake     = errors.New("handshake completed without receiving required content")
	ErrMachineFailed           = errors.New("handshake machine has failed")
	ErrUnknownSubtype          = errors.New("unknown handshake subtype")
	ErrMissingContent          = errors.New("expected handshake content but message was empty")
	ErrUnexpectedContent       = errors.New("received unexpected handshake content")
	ErrInvalidRemoteIndex      = errors.New("peer sent an invalid index in handshake payload")
	ErrIndexAllocation         = errors.New("failed to allocate local index")
	ErrNoCredential            = errors.New("no handshake credential available for cert version")
	ErrAsymmetricCipherKeys    = errors.New("noise produced only one cipher key")
	ErrMultiMessageUnsupported = errors.New("multi-message handshake patterns are not yet supported by the manager")
	ErrSubtypeMismatch         = errors.New("packet subtype does not match handshake machine subtype")
)

Functions

func MarshalPayload

func MarshalPayload(out []byte, p Payload) []byte

MarshalPayload encodes a handshake payload in protobuf wire format compatible with NebulaHandshake{Details: NebulaHandshakeDetails{...}}. Returns out (which may be nil), with the marshalled Payload appended to it.

Types

type CertVerifier

type CertVerifier func(cert.Certificate) (*cert.CachedCertificate, error)

CertVerifier is called by the Machine after reconstructing the peer's certificate from the handshake. The verifier performs all validation (CA trust, expiry, policy checks, allow lists).

type Credential

type Credential struct {
	Cert  cert.Certificate // the certificate
	Bytes []byte           // pre-marshaled certificate bytes
	// contains filtered or unexported fields
}

Credential holds everything needed to participate in a handshake at a given cert version. Version and Curve are read from Cert; the public half of the static keypair likewise comes from Cert.PublicKey().

func NewCredential

func NewCredential(
	c cert.Certificate,
	hsBytes []byte,
	privateKey []byte,
	cipherSuite noise.CipherSuite,
) *Credential

NewCredential creates a Credential with all material needed for handshake participation. The cipherSuite should be pre-built by the caller with the appropriate DH function, cipher, and hash.

type GetCredentialFunc

type GetCredentialFunc func(v cert.Version) *Credential

GetCredentialFunc returns the handshake credential for the given version, or nil if that version is not available.

Implementations must return credentials drawn from a snapshot stable for the lifetime of any single Machine. The Machine may call this multiple times during a handshake (e.g. when negotiating to the peer's version) and assumes the underlying static keypair is consistent across calls.

type IndexAllocator

type IndexAllocator func() (uint32, error)

IndexAllocator is called by the Machine to allocate a local index for the handshake. It is called at most once, when the first outgoing message that carries a payload is built.

Implementations MUST NOT return 0. Zero is reserved as a sentinel meaning "no index assigned" on the wire and in the payload-presence checks. If an allocator ever returned 0, a legitimate handshake's payload could be indistinguishable from an empty one and would be rejected.

type Machine

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

Machine drives a Noise handshake through N messages. It handles Noise protocol operations, certificate reconstruction, and payload encoding. Certificate validation is delegated to the caller via CertVerifier.

A Machine is not safe for concurrent use. The caller must ensure that Initiate and ProcessPacket are not called concurrently.

Error contract: when ProcessPacket or Initiate returns an error, callers must check Failed() to decide what to do next. If Failed() is false the underlying noise state was not advanced (the packet was rejected before ReadMessage took effect, or the rejection is non-fatal like a stale retransmit) and the Machine can accept another packet. If Failed() is true the Machine is unrecoverable and the caller must abandon it.

func NewMachine

func NewMachine(
	version cert.Version,
	getCred GetCredentialFunc,
	verifier CertVerifier,
	allocIndex IndexAllocator,
	initiator bool,
	subtype header.MessageSubType,
) (*Machine, error)

NewMachine creates a handshake state machine. The subtype determines both the noise pattern and the per-message content layout. The credential for `version` is fetched via getCred and used to seed the noise.HandshakeState. IndexAllocator is called lazily when the first outgoing payload is built.

func (*Machine) Failed

func (m *Machine) Failed() bool

Failed returns true if the Machine is in an unrecoverable state.

func (*Machine) Initiate

func (m *Machine) Initiate(out []byte) ([]byte, error)

Initiate produces the first handshake message. Only valid for initiators, and must be called exactly once before ProcessPacket.

out is a destination buffer the message is appended to and returned. Pass nil to allocate fresh, or pass a re-used buffer sliced to length 0 (e.g. buf[:0]) with sufficient capacity to avoid allocation.

An error return may not indicate a fatal condition, check Failed() to determine if the Machine can still be used.

func (*Machine) MessageIndex

func (m *Machine) MessageIndex() int

MessageIndex returns the noise handshake message index, which equals the wire counter of the most recently sent or received message.

func (*Machine) ProcessPacket

func (m *Machine) ProcessPacket(out, packet []byte) ([]byte, *Result, error)

ProcessPacket handles an incoming handshake message. It advances the Noise state, validates the peer certificate via the verifier, and optionally produces a response.

out is a destination buffer the response is appended to and returned. Pass nil to allocate fresh, or pass a re-used buffer sliced to length 0 (e.g. buf[:0]) with sufficient capacity to avoid allocation. The returned slice is nil when no outgoing message is produced (handshake complete on this side, or final message of a multi-message pattern).

Returns a non-nil Result when the handshake is complete. An error return may not indicate a fatal condition, check Failed() to determine if the Machine can still be used.

func (*Machine) Subtype

func (m *Machine) Subtype() header.MessageSubType

Subtype returns the handshake subtype this Machine was built for.

type Payload

type Payload struct {
	Cert           []byte
	InitiatorIndex uint32
	ResponderIndex uint32
	Time           uint64
	CertVersion    uint32
}

Payload represents the decoded fields of a handshake message. Wire format is protobuf-compatible with NebulaHandshake{Details: NebulaHandshakeDetails{...}}.

func UnmarshalPayload

func UnmarshalPayload(b []byte) (Payload, error)

UnmarshalPayload decodes a protobuf-encoded NebulaHandshake message.

type Result

type Result struct {
	EKey          *noise.CipherState
	DKey          *noise.CipherState
	Cipher        noise.CipherFunc // identifies which post-handshake CipherState the data plane should wrap EKey/DKey in
	MyCert        cert.Certificate
	RemoteCert    *cert.CachedCertificate
	RemoteIndex   uint32
	LocalIndex    uint32
	HandshakeTime uint64
	MessageIndex  uint64 // number of messages exchanged during the handshake
	Initiator     bool
}

Result contains the results of a successful handshake. Returned by ProcessPacket when the handshake is complete.

Jump to

Keyboard shortcuts

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