SEBWIN-296: Implemented unit tests for binary serializer.
This commit is contained in:
parent
f86615c77d
commit
817d9eaefc
4 changed files with 156 additions and 26 deletions
|
@ -6,17 +6,148 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Configuration.DataFormats;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.Configuration.Cryptography;
|
||||
using SafeExamBrowser.Contracts.Configuration.DataCompression;
|
||||
using SafeExamBrowser.Contracts.Configuration.DataFormats;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
|
||||
namespace SafeExamBrowser.Configuration.UnitTests.DataFormats
|
||||
{
|
||||
[TestClass]
|
||||
public class BinarySerializerTests
|
||||
{
|
||||
private Mock<IDataCompressor> compressor;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<IPasswordEncryption> passwordEncryption;
|
||||
private Mock<IPublicKeyEncryption> publicKeyEncryption;
|
||||
private Mock<IPublicKeyEncryption> symmetricEncryption;
|
||||
private Mock<IDataSerializer> xmlSerializer;
|
||||
private SerializeResult xmlResult;
|
||||
|
||||
private BinarySerializer sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
compressor = new Mock<IDataCompressor>();
|
||||
logger = new Mock<ILogger>();
|
||||
passwordEncryption = new Mock<IPasswordEncryption>();
|
||||
publicKeyEncryption = new Mock<IPublicKeyEncryption>();
|
||||
symmetricEncryption = new Mock<IPublicKeyEncryption>();
|
||||
xmlResult = new SerializeResult { Data = new MemoryStream(), Status = SaveStatus.Success };
|
||||
xmlSerializer = new Mock<IDataSerializer>();
|
||||
|
||||
compressor.Setup(c => c.Compress(It.IsAny<Stream>())).Returns(new MemoryStream());
|
||||
xmlSerializer.Setup(x => x.TrySerialize(It.IsAny<IDictionary<string, object>>(), It.IsAny<EncryptionParameters>())).Returns(xmlResult);
|
||||
|
||||
sut = new BinarySerializer(compressor.Object, logger.Object, passwordEncryption.Object, publicKeyEncryption.Object, symmetricEncryption.Object, xmlSerializer.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustOnlySupportBinaryFormat()
|
||||
{
|
||||
var values = Enum.GetValues(typeof(FormatType));
|
||||
|
||||
foreach (var value in values)
|
||||
{
|
||||
if (value is FormatType format && format != FormatType.Binary)
|
||||
{
|
||||
Assert.IsFalse(sut.CanSerialize(format));
|
||||
}
|
||||
}
|
||||
|
||||
Assert.IsTrue(sut.CanSerialize(FormatType.Binary));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustCorrectlySerializePlainDataBlock()
|
||||
{
|
||||
var data = new Dictionary<string, object>();
|
||||
var result = sut.TrySerialize(data);
|
||||
|
||||
compressor.Verify(c => c.Compress(It.IsAny<Stream>()), Times.Exactly(2));
|
||||
xmlSerializer.Verify(x => x.TrySerialize(It.Is<IDictionary<string, object>>(d => d == data), It.Is<EncryptionParameters>(e => e == null)), Times.Once);
|
||||
passwordEncryption.VerifyNoOtherCalls();
|
||||
publicKeyEncryption.VerifyNoOtherCalls();
|
||||
symmetricEncryption.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(SaveStatus.Success, result.Status);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustCorrectlySerializePasswordBlock()
|
||||
{
|
||||
var encrypted = new MemoryStream() as Stream;
|
||||
var data = new Dictionary<string, object>();
|
||||
var encryption = new PasswordParameters { Password = "blubb" };
|
||||
|
||||
passwordEncryption.Setup(p => p.Encrypt(It.IsAny<Stream>(), It.IsAny<string>(), out encrypted)).Returns(SaveStatus.Success);
|
||||
|
||||
var result = sut.TrySerialize(data, encryption);
|
||||
|
||||
compressor.Verify(c => c.Compress(It.IsAny<Stream>()), Times.Exactly(2));
|
||||
passwordEncryption.Verify(p => p.Encrypt(It.IsAny<Stream>(), It.Is<string>(s => s == encryption.Password), out encrypted), Times.Once);
|
||||
xmlSerializer.Verify(x => x.TrySerialize(It.Is<IDictionary<string, object>>(d => d == data), It.Is<EncryptionParameters>(e => e == null)), Times.Once);
|
||||
publicKeyEncryption.VerifyNoOtherCalls();
|
||||
symmetricEncryption.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(SaveStatus.Success, result.Status);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustCorrectlySerializePublicKeyBlock()
|
||||
{
|
||||
var encrypted = new MemoryStream() as Stream;
|
||||
var data = new Dictionary<string, object>();
|
||||
var encryption = new PublicKeyParameters
|
||||
{
|
||||
InnerEncryption = new PasswordParameters { Password = "test" },
|
||||
SymmetricEncryption = false
|
||||
};
|
||||
|
||||
passwordEncryption.Setup(p => p.Encrypt(It.IsAny<Stream>(), It.IsAny<string>(), out encrypted)).Returns(SaveStatus.Success);
|
||||
publicKeyEncryption.Setup(p => p.Encrypt(It.IsAny<Stream>(), It.IsAny<X509Certificate2>(), out encrypted)).Returns(SaveStatus.Success);
|
||||
|
||||
var result = sut.TrySerialize(data, encryption);
|
||||
|
||||
compressor.Verify(c => c.Compress(It.IsAny<Stream>()), Times.Exactly(2));
|
||||
passwordEncryption.Verify(p => p.Encrypt(It.IsAny<Stream>(), It.Is<string>(s => s == encryption.InnerEncryption.Password), out encrypted), Times.Once);
|
||||
publicKeyEncryption.Verify(p => p.Encrypt(It.IsAny<Stream>(), It.IsAny<X509Certificate2>(), out encrypted), Times.Once);
|
||||
xmlSerializer.Verify(x => x.TrySerialize(It.Is<IDictionary<string, object>>(d => d == data), It.Is<EncryptionParameters>(e => e == null)), Times.Once);
|
||||
symmetricEncryption.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(SaveStatus.Success, result.Status);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustCorrectlySerializePublicKeySymmetricBlock()
|
||||
{
|
||||
var encrypted = new MemoryStream() as Stream;
|
||||
var data = new Dictionary<string, object>();
|
||||
var encryption = new PublicKeyParameters
|
||||
{
|
||||
SymmetricEncryption = true
|
||||
};
|
||||
|
||||
symmetricEncryption.Setup(p => p.Encrypt(It.IsAny<Stream>(), It.IsAny<X509Certificate2>(), out encrypted)).Returns(SaveStatus.Success);
|
||||
|
||||
var result = sut.TrySerialize(data, encryption);
|
||||
|
||||
compressor.Verify(c => c.Compress(It.IsAny<Stream>()), Times.Exactly(2));
|
||||
symmetricEncryption.Verify(p => p.Encrypt(It.IsAny<Stream>(), It.IsAny<X509Certificate2>(), out encrypted), Times.Once);
|
||||
xmlSerializer.Verify(x => x.TrySerialize(It.Is<IDictionary<string, object>>(d => d == data), It.Is<EncryptionParameters>(e => e == null)), Times.Once);
|
||||
passwordEncryption.VerifyNoOtherCalls();
|
||||
publicKeyEncryption.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(SaveStatus.Success, result.Status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -181,19 +181,19 @@ namespace SafeExamBrowser.Configuration.DataFormats
|
|||
|
||||
private string ReadPrefix(Stream data)
|
||||
{
|
||||
var prefixData = new byte[PREFIX_LENGTH];
|
||||
var prefix = new byte[PREFIX_LENGTH];
|
||||
|
||||
if (compressor.IsCompressed(data))
|
||||
{
|
||||
prefixData = compressor.Peek(data, PREFIX_LENGTH);
|
||||
prefix = compressor.Peek(data, PREFIX_LENGTH);
|
||||
}
|
||||
else
|
||||
{
|
||||
data.Seek(0, SeekOrigin.Begin);
|
||||
data.Read(prefixData, 0, PREFIX_LENGTH);
|
||||
data.Read(prefix, 0, PREFIX_LENGTH);
|
||||
}
|
||||
|
||||
return Encoding.UTF8.GetString(prefixData);
|
||||
return Encoding.UTF8.GetString(prefix);
|
||||
}
|
||||
|
||||
private bool IsValid(string prefix)
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using SafeExamBrowser.Configuration.Cryptography;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.Configuration.Cryptography;
|
||||
using SafeExamBrowser.Contracts.Configuration.DataCompression;
|
||||
|
@ -21,12 +20,26 @@ namespace SafeExamBrowser.Configuration.DataFormats
|
|||
public class BinarySerializer : IDataSerializer
|
||||
{
|
||||
private IDataCompressor compressor;
|
||||
private IModuleLogger logger;
|
||||
private ILogger logger;
|
||||
private IPasswordEncryption passwordEncryption;
|
||||
private IPublicKeyEncryption publicKeyEncryption;
|
||||
private IPublicKeyEncryption symmetricEncryption;
|
||||
private IDataSerializer xmlSerializer;
|
||||
|
||||
public BinarySerializer(IDataCompressor compressor, IModuleLogger logger)
|
||||
public BinarySerializer(
|
||||
IDataCompressor compressor,
|
||||
ILogger logger,
|
||||
IPasswordEncryption passwordEncryption,
|
||||
IPublicKeyEncryption publicKeyEncryption,
|
||||
IPublicKeyEncryption symmetricEncryption,
|
||||
IDataSerializer xmlSerializer)
|
||||
{
|
||||
this.compressor = compressor;
|
||||
this.logger = logger;
|
||||
this.passwordEncryption = passwordEncryption;
|
||||
this.publicKeyEncryption = publicKeyEncryption;
|
||||
this.symmetricEncryption = symmetricEncryption;
|
||||
this.xmlSerializer = xmlSerializer;
|
||||
}
|
||||
|
||||
public bool CanSerialize(FormatType format)
|
||||
|
@ -65,12 +78,11 @@ namespace SafeExamBrowser.Configuration.DataFormats
|
|||
|
||||
if (result.Status == SaveStatus.Success)
|
||||
{
|
||||
var encryption = new PasswordEncryption(logger.CloneFor(nameof(PasswordEncryption)));
|
||||
var prefix = password.IsHash ? BinaryBlock.PasswordConfigureClient : BinaryBlock.Password;
|
||||
|
||||
logger.Debug("Attempting to serialize password block...");
|
||||
|
||||
var status = encryption.Encrypt(result.Data, password.Password, out var encrypted);
|
||||
var status = passwordEncryption.Encrypt(result.Data, password.Password, out var encrypted);
|
||||
|
||||
if (status == SaveStatus.Success)
|
||||
{
|
||||
|
@ -87,7 +99,6 @@ namespace SafeExamBrowser.Configuration.DataFormats
|
|||
{
|
||||
logger.Debug("Attempting to serialize plain data block...");
|
||||
|
||||
var xmlSerializer = new XmlSerializer(logger.CloneFor(nameof(XmlSerializer)));
|
||||
var result = xmlSerializer.TrySerialize(data);
|
||||
|
||||
if (result.Status == SaveStatus.Success)
|
||||
|
@ -109,7 +120,7 @@ namespace SafeExamBrowser.Configuration.DataFormats
|
|||
|
||||
if (result.Status == SaveStatus.Success)
|
||||
{
|
||||
var encryption = DetermineEncryptionForPublicKeyHashBlock(parameters);
|
||||
var encryption = parameters.SymmetricEncryption ? symmetricEncryption : publicKeyEncryption;
|
||||
var prefix = parameters.SymmetricEncryption ? BinaryBlock.PublicKeySymmetric : BinaryBlock.PublicKey;
|
||||
|
||||
logger.Debug("Attempting to serialize public key hash block...");
|
||||
|
@ -135,18 +146,6 @@ namespace SafeExamBrowser.Configuration.DataFormats
|
|||
return SerializePlainDataBlock(data, true);
|
||||
}
|
||||
|
||||
private PublicKeyEncryption DetermineEncryptionForPublicKeyHashBlock(PublicKeyParameters parameters)
|
||||
{
|
||||
var passwordEncryption = new PasswordEncryption(logger.CloneFor(nameof(PasswordEncryption)));
|
||||
|
||||
if (parameters.SymmetricEncryption)
|
||||
{
|
||||
return new PublicKeySymmetricEncryption(new CertificateStore(), logger.CloneFor(nameof(PublicKeySymmetricEncryption)), passwordEncryption);
|
||||
}
|
||||
|
||||
return new PublicKeyEncryption(new CertificateStore(), logger.CloneFor(nameof(PublicKeyEncryption)));
|
||||
}
|
||||
|
||||
private Stream WritePrefix(string prefix, Stream data)
|
||||
{
|
||||
var prefixBytes = Encoding.UTF8.GetBytes(prefix);
|
||||
|
|
|
@ -119,16 +119,16 @@ namespace SafeExamBrowser.Runtime
|
|||
var compressor = new GZipCompressor(ModuleLogger(nameof(GZipCompressor)));
|
||||
var passwordEncryption = new PasswordEncryption(ModuleLogger(nameof(PasswordEncryption)));
|
||||
var publicKeyEncryption = new PublicKeyEncryption(new CertificateStore(), ModuleLogger(nameof(PublicKeyEncryption)));
|
||||
var symmetricInnerEncryption = new PasswordEncryption(ModuleLogger(nameof(PasswordEncryption)));
|
||||
var symmetricEncryption = new PublicKeySymmetricEncryption(new CertificateStore(), ModuleLogger(nameof(PublicKeySymmetricEncryption)), symmetricInnerEncryption);
|
||||
var symmetricEncryption = new PublicKeySymmetricEncryption(new CertificateStore(), ModuleLogger(nameof(PublicKeySymmetricEncryption)), passwordEncryption);
|
||||
var repositoryLogger = ModuleLogger(nameof(ConfigurationRepository));
|
||||
var xmlParser = new XmlParser(ModuleLogger(nameof(XmlParser)));
|
||||
var xmlSerializer = new XmlSerializer(ModuleLogger(nameof(XmlSerializer)));
|
||||
|
||||
configuration = new ConfigurationRepository(new HashAlgorithm(), repositoryLogger, executable.Location, programCopyright, programTitle, programVersion);
|
||||
appConfig = configuration.InitializeAppConfig();
|
||||
|
||||
configuration.Register(new BinaryParser(compressor, new HashAlgorithm(), ModuleLogger(nameof(BinaryParser)), passwordEncryption, publicKeyEncryption, symmetricEncryption, xmlParser));
|
||||
configuration.Register(new BinarySerializer(compressor, ModuleLogger(nameof(BinarySerializer))));
|
||||
configuration.Register(new BinarySerializer(compressor, ModuleLogger(nameof(BinarySerializer)), passwordEncryption, publicKeyEncryption, symmetricEncryption, xmlSerializer));
|
||||
configuration.Register(new XmlParser(ModuleLogger(nameof(XmlParser))));
|
||||
configuration.Register(new XmlSerializer(ModuleLogger(nameof(XmlSerializer))));
|
||||
configuration.Register(new FileResourceLoader(ModuleLogger(nameof(FileResourceLoader))));
|
||||
|
|
Loading…
Reference in a new issue