diff --git a/Source/BackupEngine/Contracts/IBackupReport.cs b/Source/BackupEngine/Contracts/IBackupReport.cs index a0512de..403cb2e 100644 --- a/Source/BackupEngine/Contracts/IBackupReport.cs +++ b/Source/BackupEngine/Contracts/IBackupReport.cs @@ -2,16 +2,16 @@ { using System; - public class IBackupReport + public interface IBackupReport { - public long FilesUploaded { get; } + long FilesUploaded { get; } - public long BytesUploaded { get; } + long BytesUploaded { get; } - public long FilesUpdated { get; } + long FilesUpdated { get; } - public long FilesProcessed { get; } + long FilesProcessed { get; } - public Exception[] Errors { get; } + Exception[] Errors { get; } } } diff --git a/Source/ContentTransformer/ClearText/BufferHelpers.cs b/Source/ContentTransformer/ClearText/BufferHelpers.cs new file mode 100644 index 0000000..36821f2 --- /dev/null +++ b/Source/ContentTransformer/ClearText/BufferHelpers.cs @@ -0,0 +1,15 @@ +namespace EternalArrowBackup.ContentTransformer.ClearText +{ + using System; + + internal static class BufferHelpers + { + public static void Add(byte[] source, byte[] target, int targetOffset) { + Buffer.BlockCopy(source, 0, target, targetOffset, source.Length); + } + + public static void Extract(byte[] source, int sourceOffset, byte[] target) { + Buffer.BlockCopy(source, sourceOffset, target, 0, target.Length); + } + } +} diff --git a/Source/ContentTransformer/ClearText/ClearTextContentEncryptor.cs b/Source/ContentTransformer/ClearText/ClearTextContentEncryptor.cs index 5f6c37e..1b110b0 100644 --- a/Source/ContentTransformer/ClearText/ClearTextContentEncryptor.cs +++ b/Source/ContentTransformer/ClearText/ClearTextContentEncryptor.cs @@ -16,18 +16,12 @@ private IContentHasher Hasher { get; } - public async Task GetOriginalData(byte[] encryptedData) + public async Task GetOriginalData(byte[] transformedData) { - var hashLength = encryptedData[encryptedData.Length - 1]; + var dataWithSignature = DataWithSignature.FromByteArray(transformedData); - var originalData = new byte[encryptedData.Length - hashLength - 1]; - var hashBytes = new byte[hashLength]; - - Buffer.BlockCopy(encryptedData, 0, originalData, 0, originalData.Length); - Buffer.BlockCopy(encryptedData, originalData.Length, hashBytes, 0, hashBytes.Length); - - var expectedHash = Encoding.UTF8.GetString(hashBytes); - using (var stream = new MemoryStream(originalData)) + var expectedHash = Encoding.UTF8.GetString(dataWithSignature.Signature); + using (var stream = new MemoryStream(dataWithSignature.Data)) { var actualHash = await this.Hasher.ComputeHash(stream); @@ -37,7 +31,7 @@ } } - return new SuccessfulDecryptionResult(originalData); + return new SuccessfulDecryptionResult(dataWithSignature.Data); } public async Task TransformData(byte[] originalData) @@ -49,16 +43,9 @@ } var hashBytes = Encoding.UTF8.GetBytes(hash); - if (hashBytes.Length >= 256) - { - throw new Exception("Hash should be shorter than 256 bytes"); - } + var dataWithSignature = new DataWithSignature(originalData, hashBytes); - var result = new byte[originalData.Length + hashBytes.Length + 1]; - Buffer.BlockCopy(originalData, 0, result, 0, originalData.Length); - Buffer.BlockCopy(hashBytes, 0, result, originalData.Length, hashBytes.Length); - result[result.Length - 1] = (byte)hashBytes.Length; - return result; + return dataWithSignature.AsByteArray(); } private class FailedDecryptionResult : IDecryptionResult diff --git a/Source/ContentTransformer/ClearText/DataWithSignature.cs b/Source/ContentTransformer/ClearText/DataWithSignature.cs new file mode 100644 index 0000000..ac9f840 --- /dev/null +++ b/Source/ContentTransformer/ClearText/DataWithSignature.cs @@ -0,0 +1,56 @@ +namespace EternalArrowBackup.ContentTransformer.ClearText +{ + using System; + + public class DataWithSignature + { + public DataWithSignature(byte[] data, byte[] signature) { + if (data == null) { + throw new ArgumentNullException(nameof(data)); + } + + if (signature == null) { + throw new ArgumentNullException(nameof(signature)); + } + + if (signature.Length > 0xffff) { + throw new ArgumentOutOfRangeException(nameof(signature), "Signature should be shorter than 64k"); + } + + this.Data = data; + this.Signature = signature; + } + + public byte[] Data { get; } + + public byte[] Signature { get; } + + public static DataWithSignature FromByteArray(byte[] byteArray) { + var signatureLengthBytes = new byte[2]; + BufferHelpers.Extract(byteArray, byteArray.Length - 2, signatureLengthBytes); + var signatureLength = (signatureLengthBytes[0] * 0x100) + signatureLengthBytes[1]; + + var data = new byte[byteArray.Length - signatureLength - 2]; + var signature = new byte[signatureLength]; + + BufferHelpers.Extract(byteArray, 0, data); + BufferHelpers.Extract(byteArray, data.Length, signature); + + return new DataWithSignature(data, signature); + } + + public byte[] AsByteArray() { + var signatureLengthBytes = new[] { + (byte)(this.Signature.Length / 0x100), + (byte)(this.Signature.Length % 0x100), + }; + + var result = new byte[this.Data.Length + this.Signature.Length + 2]; + BufferHelpers.Add(this.Data, result, 0); + BufferHelpers.Add(this.Signature, result, this.Data.Length); + BufferHelpers.Add(signatureLengthBytes, result, this.Data.Length + this.Signature.Length); + + return result; + } + } +} diff --git a/Source/Hasher/SHA1/SHA1ContentHasher.cs b/Source/Hasher/SHA1/SHA1ContentHasher.cs index ad55780..14caacd 100644 --- a/Source/Hasher/SHA1/SHA1ContentHasher.cs +++ b/Source/Hasher/SHA1/SHA1ContentHasher.cs @@ -5,7 +5,7 @@ using System.Threading.Tasks; using EternalArrowBackup.Hasher.Contracts; - public class SHA1ContentHasher : IContentHasher + public class Sha1ContentHasher : IContentHasher { public Task ComputeHash(Stream content) { diff --git a/Source/ReportStorage/InMemoryReportStorage/FileInfo.cs b/Source/ReportStorage/InMemoryReportStorage/FileInfo.cs index 3002bed..92ca35b 100644 --- a/Source/ReportStorage/InMemoryReportStorage/FileInfo.cs +++ b/Source/ReportStorage/InMemoryReportStorage/FileInfo.cs @@ -1,6 +1,5 @@ namespace EternalArrowBackup.ReportStorage.InMemoryReportStorage { - using System; using EternalArrowBackup.ReportStorage.Contracts; class FileInfo : IFileInfo diff --git a/Source/SourceStorage/InMemorySourceStorage/SourceStorage.cs b/Source/SourceStorage/InMemorySourceStorage/SourceStorage.cs index 80f39e9..bd4cf0e 100644 --- a/Source/SourceStorage/InMemorySourceStorage/SourceStorage.cs +++ b/Source/SourceStorage/InMemorySourceStorage/SourceStorage.cs @@ -1,6 +1,5 @@ namespace EternalArrowBackup.SourceStorage.InMemorySourceStorage { - using System; using System.Collections.Immutable; using System.Threading; using System.Threading.Tasks; diff --git a/Source/TargetMetadataStorage/InMemoryMetadataStorage/MetadataStorage.cs b/Source/TargetMetadataStorage/InMemoryMetadataStorage/MetadataStorage.cs index a9b663b..03fdce3 100644 --- a/Source/TargetMetadataStorage/InMemoryMetadataStorage/MetadataStorage.cs +++ b/Source/TargetMetadataStorage/InMemoryMetadataStorage/MetadataStorage.cs @@ -1,6 +1,5 @@ namespace EternalArrowBackup.TargetMetadataStorage.InMemoryMetadataStorage { - using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; diff --git a/Tests/ContentTransformer/ClearText/EncryptorAndHasherTests.cs b/Tests/ContentTransformer/ClearText/EncryptorAndHasherTests.cs index e387dfe..5a2546e 100644 --- a/Tests/ContentTransformer/ClearText/EncryptorAndHasherTests.cs +++ b/Tests/ContentTransformer/ClearText/EncryptorAndHasherTests.cs @@ -15,7 +15,7 @@ public static async Task TestCorrectDecryption(string message) { var messageBytes = Encoding.ASCII.GetBytes(message); - var hasher = new SHA1ContentHasher(); + var hasher = new Sha1ContentHasher(); var encryptor = new ClearTextContentEncryptor(hasher); var encrypted = await encryptor.TransformData(messageBytes); diff --git a/Tests/Hasher/SHA1/HasherTests.cs b/Tests/Hasher/SHA1/HasherTests.cs index ea5db24..42c14c1 100644 --- a/Tests/Hasher/SHA1/HasherTests.cs +++ b/Tests/Hasher/SHA1/HasherTests.cs @@ -21,7 +21,7 @@ public static async Task TestHashes(string expectedHash, string inputMessage) { var expectedHashFormatted = expectedHash.Replace(" ", string.Empty).ToLowerInvariant(); - var hasher = new SHA1ContentHasher(); + var hasher = new Sha1ContentHasher(); var messageBytes = Encoding.ASCII.GetBytes(inputMessage); using (var stream = new MemoryStream(messageBytes)) { @@ -51,7 +51,7 @@ var expectedTimeLow = length / (MegabytesPerSecondHighSpeed * 1000); var expectedTimeHigh = 1 + length / (MegabytesPerSecondLowSpeed * 1000); - var hasher = new SHA1ContentHasher(); + var hasher = new Sha1ContentHasher(); using (var stream = new MemoryStream(messageBytes)) { await hasher.ComputeHash(stream);