Skip to content

Commit 1f8e5da

Browse files
tg123brendandburnsCopilot
authored
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 <[email protected]> * Update apiserver-pfx-data.txt with new certificate data * Update tests/KubernetesClient.Tests/CertificateValidationTests.cs Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Brendan Burns <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent 9b5e710 commit 1f8e5da

File tree

3 files changed

+66
-6
lines changed

3 files changed

+66
-6
lines changed

src/KubernetesClient/Kubernetes.ConfigInit.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,13 @@ public static bool CertificateValidationCallBack(
213213
{
214214
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
215215

216-
// Added our trusted certificates to the chain
217-
//
218-
chain.ChainPolicy.ExtraStore.AddRange(caCerts);
219-
220-
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
216+
#if NET5_0_OR_GREATER
217+
// Use custom trust store only, ignore system root CA
218+
chain.ChainPolicy.CustomTrustStore.AddRange(caCerts);
219+
chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
220+
#else
221+
throw new NotSupportedException("Custom trust store requires .NET 5.0 or later. Current platform does not support this feature.");
222+
#endif
221223
var isValid = chain.Build((X509Certificate2)certificate);
222224

223225
var isTrusted = false;

tests/KubernetesClient.Tests/CertificateValidationTests.cs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System;
2+
using System.Security.Cryptography;
13
using System.Net.Security;
24
using System.Security.Cryptography.X509Certificates;
35
using Xunit;
@@ -6,6 +8,62 @@ namespace k8s.Tests
68
{
79
public class CertificateValidationTests
810
{
11+
[Fact]
12+
public void ShouldRejectCertFromDifferentCA()
13+
{
14+
// Load our "trusted" Kubernetes CA
15+
var trustedCaCert = CertUtils.LoadPemFileCert("assets/ca.crt");
16+
17+
// Generate a completely different CA and server cert in memory
18+
using (var differentCA = CreateSelfSignedCA("CN=Different CA"))
19+
using (var untrustedServerCert = CreateServerCert(differentCA, "CN=fake-server.com"))
20+
{
21+
var chain = new X509Chain();
22+
23+
// Pre-populate the chain like SSL validation would do
24+
// This will likely succeed because we allow unknown CAs in the validation
25+
chain.Build(untrustedServerCert);
26+
27+
var errors = SslPolicyErrors.RemoteCertificateChainErrors;
28+
29+
var result = Kubernetes.CertificateValidationCallBack(this, trustedCaCert, untrustedServerCert, chain, errors);
30+
31+
// This SHOULD be false because the server cert wasn't signed by our trusted CA
32+
// But the current K8s validation logic might incorrectly return true
33+
Assert.False(result, "Should reject certificates not signed by trusted CA");
34+
}
35+
36+
// Cleanup
37+
// differentCA.Dispose();
38+
// untrustedServerCert.Dispose();
39+
}
40+
41+
// Helper methods to create test certificates
42+
private static X509Certificate2 CreateSelfSignedCA(string subject)
43+
{
44+
using (var rsa = RSA.Create(2048))
45+
{
46+
var req = new CertificateRequest(subject, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
47+
req.CertificateExtensions.Add(new X509BasicConstraintsExtension(true, false, 0, true));
48+
req.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.KeyCertSign | X509KeyUsageFlags.CrlSign, true));
49+
50+
return req.CreateSelfSigned(DateTimeOffset.UtcNow.AddDays(-1), DateTimeOffset.UtcNow.AddDays(365));
51+
}
52+
}
53+
54+
private static X509Certificate2 CreateServerCert(X509Certificate2 issuerCA, string subject)
55+
{
56+
using (var rsa = RSA.Create(2048))
57+
{
58+
var req = new CertificateRequest(subject, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
59+
req.CertificateExtensions.Add(new X509BasicConstraintsExtension(false, false, 0, true));
60+
req.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.KeyEncipherment, true));
61+
req.CertificateExtensions.Add(new X509EnhancedKeyUsageExtension(new OidCollection { new Oid("1.3.6.1.5.5.7.3.1") }, true));
62+
63+
return req.Create(issuerCA, DateTimeOffset.UtcNow.AddDays(-1), DateTimeOffset.UtcNow.AddDays(90), new byte[] { 1, 2, 3, 4 });
64+
}
65+
}
66+
967
[Fact]
1068
public void ValidCert()
1169
{
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
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

0 commit comments

Comments
 (0)