浏览代码

Some cosmetic changes
Fixes suggested in issue #703
Add tests for implemented issues

olegkap_cp 14 年之前
父节点
当前提交
0854d152db
共有 40 个文件被更改,包括 1065 次插入696 次删除
  1. 23 0
      Renci.SshClient/Renci.SshClient.Tests/ConnectionTest.cs
  2. 17 0
      Renci.SshClient/Renci.SshClient.Tests/Security/TestPrivateKeyFile.cs
  3. 4 14
      Renci.SshClient/Renci.SshClient.Tests/SshClientTests/TestPortForwarding.cs
  4. 42 0
      Renci.SshClient/Renci.SshClient.Tests/SshClientTests/TestSshCommand.cs
  5. 3 0
      Renci.SshClient/Renci.SshClient/BaseClient.cs
  6. 3 2
      Renci.SshClient/Renci.SshClient/Channels/ChannelSession.cs
  7. 2 1
      Renci.SshClient/Renci.SshClient/Common/Extensions.cs
  8. 2 11
      Renci.SshClient/Renci.SshClient/Common/PipeStream.cs
  9. 3 2
      Renci.SshClient/Renci.SshClient/Common/SshData.cs
  10. 14 1
      Renci.SshClient/Renci.SshClient/ConnectionInfo.cs
  11. 2 1
      Renci.SshClient/Renci.SshClient/ForwardedPortRemote.cs
  12. 1 1
      Renci.SshClient/Renci.SshClient/KeyboardInteractiveConnectionInfo.cs
  13. 3 2
      Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelMessage.cs
  14. 2 1
      Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelOpen/ChannelOpenMessage.cs
  15. 2 1
      Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestMessage.cs
  16. 3 4
      Renci.SshClient/Renci.SshClient/Messages/Message.cs
  17. 3 9
      Renci.SshClient/Renci.SshClient/NoneConnectionInfo.cs
  18. 1 1
      Renci.SshClient/Renci.SshClient/PasswordConnectionInfo.cs
  19. 12 2
      Renci.SshClient/Renci.SshClient/PrivateKeyFile.cs
  20. 6 4
      Renci.SshClient/Renci.SshClient/Properties/AssemblyInfo.cs
  21. 0 1
      Renci.SshClient/Renci.SshClient/Security/CipherCast.cs
  22. 1 1
      Renci.SshClient/Renci.SshClient/Security/Cryptography/Blowfish.cs
  23. 9 9
      Renci.SshClient/Renci.SshClient/Security/Cryptography/Ciphers/AesCipher.cs
  24. 8 8
      Renci.SshClient/Renci.SshClient/Security/Cryptography/Ciphers/BlowfishCipher.cs
  25. 8 8
      Renci.SshClient/Renci.SshClient/Security/Cryptography/Ciphers/CastCipher.cs
  26. 152 64
      Renci.SshClient/Renci.SshClient/Security/Cryptography/Ciphers/CipherBase.cs
  27. 489 475
      Renci.SshClient/Renci.SshClient/Security/Cryptography/Ciphers/DesCipher.cs
  28. 32 2
      Renci.SshClient/Renci.SshClient/Security/Cryptography/Ciphers/TripleDesCipher.cs
  29. 1 2
      Renci.SshClient/Renci.SshClient/Security/Cryptography/Des.cs
  30. 26 0
      Renci.SshClient/Renci.SshClient/Security/Cryptography/Modes/CbcMode.cs
  31. 4 0
      Renci.SshClient/Renci.SshClient/Security/Cryptography/Modes/CfbMode.cs
  32. 23 20
      Renci.SshClient/Renci.SshClient/Session.cs
  33. 4 3
      Renci.SshClient/Renci.SshClient/Sftp/ListDirectoryCommand.cs
  34. 1 1
      Renci.SshClient/Renci.SshClient/Sftp/Messages/NameMessage.cs
  35. 3 4
      Renci.SshClient/Renci.SshClient/Sftp/Messages/SftpMessage.cs
  36. 3 2
      Renci.SshClient/Renci.SshClient/Sftp/SftpFile.cs
  37. 8 7
      Renci.SshClient/Renci.SshClient/Sftp/SftpSession.cs
  38. 57 2
      Renci.SshClient/Renci.SshClient/Shell.cs
  39. 70 5
      Renci.SshClient/Renci.SshClient/SshClient.cs
  40. 18 25
      Renci.SshClient/Renci.SshClient/SshCommand.cs

+ 23 - 0
Renci.SshClient/Renci.SshClient.Tests/ConnectionTest.cs

@@ -7,6 +7,7 @@ using System.IO;
 using Renci.SshClient.Tests.Properties;
 using System.Security.Authentication;
 using Renci.SshClient.Common;
+using System.Net;
 
 namespace Renci.SshClient.Tests
 {
@@ -130,5 +131,27 @@ namespace Renci.SshClient.Tests
                 client.Disconnect();
             }
         }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void Test_ConnectionInfo_NullHost()
+        {
+            var connectionInfo = new PasswordConnectionInfo(null, null, null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void Test_ConnectionInfo_SmallPortNumber()
+        {
+            var connectionInfo = new PasswordConnectionInfo(Resources.HOST, IPEndPoint.MinPort - 1, null, null);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentOutOfRangeException))]
+        public void Test_ConnectionInfo_BigPortNumber()
+        {
+            var connectionInfo = new PasswordConnectionInfo(Resources.HOST, IPEndPoint.MaxPort + 1, null, null);
+        }
+
     }
 }

+ 17 - 0
Renci.SshClient/Renci.SshClient.Tests/Security/TestPrivateKeyFile.cs

@@ -3,11 +3,28 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System.IO;
 
 namespace Renci.SshClient.Tests.Security
 {
     [TestClass]
     public class TestPrivateKeyFile
     {
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void Test_PrivateKeyFile_EmptyFileName()
+        {
+            string fileName = string.Empty;
+            var keyFile = new PrivateKeyFile(fileName);
+        }
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentNullException))]
+        public void Test_PrivateKeyFile_StreamIsNull()
+        {
+            Stream stream = null;
+            var keyFile = new PrivateKeyFile(stream);
+        }
+
     }
 }

+ 4 - 14
Renci.SshClient/Renci.SshClient.Tests/SshClientTests/TestPortForwarding.cs

@@ -109,20 +109,10 @@ namespace Renci.SshClient.Tests.SshClientTests
                     //},
                     (counter) =>
                     {
-                        var start = DateTime.Now;
-                        try
-                        {
-
-                            var cmd = client.CreateCommand(string.Format("wget -O- http://localhost:{0}", boundport));
-                            var result = cmd.Execute();
-                            var end = DateTime.Now;
-                            Debug.WriteLine(string.Format("Length: {0}", result.Length));
-                        }
-                        catch (Exception exp)
-                        {
-
-                            throw;
-                        }
+                        var cmd = client.CreateCommand(string.Format("wget -O- http://localhost:{0}", boundport));
+                        var result = cmd.Execute();
+                        var end = DateTime.Now;
+                        Debug.WriteLine(string.Format("Length: {0}", result.Length));
                     }
                 );
             }

+ 42 - 0
Renci.SshClient/Renci.SshClient.Tests/SshClientTests/TestSshCommand.cs

@@ -321,6 +321,48 @@ namespace Renci.SshClient.Tests.SshClientTests
             }
         }
 
+        [TestMethod]
+        public void Test_Get_Result_Without_Execution()
+        {
+            using (var client = new SshClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
+            {
+                client.Connect();
+                var cmd = client.CreateCommand("ls -l");
+
+                Assert.IsTrue(string.IsNullOrEmpty(cmd.Result));
+                client.Disconnect();
+            }
+        }
+
+        [TestMethod]
+        public void Test_Get_Error_Without_Execution()
+        {
+            using (var client = new SshClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
+            {
+                client.Connect();
+                var cmd = client.CreateCommand("ls -l");
+
+                Assert.IsTrue(string.IsNullOrEmpty(cmd.Error));
+                client.Disconnect();
+            }
+        }
+
+
+        [TestMethod]
+        [ExpectedException(typeof(ArgumentException))]
+        public void Test_EndExecute_Before_BeginExecute()
+        {
+            using (var client = new SshClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD))
+            {
+                client.Connect();
+                var cmd = client.CreateCommand("ls -l");
+                cmd.EndExecute(null);
+                client.Disconnect();
+            }
+        }
+
+
+
         private static bool ExecuteTestCommand(Renci.SshClient.SshClient s)
         {
             var testValue = Guid.NewGuid().ToString();

+ 3 - 0
Renci.SshClient/Renci.SshClient/BaseClient.cs

@@ -80,6 +80,9 @@ namespace Renci.SshClient
         /// <param name="connectionInfo">The connection info.</param>
         public BaseClient(ConnectionInfo connectionInfo)
         {
+            if (connectionInfo == null)
+                throw new ArgumentNullException("connectionInfo");
+
             this.ConnectionInfo = connectionInfo;
             this.Session = new Session(connectionInfo);
         }

+ 3 - 2
Renci.SshClient/Renci.SshClient/Channels/ChannelSession.cs

@@ -2,6 +2,7 @@
 using System.Threading;
 using Renci.SshClient.Common;
 using Renci.SshClient.Messages.Connection;
+using System.Globalization;
 
 namespace Renci.SshClient.Channels
 {
@@ -51,7 +52,7 @@ namespace Renci.SshClient.Channels
 
                 if (!this.IsOpen)
                 {
-                    throw new SshException(string.Format("Failed to open a channel after {0} attempts.", this._failedOpenAttempts));
+                    throw new SshException(string.Format(CultureInfo.CurrentCulture, "Failed to open a channel after {0} attempts.", this._failedOpenAttempts));
                 }
             }
         }
@@ -79,7 +80,7 @@ namespace Renci.SshClient.Channels
         {
             this._failedOpenAttempts++;
 
-            Debug.WriteLine(string.Format("Local channel: {0} attempts: {1}.", this.LocalChannelNumber, this._failedOpenAttempts));
+            Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Local channel: {0} attempts: {1}.", this.LocalChannelNumber, this._failedOpenAttempts));
 
             this.SessionSemaphore.Release();
 

+ 2 - 1
Renci.SshClient/Renci.SshClient/Common/Extensions.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Diagnostics;
 using System.Linq;
 using System;
+using System.Globalization;
 
 namespace Renci.SshClient
 {
@@ -83,7 +84,7 @@ namespace Renci.SshClient
         {
             foreach (var b in bytes)
             {
-                Debug.Write(string.Format("0x{0:x2}, ", b));
+                Debug.Write(string.Format(CultureInfo.CurrentCulture, "0x{0:x2}, ", b));
             }
             Debug.WriteLine(string.Empty);
         }

+ 2 - 11
Renci.SshClient/Renci.SshClient/Common/PipeStream.cs

@@ -4,6 +4,7 @@
     using System.Collections.Generic;
     using System.IO;
     using System.Threading;
+    using System.Globalization;
 
     /// <summary>
     /// PipeStream is a thread-safe read/write data stream for use between two threads in a 
@@ -101,16 +102,6 @@
 
         #region Stream overide methods
 
-        ///<summary>
-        ///Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
-        ///</summary>
-        ///<filterpriority>2</filterpriority>
-        public new void Dispose()
-        {
-            // clear the internal buffer
-            _buffer.Clear();
-        }
-
         ///<summary>
         ///When overridden in a derived class, clears all buffers for this stream and causes any buffered data to be written to the underlying device.
         ///</summary>
@@ -177,7 +168,7 @@
             if (offset < 0 || count < 0)
                 throw new ArgumentOutOfRangeException("offset", "offset or count is negative.");
             if (BlockLastReadBuffer && count >= _maxBufferLength)
-                throw new ArgumentException(String.Format("count({0}) > mMaxBufferLength({1})", count, _maxBufferLength));
+                throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "count({0}) > mMaxBufferLength({1})", count, _maxBufferLength));
 
             if (count == 0)
                 return 0;

+ 3 - 2
Renci.SshClient/Renci.SshClient/Common/SshData.cs

@@ -4,6 +4,7 @@ using System.Linq;
 using System.Numerics;
 using System.Text;
 using Renci.SshClient;
+using System.Globalization;
 
 namespace Renci.SshClient.Common
 {
@@ -201,7 +202,7 @@ namespace Renci.SshClient.Common
 
             if (length > int.MaxValue)
             {
-                throw new NotSupportedException(string.Format("String that longer that {0} are not supported.", int.MaxValue));
+                throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "String that longer that {0} are not supported.", int.MaxValue));
             }
 
             return Encoding.ASCII.GetString(this.ReadBytes(length));
@@ -217,7 +218,7 @@ namespace Renci.SshClient.Common
 
             if (length > int.MaxValue)
             {
-                throw new NotSupportedException(string.Format("String that longer that {0} are not supported.", int.MaxValue));
+                throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "String that longer that {0} are not supported.", int.MaxValue));
             }
 
             return this.ReadBytes(length);

+ 14 - 1
Renci.SshClient/Renci.SshClient/ConnectionInfo.cs

@@ -7,6 +7,7 @@ using Renci.SshClient.Messages;
 using Renci.SshClient.Messages.Authentication;
 using Renci.SshClient.Common;
 using System.Threading;
+using System.Net;
 namespace Renci.SshClient
 {
     /// <summary>
@@ -201,6 +202,15 @@ namespace Renci.SshClient
         protected ConnectionInfo(string host, int port, string username)
             : this()
         {
+            if (string.IsNullOrEmpty(host))
+                throw new ArgumentNullException("host");
+
+            if (port < IPEndPoint.MinPort)
+                throw new ArgumentOutOfRangeException("port");
+
+            if (port > IPEndPoint.MaxPort)
+                throw new ArgumentOutOfRangeException("port");
+
             this.Host = host;
             this.Port = port;
             this.Username = username;
@@ -213,6 +223,9 @@ namespace Renci.SshClient
         /// <returns>true if authenticated; otherwise false.</returns>
         public bool Authenticate(Session session)
         {
+            if (session == null)
+                throw new ArgumentNullException("session");
+
             this.Session = session;
 
             this.Session.RegisterMessage("SSH_MSG_USERAUTH_FAILURE");
@@ -260,7 +273,7 @@ namespace Renci.SshClient
         {
             this.Session.WaitHandle(eventWaitHandle);
         }
-        
+
         /// <summary>
         /// Handles the UserAuthenticationFailureReceived event of the session.
         /// </summary>

+ 2 - 1
Renci.SshClient/Renci.SshClient/ForwardedPortRemote.cs

@@ -5,6 +5,7 @@ using Renci.SshClient.Channels;
 using Renci.SshClient.Messages.Connection;
 using Renci.SshClient.Common;
 using System.Diagnostics;
+using System.Globalization;
 
 namespace Renci.SshClient
 {
@@ -46,7 +47,7 @@ namespace Renci.SshClient
                 //  If request  failed don't handle channel opening for this request
                 this.Session.ChannelOpenReceived -= Session_ChannelOpening;
 
-                throw new SshException(string.Format("Port forwarding for '{0}' port '{1}' failed to start.", this.Host, this.Port));
+                throw new SshException(string.Format(CultureInfo.CurrentCulture, "Port forwarding for '{0}' port '{1}' failed to start.", this.Host, this.Port));
             }
             else
             {

+ 1 - 1
Renci.SshClient/Renci.SshClient/KeyboardInteractiveConnectionInfo.cs

@@ -113,7 +113,7 @@ namespace Renci.SshClient
             {
                 var eventArgs = new AuthenticationPromptEventArgs(this.Username, informationRequestMessage.Instruction, informationRequestMessage.Language, informationRequestMessage.Prompts);
 
-                var eventTask = Task.Factory.StartNew(() =>
+                Task.Factory.StartNew(() =>
                 {
                     try
                     {

+ 3 - 2
Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelMessage.cs

@@ -1,4 +1,5 @@
-namespace Renci.SshClient.Messages.Connection
+using System.Globalization;
+namespace Renci.SshClient.Messages.Connection
 {
     /// <summary>
     /// Base class for all channel specific SSH messages.
@@ -37,7 +38,7 @@
         /// </returns>
         public override string ToString()
         {
-            return string.Format("{0} : #{1}", base.ToString(), this.LocalChannelNumber);
+            return string.Format(CultureInfo.CurrentCulture, "{0} : #{1}", base.ToString(), this.LocalChannelNumber);
         }
     }
 }

+ 2 - 1
Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelOpen/ChannelOpenMessage.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Globalization;
 
 namespace Renci.SshClient.Messages.Connection
 {
@@ -95,7 +96,7 @@ namespace Renci.SshClient.Messages.Connection
             }
             else
             {
-                throw new NotSupportedException(string.Format("Channel type '{0}' is not supported.", channelName));
+                throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Channel type '{0}' is not supported.", channelName));
             }
 
             this.Info.Load(bytes);

+ 2 - 1
Renci.SshClient/Renci.SshClient/Messages/Connection/ChannelRequest/ChannelRequestMessage.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Globalization;
 
 namespace Renci.SshClient.Messages.Connection
 {
@@ -116,7 +117,7 @@ namespace Renci.SshClient.Messages.Connection
             }
             else
             {
-                throw new NotSupportedException(string.Format("Request '{0}' is not supported.", requestName));
+                throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Request '{0}' is not supported.", requestName));
             }
 
             this.Info.Load(bytes);

+ 3 - 4
Renci.SshClient/Renci.SshClient/Messages/Message.cs

@@ -1,6 +1,7 @@
 using System.Collections.Generic;
 using System.Linq;
 using Renci.SshClient.Common;
+using System.Globalization;
 
 namespace Renci.SshClient.Messages
 {
@@ -17,8 +18,6 @@ namespace Renci.SshClient.Messages
         /// <returns>SSH message object</returns>
         internal static T Load<T>(byte[] data) where T : Message, new()
         {
-            var messageType = data.FirstOrDefault();
-
             T message = new T();
 
             message.LoadBytes(data);
@@ -53,7 +52,7 @@ namespace Renci.SshClient.Messages
             var messageAttribute = this.GetType().GetCustomAttributes(typeof(MessageAttribute), true).SingleOrDefault() as MessageAttribute;
 
             if (messageAttribute == null)
-                throw new SshException(string.Format("Type '{0}' is not a valid message type.", this.GetType().AssemblyQualifiedName));
+                throw new SshException(string.Format(CultureInfo.CurrentCulture, "Type '{0}' is not a valid message type.", this.GetType().AssemblyQualifiedName));
 
             var data = new List<byte>(base.GetBytes());
 
@@ -73,7 +72,7 @@ namespace Renci.SshClient.Messages
             var messageAttribute = this.GetType().GetCustomAttributes(typeof(MessageAttribute), true).SingleOrDefault() as MessageAttribute;
 
             if (messageAttribute == null)
-                return string.Format("'{0}' without Message attribute.", this.GetType().FullName);
+                return string.Format(CultureInfo.CurrentCulture, "'{0}' without Message attribute.", this.GetType().FullName);
 
             return messageAttribute.Name;
         }

+ 3 - 9
Renci.SshClient/Renci.SshClient/NoneConnectionInfo.cs

@@ -15,8 +15,9 @@ namespace Renci.SshClient
     {
         private EventWaitHandle _authenticationCompleted = new AutoResetEvent(false);
 
-        private Exception _exception;
-
+        /// <summary>
+        /// Gets list of allowed authentications.
+        /// </summary>
         public IEnumerable<string> AllowedAuthentications { get; private set; }
 
         /// <summary>
@@ -34,7 +35,6 @@ namespace Renci.SshClient
         /// </summary>
         /// <param name="host">Connection host.</param>
         /// <param name="username">Connection username.</param>
-        /// <param name="password">Connection password.</param>
         public NoneConnectionInfo(string host, string username)
             : this(host, 22, username)
         {
@@ -47,7 +47,6 @@ namespace Renci.SshClient
         /// <param name="host">Connection host.</param>
         /// <param name="port">Connection port.</param>
         /// <param name="username">Connection username.</param>
-        /// <param name="password">Connection password.</param>
         public NoneConnectionInfo(string host, int port, string username)
             : base(host, port, username)
         {
@@ -61,11 +60,6 @@ namespace Renci.SshClient
             this.SendMessage(new RequestMessageNone(ServiceNames.Connection, this.Username));
 
             this.WaitHandle(this._authenticationCompleted);
-
-            if (this._exception != null)
-            {
-                throw this._exception;
-            }
         }
 
         /// <summary>

+ 1 - 1
Renci.SshClient/Renci.SshClient/PasswordConnectionInfo.cs

@@ -117,7 +117,7 @@ namespace Renci.SshClient
             {
                 this.Session.UnRegisterMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
 
-                var eventTask = Task.Factory.StartNew(() =>
+                Task.Factory.StartNew(() =>
                 {
                     try
                     {

+ 12 - 2
Renci.SshClient/Renci.SshClient/PrivateKeyFile.cs

@@ -8,6 +8,7 @@ using Renci.SshClient.Security;
 using System.Security.Cryptography;
 using System.Security;
 using Renci.SshClient.Common;
+using System.Globalization;
 
 namespace Renci.SshClient
 {
@@ -70,6 +71,9 @@ namespace Renci.SshClient
         /// <param name="fileName">Name of the file.</param>
         public PrivateKeyFile(string fileName)
         {
+            if (string.IsNullOrEmpty(fileName))
+                throw new ArgumentNullException("fileName");
+
             using (var keyFile = File.Open(fileName, FileMode.Open))
             {
                 this.Open(keyFile, null);
@@ -83,6 +87,9 @@ namespace Renci.SshClient
         /// <param name="passPhrase">The pass phrase.</param>
         public PrivateKeyFile(string fileName, string passPhrase)
         {
+            if (string.IsNullOrEmpty(fileName))
+                throw new ArgumentNullException("fileName");
+
             using (var keyFile = File.Open(fileName, FileMode.Open))
             {
                 this.Open(keyFile, passPhrase);
@@ -106,6 +113,9 @@ namespace Renci.SshClient
         /// <param name="passPhrase">The pass phrase.</param>
         private void Open(Stream privateKey, string passPhrase)
         {
+            if (privateKey == null)
+                throw new ArgumentNullException("privateKey");
+
             Match privateKeyMatch = null;
 
             using (StreamReader sr = new StreamReader(privateKey))
@@ -174,7 +184,7 @@ namespace Renci.SshClient
                         }
                         break;
                     default:
-                        throw new SshException(string.Format("Unknown private key cipher \"{0}\".", cipherName));
+                        throw new SshException(string.Format(CultureInfo.CurrentCulture, "Unknown private key cipher \"{0}\".", cipherName));
                 }
             }
             else
@@ -191,7 +201,7 @@ namespace Renci.SshClient
                     this._key = new CryptoPrivateKeyDss();
                     break;
                 default:
-                    throw new NotSupportedException(string.Format("Key '{0}' is not supported.", keyName));
+                    throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Key '{0}' is not supported.", keyName));
             }
 
             this._key.Load(decryptedData);

+ 6 - 4
Renci.SshClient/Renci.SshClient/Properties/AssemblyInfo.cs

@@ -1,16 +1,17 @@
 using System.Reflection;
 using System.Runtime.InteropServices;
 using System.Runtime.CompilerServices;
+using System;
 
 // General Information about an assembly is controlled through the following 
 // set of attributes. Change these attribute values to modify the information
 // associated with an assembly.
-[assembly: AssemblyTitle("SshClient")]
+[assembly: AssemblyTitle("SshNet")]
 [assembly: AssemblyDescription("")]
 [assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Microsoft")]
-[assembly: AssemblyProduct("SshClient")]
-[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
+[assembly: AssemblyCompany("Renci")]
+[assembly: AssemblyProduct("SSH.NET")]
+[assembly: AssemblyCopyright("Copyright © Renci 2011")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 
@@ -34,4 +35,5 @@ using System.Runtime.CompilerServices;
 // [assembly: AssemblyVersion("1.0.*")]
 [assembly: AssemblyVersion("0.1")]
 [assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: CLSCompliant(true)]
 [assembly: InternalsVisibleTo("Renci.SshClient.Tests")]

+ 0 - 1
Renci.SshClient/Renci.SshClient/Security/CipherCast.cs

@@ -57,7 +57,6 @@ namespace Renci.SshClient.Security
         /// <summary>
         /// Initializes a new instance of the <see cref="CipherAESCBC"/> class.
         /// </summary>
-        /// <param name="keyBitsSize">Size of the key bits.</param>
         public CipherCast()
         {
             this._algorithm = new Cryptography.Cast(128);

+ 1 - 1
Renci.SshClient/Renci.SshClient/Security/Cryptography/Blowfish.cs

@@ -25,7 +25,7 @@ namespace Renci.SshClient.Security.Cryptography
         /// <param name="keySize">Size of the key.</param>
         public Blowfish(int keySize)
         {
-            this.KeySizeValue = 16 * 8;
+            this.KeySizeValue = keySize;
             this.BlockSizeValue = 8 * 8;
             this.FeedbackSizeValue = BlockSizeValue;
             this.LegalBlockSizesValue = new KeySizes[] { new KeySizes(64, 64, 0 ) };

+ 9 - 9
Renci.SshClient/Renci.SshClient/Security/Cryptography/Ciphers/AesCipher.cs

@@ -709,7 +709,7 @@ namespace Renci.SshClient.Security.Cryptography
 
             for (int i = 0; i < key.Length; t++)
             {
-                W[t >> 2, t & 3] = CipherBase.LE_To_UInt32(key, i);
+                W[t >> 2, t & 3] = CipherBase.LittleEndianToUInt32(key, i);
                 i += 4;
             }
 
@@ -754,18 +754,18 @@ namespace Renci.SshClient.Security.Cryptography
 
         private void UnPackBlock(byte[] bytes, int off)
         {
-            C0 = CipherBase.LE_To_UInt32(bytes, off);
-            C1 = CipherBase.LE_To_UInt32(bytes, off + 4);
-            C2 = CipherBase.LE_To_UInt32(bytes, off + 8);
-            C3 = CipherBase.LE_To_UInt32(bytes, off + 12);
+            C0 = CipherBase.LittleEndianToUInt32(bytes, off);
+            C1 = CipherBase.LittleEndianToUInt32(bytes, off + 4);
+            C2 = CipherBase.LittleEndianToUInt32(bytes, off + 8);
+            C3 = CipherBase.LittleEndianToUInt32(bytes, off + 12);
         }
 
         private void PackBlock(byte[] bytes, int off)
         {
-            CipherBase.UInt32_To_LE(C0, bytes, off);
-            CipherBase.UInt32_To_LE(C1, bytes, off + 4);
-            CipherBase.UInt32_To_LE(C2, bytes, off + 8);
-            CipherBase.UInt32_To_LE(C3, bytes, off + 12);
+            CipherBase.UInt32ToLittleEndian(C0, bytes, off);
+            CipherBase.UInt32ToLittleEndian(C1, bytes, off + 4);
+            CipherBase.UInt32ToLittleEndian(C2, bytes, off + 8);
+            CipherBase.UInt32ToLittleEndian(C3, bytes, off + 12);
         }
 
         private void EncryptBlock(uint[,] KW)

+ 8 - 8
Renci.SshClient/Renci.SshClient/Security/Cryptography/Ciphers/BlowfishCipher.cs

@@ -317,8 +317,8 @@ namespace Renci.SshClient.Security.Cryptography
             if (inputCount != this.BlockSize)
                 throw new ArgumentException("inputCount");
 
-            uint xl = CipherBase.BE_To_UInt32(inputBuffer, inputOffset);
-            uint xr = CipherBase.BE_To_UInt32(inputBuffer, inputOffset + 4);
+            uint xl = CipherBase.BigEndianToUInt32(inputBuffer, inputOffset);
+            uint xr = CipherBase.BigEndianToUInt32(inputBuffer, inputOffset + 4);
 
             xl ^= P[0];
 
@@ -330,8 +330,8 @@ namespace Renci.SshClient.Security.Cryptography
 
             xr ^= P[ROUNDS + 1];
 
-            CipherBase.UInt32_To_BE(xr, outputBuffer, outputOffset);
-            CipherBase.UInt32_To_BE(xl, outputBuffer, outputOffset + 4);
+            CipherBase.UInt32ToBigEndian(xr, outputBuffer, outputOffset);
+            CipherBase.UInt32ToBigEndian(xl, outputBuffer, outputOffset + 4);
             
             return this.BlockSize;
         }
@@ -341,8 +341,8 @@ namespace Renci.SshClient.Security.Cryptography
             if (inputCount != this.BlockSize)
                 throw new ArgumentException("inputCount");
 
-            uint xl = CipherBase.BE_To_UInt32(inputBuffer, inputOffset);
-            uint xr = CipherBase.BE_To_UInt32(inputBuffer, inputOffset + 4);
+            uint xl = CipherBase.BigEndianToUInt32(inputBuffer, inputOffset);
+            uint xr = CipherBase.BigEndianToUInt32(inputBuffer, inputOffset + 4);
 
             xl ^= P[ROUNDS + 1];
 
@@ -354,8 +354,8 @@ namespace Renci.SshClient.Security.Cryptography
 
             xr ^= P[0];
 
-            CipherBase.UInt32_To_BE(xr, outputBuffer, outputOffset);
-            CipherBase.UInt32_To_BE(xl, outputBuffer, outputOffset + 4);
+            CipherBase.UInt32ToBigEndian(xr, outputBuffer, outputOffset);
+            CipherBase.UInt32ToBigEndian(xl, outputBuffer, outputOffset + 4);
 
             return this.BlockSize;
         }

+ 8 - 8
Renci.SshClient/Renci.SshClient/Security/Cryptography/Ciphers/CastCipher.cs

@@ -33,15 +33,15 @@ namespace Renci.SshClient.Security.Cryptography
             // batch the units up into a 32 bit chunk and go for it
             // the array is in bytes, the increment is 8x8 bits = 64
 
-            uint L0 = CipherBase.BE_To_UInt32(inputBuffer, inputOffset);
-            uint R0 = CipherBase.BE_To_UInt32(inputBuffer, inputOffset + 4);
+            uint L0 = CipherBase.BigEndianToUInt32(inputBuffer, inputOffset);
+            uint R0 = CipherBase.BigEndianToUInt32(inputBuffer, inputOffset + 4);
 
             uint[] result = new uint[2];
             CAST_Encipher(L0, R0, result);
 
             // now stuff them into the destination block
-            CipherBase.UInt32_To_BE(result[0], outputBuffer, outputOffset);
-            CipherBase.UInt32_To_BE(result[1], outputBuffer, outputOffset + 4);
+            CipherBase.UInt32ToBigEndian(result[0], outputBuffer, outputOffset);
+            CipherBase.UInt32ToBigEndian(result[1], outputBuffer, outputOffset + 4);
 
             return this.BlockSize;
         }
@@ -51,15 +51,15 @@ namespace Renci.SshClient.Security.Cryptography
             // process the input block
             // batch the units up into a 32 bit chunk and go for it
             // the array is in bytes, the increment is 8x8 bits = 64
-            uint L16 = CipherBase.BE_To_UInt32(inputBuffer, inputOffset);
-            uint R16 = CipherBase.BE_To_UInt32(inputBuffer, inputOffset + 4);
+            uint L16 = CipherBase.BigEndianToUInt32(inputBuffer, inputOffset);
+            uint R16 = CipherBase.BigEndianToUInt32(inputBuffer, inputOffset + 4);
 
             uint[] result = new uint[2];
             CAST_Decipher(L16, R16, result);
 
             // now stuff them into the destination block
-            CipherBase.UInt32_To_BE(result[0], outputBuffer, outputOffset);
-            CipherBase.UInt32_To_BE(result[1], outputBuffer, outputOffset + 4);
+            CipherBase.UInt32ToBigEndian(result[0], outputBuffer, outputOffset);
+            CipherBase.UInt32ToBigEndian(result[1], outputBuffer, outputOffset + 4);
 
             return this.BlockSize;
         }

+ 152 - 64
Renci.SshClient/Renci.SshClient/Security/Cryptography/Ciphers/CipherBase.cs

@@ -67,124 +67,212 @@ namespace Renci.SshClient.Security.Cryptography
 
         #region Packing functions
 
-        protected static void UInt32_To_BE(uint n, byte[] bs)
+        /// <summary>
+        /// Populates buffer with big endian number representation.
+        /// </summary>
+        /// <param name="number">The number to convert.</param>
+        /// <param name="buffer">The buffer.</param>
+        protected static void UInt32ToBigEndian(uint number, byte[] buffer)
         {
-            bs[0] = (byte)(n >> 24);
-            bs[1] = (byte)(n >> 16);
-            bs[2] = (byte)(n >> 8);
-            bs[3] = (byte)(n);
+            buffer[0] = (byte)(number >> 24);
+            buffer[1] = (byte)(number >> 16);
+            buffer[2] = (byte)(number >> 8);
+            buffer[3] = (byte)(number);
         }
 
-        protected static void UInt32_To_BE(uint n, byte[] bs, int off)
+        /// <summary>
+        /// Populates buffer with big endian number representation.
+        /// </summary>
+        /// <param name="number">The number to convert.</param>
+        /// <param name="buffer">The buffer.</param>
+        /// <param name="offset">The buffer offset.</param>
+        protected static void UInt32ToBigEndian(uint number, byte[] buffer, int offset)
         {
-            bs[off] = (byte)(n >> 24);
-            bs[++off] = (byte)(n >> 16);
-            bs[++off] = (byte)(n >> 8);
-            bs[++off] = (byte)(n);
+            buffer[offset] = (byte)(number >> 24);
+            buffer[++offset] = (byte)(number >> 16);
+            buffer[++offset] = (byte)(number >> 8);
+            buffer[++offset] = (byte)(number);
         }
 
-        protected static uint BE_To_UInt32(byte[] bs)
+        /// <summary>
+        /// Converts big endian bytes into number.
+        /// </summary>
+        /// <param name="buffer">The buffer.</param>
+        /// <returns></returns>
+        protected static uint BigEndianToUInt32(byte[] buffer)
         {
-            uint n = (uint)bs[0] << 24;
-            n |= (uint)bs[1] << 16;
-            n |= (uint)bs[2] << 8;
-            n |= (uint)bs[3];
+            uint n = (uint)buffer[0] << 24;
+            n |= (uint)buffer[1] << 16;
+            n |= (uint)buffer[2] << 8;
+            n |= (uint)buffer[3];
             return n;
         }
 
-        protected static uint BE_To_UInt32(byte[] bs, int off)
+        /// <summary>
+        /// Converts big endian bytes into number.
+        /// </summary>
+        /// <param name="buffer">The buffer.</param>
+        /// <param name="offset">The buffer offset.</param>
+        /// <returns></returns>
+        protected static uint BigEndianToUInt32(byte[] buffer, int offset)
         {
-            uint n = (uint)bs[off] << 24;
-            n |= (uint)bs[++off] << 16;
-            n |= (uint)bs[++off] << 8;
-            n |= (uint)bs[++off];
+            uint n = (uint)buffer[offset] << 24;
+            n |= (uint)buffer[++offset] << 16;
+            n |= (uint)buffer[++offset] << 8;
+            n |= (uint)buffer[++offset];
             return n;
         }
 
-        protected static ulong BE_To_UInt64(byte[] bs)
+        /// <summary>
+        /// Converts big endian bytes into number.
+        /// </summary>
+        /// <param name="buffer">The buffer.</param>
+        /// <returns></returns>
+        protected static ulong BigEndianToUInt64(byte[] buffer)
         {
-            uint hi = BE_To_UInt32(bs);
-            uint lo = BE_To_UInt32(bs, 4);
+            uint hi = BigEndianToUInt32(buffer);
+            uint lo = BigEndianToUInt32(buffer, 4);
             return ((ulong)hi << 32) | (ulong)lo;
         }
 
-        protected static ulong BE_To_UInt64(byte[] bs, int off)
+        /// <summary>
+        /// Converts big endian bytes into number.
+        /// </summary>
+        /// <param name="buffer">The buffer.</param>
+        /// <param name="offset">The buffer offset.</param>
+        /// <returns></returns>
+        protected static ulong BigEndianToUInt64(byte[] buffer, int offset)
         {
-            uint hi = BE_To_UInt32(bs, off);
-            uint lo = BE_To_UInt32(bs, off + 4);
+            uint hi = BigEndianToUInt32(buffer, offset);
+            uint lo = BigEndianToUInt32(buffer, offset + 4);
             return ((ulong)hi << 32) | (ulong)lo;
         }
 
-        protected static void UInt64_To_BE(ulong n, byte[] bs)
+        /// <summary>
+        /// Populates buffer with big endian number representation.
+        /// </summary>
+        /// <param name="number">The number to convert.</param>
+        /// <param name="buffer">The buffer.</param>
+        protected static void UInt64ToBigEndian(ulong number, byte[] buffer)
         {
-            UInt32_To_BE((uint)(n >> 32), bs);
-            UInt32_To_BE((uint)(n), bs, 4);
+            UInt32ToBigEndian((uint)(number >> 32), buffer);
+            UInt32ToBigEndian((uint)(number), buffer, 4);
         }
 
-        protected static void UInt64_To_BE(ulong n, byte[] bs, int off)
+        /// <summary>
+        /// Populates buffer with big endian number representation.
+        /// </summary>
+        /// <param name="number">The number to convert.</param>
+        /// <param name="buffer">The buffer.</param>
+        /// <param name="offset">The buffer offset.</param>
+        protected static void UInt64ToBigEndian(ulong number, byte[] buffer, int offset)
         {
-            UInt32_To_BE((uint)(n >> 32), bs, off);
-            UInt32_To_BE((uint)(n), bs, off + 4);
+            UInt32ToBigEndian((uint)(number >> 32), buffer, offset);
+            UInt32ToBigEndian((uint)(number), buffer, offset + 4);
         }
 
-        protected static void UInt32_To_LE(uint n, byte[] bs)
+        /// <summary>
+        /// Populates buffer with little endian number representation.
+        /// </summary>
+        /// <param name="number">The number to convert.</param>
+        /// <param name="buffer">The buffer.</param>
+        protected static void UInt32ToLittleEndian(uint number, byte[] buffer)
         {
-            bs[0] = (byte)(n);
-            bs[1] = (byte)(n >> 8);
-            bs[2] = (byte)(n >> 16);
-            bs[3] = (byte)(n >> 24);
+            buffer[0] = (byte)(number);
+            buffer[1] = (byte)(number >> 8);
+            buffer[2] = (byte)(number >> 16);
+            buffer[3] = (byte)(number >> 24);
         }
 
-        protected static void UInt32_To_LE(uint n, byte[] bs, int off)
+        /// <summary>
+        /// Populates buffer with little endian number representation.
+        /// </summary>
+        /// <param name="number">The number to convert.</param>
+        /// <param name="buffer">The buffer.</param>
+        /// <param name="offset">The buffer offset.</param>
+        protected static void UInt32ToLittleEndian(uint number, byte[] buffer, int offset)
         {
-            bs[off] = (byte)(n);
-            bs[++off] = (byte)(n >> 8);
-            bs[++off] = (byte)(n >> 16);
-            bs[++off] = (byte)(n >> 24);
+            buffer[offset] = (byte)(number);
+            buffer[++offset] = (byte)(number >> 8);
+            buffer[++offset] = (byte)(number >> 16);
+            buffer[++offset] = (byte)(number >> 24);
         }
 
-        protected static uint LE_To_UInt32(byte[] bs)
+        /// <summary>
+        /// Converts little endian bytes into number.
+        /// </summary>
+        /// <param name="buffer">The buffer.</param>
+        /// <returns></returns>
+        protected static uint LittleEndianToUInt32(byte[] buffer)
         {
-            uint n = (uint)bs[0];
-            n |= (uint)bs[1] << 8;
-            n |= (uint)bs[2] << 16;
-            n |= (uint)bs[3] << 24;
+            uint n = (uint)buffer[0];
+            n |= (uint)buffer[1] << 8;
+            n |= (uint)buffer[2] << 16;
+            n |= (uint)buffer[3] << 24;
             return n;
         }
 
-        protected static uint LE_To_UInt32(byte[] bs, int off)
+        /// <summary>
+        /// Converts little endian bytes into number.
+        /// </summary>
+        /// <param name="buffer">The buffer.</param>
+        /// <param name="offset">The buffer offset.</param>
+        /// <returns></returns>
+        protected static uint LittleEndianToUInt32(byte[] buffer, int offset)
         {
-            uint n = (uint)bs[off];
-            n |= (uint)bs[++off] << 8;
-            n |= (uint)bs[++off] << 16;
-            n |= (uint)bs[++off] << 24;
+            uint n = (uint)buffer[offset];
+            n |= (uint)buffer[++offset] << 8;
+            n |= (uint)buffer[++offset] << 16;
+            n |= (uint)buffer[++offset] << 24;
             return n;
         }
 
-        protected static ulong LE_To_UInt64(byte[] bs)
+        /// <summary>
+        /// Converts little endian bytes into number.
+        /// </summary>
+        /// <param name="buffer">The buffer.</param>
+        /// <returns></returns>
+        protected static ulong LittleEndianToUInt64(byte[] buffer)
         {
-            uint lo = LE_To_UInt32(bs);
-            uint hi = LE_To_UInt32(bs, 4);
+            uint lo = LittleEndianToUInt32(buffer);
+            uint hi = LittleEndianToUInt32(buffer, 4);
             return ((ulong)hi << 32) | (ulong)lo;
         }
 
-        protected static ulong LE_To_UInt64(byte[] bs, int off)
+        /// <summary>
+        /// Converts little endian bytes into number.
+        /// </summary>
+        /// <param name="buffer">The buffer.</param>
+        /// <param name="offset">The buffer offset.</param>
+        /// <returns></returns>
+        protected static ulong LittleEndianToUInt64(byte[] buffer, int offset)
         {
-            uint lo = LE_To_UInt32(bs, off);
-            uint hi = LE_To_UInt32(bs, off + 4);
+            uint lo = LittleEndianToUInt32(buffer, offset);
+            uint hi = LittleEndianToUInt32(buffer, offset + 4);
             return ((ulong)hi << 32) | (ulong)lo;
         }
 
-        protected static void UInt64_To_LE(ulong n, byte[] bs)
+        /// <summary>
+        /// Populates buffer with little endian number representation.
+        /// </summary>
+        /// <param name="number">The number to convert.</param>
+        /// <param name="buffer">The buffer.</param>
+        protected static void UInt64ToLittleEndian(ulong number, byte[] buffer)
         {
-            UInt32_To_LE((uint)(n), bs);
-            UInt32_To_LE((uint)(n >> 32), bs, 4);
+            UInt32ToLittleEndian((uint)(number), buffer);
+            UInt32ToLittleEndian((uint)(number >> 32), buffer, 4);
         }
 
-        protected static void UInt64_To_LE(ulong n, byte[] bs, int off)
+        /// <summary>
+        /// Populates buffer with little endian number representation.
+        /// </summary>
+        /// <param name="number">The number to convert.</param>
+        /// <param name="buffer">The buffer.</param>
+        /// <param name="offset">The buffer offset.</param>
+        protected static void UInt64ToLittleEndian(ulong number, byte[] buffer, int offset)
         {
-            UInt32_To_LE((uint)(n), bs, off);
-            UInt32_To_LE((uint)(n >> 32), bs, off + 4);
+            UInt32ToLittleEndian((uint)(number), buffer, offset);
+            UInt32ToLittleEndian((uint)(number >> 32), buffer, offset + 4);
         }
 
         #endregion

+ 489 - 475
Renci.SshClient/Renci.SshClient/Security/Cryptography/Ciphers/DesCipher.cs

@@ -6,487 +6,501 @@ using System.Security.Cryptography;
 
 namespace Renci.SshClient.Security.Cryptography
 {
-    /// <summary>
-    /// Represents the class for the DES algorithm.
-    /// </summary>
-    public class DesCipher : CipherBase
-    {
-        private int[] _encryptionKey;
-        /// <summary>
-        /// Gets the encryption key.
-        /// </summary>
-        protected int[] EncryptionKey
-        {
-            get
-            {
-                if (this._encryptionKey == null)
-                { 
-                    this._encryptionKey = DesCipher.GenerateWorkingKey(true, this.Key);                    
-                }
-
-                return this._encryptionKey;
-            }
-        }
-
-        private int[] _decryptionKey;
-        /// <summary>
-        /// Gets the decryption key.
-        /// </summary>
-        protected int[] DecryptionKey
-        {
-            get
-            {
-                if (this._decryptionKey == null)
-                {
-                    this._decryptionKey = DesCipher.GenerateWorkingKey(true, this.Key);
-                }
-
-                return this._decryptionKey;
-            }
-        }
-
-        #region Static tables
-
-        private static readonly short[] bytebit =
-        {
-            128, 64, 32, 16, 8, 4, 2, 1
-        };
-
-        private static readonly int[] bigbyte =
-        {
-            0x800000,	0x400000,	0x200000,	0x100000,
-            0x80000,	0x40000,	0x20000,	0x10000,
-            0x8000,		0x4000,		0x2000,		0x1000,
-            0x800,		0x400,		0x200,		0x100,
-            0x80,		0x40,		0x20,		0x10,
-            0x8,		0x4,		0x2,		0x1
-        };
-
-        /*
-        * Use the key schedule specified in the Standard (ANSI X3.92-1981).
-        */
-        private static readonly byte[] pc1 =
-        {
-            56, 48, 40, 32, 24, 16,  8,   0, 57, 49, 41, 33, 25, 17,
-            9,  1, 58, 50, 42, 34, 26,  18, 10,  2, 59, 51, 43, 35,
-            62, 54, 46, 38, 30, 22, 14,   6, 61, 53, 45, 37, 29, 21,
-            13,  5, 60, 52, 44, 36, 28,  20, 12,  4, 27, 19, 11,  3
-        };
-
-        private static readonly byte[] totrot =
-        {
-            1, 2, 4, 6, 8, 10, 12, 14,
-            15, 17, 19, 21, 23, 25, 27, 28
-        };
-
-        private static readonly byte[] pc2 =
-        {
-            13, 16, 10, 23,  0,  4,  2, 27, 14,  5, 20,  9,
-            22, 18, 11,  3, 25,  7, 15,  6, 26, 19, 12,  1,
-            40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
-            43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
-        };
-
-        private static readonly uint[] SP1 =
+	/// <summary>
+	/// Represents the class for the DES algorithm.
+	/// </summary>
+	public class DesCipher : CipherBase
+	{
+		private int[] _encryptionKey;
+		/// <summary>
+		/// Gets the encryption key.
+		/// </summary>
+		protected int[] EncryptionKey
 		{
-            0x01010400, 0x00000000, 0x00010000, 0x01010404,
-            0x01010004, 0x00010404, 0x00000004, 0x00010000,
-            0x00000400, 0x01010400, 0x01010404, 0x00000400,
-            0x01000404, 0x01010004, 0x01000000, 0x00000004,
-            0x00000404, 0x01000400, 0x01000400, 0x00010400,
-            0x00010400, 0x01010000, 0x01010000, 0x01000404,
-            0x00010004, 0x01000004, 0x01000004, 0x00010004,
-            0x00000000, 0x00000404, 0x00010404, 0x01000000,
-            0x00010000, 0x01010404, 0x00000004, 0x01010000,
-            0x01010400, 0x01000000, 0x01000000, 0x00000400,
-            0x01010004, 0x00010000, 0x00010400, 0x01000004,
-            0x00000400, 0x00000004, 0x01000404, 0x00010404,
-            0x01010404, 0x00010004, 0x01010000, 0x01000404,
-            0x01000004, 0x00000404, 0x00010404, 0x01010400,
-            0x00000404, 0x01000400, 0x01000400, 0x00000000,
-            0x00010004, 0x00010400, 0x00000000, 0x01010004
-        };
-
-        private static readonly uint[] SP2 =
+			get
+			{
+				if (this._encryptionKey == null)
+				{ 
+					this._encryptionKey = DesCipher.GenerateWorkingKey(true, this.Key);                    
+				}
+
+				return this._encryptionKey;
+			}
+		}
+
+		private int[] _decryptionKey;
+		/// <summary>
+		/// Gets the decryption key.
+		/// </summary>
+		protected int[] DecryptionKey
 		{
-            0x80108020, 0x80008000, 0x00008000, 0x00108020,
-            0x00100000, 0x00000020, 0x80100020, 0x80008020,
-            0x80000020, 0x80108020, 0x80108000, 0x80000000,
-            0x80008000, 0x00100000, 0x00000020, 0x80100020,
-            0x00108000, 0x00100020, 0x80008020, 0x00000000,
-            0x80000000, 0x00008000, 0x00108020, 0x80100000,
-            0x00100020, 0x80000020, 0x00000000, 0x00108000,
-            0x00008020, 0x80108000, 0x80100000, 0x00008020,
-            0x00000000, 0x00108020, 0x80100020, 0x00100000,
-            0x80008020, 0x80100000, 0x80108000, 0x00008000,
-            0x80100000, 0x80008000, 0x00000020, 0x80108020,
-            0x00108020, 0x00000020, 0x00008000, 0x80000000,
-            0x00008020, 0x80108000, 0x00100000, 0x80000020,
-            0x00100020, 0x80008020, 0x80000020, 0x00100020,
-            0x00108000, 0x00000000, 0x80008000, 0x00008020,
-            0x80000000, 0x80100020, 0x80108020, 0x00108000
-        };
-
-        private static readonly uint[] SP3 =
+			get
+			{
+				if (this._decryptionKey == null)
+				{
+					this._decryptionKey = DesCipher.GenerateWorkingKey(true, this.Key);
+				}
+
+				return this._decryptionKey;
+			}
+		}
+
+		#region Static tables
+
+		private static readonly short[] bytebit =
+		{
+			128, 64, 32, 16, 8, 4, 2, 1
+		};
+
+		private static readonly int[] bigbyte =
+		{
+			0x800000,	0x400000,	0x200000,	0x100000,
+			0x80000,	0x40000,	0x20000,	0x10000,
+			0x8000,		0x4000,		0x2000,		0x1000,
+			0x800,		0x400,		0x200,		0x100,
+			0x80,		0x40,		0x20,		0x10,
+			0x8,		0x4,		0x2,		0x1
+		};
+
+		/*
+		* Use the key schedule specified in the Standard (ANSI X3.92-1981).
+		*/
+		private static readonly byte[] pc1 =
+		{
+			56, 48, 40, 32, 24, 16,  8,   0, 57, 49, 41, 33, 25, 17,
+			9,  1, 58, 50, 42, 34, 26,  18, 10,  2, 59, 51, 43, 35,
+			62, 54, 46, 38, 30, 22, 14,   6, 61, 53, 45, 37, 29, 21,
+			13,  5, 60, 52, 44, 36, 28,  20, 12,  4, 27, 19, 11,  3
+		};
+
+		private static readonly byte[] totrot =
+		{
+			1, 2, 4, 6, 8, 10, 12, 14,
+			15, 17, 19, 21, 23, 25, 27, 28
+		};
+
+		private static readonly byte[] pc2 =
+		{
+			13, 16, 10, 23,  0,  4,  2, 27, 14,  5, 20,  9,
+			22, 18, 11,  3, 25,  7, 15,  6, 26, 19, 12,  1,
+			40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
+			43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
+		};
+
+		private static readonly uint[] SP1 =
 		{
-            0x00000208, 0x08020200, 0x00000000, 0x08020008,
-            0x08000200, 0x00000000, 0x00020208, 0x08000200,
-            0x00020008, 0x08000008, 0x08000008, 0x00020000,
-            0x08020208, 0x00020008, 0x08020000, 0x00000208,
-            0x08000000, 0x00000008, 0x08020200, 0x00000200,
-            0x00020200, 0x08020000, 0x08020008, 0x00020208,
-            0x08000208, 0x00020200, 0x00020000, 0x08000208,
-            0x00000008, 0x08020208, 0x00000200, 0x08000000,
-            0x08020200, 0x08000000, 0x00020008, 0x00000208,
-            0x00020000, 0x08020200, 0x08000200, 0x00000000,
-            0x00000200, 0x00020008, 0x08020208, 0x08000200,
-            0x08000008, 0x00000200, 0x00000000, 0x08020008,
-            0x08000208, 0x00020000, 0x08000000, 0x08020208,
-            0x00000008, 0x00020208, 0x00020200, 0x08000008,
-            0x08020000, 0x08000208, 0x00000208, 0x08020000,
-            0x00020208, 0x00000008, 0x08020008, 0x00020200
-        };
-
-        private static readonly uint[] SP4 =
+			0x01010400, 0x00000000, 0x00010000, 0x01010404,
+			0x01010004, 0x00010404, 0x00000004, 0x00010000,
+			0x00000400, 0x01010400, 0x01010404, 0x00000400,
+			0x01000404, 0x01010004, 0x01000000, 0x00000004,
+			0x00000404, 0x01000400, 0x01000400, 0x00010400,
+			0x00010400, 0x01010000, 0x01010000, 0x01000404,
+			0x00010004, 0x01000004, 0x01000004, 0x00010004,
+			0x00000000, 0x00000404, 0x00010404, 0x01000000,
+			0x00010000, 0x01010404, 0x00000004, 0x01010000,
+			0x01010400, 0x01000000, 0x01000000, 0x00000400,
+			0x01010004, 0x00010000, 0x00010400, 0x01000004,
+			0x00000400, 0x00000004, 0x01000404, 0x00010404,
+			0x01010404, 0x00010004, 0x01010000, 0x01000404,
+			0x01000004, 0x00000404, 0x00010404, 0x01010400,
+			0x00000404, 0x01000400, 0x01000400, 0x00000000,
+			0x00010004, 0x00010400, 0x00000000, 0x01010004
+		};
+
+		private static readonly uint[] SP2 =
 		{
-            0x00802001, 0x00002081, 0x00002081, 0x00000080,
-            0x00802080, 0x00800081, 0x00800001, 0x00002001,
-            0x00000000, 0x00802000, 0x00802000, 0x00802081,
-            0x00000081, 0x00000000, 0x00800080, 0x00800001,
-            0x00000001, 0x00002000, 0x00800000, 0x00802001,
-            0x00000080, 0x00800000, 0x00002001, 0x00002080,
-            0x00800081, 0x00000001, 0x00002080, 0x00800080,
-            0x00002000, 0x00802080, 0x00802081, 0x00000081,
-            0x00800080, 0x00800001, 0x00802000, 0x00802081,
-            0x00000081, 0x00000000, 0x00000000, 0x00802000,
-            0x00002080, 0x00800080, 0x00800081, 0x00000001,
-            0x00802001, 0x00002081, 0x00002081, 0x00000080,
-            0x00802081, 0x00000081, 0x00000001, 0x00002000,
-            0x00800001, 0x00002001, 0x00802080, 0x00800081,
-            0x00002001, 0x00002080, 0x00800000, 0x00802001,
-            0x00000080, 0x00800000, 0x00002000, 0x00802080
-        };
-
-        private static readonly uint[] SP5 =
+			0x80108020, 0x80008000, 0x00008000, 0x00108020,
+			0x00100000, 0x00000020, 0x80100020, 0x80008020,
+			0x80000020, 0x80108020, 0x80108000, 0x80000000,
+			0x80008000, 0x00100000, 0x00000020, 0x80100020,
+			0x00108000, 0x00100020, 0x80008020, 0x00000000,
+			0x80000000, 0x00008000, 0x00108020, 0x80100000,
+			0x00100020, 0x80000020, 0x00000000, 0x00108000,
+			0x00008020, 0x80108000, 0x80100000, 0x00008020,
+			0x00000000, 0x00108020, 0x80100020, 0x00100000,
+			0x80008020, 0x80100000, 0x80108000, 0x00008000,
+			0x80100000, 0x80008000, 0x00000020, 0x80108020,
+			0x00108020, 0x00000020, 0x00008000, 0x80000000,
+			0x00008020, 0x80108000, 0x00100000, 0x80000020,
+			0x00100020, 0x80008020, 0x80000020, 0x00100020,
+			0x00108000, 0x00000000, 0x80008000, 0x00008020,
+			0x80000000, 0x80100020, 0x80108020, 0x00108000
+		};
+
+		private static readonly uint[] SP3 =
 		{
-            0x00000100, 0x02080100, 0x02080000, 0x42000100,
-            0x00080000, 0x00000100, 0x40000000, 0x02080000,
-            0x40080100, 0x00080000, 0x02000100, 0x40080100,
-            0x42000100, 0x42080000, 0x00080100, 0x40000000,
-            0x02000000, 0x40080000, 0x40080000, 0x00000000,
-            0x40000100, 0x42080100, 0x42080100, 0x02000100,
-            0x42080000, 0x40000100, 0x00000000, 0x42000000,
-            0x02080100, 0x02000000, 0x42000000, 0x00080100,
-            0x00080000, 0x42000100, 0x00000100, 0x02000000,
-            0x40000000, 0x02080000, 0x42000100, 0x40080100,
-            0x02000100, 0x40000000, 0x42080000, 0x02080100,
-            0x40080100, 0x00000100, 0x02000000, 0x42080000,
-            0x42080100, 0x00080100, 0x42000000, 0x42080100,
-            0x02080000, 0x00000000, 0x40080000, 0x42000000,
-            0x00080100, 0x02000100, 0x40000100, 0x00080000,
-            0x00000000, 0x40080000, 0x02080100, 0x40000100
-        };
-
-        private static readonly uint[] SP6 =
+			0x00000208, 0x08020200, 0x00000000, 0x08020008,
+			0x08000200, 0x00000000, 0x00020208, 0x08000200,
+			0x00020008, 0x08000008, 0x08000008, 0x00020000,
+			0x08020208, 0x00020008, 0x08020000, 0x00000208,
+			0x08000000, 0x00000008, 0x08020200, 0x00000200,
+			0x00020200, 0x08020000, 0x08020008, 0x00020208,
+			0x08000208, 0x00020200, 0x00020000, 0x08000208,
+			0x00000008, 0x08020208, 0x00000200, 0x08000000,
+			0x08020200, 0x08000000, 0x00020008, 0x00000208,
+			0x00020000, 0x08020200, 0x08000200, 0x00000000,
+			0x00000200, 0x00020008, 0x08020208, 0x08000200,
+			0x08000008, 0x00000200, 0x00000000, 0x08020008,
+			0x08000208, 0x00020000, 0x08000000, 0x08020208,
+			0x00000008, 0x00020208, 0x00020200, 0x08000008,
+			0x08020000, 0x08000208, 0x00000208, 0x08020000,
+			0x00020208, 0x00000008, 0x08020008, 0x00020200
+		};
+
+		private static readonly uint[] SP4 =
 		{
-            0x20000010, 0x20400000, 0x00004000, 0x20404010,
-            0x20400000, 0x00000010, 0x20404010, 0x00400000,
-            0x20004000, 0x00404010, 0x00400000, 0x20000010,
-            0x00400010, 0x20004000, 0x20000000, 0x00004010,
-            0x00000000, 0x00400010, 0x20004010, 0x00004000,
-            0x00404000, 0x20004010, 0x00000010, 0x20400010,
-            0x20400010, 0x00000000, 0x00404010, 0x20404000,
-            0x00004010, 0x00404000, 0x20404000, 0x20000000,
-            0x20004000, 0x00000010, 0x20400010, 0x00404000,
-            0x20404010, 0x00400000, 0x00004010, 0x20000010,
-            0x00400000, 0x20004000, 0x20000000, 0x00004010,
-            0x20000010, 0x20404010, 0x00404000, 0x20400000,
-            0x00404010, 0x20404000, 0x00000000, 0x20400010,
-            0x00000010, 0x00004000, 0x20400000, 0x00404010,
-            0x00004000, 0x00400010, 0x20004010, 0x00000000,
-            0x20404000, 0x20000000, 0x00400010, 0x20004010
-        };
-
-        private static readonly uint[] SP7 =
+			0x00802001, 0x00002081, 0x00002081, 0x00000080,
+			0x00802080, 0x00800081, 0x00800001, 0x00002001,
+			0x00000000, 0x00802000, 0x00802000, 0x00802081,
+			0x00000081, 0x00000000, 0x00800080, 0x00800001,
+			0x00000001, 0x00002000, 0x00800000, 0x00802001,
+			0x00000080, 0x00800000, 0x00002001, 0x00002080,
+			0x00800081, 0x00000001, 0x00002080, 0x00800080,
+			0x00002000, 0x00802080, 0x00802081, 0x00000081,
+			0x00800080, 0x00800001, 0x00802000, 0x00802081,
+			0x00000081, 0x00000000, 0x00000000, 0x00802000,
+			0x00002080, 0x00800080, 0x00800081, 0x00000001,
+			0x00802001, 0x00002081, 0x00002081, 0x00000080,
+			0x00802081, 0x00000081, 0x00000001, 0x00002000,
+			0x00800001, 0x00002001, 0x00802080, 0x00800081,
+			0x00002001, 0x00002080, 0x00800000, 0x00802001,
+			0x00000080, 0x00800000, 0x00002000, 0x00802080
+		};
+
+		private static readonly uint[] SP5 =
+		{
+			0x00000100, 0x02080100, 0x02080000, 0x42000100,
+			0x00080000, 0x00000100, 0x40000000, 0x02080000,
+			0x40080100, 0x00080000, 0x02000100, 0x40080100,
+			0x42000100, 0x42080000, 0x00080100, 0x40000000,
+			0x02000000, 0x40080000, 0x40080000, 0x00000000,
+			0x40000100, 0x42080100, 0x42080100, 0x02000100,
+			0x42080000, 0x40000100, 0x00000000, 0x42000000,
+			0x02080100, 0x02000000, 0x42000000, 0x00080100,
+			0x00080000, 0x42000100, 0x00000100, 0x02000000,
+			0x40000000, 0x02080000, 0x42000100, 0x40080100,
+			0x02000100, 0x40000000, 0x42080000, 0x02080100,
+			0x40080100, 0x00000100, 0x02000000, 0x42080000,
+			0x42080100, 0x00080100, 0x42000000, 0x42080100,
+			0x02080000, 0x00000000, 0x40080000, 0x42000000,
+			0x00080100, 0x02000100, 0x40000100, 0x00080000,
+			0x00000000, 0x40080000, 0x02080100, 0x40000100
+		};
+
+		private static readonly uint[] SP6 =
+		{
+			0x20000010, 0x20400000, 0x00004000, 0x20404010,
+			0x20400000, 0x00000010, 0x20404010, 0x00400000,
+			0x20004000, 0x00404010, 0x00400000, 0x20000010,
+			0x00400010, 0x20004000, 0x20000000, 0x00004010,
+			0x00000000, 0x00400010, 0x20004010, 0x00004000,
+			0x00404000, 0x20004010, 0x00000010, 0x20400010,
+			0x20400010, 0x00000000, 0x00404010, 0x20404000,
+			0x00004010, 0x00404000, 0x20404000, 0x20000000,
+			0x20004000, 0x00000010, 0x20400010, 0x00404000,
+			0x20404010, 0x00400000, 0x00004010, 0x20000010,
+			0x00400000, 0x20004000, 0x20000000, 0x00004010,
+			0x20000010, 0x20404010, 0x00404000, 0x20400000,
+			0x00404010, 0x20404000, 0x00000000, 0x20400010,
+			0x00000010, 0x00004000, 0x20400000, 0x00404010,
+			0x00004000, 0x00400010, 0x20004010, 0x00000000,
+			0x20404000, 0x20000000, 0x00400010, 0x20004010
+		};
+
+		private static readonly uint[] SP7 =
+		{
+			0x00200000, 0x04200002, 0x04000802, 0x00000000,
+			0x00000800, 0x04000802, 0x00200802, 0x04200800,
+			0x04200802, 0x00200000, 0x00000000, 0x04000002,
+			0x00000002, 0x04000000, 0x04200002, 0x00000802,
+			0x04000800, 0x00200802, 0x00200002, 0x04000800,
+			0x04000002, 0x04200000, 0x04200800, 0x00200002,
+			0x04200000, 0x00000800, 0x00000802, 0x04200802,
+			0x00200800, 0x00000002, 0x04000000, 0x00200800,
+			0x04000000, 0x00200800, 0x00200000, 0x04000802,
+			0x04000802, 0x04200002, 0x04200002, 0x00000002,
+			0x00200002, 0x04000000, 0x04000800, 0x00200000,
+			0x04200800, 0x00000802, 0x00200802, 0x04200800,
+			0x00000802, 0x04000002, 0x04200802, 0x04200000,
+			0x00200800, 0x00000000, 0x00000002, 0x04200802,
+			0x00000000, 0x00200802, 0x04200000, 0x00000800,
+			0x04000002, 0x04000800, 0x00000800, 0x00200002
+		};
+
+		private static readonly uint[] SP8 =
+		{
+			0x10001040, 0x00001000, 0x00040000, 0x10041040,
+			0x10000000, 0x10001040, 0x00000040, 0x10000000,
+			0x00040040, 0x10040000, 0x10041040, 0x00041000,
+			0x10041000, 0x00041040, 0x00001000, 0x00000040,
+			0x10040000, 0x10000040, 0x10001000, 0x00001040,
+			0x00041000, 0x00040040, 0x10040040, 0x10041000,
+			0x00001040, 0x00000000, 0x00000000, 0x10040040,
+			0x10000040, 0x10001000, 0x00041040, 0x00040000,
+			0x00041040, 0x00040000, 0x10041000, 0x00001000,
+			0x00000040, 0x10040040, 0x00001000, 0x00041040,
+			0x10001000, 0x00000040, 0x10000040, 0x10040000,
+			0x10040040, 0x10000000, 0x00040000, 0x10001040,
+			0x00000000, 0x10041040, 0x00040040, 0x10000040,
+			0x10040000, 0x10001000, 0x10001040, 0x00000000,
+			0x10041040, 0x00041000, 0x00041000, 0x00001040,
+			0x00001040, 0x00040040, 0x10000000, 0x10041000
+		};
+
+		#endregion
+
+		/// <summary>
+		/// Gets the size of the block.
+		/// </summary>
+		/// <value>
+		/// The size of the block.
+		/// </value>
+		public override int BlockSize
+		{
+			get { return 8; }
+		}
+
+		/// <summary>
+		/// Initializes a new instance of the <see cref="DesCipher"/> class.
+		/// </summary>
+		/// <param name="key">The key.</param>
+		/// <param name="iv">The iv.</param>
+		public DesCipher(byte[] key, byte[] iv)
+			: base(key, iv)
+		{
+		}
+
+		/// <summary>
+		/// Encrypts the specified region of the input byte array and copies the encrypted data to the specified region of the output byte array.
+		/// </summary>
+		/// <param name="inputBuffer">The input data to encrypt.</param>
+		/// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
+		/// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
+		/// <param name="outputBuffer">The output to which to write encrypted data.</param>
+		/// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
+		/// <returns>
+		/// The number of bytes encrypted.
+		/// </returns>
+		public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
+		{
+			if ((inputOffset + this.BlockSize) > inputBuffer.Length)
+				throw new IndexOutOfRangeException("input buffer too short");
+
+			if ((outputOffset + this.BlockSize) > outputBuffer.Length)
+				throw new IndexOutOfRangeException("output buffer too short");
+
+			DesCipher.DesFunc(this.EncryptionKey, inputBuffer, inputOffset, outputBuffer, outputOffset);
+
+			return this.BlockSize;
+		}
+
+		/// <summary>
+		/// Decrypts the specified region of the input byte array and copies the decrypted data to the specified region of the output byte array.
+		/// </summary>
+		/// <param name="inputBuffer">The input data to decrypt.</param>
+		/// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
+		/// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
+		/// <param name="outputBuffer">The output to which to write decrypted data.</param>
+		/// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
+		/// <returns>
+		/// The number of bytes decrypted.
+		/// </returns>
+		public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
+		{
+			if ((inputOffset + this.BlockSize) > inputBuffer.Length)
+				throw new IndexOutOfRangeException("input buffer too short");
+
+			if ((outputOffset + this.BlockSize) > outputBuffer.Length)
+				throw new IndexOutOfRangeException("output buffer too short");
+
+			DesCipher.DesFunc(this.DecryptionKey, inputBuffer, inputOffset, outputBuffer, outputOffset);
+
+			return this.BlockSize;
+		}
+
+		/// <summary>
+		/// Generates the working key.
+		/// </summary>
+		/// <param name="encrypting">if set to <c>true</c> [encrypting].</param>
+		/// <param name="key">The key.</param>
+		/// <returns></returns>
+		protected static int[] GenerateWorkingKey(bool encrypting, byte[] key)
 		{
-            0x00200000, 0x04200002, 0x04000802, 0x00000000,
-            0x00000800, 0x04000802, 0x00200802, 0x04200800,
-            0x04200802, 0x00200000, 0x00000000, 0x04000002,
-            0x00000002, 0x04000000, 0x04200002, 0x00000802,
-            0x04000800, 0x00200802, 0x00200002, 0x04000800,
-            0x04000002, 0x04200000, 0x04200800, 0x00200002,
-            0x04200000, 0x00000800, 0x00000802, 0x04200802,
-            0x00200800, 0x00000002, 0x04000000, 0x00200800,
-            0x04000000, 0x00200800, 0x00200000, 0x04000802,
-            0x04000802, 0x04200002, 0x04200002, 0x00000002,
-            0x00200002, 0x04000000, 0x04000800, 0x00200000,
-            0x04200800, 0x00000802, 0x00200802, 0x04200800,
-            0x00000802, 0x04000002, 0x04200802, 0x04200000,
-            0x00200800, 0x00000000, 0x00000002, 0x04200802,
-            0x00000000, 0x00200802, 0x04200000, 0x00000800,
-            0x04000002, 0x04000800, 0x00000800, 0x00200002
-        };
-
-        private static readonly uint[] SP8 =
+			int[] newKey = new int[32];
+			bool[] pc1m = new bool[56];
+			bool[] pcr = new bool[56];
+
+			for (int j = 0; j < 56; j++)
+			{
+				int l = pc1[j];
+
+				pc1m[j] = ((key[(uint)l >> 3] & bytebit[l & 07]) != 0);
+			}
+
+			for (int i = 0; i < 16; i++)
+			{
+				int l, m, n;
+
+				if (encrypting)
+				{
+					m = i << 1;
+				}
+				else
+				{
+					m = (15 - i) << 1;
+				}
+
+				n = m + 1;
+				newKey[m] = newKey[n] = 0;
+
+				for (int j = 0; j < 28; j++)
+				{
+					l = j + totrot[i];
+					if (l < 28)
+					{
+						pcr[j] = pc1m[l];
+					}
+					else
+					{
+						pcr[j] = pc1m[l - 28];
+					}
+				}
+
+				for (int j = 28; j < 56; j++)
+				{
+					l = j + totrot[i];
+					if (l < 56)
+					{
+						pcr[j] = pc1m[l];
+					}
+					else
+					{
+						pcr[j] = pc1m[l - 28];
+					}
+				}
+
+				for (int j = 0; j < 24; j++)
+				{
+					if (pcr[pc2[j]])
+					{
+						newKey[m] |= bigbyte[j];
+					}
+
+					if (pcr[pc2[j + 24]])
+					{
+						newKey[n] |= bigbyte[j];
+					}
+				}
+			}
+
+			//
+			// store the processed key
+			//
+			for (int i = 0; i != 32; i += 2)
+			{
+				int i1, i2;
+
+				i1 = newKey[i];
+				i2 = newKey[i + 1];
+
+				newKey[i] = (int)((uint)((i1 & 0x00fc0000) << 6) |
+									(uint)((i1 & 0x00000fc0) << 10) |
+									((uint)(i2 & 0x00fc0000) >> 10) |
+									((uint)(i2 & 0x00000fc0) >> 6));
+
+				newKey[i + 1] = (int)((uint)((i1 & 0x0003f000) << 12) |
+										(uint)((i1 & 0x0000003f) << 16) |
+										((uint)(i2 & 0x0003f000) >> 4) |
+										(uint)(i2 & 0x0000003f));
+			}
+
+			return newKey;
+		}
+
+		/// <summary>
+		/// Perfoms DES function.
+		/// </summary>
+		/// <param name="wKey">The w key.</param>
+		/// <param name="input">The input.</param>
+		/// <param name="inOff">The in off.</param>
+		/// <param name="outBytes">The out bytes.</param>
+		/// <param name="outOff">The out off.</param>
+		protected static void DesFunc(int[] wKey, byte[] input, int inOff, byte[] outBytes, int outOff)
 		{
-            0x10001040, 0x00001000, 0x00040000, 0x10041040,
-            0x10000000, 0x10001040, 0x00000040, 0x10000000,
-            0x00040040, 0x10040000, 0x10041040, 0x00041000,
-            0x10041000, 0x00041040, 0x00001000, 0x00000040,
-            0x10040000, 0x10000040, 0x10001000, 0x00001040,
-            0x00041000, 0x00040040, 0x10040040, 0x10041000,
-            0x00001040, 0x00000000, 0x00000000, 0x10040040,
-            0x10000040, 0x10001000, 0x00041040, 0x00040000,
-            0x00041040, 0x00040000, 0x10041000, 0x00001000,
-            0x00000040, 0x10040040, 0x00001000, 0x00041040,
-            0x10001000, 0x00000040, 0x10000040, 0x10040000,
-            0x10040040, 0x10000000, 0x00040000, 0x10001040,
-            0x00000000, 0x10041040, 0x00040040, 0x10000040,
-            0x10040000, 0x10001000, 0x10001040, 0x00000000,
-            0x10041040, 0x00041000, 0x00041000, 0x00001040,
-            0x00001040, 0x00040040, 0x10000000, 0x10041000
-        };
-
-        #endregion
-
-        /// <summary>
-        /// Gets the size of the block.
-        /// </summary>
-        /// <value>
-        /// The size of the block.
-        /// </value>
-        public override int BlockSize
-        {
-            get { return 8; }
-        }
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="DesCipher"/> class.
-        /// </summary>
-        /// <param name="key">The key.</param>
-        /// <param name="iv">The iv.</param>
-        public DesCipher(byte[] key, byte[] iv)
-            : base(key, iv)
-        {
-        }
-
-        /// <summary>
-        /// Encrypts the specified region of the input byte array and copies the encrypted data to the specified region of the output byte array.
-        /// </summary>
-        /// <param name="inputBuffer">The input data to encrypt.</param>
-        /// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
-        /// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
-        /// <param name="outputBuffer">The output to which to write encrypted data.</param>
-        /// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
-        /// <returns>
-        /// The number of bytes encrypted.
-        /// </returns>
-        public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
-        {
-            if ((inputOffset + this.BlockSize) > inputBuffer.Length)
-                throw new IndexOutOfRangeException("input buffer too short");
-
-            if ((outputOffset + this.BlockSize) > outputBuffer.Length)
-                throw new IndexOutOfRangeException("output buffer too short");
-
-            DesCipher.DesFunc(this.EncryptionKey, inputBuffer, inputOffset, outputBuffer, outputOffset);
-
-            return this.BlockSize;
-        }
-
-        /// <summary>
-        /// Decrypts the specified region of the input byte array and copies the decrypted data to the specified region of the output byte array.
-        /// </summary>
-        /// <param name="inputBuffer">The input data to decrypt.</param>
-        /// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
-        /// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
-        /// <param name="outputBuffer">The output to which to write decrypted data.</param>
-        /// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
-        /// <returns>
-        /// The number of bytes decrypted.
-        /// </returns>
-        public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
-        {
-            if ((inputOffset + this.BlockSize) > inputBuffer.Length)
-                throw new IndexOutOfRangeException("input buffer too short");
-
-            if ((outputOffset + this.BlockSize) > outputBuffer.Length)
-                throw new IndexOutOfRangeException("output buffer too short");
-
-            DesCipher.DesFunc(this.DecryptionKey, inputBuffer, inputOffset, outputBuffer, outputOffset);
-
-            return this.BlockSize;
-        }
-
-        protected static int[] GenerateWorkingKey(bool encrypting, byte[] key)
-        {
-            int[] newKey = new int[32];
-            bool[] pc1m = new bool[56];
-            bool[] pcr = new bool[56];
-
-            for (int j = 0; j < 56; j++)
-            {
-                int l = pc1[j];
-
-                pc1m[j] = ((key[(uint)l >> 3] & bytebit[l & 07]) != 0);
-            }
-
-            for (int i = 0; i < 16; i++)
-            {
-                int l, m, n;
-
-                if (encrypting)
-                {
-                    m = i << 1;
-                }
-                else
-                {
-                    m = (15 - i) << 1;
-                }
-
-                n = m + 1;
-                newKey[m] = newKey[n] = 0;
-
-                for (int j = 0; j < 28; j++)
-                {
-                    l = j + totrot[i];
-                    if (l < 28)
-                    {
-                        pcr[j] = pc1m[l];
-                    }
-                    else
-                    {
-                        pcr[j] = pc1m[l - 28];
-                    }
-                }
-
-                for (int j = 28; j < 56; j++)
-                {
-                    l = j + totrot[i];
-                    if (l < 56)
-                    {
-                        pcr[j] = pc1m[l];
-                    }
-                    else
-                    {
-                        pcr[j] = pc1m[l - 28];
-                    }
-                }
-
-                for (int j = 0; j < 24; j++)
-                {
-                    if (pcr[pc2[j]])
-                    {
-                        newKey[m] |= bigbyte[j];
-                    }
-
-                    if (pcr[pc2[j + 24]])
-                    {
-                        newKey[n] |= bigbyte[j];
-                    }
-                }
-            }
-
-            //
-            // store the processed key
-            //
-            for (int i = 0; i != 32; i += 2)
-            {
-                int i1, i2;
-
-                i1 = newKey[i];
-                i2 = newKey[i + 1];
-
-                newKey[i] = (int)((uint)((i1 & 0x00fc0000) << 6) |
-                                    (uint)((i1 & 0x00000fc0) << 10) |
-                                    ((uint)(i2 & 0x00fc0000) >> 10) |
-                                    ((uint)(i2 & 0x00000fc0) >> 6));
-
-                newKey[i + 1] = (int)((uint)((i1 & 0x0003f000) << 12) |
-                                        (uint)((i1 & 0x0000003f) << 16) |
-                                        ((uint)(i2 & 0x0003f000) >> 4) |
-                                        (uint)(i2 & 0x0000003f));
-            }
-
-            return newKey;
-        }
-
-        protected static void DesFunc(int[] wKey, byte[] input, int inOff, byte[] outBytes, int outOff)
-        {
-            uint left = CipherBase.BE_To_UInt32(input, inOff);
-            uint right = CipherBase.BE_To_UInt32(input, inOff + 4);
-            uint work;
-
-            work = ((left >> 4) ^ right) & 0x0f0f0f0f;
-            right ^= work;
-            left ^= (work << 4);
-            work = ((left >> 16) ^ right) & 0x0000ffff;
-            right ^= work;
-            left ^= (work << 16);
-            work = ((right >> 2) ^ left) & 0x33333333;
-            left ^= work;
-            right ^= (work << 2);
-            work = ((right >> 8) ^ left) & 0x00ff00ff;
-            left ^= work;
-            right ^= (work << 8);
-            right = (right << 1) | (right >> 31);
-            work = (left ^ right) & 0xaaaaaaaa;
-            left ^= work;
-            right ^= work;
-            left = (left << 1) | (left >> 31);
-
-            for (int round = 0; round < 8; round++)
-            {
-                uint fval;
-
-                work = (right << 28) | (right >> 4);
-                work ^= (uint)wKey[round * 4 + 0];
-                fval = SP7[work & 0x3f];
-                fval |= SP5[(work >> 8) & 0x3f];
-                fval |= SP3[(work >> 16) & 0x3f];
-                fval |= SP1[(work >> 24) & 0x3f];
-                work = right ^ (uint)wKey[round * 4 + 1];
-                fval |= SP8[work & 0x3f];
-                fval |= SP6[(work >> 8) & 0x3f];
-                fval |= SP4[(work >> 16) & 0x3f];
-                fval |= SP2[(work >> 24) & 0x3f];
-                left ^= fval;
-                work = (left << 28) | (left >> 4);
-                work ^= (uint)wKey[round * 4 + 2];
-                fval = SP7[work & 0x3f];
-                fval |= SP5[(work >> 8) & 0x3f];
-                fval |= SP3[(work >> 16) & 0x3f];
-                fval |= SP1[(work >> 24) & 0x3f];
-                work = left ^ (uint)wKey[round * 4 + 3];
-                fval |= SP8[work & 0x3f];
-                fval |= SP6[(work >> 8) & 0x3f];
-                fval |= SP4[(work >> 16) & 0x3f];
-                fval |= SP2[(work >> 24) & 0x3f];
-                right ^= fval;
-            }
-
-            right = (right << 31) | (right >> 1);
-            work = (left ^ right) & 0xaaaaaaaa;
-            left ^= work;
-            right ^= work;
-            left = (left << 31) | (left >> 1);
-            work = ((left >> 8) ^ right) & 0x00ff00ff;
-            right ^= work;
-            left ^= (work << 8);
-            work = ((left >> 2) ^ right) & 0x33333333;
-            right ^= work;
-            left ^= (work << 2);
-            work = ((right >> 16) ^ left) & 0x0000ffff;
-            left ^= work;
-            right ^= (work << 16);
-            work = ((right >> 4) ^ left) & 0x0f0f0f0f;
-            left ^= work;
-            right ^= (work << 4);
-
-            CipherBase.UInt32_To_BE(right, outBytes, outOff);
-            CipherBase.UInt32_To_BE(left, outBytes, outOff + 4);
-        }
-
-
-    }
+			uint left = CipherBase.BigEndianToUInt32(input, inOff);
+			uint right = CipherBase.BigEndianToUInt32(input, inOff + 4);
+			uint work;
+
+			work = ((left >> 4) ^ right) & 0x0f0f0f0f;
+			right ^= work;
+			left ^= (work << 4);
+			work = ((left >> 16) ^ right) & 0x0000ffff;
+			right ^= work;
+			left ^= (work << 16);
+			work = ((right >> 2) ^ left) & 0x33333333;
+			left ^= work;
+			right ^= (work << 2);
+			work = ((right >> 8) ^ left) & 0x00ff00ff;
+			left ^= work;
+			right ^= (work << 8);
+			right = (right << 1) | (right >> 31);
+			work = (left ^ right) & 0xaaaaaaaa;
+			left ^= work;
+			right ^= work;
+			left = (left << 1) | (left >> 31);
+
+			for (int round = 0; round < 8; round++)
+			{
+				uint fval;
+
+				work = (right << 28) | (right >> 4);
+				work ^= (uint)wKey[round * 4 + 0];
+				fval = SP7[work & 0x3f];
+				fval |= SP5[(work >> 8) & 0x3f];
+				fval |= SP3[(work >> 16) & 0x3f];
+				fval |= SP1[(work >> 24) & 0x3f];
+				work = right ^ (uint)wKey[round * 4 + 1];
+				fval |= SP8[work & 0x3f];
+				fval |= SP6[(work >> 8) & 0x3f];
+				fval |= SP4[(work >> 16) & 0x3f];
+				fval |= SP2[(work >> 24) & 0x3f];
+				left ^= fval;
+				work = (left << 28) | (left >> 4);
+				work ^= (uint)wKey[round * 4 + 2];
+				fval = SP7[work & 0x3f];
+				fval |= SP5[(work >> 8) & 0x3f];
+				fval |= SP3[(work >> 16) & 0x3f];
+				fval |= SP1[(work >> 24) & 0x3f];
+				work = left ^ (uint)wKey[round * 4 + 3];
+				fval |= SP8[work & 0x3f];
+				fval |= SP6[(work >> 8) & 0x3f];
+				fval |= SP4[(work >> 16) & 0x3f];
+				fval |= SP2[(work >> 24) & 0x3f];
+				right ^= fval;
+			}
+
+			right = (right << 31) | (right >> 1);
+			work = (left ^ right) & 0xaaaaaaaa;
+			left ^= work;
+			right ^= work;
+			left = (left << 31) | (left >> 1);
+			work = ((left >> 8) ^ right) & 0x00ff00ff;
+			right ^= work;
+			left ^= (work << 8);
+			work = ((left >> 2) ^ right) & 0x33333333;
+			right ^= work;
+			left ^= (work << 2);
+			work = ((right >> 16) ^ left) & 0x0000ffff;
+			left ^= work;
+			right ^= (work << 16);
+			work = ((right >> 4) ^ left) & 0x0f0f0f0f;
+			left ^= work;
+			right ^= (work << 4);
+
+			CipherBase.UInt32ToBigEndian(right, outBytes, outOff);
+			CipherBase.UInt32ToBigEndian(left, outBytes, outOff + 4);
+		}
+
+
+	}
 }

+ 32 - 2
Renci.SshClient/Renci.SshClient/Security/Cryptography/Ciphers/TripleDesCipher.cs

@@ -14,13 +14,27 @@ namespace Renci.SshClient.Security.Cryptography
         private byte[] _pass1;
         private byte[] _pass2;
 
+        /// <summary>
+        /// Initializes a new instance of the <see cref="TripleDesCipher"/> class.
+        /// </summary>
+        /// <param name="key">The key.</param>
+        /// <param name="iv">The iv.</param>
         public TripleDesCipher(byte[] key, byte[] iv)
             : base(key, iv)
         {
-            this._pass1 = new byte[this.BlockSize];
-            this._pass2 = new byte[this.BlockSize];
         }
 
+        /// <summary>
+        /// Encrypts the specified region of the input byte array and copies the encrypted data to the specified region of the output byte array.
+        /// </summary>
+        /// <param name="inputBuffer">The input data to encrypt.</param>
+        /// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
+        /// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
+        /// <param name="outputBuffer">The output to which to write encrypted data.</param>
+        /// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
+        /// <returns>
+        /// The number of bytes encrypted.
+        /// </returns>
         public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
         {
             if ((inputOffset + this.BlockSize) > inputBuffer.Length)
@@ -29,6 +43,11 @@ namespace Renci.SshClient.Security.Cryptography
             if ((outputOffset + this.BlockSize) > outputBuffer.Length)
                 throw new IndexOutOfRangeException("output buffer too short");
 
+            if (this._pass1 == null)
+                this._pass1 = new byte[this.BlockSize];
+            if (this._pass2 == null)
+                this._pass2 = new byte[this.BlockSize];
+
             DesCipher.DesFunc(this.EncryptionKey, inputBuffer, inputOffset, this._pass1, 0);
             DesCipher.DesFunc(this.EncryptionKey, this._pass1, 0, this._pass2, 0);
             DesCipher.DesFunc(this.EncryptionKey, this._pass2, 0, outputBuffer, outputOffset);
@@ -36,6 +55,17 @@ namespace Renci.SshClient.Security.Cryptography
             return this.BlockSize;
         }
 
+        /// <summary>
+        /// Decrypts the specified region of the input byte array and copies the decrypted data to the specified region of the output byte array.
+        /// </summary>
+        /// <param name="inputBuffer">The input data to decrypt.</param>
+        /// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
+        /// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
+        /// <param name="outputBuffer">The output to which to write decrypted data.</param>
+        /// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
+        /// <returns>
+        /// The number of bytes decrypted.
+        /// </returns>
         public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
         {
             if ((inputOffset + this.BlockSize) > inputBuffer.Length)

+ 1 - 2
Renci.SshClient/Renci.SshClient/Security/Cryptography/Des.cs

@@ -15,8 +15,7 @@ namespace Renci.SshClient.Security.Cryptography
         /// <summary>
         /// Initializes a new instance of the <see cref="Des"/> class.
         /// </summary>
-        /// <param name="keySize">Size of the key.</param>
-        public Des(int keySize)
+        public Des()
         {
             this.KeySizeValue = 64;
             this.BlockSizeValue = 64;

+ 26 - 0
Renci.SshClient/Renci.SshClient/Security/Cryptography/Modes/CbcMode.cs

@@ -28,6 +28,10 @@ namespace Renci.SshClient.Security.Cryptography
             get { return this._blockSize; }
         }
 
+        /// <summary>
+        /// Initializes a new instance of the <see cref="CbcMode"/> class.
+        /// </summary>
+        /// <param name="cipher">The cipher.</param>
         public CbcMode(CipherBase cipher)
             : base(cipher)
         {
@@ -36,6 +40,17 @@ namespace Renci.SshClient.Security.Cryptography
             this._nextIV = new byte[this._iv.Length];
         }
 
+        /// <summary>
+        /// Encrypts the specified region of the input byte array and copies the encrypted data to the specified region of the output byte array.
+        /// </summary>
+        /// <param name="inputBuffer">The input data to encrypt.</param>
+        /// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
+        /// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
+        /// <param name="outputBuffer">The output to which to write encrypted data.</param>
+        /// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
+        /// <returns>
+        /// The number of bytes encrypted.
+        /// </returns>
         public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
         {
             if (inputBuffer.Length - inputOffset < this._blockSize)
@@ -59,6 +74,17 @@ namespace Renci.SshClient.Security.Cryptography
             return this._blockSize;
         }
 
+        /// <summary>
+        /// Decrypts the specified region of the input byte array and copies the decrypted data to the specified region of the output byte array.
+        /// </summary>
+        /// <param name="inputBuffer">The input data to decrypt.</param>
+        /// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
+        /// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
+        /// <param name="outputBuffer">The output to which to write decrypted data.</param>
+        /// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
+        /// <returns>
+        /// The number of bytes decrypted.
+        /// </returns>
         public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
         {
             if (inputBuffer.Length - inputOffset < this._blockSize)

+ 4 - 0
Renci.SshClient/Renci.SshClient/Security/Cryptography/Modes/CfbMode.cs

@@ -28,6 +28,10 @@ namespace Renci.SshClient.Security.Cryptography
             get { return this._blockSize; }
         }
 
+        /// <summary>
+        /// Initializes a new instance of the <see cref="CfbMode"/> class.
+        /// </summary>
+        /// <param name="cipher">The cipher.</param>
         public CfbMode(CipherBase cipher)
             : base(cipher)
         {

+ 23 - 20
Renci.SshClient/Renci.SshClient/Session.cs

@@ -17,6 +17,7 @@ using Renci.SshClient.Messages.Authentication;
 using Renci.SshClient.Messages.Connection;
 using Renci.SshClient.Messages.Transport;
 using Renci.SshClient.Security;
+using System.Globalization;
 
 namespace Renci.SshClient
 {
@@ -385,7 +386,7 @@ namespace Renci.SshClient
         internal Session(ConnectionInfo connectionInfo)
         {
             this.ConnectionInfo = connectionInfo;
-            this.ClientVersion = string.Format("SSH-2.0-Renci.SshClient.{0}", this.GetType().Assembly.GetName().Version);
+            this.ClientVersion = string.Format(CultureInfo.CurrentCulture, "SSH-2.0-Renci.SshClient.{0}", this.GetType().Assembly.GetName().Version);
         }
 
         /// <summary>
@@ -471,10 +472,10 @@ namespace Renci.SshClient
 
                     if (!(version.Equals("2.0") || version.Equals("1.99")))
                     {
-                        throw new SshConnectionException(string.Format("Server version '{0}' is not supported.", version), DisconnectReasons.ProtocolVersionNotSupported);
+                        throw new SshConnectionException(string.Format(CultureInfo.CurrentCulture, "Server version '{0}' is not supported.", version), DisconnectReasons.ProtocolVersionNotSupported);
                     }
 
-                    this.Write(Encoding.ASCII.GetBytes(string.Format("{0}\x0D\x0A", this.ClientVersion)));
+                    this.Write(Encoding.ASCII.GetBytes(string.Format(CultureInfo.InvariantCulture, "{0}\x0D\x0A", this.ClientVersion)));
 
                     //  Register Transport response messages
                     this.RegisterMessage("SSH_MSG_DISCONNECT");
@@ -513,24 +514,26 @@ namespace Renci.SshClient
                     }
 
                     //  Try authenticate using none method
-                    var noneConnectionInfo = new NoneConnectionInfo(this.ConnectionInfo.Host, this.ConnectionInfo.Port, this.ConnectionInfo.Username);
-                    noneConnectionInfo.Authenticate(this);
+                    using (var noneConnectionInfo = new NoneConnectionInfo(this.ConnectionInfo.Host, this.ConnectionInfo.Port, this.ConnectionInfo.Username))
+                    {
+                        noneConnectionInfo.Authenticate(this);
 
-                    this._isAuthenticated = noneConnectionInfo.IsAuthenticated;
+                        this._isAuthenticated = noneConnectionInfo.IsAuthenticated;
 
-                    if (!this._isAuthenticated)
-                    {
-                        //  Ensure that authentication method is allowed
-                        if (!noneConnectionInfo.AllowedAuthentications.Contains(this.ConnectionInfo.Name))
+                        if (!this._isAuthenticated)
                         {
-                            throw new SshAuthenticationException("User authentication method is not supported.");
-                        }
+                            //  Ensure that authentication method is allowed
+                            if (!noneConnectionInfo.AllowedAuthentications.Contains(this.ConnectionInfo.Name))
+                            {
+                                throw new SshAuthenticationException("User authentication method is not supported.");
+                            }
 
-                        //  In future, if more then one authentication methods are supported perform the check here.
-                        //  Authenticate using provided connection info object
-                        this.ConnectionInfo.Authenticate(this);
+                            //  In future, if more then one authentication methods are supported perform the check here.
+                            //  Authenticate using provided connection info object
+                            this.ConnectionInfo.Authenticate(this);
 
-                        this._isAuthenticated = this.ConnectionInfo.IsAuthenticated;
+                            this._isAuthenticated = this.ConnectionInfo.IsAuthenticated;
+                        }
                     }
 
                     if (!this._isAuthenticated)
@@ -635,7 +638,7 @@ namespace Renci.SshClient
 
             if (messageData.Length > Session.MAXIMUM_PAYLOAD_SIZE)
             {
-                throw new InvalidOperationException(string.Format("Payload cannot be more then {0} bytes.", Session.MAXIMUM_PAYLOAD_SIZE));
+                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "Payload cannot be more then {0} bytes.", Session.MAXIMUM_PAYLOAD_SIZE));
             }
 
             if (this._clientCompression != null)
@@ -683,7 +686,7 @@ namespace Renci.SshClient
 
                 if (packetData.Length > Session.MAXIMUM_PACKET_SIZE)
                 {
-                    throw new InvalidOperationException(string.Format("Packet is too big. Maximum packet size is {0} bytes.", Session.MAXIMUM_PACKET_SIZE));
+                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "Packet is too big. Maximum packet size is {0} bytes.", Session.MAXIMUM_PACKET_SIZE));
                 }
 
                 if (this._clientMac == null)
@@ -731,7 +734,7 @@ namespace Renci.SshClient
 
             //  Test packet minimum and maximum boundaries
             if (packetLength < Math.Max((byte)16, blockSize) - 4 || packetLength > Session.MAXIMUM_PACKET_SIZE - 4)
-                throw new SshConnectionException(string.Format("Bad packet length {0}", packetLength), DisconnectReasons.ProtocolError);
+                throw new SshConnectionException(string.Format(CultureInfo.CurrentCulture, "Bad packet length {0}", packetLength), DisconnectReasons.ProtocolError);
 
             //  Read rest of the packet data
             int bytesToRead = (int)(packetLength - (blockSize - 4));
@@ -1521,7 +1524,7 @@ namespace Renci.SshClient
             var messageMetadata = (from m in this._messagesMetadata where m.Number == messageType && m.Enabled && m.Activated select m).SingleOrDefault();
 
             if (messageMetadata == null)
-                throw new SshException(string.Format("Message type {0} is not valid.", messageType));
+                throw new SshException(string.Format(CultureInfo.CurrentCulture, "Message type {0} is not valid.", messageType));
 
             var message = messageMetadata.Type.CreateInstance<Message>();
 

+ 4 - 3
Renci.SshClient/Renci.SshClient/Sftp/ListDirectoryCommand.cs

@@ -2,6 +2,7 @@
 using System.Linq;
 using Renci.SshClient.Common;
 using Renci.SshClient.Sftp.Messages;
+using System.Globalization;
 
 namespace Renci.SshClient.Sftp
 {
@@ -46,11 +47,11 @@ namespace Renci.SshClient.Sftp
             base.OnName(files);
 
             var seperator = "/";
-            if (this._path.EndsWith(seperator))
+            if (this._path[this._path.Length - 1] == '/')
                 seperator = string.Empty;
 
             var sftpFiles = from f in files
-                            select new SftpFile(this.SftpSession, string.Format("{0}{1}{2}", this._path, seperator, f.Key), f.Value);
+                            select new SftpFile(this.SftpSession, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", this._path, seperator, f.Key), f.Value);
 
             this._files.AddRange(sftpFiles);
 
@@ -63,7 +64,7 @@ namespace Renci.SshClient.Sftp
 
             if (statusCode == StatusCodes.NoSuchFile)
             {
-                throw new SshFileNotFoundException(string.Format("Path '{0}' is not found.", this._path));
+                throw new SshFileNotFoundException(string.Format(CultureInfo.CurrentCulture, "Path '{0}' is not found.", this._path));
             }
 
             if (statusCode == StatusCodes.Eof)

+ 1 - 1
Renci.SshClient/Renci.SshClient/Sftp/Messages/NameMessage.cs

@@ -25,7 +25,7 @@ namespace Renci.SshClient.Sftp.Messages
             for (int i = 0; i < this.Count; i++)
             {
                 var fileName = this.ReadString();
-                var fullName = this.ReadString();   //  This field value has meaningless information
+                this.ReadString();   //  This field value has meaningless information
                 var attributes = this.ReadAttributes();
 
                 this.Files.Add(fileName, attributes);

+ 3 - 4
Renci.SshClient/Renci.SshClient/Sftp/Messages/SftpMessage.cs

@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Linq;
 using Renci.SshClient.Common;
+using System.Globalization;
 
 namespace Renci.SshClient.Sftp.Messages
 {
@@ -166,14 +167,12 @@ namespace Renci.SshClient.Sftp.Messages
             }
             else
             {
-                throw new NotSupportedException(string.Format("Message type '{0}' is not registered.", messageType));
+                throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Message type '{0}' is not registered.", messageType));
             }
         }
 
         private static T Load<T>(byte[] data) where T : SftpMessage, new()
         {
-            var messageType = (SftpMessageTypes)data[0];
-
             T message = new T();
 
             message.LoadBytes(data);
@@ -187,7 +186,7 @@ namespace Renci.SshClient.Sftp.Messages
 
         public override string ToString()
         {
-            return string.Format("SFTP Message : {0}", this.SftpMessageType);
+            return string.Format(CultureInfo.CurrentCulture, "SFTP Message : {0}", this.SftpMessageType);
         }
     }
 }

+ 3 - 2
Renci.SshClient/Renci.SshClient/Sftp/SftpFile.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Security;
 using Renci.SshClient.Sftp.Messages;
+using System.Globalization;
 
 namespace Renci.SshClient.Sftp
 {
@@ -350,7 +351,7 @@ namespace Renci.SshClient.Sftp
         /// <param name="mode">The mode.</param>
         public void SetPermissions(ushort mode)
         {
-            var modeBytes = mode.ToString().ToArray();
+            var modeBytes = mode.ToString(CultureInfo.InvariantCulture).ToArray();
 
             var permission = (modeBytes[0] & 0x0F) * 8 * 8 + (modeBytes[1] & 0x0F) * 8 + (modeBytes[2] & 0x0F);
 
@@ -518,7 +519,7 @@ namespace Renci.SshClient.Sftp
         /// </returns>
         public override string ToString()
         {
-            return string.Format("Name {0}, Size {1}, User ID {2}, Group ID {3}, Accessed {4}, Modified {5}", this.Name, this.Size, this.UserId, this.GroupId, this.LastAccessTime, this.LastWriteTime);
+            return string.Format(CultureInfo.CurrentCulture, "Name {0}, Size {1}, User ID {2}, Group ID {3}, Accessed {4}, Modified {5}", this.Name, this.Size, this.UserId, this.GroupId, this.LastAccessTime, this.LastWriteTime);
         }
     }
 }

+ 8 - 7
Renci.SshClient/Renci.SshClient/Sftp/SftpSession.cs

@@ -8,6 +8,7 @@ using Renci.SshClient.Common;
 using Renci.SshClient.Sftp.Messages;
 using System.Diagnostics;
 using System.Collections.Generic;
+using System.Globalization;
 
 namespace Renci.SshClient.Sftp
 {
@@ -112,15 +113,15 @@ namespace Renci.SshClient.Sftp
         {
             var fullPath = path;
 
-            if (!path.StartsWith("/") && this.WorkingDirectory != null)
+            if (path[0] == '/' && this.WorkingDirectory != null)
             {
-                if (this.WorkingDirectory.EndsWith("/"))
+                if (this.WorkingDirectory[this.WorkingDirectory.Length - 1] == '/')
                 {
-                    fullPath = string.Format("{0}{1}", this.WorkingDirectory, path);
+                    fullPath = string.Format(CultureInfo.InvariantCulture, "{0}{1}", this.WorkingDirectory, path);
                 }
                 else
                 {
-                    fullPath = string.Format("{0}/{1}", this.WorkingDirectory, path);
+                    fullPath = string.Format(CultureInfo.InvariantCulture, "{0}/{1}", this.WorkingDirectory, path);
                 }
             }
 
@@ -151,7 +152,7 @@ namespace Renci.SshClient.Sftp
                 var slash = string.Empty;
                 if (!canonizedPath.EndsWith("/"))
                     slash = "/";
-                return string.Format("{0}{1}{2}", canonizedPath, slash, pathParts[pathParts.Length - 1]);
+                return string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", canonizedPath, slash, pathParts[pathParts.Length - 1]);
             }
         }
 
@@ -229,7 +230,7 @@ namespace Renci.SshClient.Sftp
             }
             else
             {
-                throw new NotSupportedException(string.Format("Server SFTP version {0} is not supported.", message.Version));
+                throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Server SFTP version {0} is not supported.", message.Version));
             }
         }
 
@@ -323,7 +324,7 @@ namespace Renci.SshClient.Sftp
             else if (index > 1)
             {
                 //  throw time out error
-                throw new SshOperationTimeoutException(string.Format("Sftp operation has timed out."));
+                throw new SshOperationTimeoutException(string.Format(CultureInfo.CurrentCulture, "Sftp operation has timed out."));
             }
         }
 

+ 57 - 2
Renci.SshClient/Renci.SshClient/Shell.cs

@@ -14,7 +14,7 @@ namespace Renci.SshClient
     /// <summary>
     /// Represents instance of the SSH shell object
     /// </summary>
-    public class Shell
+    public class Shell : IDisposable
     {
         private readonly Session _session;
 
@@ -129,7 +129,7 @@ namespace Renci.SshClient
             this._session.ErrorOccured += Session_ErrorOccured;
 
             this._channel.Open();
-            this._channel.SendPseudoTerminalRequest(this._terminalName, this._columns, this._columns, this._width, this._height, this._terminalMode);
+            this._channel.SendPseudoTerminalRequest(this._terminalName, this._columns, this._rows, this._width, this._height, this._terminalMode);
             this._channel.SendShellRequest();
 
             this._channelClosedWaitHandle = new AutoResetEvent(false);
@@ -257,5 +257,60 @@ namespace Renci.SshClient
 
             this._channel = null;
         }
+
+
+        #region IDisposable Members
+
+        private bool _disposed = false;
+
+        /// <summary>
+        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged ResourceMessages.
+        /// </summary>
+        public void Dispose()
+        {
+            Dispose(true);
+
+            GC.SuppressFinalize(this);
+        }
+
+        /// <summary>
+        /// Releases unmanaged and - optionally - managed resources
+        /// </summary>
+        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged ResourceMessages.</param>
+        protected virtual void Dispose(bool disposing)
+        {
+            // Check to see if Dispose has already been called.
+            if (!this._disposed)
+            {
+                // If disposing equals true, dispose all managed
+                // and unmanaged ResourceMessages.
+                if (disposing)
+                {
+                    if (this._channelClosedWaitHandle != null)
+                    {
+                        this._channelClosedWaitHandle.Dispose();
+                        this._channelClosedWaitHandle = null;
+                    }
+                }
+
+                // Note disposing has been done.
+                this._disposed = true;
+            }
+        }
+
+        /// <summary>
+        /// Releases unmanaged resources and performs other cleanup operations before the
+        /// <see cref="Session"/> is reclaimed by garbage collection.
+        /// </summary>
+        ~Shell()
+        {
+            // Do not re-create Dispose clean-up code here.
+            // Calling Dispose(false) is optimal in terms of
+            // readability and maintainability.
+            Dispose(false);
+        }
+
+        #endregion
+
     }
 }

+ 70 - 5
Renci.SshClient/Renci.SshClient/SshClient.cs

@@ -190,7 +190,7 @@ namespace Renci.SshClient
         }
 
         /// <summary>
-        /// Creates the shell. (not complete)
+        /// Creates the shell.
         /// </summary>
         /// <param name="input">The input.</param>
         /// <param name="output">The output.</param>
@@ -201,8 +201,9 @@ namespace Renci.SshClient
         /// <param name="width">The width.</param>
         /// <param name="height">The height.</param>
         /// <param name="terminalMode">The terminal mode.</param>
+        /// <param name="bufferSize">Size of the internal read buffer.</param>
         /// <returns></returns>
-        public Shell CreateShell(Stream input, Stream output, Stream extendedOutput, string terminalName = "", uint columns = 0, uint rows = 0, uint width = 0, uint height = 0, string terminalMode = "", int bufferSize = 1024)
+        public Shell CreateShell(Stream input, Stream output, Stream extendedOutput, string terminalName, uint columns, uint rows, uint width, uint height, string terminalMode, int bufferSize)
         {
             //  Ensure that connection is established.
             this.EnsureConnection();
@@ -211,7 +212,7 @@ namespace Renci.SshClient
         }
 
         /// <summary>
-        /// Creates the shell. (not complete)
+        /// Creates the shell.
         /// </summary>
         /// <param name="input">The input.</param>
         /// <param name="output">The output.</param>
@@ -223,7 +224,39 @@ namespace Renci.SshClient
         /// <param name="height">The height.</param>
         /// <param name="terminalMode">The terminal mode.</param>
         /// <returns></returns>
-        public Shell CreateShell(Encoding encoding, string input, Stream output, Stream extendedOutput, string terminalName = "", uint columns = 0, uint rows = 0, uint width = 0, uint height = 0, string terminalMode = "", int bufferSize = 1024)
+        public Shell CreateShell(Stream input, Stream output, Stream extendedOutput, string terminalName, uint columns, uint rows, uint width, uint height, string terminalMode)
+        {
+            return this.CreateShell(input, output, extendedOutput, terminalName, columns, rows, width, height, terminalMode, 1024);
+        }
+
+        /// <summary>
+        /// Creates the shell.
+        /// </summary>
+        /// <param name="input">The input.</param>
+        /// <param name="output">The output.</param>
+        /// <param name="extendedOutput">The extended output.</param>
+        /// <returns></returns>
+        public Shell CreateShell(Stream input, Stream output, Stream extendedOutput)
+        {
+            return this.CreateShell(input, output, extendedOutput, string.Empty, 0, 0, 0, 0, string.Empty, 1024);
+        }
+
+        /// <summary>
+        /// Creates the shell.
+        /// </summary>
+        /// <param name="encoding">The encoding to use to send the input.</param>
+        /// <param name="input">The input.</param>
+        /// <param name="output">The output.</param>
+        /// <param name="extendedOutput">The extended output.</param>
+        /// <param name="terminalName">Name of the terminal.</param>
+        /// <param name="columns">The columns.</param>
+        /// <param name="rows">The rows.</param>
+        /// <param name="width">The width.</param>
+        /// <param name="height">The height.</param>
+        /// <param name="terminalMode">The terminal mode.</param>
+        /// <param name="bufferSize">Size of the internal read buffer.</param>
+        /// <returns></returns>
+        public Shell CreateShell(Encoding encoding, string input, Stream output, Stream extendedOutput, string terminalName, uint columns, uint rows, uint width , uint height , string terminalMode, int bufferSize)
         {
             //  Ensure that connection is established.
             this.EnsureConnection();
@@ -232,7 +265,39 @@ namespace Renci.SshClient
             new StreamWriter(inputStream, encoding).Write(input);
             inputStream.Seek(0, SeekOrigin.Begin);
 
-            return new Shell(this.Session, inputStream, output, extendedOutput, terminalName, columns, rows, width, height, terminalMode, bufferSize);
+            return this.CreateShell(inputStream, output, extendedOutput, terminalName, columns, rows, width, height, terminalMode, bufferSize);
+        }
+
+        /// <summary>
+        /// Creates the shell.
+        /// </summary>
+        /// <param name="encoding">The encoding.</param>
+        /// <param name="input">The input.</param>
+        /// <param name="output">The output.</param>
+        /// <param name="extendedOutput">The extended output.</param>
+        /// <param name="terminalName">Name of the terminal.</param>
+        /// <param name="columns">The columns.</param>
+        /// <param name="rows">The rows.</param>
+        /// <param name="width">The width.</param>
+        /// <param name="height">The height.</param>
+        /// <param name="terminalMode">The terminal mode.</param>
+        /// <returns></returns>
+        public Shell CreateShell(Encoding encoding, string input, Stream output, Stream extendedOutput, string terminalName, uint columns, uint rows, uint width, uint height, string terminalMode)
+        {
+            return this.CreateShell(encoding, input, output, extendedOutput, terminalName, columns, rows, width, height, terminalMode, 1024);
+        }
+
+        /// <summary>
+        /// Creates the shell.
+        /// </summary>
+        /// <param name="encoding">The encoding.</param>
+        /// <param name="input">The input.</param>
+        /// <param name="output">The output.</param>
+        /// <param name="extendedOutput">The extended output.</param>
+        /// <returns></returns>
+        public Shell CreateShell(Encoding encoding, string input, Stream output, Stream extendedOutput)
+        {
+            return this.CreateShell(encoding, input, output, extendedOutput, string.Empty, 0, 0, 0, 0, string.Empty, 1024);
         }
 
     }

+ 18 - 25
Renci.SshClient/Renci.SshClient/SshCommand.cs

@@ -9,6 +9,7 @@ using Renci.SshClient.Common;
 using Renci.SshClient.Messages;
 using Renci.SshClient.Messages.Connection;
 using Renci.SshClient.Messages.Transport;
+using System.Globalization;
 
 namespace Renci.SshClient
 {
@@ -17,14 +18,6 @@ namespace Renci.SshClient
     /// </summary>
     public class SshCommand : IDisposable
     {
-        //private StreamReader _outputSteamReader;
-
-        //private StreamReader _extendedOutputSteamReader;
-
-        //private StreamWriter _outputSteamWriter;
-
-        //private StreamWriter _extendedOutputSteamWriter;
-
         private Encoding _encoding;
 
         private Session _session;
@@ -82,7 +75,7 @@ namespace Renci.SshClient
                     this._result = new StringBuilder();
                 }
 
-                if (this.OutputStream.Length > 0)
+                if (this.OutputStream != null && this.OutputStream.Length > 0)
                 {
                     using (var sr = new StreamReader(this.OutputStream, this._encoding))
                     {
@@ -109,7 +102,7 @@ namespace Renci.SshClient
                         this._error = new StringBuilder();
                     }
 
-                    if (this.ExtendedOutputStream.Length > 0)
+                    if (this.ExtendedOutputStream != null && this.ExtendedOutputStream.Length > 0)
                     {
                         using (var sr = new StreamReader(this.ExtendedOutputStream, this._encoding))
                         {
@@ -132,6 +125,9 @@ namespace Renci.SshClient
         /// <param name="encoding">The encoding.</param>
         internal SshCommand(Session session, string commandText, Encoding encoding)
         {
+            if (session == null)
+                throw new ArgumentNullException("session");
+
             this._encoding = encoding;
             this._session = session;
             this.CommandText = commandText;
@@ -154,7 +150,7 @@ namespace Renci.SshClient
             //  Prevent from executing BeginExecute before calling EndExecute
             if (this._asyncResult != null)
             {
-                throw new InvalidOperationException("");
+                throw new InvalidOperationException("Asynchronous operation is already in progress.");
             }
 
             //  Create new AsyncResult object
@@ -204,11 +200,14 @@ namespace Renci.SshClient
         /// <summary>
         /// Waits for the pending asynchronous command execution to complete.
         /// </summary>
-        /// <param name="asynchResult">The reference to the pending asynchronous request to finish.</param>
+        /// <param name="asyncResult">The reference to the pending asynchronous request to finish.</param>
         /// <returns></returns>
-        public string EndExecute(IAsyncResult asynchResult)
+        public string EndExecute(IAsyncResult asyncResult)
         {
-            CommandAsyncResult channelAsyncResult = asynchResult as CommandAsyncResult;
+            CommandAsyncResult channelAsyncResult = asyncResult as CommandAsyncResult;
+
+            if (channelAsyncResult == null)
+                throw new ArgumentException("Not valid 'asynchResult' parameter.");
 
             channelAsyncResult.ValidateCommand(this);
 
@@ -235,13 +234,12 @@ namespace Renci.SshClient
             return this.EndExecute(this.BeginExecute(null, null));
         }
 
+        /// <summary>
+        /// Cancels command execution in asynchronous scenarios. CURRENTLY NOT IMPLEMENTED.
+        /// </summary>
         public void Cancel()
         {
-            if (this._channel != null && this._channel.IsOpen)
-            {
-                this._session.SendMessage(new ChannelEofMessage(this._channel.RemoteChannelNumber));
-                this._session.SendMessage(new ChannelCloseMessage(this._channel.RemoteChannelNumber));
-            }
+            throw new NotImplementedException();
         }
 
         /// <summary>
@@ -266,11 +264,6 @@ namespace Renci.SshClient
             this._channel.Closed += Channel_Closed;
             this.OutputStream = new PipeStream();
             this.ExtendedOutputStream = new PipeStream();
-
-            //this._outputSteamReader = new StreamReader(this.OutputStream);
-            //this._extendedOutputSteamReader = new StreamReader(this.ExtendedOutputStream);
-            //this._outputSteamWriter = new StreamWriter(this.OutputStream);
-            //this._extendedOutputSteamWriter = new StreamWriter(this.ExtendedOutputStream);
         }
 
         private void Session_Disconnected(object sender, EventArgs e)
@@ -381,7 +374,7 @@ namespace Renci.SshClient
             else if (index > 1)
             {
                 //  throw time out error
-                throw new SshOperationTimeoutException(string.Format("Command '{0}' has timed out.", this.CommandText));
+                throw new SshOperationTimeoutException(string.Format(CultureInfo.CurrentCulture, "Command '{0}' has timed out.", this.CommandText));
             }
         }