Repository navigation
fix(security): verify the server host key presented on re-key #336
Description
Problem
OpenSSH 10.3p1 verifies the host key on every key exchange, re-keys included: kex_verify_host_key (kex.c:1189) is called from kexgen.c:167 and kexgexc.c:169. verify_host_key (sshconnect.c) skips the check only when the key equals previous_host_key (sshconnect.c:1497, cached at 1564-1565). A different key on re-key goes through known_hosts, KnownHostsCommand, RevokedHostKeys and CA rules again.
russh 0.64.1 calls Handler::check_server_key only on the initial exchange (src/client/mod.rs around 2005-2021, the else branch of if session.common.encrypted.is_some()). On a re-key it verifies the exchange signature with the presented key (src/client/kex.rs:337) but never passes that key or certificate to the handler. bssh's handler (src/ssh/tokio_client/connection.rs:3744) never sees it, so the re-key host key is accepted unchecked.
Severity
Low: a re-key runs inside the encrypted transport, so a network attacker cannot inject a key without the session keys. The gap matters for a server that changes or loses its key mid-session, and for parity with OpenSSH policy (RevokedHostKeys, the host-key type match added in #333).
Blocked on upstream
bssh consumes only released upstream russh, with no fork (dependency boundary in docs/openssh-compatibility-status.md). russh must first either call check_server_key (or a new re-key callback) on re-key, or expose the re-key host key to the client. #327 is blocked for the same handler-visibility reason (russh PR #794).
Acceptance Criteria
- A released upstream russh version exposes the re-key host key or certificate to the client handler, and that version is recorded in
docs/openssh-compatibility-status.md. - bssh accepts a re-key whose host key equals the key verified at connection start without re-running verification, and runs the full verification (the
check_server_keypath, including certificates,RevokedHostKeysand the negotiated-algorithm type match) when the key differs, failing the connection on rejection. - A test against a scripted or in-process server that changes its host key on re-key fails before the change and passes after.
- Until upstream lands,
docs/openssh-compatibility-status.mdlists this gap as its own entry (today it is only a sentence in the host-certificate paragraph).
Activity