1414package io .kubernetes .client .util .authenticators ;
1515
1616import io .kubernetes .client .util .KubeConfig ;
17+ import java .io .ByteArrayInputStream ;
1718import java .io .IOException ;
1819import java .io .OutputStream ;
1920import java .net .URL ;
2021import java .net .URLEncoder ;
2122import java .nio .charset .StandardCharsets ;
23+ import java .security .KeyManagementException ;
24+ import java .security .KeyStore ;
25+ import java .security .KeyStoreException ;
26+ import java .security .NoSuchAlgorithmException ;
27+ import java .security .SecureRandom ;
28+ import java .security .cert .Certificate ;
29+ import java .security .cert .CertificateException ;
30+ import java .security .cert .CertificateFactory ;
2231import java .util .Base64 ;
32+ import java .util .Collection ;
33+ import java .util .Iterator ;
2334import java .util .Map ;
2435import java .util .Scanner ;
2536import javax .net .ssl .HttpsURLConnection ;
37+ import javax .net .ssl .SSLContext ;
38+ import javax .net .ssl .TrustManagerFactory ;
2639import org .jose4j .json .internal .json_simple .JSONObject ;
2740import org .jose4j .json .internal .json_simple .parser .JSONParser ;
2841import org .jose4j .json .internal .json_simple .parser .ParseException ;
@@ -46,6 +59,8 @@ public class OpenIDConnectAuthenticator implements Authenticator {
4659 private static final String OIDC_CLIENT_ID = "client-id" ;
4760 /** Optional client secret */
4861 private static final String OIDC_CLIENT_SECRET = "client-secret" ;
62+ /** Optional IdP TLS Certificate */
63+ private static final String OIDC_IDP_CERT_DATA = "idp-certificate-authority-data" ;
4964
5065 static {
5166 KubeConfig .registerAuthenticator (new OpenIDConnectAuthenticator ());
@@ -90,6 +105,50 @@ public Map<String, Object> refresh(Map<String, Object> config) {
90105 String clientId = (String ) config .get (OIDC_CLIENT_ID );
91106 String refreshToken = (String ) config .get (OIDC_REFRESH_TOKEN );
92107 String clientSecret = (String ) config .get (OIDC_CLIENT_SECRET );
108+ String idpCert = (String ) config .get (OIDC_IDP_CERT_DATA );
109+
110+ SSLContext sslContext = null ;
111+
112+ if (idpCert != null ) {
113+ // fist, lets get the pem
114+ String pemCert = new String (Base64 .getDecoder ().decode (idpCert ));
115+
116+ // next lets get a cert object
117+ String alias = "doenotmatter" ;
118+ KeyStore ks ;
119+
120+ try {
121+ ks = java .security .KeyStore .getInstance ("PKCS12" );
122+ ks .load (null , "doesnotmatter" .toCharArray ());
123+ ByteArrayInputStream bais = new ByteArrayInputStream (pemCert .getBytes ("UTF-8" ));
124+ CertificateFactory cf = CertificateFactory .getInstance ("X.509" );
125+ Collection <? extends java .security .cert .Certificate > c = cf .generateCertificates (bais );
126+
127+ if (c .size () > 1 ) {
128+ int j = 0 ;
129+ Iterator <? extends java .security .cert .Certificate > i = c .iterator ();
130+ while (i .hasNext ()) {
131+ Certificate certificate = (Certificate ) i .next ();
132+ ks .setCertificateEntry (alias + "-" + j , certificate );
133+ }
134+ } else {
135+ ks .setCertificateEntry (alias , c .iterator ().next ());
136+ }
137+
138+ TrustManagerFactory tmf = TrustManagerFactory .getInstance ("PKIX" );
139+ tmf .init (ks );
140+
141+ sslContext = SSLContext .getInstance ("TLSv1.2" );
142+ sslContext .init (null , tmf .getTrustManagers (), new SecureRandom ());
143+
144+ } catch (KeyStoreException
145+ | NoSuchAlgorithmException
146+ | CertificateException
147+ | IOException
148+ | KeyManagementException e ) {
149+ throw new RuntimeException ("Could not import idp certificate" , e );
150+ }
151+ }
93152
94153 if (clientSecret == null ) {
95154 clientSecret = "" ;
@@ -108,6 +167,9 @@ public Map<String, Object> refresh(Map<String, Object> config) {
108167 URL wellKnown = new URL (wellKnownURL );
109168 HttpsURLConnection https = (HttpsURLConnection ) wellKnown .openConnection ();
110169 https .setRequestMethod ("GET" );
170+ if (sslContext != null ) {
171+ https .setSSLSocketFactory (sslContext .getSocketFactory ());
172+ }
111173 https .setUseCaches (false );
112174 int code = https .getResponseCode ();
113175 if (code == 200 ) {
@@ -120,6 +182,9 @@ public Map<String, Object> refresh(Map<String, Object> config) {
120182 URL tokenEndpoint = new URL (tokenUrl );
121183 https = (HttpsURLConnection ) tokenEndpoint .openConnection ();
122184 https .setRequestMethod ("POST" );
185+ if (sslContext != null ) {
186+ https .setSSLSocketFactory (sslContext .getSocketFactory ());
187+ }
123188
124189 String credentials =
125190 Base64 .getEncoder ()
0 commit comments