From 6ab629be5e31660579425a738ba8870beb5b7404 Mon Sep 17 00:00:00 2001 From: Kaleb Elwert Date: Mon, 19 Sep 2016 11:57:51 -0700 Subject: [PATCH] ssh: properly handle wrong guess for FirstKexFollows in server In the initial key exchange, a client has the option of sending a guessed key exchange packet. This guess is considered wrong (RFC 4253 Section 7) if "the kex algorithm and/or the host key algorithm is guessed wrong (server and client have different preferred algorithm), or if any of the other algorithms cannot be agreed upon...". The library should be checking the first algorithm in the supported algorithms, not the agreed algorithm. It also needs to check both the kex algorithm and the host key algorithm. Fixes golang/go#16962 Change-Id: I6b62b1f5b39731326280571d373635085135a2a1 Reviewed-on: https://go-review.googlesource.com/28750 Reviewed-by: Han-Wen Nienhuys Run-TryBot: Han-Wen Nienhuys TryBot-Result: Gobot Gobot --- ssh/handshake.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ssh/handshake.go b/ssh/handshake.go index ae26191..37d42e4 100644 --- a/ssh/handshake.go +++ b/ssh/handshake.go @@ -371,7 +371,16 @@ func (t *handshakeTransport) enterKeyExchangeLocked(otherInitPacket []byte) erro } // We don't send FirstKexFollows, but we handle receiving it. - if otherInit.FirstKexFollows && algs.kex != otherInit.KexAlgos[0] { + // + // RFC 4253 section 7 defines the kex and the agreement method for + // first_kex_packet_follows. It states that the guessed packet + // should be ignored if the "kex algorithm and/or the host + // key algorithm is guessed wrong (server and client have + // different preferred algorithm), or if any of the other + // algorithms cannot be agreed upon". The other algorithms have + // already been checked above so the kex algorithm and host key + // algorithm are checked here. + if otherInit.FirstKexFollows && (clientInit.KexAlgos[0] != serverInit.KexAlgos[0] || clientInit.ServerHostKeyAlgos[0] != serverInit.ServerHostKeyAlgos[0]) { // other side sent a kex message for the wrong algorithm, // which we have to ignore. if _, err := t.conn.readPacket(); err != nil {