diff --git a/E2ETest/RejectSubmissionTest.cs b/E2ETest/RejectSubmissionTest.cs index 393084aae66ca071b098a01bb32d1e3fb3ce50f8..69ea1e2d8f7dd82cb221787df1b56db8731b791f 100644 --- a/E2ETest/RejectSubmissionTest.cs +++ b/E2ETest/RejectSubmissionTest.cs @@ -12,6 +12,7 @@ public class RejectSubmissionTest : EndToEndTestBase { [Order(10)] [Test] public void SendingSubmission() { + // TODO - weaker test for signature validation certificates var submission = Sender.WithDestination(Settings.DestinationId) .WithServiceType("Straight forward test", Settings.LeikaKey) .WithAttachments(new Attachment("Test.pdf", "A simple PDF")) diff --git a/FitConnect/Encryption/CertificateHelper.cs b/FitConnect/Encryption/CertificateHelper.cs index 146b67922c64b897f5285c5b68b4033f50524cea..e49343b4079b7a493445fb343724aa53b1d8eb92 100644 --- a/FitConnect/Encryption/CertificateHelper.cs +++ b/FitConnect/Encryption/CertificateHelper.cs @@ -29,24 +29,25 @@ public class CertificateHelper { // https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.x509chain.build?view=net-5.0 var certificateChain = new X509Chain(); - certificateChain.ChainPolicy.ExtraStore.AddRange(extras ?? Array.Empty<X509Certificate2>()); + if (extras != null) + certificateChain.ChainPolicy.ExtraStore.AddRange(extras); _logger?.LogDebug("Issuers: {Issuer}", certificate.Issuer); + certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.Online; + certificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; + if (rootCertificate != null) { certificateChain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; certificateChain.ChainPolicy.CustomTrustStore.AddRange(rootCertificate); - certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.Online; - certificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; certificateChain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag; _logger?.LogDebug("Using custom root certificate"); } else { - certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.Online; - certificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; certificateChain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag; + //X509VerificationFlags.AllowUnknownCertificateAuthority; } - + var result = certificateChain.Build(certificate); chainStatus = certificateChain.ChainStatus @@ -56,7 +57,8 @@ public class CertificateHelper { (r, s) => r + "\n\t - " + s.Status + ": " + s.StatusInformation); if (certificateChain.ChainStatus.Length > 0) - _logger?.Log(logLevel, "Certificate status: {ObjStatusInformation}", + _logger?.Log(result ? LogLevel.Information : logLevel, + "Certificate status: {ObjStatusInformation}", statusAggregation); return result; @@ -72,7 +74,7 @@ public class CertificateHelper { _logger?.Log(logLevel, "Certificate does not match FIT-Connect requirements"); return false; } - + var valid = ValidateCertificate(certificates.First(), out _, root, certificates.ToArray(), logLevel); return valid && fitConnectRequirements; @@ -94,7 +96,7 @@ public static class CertificateExtensions { public static bool MatchesFitConnectRequirements(this JsonWebKey key) { return key.X5c.Count == 3 - && key.KeySize == 4096 - && (key.KeyOps.Contains("wrapKey")); + && key.KeySize == 4096 + && (key.KeyOps.Contains("wrapKey")); } } diff --git a/IntegrationTests/CertificateValidation.cs b/IntegrationTests/CertificateValidation.cs index e92ba81b1d998e1b12b894ebcda9119af8ef07d0..6a24b057720eba67e86b69fe8ced86098c8e9981 100644 --- a/IntegrationTests/CertificateValidation.cs +++ b/IntegrationTests/CertificateValidation.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; +using System.Net.Http; +using System.Net.Http.Json; using System.Security; using System.Security.Cryptography.X509Certificates; using Autofac; @@ -14,6 +16,7 @@ using Microsoft.Extensions.Logging; using Microsoft.IdentityModel.Tokens; using MockContainer; using Moq; +using Newtonsoft.Json; using NUnit.Framework; namespace IntegrationTests; @@ -114,18 +117,28 @@ public class CertificateValidation { [Test] + [Ignore("Certificate from server is invalid, x5c are mixed")] public void TestDvdvCertificate() { - var content = File.ReadAllText("./certificates/valid_dvdv.json"); + var destinationJson = new HttpClient() + .GetStringAsync( + "https://dvdv-microservice-fit-connect.governikus-asp.de/dvdv-fitconnect/v1/destinations/f05bdafc-3ee7-418f-ab30-3c9fe6e1c7d6") + .Result; + + var destination = (dynamic)JsonConvert.DeserializeObject(destinationJson); + var content = JsonConvert.SerializeObject(destination.publicKeys.keys[0]); var jwk = new JsonWebKey(content); - var result = _certificateHelper.ValidateCertificate(jwk, LogLevel.Error, Directory - .GetFiles("./certificates/roots") - .Select(file => new X509Certificate2(file)).ToArray()); + var result = _certificateHelper.ValidateCertificate(jwk); result.Should().BeTrue(); } [Test] public void CheckPemFiles() { - var files = System.IO.Directory.GetFiles("./certificates"); + if (!Directory.Exists("./certificates") || !Directory.Exists("./certificates/roots")) { + Assert.Inconclusive("No certificates found"); + return; + } + + var files = Directory.GetFiles("./certificates"); var success = 0; var failed = 0; var failedCerts = new List<string>();