MatterEx.CASE (matter_ex v0.4.0)

Copy Markdown View Source

CASE (Certificate Authenticated Session Establishment) state machine.

Pure functional state machine — no GenServer. Caller threads state through. Implements both device (responder) and initiator roles using the Sigma protocol.

Device flow

device = CASE.new_device(noc: noc, private_key: priv, ipk: ipk,
                         node_id: 1, fabric_id: 1, local_session_id: 1)
{:reply, :case_sigma2, sigma2, device} = CASE.handle(device, :case_sigma1, sigma1)
{:established, :status_report, sr, session, device} = CASE.handle(device, :case_sigma3, sigma3)

Initiator flow

init = CASE.new_initiator(noc: noc, private_key: priv, ipk: ipk,
                          node_id: 2, fabric_id: 1, local_session_id: 2,
                          peer_node_id: 1, peer_fabric_id: 1)
{:send, :case_sigma1, sigma1, init} = CASE.initiate(init)
{:send, :case_sigma3, sigma3, init} = CASE.handle(init, :case_sigma2, sigma2)
{:established, session, init} = CASE.handle(init, :status_report, sr)

Summary

Functions

Initiator starts the CASE flow by sending Sigma1.

Create a new device (responder) CASE state.

Create a new initiator CASE state.

Types

t()

@type t() :: %MatterEx.CASE{
  eph_priv: term(),
  eph_pub: term(),
  fabric_id: term(),
  fabric_index: term(),
  icac: term(),
  ipk: term(),
  local_session_id: term(),
  noc: term(),
  node_id: term(),
  peer_eph_pub: term(),
  peer_fabric_id: term(),
  peer_node_id: term(),
  peer_session_id: term(),
  private_key: term(),
  role: term(),
  root_public_key: term(),
  shared_secret: term(),
  skip_dest_check: term(),
  state: term(),
  transcript: term()
}

Functions

handle(cs, arg2, payload)

@spec handle(t(), atom(), binary()) ::
  {:reply, atom(), binary(), t()}
  | {:send, atom(), binary(), t()}
  | {:established, atom(), binary(), MatterEx.Session.t(), t()}
  | {:established, MatterEx.Session.t(), t()}
  | {:error, atom()}

initiate(cs)

@spec initiate(t()) :: {:send, :case_sigma1, binary(), t()}

Initiator starts the CASE flow by sending Sigma1.

new_device(opts)

@spec new_device(keyword()) :: t()

Create a new device (responder) CASE state.

Required opts: :noc, :private_key, :ipk, :node_id, :fabric_id, :local_session_id Optional: :icac, :fabric_index, :root_public_key

new_initiator(opts)

@spec new_initiator(keyword()) :: t()

Create a new initiator CASE state.

Required opts: :noc, :private_key, :ipk, :node_id, :fabric_id,

           `:local_session_id`, `:peer_node_id`, `:peer_fabric_id`

Optional: :icac, :root_public_key