1
2
3
4
5
6
7
8
9
10
11 package org.mule.api.security.tls;
12
13 import org.mule.api.lifecycle.CreateException;
14 import org.mule.api.security.TlsDirectKeyStore;
15 import org.mule.api.security.TlsDirectTrustStore;
16 import org.mule.api.security.TlsIndirectKeyStore;
17 import org.mule.api.security.TlsProtocolHandler;
18 import org.mule.api.security.provider.AutoDiscoverySecurityProviderFactory;
19 import org.mule.api.security.provider.SecurityProviderFactory;
20 import org.mule.api.security.provider.SecurityProviderInfo;
21 import org.mule.config.i18n.CoreMessages;
22 import org.mule.util.FileUtils;
23 import org.mule.util.IOUtils;
24 import org.mule.util.StringUtils;
25
26 import java.io.FileNotFoundException;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.security.GeneralSecurityException;
30 import java.security.KeyManagementException;
31 import java.security.KeyStore;
32 import java.security.KeyStoreException;
33 import java.security.NoSuchAlgorithmException;
34 import java.security.Provider;
35 import java.security.Security;
36 import java.util.Enumeration;
37
38 import javax.net.ssl.KeyManager;
39 import javax.net.ssl.KeyManagerFactory;
40 import javax.net.ssl.SSLContext;
41 import javax.net.ssl.SSLServerSocketFactory;
42 import javax.net.ssl.SSLSocketFactory;
43 import javax.net.ssl.TrustManager;
44 import javax.net.ssl.TrustManagerFactory;
45
46 import org.apache.commons.logging.Log;
47 import org.apache.commons.logging.LogFactory;
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116 public final class TlsConfiguration
117 implements TlsDirectTrustStore, TlsDirectKeyStore, TlsIndirectKeyStore, TlsProtocolHandler
118 {
119
120 public static final String DEFAULT_KEYSTORE = ".keystore";
121 public static final String DEFAULT_KEYSTORE_TYPE = KeyStore.getDefaultType();
122 public static final String JSSE_NAMESPACE = "javax.net";
123
124 private Log logger = LogFactory.getLog(getClass());
125
126 private SecurityProviderFactory spFactory = new AutoDiscoverySecurityProviderFactory();
127 private SecurityProviderInfo spInfo = spFactory.getSecurityProviderInfo();
128 private Provider provider = spFactory.getProvider();
129 private String sslType = spInfo.getDefaultSslType();
130
131
132 private String protocolHandler = spInfo.getProtocolHandler();
133
134
135
136 private String keyStoreName = DEFAULT_KEYSTORE;
137 private String keyAlias = null;
138 private String keyPassword = null;
139 private String keyStorePassword = null;
140 private String keystoreType = DEFAULT_KEYSTORE_TYPE;
141 private String keyManagerAlgorithm = spInfo.getKeyManagerAlgorithm();
142 private KeyManagerFactory keyManagerFactory = null;
143
144
145
146
147
148
149 private String clientKeyStoreName = null;
150 private String clientKeyStorePassword = null;
151 private String clientKeyStoreType = DEFAULT_KEYSTORE_TYPE;
152
153
154
155 private String trustStoreName = null;
156 private String trustStorePassword = null;
157 private String trustStoreType = DEFAULT_KEYSTORE_TYPE;
158 private String trustManagerAlgorithm = spInfo.getKeyManagerAlgorithm();
159 private TrustManagerFactory trustManagerFactory = null;
160 private boolean explicitTrustStoreOnly = false;
161 private boolean requireClientAuthentication = false;
162
163
164
165
166
167
168 public TlsConfiguration(String keyStore)
169 {
170 this.keyStoreName = keyStore;
171 }
172
173
174
175
176
177
178
179
180
181
182 public void initialise(boolean anon, String namespace) throws CreateException
183 {
184 if (logger.isDebugEnabled())
185 {
186 logger.debug("initialising: anon " + anon);
187 }
188 validate(anon);
189
190 Security.addProvider(provider);
191 System.setProperty("java.protocol.handler.pkgs", protocolHandler);
192
193 if (!anon)
194 {
195 initKeyManagerFactory();
196 }
197 initTrustManagerFactory();
198
199 if (null != namespace)
200 {
201 new TlsPropertiesMapper(namespace).writeToProperties(System.getProperties(), this);
202 }
203 }
204
205 private void validate(boolean anon) throws CreateException
206 {
207 assertNotNull(getProvider(), "The security provider cannot be null");
208 if (!anon)
209 {
210 assertNotNull(getKeyStore(), "The KeyStore location cannot be null");
211 assertNotNull(getKeyPassword(), "The Key password cannot be null");
212 assertNotNull(getKeyStorePassword(), "The KeyStore password cannot be null");
213 assertNotNull(getKeyManagerAlgorithm(), "The Key Manager Algorithm cannot be null");
214 }
215 }
216
217 private void initKeyManagerFactory() throws CreateException
218 {
219 if (logger.isDebugEnabled())
220 {
221 logger.debug("initialising key manager factory from keystore data");
222 }
223
224 KeyStore tempKeyStore;
225 try
226 {
227 tempKeyStore = loadKeyStore();
228 checkKeyStoreContainsAlias(tempKeyStore);
229 }
230 catch (Exception e)
231 {
232 throw new CreateException(
233 CoreMessages.failedToLoad("KeyStore: " + keyStoreName), e, this);
234 }
235
236 try
237 {
238 keyManagerFactory = KeyManagerFactory.getInstance(getKeyManagerAlgorithm());
239 keyManagerFactory.init(tempKeyStore, keyPassword.toCharArray());
240 }
241 catch (Exception e)
242 {
243 throw new CreateException(CoreMessages.failedToLoad("Key Manager"), e, this);
244 }
245 }
246
247 protected KeyStore loadKeyStore() throws GeneralSecurityException, IOException
248 {
249 KeyStore tempKeyStore = KeyStore.getInstance(keystoreType);
250
251 InputStream is = IOUtils.getResourceAsStream(keyStoreName, getClass());
252 if (null == is)
253 {
254 throw new FileNotFoundException(
255 CoreMessages.cannotLoadFromClasspath("Keystore: " + keyStoreName).getMessage());
256 }
257
258 tempKeyStore.load(is, keyStorePassword.toCharArray());
259 return tempKeyStore;
260 }
261
262 protected void checkKeyStoreContainsAlias(KeyStore keyStore) throws KeyStoreException
263 {
264 if (StringUtils.isNotBlank(keyAlias))
265 {
266 boolean keyAliasFound = false;
267
268 Enumeration<String> aliases = keyStore.aliases();
269 while (aliases.hasMoreElements())
270 {
271 String alias = aliases.nextElement();
272
273 if (alias.equals(keyAlias))
274 {
275
276
277 keyAliasFound = true;
278 }
279 else
280 {
281
282
283 keyStore.deleteEntry(alias);
284 }
285 }
286
287
288 if (!keyAliasFound)
289 {
290 throw new IllegalStateException("Key with alias \"" + keyAlias + "\" was not found");
291 }
292 }
293 }
294
295 private void initTrustManagerFactory() throws CreateException
296 {
297 if (null != trustStoreName)
298 {
299 trustStorePassword = null == trustStorePassword ? "" : trustStorePassword;
300
301 KeyStore trustStore;
302 try
303 {
304 trustStore = KeyStore.getInstance(trustStoreType);
305 InputStream is = IOUtils.getResourceAsStream(trustStoreName, getClass());
306 if (null == is)
307 {
308 throw new FileNotFoundException(
309 "Failed to load truststore from classpath or local file: " + trustStoreName);
310 }
311 trustStore.load(is, trustStorePassword.toCharArray());
312 }
313 catch (Exception e)
314 {
315 throw new CreateException(
316 CoreMessages.failedToLoad("TrustStore: " + trustStoreName), e, this);
317 }
318
319 try
320 {
321 trustManagerFactory = TrustManagerFactory.getInstance(trustManagerAlgorithm);
322 trustManagerFactory.init(trustStore);
323 }
324 catch (Exception e)
325 {
326 throw new CreateException(
327 CoreMessages.failedToLoad("Trust Manager (" + trustManagerAlgorithm + ")"), e, this);
328 }
329 }
330 }
331
332
333 private static void assertNotNull(Object value, String message)
334 {
335 if (null == value)
336 {
337 throw new IllegalArgumentException(message);
338 }
339 }
340
341 private static String defaultForNull(String value, String deflt)
342 {
343 if (null == value)
344 {
345 return deflt;
346 }
347 else
348 {
349 return value;
350 }
351 }
352
353 public SSLSocketFactory getSocketFactory() throws NoSuchAlgorithmException, KeyManagementException
354 {
355 return getSslContext().getSocketFactory();
356 }
357
358 public SSLServerSocketFactory getServerSocketFactory()
359 throws NoSuchAlgorithmException, KeyManagementException
360 {
361 return getSslContext().getServerSocketFactory();
362 }
363
364 public SSLContext getSslContext() throws NoSuchAlgorithmException, KeyManagementException
365 {
366 KeyManager[] keyManagers =
367 null == getKeyManagerFactory() ? null : getKeyManagerFactory().getKeyManagers();
368 TrustManager[] trustManagers =
369 null == getTrustManagerFactory() ? null : getTrustManagerFactory().getTrustManagers();
370
371 SSLContext context = SSLContext.getInstance(getSslType());
372
373 context.init(keyManagers, trustManagers, null);
374 return context;
375 }
376
377 public String getSslType()
378 {
379 return sslType;
380 }
381
382 public void setSslType(String sslType)
383 {
384 this.sslType = sslType;
385 }
386
387 public Provider getProvider()
388 {
389 return provider;
390 }
391
392 public void setProvider(Provider provider)
393 {
394 this.provider = provider;
395 }
396
397 public String getProtocolHandler()
398 {
399 return protocolHandler;
400 }
401
402 public void setProtocolHandler(String protocolHandler)
403 {
404 this.protocolHandler = protocolHandler;
405 }
406
407 public SecurityProviderFactory getSecurityProviderFactory()
408 {
409 return spFactory;
410 }
411
412 public void setSecurityProviderFactory(SecurityProviderFactory spFactory)
413 {
414 this.spFactory = spFactory;
415 }
416
417
418
419 public String getKeyStore()
420 {
421 return keyStoreName;
422 }
423
424 public void setKeyStore(String name) throws IOException
425 {
426 keyStoreName = name;
427 if (null != keyStoreName)
428 {
429 keyStoreName = FileUtils.getResourcePath(keyStoreName, getClass());
430 if (logger.isDebugEnabled())
431 {
432 logger.debug("Normalised keyStore path to: " + keyStoreName);
433 }
434 }
435 }
436
437 public String getKeyPassword()
438 {
439 return keyPassword;
440 }
441
442 public void setKeyPassword(String keyPassword)
443 {
444 this.keyPassword = keyPassword;
445 }
446
447 public String getKeyStorePassword()
448 {
449 return keyStorePassword;
450 }
451
452 public void setKeyStorePassword(String storePassword)
453 {
454 this.keyStorePassword = storePassword;
455 }
456
457 public String getKeyStoreType()
458 {
459 return keystoreType;
460 }
461
462 public void setKeyStoreType(String keystoreType)
463 {
464 this.keystoreType = keystoreType;
465 }
466
467 public String getKeyManagerAlgorithm()
468 {
469 return keyManagerAlgorithm;
470 }
471
472 public void setKeyManagerAlgorithm(String keyManagerAlgorithm)
473 {
474 this.keyManagerAlgorithm = keyManagerAlgorithm;
475 }
476
477 public KeyManagerFactory getKeyManagerFactory()
478 {
479 return keyManagerFactory;
480 }
481
482
483
484 public String getClientKeyStore()
485 {
486 return clientKeyStoreName;
487 }
488
489 public void setClientKeyStore(String name) throws IOException
490 {
491 clientKeyStoreName = name;
492 if (null != clientKeyStoreName)
493 {
494 clientKeyStoreName = FileUtils.getResourcePath(clientKeyStoreName, getClass());
495 if (logger.isDebugEnabled())
496 {
497 logger.debug("Normalised clientKeyStore path to: " + clientKeyStoreName);
498 }
499 }
500 }
501
502 public String getClientKeyStorePassword()
503 {
504 return clientKeyStorePassword;
505 }
506
507 public void setClientKeyStorePassword(String clientKeyStorePassword)
508 {
509 this.clientKeyStorePassword = clientKeyStorePassword;
510 }
511
512 public void setClientKeyStoreType(String clientKeyStoreType)
513 {
514 this.clientKeyStoreType = clientKeyStoreType;
515 }
516
517 public String getClientKeyStoreType()
518 {
519 return clientKeyStoreType;
520 }
521
522
523
524 public String getTrustStore()
525 {
526 return trustStoreName;
527 }
528
529 public void setTrustStore(String name) throws IOException
530 {
531 trustStoreName = name;
532 if (null != trustStoreName)
533 {
534 trustStoreName = FileUtils.getResourcePath(trustStoreName, getClass());
535 if (logger.isDebugEnabled())
536 {
537 logger.debug("Normalised trustStore path to: " + trustStoreName);
538 }
539 }
540 }
541
542 public String getTrustStorePassword()
543 {
544 return trustStorePassword;
545 }
546
547 public void setTrustStorePassword(String trustStorePassword)
548 {
549 this.trustStorePassword = trustStorePassword;
550 }
551
552 public String getTrustStoreType()
553 {
554 return trustStoreType;
555 }
556
557 public void setTrustStoreType(String trustStoreType)
558 {
559 this.trustStoreType = trustStoreType;
560 }
561
562 public String getTrustManagerAlgorithm()
563 {
564 return trustManagerAlgorithm;
565 }
566
567 public void setTrustManagerAlgorithm(String trustManagerAlgorithm)
568 {
569 this.trustManagerAlgorithm = defaultForNull(trustManagerAlgorithm, spInfo.getKeyManagerAlgorithm());
570 }
571
572 public TrustManagerFactory getTrustManagerFactory()
573 {
574 return trustManagerFactory;
575 }
576
577 public void setTrustManagerFactory(TrustManagerFactory trustManagerFactory)
578 {
579 this.trustManagerFactory = trustManagerFactory;
580 }
581
582 public boolean isExplicitTrustStoreOnly()
583 {
584 return explicitTrustStoreOnly;
585 }
586
587 public void setExplicitTrustStoreOnly(boolean explicitTrustStoreOnly)
588 {
589 this.explicitTrustStoreOnly = explicitTrustStoreOnly;
590 }
591
592 public boolean isRequireClientAuthentication()
593 {
594 return requireClientAuthentication;
595 }
596
597 public void setRequireClientAuthentication(boolean requireClientAuthentication)
598 {
599 this.requireClientAuthentication = requireClientAuthentication;
600 }
601
602 public String getKeyAlias()
603 {
604 return keyAlias;
605 }
606
607 public void setKeyAlias(String keyAlias)
608 {
609 this.keyAlias = keyAlias;
610 }
611
612 }
613
614