distribute/handshake/state

Types

Interface for crypto providers in the handshake state machine.

This type allows injecting different crypto implementations:

  • provider_stub for testing (no real crypto)
  • Custom implementations for production

Example

// Use stub for testing
let test_provider = stub_crypto_provider()

// Use custom provider
let custom_provider = CryptoProvider(
  init: my_init,
  start_key_exchange: my_start_ke,
  handle_key_exchange: my_handle_ke,
)
pub type CryptoProvider {
  CryptoProvider(
    init: fn() -> provider.ProviderState,
    start_key_exchange: fn(provider.ProviderState, BitArray) -> #(
      BitArray,
      provider.ProviderState,
    ),
    handle_key_exchange: fn(provider.ProviderState, BitArray) -> #(
      option.Option(BitArray),
      provider.ProviderState,
      option.Option(provider.SecureContext),
    ),
  )
}

Constructors

State of the handshake state machine.

The handshake progresses through several states depending on the role:

  • InitiatorState: Active state for the connection initiator
  • ResponderState: Active state for the connection responder
  • Established: Terminal success state with secure context
  • Failed: Terminal error state with reason
pub type HandshakeState {
  InitiatorState(
    state: provider.ProviderState,
    local_hello: handshake.Hello,
    negotiated: option.Option(#(String, Int)),
    secure: option.Option(provider.SecureContext),
    waiting: option.Option(String),
    retries: Int,
    pending: option.Option(BitArray),
    crypto: CryptoProvider,
  )
  ResponderState(
    state: provider.ProviderState,
    negotiated: option.Option(#(String, Int)),
    secure: option.Option(provider.SecureContext),
    waiting: option.Option(String),
    retries: Int,
    pending: option.Option(BitArray),
    crypto: CryptoProvider,
  )
  Established(#(String, provider.SecureContext))
  Failed(String)
}

Constructors

Result of processing a handshake message.

  • Sent: Produced an outgoing message and new state
  • Received: Processed incoming message, optionally with reply
pub type Outcome {
  Sent(BitArray, HandshakeState)
  Received(option.Option(BitArray), HandshakeState)
}

Constructors

Handshake state machine for secure connection establishment.

This module implements the state transitions for both initiator and responder roles in a cryptographic handshake. The state machine handles:

  • Hello message exchange with capabilities
  • Protocol/version negotiation
  • Key exchange for establishing secure contexts
  • Retry logic for transient failures Role in the handshake - determines which state machine path to follow.
pub type Role {
  Initiator
  Responder
}

Constructors

  • Initiator
  • Responder

Values

pub fn handshake_on_timeout(
  state: HandshakeState,
) -> Result(Outcome, String)

Handle a timeout during handshake.

Either retransmits the pending message if retries remain, or transitions to Failed state if max retries exceeded.

pub fn initiator_handle_message(
  state: HandshakeState,
  data: BitArray,
) -> Result(Outcome, String)

Handle an incoming message as the initiator.

Processes Capabilities, Reject, or KeyExchange messages and returns the appropriate Outcome with optional outgoing message and new state.

pub fn initiator_start(
  local: handshake.Hello,
  crypto: CryptoProvider,
) -> #(BitArray, HandshakeState)

Start the handshake as initiator.

Produces the initial Hello message to send to the responder and returns the new initiator state.

Arguments

  • local - Local node’s Hello message with capabilities
  • crypto - Crypto provider to use for key exchange

Example

let crypto = stub_crypto_provider()  // Use real provider in production!
let hello = handshake.Hello(node_id: "node1", capabilities: [...])
let #(msg, state) = initiator_start(hello, crypto)
pub fn initiator_start_with_stub(
  local: handshake.Hello,
) -> #(BitArray, HandshakeState)

Deprecated: Use initiator_start(local, crypto) with explicit provider

Start the handshake as initiator using the default stub provider.

Deprecated: Use initiator_start(local, crypto) instead. This function exists for backward compatibility.

Warning

Uses provider_stub which provides NO actual security.

pub fn responder_handle_message(
  state: HandshakeState,
  data: BitArray,
) -> Result(Outcome, String)

Handle an incoming message as the responder.

Processes Hello, Accept, or KeyExchange messages and returns the appropriate Outcome with optional outgoing message and new state.

pub fn responder_init(crypto: CryptoProvider) -> HandshakeState

Initialize the responder state.

Creates a fresh responder state ready to receive a Hello message from the initiator.

Arguments

  • crypto - Crypto provider to use for key exchange

Example

let crypto = stub_crypto_provider()  // Use real provider in production!
let state = responder_init(crypto)
pub fn responder_init_with_stub() -> HandshakeState

Deprecated: Use responder_init(crypto) with explicit provider

Initialize the responder state using the default stub provider.

Deprecated: Use responder_init(crypto) instead. This function exists for backward compatibility.

Warning

Uses provider_stub which provides NO actual security.

pub fn stub_crypto_provider() -> CryptoProvider

Default stub crypto provider (insecure, for testing only).

Returns a CryptoProvider that wraps provider_stub, providing passthrough encryption (no actual security).

Warning

Do NOT use in production. This provider performs no actual cryptographic operations.

Search Document