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