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()