Update certificate validation to use custom trust store for .NET 5.0+ (#1653)

* Update certificate validation to use custom trust store for .NET 5.0 and greater

* Update src/KubernetesClient/Kubernetes.ConfigInit.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update apiserver-pfx-data.txt with new certificate data

* Update tests/KubernetesClient.Tests/CertificateValidationTests.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Brendan Burns <5751682+brendandburns@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Boshi Lian
2025-08-27 05:48:09 -07:00
committed by GitHub
parent 9b5e710c47
commit 1f8e5da0c2
3 changed files with 66 additions and 6 deletions

View File

@@ -213,11 +213,13 @@ namespace k8s
{
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 requires .NET 5.0 or later. Current platform does not support this feature.");
#endif
var isValid = chain.Build((X509Certificate2)certificate);
var isTrusted = false;

View File

@@ -1,3 +1,5 @@
using System;
using System.Security.Cryptography;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using Xunit;
@@ -6,6 +8,62 @@ 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
using (var differentCA = CreateSelfSignedCA("CN=Different CA"))
using (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()
{

View File

@@ -1 +1 @@
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