3535import okhttp3 .Response ;
3636import okhttp3 .logging .HttpLoggingInterceptor ;
3737
38+ import javax .net .ssl .KeyManagerFactory ;
39+ import javax .net .ssl .SSLContext ;
40+ import javax .net .ssl .TrustManager ;
41+ import javax .net .ssl .TrustManagerFactory ;
42+ import javax .net .ssl .X509TrustManager ;
43+ import java .io .FileInputStream ;
3844import java .io .IOException ;
45+ import java .io .InputStream ;
3946import java .net .InetSocketAddress ;
4047import java .net .Proxy ;
48+ import java .security .KeyManagementException ;
49+ import java .security .KeyStore ;
50+ import java .security .KeyStoreException ;
51+ import java .security .NoSuchAlgorithmException ;
52+ import java .security .UnrecoverableKeyException ;
53+ import java .security .cert .CertificateException ;
54+ import java .util .Arrays ;
4155import java .util .List ;
4256import java .util .Map ;
4357import java .util .Optional ;
@@ -68,7 +82,8 @@ public void configure(Map<String, ?> configs) {
6882 OkHttpClientConfig config = new OkHttpClientConfig (configs );
6983
7084 authenticator = config .getAuthenticator ();
71- client = new okhttp3 .OkHttpClient .Builder ()
85+
86+ okhttp3 .OkHttpClient .Builder builder = new okhttp3 .OkHttpClient .Builder ()
7287 .connectionPool (new ConnectionPool (config .getMaxIdleConnections (), config .getKeepAliveDuration (), MILLISECONDS ))
7388 .connectTimeout (config .getConnectionTimeoutMillis (), MILLISECONDS )
7489 .readTimeout (config .getReadTimeoutMillis (), MILLISECONDS )
@@ -77,8 +92,11 @@ public void configure(Map<String, ?> configs) {
7792 .addInterceptor (chain -> chain .proceed (authorize (chain .request ())))
7893 .authenticator ((route , response ) -> authorize (response .request ()))
7994 .proxy (resolveProxy (config .getProxyHost (), config .getProxyPort ()))
80- .proxyAuthenticator (resolveProxyAuthenticator (config .getProxyUsername (), config .getProxyPassword ()))
81- .build ();
95+ .proxyAuthenticator (resolveProxyAuthenticator (config .getProxyUsername (), config .getProxyPassword ()));
96+
97+ resolveSslSocketFactory (builder , config .getKeyStore (), config .getKeyStorePassword ().value ());
98+
99+ client = builder .build ();
82100 }
83101
84102 private Request authorize (Request request ) {
@@ -108,6 +126,57 @@ private static Authenticator resolveProxyAuthenticator(String username, String p
108126 .build ();
109127 }
110128
129+ private static void resolveSslSocketFactory (okhttp3 .OkHttpClient .Builder builder , String keyStorePath , String keyStorePassword ) {
130+ if (keyStorePath .isEmpty ()) {
131+ return ;
132+ }
133+
134+ KeyStore keyStore ;
135+ try {
136+ keyStore = KeyStore .getInstance ("PKCS12" );
137+ } catch (KeyStoreException e ) {
138+ throw new IllegalStateException ("Unable to create keystore" , e );
139+ }
140+
141+ try (InputStream is = new FileInputStream (keyStorePath )) {
142+ keyStore .load (is , keyStorePassword .toCharArray ());
143+ }
144+ catch (CertificateException | IOException | NoSuchAlgorithmException e ) {
145+ throw new IllegalStateException (String .format ("Unable to load keystore '%s'" , keyStorePath ), e );
146+ }
147+
148+ KeyManagerFactory kmf ;
149+ try {
150+ kmf = KeyManagerFactory .getInstance (KeyManagerFactory .getDefaultAlgorithm ());
151+ kmf .init (keyStore , keyStorePassword .toCharArray ());
152+ } catch (UnrecoverableKeyException | NoSuchAlgorithmException | KeyStoreException e ) {
153+ throw new IllegalStateException ("Unable to initialize key manager" , e );
154+ }
155+
156+ SSLContext sslContext ;
157+ try {
158+ sslContext = SSLContext .getInstance ("TLS" );
159+ sslContext .init (kmf .getKeyManagers (), null , null );
160+ } catch (NoSuchAlgorithmException | KeyManagementException e ) {
161+ throw new IllegalStateException ("Unable to initialize SSL context" , e );
162+ }
163+
164+ TrustManagerFactory trustManagerFactory ;
165+ try {
166+ trustManagerFactory = TrustManagerFactory .getInstance (TrustManagerFactory .getDefaultAlgorithm ());
167+ trustManagerFactory .init ((KeyStore ) null );
168+ } catch (NoSuchAlgorithmException | KeyStoreException e ) {
169+ throw new IllegalStateException ("Unable to initialize trust manager" , e );
170+ }
171+
172+ TrustManager [] trustManagers = trustManagerFactory .getTrustManagers ();
173+ if (trustManagers .length != 1 || !(trustManagers [0 ] instanceof X509TrustManager )) {
174+ throw new IllegalStateException ("Unexpected default trust managers:" + Arrays .toString (trustManagers ));
175+ }
176+
177+ builder .sslSocketFactory (sslContext .getSocketFactory (), (X509TrustManager ) trustManagers [0 ]);
178+ }
179+
111180 @ Override
112181 @ SneakyThrows (IOException .class )
113182 public HttpResponse execute (HttpRequest httpRequest ) {
0 commit comments