Przeglądaj źródła

Fix key material extension during key exchange (#1689)

When the key exchange produces less key material than is needed for the cipher or hmac
algorithms, there is an iterative procedure to produce more.

For example, a SHA-1 key exchange algorithm produces 20 bytes of key material.
A SHA-256 hmac uses a 32 byte key, so one iteration of the procedure produces another
20 bytes of key material for a total of 40 which is sufficient for the hmac key.

The library works correctly in such cases of one iteration, but the logic is wrong if
more than one iteration is needed. In #1660, the connection uses a SHA-1 kex algorithm
with a SHA-512 hmac (64 byte key), requiring 3 iterations of the extension procedure and
resulting in an error upon connection.

This change fixes the logic to use the output of the previous iteration per the spec.

closes #1660
Rob Hague 2 miesięcy temu
rodzic
commit
b199467971

+ 3 - 6
src/Renci.SshNet/Security/KeyExchange.cs

@@ -1,5 +1,4 @@
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Security.Cryptography;
 
@@ -530,9 +529,7 @@ namespace Renci.SshNet.Security
         /// </returns>
         private byte[] GenerateSessionKey(byte[] sharedKey, byte[] exchangeHash, byte[] key, int size)
         {
-            var result = new List<byte>(key);
-
-            while (size > result.Count)
+            while (key.Length < size)
             {
                 var sessionKeyAdjustment = new SessionKeyAdjustment
                 {
@@ -541,10 +538,10 @@ namespace Renci.SshNet.Security
                     Key = key,
                 };
 
-                result.AddRange(Hash(sessionKeyAdjustment.GetBytes()));
+                key = key.Concat(Hash(sessionKeyAdjustment.GetBytes()));
             }
 
-            return result.ToArray();
+            return key;
         }
 
         /// <summary>

+ 16 - 0
test/Renci.SshNet.IntegrationTests/HmacTests.cs

@@ -40,6 +40,22 @@ namespace Renci.SshNet.IntegrationTests
             DoTest(MessageAuthenticationCodeAlgorithm.HmacSha2_512);
         }
 
+        [TestMethod]
+        public void HmacSha2_512_ShortKexOutput()
+        {
+            _remoteSshdConfig.ClearMessageAuthenticationCodeAlgorithms()
+                             .AddMessageAuthenticationCodeAlgorithm(MessageAuthenticationCodeAlgorithm.HmacSha2_512)
+                             .ClearKeyExchangeAlgorithms()
+                             .AddKeyExchangeAlgorithm(KeyExchangeAlgorithm.DiffieHellmanGroupExchangeSha1)
+                             .Update()
+                             .Restart();
+
+            using (var client = new SshClient(_connectionInfoFactory.Create()))
+            {
+                client.Connect();
+                client.Disconnect();
+            }
+        }
 
         [TestMethod]
         public void HmacSha1_Etm()