2019-02-19 15:54:11 +01:00
|
|
|
|
/*
|
2024-03-05 18:37:42 +01:00
|
|
|
|
* Copyright (c) 2024 ETH Zürich, IT Services
|
2019-02-19 15:54:11 +01:00
|
|
|
|
*
|
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
|
*/
|
|
|
|
|
|
2019-02-20 08:47:30 +01:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Security.Cryptography.X509Certificates;
|
2019-02-19 15:54:11 +01:00
|
|
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
2019-02-20 08:47:30 +01:00
|
|
|
|
using Moq;
|
|
|
|
|
using SafeExamBrowser.Configuration.DataFormats;
|
2019-08-30 09:55:26 +02:00
|
|
|
|
using SafeExamBrowser.Configuration.Contracts;
|
|
|
|
|
using SafeExamBrowser.Configuration.Contracts.Cryptography;
|
|
|
|
|
using SafeExamBrowser.Configuration.Contracts.DataCompression;
|
|
|
|
|
using SafeExamBrowser.Configuration.Contracts.DataFormats;
|
|
|
|
|
using SafeExamBrowser.Logging.Contracts;
|
2019-02-19 15:54:11 +01:00
|
|
|
|
|
|
|
|
|
namespace SafeExamBrowser.Configuration.UnitTests.DataFormats
|
|
|
|
|
{
|
|
|
|
|
[TestClass]
|
|
|
|
|
public class BinarySerializerTests
|
|
|
|
|
{
|
2019-02-20 08:47:30 +01:00
|
|
|
|
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;
|
|
|
|
|
|
2019-02-19 15:54:11 +01:00
|
|
|
|
[TestInitialize]
|
|
|
|
|
public void Initialize()
|
|
|
|
|
{
|
2019-02-20 08:47:30 +01:00
|
|
|
|
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();
|
2019-02-19 15:54:11 +01:00
|
|
|
|
|
2019-02-20 08:47:30 +01:00
|
|
|
|
Assert.AreEqual(SaveStatus.Success, result.Status);
|
2019-02-19 15:54:11 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|