From bf0998c8f64514088e3823cc8aababb64d5f05ed Mon Sep 17 00:00:00 2001 From: olegkap_cp Date: Fri, 17 Dec 2010 13:34:00 +0000 Subject: [PATCH] Add "diffie-hellman-group14-sha1" implementation --- .../Renci.SshClient/Renci.SshClient.csproj | 4 +- .../Renci.SshClient/Security/CipherAES.cs | 20 ++++++-- .../Security/KeyExchangeDiffieHellman.cs | 30 +++--------- .../KeyExchangeDiffieHellmanGroup14Sha1.cs | 46 +++++++++++++++++++ .../KeyExchangeDiffieHellmanGroup1Sha1.cs | 46 +++++++++++++++++++ Renci.SshClient/Renci.SshClient/Session.cs | 30 +++++++++++- 6 files changed, 145 insertions(+), 31 deletions(-) create mode 100644 Renci.SshClient/Renci.SshClient/Security/KeyExchangeDiffieHellmanGroup14Sha1.cs create mode 100644 Renci.SshClient/Renci.SshClient/Security/KeyExchangeDiffieHellmanGroup1Sha1.cs diff --git a/Renci.SshClient/Renci.SshClient/Renci.SshClient.csproj b/Renci.SshClient/Renci.SshClient/Renci.SshClient.csproj index 64eea75e..28241f94 100644 --- a/Renci.SshClient/Renci.SshClient/Renci.SshClient.csproj +++ b/Renci.SshClient/Renci.SshClient/Renci.SshClient.csproj @@ -89,6 +89,8 @@ + + @@ -171,7 +173,7 @@ - + diff --git a/Renci.SshClient/Renci.SshClient/Security/CipherAES.cs b/Renci.SshClient/Renci.SshClient/Security/CipherAES.cs index 1908ce12..3106f457 100644 --- a/Renci.SshClient/Renci.SshClient/Security/CipherAES.cs +++ b/Renci.SshClient/Renci.SshClient/Security/CipherAES.cs @@ -13,11 +13,6 @@ namespace Renci.SshClient.Security private ICryptoTransform _decryptor; - public override string Name - { - get { return "aes128-cbc"; } - } - public override int KeySize { get @@ -109,6 +104,11 @@ namespace Renci.SshClient.Security public class CipherAES128CBC : CipherAES { + public override string Name + { + get { return "aes128-cbc"; } + } + public CipherAES128CBC() : base(128) { @@ -118,6 +118,11 @@ namespace Renci.SshClient.Security public class CipherAES192CBC : CipherAES { + public override string Name + { + get { return "aes192-cbc"; } + } + public CipherAES192CBC() : base(192) { @@ -127,6 +132,11 @@ namespace Renci.SshClient.Security public class CipherAES256CBC : CipherAES { + public override string Name + { + get { return "aes256-cbc"; } + } + public CipherAES256CBC() : base(256) { diff --git a/Renci.SshClient/Renci.SshClient/Security/KeyExchangeDiffieHellman.cs b/Renci.SshClient/Renci.SshClient/Security/KeyExchangeDiffieHellman.cs index fb9860b8..676f52ed 100644 --- a/Renci.SshClient/Renci.SshClient/Security/KeyExchangeDiffieHellman.cs +++ b/Renci.SshClient/Renci.SshClient/Security/KeyExchangeDiffieHellman.cs @@ -9,29 +9,13 @@ using Renci.SshClient.Messages.Transport; namespace Renci.SshClient.Security { - internal class KeyExchangeDiffieHellman : KeyExchangeAlgorithm + internal abstract class KeyExchangeDiffieHellman : KeyExchangeAlgorithm { private static RNGCryptoServiceProvider _randomizer = new System.Security.Cryptography.RNGCryptoServiceProvider(); - private static BigInteger _prime = new BigInteger(new byte[] { (byte)0x00, - (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, - (byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34, - (byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1, - (byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74, - (byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22, - (byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD, - (byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B, - (byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37, - (byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45, - (byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6, - (byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B, - (byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED, - (byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5, - (byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6, - (byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE6,(byte)0x53,(byte)0x81, - (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF}.Reverse().ToArray()); + protected abstract BigInteger Prime { get; } - private static BigInteger _group = new BigInteger(new byte[] { 2 }); + protected abstract BigInteger Group { get; } private string _clientPayload; @@ -53,7 +37,7 @@ namespace Renci.SshClient.Security } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The session information. public KeyExchangeDiffieHellman() @@ -101,9 +85,9 @@ namespace Renci.SshClient.Security _randomizer.GetBytes(bytesArray); bytesArray[bytesArray.Length - 1] = (byte)(bytesArray[bytesArray.Length - 1] & 0x7F); // Ensure not a negative value this._randomValue = new BigInteger(bytesArray); - clientExchangeValue = System.Numerics.BigInteger.ModPow(KeyExchangeDiffieHellman._group, this._randomValue, KeyExchangeDiffieHellman._prime); + clientExchangeValue = System.Numerics.BigInteger.ModPow(this.Group, this._randomValue, this.Prime); - } while (clientExchangeValue < 1 || clientExchangeValue > ((KeyExchangeDiffieHellman._prime - 1))); + } while (clientExchangeValue < 1 || clientExchangeValue > ((this.Prime - 1))); this._clientExchangeValue = clientExchangeValue; @@ -123,7 +107,7 @@ namespace Renci.SshClient.Security this._serverExchangeValue = message.F; this._hostKey = message.HostKey; - this.SharedKey = System.Numerics.BigInteger.ModPow(message.F, this._randomValue, KeyExchangeDiffieHellman._prime); + this.SharedKey = System.Numerics.BigInteger.ModPow(message.F, this._randomValue, this.Prime); this._signature = message.Signature; } diff --git a/Renci.SshClient/Renci.SshClient/Security/KeyExchangeDiffieHellmanGroup14Sha1.cs b/Renci.SshClient/Renci.SshClient/Security/KeyExchangeDiffieHellmanGroup14Sha1.cs new file mode 100644 index 00000000..4e2b9f66 --- /dev/null +++ b/Renci.SshClient/Renci.SshClient/Security/KeyExchangeDiffieHellmanGroup14Sha1.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Security.Cryptography; +using Renci.SshClient.Common; +using Renci.SshClient.Messages; +using Renci.SshClient.Messages.Transport; +using System.Globalization; + +namespace Renci.SshClient.Security +{ + internal class KeyExchangeDiffieHellmanGroup14Sha1 : KeyExchangeDiffieHellman + { + private static object _lock = new object(); + + private static BigInteger _prime; + + private static BigInteger _group = new BigInteger(new byte[] { 2 }); + + protected override BigInteger Prime + { + get + { + if (_prime.IsZero) + { + lock (_lock) + { + if (_prime.IsZero) + { + var secondOkleyGroup = "00FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF"; + BigInteger.TryParse(secondOkleyGroup, System.Globalization.NumberStyles.AllowHexSpecifier, CultureInfo.CurrentCulture, out KeyExchangeDiffieHellmanGroup14Sha1._prime); + } + } + } + + return KeyExchangeDiffieHellmanGroup14Sha1._prime; + } + } + + protected override BigInteger Group + { + get { return KeyExchangeDiffieHellmanGroup14Sha1._group; } + } + } +} diff --git a/Renci.SshClient/Renci.SshClient/Security/KeyExchangeDiffieHellmanGroup1Sha1.cs b/Renci.SshClient/Renci.SshClient/Security/KeyExchangeDiffieHellmanGroup1Sha1.cs new file mode 100644 index 00000000..083954a7 --- /dev/null +++ b/Renci.SshClient/Renci.SshClient/Security/KeyExchangeDiffieHellmanGroup1Sha1.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Security.Cryptography; +using Renci.SshClient.Common; +using Renci.SshClient.Messages; +using Renci.SshClient.Messages.Transport; +using System.Globalization; + +namespace Renci.SshClient.Security +{ + internal class KeyExchangeDiffieHellmanGroup1Sha1 : KeyExchangeDiffieHellman + { + private static object _lock = new object(); + + private static BigInteger _prime; + + private static BigInteger _group = new BigInteger(new byte[] { 2 }); + + protected override BigInteger Prime + { + get + { + if (_prime.IsZero) + { + lock (_lock) + { + if (_prime.IsZero) + { + var secondOkleyGroup = @"00FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF"; + BigInteger.TryParse(secondOkleyGroup, System.Globalization.NumberStyles.AllowHexSpecifier, CultureInfo.CurrentCulture, out KeyExchangeDiffieHellmanGroup1Sha1._prime); + } + } + } + + return KeyExchangeDiffieHellmanGroup1Sha1._prime; + } + } + + protected override BigInteger Group + { + get { return KeyExchangeDiffieHellmanGroup1Sha1._group; } + } + } +} diff --git a/Renci.SshClient/Renci.SshClient/Session.cs b/Renci.SshClient/Renci.SshClient/Session.cs index 55510170..a6d7682a 100644 --- a/Renci.SshClient/Renci.SshClient/Session.cs +++ b/Renci.SshClient/Renci.SshClient/Session.cs @@ -390,8 +390,10 @@ namespace Renci.SshClient this.KeyExchangeAlgorithms = new Dictionary() { - {"diffie-hellman-group1-sha1", typeof(KeyExchangeDiffieHellman).AssemblyQualifiedName}, + {"diffie-hellman-group1-sha1", typeof(KeyExchangeDiffieHellmanGroup1Sha1).AssemblyQualifiedName}, + {"diffie-hellman-group14-sha1", typeof(KeyExchangeDiffieHellmanGroup14Sha1).AssemblyQualifiedName}, //"diffie-hellman-group-exchange-sha1" + //diffie-hellman-group-exchange-sha256 }; this.Encryptions = new Dictionary() @@ -400,18 +402,41 @@ namespace Renci.SshClient {"aes128-cbc", typeof(CipherAES128CBC).AssemblyQualifiedName}, {"aes192-cbc", typeof(CipherAES192CBC).AssemblyQualifiedName}, {"aes256-cbc", typeof(CipherAES256CBC).AssemblyQualifiedName}, + //{"blowfish-cbc", typeof(...).AssemblyQualifiedName}, + //{"twofish256-cbc", typeof(...).AssemblyQualifiedName}, + //{"twofish-cbc", typeof(...).AssemblyQualifiedName}, + //{"twofish192-cbc", typeof(...).AssemblyQualifiedName}, + //{"twofish128-cbc", typeof(...).AssemblyQualifiedName}, + //{"serpent256-cbc", typeof(...).AssemblyQualifiedName}, + //{"serpent192-cbc", typeof(...).AssemblyQualifiedName}, + //{"serpent128-cbc", typeof(...).AssemblyQualifiedName}, + //{"arcfour128", typeof(...).AssemblyQualifiedName}, + //{"arcfour256", typeof(...).AssemblyQualifiedName}, + //{"arcfour", typeof(...).AssemblyQualifiedName}, + //{"idea-cbc", typeof(...).AssemblyQualifiedName}, + //{"cast128-cbc", typeof(...).AssemblyQualifiedName}, + //{"rijndael-cbc@lysator.liu.se", typeof(...).AssemblyQualifiedName}, + //{"aes128-ctr", typeof(...).AssemblyQualifiedName}, + //{"aes192-ctr", typeof(...).AssemblyQualifiedName}, + //{"aes256-ctr", typeof(...).AssemblyQualifiedName}, }; this.HmacAlgorithms = new Dictionary() { {"hmac-md5", typeof(HMacMD5).AssemblyQualifiedName}, {"hmac-sha1", typeof(HMacSha1).AssemblyQualifiedName}, + //{"umac-64@openssh.com", typeof(HMacSha1).AssemblyQualifiedName}, + //{"hmac-ripemd160", typeof(HMacSha1).AssemblyQualifiedName}, + //{"hmac-ripemd160@openssh.com", typeof(HMacSha1).AssemblyQualifiedName}, + //{"hmac-md5-96", typeof(...).AssemblyQualifiedName}, + //{"hmac-sha1-96", typeof(...).AssemblyQualifiedName}, + //{"none", typeof(...).AssemblyQualifiedName}, }; this.HostKeyAlgorithms = new Dictionary() { {"ssh-rsa", typeof(CryptoPublicKeyRsa).AssemblyQualifiedName}, - {"ssh-dsa", typeof(CryptoPublicKeyDss).AssemblyQualifiedName}, // TODO: Need to be tested + //{"ssh-dss", typeof(CryptoPublicKeyDss).AssemblyQualifiedName}, }; this.SupportedAuthenticationMethods = new Dictionary() @@ -419,6 +444,7 @@ namespace Renci.SshClient {"none", typeof(UserAuthenticationNone).AssemblyQualifiedName}, {"publickey", typeof(UserAuthenticationPublicKey).AssemblyQualifiedName}, {"password", typeof(UserAuthenticationPassword).AssemblyQualifiedName}, + //{"hostbased", typeof(...).AssemblyQualifiedName}, }; this.CompressionAlgorithms = new Dictionary()