mirror of
https://github.com/sshnet/SSH.NET.git
synced 2026-09-11 01:36:39 +00:00
Some cosmetic changes
Fixes suggested in issue #703 Add tests for implemented issues
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -117,7 +117,7 @@ namespace Renci.SshClient
|
||||
{
|
||||
this.Session.UnRegisterMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
|
||||
|
||||
var eventTask = Task.Factory.StartNew(() =>
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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")]
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 ) };
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
get
|
||||
{
|
||||
if (this._encryptionKey == null)
|
||||
{
|
||||
this._encryptionKey = DesCipher.GenerateWorkingKey(true, this.Key);
|
||||
}
|
||||
|
||||
private static readonly uint[] SP2 =
|
||||
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
|
||||
};
|
||||
get
|
||||
{
|
||||
if (this._decryptionKey == null)
|
||||
{
|
||||
this._decryptionKey = DesCipher.GenerateWorkingKey(true, this.Key);
|
||||
}
|
||||
|
||||
private static readonly uint[] SP3 =
|
||||
return this._decryptionKey;
|
||||
}
|
||||
}
|
||||
|
||||
#region Static tables
|
||||
|
||||
private static readonly short[] bytebit =
|
||||
{
|
||||
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
|
||||
};
|
||||
128, 64, 32, 16, 8, 4, 2, 1
|
||||
};
|
||||
|
||||
private static readonly uint[] SP4 =
|
||||
private static readonly int[] bigbyte =
|
||||
{
|
||||
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
|
||||
};
|
||||
0x800000, 0x400000, 0x200000, 0x100000,
|
||||
0x80000, 0x40000, 0x20000, 0x10000,
|
||||
0x8000, 0x4000, 0x2000, 0x1000,
|
||||
0x800, 0x400, 0x200, 0x100,
|
||||
0x80, 0x40, 0x20, 0x10,
|
||||
0x8, 0x4, 0x2, 0x1
|
||||
};
|
||||
|
||||
private static readonly uint[] SP5 =
|
||||
/*
|
||||
* Use the key schedule specified in the Standard (ANSI X3.92-1981).
|
||||
*/
|
||||
private static readonly byte[] pc1 =
|
||||
{
|
||||
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
|
||||
};
|
||||
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 uint[] SP6 =
|
||||
private static readonly byte[] totrot =
|
||||
{
|
||||
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
|
||||
};
|
||||
1, 2, 4, 6, 8, 10, 12, 14,
|
||||
15, 17, 19, 21, 23, 25, 27, 28
|
||||
};
|
||||
|
||||
private static readonly uint[] SP7 =
|
||||
private static readonly byte[] pc2 =
|
||||
{
|
||||
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
|
||||
};
|
||||
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[] SP8 =
|
||||
private static readonly uint[] SP1 =
|
||||
{
|
||||
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
|
||||
};
|
||||
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
|
||||
};
|
||||
|
||||
#endregion
|
||||
private static readonly uint[] SP2 =
|
||||
{
|
||||
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
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of the block.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The size of the block.
|
||||
/// </value>
|
||||
public override int BlockSize
|
||||
{
|
||||
get { return 8; }
|
||||
}
|
||||
private static readonly uint[] SP3 =
|
||||
{
|
||||
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
|
||||
};
|
||||
|
||||
/// <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)
|
||||
{
|
||||
}
|
||||
private static readonly uint[] SP4 =
|
||||
{
|
||||
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
|
||||
};
|
||||
|
||||
/// <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");
|
||||
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
|
||||
};
|
||||
|
||||
if ((outputOffset + this.BlockSize) > outputBuffer.Length)
|
||||
throw new IndexOutOfRangeException("output buffer too short");
|
||||
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
|
||||
};
|
||||
|
||||
DesCipher.DesFunc(this.EncryptionKey, inputBuffer, inputOffset, outputBuffer, outputOffset);
|
||||
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
|
||||
};
|
||||
|
||||
return this.BlockSize;
|
||||
}
|
||||
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
|
||||
};
|
||||
|
||||
/// <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");
|
||||
#endregion
|
||||
|
||||
if ((outputOffset + this.BlockSize) > outputBuffer.Length)
|
||||
throw new IndexOutOfRangeException("output buffer too short");
|
||||
/// <summary>
|
||||
/// Gets the size of the block.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The size of the block.
|
||||
/// </value>
|
||||
public override int BlockSize
|
||||
{
|
||||
get { return 8; }
|
||||
}
|
||||
|
||||
DesCipher.DesFunc(this.DecryptionKey, inputBuffer, inputOffset, outputBuffer, outputOffset);
|
||||
/// <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)
|
||||
{
|
||||
}
|
||||
|
||||
return 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)
|
||||
throw new IndexOutOfRangeException("input buffer too short");
|
||||
|
||||
protected static int[] GenerateWorkingKey(bool encrypting, byte[] key)
|
||||
{
|
||||
int[] newKey = new int[32];
|
||||
bool[] pc1m = new bool[56];
|
||||
bool[] pcr = new bool[56];
|
||||
if ((outputOffset + this.BlockSize) > outputBuffer.Length)
|
||||
throw new IndexOutOfRangeException("output buffer too short");
|
||||
|
||||
for (int j = 0; j < 56; j++)
|
||||
{
|
||||
int l = pc1[j];
|
||||
DesCipher.DesFunc(this.EncryptionKey, inputBuffer, inputOffset, outputBuffer, outputOffset);
|
||||
|
||||
pc1m[j] = ((key[(uint)l >> 3] & bytebit[l & 07]) != 0);
|
||||
}
|
||||
return this.BlockSize;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
int l, m, n;
|
||||
/// <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 (encrypting)
|
||||
{
|
||||
m = i << 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m = (15 - i) << 1;
|
||||
}
|
||||
if ((outputOffset + this.BlockSize) > outputBuffer.Length)
|
||||
throw new IndexOutOfRangeException("output buffer too short");
|
||||
|
||||
n = m + 1;
|
||||
newKey[m] = newKey[n] = 0;
|
||||
DesCipher.DesFunc(this.DecryptionKey, inputBuffer, inputOffset, outputBuffer, outputOffset);
|
||||
|
||||
for (int j = 0; j < 28; j++)
|
||||
{
|
||||
l = j + totrot[i];
|
||||
if (l < 28)
|
||||
{
|
||||
pcr[j] = pc1m[l];
|
||||
}
|
||||
else
|
||||
{
|
||||
pcr[j] = pc1m[l - 28];
|
||||
}
|
||||
}
|
||||
return this.BlockSize;
|
||||
}
|
||||
|
||||
for (int j = 28; j < 56; j++)
|
||||
{
|
||||
l = j + totrot[i];
|
||||
if (l < 56)
|
||||
{
|
||||
pcr[j] = pc1m[l];
|
||||
}
|
||||
else
|
||||
{
|
||||
pcr[j] = pc1m[l - 28];
|
||||
}
|
||||
}
|
||||
/// <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)
|
||||
{
|
||||
int[] newKey = new int[32];
|
||||
bool[] pc1m = new bool[56];
|
||||
bool[] pcr = new bool[56];
|
||||
|
||||
for (int j = 0; j < 24; j++)
|
||||
{
|
||||
if (pcr[pc2[j]])
|
||||
{
|
||||
newKey[m] |= bigbyte[j];
|
||||
}
|
||||
for (int j = 0; j < 56; j++)
|
||||
{
|
||||
int l = pc1[j];
|
||||
|
||||
if (pcr[pc2[j + 24]])
|
||||
{
|
||||
newKey[n] |= bigbyte[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
pc1m[j] = ((key[(uint)l >> 3] & bytebit[l & 07]) != 0);
|
||||
}
|
||||
|
||||
//
|
||||
// store the processed key
|
||||
//
|
||||
for (int i = 0; i != 32; i += 2)
|
||||
{
|
||||
int i1, i2;
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
int l, m, n;
|
||||
|
||||
i1 = newKey[i];
|
||||
i2 = newKey[i + 1];
|
||||
if (encrypting)
|
||||
{
|
||||
m = i << 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m = (15 - i) << 1;
|
||||
}
|
||||
|
||||
newKey[i] = (int)((uint)((i1 & 0x00fc0000) << 6) |
|
||||
(uint)((i1 & 0x00000fc0) << 10) |
|
||||
((uint)(i2 & 0x00fc0000) >> 10) |
|
||||
((uint)(i2 & 0x00000fc0) >> 6));
|
||||
n = m + 1;
|
||||
newKey[m] = newKey[n] = 0;
|
||||
|
||||
newKey[i + 1] = (int)((uint)((i1 & 0x0003f000) << 12) |
|
||||
(uint)((i1 & 0x0000003f) << 16) |
|
||||
((uint)(i2 & 0x0003f000) >> 4) |
|
||||
(uint)(i2 & 0x0000003f));
|
||||
}
|
||||
for (int j = 0; j < 28; j++)
|
||||
{
|
||||
l = j + totrot[i];
|
||||
if (l < 28)
|
||||
{
|
||||
pcr[j] = pc1m[l];
|
||||
}
|
||||
else
|
||||
{
|
||||
pcr[j] = pc1m[l - 28];
|
||||
}
|
||||
}
|
||||
|
||||
return newKey;
|
||||
}
|
||||
for (int j = 28; j < 56; j++)
|
||||
{
|
||||
l = j + totrot[i];
|
||||
if (l < 56)
|
||||
{
|
||||
pcr[j] = pc1m[l];
|
||||
}
|
||||
else
|
||||
{
|
||||
pcr[j] = pc1m[l - 28];
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
for (int j = 0; j < 24; j++)
|
||||
{
|
||||
if (pcr[pc2[j]])
|
||||
{
|
||||
newKey[m] |= bigbyte[j];
|
||||
}
|
||||
|
||||
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);
|
||||
if (pcr[pc2[j + 24]])
|
||||
{
|
||||
newKey[n] |= bigbyte[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int round = 0; round < 8; round++)
|
||||
{
|
||||
uint fval;
|
||||
//
|
||||
// store the processed key
|
||||
//
|
||||
for (int i = 0; i != 32; i += 2)
|
||||
{
|
||||
int i1, i2;
|
||||
|
||||
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;
|
||||
}
|
||||
i1 = newKey[i];
|
||||
i2 = newKey[i + 1];
|
||||
|
||||
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);
|
||||
newKey[i] = (int)((uint)((i1 & 0x00fc0000) << 6) |
|
||||
(uint)((i1 & 0x00000fc0) << 10) |
|
||||
((uint)(i2 & 0x00fc0000) >> 10) |
|
||||
((uint)(i2 & 0x00000fc0) >> 6));
|
||||
|
||||
CipherBase.UInt32_To_BE(right, outBytes, outOff);
|
||||
CipherBase.UInt32_To_BE(left, outBytes, outOff + 4);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
this._isAuthenticated = noneConnectionInfo.IsAuthenticated;
|
||||
|
||||
if (!this._isAuthenticated)
|
||||
using (var noneConnectionInfo = new NoneConnectionInfo(this.ConnectionInfo.Host, this.ConnectionInfo.Port, this.ConnectionInfo.Username))
|
||||
{
|
||||
// Ensure that authentication method is allowed
|
||||
if (!noneConnectionInfo.AllowedAuthentications.Contains(this.ConnectionInfo.Name))
|
||||
noneConnectionInfo.Authenticate(this);
|
||||
|
||||
this._isAuthenticated = noneConnectionInfo.IsAuthenticated;
|
||||
|
||||
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);
|
||||
|
||||
this._isAuthenticated = this.ConnectionInfo.IsAuthenticated;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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>();
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,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,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."));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user