-
Klaus Fischer authoredKlaus Fischer authored
CertificateValidation.cs 7.42 KiB
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
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 Newtonsoft.Json;
using NUnit.Framework;
namespace IntegrationTests;
[TestFixture]
public class CertificateValidation {
[SetUp]
public void Setup() {
var container = Container.Create();
_settings = container.Resolve<IFitConnectSettings>();
_logger = LoggerFactory.Create(
builder => {
builder.AddConsole();
builder.SetMinimumLevel(LogLevel.Debug);
}).CreateLogger("E2E Test");
_certificateHelper = new CertificateHelper(_logger);
}
private IFitConnectSettings _settings = null!;
private ILogger _logger = null!;
private CertificateHelper _certificateHelper = null!;
[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)!
.GetPublicKeyForDestinationAsync(_settings.DestinationId).Result;
new CertificateHelper(_logger).ValidateCertificateJsonWebKeyAsync(
JsonWebKey.Create(certificate),
null,
LogLevel.Trace).Wait();
}
[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)!
.GetPublicKeyForDestinationAsync(_settings.DestinationId).Result;
new CertificateHelper(_logger).ValidateCertificateJsonWebKeyAsync(
JsonWebKey.Create(certificate),
null,
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.SendAsync(SubmissionBuilder.WithDestination(_settings.DestinationId)
.WithServiceType("", _settings.LeikaKey)
.WithJsonData(@"{""data"":""value""}")
.WithAttachments(new Attachment("Test.pdf", "Simple Test PDF"))
.Build()).Wait();
})!.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.SendAsync(SubmissionBuilder.WithDestination(_settings.DestinationId)
.WithServiceType("", _settings.LeikaKey)
.WithJsonData(@"{""data"":""value""}")
.WithAttachments(new Attachment("Test.pdf", "Simple Test PDF"))
.Build()).Wait();
})!.InnerExceptions.Any(e => e.GetType() == typeof(SecurityException)).Should().BeTrue();
}
[Test]
public void CheckPublicKeyEncryption() {
_certificateHelper
.ValidateCertificateJsonWebKeyAsync(new JsonWebKey(_settings.PublicKeyEncryption))
.Result
.Should().BeFalse();
}
[Test]
public void CheckPublicKeySignature() {
_certificateHelper
.ValidateCertificateJsonWebKeyAsync(
new JsonWebKey(_settings.PublicKeySignatureVerification))
.Result
.Should().BeFalse();
}
[Test]
[Ignore("Certificate from server is invalid, x5c are mixed")]
public void TestDvdvCertificate() {
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.ValidateCertificateJsonWebKeyAsync(jwk).Result;
result.Should().BeTrue();
}
[Test]
[Ignore("Not implemented")]
public void CheckPemFiles() {
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>();
foreach (var fileName in files.Where(f => !f.EndsWith("root.pem"))) {
_logger.LogInformation(
"\n\n-----------------------------------------\nChecking file: {FileName}",
fileName);
if (fileName.EndsWith(".pem")) {
var certificate = X509Certificate2.CreateFromPem(File.ReadAllText(fileName));
var valid = _certificateHelper.ValidateCertificatePemAsync(certificate).Result;
if (valid) {
success++;
}
else {
failed++;
failedCerts.Add(fileName);
}
}
if (fileName.EndsWith(".json")) {
var shouldFail = !fileName.Contains("/valid");
var keySetImport = new JsonWebKeySet(File.ReadAllText(fileName));
var keySet = keySetImport.Keys.Count != 0
? keySetImport.Keys.ToList()
: new List<JsonWebKey> {
new(File.ReadAllText(fileName))
};
foreach (var jwk in keySet) {
var valid = _certificateHelper.ValidateCertificateJsonWebKeyAsync(jwk,
Directory.GetFiles("./certificates/roots")
.Select(file => new X509Certificate2(file)).ToArray(),
shouldFail ? LogLevel.Warning : LogLevel.Critical
).Result;
if (shouldFail)
valid = !valid;
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);
}
}