From 65d84f0b455d509f3c87c1805990b19195b9d9ca Mon Sep 17 00:00:00 2001 From: Boshi LIAN Date: Mon, 25 Aug 2025 22:05:22 -0700 Subject: [PATCH 1/4] Update certificate validation to use custom trust store for .NET 5.0 and greater --- src/KubernetesClient/Kubernetes.ConfigInit.cs | 12 ++-- .../CertificateValidationTests.cs | 57 +++++++++++++++++++ 2 files changed, 64 insertions(+), 5 deletions(-) diff --git a/src/KubernetesClient/Kubernetes.ConfigInit.cs b/src/KubernetesClient/Kubernetes.ConfigInit.cs index da36c9fcf..0f19d3e84 100644 --- a/src/KubernetesClient/Kubernetes.ConfigInit.cs +++ b/src/KubernetesClient/Kubernetes.ConfigInit.cs @@ -213,11 +213,13 @@ public static bool CertificateValidationCallBack( { chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; - // Added our trusted certificates to the chain - // - chain.ChainPolicy.ExtraStore.AddRange(caCerts); - - chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; +#if NET5_0_OR_GREATER + // Use custom trust store only, ignore system root CA + chain.ChainPolicy.CustomTrustStore.AddRange(caCerts); + chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; +#else + throw new NotSupportedException("Custom trust store is not supported on this platform."); +#endif var isValid = chain.Build((X509Certificate2)certificate); var isTrusted = false; diff --git a/tests/KubernetesClient.Tests/CertificateValidationTests.cs b/tests/KubernetesClient.Tests/CertificateValidationTests.cs index f0827b7a8..187d68499 100644 --- a/tests/KubernetesClient.Tests/CertificateValidationTests.cs +++ b/tests/KubernetesClient.Tests/CertificateValidationTests.cs @@ -1,3 +1,5 @@ +using System; +using System.Security.Cryptography; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using Xunit; @@ -6,6 +8,61 @@ namespace k8s.Tests { public class CertificateValidationTests { + [Fact] + public void ShouldRejectCertFromDifferentCA() + { + // Load our "trusted" Kubernetes CA + var trustedCaCert = CertUtils.LoadPemFileCert("assets/ca.crt"); + + // Generate a completely different CA and server cert in memory + var differentCA = CreateSelfSignedCA("CN=Different CA"); + var untrustedServerCert = CreateServerCert(differentCA, "CN=fake-server.com"); + + var chain = new X509Chain(); + + // Pre-populate the chain like SSL validation would do + // This will likely succeed because we allow unknown CAs in the validation + chain.Build(untrustedServerCert); + + var errors = SslPolicyErrors.RemoteCertificateChainErrors; + + var result = Kubernetes.CertificateValidationCallBack(this, trustedCaCert, untrustedServerCert, chain, errors); + + // This SHOULD be false because the server cert wasn't signed by our trusted CA + // But the current K8s validation logic might incorrectly return true + Assert.False(result, "Should reject certificates not signed by trusted CA"); + + // Cleanup + differentCA.Dispose(); + untrustedServerCert.Dispose(); + } + + // Helper methods to create test certificates + private static X509Certificate2 CreateSelfSignedCA(string subject) + { + using (var rsa = RSA.Create(2048)) + { + var req = new CertificateRequest(subject, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); + req.CertificateExtensions.Add(new X509BasicConstraintsExtension(true, false, 0, true)); + req.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.KeyCertSign | X509KeyUsageFlags.CrlSign, true)); + + return req.CreateSelfSigned(DateTimeOffset.UtcNow.AddDays(-1), DateTimeOffset.UtcNow.AddDays(365)); + } + } + + private static X509Certificate2 CreateServerCert(X509Certificate2 issuerCA, string subject) + { + using (var rsa = RSA.Create(2048)) + { + var req = new CertificateRequest(subject, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); + req.CertificateExtensions.Add(new X509BasicConstraintsExtension(false, false, 0, true)); + req.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.KeyEncipherment, true)); + req.CertificateExtensions.Add(new X509EnhancedKeyUsageExtension(new OidCollection { new Oid("1.3.6.1.5.5.7.3.1") }, true)); + + return req.Create(issuerCA, DateTimeOffset.UtcNow.AddDays(-1), DateTimeOffset.UtcNow.AddDays(90), new byte[] { 1, 2, 3, 4 }); + } + } + [Fact] public void ValidCert() { From 33b5ef2c158a90f47c3f94812e9ce454b1949551 Mon Sep 17 00:00:00 2001 From: Brendan Burns <5751682+brendandburns@users.noreply.github.com> Date: Tue, 26 Aug 2025 18:13:30 -0700 Subject: [PATCH 2/4] Update src/KubernetesClient/Kubernetes.ConfigInit.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/KubernetesClient/Kubernetes.ConfigInit.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KubernetesClient/Kubernetes.ConfigInit.cs b/src/KubernetesClient/Kubernetes.ConfigInit.cs index 0f19d3e84..e87e4e96a 100644 --- a/src/KubernetesClient/Kubernetes.ConfigInit.cs +++ b/src/KubernetesClient/Kubernetes.ConfigInit.cs @@ -218,7 +218,7 @@ public static bool CertificateValidationCallBack( chain.ChainPolicy.CustomTrustStore.AddRange(caCerts); chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; #else - throw new NotSupportedException("Custom trust store is not supported on this platform."); + throw new NotSupportedException("Custom trust store requires .NET 5.0 or later. Current platform does not support this feature."); #endif var isValid = chain.Build((X509Certificate2)certificate); From 3739514b207cbb10fbcdfaae79dea88bd060a3c9 Mon Sep 17 00:00:00 2001 From: Boshi LIAN Date: Wed, 27 Aug 2025 00:44:09 -0700 Subject: [PATCH 3/4] Update apiserver-pfx-data.txt with new certificate data --- tests/KubernetesClient.Tests/assets/apiserver-pfx-data.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/KubernetesClient.Tests/assets/apiserver-pfx-data.txt b/tests/KubernetesClient.Tests/assets/apiserver-pfx-data.txt index 6b3dc9421..90c23f6fe 100644 --- a/tests/KubernetesClient.Tests/assets/apiserver-pfx-data.txt +++ b/tests/KubernetesClient.Tests/assets/apiserver-pfx-data.txt @@ -1 +1 @@ -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 \ No newline at end of file From f21f787f4377ab564fe617362c4bce4caaef51b4 Mon Sep 17 00:00:00 2001 From: Boshi Lian Date: Wed, 27 Aug 2025 00:45:36 -0700 Subject: [PATCH 4/4] Update tests/KubernetesClient.Tests/CertificateValidationTests.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../CertificateValidationTests.cs | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/tests/KubernetesClient.Tests/CertificateValidationTests.cs b/tests/KubernetesClient.Tests/CertificateValidationTests.cs index 187d68499..82058bbb7 100644 --- a/tests/KubernetesClient.Tests/CertificateValidationTests.cs +++ b/tests/KubernetesClient.Tests/CertificateValidationTests.cs @@ -15,26 +15,27 @@ public void ShouldRejectCertFromDifferentCA() var trustedCaCert = CertUtils.LoadPemFileCert("assets/ca.crt"); // Generate a completely different CA and server cert in memory - var differentCA = CreateSelfSignedCA("CN=Different CA"); - var untrustedServerCert = CreateServerCert(differentCA, "CN=fake-server.com"); + using (var differentCA = CreateSelfSignedCA("CN=Different CA")) + using (var untrustedServerCert = CreateServerCert(differentCA, "CN=fake-server.com")) + { + var chain = new X509Chain(); - var chain = new X509Chain(); + // Pre-populate the chain like SSL validation would do + // This will likely succeed because we allow unknown CAs in the validation + chain.Build(untrustedServerCert); - // Pre-populate the chain like SSL validation would do - // This will likely succeed because we allow unknown CAs in the validation - chain.Build(untrustedServerCert); + var errors = SslPolicyErrors.RemoteCertificateChainErrors; - var errors = SslPolicyErrors.RemoteCertificateChainErrors; + var result = Kubernetes.CertificateValidationCallBack(this, trustedCaCert, untrustedServerCert, chain, errors); - var result = Kubernetes.CertificateValidationCallBack(this, trustedCaCert, untrustedServerCert, chain, errors); - - // This SHOULD be false because the server cert wasn't signed by our trusted CA - // But the current K8s validation logic might incorrectly return true - Assert.False(result, "Should reject certificates not signed by trusted CA"); + // This SHOULD be false because the server cert wasn't signed by our trusted CA + // But the current K8s validation logic might incorrectly return true + Assert.False(result, "Should reject certificates not signed by trusted CA"); + } // Cleanup - differentCA.Dispose(); - untrustedServerCert.Dispose(); + // differentCA.Dispose(); + // untrustedServerCert.Dispose(); } // Helper methods to create test certificates