mirror of
https://github.com/sshnet/SSH.NET.git
synced 2026-10-19 23:30:23 +08:00
Create output buffer after padding to ensure its length matches the padded length.
Fixes issue #2547.
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
* Signing key is missing from source download (issue #2455)
|
||||
* Forwarded Port channels can get stuck waiting (issue #1558)
|
||||
* NullReferenceException when SftpFileStream is finalized after dispose of session (issue #2013)
|
||||
* BlockCipher.Encrypt fails if input message is not padded (issue #2547)
|
||||
|
||||
2014.4.6-beta1
|
||||
==============
|
||||
|
||||
+69
-7
@@ -1,15 +1,77 @@
|
||||
using Renci.SshNet.Security.Cryptography;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Renci.SshNet.Security.Cryptography;
|
||||
using Renci.SshNet.Security.Cryptography.Ciphers;
|
||||
using Renci.SshNet.Security.Cryptography.Ciphers.Paddings;
|
||||
using Renci.SshNet.Tests.Common;
|
||||
|
||||
namespace Renci.SshNet.Tests
|
||||
namespace Renci.SshNet.Tests.Classes.Security.Cryptography
|
||||
{
|
||||
/// <summary>
|
||||
///This is a test class for BlockCipherTest and is intended
|
||||
///to contain all BlockCipherTest Unit Tests
|
||||
///</summary>
|
||||
[TestClass()]
|
||||
[TestClass]
|
||||
public class BlockCipherTest : TestBase
|
||||
{
|
||||
[TestMethod]
|
||||
public void EncryptShouldTakeIntoAccountPaddingForLengthOfOutputBufferPassedToEncryptBlock()
|
||||
{
|
||||
var input = new byte[] { 0x2c, 0x1a, 0x05, 0x00, 0x68 };
|
||||
var output = new byte[] { 0x0a, 0x00, 0x03, 0x02, 0x06, 0x08, 0x07, 0x05 };
|
||||
var key = new byte[] { 0x17, 0x78, 0x56, 0xe1, 0x3e, 0xbd, 0x3e, 0x50, 0x1d, 0x79, 0x3f, 0x0f, 0x55, 0x37, 0x45, 0x54 };
|
||||
var blockCipher = new BlockCipherStub(key, 8, null, new PKCS5Padding())
|
||||
{
|
||||
EncryptBlockDelegate = (inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset) =>
|
||||
{
|
||||
Assert.AreEqual(8, outputBuffer.Length);
|
||||
Buffer.BlockCopy(output, 0, outputBuffer, 0, output.Length);
|
||||
return inputBuffer.Length;
|
||||
}
|
||||
};
|
||||
|
||||
var actual = blockCipher.Encrypt(input);
|
||||
|
||||
Assert.IsTrue(output.SequenceEqual(actual));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void DecryptShouldTakeIntoAccountPaddingForLengthOfOutputBufferPassedToDecryptBlock()
|
||||
{
|
||||
var input = new byte[] { 0x2c, 0x1a, 0x05, 0x00, 0x68 };
|
||||
var output = new byte[] { 0x0a, 0x00, 0x03, 0x02, 0x06, 0x08, 0x07, 0x05 };
|
||||
var key = new byte[] { 0x17, 0x78, 0x56, 0xe1, 0x3e, 0xbd, 0x3e, 0x50, 0x1d, 0x79, 0x3f, 0x0f, 0x55, 0x37, 0x45, 0x54 };
|
||||
var blockCipher = new BlockCipherStub(key, 8, null, new PKCS5Padding())
|
||||
{
|
||||
DecryptBlockDelegate = (inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset) =>
|
||||
{
|
||||
Assert.AreEqual(8, outputBuffer.Length);
|
||||
Buffer.BlockCopy(output, 0, outputBuffer, 0, output.Length);
|
||||
return inputBuffer.Length;
|
||||
}
|
||||
};
|
||||
|
||||
var actual = blockCipher.Decrypt(input);
|
||||
|
||||
Assert.IsTrue(output.SequenceEqual(actual));
|
||||
}
|
||||
|
||||
|
||||
private class BlockCipherStub : BlockCipher
|
||||
{
|
||||
public Func<byte[], int, int, byte[], int, int> EncryptBlockDelegate;
|
||||
public Func<byte[], int, int, byte[], int, int> DecryptBlockDelegate;
|
||||
|
||||
public BlockCipherStub(byte[] key, byte blockSize, CipherMode mode, CipherPadding padding) : base(key, blockSize, mode, padding)
|
||||
{
|
||||
}
|
||||
|
||||
public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
|
||||
{
|
||||
return EncryptBlockDelegate(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
|
||||
}
|
||||
|
||||
public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
|
||||
{
|
||||
return DecryptBlockDelegate(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,8 +71,6 @@ namespace Renci.SshNet.Security.Cryptography
|
||||
/// <returns>Encrypted data</returns>
|
||||
public override byte[] Encrypt(byte[] data)
|
||||
{
|
||||
var output = new byte[data.Length];
|
||||
|
||||
if (data.Length % _blockSize > 0)
|
||||
{
|
||||
if (_padding == null)
|
||||
@@ -82,9 +80,10 @@ namespace Renci.SshNet.Security.Cryptography
|
||||
data = _padding.Pad(_blockSize, data);
|
||||
}
|
||||
|
||||
var output = new byte[data.Length];
|
||||
var writtenBytes = 0;
|
||||
|
||||
for (int i = 0; i < data.Length / _blockSize; i++)
|
||||
for (var i = 0; i < data.Length / _blockSize; i++)
|
||||
{
|
||||
if (_mode == null)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user