From 5ce5c78641c9b94fc32010e2dc5b46c6cfce2658 Mon Sep 17 00:00:00 2001 From: dbuechel Date: Mon, 10 Feb 2020 12:19:25 +0100 Subject: [PATCH] SEBWIN-309: Implemented draft of browser exam key. --- .../Handlers/ResourceHandler.cs | 12 ++++--- .../AppConfig.cs | 5 +++ .../ConfigurationRepositoryTests.cs | 4 +-- .../ConfigurationData/DataValues.cs | 32 +++++++------------ .../ConfigurationRepository.cs | 12 ++----- SafeExamBrowser.Runtime/CompositionRoot.cs | 17 +--------- 6 files changed, 28 insertions(+), 54 deletions(-) diff --git a/SafeExamBrowser.Browser/Handlers/ResourceHandler.cs b/SafeExamBrowser.Browser/Handlers/ResourceHandler.cs index bafa5a09..368608b1 100644 --- a/SafeExamBrowser.Browser/Handlers/ResourceHandler.cs +++ b/SafeExamBrowser.Browser/Handlers/ResourceHandler.cs @@ -106,12 +106,16 @@ namespace SafeExamBrowser.Browser.Handlers { var headers = new NameValueCollection(request.Headers); var urlWithoutFragment = request.Url.Split('#')[0]; - var hash = algorithm.ComputeHash(Encoding.UTF8.GetBytes(urlWithoutFragment + settings.HashValue)); - var configurationKey = BitConverter.ToString(hash).ToLower().Replace("-", string.Empty); + var configurationBytes = algorithm.ComputeHash(Encoding.UTF8.GetBytes(urlWithoutFragment + settings.HashValue)); + var configurationKey = BitConverter.ToString(configurationBytes).ToLower().Replace("-", string.Empty); + var browserExamBytes = algorithm.ComputeHash(Encoding.UTF8.GetBytes(appConfig.CodeSignatureHash + appConfig.ProgramBuildVersion + configurationKey)); + var browserExamKey = BitConverter.ToString(browserExamBytes).ToLower().Replace("-", string.Empty); + var requestHashBytes = algorithm.ComputeHash(Encoding.UTF8.GetBytes(urlWithoutFragment + browserExamKey)); + var requestHashKey = BitConverter.ToString(requestHashBytes).ToLower().Replace("-", string.Empty); - // TODO: Implement Browser Exam Key calculation. - // headers["X-SafeExamBrowser-RequestHash"] = ...; headers["X-SafeExamBrowser-ConfigKeyHash"] = configurationKey; + headers["X-SafeExamBrowser-RequestHash"] = requestHashKey; + request.Headers = headers; } diff --git a/SafeExamBrowser.Configuration.Contracts/AppConfig.cs b/SafeExamBrowser.Configuration.Contracts/AppConfig.cs index 322527f8..f7d68a57 100644 --- a/SafeExamBrowser.Configuration.Contracts/AppConfig.cs +++ b/SafeExamBrowser.Configuration.Contracts/AppConfig.cs @@ -86,6 +86,11 @@ namespace SafeExamBrowser.Configuration.Contracts /// public string ClientLogFilePath { get; set; } + /// + /// The hash value of the certificate used to sign the application binaries, or null if the binaries are unsigned. + /// + public string CodeSignatureHash { get; set; } + /// /// The file extension of configuration files for the application (including the period). /// diff --git a/SafeExamBrowser.Configuration.UnitTests/ConfigurationRepositoryTests.cs b/SafeExamBrowser.Configuration.UnitTests/ConfigurationRepositoryTests.cs index 4fe3e5c1..96283c33 100644 --- a/SafeExamBrowser.Configuration.UnitTests/ConfigurationRepositoryTests.cs +++ b/SafeExamBrowser.Configuration.UnitTests/ConfigurationRepositoryTests.cs @@ -39,8 +39,6 @@ namespace SafeExamBrowser.Configuration.UnitTests [TestInitialize] public void Initialize() { - var executablePath = Assembly.GetExecutingAssembly().Location; - binaryParser = new Mock(); binarySerializer = new Mock(); certificateStore = new Mock(); @@ -56,7 +54,7 @@ namespace SafeExamBrowser.Configuration.UnitTests fileSaver.Setup(f => f.CanSave(It.IsAny())).Returns(u => u.IsFile); networkLoader.Setup(n => n.CanLoad(It.IsAny())).Returns(u => u.Scheme.Equals("http") || u.Scheme.Equals("seb")); - sut = new ConfigurationRepository(certificateStore.Object, hashAlgorithm.Object, logger.Object, executablePath, string.Empty, string.Empty, string.Empty, string.Empty); + sut = new ConfigurationRepository(certificateStore.Object, hashAlgorithm.Object, logger.Object); sut.InitializeAppConfig(); } diff --git a/SafeExamBrowser.Configuration/ConfigurationData/DataValues.cs b/SafeExamBrowser.Configuration/ConfigurationData/DataValues.cs index 07a3227d..6d878422 100644 --- a/SafeExamBrowser.Configuration/ConfigurationData/DataValues.cs +++ b/SafeExamBrowser.Configuration/ConfigurationData/DataValues.cs @@ -7,7 +7,10 @@ */ using System; +using System.Diagnostics; using System.IO; +using System.Linq; +using System.Reflection; using SafeExamBrowser.Configuration.Contracts; using SafeExamBrowser.Settings; using SafeExamBrowser.Settings.Browser; @@ -22,27 +25,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData internal class DataValues { private const string DEFAULT_CONFIGURATION_NAME = "SebClientSettings.seb"; - private AppConfig appConfig; - private string executablePath; - private string programBuild; - private string programCopyright; - private string programTitle; - private string programVersion; - - internal DataValues( - string executablePath, - string programBuild, - string programCopyright, - string programTitle, - string programVersion) - { - this.executablePath = executablePath ?? string.Empty; - this.programBuild = programBuild ?? string.Empty; - this.programCopyright = programCopyright ?? string.Empty; - this.programTitle = programTitle ?? string.Empty; - this.programVersion = programVersion ?? string.Empty; - } internal string GetAppDataFilePath() { @@ -51,6 +34,12 @@ namespace SafeExamBrowser.Configuration.ConfigurationData internal AppConfig InitializeAppConfig() { + var executable = Assembly.GetExecutingAssembly(); + var certificate = executable.Modules.First().GetSignerCertificate(); + var programBuild = FileVersionInfo.GetVersionInfo(executable.Location).FileVersion; + var programCopyright = executable.GetCustomAttribute().Copyright; + var programTitle = executable.GetCustomAttribute().Title; + var programVersion = executable.GetCustomAttribute().InformationalVersion; var appDataLocalFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), nameof(SafeExamBrowser)); var appDataRoamingFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), nameof(SafeExamBrowser)); var programDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), nameof(SafeExamBrowser)); @@ -65,8 +54,9 @@ namespace SafeExamBrowser.Configuration.ConfigurationData appConfig.BrowserLogFilePath = Path.Combine(logFolder, $"{logFilePrefix}_Browser.log"); appConfig.ClientId = Guid.NewGuid(); appConfig.ClientAddress = $"{AppConfig.BASE_ADDRESS}/client/{Guid.NewGuid()}"; - appConfig.ClientExecutablePath = Path.Combine(Path.GetDirectoryName(executablePath), $"{nameof(SafeExamBrowser)}.Client.exe"); + appConfig.ClientExecutablePath = Path.Combine(Path.GetDirectoryName(executable.Location), $"{nameof(SafeExamBrowser)}.Client.exe"); appConfig.ClientLogFilePath = Path.Combine(logFolder, $"{logFilePrefix}_Client.log"); + appConfig.CodeSignatureHash = certificate?.GetCertHashString(); appConfig.ConfigurationFileExtension = ".seb"; appConfig.ConfigurationFileMimeType = "application/seb"; appConfig.ProgramBuildVersion = programBuild; diff --git a/SafeExamBrowser.Configuration/ConfigurationRepository.cs b/SafeExamBrowser.Configuration/ConfigurationRepository.cs index 7a6e31a6..f12f7659 100644 --- a/SafeExamBrowser.Configuration/ConfigurationRepository.cs +++ b/SafeExamBrowser.Configuration/ConfigurationRepository.cs @@ -33,15 +33,7 @@ namespace SafeExamBrowser.Configuration private IList resourceLoaders; private IList resourceSavers; - public ConfigurationRepository( - ICertificateStore certificateStore, - IHashAlgorithm hashAlgorithm, - IModuleLogger logger, - string executablePath, - string programBuild, - string programCopyright, - string programTitle, - string programVersion) + public ConfigurationRepository(ICertificateStore certificateStore, IHashAlgorithm hashAlgorithm, IModuleLogger logger) { this.certificateStore = certificateStore; this.hashAlgorithm = hashAlgorithm; @@ -51,7 +43,7 @@ namespace SafeExamBrowser.Configuration dataSerializers = new List(); dataMapper = new DataMapper(); dataProcessor = new DataProcessor(); - dataValues = new DataValues(executablePath, programBuild, programCopyright, programTitle, programVersion); + dataValues = new DataValues(); resourceLoaders = new List(); resourceSavers = new List(); } diff --git a/SafeExamBrowser.Runtime/CompositionRoot.cs b/SafeExamBrowser.Runtime/CompositionRoot.cs index aa432ca4..7a1be963 100644 --- a/SafeExamBrowser.Runtime/CompositionRoot.cs +++ b/SafeExamBrowser.Runtime/CompositionRoot.cs @@ -8,7 +8,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Reflection; using SafeExamBrowser.Communication.Contracts; @@ -129,12 +128,6 @@ namespace SafeExamBrowser.Runtime private void InitializeConfiguration() { - var executable = Assembly.GetExecutingAssembly(); - var programBuild = FileVersionInfo.GetVersionInfo(executable.Location).FileVersion; - var programCopyright = executable.GetCustomAttribute().Copyright; - var programTitle = executable.GetCustomAttribute().Title; - var programVersion = executable.GetCustomAttribute().InformationalVersion; - var certificateStore = new CertificateStore(ModuleLogger(nameof(CertificateStore))); var compressor = new GZipCompressor(ModuleLogger(nameof(GZipCompressor))); var passwordEncryption = new PasswordEncryption(ModuleLogger(nameof(PasswordEncryption))); @@ -144,15 +137,7 @@ namespace SafeExamBrowser.Runtime var xmlParser = new XmlParser(compressor, ModuleLogger(nameof(XmlParser))); var xmlSerializer = new XmlSerializer(ModuleLogger(nameof(XmlSerializer))); - configuration = new ConfigurationRepository( - certificateStore, - new HashAlgorithm(), - repositoryLogger, - executable.Location, - programBuild, - programCopyright, - programTitle, - programVersion); + configuration = new ConfigurationRepository(certificateStore, new HashAlgorithm(), repositoryLogger); appConfig = configuration.InitializeAppConfig(); configuration.Register(new BinaryParser(