2323
2424import javax .annotation .Nullable ;
2525import javax .net .ssl .HostnameVerifier ;
26+ import javax .net .ssl .KeyManager ;
27+ import javax .net .ssl .KeyManagerFactory ;
2628import javax .net .ssl .SSLContext ;
2729import javax .net .ssl .SSLSession ;
2830import javax .net .ssl .SSLSocketFactory ;
2931import javax .net .ssl .TrustManager ;
3032import javax .net .ssl .X509TrustManager ;
31- import java .security .KeyManagementException ;
33+ import java .io .FileInputStream ;
34+ import java .io .IOException ;
35+ import java .security .GeneralSecurityException ;
36+ import java .security .KeyStore ;
3237import java .security .NoSuchAlgorithmException ;
3338import java .security .cert .X509Certificate ;
3439import java .util .Objects ;
@@ -108,19 +113,28 @@ public static SSLSocketFactory getSSLSocketFactory(boolean validateCertificates)
108113 }
109114
110115 @ Nullable
111- private static SSLSocketFactory createSocketFactory (TrustManager [] trustAllCerts ) throws NoSuchAlgorithmException , KeyManagementException {
116+ private static SSLSocketFactory createSocketFactory (@ Nullable TrustManager [] trustManagers ) throws IOException , GeneralSecurityException {
112117 SSLContext sslContext ;
113118 try {
114119 sslContext = SSLContext .getInstance ("SSL" );
115120 } catch (NoSuchAlgorithmException e ) {
116121 logger .info ("SSL is not supported, trying to use TLS instead." );
117122 sslContext = SSLContext .getInstance ("TLS" );
118123 }
119- sslContext .init (null , trustAllCerts , new java .security .SecureRandom ());
124+
125+ KeyManager [] keyManagers = null ;
126+ try {
127+ keyManagers = getKeyManagers ();
128+ } catch (IOException | GeneralSecurityException e ) {
129+ logger .warn ("unable to setup key managers, keystore options will be ignored" );
130+ logger .debug ("key manager creation error stack trace: " , e );
131+ }
132+
133+ sslContext .init (keyManagers , trustManagers , new java .security .SecureRandom ());
120134 return sslContext .getSocketFactory ();
121135 }
122136
123- public static SSLSocketFactory createTrustAllSocketFactory () throws NoSuchAlgorithmException , KeyManagementException {
137+ public static SSLSocketFactory createTrustAllSocketFactory () throws GeneralSecurityException , IOException {
124138 return Objects .requireNonNull (createSocketFactory (new TrustManager []{X_509_TRUST_ALL }));
125139 }
126140
@@ -132,4 +146,39 @@ public static X509TrustManager getTrustAllManager() {
132146 return X_509_TRUST_ALL ;
133147 }
134148
149+ @ Nullable
150+ public static KeyManager [] getKeyManagers () throws IOException , GeneralSecurityException {
151+ // re-implements parts of sun.security.ssl.SSLContextImpl.DefaultManagersHolder.getKeyManagers
152+ // as there is no simple way to reuse existing implementation
153+
154+ String keyStore = System .getProperty ("javax.net.ssl.keyStore" );
155+ String keyStorePassword = System .getProperty ("javax.net.ssl.keyStorePassword" );
156+ String keyStoreType = System .getProperty ("javax.net.ssl.keyStoreType" );
157+ String keyStoreProvider = System .getProperty ("javax.net.ssl.keyStoreProvider" );
158+
159+ if (keyStore == null ) {
160+ return null ;
161+ }
162+ logger .debug ("using keystore {}" , keyStore );
163+
164+ char [] pwd = keyStorePassword != null ? keyStorePassword .toCharArray () : null ;
165+
166+ KeyStore ks = null ;
167+ try (FileInputStream input = new FileInputStream (keyStore )) {
168+ if (keyStoreType != null ) {
169+ ks = keyStoreProvider == null ?
170+ KeyStore .getInstance (keyStoreType ) :
171+ KeyStore .getInstance (keyStoreType , keyStoreProvider );
172+ ks .load (input , pwd );
173+ }
174+ }
175+
176+ KeyManagerFactory kmf = KeyManagerFactory .getInstance (
177+ KeyManagerFactory .getDefaultAlgorithm ());
178+
179+ kmf .init (ks , pwd );
180+
181+ return kmf .getKeyManagers ();
182+ }
183+
135184}
0 commit comments