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

Fix: must offer KeyAlgoRSA to Psiphon server

Rod Hynes 7 лет назад
Родитель
Сommit
baee7cd844
1 измененных файлов с 36 добавлено и 16 удалено
  1. 36 16
      psiphon/common/crypto/ssh/handshake.go

+ 36 - 16
psiphon/common/crypto/ssh/handshake.go

@@ -482,8 +482,7 @@ func (t *handshakeTransport) sendKexInit() error {
 	//
 	if t.remoteAddr != nil {
 
-		transform := func(list []string, doCut bool) []string {
-
+		permute := func(list []string) []string {
 			newList := make([]string, len(list))
 			perm, err := common.MakeSecureRandomPerm(len(list))
 			if err == nil {
@@ -491,29 +490,50 @@ func (t *handshakeTransport) sendKexInit() error {
 					newList[j] = list[i]
 				}
 			}
+			return newList
+		}
 
-			if doCut {
-				cut := len(newList)
-				for ; cut > 1; cut-- {
-					if !common.FlipCoin() {
-						break
-					}
+		truncate := func(list []string) []string {
+			cut := len(list)
+			for ; cut > 1; cut-- {
+				if !common.FlipCoin() {
+					break
 				}
-				newList = newList[:cut]
 			}
-
-			return newList
+			return list[:cut]
 		}
 
-		msg.KexAlgos = transform(t.config.KeyExchanges, true)
-		ciphers := transform(t.config.Ciphers, true)
+		msg.KexAlgos = truncate(permute(t.config.KeyExchanges))
+		ciphers := truncate(permute(t.config.Ciphers))
 		msg.CiphersClientServer = ciphers
 		msg.CiphersServerClient = ciphers
-		MACs := transform(t.config.MACs, true)
+		MACs := truncate(permute(t.config.MACs))
 		msg.MACsClientServer = MACs
 		msg.MACsServerClient = MACs
-		msg.ServerHostKeyAlgos = transform(
-			msg.ServerHostKeyAlgos, len(t.hostKeys) == 0)
+
+		if len(t.hostKeys) > 0 {
+			msg.ServerHostKeyAlgos = permute(msg.ServerHostKeyAlgos)
+		} else {
+			serverHostKeyAlgos := truncate(permute(msg.ServerHostKeyAlgos))
+
+			// Must offer KeyAlgoRSA to Psiphon server.
+			hasKeyAlgoRSA := false
+			for _, algo := range serverHostKeyAlgos {
+				if algo == KeyAlgoRSA {
+					hasKeyAlgoRSA = true
+					break
+				}
+			}
+			if !hasKeyAlgoRSA {
+				replace, err := common.MakeSecureRandomInt(len(serverHostKeyAlgos))
+				if err != nil {
+					replace = 0
+				}
+				serverHostKeyAlgos[replace] = KeyAlgoRSA
+			}
+
+			msg.ServerHostKeyAlgos = serverHostKeyAlgos
+		}
 
 		// Offer "zlib@openssh.com", which is offered by OpenSSH.
 		// Since server only supports "none", must always offer "none"