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

Added Trusted Root certificate

parent a8235c7c
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.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.Unicode;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using Microsoft.Win32.SafeHandles;
namespace FitConnect.Encryption; namespace FitConnect.Encryption;
...@@ -18,30 +21,48 @@ public class CertificateHelper { ...@@ -18,30 +21,48 @@ public class CertificateHelper {
var certificates = key.X5c.Select(s => new X509Certificate2(Convert.FromBase64String(s))) var certificates = key.X5c.Select(s => new X509Certificate2(Convert.FromBase64String(s)))
.ToList(); .ToList();
var root = new X509Certificate2("./certificates/root.pem");
_logger?.LogTrace("Found {Count} certificate(s)", certificates.Count); _logger?.LogTrace("Found {Count} certificate(s)", certificates.Count);
var valid = certificates.Aggregate(true, var valid = certificates.Aggregate(true,
(result, cert) => result (result, cert) => result
&& ValidateCertificate(cert, out var _, logLevel) && ValidateCertificate(cert, out _,
root,
logLevel)
&& cert.Verify() && cert.Verify()
); );
return valid; return valid;
} }
internal bool ValidateCertificate(X509Certificate2 certificateX509, internal bool ValidateCertificate(X509Certificate2 certificate,
out X509ChainStatus[] chainStatus, LogLevel logLevel = LogLevel.Warning) { out X509ChainStatus[] chainStatus,
X509Certificate2? rootCertificate = null,
LogLevel logLevel = LogLevel.Warning) {
var certificateChain = new X509Chain(); var certificateChain = new X509Chain();
if (rootCertificate != null) {
certificateChain.ChainPolicy.CustomTrustStore.Add(rootCertificate);
certificateChain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
}
certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.Online; certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
certificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; certificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
certificateChain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag; certificateChain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
certificateChain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 30); certificateChain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 30);
certificateChain.Build(certificateX509);
var result = certificateChain.Build(certificate);
chainStatus = certificateChain.ChainStatus; chainStatus = certificateChain.ChainStatus;
_logger?.Log(logLevel, "Certificate status: {ObjStatusInformation}", var statusAggregation = certificateChain.ChainStatus.Aggregate("",
certificateChain.ChainStatus.Aggregate("", (r, s) => r + "\n\t - " + s.Status + ": " + s.StatusInformation);
(r, s) => r + "\n\t - " + s.Status + ": " + s.StatusInformation));
return certificateChain.ChainStatus.Length == 0; if (!string.IsNullOrWhiteSpace(statusAggregation))
_logger?.Log(logLevel, "Certificate status: {ObjStatusInformation}",
statusAggregation);
return result;
} }
} }
...@@ -64,7 +64,7 @@ public class CertificateValidation { ...@@ -64,7 +64,7 @@ public class CertificateValidation {
.WithServiceType("", _settings.LeikaKey) .WithServiceType("", _settings.LeikaKey)
.WithAttachments(new Attachment("Test.pdf", "Simple Test PDF")) .WithAttachments(new Attachment("Test.pdf", "Simple Test PDF"))
.Submit(); .Submit();
}).InnerExceptions.Any(e=>e.GetType() == typeof(SecurityException)); }).InnerExceptions.Any(e => e.GetType() == typeof(SecurityException));
} }
[Test] [Test]
...@@ -101,10 +101,45 @@ public class CertificateValidation { ...@@ -101,10 +101,45 @@ public class CertificateValidation {
[Test] [Test]
public void CheckPemFiles() { public void CheckPemFiles() {
var files = System.IO.Directory.GetFiles("./certificates"); var files = System.IO.Directory.GetFiles("./certificates");
foreach (var fileName in files) { var success = 0;
var failed = 0;
foreach (var fileName in files.Where(f => !f.EndsWith("root.pem"))) {
_logger.LogInformation("Checking file: {FileName}", fileName); _logger.LogInformation("Checking file: {FileName}", fileName);
var certificate = X509Certificate2.CreateFromPem(File.ReadAllText(fileName));
_certificateHelper.ValidateCertificate(certificate, out var states);
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++;
}
}
if (fileName.EndsWith(".json")) {
var shouldFail = !fileName.Contains("/valid");
var jwk = new JsonWebKey(File.ReadAllText(fileName));
var valid = _certificateHelper.ValidateCertificate(jwk,
shouldFail ? LogLevel.Trace : LogLevel.Critical);
if (shouldFail)
valid = !valid;
if (valid) {
success++;
}
else {
failed++;
}
}
} }
_logger.LogInformation("Success: {Success}, Failed: {Failed}", success, failed);
failed.Should().Be(0);
} }
} }
...@@ -36,6 +36,24 @@ ...@@ -36,6 +36,24 @@
<None Update="certificates\www-amazon-de-zertifikatskette.pem"> <None Update="certificates\www-amazon-de-zertifikatskette.pem">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Update="certificates\invalidEncJwkWithLessThan3Certificates.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="certificates\validEncJW_KeyUse.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="certificates\ValidEncJWK.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="certificates\validSigJWK.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="certificates\revokedEncJWK.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="certificates\root.pem">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup> </ItemGroup>
</Project> </Project>
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