1
+ using System ;
2
+ using System . Security . Cryptography ;
1
3
using System . Net . Security ;
2
4
using System . Security . Cryptography . X509Certificates ;
3
5
using Xunit ;
@@ -6,6 +8,62 @@ namespace k8s.Tests
6
8
{
7
9
public class CertificateValidationTests
8
10
{
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
+
9
67
[ Fact ]
10
68
public void ValidCert ( )
11
69
{
0 commit comments