11using System ;
2+ using System . Diagnostics ;
3+ using System . IO ;
24using System . Net . Http ;
35using System . Net . Security ;
6+ using System . Security . Claims ;
47using System . Security . Cryptography . X509Certificates ;
8+ using System . Xml . Linq ;
59using Microsoft . Rest . TransientFaultHandling ;
610
711namespace Kudu . Core . Kube
@@ -11,6 +15,7 @@ public class KubernetesClientUtil
1115 public const int ClientRetryCount = 3 ;
1216 public const int ClientRetryIntervalInSeconds = 5 ;
1317 private const string caPath = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" ;
18+ private const string serviceCAPath = "/var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt" ;
1419
1520 public static void ExecuteWithRetry ( Action action )
1621 {
@@ -21,12 +26,23 @@ public static void ExecuteWithRetry(Action action)
2126 retryPolicy . ExecuteAction ( action ) ;
2227 }
2328
24- public static bool ServerCertificateValidationCallback (
29+ public static bool ServerCertificateValidationCallback2 (
2530 HttpRequestMessage request ,
2631 X509Certificate2 certificate ,
2732 X509Chain certChain ,
2833 SslPolicyErrors sslPolicyErrors )
2934 {
35+ Console . WriteLine ( "ServerCertificateValidationCallback2 : true" ) ;
36+ return true ;
37+ }
38+
39+ public static bool ServerCertificateValidationCallback (
40+ HttpRequestMessage request ,
41+ X509Certificate2 certificate ,
42+ X509Chain certChain ,
43+ SslPolicyErrors sslPolicyErrors )
44+ {
45+ Console . WriteLine ( $ "sslPolicyErrors: { sslPolicyErrors } ") ;
3046 if ( sslPolicyErrors == SslPolicyErrors . None )
3147 {
3248 // certificate is already valid
@@ -36,6 +52,7 @@ public static bool ServerCertificateValidationCallback(
3652 {
3753 // only remaining error state is RemoteCertificateChainErrors
3854 // check custom CA
55+ bool caresult = true ;
3956 var privateChain = new X509Chain ( ) ;
4057 privateChain . ChainPolicy . RevocationMode = X509RevocationMode . NoCheck ;
4158
@@ -46,17 +63,72 @@ public static bool ServerCertificateValidationCallback(
4663 // Build the chain for `certificate` which should be the self-signed kubernetes api-server cert.
4764 privateChain . Build ( certificate ) ;
4865
66+ foreach ( X509ChainElement element in privateChain . ChainElements )
67+ {
68+ Console . WriteLine ( ) ;
69+ Console . WriteLine ( element . Certificate . Subject ) ;
70+ Console . WriteLine ( element . ChainElementStatus . Length ) ;
71+ foreach ( X509ChainStatus status in element . ChainElementStatus )
72+ {
73+ Console . WriteLine ( $ "Status: { status . Status } : { status . StatusInformation } ") ;
74+ }
75+ }
76+
4977 foreach ( X509ChainStatus chainStatus in privateChain . ChainStatus )
5078 {
5179 if ( chainStatus . Status != X509ChainStatusFlags . NoError &&
5280 // root CA cert is not always trusted.
5381 chainStatus . Status != X509ChainStatusFlags . UntrustedRoot )
5482 {
55- return false ;
83+ Console . WriteLine ( $ "ca crt: { chainStatus . Status } ") ;
84+ caresult = false ;
85+ break ;
5686 }
5787 }
5888
59- return true ;
89+ if ( caresult )
90+ {
91+ return true ;
92+ }
93+
94+ if ( File . Exists ( serviceCAPath ) )
95+ {
96+ var serviceCAprivateChain = new X509Chain ( ) ;
97+ serviceCAprivateChain . ChainPolicy . RevocationMode = X509RevocationMode . NoCheck ;
98+
99+ var serviceCA = new X509Certificate2 ( serviceCAPath ) ;
100+ // https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.x509chainpolicy?view=netcore-2.2
101+ // Add CA cert to the chain store to include it in the chain check.
102+ serviceCAprivateChain . ChainPolicy . ExtraStore . Add ( serviceCA ) ;
103+ // Build the chain for `certificate` which should be the self-signed kubernetes api-server cert.
104+ serviceCAprivateChain . Build ( certificate ) ;
105+
106+ foreach ( X509ChainElement element in serviceCAprivateChain . ChainElements )
107+ {
108+ Console . WriteLine ( ) ;
109+ Console . WriteLine ( element . Certificate . Subject ) ;
110+ Console . WriteLine ( element . ChainElementStatus . Length ) ;
111+ foreach ( X509ChainStatus status in element . ChainElementStatus )
112+ {
113+ Console . WriteLine ( $ "Status: { status . Status } : { status . StatusInformation } ") ;
114+ }
115+ }
116+
117+ foreach ( X509ChainStatus chainStatus in serviceCAprivateChain . ChainStatus )
118+ {
119+ if ( chainStatus . Status != X509ChainStatusFlags . NoError &&
120+ // root CA cert is not always trusted.
121+ chainStatus . Status != X509ChainStatusFlags . UntrustedRoot )
122+ {
123+ Console . WriteLine ( $ "service crt: { chainStatus . Status } ") ;
124+ return false ;
125+ }
126+ }
127+
128+ return true ;
129+ }
130+
131+ return false ;
60132 }
61133 else
62134 {
0 commit comments