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