From 2c064388f78c5846aab6583ab5ca0fea305bc189 Mon Sep 17 00:00:00 2001
From: Klaus Fischer <klaus.fischer@eloware.com>
Date: Wed, 31 Aug 2022 10:30:48 +0200
Subject: [PATCH] WIP: OnBoard validation

---
 FitConnect/Encryption/CertificateHelper.cs | 39 ++++++++++++++++++++
 FitConnect/Encryption/FitEncryption.cs     |  2 +-
 FitConnect/FitConnect.csproj               | 32 ++++++++---------
 IntegrationTests/CertificateValidation.cs  | 42 ++++++++++++++++++++++
 4 files changed, 98 insertions(+), 17 deletions(-)
 create mode 100644 FitConnect/Encryption/CertificateHelper.cs
 create mode 100644 IntegrationTests/CertificateValidation.cs

diff --git a/FitConnect/Encryption/CertificateHelper.cs b/FitConnect/Encryption/CertificateHelper.cs
new file mode 100644
index 00000000..2a27b156
--- /dev/null
+++ b/FitConnect/Encryption/CertificateHelper.cs
@@ -0,0 +1,39 @@
+using System.Security.Cryptography.X509Certificates;
+using Microsoft.Extensions.Logging;
+using Microsoft.IdentityModel.Tokens;
+
+namespace FitConnect.Encryption;
+
+public class CertificateHelper {
+    private readonly ILogger? _logger;
+
+    public CertificateHelper(ILogger? logger = null) {
+        _logger = logger;
+    }
+
+    internal bool ValidateCertificate(JsonWebKey key) {
+        var certificates = key.X5c.Select(s => new X509Certificate2(Convert.FromBase64String(s)))
+            .ToList();
+        var valid = certificates.Aggregate(true,
+            (result, cert) => result
+                              && cert.Verify()
+                              && OcspCheck(cert, cert.Issuer)
+        );
+        return valid;
+    }
+
+    private bool OcspCheck(X509Certificate2 certificateX509, string issuer) {
+        var issuerBytes = Convert.FromBase64String(issuer);
+
+        var issuerX509 = new X509Certificate2(issuerBytes);
+        var certificateChain = new X509Chain();
+        certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
+        certificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
+        certificateChain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
+        certificateChain.ChainPolicy.ExtraStore.Add(issuerX509);
+        certificateChain.Build(certificateX509);
+
+
+        return certificateChain.ChainStatus.Length == 0;
+    }
+}
diff --git a/FitConnect/Encryption/FitEncryption.cs b/FitConnect/Encryption/FitEncryption.cs
index 620d281a..309ccbfa 100644
--- a/FitConnect/Encryption/FitEncryption.cs
+++ b/FitConnect/Encryption/FitEncryption.cs
@@ -272,4 +272,4 @@ public class FitEncryption {
 
         return result.IsValid;
     }
-}
+}
\ No newline at end of file
diff --git a/FitConnect/FitConnect.csproj b/FitConnect/FitConnect.csproj
index c131e6d9..c4077619 100644
--- a/FitConnect/FitConnect.csproj
+++ b/FitConnect/FitConnect.csproj
@@ -11,28 +11,28 @@
     </PropertyGroup>
 
     <ItemGroup>
-        <PackageReference Include="Autofac" Version="6.4.0"/>
-        <PackageReference Include="IdentityModel" Version="6.0.0"/>
-        <PackageReference Include="jose-jwt" Version="4.0.0"/>
-        <PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0"/>
-        <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.1"/>
-        <PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="6.22.0"/>
-        <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.22.0"/>
-        <PackageReference Include="Newtonsoft.Json" Version="13.0.1"/>
-        <PackageReference Include="Newtonsoft.Json.Schema" Version="3.0.14"/>
-        <PackageReference Include="NJsonSchema" Version="10.7.2"/>
-        <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.21.0"/>
+        <PackageReference Include="Autofac" Version="6.4.0" />
+        <PackageReference Include="IdentityModel" Version="6.0.0" />
+        <PackageReference Include="jose-jwt" Version="4.0.0" />
+        <PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
+        <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.1" />
+        <PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="6.22.0" />
+        <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.22.0" />
+        <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
+        <PackageReference Include="Newtonsoft.Json.Schema" Version="3.0.14" />
+        <PackageReference Include="NJsonSchema" Version="10.7.2" />
+        <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.21.0" />
     </ItemGroup>
 
     <ItemGroup>
-        <None Remove="metadata.schema.json"/>
-        <EmbeddedResource Include="metadata.schema.json"/>
+        <None Remove="metadata.schema.json" />
+        <EmbeddedResource Include="metadata.schema.json" />
     </ItemGroup>
 
     <ItemGroup>
-        <Compile Remove="FunctionalBaseClass.cs"/>
-        <Compile Remove="Models\OAuthAccessToken.cs"/>
-        <Compile Remove="DiContainer.cs"/>
+        <Compile Remove="FunctionalBaseClass.cs" />
+        <Compile Remove="Models\OAuthAccessToken.cs" />
+        <Compile Remove="DiContainer.cs" />
     </ItemGroup>
 
 </Project>
diff --git a/IntegrationTests/CertificateValidation.cs b/IntegrationTests/CertificateValidation.cs
new file mode 100644
index 00000000..1fb92570
--- /dev/null
+++ b/IntegrationTests/CertificateValidation.cs
@@ -0,0 +1,42 @@
+using Autofac;
+using FitConnect.Encryption;
+using FluentAssertions;
+using Microsoft.Extensions.Logging;
+using Microsoft.IdentityModel.Tokens;
+using MockContainer;
+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]
+    public void CheckPublicKeyEncryption() {
+        _certificateHelper.ValidateCertificate(new JsonWebKey(_settings.PublicKeyEncryption))
+            .Should().BeTrue();
+    }
+
+    [Test]
+    public void CheckPrivateKeyDecryption() {
+        _certificateHelper.ValidateCertificate(new JsonWebKey(_settings.PrivateKeyDecryption))
+            .Should().BeTrue();
+    }
+}
-- 
GitLab