Skip to content
Snippets Groups Projects
Commit f92af338 authored by Klaus Fischer's avatar Klaus Fischer
Browse files

Working

parent b0d3fdb1
No related branches found
No related tags found
1 merge request!9.NET-SDK: SET-Empfang inkl. Signaturprüfung - Ticket 562
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.Unicode;
......@@ -29,19 +30,16 @@ public class CertificateHelper {
_logger?.LogDebug("Issuers: {Issuer}", certificate.Issuer);
if (rootCertificate != null) {
certificateChain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
certificateChain.ChainPolicy.CustomTrustStore.AddRange(rootCertificate);
certificateChain.ChainPolicy.ExtraStore.AddRange(rootCertificate);
certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
certificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
certificateChain.ChainPolicy.DisableCertificateDownloads = false;
certificateChain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.Offline;
certificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.EndCertificateOnly;
_logger?.LogDebug("Using custom root certificate");
}
else {
certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
certificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
certificateChain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
certificateChain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 30);
}
......@@ -53,9 +51,11 @@ public class CertificateHelper {
var statusAggregation = certificateChain.ChainStatus.Aggregate("",
(r, s) => r + "\n\t - " + s.Status + ": " + s.StatusInformation);
if (certificateChain.ChainStatus.Length > 0)
if (certificateChain.ChainStatus.Length > 0) {
_logger?.Log(logLevel, "Certificate status: {ObjStatusInformation}",
statusAggregation);
// _logger?.Log(logLevel, "Chain status: {ChainStatus}", certificateChain.ToDisplayString());
}
return result;
}
......@@ -93,4 +93,58 @@ public static class X509Certificate2Extensions {
File.WriteAllText(fileName + ".pem", content);
File.WriteAllText(fileName + ".json", JsonConvert.SerializeObject(certificate));
}
public static string ToDisplayString(this X509Chain chain) {
var b = new StringBuilder();
b.AppendLine($"[{nameof(chain.ChainPolicy.RevocationFlag)}]");
b.AppendLine($" {chain.ChainPolicy.RevocationFlag}");
b.AppendLine();
b.AppendLine($"[{nameof(chain.ChainPolicy.RevocationMode)}]");
b.AppendLine($" {chain.ChainPolicy.RevocationMode}");
b.AppendLine();
b.AppendLine($"[{nameof(chain.ChainPolicy.VerificationFlags)}]");
b.AppendLine($" {chain.ChainPolicy.VerificationFlags}");
b.AppendLine();
b.AppendLine($"[{nameof(chain.ChainPolicy.VerificationTime)}]");
b.AppendLine($" {chain.ChainPolicy.VerificationTime}");
b.AppendLine();
b.AppendLine($"[Application Policy]");
foreach (var policy in chain.ChainPolicy.ApplicationPolicy) {
b.AppendLine($" {policy.ToDisplayString()}");
}
b.AppendLine();
b.AppendLine($"[Certificate Policy]");
foreach (var policy in chain.ChainPolicy.CertificatePolicy) {
b.AppendLine($" {policy.ToDisplayString()}");
}
b.AppendLine();
b.AppendLine($"[Elements]");
foreach (var (element, index) in chain.ChainElements.Cast<X509ChainElement>()
.Select((element, index) => (element, index))) {
b.AppendLine();
b.AppendLine($"[Element {index + 1}]");
b.AppendLine();
b.Append(element.Certificate.ToString());
b.AppendLine();
b.AppendLine($"[Status]");
foreach (var status in element.ChainElementStatus) {
b.AppendLine($" {status.ToDisplayString()}");
}
}
return b.ToString();
}
public static string ToDisplayString(this Oid oid) {
return oid.FriendlyName == oid.Value
? $"{oid.Value}"
: $"{oid.FriendlyName}: {oid.Value}";
}
public static string ToDisplayString(this X509ChainStatus status) {
return $"{status.Status}: {status.StatusInformation}";
}
}
......@@ -106,14 +106,6 @@ public abstract class FitConnectClient {
var events = SubmissionService.GetStatusForSubmissionAsync(caseId, destinationId, skipTest)
.Result?.Select(e => new SecurityEventToken(e!)).ToList() ??
new List<SecurityEventToken>();
// Check OCSP Signature of SET Event
#warning Sender has no way to verify the OCSP signature
if (_publicKeySignatureVerification != null) {
var setsSignatureValid = events.Aggregate(true,
(run, e) => run &= FitEncryption.VerifyJwt(e.TokenString,
new JsonWebKey(_publicKeySignatureVerification), Logger));
}
return events;
}
......
......@@ -254,8 +254,21 @@ internal class SubmissionService : RestCallService, ISubmissionService {
: keySet.Keys.Append(_signatureValidationKey)).ToList();
return (await GetKeyIdsFromEvent(events, destinationId, keys.Select(k => k.Kid).ToList()))
.Union(keys);
var result =
(await GetKeyIdsFromEvent(events, destinationId, keys.Select(k => k.Kid).ToList()))
.Union(keys).ToList();
var valid = result.Aggregate(true,
(a, key) => (new CertificateHelper(_logger).ValidateCertificate(key)));
if (!valid) {
_logger?.LogError("(SET Events verification) Invalid certificate");
throw new ArgumentException("(SET Events verification) Invalid certificate");
}
else {
_logger?.LogInformation("(SET Events verification) Certificate is valid");
}
return result;
}
private async Task<IEnumerable<JsonWebKey>> GetKeyIdsFromEvent(EventLogDto events,
......
......@@ -130,37 +130,29 @@ public class CertificateValidation {
.Should().BeTrue();
}
[Ignore("Not the scope of this branch - reactivate later")]
[Test]
public void CheckPemFiles() {
var files = System.IO.Directory.GetFiles("./certificates");
var files = Directory.GetFiles("./certificates");
var success = 0;
var failed = 0;
var failedCerts = new List<string>();
foreach (var fileName in files.Where(f => !f.EndsWith("root.pem"))) {
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(".pem")) {
var certificate = X509Certificate2.CreateFromPem(File.ReadAllText(fileName));
var valid = _certificateHelper.ValidateCertificate(certificate, out var states,
null);
if (valid) {
success++;
}
else {
failed++;
failedCerts.Add(fileName);
}
}
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,
Directory.GetFiles("./certificates/roots")
.Select(file => new X509Certificate2(file)).ToArray());
shouldFail ? LogLevel.Warning : LogLevel.Critical, rootCertificates
);
if (shouldFail)
valid = !valid;
......@@ -173,6 +165,18 @@ public class CertificateValidation {
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}",
......
......@@ -144,6 +144,42 @@
<None Update="certificates\valid_productionKey.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="certificates\roots\ca.1212.der">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="certificates\roots\ca.1230.der">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="certificates\roots\ca.1249.der">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="certificates\roots\ca.1269.der">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="certificates\roots\ca.1286.der">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="certificates\roots\ca.1305.der">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="certificates\roots\ca.1322.der">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="certificates\roots\ca.1340.der">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="certificates\roots\ca.1357.der">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="certificates\validEncJWK_KeyUse.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="certificates\ValidEncJWK.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="certificates\validSigJWK.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
......@@ -13,6 +13,8 @@ using NUnit.Framework;
namespace IntegrationTests;
// Change to https://hub.docker.com/r/mitmproxy/mitmproxy/
[Ignore("Not testable in docker container, take to long to run every time")]
[TestFixture]
public class ProxyTest {
......@@ -25,8 +27,8 @@ public class ProxyTest {
File.WriteAllText("proxy/access.log", "");
_container = new TestcontainersBuilder<TestcontainersContainer>()
.WithImage("ubuntu/squid")
.WithPortBinding("3128", "3128")
.WithImage("mitmproxy/mitmproxy")
.WithPortBinding("3128", "8081")
.WithBindMount(path, @"/var/log/squid")
.Build();
_container.StartAsync().Wait();
......@@ -39,7 +41,7 @@ public class ProxyTest {
new FitConnect.Sender(FitConnectEnvironment.Testing,
_id,
_secret)
.WithProxy("localhost", 3128);
.WithProxy("localhost", 3128, null, null);
#pragma warning disable SYSLIB0014
_webClient = new WebClient {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment