Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
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 ¶
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 ¶
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) Initiate ¶
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 ¶
MessageIndex returns the noise handshake message index, which equals the wire counter of the most recently sent or received message.
func (*Machine) ProcessPacket ¶
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 ¶
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.