using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Security; using System.Security.Cryptography.X509Certificates; using Autofac; using FitConnect; using FitConnect.Encryption; using FitConnect.Models; using FluentAssertions; using Microsoft.Extensions.Logging; using Microsoft.IdentityModel.Tokens; using MockContainer; using Moq; using NUnit.Framework; namespace IntegrationTests; [TestFixture] public class CertificateValidation { private MockSettings _settings = null!; private ILogger _logger = null!; private CertificateHelper _certificateHelper = null!; [SetUp] public void Setup() { var container = Container.Create(); _settings = container.Resolve<MockSettings>(); _logger = LoggerFactory.Create( builder => { builder.AddConsole(); builder.SetMinimumLevel(LogLevel.Debug); }).CreateLogger("E2E Test"); _certificateHelper = new CertificateHelper(_logger); } [Test] [Ignore("No credentials for dev environment")] public void CheckCertificateInEnvironment_Dev() { var environment = FitConnectEnvironment.Develop; var sender = Client.GetSender(environment, _settings.SenderClientId, _settings.SenderClientSecret, _logger); var certificate = (sender as FitConnect.Sender)! .GetPublicKeyFromDestination(_settings.DestinationId).Result; new CertificateHelper(_logger).ValidateCertificate(JsonWebKey.Create(certificate), LogLevel.Trace); } [Test] public void CheckCertificateInEnvironment_Testing() { var environment = FitConnectEnvironment.Testing; var sender = Client.GetSender(environment, _settings.SenderClientId, _settings.SenderClientSecret, _logger); var certificate = (sender as FitConnect.Sender)! .GetPublicKeyFromDestination(_settings.DestinationId).Result; new CertificateHelper(_logger).ValidateCertificate(JsonWebKey.Create(certificate), LogLevel.Trace); } [Test] [Ignore("No credentials for staging environment")] public void CheckCertificateInEnvironment_Staging() { var environment = FitConnectEnvironment.Staging; var sender = Client.GetSender(environment, _settings.SenderClientId, _settings.SenderClientSecret, _logger); Assert.Throws<AggregateException>(() => { sender.WithDestination(_settings.DestinationId) .WithServiceType("", _settings.LeikaKey) .WithAttachments(new Attachment("Test.pdf", "Simple Test PDF")) .Submit(); })!.InnerExceptions.Any(e => e.GetType() == typeof(SecurityException)).Should().BeTrue(); } [Test] [Ignore("No credentials for production environment")] public void CheckCertificateInEnvironment_Production() { var environment = FitConnectEnvironment.Production; var sender = Client.GetSender(environment, _settings.SenderClientId, _settings.SenderClientSecret, _logger); Assert.Throws<AggregateException>(() => { sender.WithDestination(_settings.DestinationId) .WithServiceType("", _settings.LeikaKey) .WithAttachments(new Attachment("Test.pdf", "Simple Test PDF")) .Submit(); })!.InnerExceptions.Any(e => e.GetType() == typeof(SecurityException)).Should().BeTrue(); } [Test] public void CheckPublicKeyEncryption() { _certificateHelper.ValidateCertificate(new JsonWebKey(_settings.PublicKeyEncryption)) .Should().BeFalse(); } [Test] public void CheckPublicKeySignature() { _certificateHelper .ValidateCertificate(new JsonWebKey(_settings.PublicKeySignatureVerification)) .Should().BeFalse(); } [Test] public void CheckPrivateKeyDecryption() { _certificateHelper.ValidateCertificate(new JsonWebKey(_settings.PrivateKeyDecryption)) .Should().BeTrue(); } [Test] public void CheckSetPublicKey() { _certificateHelper.ValidateCertificate(new JsonWebKey(_settings.SetPublicKeys)) .Should().BeTrue(); } [Test] public void CheckPrivateKeySigning() { _certificateHelper.ValidateCertificate(new JsonWebKey(_settings.PrivateKeySigning)) .Should().BeTrue(); } [Ignore("Not the scope of this branch - reactivate later")] [Test] public void CheckPemFiles() { var files = Directory.GetFiles("./certificates"); var success = 0; var failed = 0; var failedCerts = new List<string>(); foreach (var fileName in files) { _logger.LogInformation("Checking file: {FileName}", fileName); var certificateContents = Directory.GetFiles("./certificates/roots"); var rootCertificates = certificateContents .Select(file => new X509Certificate2(file)).ToArray(); certificateContents.Length.Should().Be(rootCertificates.Length); if (fileName.EndsWith(".json")) { var shouldFail = !fileName.Contains("/valid"); var jwk = new JsonWebKey(File.ReadAllText(fileName)); var valid = _certificateHelper.ValidateCertificate(jwk, shouldFail ? LogLevel.Warning : LogLevel.Critical, rootCertificates ); if (shouldFail) valid = !valid; if (valid) { success++; } else { failed++; failedCerts.Add(fileName); } } else { var certificate = new X509Certificate2(fileName); var valid = _certificateHelper.ValidateCertificate(certificate, out var states, null); if (valid) { success++; } else { failed++; failedCerts.Add(fileName); } } } _logger.LogWarning("Failed certificates: {Certs}", failedCerts.Aggregate("\n", (a, b) => a + "\t - " + b + "\n")); _logger.LogInformation("Success: {Success}, Failed: {Failed}", success, failed); failed.Should().Be(0); } }