Skip to content

Handshake Extensions

HandshakeExtensions provides the client-side X25519 handshake used to establish an encrypted TransportSession. For reconnect flows, see ResumeExtensions.

Source mapping

  • src/Nalix.SDK/Transport/Extensions/HandshakeExtensions.cs
  • src/Nalix.Codec/DataFrames/SignalFrames/Handshake.cs
  • src/Nalix.Codec/Security/HandshakeX25519.cs

Implementation Flow

sequenceDiagram
    participant App as Client App
    participant S as TransportSession
    participant Server as Server Runtime

    App->>S: HandshakeAsync(ct)
    S->>S: require IsConnected
    S->>S: generate X25519 key pair + client nonce
    S->>Server: CLIENT_HELLO via RequestAsync()
    Server-->>S: SERVER_HELLO or ERROR
    S->>S: Validate SERVER_HELLO
    S->>S: require Options.ServerPublicKey
    S->>S: derive EE + static shared secrets
    S->>S: verify server proof
    S->>S: set Secret, Algorithm (before CLIENT_FINISH)
    S->>Server: CLIENT_FINISH via RequestAsync()
    Server-->>S: SERVER_FINISH or ERROR
    S->>S: Validate SERVER_FINISH + proof
    S->>S: set EncryptionEnabled, SessionToken (after SERVER_FINISH)

Role and Design

This helper performs the full client-side handshake sequence after a transport is connected.

  • Ephemeral key exchange: Generates a fresh X25519 key pair for each handshake.
  • Proof verification: Validates the server's response before deriving session material.
  • Session activation: Updates TransportOptions.Secret and TransportOptions.Algorithm before CLIENT_FINISH, then sets TransportOptions.EncryptionEnabled and TransportOptions.SessionToken after validating SERVER_FINISH.

API Reference

Method Description
HandshakeAsync Performs the client-side X25519 handshake on a connected TransportSession.

Basic usage

// 1. Configure the expected server public key (Identity Pinning)
client.Options.ServerPublicKey = "your-server-public-key-hex";

// 2. Connect and perform authenticated handshake
await client.ConnectAsync();
await client.HandshakeAsync();

Important notes

  • Call this only after the session is connected.
  • Identity Pinning is Mandatory: The client MUST provide the expected server public key via TransportOptions.ServerPublicKey. Anonymous handshakes are strictly forbidden to prevent MitM attacks.
  • On success, the session switches to CipherSuiteType.Chacha20Poly1305.
  • HandshakeAsync(...) uses RequestAsync<Handshake>(...) for both CLIENT_HELLO and CLIENT_FINISH, filtering for the expected response stages.