ddn.net.ssh.kexinit

SSH_MSG_KEXINIT construction, parsing, and algorithm negotiation (RFC 4253 section 7.1, RFC 8308, strict KEX).

The client appends the RFC 8308 ext-info-c indicator and the strict-KEX marker to its key-exchange list; neither is ever selectable as the actual algorithm. Negotiation picks the first client preference the server also lists, skipping indicator names, and fails closed when any category has no match.

Types 3

Pseudo-algorithm indicators carried inside kex_algorithms.

extInfoClient = "ext-info-c"RFC 8308: client wants to receive SSH_MSG_EXT_INFO
extInfoServer = "ext-info-s"RFC 8308: server is prepared to receive SSH_MSG_EXT_INFO
strictServer = "kex-strict-c-v00@openssh.com"Strict KEX: client asks the server to enforce strict behaviour
strictClient = "kex-strict-s-v00@openssh.com"Strict KEX: server agrees to enforce strict behaviour

A parsed SSH_MSG_KEXINIT.

rawPayload preserves the exact payload bytes (including the message-number byte) for the exchange-hash transcript.

Fields
ubyte[16] cookie
string[] kex
string[] hostKey
string[] cipherC2S
string[] cipherS2C
string[] macC2S
string[] macS2C
string[] compressionC2S
string[] compressionS2C
string[] languagesC2S
string[] languagesS2C
bool firstKexPacketFollows
const(ubyte)[] rawPayload

Outcome of algorithm negotiation plus extension signalling.

Fields
bool strictKex
bool peerExpectsExtInfoFromUs

Functions 13

fnbool isCurve25519Kex(scope const(char)[] name) pure nothrow @safe @nogcWhether a KEX name selects the curve25519-sha256 method.
fnubyte[] buildKexInitPayload(const SshAlgorithmPreferences prefs, in ubyte[16] cookie, bool strictKex = true) @safeBuilds the client's KEXINIT payload.
fnSshKexInit parseKexInitPayload(const(ubyte)[] payload) @safeParses a KEXINIT payload.
fnSshNegotiationResult negotiate(const SshKexInit client, const SshKexInit server) @safeNegotiates algorithms from the client's and server's KEXINIT.
fnbool serverAdvertisesStrictKex(scope const SshKexInit server) @safe pure nothrowWhether a server KEXINIT advertises the strict-KEX server marker.
fnstring negotiateKexName(scope const SshKexInit client, scope const SshKexInit server) @safeNegotiates only the key-exchange name from both KEXINITs.
fnstring firstKexAlgorithm(scope const SshKexInit server) @safe pure nothrowReturns the server's actual guessed key exchange.
fnstring firstHostKeyAlgorithm(scope const SshKexInit server) @safe pure nothrowReturns the server host-key algorithm covered by a speculative first key-exchange packet.
private fnbool cipherNeedsMac(string cipher) @safe pure nothrow
private fnbool isIndicator(string name) @safe pure nothrow
private fnbool containsName(scope const string[] list, string name) @safe pure nothrow
private fnstring matchSkippingIndicators(scope const string[] client, scope const string[] server) @safe
private fnSshKexInit parseRoundTrip(const SshAlgorithmPreferences prefs, bool strictKex = true) @safe

Variables 1

enumvarCURVE25519_SHA256_LIBSSH = "curve25519-sha256@libssh.org"

Compatibility alias selecting the same key exchange as curve25519-sha256 (OpenSSH and libssh wire name).