Skip to main content

Module handshake

Module handshake 

Source
Expand description

macula 12’s post-quantum connection handshake, as macula_handshake and macula-go build and check it: the opener, challenge, CONNECT, HELLO and status frames (D16, D22), as CBOR bytes without the length prefix.

The client opens with an opener. The station answers with a challenge: its carried identity key, its TLS binding and status statement, and a fresh nonce. The client checks the challenge against the node_id it dialed and the leaf it received, before it signs anything, and answers with CONNECT: its identity and CONNECT keys, the CONNECT binding and status statement, and a proof by the CONNECT key. The station checks CONNECT, the puzzle before any signature, and answers with HELLO. Status frames renew a peer’s statement on the open connection.

Every frame decodes under the decoding rule and must hold exactly the keys of its type, each of its type and length. Close reasons are local: a refusing station sends only a HELLO with one coarse refusal code.

Structs§

Client
What a station knows of an accepted client.
ClientSession
What a client brings to a handshake: its profile, the node_id it dialed, the leaf DER it received in this TLS handshake, its carried identity key, its CONNECT key with binding and status statement, its capability bits, the time in milliseconds, and the realm membership endorsement CONNECT carries, empty for a node that holds none.
Peer
What a connection checks a peer’s status frames against: the profile, the identity key and binding the handshake verified, and the time in milliseconds.
Station
What a client knows of the station once it has checked the challenge.
StationMaterial
What a station precomputes for its challenges: its carried identity key, and the TLS binding and status statement for the leaf it presents.
StationSession
What a station brings to a CONNECT check: its profile, the challenge bytes it sent, the leaf DER this connection presented, its puzzle difficulty and mode, its capability bits, and the time in milliseconds.

Enums§

HandshakeError
The handshake’s close reasons, named as macula names them. A binding or status statement that fails its check closes with its BindingError.
PuzzleMode
How a station treats a client’s node_id puzzle.
PuzzleResult
What a station found of a client’s puzzle.
RefusalCode
The one coarse reason a refusing HELLO carries.

Constants§

VERSION
The handshake’s frame version: 4, as macula 12’s. A peer on another version hears unsupported_version.

Functions§

accept_connect
Checks a CONNECT, and returns the verdict with the HELLO to send. It checks, in macula’s order: the frame, the carried keys and the proof’s length, that each key serves one purpose, the puzzle on the derived node_id before any signature, the CONNECT binding and status statement, and the proof against the challenge this station sent and the leaf it presented. A refusal is the local close reason, and the HELLO refuses with one coarse code.
answer_challenge
Checks a challenge and, when every check passes, returns the CONNECT to send. It checks, in macula’s order: the frame, the profile, the station’s carried key, that each key in view serves one purpose, the station’s node_id against the one dialed, the TLS binding against the leaf received, and the status statement. It signs nothing before all of them pass.
challenge
A station’s challenge, with a fresh nonce. The station keeps the bytes it sends, for the proof check.
opener
The client’s first frame on the control stream. It carries nothing that relates to identity.
read_hello
The client’s reading of HELLO: the station’s capability bits, or HandshakeError::Refused with its refusal code.
read_opener
The station’s check of the first frame.
read_status
Checks a peer’s status frame, and returns when its statement expires.
status_frame
A status frame carrying a fresh status statement, sent at every reissue.