1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 package org.metricshub.wbem.sblim.cimclient.internal.http;
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 import java.io.FileInputStream;
62 import java.io.FileNotFoundException;
63 import java.io.IOException;
64 import java.net.Socket;
65 import java.security.KeyStore;
66 import java.security.KeyStoreException;
67 import java.security.NoSuchAlgorithmException;
68 import java.security.Principal;
69 import java.security.PrivateKey;
70 import java.security.Provider;
71 import java.security.Security;
72 import java.security.UnrecoverableKeyException;
73 import java.security.cert.CertificateException;
74 import java.security.cert.X509Certificate;
75 import java.util.logging.Level;
76 import javax.net.ServerSocketFactory;
77 import javax.net.SocketFactory;
78 import javax.net.ssl.KeyManager;
79 import javax.net.ssl.KeyManagerFactory;
80 import javax.net.ssl.SSLContext;
81 import javax.net.ssl.TrustManager;
82 import javax.net.ssl.TrustManagerFactory;
83 import javax.net.ssl.X509KeyManager;
84 import javax.net.ssl.X509TrustManager;
85 import org.metricshub.wbem.sblim.cimclient.internal.logging.LogAndTraceBroker;
86 import org.metricshub.wbem.sblim.cimclient.internal.logging.Messages;
87 import org.metricshub.wbem.sblim.cimclient.internal.util.WBEMConfiguration;
88
89
90
91
92
93 public class HttpSocketFactory {
94 private static HttpSocketFactory cInstance = new HttpSocketFactory();
95
96 private HttpSocketFactory() {
97
98 }
99
100
101
102
103
104
105 public static HttpSocketFactory getInstance() {
106 return cInstance;
107 }
108
109
110
111
112
113
114
115
116
117
118 public ServerSocketFactory getServerSocketFactory(SSLContext pContext) {
119 return pContext != null ? pContext.getServerSocketFactory() : ServerSocketFactory.getDefault();
120 }
121
122
123
124
125
126
127
128
129 public SocketFactory getClientSocketFactory(SSLContext pContext) {
130 return pContext != null ? pContext.getSocketFactory() : SocketFactory.getDefault();
131 }
132
133
134
135
136
137
138
139
140
141 public SSLContext getClientSSLContext(final WBEMConfiguration pProperties) {
142 return getSSLContext(pProperties, false);
143 }
144
145
146
147
148
149
150
151
152
153 public SSLContext getServerSSLContext(final WBEMConfiguration pProperties) {
154 return getSSLContext(pProperties, true);
155 }
156
157
158
159
160
161
162
163
164
165
166
167
168 private SSLContext getSSLContext(final WBEMConfiguration pProperties, boolean pIsServer) {
169 final LogAndTraceBroker logger = LogAndTraceBroker.getBroker();
170 logger.entry();
171
172 final String provider = pIsServer ? pProperties.getSslServerSocketProvider() : pProperties.getSslSocketProvider();
173 logger.trace(Level.FINER, "Loading JSSE provider:" + provider);
174
175 final Provider securityProvider;
176
177 try {
178 Class<?> providerClass = Class.forName(provider);
179 securityProvider = (java.security.Provider) providerClass.newInstance();
180 if (Security.getProvider(securityProvider.getName()) == null) {
181 Security.addProvider(securityProvider);
182 }
183 } catch (Exception e) {
184 logger.trace(Level.FINER, "Exception while loading JSSE provider", e);
185 logger.message(Messages.SSL_JSSE_PROVIDER_LOAD_FAILED, provider);
186 logger.exit();
187 throw new RuntimeException(e);
188 }
189
190 try {
191 KeyManager[] keyManager = loadKeystore(pProperties, securityProvider, pIsServer);
192
193 TrustManager[] trustManager = loadTruststore(pProperties, securityProvider, pIsServer);
194
195 String sslProtocol = pIsServer ? pProperties.getSslListenerProtocol() : pProperties.getSslClientProtocol();
196
197 SSLContext sslContext = SSLContext.getInstance(
198 sslProtocol != null ? sslProtocol : pProperties.getSslProtocol(),
199 securityProvider
200 );
201
202 sslContext.init(keyManager, trustManager, null);
203
204 logger.exit();
205
206 return sslContext;
207 } catch (Exception e) {
208 logger.trace(Level.FINER, "Exception while initializing SSL context (provider:" + provider + ")", e);
209 logger.message(Messages.SSL_CONTEXT_INIT_FAILED);
210 logger.exit();
211 return null;
212 }
213 }
214
215 private TrustManager[] loadTruststore(
216 final WBEMConfiguration pProperties,
217 final Provider pSecurityProvider,
218 boolean pIsServer
219 ) {
220 final LogAndTraceBroker logger = LogAndTraceBroker.getBroker();
221 logger.entry();
222
223 final TrustManager[] trustAll = new X509TrustManager[] { new AllTrustManager() };
224 final TrustManager[] trustNone = new X509TrustManager[] { new NoTrustManager() };
225 TrustManager[] trustManager = trustNone;
226
227 final String truststorePath = pProperties.getSslTrustStorePath();
228 final char[] truststorePassword = pProperties.getSslTrustStorePassword().toCharArray();
229 final String truststoreType = pProperties.getSslTrustStoreType();
230 final String trustManagerAlgorithm = pProperties.getSslTrustManagerAlgorithm();
231 final boolean clientPeerVerification = pProperties.getSslClientPeerVerification();
232 final String listenerPeerVerification = pProperties.getSslListenerPeerVerification();
233
234 logger.trace(
235 Level.FINER,
236 "Using SSL truststore \"" + truststorePath + "\" (" + truststoreType + "/" + trustManagerAlgorithm + ")"
237 );
238
239 if (pIsServer && listenerPeerVerification.equalsIgnoreCase("ignore") || (!pIsServer && !clientPeerVerification)) {
240 trustManager = trustAll;
241 if (truststorePath == null || truststorePath.trim().length() == 0) {
242 logger.trace(Level.FINER, "Peer verification disabled for " + (pIsServer ? "Listener" : "Client"));
243 } else {
244 logger.message(Messages.SSL_TRUSTSTORE_INACTIVE);
245 }
246 } else {
247 if (truststorePath == null || truststorePath.trim().length() == 0) {
248 logger.trace(
249 Level.FINER,
250 "Peer verification enabled for " + (pIsServer ? "Listener" : "Client") + " but no truststore specified!"
251 );
252 logger.message(Messages.SSL_TRUSTSTORE_NULL);
253 } else {
254 logger.trace(Level.FINER, "Peer verification enabled for " + (pIsServer ? "Listener" : "Client"));
255 FileInputStream fis = null;
256 try {
257 final KeyStore trustStore = KeyStore.getInstance(truststoreType);
258 fis = new FileInputStream(truststorePath);
259 trustStore.load(fis, truststorePassword);
260 final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
261 trustManagerAlgorithm,
262 pSecurityProvider
263 );
264 trustManagerFactory.init(trustStore);
265 trustManager = trustManagerFactory.getTrustManagers();
266 logger.trace(Level.FINER, "Truststore successfully loaded for " + (pIsServer ? "Listener" : "Client"));
267 } catch (FileNotFoundException e) {
268 logger.trace(Level.FINER, "Exception while loading truststore", e);
269 logger.message(Messages.SSL_TRUSTSTORE_NOT_FOUND, truststorePath);
270 } catch (IOException e) {
271 logger.trace(Level.FINER, "Exception while loading truststore", e);
272 logger.message(Messages.SSL_TRUSTSTORE_NOT_READABLE, truststorePath);
273 } catch (NoSuchAlgorithmException e) {
274 logger.trace(Level.FINER, "Exception while loading truststore", e);
275 logger.message(Messages.SSL_TRUSTSTORE_INVALID_ALGORITHM, trustManagerAlgorithm);
276 } catch (CertificateException e) {
277 logger.trace(Level.FINER, "Exception while loading truststore", e);
278 logger.message(Messages.SSL_TRUSTSTORE_INVALID_CERT, truststorePath);
279 } catch (KeyStoreException e) {
280 logger.trace(Level.FINER, "Exception while loading truststore", e);
281 logger.message(Messages.SSL_TRUSTSTORE_INVALID, truststoreType);
282 } catch (Exception e) {
283 logger.trace(Level.FINER, "Exception while loading truststore", e);
284 logger.message(Messages.SSL_TRUSTSTORE_OTHER, truststorePath);
285 } finally {
286 if (fis != null) {
287 try {
288 fis.close();
289 } catch (IOException e) {
290 logger.trace(Level.FINER, "Exception while closing truststore", e);
291 }
292 }
293 }
294 }
295 }
296
297 if (trustManager == trustAll) {
298 logger.message(Messages.SSL_TRUSTSTORE_FALLBACK);
299 } else if (trustManager == trustNone) {
300 logger.message(Messages.SSL_TRUSTSTORE_FALLBACK_NOTRUST);
301 } else {
302 logger.message(Messages.SSL_TRUSTSTORE_ACTIVE);
303 }
304
305 logger.exit();
306 return trustManager;
307 }
308
309 private KeyManager[] loadKeystore(
310 final WBEMConfiguration pProperties,
311 final Provider pSecurityProvider,
312 boolean pIsServer
313 ) {
314 final LogAndTraceBroker logger = LogAndTraceBroker.getBroker();
315 logger.entry();
316
317 final KeyManager[] noKeys = new KeyManager[] { new EmptyKeyManager() };
318 KeyManager[] keyManager = noKeys;
319
320 final String keystorePath = pProperties.getSslKeyStorePath();
321 final char[] keystorePassword = pProperties.getSslKeyStorePassword().toCharArray();
322 final String keystoreType = pProperties.getSslKeyStoreType();
323 final String keyManagerAlgorithm = pProperties.getSslKeyManagerAlgorithm();
324
325 logger.trace(
326 Level.FINER,
327 "Using SSL keystore \"" + keystorePath + "\" (" + keystoreType + "/" + keyManagerAlgorithm + ")"
328 );
329
330 if (keystorePath == null || keystorePath.trim().length() == 0) {
331 logger.trace(Level.FINER, "Keystore not specified for " + (pIsServer ? "Listener" : "Client"));
332 logger.message(Messages.SSL_KEYSTORE_NULL);
333 } else {
334 logger.trace(Level.FINER, "Keystore specified and activated for " + (pIsServer ? "Listener" : "Client"));
335 FileInputStream fis = null;
336 try {
337 final KeyStore keystore = KeyStore.getInstance(keystoreType);
338 fis = new FileInputStream(keystorePath);
339 keystore.load(fis, keystorePassword);
340
341 final KeyManagerFactory keymanagerfactory = KeyManagerFactory.getInstance(
342 keyManagerAlgorithm,
343 pSecurityProvider
344 );
345 keymanagerfactory.init(keystore, keystorePassword);
346 keyManager = keymanagerfactory.getKeyManagers();
347 logger.trace(Level.FINER, "Keystore successfully loaded for " + (pIsServer ? "Listener" : "Client"));
348 } catch (FileNotFoundException e) {
349 logger.trace(Level.FINER, "Exception while loading keystore", e);
350 logger.message(Messages.SSL_KEYSTORE_NOT_FOUND, keystorePath);
351 } catch (IOException e) {
352 logger.trace(Level.FINER, "Exception while loading keystore", e);
353 logger.message(Messages.SSL_KEYSTORE_NOT_READABLE, keystorePath);
354 } catch (NoSuchAlgorithmException e) {
355 logger.trace(Level.FINER, "Exception while loading keystore", e);
356 logger.message(Messages.SSL_KEYSTORE_INVALID_ALGORITHM, keyManagerAlgorithm);
357 } catch (CertificateException e) {
358 logger.trace(Level.FINER, "Exception while loading keystore", e);
359 logger.message(Messages.SSL_KEYSTORE_INVALID_CERT, keystorePath);
360 } catch (UnrecoverableKeyException e) {
361 logger.trace(Level.FINER, "Exception while loading keystore", e);
362 logger.message(Messages.SSL_KEYSTORE_UNRECOVERABLE_KEY, keystorePath);
363 } catch (KeyStoreException e) {
364 logger.trace(Level.FINER, "Exception while loading keystore", e);
365 logger.message(Messages.SSL_KEYSTORE_INVALID, keystoreType);
366 } catch (Exception e) {
367 logger.trace(Level.FINER, "Exception while loading keystore", e);
368 logger.message(Messages.SSL_KEYSTORE_OTHER, keystorePath);
369 } finally {
370 if (fis != null) {
371 try {
372 fis.close();
373 } catch (IOException e) {
374 logger.trace(Level.FINER, "Exception while closing keystore", e);
375 }
376 }
377 }
378 }
379
380 if (keyManager == noKeys) {
381 logger.message(Messages.SSL_KEYSTORE_FALLBACK);
382 }
383
384 logger.exit();
385 return keyManager;
386 }
387 }
388
389 class AllTrustManager implements X509TrustManager {
390
391
392
393
394
395 public void checkClientTrusted(X509Certificate[] arg0, String arg1) {
396 return;
397 }
398
399
400
401
402
403 public void checkServerTrusted(X509Certificate[] arg0, String arg1) {
404 return;
405 }
406
407 public X509Certificate[] getAcceptedIssuers() {
408 return null;
409 }
410 }
411
412 class NoTrustManager implements X509TrustManager {
413
414
415
416
417
418
419 public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
420 throw new CertificateException();
421 }
422
423
424
425
426
427
428 public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
429 throw new CertificateException();
430 }
431
432 public X509Certificate[] getAcceptedIssuers() {
433 return null;
434 }
435 }
436
437 class EmptyKeyManager implements X509KeyManager {
438
439
440
441
442
443
444
445 public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
446 return null;
447 }
448
449
450
451
452
453
454
455 public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
456 return null;
457 }
458
459
460
461
462
463 public X509Certificate[] getCertificateChain(String alias) {
464 return null;
465 }
466
467
468
469
470
471
472 public String[] getClientAliases(String keyType, Principal[] issuers) {
473 return null;
474 }
475
476
477
478
479
480 public PrivateKey getPrivateKey(String alias) {
481 return null;
482 }
483
484
485
486
487
488
489 public String[] getServerAliases(String keyType, Principal[] issuers) {
490 return null;
491 }
492 }