SEBWIN-296: Decoupled cryptographic implementations from data formats to be able to unit test the latter.
This commit is contained in:
		
							parent
							
								
									f817f31f2d
								
							
						
					
					
						commit
						cf7d6c4d3e
					
				
					 20 changed files with 392 additions and 81 deletions
				
			
		|  | @ -21,13 +21,13 @@ using SafeExamBrowser.Contracts.Logging; | ||||||
| namespace SafeExamBrowser.Configuration.UnitTests.Cryptography | namespace SafeExamBrowser.Configuration.UnitTests.Cryptography | ||||||
| { | { | ||||||
| 	[TestClass] | 	[TestClass] | ||||||
| 	public class PublicKeyHashEncryptionTests | 	public class PublicKeyEncryptionTests | ||||||
| 	{ | 	{ | ||||||
| 		private Mock<ILogger> logger; | 		private Mock<ILogger> logger; | ||||||
| 		private Mock<ICertificateStore> store; | 		private Mock<ICertificateStore> store; | ||||||
| 		private X509Certificate2 certificate; | 		private X509Certificate2 certificate; | ||||||
| 
 | 
 | ||||||
| 		private PublicKeyHashEncryption sut; | 		private PublicKeyEncryption sut; | ||||||
| 
 | 
 | ||||||
| 		[TestInitialize] | 		[TestInitialize] | ||||||
| 		public void Initialize() | 		public void Initialize() | ||||||
|  | @ -38,7 +38,7 @@ namespace SafeExamBrowser.Configuration.UnitTests.Cryptography | ||||||
| 			LoadCertificate(); | 			LoadCertificate(); | ||||||
| 			store.Setup(s => s.TryGetCertificateWith(It.IsAny<byte[]>(), out certificate)).Returns(true); | 			store.Setup(s => s.TryGetCertificateWith(It.IsAny<byte[]>(), out certificate)).Returns(true); | ||||||
| 
 | 
 | ||||||
| 			sut = new PublicKeyHashEncryption(store.Object, logger.Object); | 			sut = new PublicKeyEncryption(store.Object, logger.Object); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		[TestMethod] | 		[TestMethod] | ||||||
|  | @ -21,13 +21,13 @@ using SafeExamBrowser.Contracts.Logging; | ||||||
| namespace SafeExamBrowser.Configuration.UnitTests.Cryptography | namespace SafeExamBrowser.Configuration.UnitTests.Cryptography | ||||||
| { | { | ||||||
| 	[TestClass] | 	[TestClass] | ||||||
| 	public class PublicKeyHashWithSymmetricKeyEncryptionTests | 	public class PublicKeySymmetricEncryptionTests | ||||||
| 	{ | 	{ | ||||||
| 		private Mock<ILogger> logger; | 		private Mock<ILogger> logger; | ||||||
| 		private PasswordEncryption passwordEncryption; | 		private PasswordEncryption passwordEncryption; | ||||||
| 		private Mock<ICertificateStore> store; | 		private Mock<ICertificateStore> store; | ||||||
| 
 | 
 | ||||||
| 		private PublicKeyHashWithSymmetricKeyEncryption sut; | 		private PublicKeySymmetricEncryption sut; | ||||||
| 		private X509Certificate2 certificate; | 		private X509Certificate2 certificate; | ||||||
| 
 | 
 | ||||||
| 		[TestInitialize] | 		[TestInitialize] | ||||||
|  | @ -40,7 +40,7 @@ namespace SafeExamBrowser.Configuration.UnitTests.Cryptography | ||||||
| 			LoadCertificate(); | 			LoadCertificate(); | ||||||
| 			store.Setup(s => s.TryGetCertificateWith(It.IsAny<byte[]>(), out certificate)).Returns(true); | 			store.Setup(s => s.TryGetCertificateWith(It.IsAny<byte[]>(), out certificate)).Returns(true); | ||||||
| 
 | 
 | ||||||
| 			sut = new PublicKeyHashWithSymmetricKeyEncryption(store.Object, logger.Object, passwordEncryption); | 			sut = new PublicKeySymmetricEncryption(store.Object, logger.Object, passwordEncryption); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		[TestMethod] | 		[TestMethod] | ||||||
|  | @ -0,0 +1,168 @@ | ||||||
|  | /* | ||||||
|  |  * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) | ||||||
|  |  *  | ||||||
|  |  * 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/. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | using System.IO; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Security.Cryptography.X509Certificates; | ||||||
|  | using System.Text; | ||||||
|  | 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 BinaryParserTests | ||||||
|  | 	{ | ||||||
|  | 		private Mock<IDataCompressor> compressor; | ||||||
|  | 		private Mock<IHashAlgorithm> hashAlgorithm; | ||||||
|  | 		private Mock<ILogger> logger; | ||||||
|  | 		private Mock<IPasswordEncryption> passwordEncryption; | ||||||
|  | 		private Mock<IPublicKeyEncryption> publicKeyEncryption; | ||||||
|  | 		private Mock<IPublicKeyEncryption> symmetricEncryption; | ||||||
|  | 		private Mock<IDataParser> xmlParser; | ||||||
|  | 
 | ||||||
|  | 		private BinaryParser sut; | ||||||
|  | 
 | ||||||
|  | 		[TestInitialize] | ||||||
|  | 		public void Initialize() | ||||||
|  | 		{ | ||||||
|  | 			compressor = new Mock<IDataCompressor>(); | ||||||
|  | 			hashAlgorithm = new Mock<IHashAlgorithm>(); | ||||||
|  | 			logger = new Mock<ILogger>(); | ||||||
|  | 			passwordEncryption = new Mock<IPasswordEncryption>(); | ||||||
|  | 			publicKeyEncryption = new Mock<IPublicKeyEncryption>(); | ||||||
|  | 			symmetricEncryption = new Mock<IPublicKeyEncryption>(); | ||||||
|  | 			xmlParser = new Mock<IDataParser>(); | ||||||
|  | 
 | ||||||
|  | 			xmlParser.Setup(p => p.TryParse(It.IsAny<Stream>(), It.IsAny<PasswordParameters>())).Returns(new ParseResult { Status = LoadStatus.Success }); | ||||||
|  | 
 | ||||||
|  | 			sut = new BinaryParser(compressor.Object, hashAlgorithm.Object, logger.Object, passwordEncryption.Object, publicKeyEncryption.Object, symmetricEncryption.Object, xmlParser.Object); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		[TestMethod] | ||||||
|  | 		public void MustCorrectlyDetectValidPrefixes() | ||||||
|  | 		{ | ||||||
|  | 			var data = new byte[123]; | ||||||
|  | 			var pswd = new MemoryStream(Encoding.UTF8.GetBytes(BinaryBlock.Password).Concat(data).ToArray()); | ||||||
|  | 			var pwcc = new MemoryStream(Encoding.UTF8.GetBytes(BinaryBlock.PasswordConfigureClient).Concat(data).ToArray()); | ||||||
|  | 			var plnd = new MemoryStream(Encoding.UTF8.GetBytes(BinaryBlock.PlainData).Concat(data).ToArray()); | ||||||
|  | 			var pkhs = new MemoryStream(Encoding.UTF8.GetBytes(BinaryBlock.PublicKey).Concat(data).ToArray()); | ||||||
|  | 			var phsk = new MemoryStream(Encoding.UTF8.GetBytes(BinaryBlock.PublicKeySymmetric).Concat(data).ToArray()); | ||||||
|  | 
 | ||||||
|  | 			Assert.IsFalse(sut.CanParse(null)); | ||||||
|  | 			Assert.IsFalse(sut.CanParse(new MemoryStream())); | ||||||
|  | 			Assert.IsFalse(sut.CanParse(new MemoryStream(data))); | ||||||
|  | 
 | ||||||
|  | 			Assert.IsTrue(sut.CanParse(pswd)); | ||||||
|  | 			Assert.IsTrue(sut.CanParse(pwcc)); | ||||||
|  | 			Assert.IsTrue(sut.CanParse(plnd)); | ||||||
|  | 			Assert.IsTrue(sut.CanParse(pkhs)); | ||||||
|  | 			Assert.IsTrue(sut.CanParse(phsk)); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		[TestMethod] | ||||||
|  | 		public void MustCorrectlyParsePasswordBlock() | ||||||
|  | 		{ | ||||||
|  | 			var data = new byte[123]; | ||||||
|  | 			var decrypted = default(Stream); | ||||||
|  | 			var pswd = new MemoryStream(Encoding.UTF8.GetBytes(BinaryBlock.Password).Concat(data).ToArray()) as Stream; | ||||||
|  | 
 | ||||||
|  | 			passwordEncryption.Setup(p => p.Decrypt(It.IsAny<Stream>(), It.Is<string>(s => s == "wrong"), out decrypted)).Returns(LoadStatus.PasswordNeeded); | ||||||
|  | 			passwordEncryption.Setup(p => p.Decrypt(It.IsAny<Stream>(), It.Is<string>(s => s == "correct"), out decrypted)).Returns(LoadStatus.Success); | ||||||
|  | 
 | ||||||
|  | 			var result = sut.TryParse(pswd); | ||||||
|  | 
 | ||||||
|  | 			Assert.AreEqual(LoadStatus.PasswordNeeded, result.Status); | ||||||
|  | 
 | ||||||
|  | 			result = sut.TryParse(pswd, new PasswordParameters { Password = "wrong" }); | ||||||
|  | 
 | ||||||
|  | 			Assert.AreEqual(LoadStatus.PasswordNeeded, result.Status); | ||||||
|  | 
 | ||||||
|  | 			result = sut.TryParse(pswd, new PasswordParameters { Password = "correct" }); | ||||||
|  | 
 | ||||||
|  | 			passwordEncryption.Verify(p => p.Decrypt(It.IsAny<Stream>(), It.IsAny<string>(), out decrypted), Times.AtLeastOnce); | ||||||
|  | 			xmlParser.Verify(p => p.TryParse(It.Is<Stream>(s => s == decrypted), It.IsAny<PasswordParameters>()), Times.Once); | ||||||
|  | 			publicKeyEncryption.VerifyNoOtherCalls(); | ||||||
|  | 			symmetricEncryption.VerifyNoOtherCalls(); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		[TestMethod] | ||||||
|  | 		public void MustCorrectlyParsePlainDataBlock() | ||||||
|  | 		{ | ||||||
|  | 			var data = new byte[123]; | ||||||
|  | 			var plnd = new MemoryStream(Encoding.UTF8.GetBytes(BinaryBlock.PlainData).Concat(data).ToArray()); | ||||||
|  | 
 | ||||||
|  | 			compressor.Setup(c => c.Decompress(It.IsAny<Stream>())).Returns(plnd); | ||||||
|  | 			compressor.Setup(c => c.Peek(It.IsAny<Stream>(), It.IsAny<int>())).Returns(Encoding.UTF8.GetBytes(BinaryBlock.PlainData)); | ||||||
|  | 			compressor.Setup(c => c.IsCompressed(It.IsAny<Stream>())).Returns(true); | ||||||
|  | 
 | ||||||
|  | 			var result = sut.TryParse(plnd); | ||||||
|  | 
 | ||||||
|  | 			compressor.Verify(c => c.IsCompressed(It.IsAny<Stream>()), Times.AtLeastOnce); | ||||||
|  | 			compressor.Verify(c => c.Decompress(It.IsAny<Stream>()), Times.AtLeastOnce); | ||||||
|  | 			xmlParser.Verify(x => x.TryParse(It.IsAny<Stream>(), It.IsAny<PasswordParameters>()), Times.Once); | ||||||
|  | 			passwordEncryption.VerifyNoOtherCalls(); | ||||||
|  | 			publicKeyEncryption.VerifyNoOtherCalls(); | ||||||
|  | 			symmetricEncryption.VerifyNoOtherCalls(); | ||||||
|  | 
 | ||||||
|  | 			Assert.AreEqual(LoadStatus.Success, result.Status); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		[TestMethod] | ||||||
|  | 		public void MustCorrectlyParsePublicKeyBlock() | ||||||
|  | 		{ | ||||||
|  | 			var data = new byte[123]; | ||||||
|  | 			var certificate = default(X509Certificate2); | ||||||
|  | 			var decrypted = default(Stream); | ||||||
|  | 			var pswd = new MemoryStream(Encoding.UTF8.GetBytes(BinaryBlock.Password).Concat(data).ToArray()) as Stream; | ||||||
|  | 			var pkhs = new MemoryStream(Encoding.UTF8.GetBytes(BinaryBlock.PublicKey).Concat(data).ToArray()); | ||||||
|  | 
 | ||||||
|  | 			passwordEncryption.Setup(p => p.Decrypt(It.IsAny<Stream>(), It.IsAny<string>(), out decrypted)).Returns(LoadStatus.Success); | ||||||
|  | 			publicKeyEncryption.Setup(p => p.Decrypt(It.IsAny<Stream>(), out pswd, out certificate)).Returns(LoadStatus.Success); | ||||||
|  | 
 | ||||||
|  | 			var result = sut.TryParse(pkhs, new PasswordParameters { Password = "blubb" }); | ||||||
|  | 
 | ||||||
|  | 			publicKeyEncryption.Verify(p => p.Decrypt(It.IsAny<Stream>(), out decrypted, out certificate), Times.Once); | ||||||
|  | 			passwordEncryption.Verify(p => p.Decrypt(It.IsAny<Stream>(), It.Is<string>(s => s == "blubb"), out decrypted), Times.Once); | ||||||
|  | 			symmetricEncryption.VerifyNoOtherCalls(); | ||||||
|  | 
 | ||||||
|  | 			Assert.AreEqual(LoadStatus.Success, result.Status); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		[TestMethod] | ||||||
|  | 		public void MustOnlyParseIfFormatSupported() | ||||||
|  | 		{ | ||||||
|  | 			var data = new byte[123]; | ||||||
|  | 			var certificate = default(X509Certificate2); | ||||||
|  | 			var decrypted = default(Stream); | ||||||
|  | 			var pswd = new MemoryStream(Encoding.UTF8.GetBytes(BinaryBlock.Password).Concat(data).ToArray()) as Stream; | ||||||
|  | 			var pwcc = new MemoryStream(Encoding.UTF8.GetBytes(BinaryBlock.PasswordConfigureClient).Concat(data).ToArray()); | ||||||
|  | 			var plnd = new MemoryStream(Encoding.UTF8.GetBytes(BinaryBlock.PlainData).Concat(data).ToArray()); | ||||||
|  | 			var pkhs = new MemoryStream(Encoding.UTF8.GetBytes(BinaryBlock.PublicKey).Concat(data).ToArray()); | ||||||
|  | 			var phsk = new MemoryStream(Encoding.UTF8.GetBytes(BinaryBlock.PublicKeySymmetric).Concat(data).ToArray()); | ||||||
|  | 
 | ||||||
|  | 			passwordEncryption.Setup(p => p.Decrypt(It.IsAny<Stream>(), It.IsAny<string>(), out decrypted)).Returns(LoadStatus.Success); | ||||||
|  | 			publicKeyEncryption.Setup(p => p.Decrypt(It.IsAny<Stream>(), out pswd, out certificate)).Returns(LoadStatus.Success); | ||||||
|  | 			symmetricEncryption.Setup(p => p.Decrypt(It.IsAny<Stream>(), out pswd, out certificate)).Returns(LoadStatus.Success); | ||||||
|  | 
 | ||||||
|  | 			Assert.AreEqual(LoadStatus.InvalidData, sut.TryParse(new MemoryStream(data)).Status); | ||||||
|  | 
 | ||||||
|  | 			Assert.AreEqual(LoadStatus.Success, sut.TryParse(pswd, new PasswordParameters { Password = "blubb" })?.Status); | ||||||
|  | 			Assert.AreEqual(LoadStatus.Success, sut.TryParse(pwcc, new PasswordParameters { Password = "blubb" })?.Status); | ||||||
|  | 			Assert.AreEqual(LoadStatus.Success, sut.TryParse(plnd).Status); | ||||||
|  | 			Assert.AreEqual(LoadStatus.Success, sut.TryParse(pkhs, new PasswordParameters { Password = "blubb" }).Status); | ||||||
|  | 			Assert.AreEqual(LoadStatus.Success, sut.TryParse(phsk, new PasswordParameters { Password = "blubb" }).Status); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -0,0 +1,22 @@ | ||||||
|  | /* | ||||||
|  |  * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) | ||||||
|  |  *  | ||||||
|  |  * 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/. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||||
|  | 
 | ||||||
|  | namespace SafeExamBrowser.Configuration.UnitTests.DataFormats | ||||||
|  | { | ||||||
|  | 	[TestClass] | ||||||
|  | 	public class BinarySerializerTests | ||||||
|  | 	{ | ||||||
|  | 		[TestInitialize] | ||||||
|  | 		public void Initialize() | ||||||
|  | 		{ | ||||||
|  | 
 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -0,0 +1,22 @@ | ||||||
|  | /* | ||||||
|  |  * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) | ||||||
|  |  *  | ||||||
|  |  * 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/. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||||
|  | 
 | ||||||
|  | namespace SafeExamBrowser.Configuration.UnitTests.DataFormats | ||||||
|  | { | ||||||
|  | 	[TestClass] | ||||||
|  | 	public class XmlParserTests | ||||||
|  | 	{ | ||||||
|  | 		[TestInitialize] | ||||||
|  | 		public void Initialize() | ||||||
|  | 		{ | ||||||
|  | 
 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -0,0 +1,22 @@ | ||||||
|  | /* | ||||||
|  |  * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) | ||||||
|  |  *  | ||||||
|  |  * 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/. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||||
|  | 
 | ||||||
|  | namespace SafeExamBrowser.Configuration.UnitTests.DataFormats | ||||||
|  | { | ||||||
|  | 	[TestClass] | ||||||
|  | 	public class XmlSerializerTests | ||||||
|  | 	{ | ||||||
|  | 		[TestInitialize] | ||||||
|  | 		public void Initialize() | ||||||
|  | 		{ | ||||||
|  | 
 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -86,9 +86,13 @@ | ||||||
|     <Compile Include="ConfigurationRepositoryTests.cs" /> |     <Compile Include="ConfigurationRepositoryTests.cs" /> | ||||||
|     <Compile Include="Cryptography\HashAlgorithmTests.cs" /> |     <Compile Include="Cryptography\HashAlgorithmTests.cs" /> | ||||||
|     <Compile Include="Cryptography\PasswordEncryptionTests.cs" /> |     <Compile Include="Cryptography\PasswordEncryptionTests.cs" /> | ||||||
|     <Compile Include="Cryptography\PublicKeyHashEncryptionTests.cs" /> |     <Compile Include="Cryptography\PublicKeyEncryptionTests.cs" /> | ||||||
|     <Compile Include="Cryptography\PublicKeyHashWithSymmetricKeyEncryptionTests.cs" /> |     <Compile Include="Cryptography\PublicKeySymmetricEncryptionTests.cs" /> | ||||||
|     <Compile Include="DataCompression\GZipCompressorTests.cs" /> |     <Compile Include="DataCompression\GZipCompressorTests.cs" /> | ||||||
|  |     <Compile Include="DataFormats\BinaryParserTests.cs" /> | ||||||
|  |     <Compile Include="DataFormats\BinarySerializerTests.cs" /> | ||||||
|  |     <Compile Include="DataFormats\XmlParserTests.cs" /> | ||||||
|  |     <Compile Include="DataFormats\XmlSerializerTests.cs" /> | ||||||
|     <Compile Include="Properties\AssemblyInfo.cs" /> |     <Compile Include="Properties\AssemblyInfo.cs" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|  |  | ||||||
|  | @ -13,7 +13,7 @@ using SafeExamBrowser.Contracts.Configuration.Cryptography; | ||||||
| 
 | 
 | ||||||
| namespace SafeExamBrowser.Configuration.Cryptography | namespace SafeExamBrowser.Configuration.Cryptography | ||||||
| { | { | ||||||
| 	internal class CertificateStore : ICertificateStore | 	public class CertificateStore : ICertificateStore | ||||||
| 	{ | 	{ | ||||||
| 		private readonly X509Store[] stores = new[] | 		private readonly X509Store[] stores = new[] | ||||||
| 		{ | 		{ | ||||||
|  |  | ||||||
|  | @ -10,11 +10,12 @@ using System.IO; | ||||||
| using System.Linq; | using System.Linq; | ||||||
| using System.Security.Cryptography; | using System.Security.Cryptography; | ||||||
| using SafeExamBrowser.Contracts.Configuration; | using SafeExamBrowser.Contracts.Configuration; | ||||||
|  | using SafeExamBrowser.Contracts.Configuration.Cryptography; | ||||||
| using SafeExamBrowser.Contracts.Logging; | using SafeExamBrowser.Contracts.Logging; | ||||||
| 
 | 
 | ||||||
| namespace SafeExamBrowser.Configuration.Cryptography | namespace SafeExamBrowser.Configuration.Cryptography | ||||||
| { | { | ||||||
| 	internal class PasswordEncryption | 	public class PasswordEncryption : IPasswordEncryption | ||||||
| 	{ | 	{ | ||||||
| 		private const int BLOCK_SIZE = 16; | 		private const int BLOCK_SIZE = 16; | ||||||
| 		private const int HEADER_SIZE = 2; | 		private const int HEADER_SIZE = 2; | ||||||
|  | @ -26,14 +27,14 @@ namespace SafeExamBrowser.Configuration.Cryptography | ||||||
| 
 | 
 | ||||||
| 		private ILogger logger; | 		private ILogger logger; | ||||||
| 
 | 
 | ||||||
| 		internal PasswordEncryption(ILogger logger) | 		public PasswordEncryption(ILogger logger) | ||||||
| 		{ | 		{ | ||||||
| 			this.logger = logger; | 			this.logger = logger; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		internal LoadStatus Decrypt(Stream data, string password, out Stream decryptedData) | 		public LoadStatus Decrypt(Stream data, string password, out Stream decrypted) | ||||||
| 		{ | 		{ | ||||||
| 			decryptedData = default(Stream); | 			decrypted = default(Stream); | ||||||
| 
 | 
 | ||||||
| 			if (password == null) | 			if (password == null) | ||||||
| 			{ | 			{ | ||||||
|  | @ -49,17 +50,17 @@ namespace SafeExamBrowser.Configuration.Cryptography | ||||||
| 				return FailForInvalidHmac(); | 				return FailForInvalidHmac(); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			decryptedData = Decrypt(data, encryptionKey, originalHmac.Length); | 			decrypted = Decrypt(data, encryptionKey, originalHmac.Length); | ||||||
| 
 | 
 | ||||||
| 			return LoadStatus.Success; | 			return LoadStatus.Success; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		internal SaveStatus Encrypt(Stream data, string password, out Stream encryptedData) | 		public SaveStatus Encrypt(Stream data, string password, out Stream encrypted) | ||||||
| 		{ | 		{ | ||||||
| 			var (authKey, authSalt, encrKey, encrSalt) = GenerateKeysForEncryption(password); | 			var (authKey, authSalt, encrKey, encrSalt) = GenerateKeysForEncryption(password); | ||||||
| 			 | 			 | ||||||
| 			encryptedData = Encrypt(data, encrKey, out var initVector); | 			encrypted = Encrypt(data, encrKey, out var initVector); | ||||||
| 			encryptedData = WriteEncryptionParameters(authKey, authSalt, encrSalt, initVector, encryptedData); | 			encrypted = WriteEncryptionParameters(authKey, authSalt, encrSalt, initVector, encrypted); | ||||||
| 
 | 
 | ||||||
| 			return SaveStatus.Success; | 			return SaveStatus.Success; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -15,20 +15,20 @@ using SafeExamBrowser.Contracts.Logging; | ||||||
| 
 | 
 | ||||||
| namespace SafeExamBrowser.Configuration.Cryptography | namespace SafeExamBrowser.Configuration.Cryptography | ||||||
| { | { | ||||||
| 	internal class PublicKeyHashEncryption | 	public class PublicKeyEncryption : IPublicKeyEncryption | ||||||
| 	{ | 	{ | ||||||
| 		protected const int PUBLIC_KEY_HASH_SIZE = 20; | 		protected const int PUBLIC_KEY_HASH_SIZE = 20; | ||||||
| 
 | 
 | ||||||
| 		protected ICertificateStore store; | 		protected ICertificateStore store; | ||||||
| 		protected ILogger logger; | 		protected ILogger logger; | ||||||
| 
 | 
 | ||||||
| 		internal PublicKeyHashEncryption(ICertificateStore store, ILogger logger) | 		public PublicKeyEncryption(ICertificateStore store, ILogger logger) | ||||||
| 		{ | 		{ | ||||||
| 			this.logger = logger; | 			this.logger = logger; | ||||||
| 			this.store = store; | 			this.store = store; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		internal virtual LoadStatus Decrypt(Stream data, out Stream decryptedData, out X509Certificate2 certificate) | 		public virtual LoadStatus Decrypt(Stream data, out Stream decryptedData, out X509Certificate2 certificate) | ||||||
| 		{ | 		{ | ||||||
| 			var publicKeyHash = ParsePublicKeyHash(data); | 			var publicKeyHash = ParsePublicKeyHash(data); | ||||||
| 			var found = store.TryGetCertificateWith(publicKeyHash, out certificate); | 			var found = store.TryGetCertificateWith(publicKeyHash, out certificate); | ||||||
|  | @ -45,7 +45,7 @@ namespace SafeExamBrowser.Configuration.Cryptography | ||||||
| 			return LoadStatus.Success; | 			return LoadStatus.Success; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		internal virtual SaveStatus Encrypt(Stream data, X509Certificate2 certificate, out Stream encryptedData) | 		public virtual SaveStatus Encrypt(Stream data, X509Certificate2 certificate, out Stream encryptedData) | ||||||
| 		{ | 		{ | ||||||
| 			var publicKeyHash = GeneratePublicKeyHash(certificate); | 			var publicKeyHash = GeneratePublicKeyHash(certificate); | ||||||
| 
 | 
 | ||||||
|  | @ -16,19 +16,19 @@ using SafeExamBrowser.Contracts.Logging; | ||||||
| 
 | 
 | ||||||
| namespace SafeExamBrowser.Configuration.Cryptography | namespace SafeExamBrowser.Configuration.Cryptography | ||||||
| { | { | ||||||
| 	internal class PublicKeyHashWithSymmetricKeyEncryption : PublicKeyHashEncryption | 	public class PublicKeySymmetricEncryption : PublicKeyEncryption | ||||||
| 	{ | 	{ | ||||||
| 		private const int ENCRYPTION_KEY_LENGTH = 32; | 		private const int ENCRYPTION_KEY_LENGTH = 32; | ||||||
| 		private const int KEY_LENGTH_SIZE = 4; | 		private const int KEY_LENGTH_SIZE = 4; | ||||||
| 
 | 
 | ||||||
| 		private PasswordEncryption passwordEncryption; | 		private PasswordEncryption passwordEncryption; | ||||||
| 
 | 
 | ||||||
| 		internal PublicKeyHashWithSymmetricKeyEncryption(ICertificateStore store, ILogger logger, PasswordEncryption passwordEncryption) : base(store, logger) | 		public PublicKeySymmetricEncryption(ICertificateStore store, ILogger logger, PasswordEncryption passwordEncryption) : base(store, logger) | ||||||
| 		{ | 		{ | ||||||
| 			this.passwordEncryption = passwordEncryption; | 			this.passwordEncryption = passwordEncryption; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		internal override LoadStatus Decrypt(Stream data, out Stream decryptedData, out X509Certificate2 certificate) | 		public override LoadStatus Decrypt(Stream data, out Stream decryptedData, out X509Certificate2 certificate) | ||||||
| 		{ | 		{ | ||||||
| 			var publicKeyHash = ParsePublicKeyHash(data); | 			var publicKeyHash = ParsePublicKeyHash(data); | ||||||
| 			var found = store.TryGetCertificateWith(publicKeyHash, out certificate); | 			var found = store.TryGetCertificateWith(publicKeyHash, out certificate); | ||||||
|  | @ -47,7 +47,7 @@ namespace SafeExamBrowser.Configuration.Cryptography | ||||||
| 			return status; | 			return status; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		internal override SaveStatus Encrypt(Stream data, X509Certificate2 certificate, out Stream encryptedData) | 		public override SaveStatus Encrypt(Stream data, X509Certificate2 certificate, out Stream encryptedData) | ||||||
| 		{ | 		{ | ||||||
| 			var publicKeyHash = GeneratePublicKeyHash(certificate); | 			var publicKeyHash = GeneratePublicKeyHash(certificate); | ||||||
| 			var symmetricKey = GenerateSymmetricKey(); | 			var symmetricKey = GenerateSymmetricKey(); | ||||||
|  | @ -13,7 +13,7 @@ namespace SafeExamBrowser.Configuration.DataFormats | ||||||
| 		internal const string Password = "pswd"; | 		internal const string Password = "pswd"; | ||||||
| 		internal const string PasswordConfigureClient = "pwcc"; | 		internal const string PasswordConfigureClient = "pwcc"; | ||||||
| 		internal const string PlainData = "plnd"; | 		internal const string PlainData = "plnd"; | ||||||
| 		internal const string PublicKeyHash = "pkhs"; | 		internal const string PublicKey = "pkhs"; | ||||||
| 		internal const string PublicKeyHashWithSymmetricKey = "phsk"; | 		internal const string PublicKeySymmetric = "phsk"; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -11,7 +11,6 @@ using System.IO; | ||||||
| using System.Linq; | using System.Linq; | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
| using System.Text; | using System.Text; | ||||||
| using SafeExamBrowser.Configuration.Cryptography; |  | ||||||
| using SafeExamBrowser.Contracts.Configuration; | using SafeExamBrowser.Contracts.Configuration; | ||||||
| using SafeExamBrowser.Contracts.Configuration.Cryptography; | using SafeExamBrowser.Contracts.Configuration.Cryptography; | ||||||
| using SafeExamBrowser.Contracts.Configuration.DataCompression; | using SafeExamBrowser.Contracts.Configuration.DataCompression; | ||||||
|  | @ -26,13 +25,28 @@ namespace SafeExamBrowser.Configuration.DataFormats | ||||||
| 
 | 
 | ||||||
| 		private IDataCompressor compressor; | 		private IDataCompressor compressor; | ||||||
| 		private IHashAlgorithm hashAlgorithm; | 		private IHashAlgorithm hashAlgorithm; | ||||||
| 		private IModuleLogger logger; | 		private ILogger logger; | ||||||
|  | 		private IPasswordEncryption passwordEncryption; | ||||||
|  | 		private IPublicKeyEncryption publicKeyEncryption; | ||||||
|  | 		private IPublicKeyEncryption publicKeySymmetricEncryption; | ||||||
|  | 		private readonly IDataParser xmlParser; | ||||||
| 
 | 
 | ||||||
| 		public BinaryParser(IDataCompressor compressor, IHashAlgorithm hashAlgorithm, IModuleLogger logger) | 		public BinaryParser( | ||||||
|  | 			IDataCompressor compressor, | ||||||
|  | 			IHashAlgorithm hashAlgorithm, | ||||||
|  | 			ILogger logger, | ||||||
|  | 			IPasswordEncryption passwordEncryption, | ||||||
|  | 			IPublicKeyEncryption publicKeyEncryption, | ||||||
|  | 			IPublicKeyEncryption publicKeySymmetricEncryption, | ||||||
|  | 			IDataParser xmlParser) | ||||||
| 		{ | 		{ | ||||||
| 			this.compressor = compressor; | 			this.compressor = compressor; | ||||||
| 			this.hashAlgorithm = hashAlgorithm; | 			this.hashAlgorithm = hashAlgorithm; | ||||||
| 			this.logger = logger; | 			this.logger = logger; | ||||||
|  | 			this.passwordEncryption = passwordEncryption; | ||||||
|  | 			this.publicKeyEncryption = publicKeyEncryption; | ||||||
|  | 			this.publicKeySymmetricEncryption = publicKeySymmetricEncryption; | ||||||
|  | 			this.xmlParser = xmlParser; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		public bool CanParse(Stream data) | 		public bool CanParse(Stream data) | ||||||
|  | @ -55,7 +69,7 @@ namespace SafeExamBrowser.Configuration.DataFormats | ||||||
| 			} | 			} | ||||||
| 			catch (Exception e) | 			catch (Exception e) | ||||||
| 			{ | 			{ | ||||||
| 				logger.Error($"Failed to determine whether '{data}' with {data.Length / 1000.0} KB data matches the {FormatType.Binary} format!", e); | 				logger.Error($"Failed to determine whether '{data}' with {data?.Length / 1000.0} KB data matches the {FormatType.Binary} format!", e); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			return false; | 			return false; | ||||||
|  | @ -78,9 +92,9 @@ namespace SafeExamBrowser.Configuration.DataFormats | ||||||
| 						return ParsePasswordBlock(data, prefix, password); | 						return ParsePasswordBlock(data, prefix, password); | ||||||
| 					case BinaryBlock.PlainData: | 					case BinaryBlock.PlainData: | ||||||
| 						return ParsePlainDataBlock(data); | 						return ParsePlainDataBlock(data); | ||||||
| 					case BinaryBlock.PublicKeyHash: | 					case BinaryBlock.PublicKey: | ||||||
| 					case BinaryBlock.PublicKeyHashWithSymmetricKey: | 					case BinaryBlock.PublicKeySymmetric: | ||||||
| 						return ParsePublicKeyHashBlock(data, prefix, password); | 						return ParsePublicKeyBlock(data, prefix, password); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -91,20 +105,19 @@ namespace SafeExamBrowser.Configuration.DataFormats | ||||||
| 
 | 
 | ||||||
| 		private ParseResult ParsePasswordBlock(Stream data, string prefix, PasswordParameters password = null) | 		private ParseResult ParsePasswordBlock(Stream data, string prefix, PasswordParameters password = null) | ||||||
| 		{ | 		{ | ||||||
| 			var encryption = new PasswordEncryption(logger.CloneFor(nameof(PasswordEncryption))); |  | ||||||
| 			var result = new ParseResult(); | 			var result = new ParseResult(); | ||||||
| 
 | 
 | ||||||
| 			if (password != null) | 			if (password != null) | ||||||
| 			{ | 			{ | ||||||
| 				var encryptionParameters = DetermineEncryptionParametersFor(prefix, password); | 				var parameters = DetermineEncryptionParametersFor(prefix, password); | ||||||
| 
 | 
 | ||||||
| 				logger.Debug($"Attempting to parse password block with prefix '{prefix}'..."); | 				logger.Debug($"Attempting to parse password block with prefix '{prefix}'..."); | ||||||
| 				result.Status = encryption.Decrypt(data, encryptionParameters.Password, out var decrypted); | 				result.Status = passwordEncryption.Decrypt(data, parameters.Password, out var decrypted); | ||||||
| 
 | 
 | ||||||
| 				if (result.Status == LoadStatus.Success) | 				if (result.Status == LoadStatus.Success) | ||||||
| 				{ | 				{ | ||||||
| 					result = ParsePlainDataBlock(decrypted); | 					result = ParsePlainDataBlock(decrypted); | ||||||
| 					result.Encryption = encryptionParameters; | 					result.Encryption = parameters; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			else | 			else | ||||||
|  | @ -117,20 +130,18 @@ namespace SafeExamBrowser.Configuration.DataFormats | ||||||
| 
 | 
 | ||||||
| 		private ParseResult ParsePlainDataBlock(Stream data) | 		private ParseResult ParsePlainDataBlock(Stream data) | ||||||
| 		{ | 		{ | ||||||
| 			var xmlFormat = new XmlParser(logger.CloneFor(nameof(XmlParser))); |  | ||||||
| 
 |  | ||||||
| 			data = compressor.IsCompressed(data) ? compressor.Decompress(data) : data; | 			data = compressor.IsCompressed(data) ? compressor.Decompress(data) : data; | ||||||
| 			logger.Debug("Attempting to parse plain data block..."); | 			logger.Debug("Attempting to parse plain data block..."); | ||||||
| 
 | 
 | ||||||
| 			var result = xmlFormat.TryParse(data); | 			var result = xmlParser.TryParse(data); | ||||||
| 			result.Format = FormatType.Binary; | 			result.Format = FormatType.Binary; | ||||||
| 
 | 
 | ||||||
| 			return result; | 			return result; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		private ParseResult ParsePublicKeyHashBlock(Stream data, string prefix, PasswordParameters password = null) | 		private ParseResult ParsePublicKeyBlock(Stream data, string prefix, PasswordParameters password = null) | ||||||
| 		{ | 		{ | ||||||
| 			var encryption = DetermineEncryptionForPublicKeyHashBlock(prefix); | 			var encryption = prefix == BinaryBlock.PublicKey ? publicKeyEncryption : publicKeySymmetricEncryption; | ||||||
| 			var result = new ParseResult(); | 			var result = new ParseResult(); | ||||||
| 
 | 
 | ||||||
| 			logger.Debug($"Attempting to parse public key hash block with prefix '{prefix}'..."); | 			logger.Debug($"Attempting to parse public key hash block with prefix '{prefix}'..."); | ||||||
|  | @ -139,29 +150,17 @@ namespace SafeExamBrowser.Configuration.DataFormats | ||||||
| 			if (result.Status == LoadStatus.Success) | 			if (result.Status == LoadStatus.Success) | ||||||
| 			{ | 			{ | ||||||
| 				result = TryParse(decrypted, password); | 				result = TryParse(decrypted, password); | ||||||
| 				result.Encryption = new PublicKeyHashParameters | 				result.Encryption = new PublicKeyParameters | ||||||
| 				{ | 				{ | ||||||
| 					Certificate = certificate, | 					Certificate = certificate, | ||||||
| 					InnerEncryption = result.Encryption as PasswordParameters, | 					InnerEncryption = result.Encryption as PasswordParameters, | ||||||
| 					SymmetricEncryption = prefix == BinaryBlock.PublicKeyHashWithSymmetricKey | 					SymmetricEncryption = prefix == BinaryBlock.PublicKeySymmetric | ||||||
| 				}; | 				}; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			return result; | 			return result; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		private PublicKeyHashEncryption DetermineEncryptionForPublicKeyHashBlock(string prefix) |  | ||||||
| 		{ |  | ||||||
| 			var passwordEncryption = new PasswordEncryption(logger.CloneFor(nameof(PasswordEncryption))); |  | ||||||
| 
 |  | ||||||
| 			if (prefix == BinaryBlock.PublicKeyHash) |  | ||||||
| 			{ |  | ||||||
| 				return new PublicKeyHashEncryption(new CertificateStore(), logger.CloneFor(nameof(PublicKeyHashEncryption))); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			return new PublicKeyHashWithSymmetricKeyEncryption(new CertificateStore(), logger.CloneFor(nameof(PublicKeyHashWithSymmetricKeyEncryption)), passwordEncryption); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		private PasswordParameters DetermineEncryptionParametersFor(string prefix, PasswordParameters password) | 		private PasswordParameters DetermineEncryptionParametersFor(string prefix, PasswordParameters password) | ||||||
| 		{ | 		{ | ||||||
| 			var parameters = new PasswordParameters(); | 			var parameters = new PasswordParameters(); | ||||||
|  |  | ||||||
|  | @ -43,7 +43,7 @@ namespace SafeExamBrowser.Configuration.DataFormats | ||||||
| 				case PasswordParameters p: | 				case PasswordParameters p: | ||||||
| 					result = SerializePasswordBlock(data, p); | 					result = SerializePasswordBlock(data, p); | ||||||
| 					break; | 					break; | ||||||
| 				case PublicKeyHashParameters p: | 				case PublicKeyParameters p: | ||||||
| 					result = SerializePublicKeyHashBlock(data, p); | 					result = SerializePublicKeyHashBlock(data, p); | ||||||
| 					break; | 					break; | ||||||
| 				default: | 				default: | ||||||
|  | @ -103,14 +103,14 @@ namespace SafeExamBrowser.Configuration.DataFormats | ||||||
| 			return result; | 			return result; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		private SerializeResult SerializePublicKeyHashBlock(IDictionary<string, object> data, PublicKeyHashParameters parameters) | 		private SerializeResult SerializePublicKeyHashBlock(IDictionary<string, object> data, PublicKeyParameters parameters) | ||||||
| 		{ | 		{ | ||||||
| 			var result = SerializePublicKeyHashInnerBlock(data, parameters); | 			var result = SerializePublicKeyHashInnerBlock(data, parameters); | ||||||
| 
 | 
 | ||||||
| 			if (result.Status == SaveStatus.Success) | 			if (result.Status == SaveStatus.Success) | ||||||
| 			{ | 			{ | ||||||
| 				var encryption = DetermineEncryptionForPublicKeyHashBlock(parameters); | 				var encryption = DetermineEncryptionForPublicKeyHashBlock(parameters); | ||||||
| 				var prefix = parameters.SymmetricEncryption ? BinaryBlock.PublicKeyHashWithSymmetricKey : BinaryBlock.PublicKeyHash; | 				var prefix = parameters.SymmetricEncryption ? BinaryBlock.PublicKeySymmetric : BinaryBlock.PublicKey; | ||||||
| 
 | 
 | ||||||
| 				logger.Debug("Attempting to serialize public key hash block..."); | 				logger.Debug("Attempting to serialize public key hash block..."); | ||||||
| 
 | 
 | ||||||
|  | @ -125,7 +125,7 @@ namespace SafeExamBrowser.Configuration.DataFormats | ||||||
| 			return result; | 			return result; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		private SerializeResult SerializePublicKeyHashInnerBlock(IDictionary<string, object> data, PublicKeyHashParameters parameters) | 		private SerializeResult SerializePublicKeyHashInnerBlock(IDictionary<string, object> data, PublicKeyParameters parameters) | ||||||
| 		{ | 		{ | ||||||
| 			if (parameters.InnerEncryption is PasswordParameters password) | 			if (parameters.InnerEncryption is PasswordParameters password) | ||||||
| 			{ | 			{ | ||||||
|  | @ -135,16 +135,16 @@ namespace SafeExamBrowser.Configuration.DataFormats | ||||||
| 			return SerializePlainDataBlock(data, true); | 			return SerializePlainDataBlock(data, true); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		private PublicKeyHashEncryption DetermineEncryptionForPublicKeyHashBlock(PublicKeyHashParameters parameters) | 		private PublicKeyEncryption DetermineEncryptionForPublicKeyHashBlock(PublicKeyParameters parameters) | ||||||
| 		{ | 		{ | ||||||
| 			var passwordEncryption = new PasswordEncryption(logger.CloneFor(nameof(PasswordEncryption))); | 			var passwordEncryption = new PasswordEncryption(logger.CloneFor(nameof(PasswordEncryption))); | ||||||
| 
 | 
 | ||||||
| 			if (parameters.SymmetricEncryption) | 			if (parameters.SymmetricEncryption) | ||||||
| 			{ | 			{ | ||||||
| 				return new PublicKeyHashWithSymmetricKeyEncryption(new CertificateStore(), logger.CloneFor(nameof(PublicKeyHashWithSymmetricKeyEncryption)), passwordEncryption); | 				return new PublicKeySymmetricEncryption(new CertificateStore(), logger.CloneFor(nameof(PublicKeySymmetricEncryption)), passwordEncryption); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			return new PublicKeyHashEncryption(new CertificateStore(), logger.CloneFor(nameof(PublicKeyHashEncryption))); | 			return new PublicKeyEncryption(new CertificateStore(), logger.CloneFor(nameof(PublicKeyEncryption))); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		private Stream WritePrefix(string prefix, Stream data) | 		private Stream WritePrefix(string prefix, Stream data) | ||||||
|  |  | ||||||
|  | @ -64,8 +64,8 @@ | ||||||
|     <Compile Include="Cryptography\CertificateStore.cs" /> |     <Compile Include="Cryptography\CertificateStore.cs" /> | ||||||
|     <Compile Include="DataCompression\GZipCompressor.cs" /> |     <Compile Include="DataCompression\GZipCompressor.cs" /> | ||||||
|     <Compile Include="Cryptography\PasswordEncryption.cs" /> |     <Compile Include="Cryptography\PasswordEncryption.cs" /> | ||||||
|     <Compile Include="Cryptography\PublicKeyHashEncryption.cs" /> |     <Compile Include="Cryptography\PublicKeyEncryption.cs" /> | ||||||
|     <Compile Include="Cryptography\PublicKeyHashWithSymmetricKeyEncryption.cs" /> |     <Compile Include="Cryptography\PublicKeySymmetricEncryption.cs" /> | ||||||
|     <Compile Include="DataFormats\BinaryParser.cs" /> |     <Compile Include="DataFormats\BinaryParser.cs" /> | ||||||
|     <Compile Include="DataFormats\BinarySerializer.cs" /> |     <Compile Include="DataFormats\BinarySerializer.cs" /> | ||||||
|     <Compile Include="DataFormats\BinaryBlock.cs" /> |     <Compile Include="DataFormats\BinaryBlock.cs" /> | ||||||
|  |  | ||||||
|  | @ -0,0 +1,30 @@ | ||||||
|  | /* | ||||||
|  |  * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) | ||||||
|  |  *  | ||||||
|  |  * 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/. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | using System.IO; | ||||||
|  | 
 | ||||||
|  | namespace SafeExamBrowser.Contracts.Configuration.Cryptography | ||||||
|  | { | ||||||
|  | 	/// <summary> | ||||||
|  | 	/// Encrypts and decrypts data with a password. | ||||||
|  | 	/// </summary> | ||||||
|  | 	public interface IPasswordEncryption | ||||||
|  | 	{ | ||||||
|  | 		/// <summary> | ||||||
|  | 		/// Attempts to decrypt the given data. The decrypted data stream can only be considered valid if <see cref="LoadStatus.Success"/> | ||||||
|  | 		/// is returned! | ||||||
|  | 		/// </summary> | ||||||
|  | 		LoadStatus Decrypt(Stream data, string password, out Stream decrypted); | ||||||
|  | 
 | ||||||
|  | 		/// <summary> | ||||||
|  | 		/// Attempts to encrypt the given data. The encrypted data stream can only be considered valid if <see cref="SaveStatus.Success"/> | ||||||
|  | 		/// is returned. | ||||||
|  | 		/// </summary> | ||||||
|  | 		SaveStatus Encrypt(Stream data, string password, out Stream encrypted); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -0,0 +1,31 @@ | ||||||
|  | /* | ||||||
|  |  * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) | ||||||
|  |  *  | ||||||
|  |  * 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/. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | using System.IO; | ||||||
|  | using System.Security.Cryptography.X509Certificates; | ||||||
|  | 
 | ||||||
|  | namespace SafeExamBrowser.Contracts.Configuration.Cryptography | ||||||
|  | { | ||||||
|  | 	/// <summary> | ||||||
|  | 	/// Encrypts and decrypts data with a certificate. | ||||||
|  | 	/// </summary> | ||||||
|  | 	public interface IPublicKeyEncryption | ||||||
|  | 	{ | ||||||
|  | 		/// <summary> | ||||||
|  | 		/// Attempts to decrypt the given data. The decrypted data stream and the certificate can only be considered valid if | ||||||
|  | 		/// <see cref="LoadStatus.Success"/> is returned! | ||||||
|  | 		/// </summary> | ||||||
|  | 		LoadStatus Decrypt(Stream data, out Stream decrypted, out X509Certificate2 certificate); | ||||||
|  | 
 | ||||||
|  | 		/// <summary> | ||||||
|  | 		/// Attempts to encrypt the given data. The encrypted data stream can only be considered valid if <see cref="SaveStatus.Success"/> | ||||||
|  | 		/// is returned. | ||||||
|  | 		/// </summary> | ||||||
|  | 		SaveStatus Encrypt(Stream data, X509Certificate2 certificate, out Stream encrypted); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -13,7 +13,7 @@ namespace SafeExamBrowser.Contracts.Configuration.Cryptography | ||||||
| 	/// <summary> | 	/// <summary> | ||||||
| 	/// Holds all parameters for data encryption by certificate. | 	/// Holds all parameters for data encryption by certificate. | ||||||
| 	/// </summary> | 	/// </summary> | ||||||
| 	public class PublicKeyHashParameters : EncryptionParameters | 	public class PublicKeyParameters : EncryptionParameters | ||||||
| 	{ | 	{ | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// The certificate holding the public key used for encryption. | 		/// The certificate holding the public key used for encryption. | ||||||
|  | @ -59,8 +59,10 @@ | ||||||
|     <Compile Include="Communication\Events\MessageBoxRequestEventArgs.cs" /> |     <Compile Include="Communication\Events\MessageBoxRequestEventArgs.cs" /> | ||||||
|     <Compile Include="Configuration\Cryptography\EncryptionParameters.cs" /> |     <Compile Include="Configuration\Cryptography\EncryptionParameters.cs" /> | ||||||
|     <Compile Include="Configuration\Cryptography\ICertificateStore.cs" /> |     <Compile Include="Configuration\Cryptography\ICertificateStore.cs" /> | ||||||
|  |     <Compile Include="Configuration\Cryptography\IPasswordEncryption.cs" /> | ||||||
|  |     <Compile Include="Configuration\Cryptography\IPublicKeyEncryption.cs" /> | ||||||
|     <Compile Include="Configuration\Cryptography\PasswordParameters.cs" /> |     <Compile Include="Configuration\Cryptography\PasswordParameters.cs" /> | ||||||
|     <Compile Include="Configuration\Cryptography\PublicKeyHashParameters.cs" /> |     <Compile Include="Configuration\Cryptography\PublicKeyParameters.cs" /> | ||||||
|     <Compile Include="Configuration\DataFormats\FormatType.cs" /> |     <Compile Include="Configuration\DataFormats\FormatType.cs" /> | ||||||
|     <Compile Include="Configuration\DataCompression\IDataCompressor.cs" /> |     <Compile Include="Configuration\DataCompression\IDataCompressor.cs" /> | ||||||
|     <Compile Include="Configuration\Cryptography\IHashAlgorithm.cs" /> |     <Compile Include="Configuration\Cryptography\IHashAlgorithm.cs" /> | ||||||
|  |  | ||||||
|  | @ -62,12 +62,12 @@ namespace SafeExamBrowser.Runtime | ||||||
| 			InitializeText(); | 			InitializeText(); | ||||||
| 
 | 
 | ||||||
| 			var messageBox = new MessageBox(text); | 			var messageBox = new MessageBox(text); | ||||||
| 			var desktopFactory = new DesktopFactory(new ModuleLogger(logger, nameof(DesktopFactory))); | 			var desktopFactory = new DesktopFactory(ModuleLogger(nameof(DesktopFactory))); | ||||||
| 			var explorerShell = new ExplorerShell(new ModuleLogger(logger, nameof(ExplorerShell)), nativeMethods); | 			var explorerShell = new ExplorerShell(ModuleLogger(nameof(ExplorerShell)), nativeMethods); | ||||||
| 			var processFactory = new ProcessFactory(new ModuleLogger(logger, nameof(ProcessFactory))); | 			var processFactory = new ProcessFactory(ModuleLogger(nameof(ProcessFactory))); | ||||||
| 			var proxyFactory = new ProxyFactory(new ProxyObjectFactory(), logger); | 			var proxyFactory = new ProxyFactory(new ProxyObjectFactory(), logger); | ||||||
| 			var runtimeHost = new RuntimeHost(appConfig.RuntimeAddress, new HostObjectFactory(), new ModuleLogger(logger, nameof(RuntimeHost)), FIVE_SECONDS); | 			var runtimeHost = new RuntimeHost(appConfig.RuntimeAddress, new HostObjectFactory(), ModuleLogger(nameof(RuntimeHost)), FIVE_SECONDS); | ||||||
| 			var serviceProxy = new ServiceProxy(appConfig.ServiceAddress, new ProxyObjectFactory(), new ModuleLogger(logger, nameof(ServiceProxy))); | 			var serviceProxy = new ServiceProxy(appConfig.ServiceAddress, new ProxyObjectFactory(), ModuleLogger(nameof(ServiceProxy))); | ||||||
| 			var sessionContext = new SessionContext(); | 			var sessionContext = new SessionContext(); | ||||||
| 			var uiFactory = new UserInterfaceFactory(text); | 			var uiFactory = new UserInterfaceFactory(text); | ||||||
| 
 | 
 | ||||||
|  | @ -116,18 +116,23 @@ namespace SafeExamBrowser.Runtime | ||||||
| 			var programCopyright = executable.GetCustomAttribute<AssemblyCopyrightAttribute>().Copyright; | 			var programCopyright = executable.GetCustomAttribute<AssemblyCopyrightAttribute>().Copyright; | ||||||
| 			var programTitle = executable.GetCustomAttribute<AssemblyTitleAttribute>().Title; | 			var programTitle = executable.GetCustomAttribute<AssemblyTitleAttribute>().Title; | ||||||
| 			var programVersion = executable.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion; | 			var programVersion = executable.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion; | ||||||
| 			var compressor = new GZipCompressor(new ModuleLogger(logger, nameof(GZipCompressor))); | 			var compressor = new GZipCompressor(ModuleLogger(nameof(GZipCompressor))); | ||||||
| 			var repositoryLogger = new ModuleLogger(logger, nameof(ConfigurationRepository)); | 			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 repositoryLogger = ModuleLogger(nameof(ConfigurationRepository)); | ||||||
|  | 			var xmlParser = new XmlParser(ModuleLogger(nameof(XmlParser))); | ||||||
| 
 | 
 | ||||||
| 			configuration = new ConfigurationRepository(new HashAlgorithm(), repositoryLogger, executable.Location, programCopyright, programTitle, programVersion); | 			configuration = new ConfigurationRepository(new HashAlgorithm(), repositoryLogger, executable.Location, programCopyright, programTitle, programVersion); | ||||||
| 			appConfig = configuration.InitializeAppConfig(); | 			appConfig = configuration.InitializeAppConfig(); | ||||||
| 
 | 
 | ||||||
| 			configuration.Register(new BinaryParser(compressor, new HashAlgorithm(), new ModuleLogger(logger, nameof(BinaryParser)))); | 			configuration.Register(new BinaryParser(compressor, new HashAlgorithm(), ModuleLogger(nameof(BinaryParser)), passwordEncryption, publicKeyEncryption, symmetricEncryption, xmlParser)); | ||||||
| 			configuration.Register(new BinarySerializer(compressor, new ModuleLogger(logger, nameof(BinarySerializer)))); | 			configuration.Register(new BinarySerializer(compressor, ModuleLogger(nameof(BinarySerializer)))); | ||||||
| 			configuration.Register(new XmlParser(new ModuleLogger(logger, nameof(XmlParser)))); | 			configuration.Register(new XmlParser(ModuleLogger(nameof(XmlParser)))); | ||||||
| 			configuration.Register(new XmlSerializer(new ModuleLogger(logger, nameof(XmlSerializer)))); | 			configuration.Register(new XmlSerializer(ModuleLogger(nameof(XmlSerializer)))); | ||||||
| 			configuration.Register(new FileResourceLoader(new ModuleLogger(logger, nameof(FileResourceLoader)))); | 			configuration.Register(new FileResourceLoader(ModuleLogger(nameof(FileResourceLoader)))); | ||||||
| 			configuration.Register(new FileResourceSaver(new ModuleLogger(logger, nameof(FileResourceSaver)))); | 			configuration.Register(new FileResourceSaver(ModuleLogger(nameof(FileResourceSaver)))); | ||||||
| 			configuration.Register(new NetworkResourceLoader(appConfig, new ModuleLogger(logger, nameof(NetworkResourceLoader)))); | 			configuration.Register(new NetworkResourceLoader(appConfig, new ModuleLogger(logger, nameof(NetworkResourceLoader)))); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -148,5 +153,10 @@ namespace SafeExamBrowser.Runtime | ||||||
| 			text = new Text(logger); | 			text = new Text(logger); | ||||||
| 			textResource = new XmlTextResource(path); | 			textResource = new XmlTextResource(path); | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
|  | 		private IModuleLogger ModuleLogger(string moduleInfo) | ||||||
|  | 		{ | ||||||
|  | 			return new ModuleLogger(logger, moduleInfo); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 dbuechel
						dbuechel