diff --git a/src/ZB.MOM.WW.MxGateway.Server/Security/Tls/KestrelTlsInspector.cs b/src/ZB.MOM.WW.MxGateway.Server/Security/Tls/KestrelTlsInspector.cs index 290822c..123de00 100644 --- a/src/ZB.MOM.WW.MxGateway.Server/Security/Tls/KestrelTlsInspector.cs +++ b/src/ZB.MOM.WW.MxGateway.Server/Security/Tls/KestrelTlsInspector.cs @@ -9,6 +9,13 @@ namespace ZB.MOM.WW.MxGateway.Server.Security.Tls; /// public static class KestrelTlsInspector { + /// + /// Returns when at least one HTTPS endpoint in + /// Kestrel:Endpoints has no certificate of its own (no + /// Certificate:Path, Certificate:Subject, or + /// Certificate:Thumbprint), meaning the gateway must supply a + /// generated fallback certificate. + /// public static bool RequiresGeneratedCertificate(IConfiguration configuration) { IConfigurationSection endpoints = configuration.GetSection("Kestrel:Endpoints"); @@ -24,7 +31,8 @@ public static class KestrelTlsInspector IConfigurationSection certificate = endpoint.GetSection("Certificate"); bool hasOwnCertificate = !string.IsNullOrWhiteSpace(certificate["Path"]) || - !string.IsNullOrWhiteSpace(certificate["Subject"]); + !string.IsNullOrWhiteSpace(certificate["Subject"]) || + !string.IsNullOrWhiteSpace(certificate["Thumbprint"]); if (!hasOwnCertificate) { diff --git a/src/ZB.MOM.WW.MxGateway.Tests/Security/Tls/KestrelTlsInspectorTests.cs b/src/ZB.MOM.WW.MxGateway.Tests/Security/Tls/KestrelTlsInspectorTests.cs index 2905d29..d55c498 100644 --- a/src/ZB.MOM.WW.MxGateway.Tests/Security/Tls/KestrelTlsInspectorTests.cs +++ b/src/ZB.MOM.WW.MxGateway.Tests/Security/Tls/KestrelTlsInspectorTests.cs @@ -31,4 +31,31 @@ public sealed class KestrelTlsInspectorTests [Fact] public void RequiresGeneratedCertificate_False_WhenNoEndpointsConfigured() => Assert.False(KestrelTlsInspector.RequiresGeneratedCertificate(Config())); + + [Fact] + public void RequiresGeneratedCertificate_False_WhenHttpsEndpointHasThumbprintOnly() + => Assert.False(KestrelTlsInspector.RequiresGeneratedCertificate( + Config( + ("Kestrel:Endpoints:Https:Url", "https://0.0.0.0:5120"), + ("Kestrel:Endpoints:Https:Certificate:Thumbprint", "AABBCCDDEEFF00112233445566778899AABBCCDD")))); + + [Fact] + public void RequiresGeneratedCertificate_False_WhenHttpsEndpointHasSubjectOnly() + => Assert.False(KestrelTlsInspector.RequiresGeneratedCertificate( + Config( + ("Kestrel:Endpoints:Https:Url", "https://0.0.0.0:5120"), + ("Kestrel:Endpoints:Https:Certificate:Subject", "CN=myserver")))); + + [Fact] + public void RequiresGeneratedCertificate_True_WhenHttpsUrlIsUppercase() + => Assert.True(KestrelTlsInspector.RequiresGeneratedCertificate( + Config(("Kestrel:Endpoints:Https:Url", "HTTPS://0.0.0.0:5120")))); + + [Fact] + public void RequiresGeneratedCertificate_True_WhenMixedEndpointsAndOneHttpsHasNoCert() + => Assert.True(KestrelTlsInspector.RequiresGeneratedCertificate( + Config( + ("Kestrel:Endpoints:Grpc:Url", "https://0.0.0.0:5120"), + ("Kestrel:Endpoints:Grpc:Certificate:Thumbprint", "AABBCCDDEEFF00112233445566778899AABBCCDD"), + ("Kestrel:Endpoints:Dashboard:Url", "https://0.0.0.0:5130")))); }