Просмотр исходного кода

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 <hanwen@google.com>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Kaleb Elwert 9 лет назад
Родитель
Сommit
6ab629be5e
1 измененных файлов с 10 добавлено и 1 удалено
  1. 10 1
      ssh/handshake.go

+ 10 - 1
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 {