1 //========================================================================
2 //Copyright (c) Webtide LLC
3 //------------------------------------------------------------------------
4 //All rights reserved. This program and the accompanying materials
5 //are made available under the terms of the Eclipse Public License v1.0
6 //and Apache License v2.0 which accompanies this distribution.
7 //
8 //The Eclipse Public License is available at
9 //http://www.eclipse.org/legal/epl-v10.html
10 //
11 //The Apache License v2.0 is available at
12 //http://www.apache.org/licenses/LICENSE-2.0.txt
13 //
14 //You may elect to redistribute this code under either of these licenses.
15 //========================================================================
16
17 package org.eclipse.jetty.util.ssl;
18
19 import java.io.ByteArrayInputStream;
20 import java.io.ByteArrayOutputStream;
21 import java.io.File;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.net.InetAddress;
25 import java.security.InvalidParameterException;
26 import java.security.KeyStore;
27 import java.security.SecureRandom;
28 import java.security.Security;
29 import java.security.cert.CRL;
30 import java.security.cert.CertStore;
31 import java.security.cert.Certificate;
32 import java.security.cert.CollectionCertStoreParameters;
33 import java.security.cert.PKIXBuilderParameters;
34 import java.security.cert.X509CertSelector;
35 import java.util.Arrays;
36 import java.util.Collection;
37 import java.util.Collections;
38 import java.util.HashSet;
39 import java.util.List;
40 import java.util.Set;
41
42 import javax.net.ssl.CertPathTrustManagerParameters;
43 import javax.net.ssl.KeyManager;
44 import javax.net.ssl.KeyManagerFactory;
45 import javax.net.ssl.SSLContext;
46 import javax.net.ssl.SSLEngine;
47 import javax.net.ssl.SSLServerSocket;
48 import javax.net.ssl.SSLServerSocketFactory;
49 import javax.net.ssl.SSLSocket;
50 import javax.net.ssl.SSLSocketFactory;
51 import javax.net.ssl.TrustManager;
52 import javax.net.ssl.TrustManagerFactory;
53 import javax.net.ssl.X509KeyManager;
54 import javax.net.ssl.X509TrustManager;
55
56 import org.eclipse.jetty.util.IO;
57 import org.eclipse.jetty.util.component.AbstractLifeCycle;
58 import org.eclipse.jetty.util.log.Log;
59 import org.eclipse.jetty.util.log.Logger;
60 import org.eclipse.jetty.util.resource.Resource;
61 import org.eclipse.jetty.util.security.CertificateUtils;
62 import org.eclipse.jetty.util.security.CertificateValidator;
63 import org.eclipse.jetty.util.security.Password;
64
65
66 /* ------------------------------------------------------------ */
67 /**
68 * SslContextFactory is used to configure SSL connectors
69 * as well as HttpClient. It holds all SSL parameters and
70 * creates SSL context based on these parameters to be
71 * used by the SSL connectors.
72 */
73 public class SslContextFactory extends AbstractLifeCycle
74 {
75 private static final Logger LOG = Log.getLogger(SslContextFactory.class);
76
77 public static final String DEFAULT_KEYMANAGERFACTORY_ALGORITHM =
78 (Security.getProperty("ssl.KeyManagerFactory.algorithm") == null ?
79 "SunX509" : Security.getProperty("ssl.KeyManagerFactory.algorithm"));
80 public static final String DEFAULT_TRUSTMANAGERFACTORY_ALGORITHM =
81 (Security.getProperty("ssl.TrustManagerFactory.algorithm") == null ?
82 "SunX509" : Security.getProperty("ssl.TrustManagerFactory.algorithm"));
83
84 /** Default value for the keystore location path. */
85 public static final String DEFAULT_KEYSTORE_PATH =
86 System.getProperty("user.home") + File.separator + ".keystore";
87
88 /** String name of key password property. */
89 public static final String KEYPASSWORD_PROPERTY = "org.eclipse.jetty.ssl.keypassword";
90
91 /** String name of keystore password property. */
92 public static final String PASSWORD_PROPERTY = "org.eclipse.jetty.ssl.password";
93
94 /** Excluded protocols. */
95 private final Set<String> _excludeProtocols = new HashSet<String>();
96 // private final Set<String> _excludeProtocols = new HashSet<String>(Collections.singleton("SSLv2Hello"));
97 /** Included protocols. */
98 private Set<String> _includeProtocols = null;
99
100 /** Excluded cipher suites. */
101 private final Set<String> _excludeCipherSuites = new HashSet<String>();
102 /** Included cipher suites. */
103 private Set<String> _includeCipherSuites = null;
104
105 /** Keystore path. */
106 private String _keyStorePath;
107 /** Keystore provider name */
108 private String _keyStoreProvider;
109 /** Keystore type */
110 private String _keyStoreType = "JKS";
111 /** Keystore input stream */
112 private InputStream _keyStoreInputStream;
113
114 /** SSL certificate alias */
115 private String _certAlias;
116
117 /** Truststore path */
118 private String _trustStorePath;
119 /** Truststore provider name */
120 private String _trustStoreProvider;
121 /** Truststore type */
122 private String _trustStoreType = "JKS";
123 /** Truststore input stream */
124 private InputStream _trustStoreInputStream;
125
126 /** Set to true if client certificate authentication is required */
127 private boolean _needClientAuth = false;
128 /** Set to true if client certificate authentication is desired */
129 private boolean _wantClientAuth = false;
130
131 /** Set to true if renegotiation is allowed */
132 private boolean _allowRenegotiate = true;
133
134 /** Keystore password */
135 private transient Password _keyStorePassword;
136 /** Key manager password */
137 private transient Password _keyManagerPassword;
138 /** Truststore password */
139 private transient Password _trustStorePassword;
140
141 /** SSL provider name */
142 private String _sslProvider;
143 /** SSL protocol name */
144 private String _sslProtocol = "TLS";
145
146 /** SecureRandom algorithm */
147 private String _secureRandomAlgorithm;
148 /** KeyManager factory algorithm */
149 private String _keyManagerFactoryAlgorithm = DEFAULT_KEYMANAGERFACTORY_ALGORITHM;
150 /** TrustManager factory algorithm */
151 private String _trustManagerFactoryAlgorithm = DEFAULT_TRUSTMANAGERFACTORY_ALGORITHM;
152
153 /** Set to true if SSL certificate validation is required */
154 private boolean _validateCerts;
155 /** Set to true if SSL certificate of the peer validation is required */
156 private boolean _validatePeerCerts;
157 /** Maximum certification path length (n - number of intermediate certs, -1 for unlimited) */
158 private int _maxCertPathLength = -1;
159 /** Path to file that contains Certificate Revocation List */
160 private String _crlPath;
161 /** Set to true to enable CRL Distribution Points (CRLDP) support */
162 private boolean _enableCRLDP = false;
163 /** Set to true to enable On-Line Certificate Status Protocol (OCSP) support */
164 private boolean _enableOCSP = false;
165 /** Location of OCSP Responder */
166 private String _ocspResponderURL;
167
168 /** SSL keystore */
169 private KeyStore _keyStore;
170 /** SSL truststore */
171 private KeyStore _trustStore;
172 /** Set to true to enable SSL Session caching */
173 private boolean _sessionCachingEnabled = true;
174 /** SSL session cache size */
175 private int _sslSessionCacheSize;
176 /** SSL session timeout */
177 private int _sslSessionTimeout;
178
179 /** SSL context */
180 private SSLContext _context;
181
182 private boolean _trustAll;
183
184 /* ------------------------------------------------------------ */
185 /**
186 * Construct an instance of SslContextFactory
187 * Default constructor for use in XmlConfiguration files
188 */
189 public SslContextFactory()
190 {
191 _trustAll=true;
192 }
193
194 /* ------------------------------------------------------------ */
195 /**
196 * Construct an instance of SslContextFactory
197 * Default constructor for use in XmlConfiguration files
198 */
199 public SslContextFactory(boolean trustAll)
200 {
201 _trustAll=trustAll;
202 }
203
204 /* ------------------------------------------------------------ */
205 /**
206 * Construct an instance of SslContextFactory
207 * @param keyStorePath default keystore location
208 */
209 public SslContextFactory(String keyStorePath)
210 {
211 _keyStorePath = keyStorePath;
212 }
213
214 /* ------------------------------------------------------------ */
215 /**
216 * Create the SSLContext object and start the lifecycle
217 * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
218 */
219 @Override
220 protected void doStart() throws Exception
221 {
222 if (_context == null)
223 {
224 if (_keyStore==null && _keyStoreInputStream == null && _keyStorePath == null &&
225 _trustStore==null && _trustStoreInputStream == null && _trustStorePath == null )
226 {
227 TrustManager[] trust_managers=null;
228
229 if (_trustAll)
230 {
231 LOG.debug("No keystore or trust store configured. ACCEPTING UNTRUSTED CERTIFICATES!!!!!");
232 // Create a trust manager that does not validate certificate chains
233 TrustManager trustAllCerts = new X509TrustManager()
234 {
235 public java.security.cert.X509Certificate[] getAcceptedIssuers()
236 {
237 return null;
238 }
239
240 public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
241 {
242 }
243
244 public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
245 {
246 }
247 };
248 trust_managers = new TrustManager[] { trustAllCerts };
249 }
250
251 SecureRandom secureRandom = (_secureRandomAlgorithm == null)?null:SecureRandom.getInstance(_secureRandomAlgorithm);
252 _context = SSLContext.getInstance(_sslProtocol);
253 _context.init(null, trust_managers, secureRandom);
254 }
255 else
256 {
257 // verify that keystore and truststore
258 // parameters are set up correctly
259 checkKeyStore();
260
261 KeyStore keyStore = loadKeyStore();
262 KeyStore trustStore = loadTrustStore();
263
264 Collection<? extends CRL> crls = loadCRL(_crlPath);
265
266 if (_validateCerts && keyStore != null)
267 {
268 if (_certAlias == null)
269 {
270 List<String> aliases = Collections.list(keyStore.aliases());
271 _certAlias = aliases.size() == 1 ? aliases.get(0) : null;
272 }
273
274 Certificate cert = _certAlias == null?null:keyStore.getCertificate(_certAlias);
275 if (cert == null)
276 {
277 throw new Exception("No certificate found in the keystore" + (_certAlias==null ? "":" for alias " + _certAlias));
278 }
279
280 CertificateValidator validator = new CertificateValidator(trustStore, crls);
281 validator.setMaxCertPathLength(_maxCertPathLength);
282 validator.setEnableCRLDP(_enableCRLDP);
283 validator.setEnableOCSP(_enableOCSP);
284 validator.setOcspResponderURL(_ocspResponderURL);
285 validator.validate(keyStore, cert);
286 }
287
288 KeyManager[] keyManagers = getKeyManagers(keyStore);
289 TrustManager[] trustManagers = getTrustManagers(trustStore,crls);
290
291 SecureRandom secureRandom = (_secureRandomAlgorithm == null)?null:SecureRandom.getInstance(_secureRandomAlgorithm);
292 _context = (_sslProvider == null)?SSLContext.getInstance(_sslProtocol):SSLContext.getInstance(_sslProtocol,_sslProvider);
293 _context.init(keyManagers,trustManagers,secureRandom);
294
295 SSLEngine engine=newSslEngine();
296
297 LOG.info("Enabled Protocols {} of {}",Arrays.asList(engine.getEnabledProtocols()),Arrays.asList(engine.getSupportedProtocols()));
298 if (LOG.isDebugEnabled())
299 LOG.debug("Enabled Ciphers {} of {}",Arrays.asList(engine.getEnabledCipherSuites()),Arrays.asList(engine.getSupportedCipherSuites()));
300 }
301 }
302 }
303
304 /* ------------------------------------------------------------ */
305 /**
306 * @return The array of protocol names to exclude from
307 * {@link SSLEngine#setEnabledProtocols(String[])}
308 */
309 public String[] getExcludeProtocols()
310 {
311 return _excludeProtocols.toArray(new String[_excludeProtocols.size()]);
312 }
313
314 /* ------------------------------------------------------------ */
315 /**
316 * @param Protocols
317 * The array of protocol names to exclude from
318 * {@link SSLEngine#setEnabledProtocols(String[])}
319 */
320 public void setExcludeProtocols(String... protocols)
321 {
322 checkNotStarted();
323
324 _excludeProtocols.clear();
325 _excludeProtocols.addAll(Arrays.asList(protocols));
326 }
327
328 /* ------------------------------------------------------------ */
329 /**
330 * @param protocol Protocol names to add to {@link SSLEngine#setEnabledProtocols(String[])}
331 */
332 public void addExcludeProtocols(String... protocol)
333 {
334 checkNotStarted();
335 _excludeProtocols.addAll(Arrays.asList(protocol));
336 }
337
338 /* ------------------------------------------------------------ */
339 /**
340 * @return The array of protocol names to include in
341 * {@link SSLEngine#setEnabledProtocols(String[])}
342 */
343 public String[] getIncludeProtocols()
344 {
345 return _includeProtocols.toArray(new String[_includeProtocols.size()]);
346 }
347
348 /* ------------------------------------------------------------ */
349 /**
350 * @param Protocols
351 * The array of protocol names to include in
352 * {@link SSLEngine#setEnabledProtocols(String[])}
353 */
354 public void setIncludeProtocols(String... protocols)
355 {
356 checkNotStarted();
357
358 _includeProtocols = new HashSet<String>(Arrays.asList(protocols));
359 }
360
361 /* ------------------------------------------------------------ */
362 /**
363 * @return The array of cipher suite names to exclude from
364 * {@link SSLEngine#setEnabledCipherSuites(String[])}
365 */
366 public String[] getExcludeCipherSuites()
367 {
368 return _excludeCipherSuites.toArray(new String[_excludeCipherSuites.size()]);
369 }
370
371 /* ------------------------------------------------------------ */
372 /**
373 * @param cipherSuites
374 * The array of cipher suite names to exclude from
375 * {@link SSLEngine#setEnabledCipherSuites(String[])}
376 */
377 public void setExcludeCipherSuites(String... cipherSuites)
378 {
379 checkNotStarted();
380 _excludeCipherSuites.clear();
381 _excludeCipherSuites.addAll(Arrays.asList(cipherSuites));
382 }
383
384 /* ------------------------------------------------------------ */
385 /**
386 * @param cipher Cipher names to add to {@link SSLEngine#setEnabledCipherSuites(String[])}
387 */
388 public void addExcludeCipherSuites(String... cipher)
389 {
390 checkNotStarted();
391 _excludeCipherSuites.addAll(Arrays.asList(cipher));
392 }
393
394 /* ------------------------------------------------------------ */
395 /**
396 * @return The array of cipher suite names to include in
397 * {@link SSLEngine#setEnabledCipherSuites(String[])}
398 */
399 public String[] getIncludeCipherSuites()
400 {
401 return _includeCipherSuites.toArray(new String[_includeCipherSuites.size()]);
402 }
403
404 /* ------------------------------------------------------------ */
405 /**
406 * @param cipherSuites
407 * The array of cipher suite names to include in
408 * {@link SSLEngine#setEnabledCipherSuites(String[])}
409 */
410 public void setIncludeCipherSuites(String... cipherSuites)
411 {
412 checkNotStarted();
413
414 _includeCipherSuites = new HashSet<String>(Arrays.asList(cipherSuites));
415 }
416
417 /* ------------------------------------------------------------ */
418 /**
419 * @return The file or URL of the SSL Key store.
420 */
421 public String getKeyStorePath()
422 {
423 return _keyStorePath;
424 }
425
426 /* ------------------------------------------------------------ */
427 @Deprecated
428 public String getKeyStore()
429 {
430 return _keyStorePath;
431 }
432
433 /* ------------------------------------------------------------ */
434 /**
435 * @param keyStorePath
436 * The file or URL of the SSL Key store.
437 */
438 public void setKeyStorePath(String keyStorePath)
439 {
440 checkNotStarted();
441
442 _keyStorePath = keyStorePath;
443 }
444
445 /* ------------------------------------------------------------ */
446 /**
447 * @param keyStorePath
448 * @deprecated Use {@link #setKeyStorePath(String)}
449 */
450 @Deprecated
451 public void setKeyStore(String keyStorePath)
452 {
453 checkNotStarted();
454
455 _keyStorePath = keyStorePath;
456 }
457
458 /* ------------------------------------------------------------ */
459 /**
460 * @return The provider of the key store
461 */
462 public String getKeyStoreProvider()
463 {
464 return _keyStoreProvider;
465 }
466
467 /* ------------------------------------------------------------ */
468 /**
469 * @param keyStoreProvider
470 * The provider of the key store
471 */
472 public void setKeyStoreProvider(String keyStoreProvider)
473 {
474 checkNotStarted();
475
476 _keyStoreProvider = keyStoreProvider;
477 }
478
479 /* ------------------------------------------------------------ */
480 /**
481 * @return The type of the key store (default "JKS")
482 */
483 public String getKeyStoreType()
484 {
485 return (_keyStoreType);
486 }
487
488 /* ------------------------------------------------------------ */
489 /**
490 * @param keyStoreType
491 * The type of the key store (default "JKS")
492 */
493 public void setKeyStoreType(String keyStoreType)
494 {
495 checkNotStarted();
496
497 _keyStoreType = keyStoreType;
498 }
499
500 /* ------------------------------------------------------------ */
501 /** Get the _keyStoreInputStream.
502 * @return the _keyStoreInputStream
503 *
504 * @deprecated
505 */
506 @Deprecated
507 public InputStream getKeyStoreInputStream()
508 {
509 checkKeyStore();
510
511 return _keyStoreInputStream;
512 }
513
514 /* ------------------------------------------------------------ */
515 /** Set the keyStoreInputStream.
516 * @param keyStoreInputStream the InputStream to the KeyStore
517 *
518 * @deprecated Use {@link #setKeyStore(KeyStore)}
519 */
520 @Deprecated
521 public void setKeyStoreInputStream(InputStream keyStoreInputStream)
522 {
523 checkNotStarted();
524
525 _keyStoreInputStream = keyStoreInputStream;
526 }
527
528 /* ------------------------------------------------------------ */
529 /**
530 * @return Alias of SSL certificate for the connector
531 */
532 public String getCertAlias()
533 {
534 return _certAlias;
535 }
536
537 /* ------------------------------------------------------------ */
538 /**
539 * @param certAlias
540 * Alias of SSL certificate for the connector
541 */
542 public void setCertAlias(String certAlias)
543 {
544 checkNotStarted();
545
546 _certAlias = certAlias;
547 }
548
549 /* ------------------------------------------------------------ */
550 /**
551 * @return The file name or URL of the trust store location
552 */
553 public String getTrustStore()
554 {
555 return _trustStorePath;
556 }
557
558 /* ------------------------------------------------------------ */
559 /**
560 * @param trustStorePath
561 * The file name or URL of the trust store location
562 */
563 public void setTrustStore(String trustStorePath)
564 {
565 checkNotStarted();
566
567 _trustStorePath = trustStorePath;
568 }
569
570 /* ------------------------------------------------------------ */
571 /**
572 * @return The provider of the trust store
573 */
574 public String getTrustStoreProvider()
575 {
576 return _trustStoreProvider;
577 }
578
579 /* ------------------------------------------------------------ */
580 /**
581 * @param trustStoreProvider
582 * The provider of the trust store
583 */
584 public void setTrustStoreProvider(String trustStoreProvider)
585 {
586 checkNotStarted();
587
588 _trustStoreProvider = trustStoreProvider;
589 }
590
591 /* ------------------------------------------------------------ */
592 /**
593 * @return The type of the trust store (default "JKS")
594 */
595 public String getTrustStoreType()
596 {
597 return _trustStoreType;
598 }
599
600 /* ------------------------------------------------------------ */
601 /**
602 * @param trustStoreType
603 * The type of the trust store (default "JKS")
604 */
605 public void setTrustStoreType(String trustStoreType)
606 {
607 checkNotStarted();
608
609 _trustStoreType = trustStoreType;
610 }
611
612 /* ------------------------------------------------------------ */
613 /** Get the _trustStoreInputStream.
614 * @return the _trustStoreInputStream
615 *
616 * @deprecated
617 */
618 @Deprecated
619 public InputStream getTrustStoreInputStream()
620 {
621 checkKeyStore();
622
623 return _trustStoreInputStream;
624 }
625
626 /* ------------------------------------------------------------ */
627 /** Set the _trustStoreInputStream.
628 * @param trustStoreInputStream the InputStream to the TrustStore
629 *
630 * @deprecated
631 */
632 @Deprecated
633 public void setTrustStoreInputStream(InputStream trustStoreInputStream)
634 {
635 checkNotStarted();
636
637 _trustStoreInputStream = trustStoreInputStream;
638 }
639
640 /* ------------------------------------------------------------ */
641 /**
642 * @return True if SSL needs client authentication.
643 * @see SSLEngine#getNeedClientAuth()
644 */
645 public boolean getNeedClientAuth()
646 {
647 return _needClientAuth;
648 }
649
650 /* ------------------------------------------------------------ */
651 /**
652 * @param needClientAuth
653 * True if SSL needs client authentication.
654 * @see SSLEngine#getNeedClientAuth()
655 */
656 public void setNeedClientAuth(boolean needClientAuth)
657 {
658 checkNotStarted();
659
660 _needClientAuth = needClientAuth;
661 }
662
663 /* ------------------------------------------------------------ */
664 /**
665 * @return True if SSL wants client authentication.
666 * @see SSLEngine#getWantClientAuth()
667 */
668 public boolean getWantClientAuth()
669 {
670 return _wantClientAuth;
671 }
672
673 /* ------------------------------------------------------------ */
674 /**
675 * @param wantClientAuth
676 * True if SSL wants client authentication.
677 * @see SSLEngine#getWantClientAuth()
678 */
679 public void setWantClientAuth(boolean wantClientAuth)
680 {
681 checkNotStarted();
682
683 _wantClientAuth = wantClientAuth;
684 }
685
686 /* ------------------------------------------------------------ */
687 /**
688 * @return true if SSL certificate has to be validated
689 * @deprecated
690 */
691 @Deprecated
692 public boolean getValidateCerts()
693 {
694 return _validateCerts;
695 }
696
697 /* ------------------------------------------------------------ */
698 /**
699 * @return true if SSL certificate has to be validated
700 */
701 public boolean isValidateCerts()
702 {
703 return _validateCerts;
704 }
705
706 /* ------------------------------------------------------------ */
707 /**
708 * @param validateCerts
709 * true if SSL certificates have to be validated
710 */
711 public void setValidateCerts(boolean validateCerts)
712 {
713 checkNotStarted();
714
715 _validateCerts = validateCerts;
716 }
717
718 /* ------------------------------------------------------------ */
719 /**
720 * @return true if SSL certificates of the peer have to be validated
721 */
722 public boolean isValidatePeerCerts()
723 {
724 return _validatePeerCerts;
725 }
726
727 /* ------------------------------------------------------------ */
728 /**
729 * @param validatePeerCerts
730 * true if SSL certificates of the peer have to be validated
731 */
732 public void setValidatePeerCerts(boolean validatePeerCerts)
733 {
734 checkNotStarted();
735
736 _validatePeerCerts = validatePeerCerts;
737 }
738
739 /* ------------------------------------------------------------ */
740 /**
741 * @return True if SSL re-negotiation is allowed (default false)
742 */
743 public boolean isAllowRenegotiate()
744 {
745 return _allowRenegotiate;
746 }
747
748 /* ------------------------------------------------------------ */
749 /**
750 * Set if SSL re-negotiation is allowed. CVE-2009-3555 discovered
751 * a vulnerability in SSL/TLS with re-negotiation. If your JVM
752 * does not have CVE-2009-3555 fixed, then re-negotiation should
753 * not be allowed. CVE-2009-3555 was fixed in Sun java 1.6 with a ban
754 * of renegotiates in u19 and with RFC5746 in u22.
755 *
756 * @param allowRenegotiate
757 * true if re-negotiation is allowed (default false)
758 */
759 public void setAllowRenegotiate(boolean allowRenegotiate)
760 {
761 checkNotStarted();
762
763 _allowRenegotiate = allowRenegotiate;
764 }
765
766 /* ------------------------------------------------------------ */
767 /**
768 * @param password
769 * The password for the key store
770 */
771 public void setKeyStorePassword(String password)
772 {
773 checkNotStarted();
774
775 _keyStorePassword = Password.getPassword(PASSWORD_PROPERTY,password,null);
776 }
777
778 /* ------------------------------------------------------------ */
779 /**
780 * @param password
781 * The password (if any) for the specific key within the key store
782 */
783 public void setKeyManagerPassword(String password)
784 {
785 checkNotStarted();
786
787 _keyManagerPassword = Password.getPassword(KEYPASSWORD_PROPERTY,password,null);
788 }
789
790 /* ------------------------------------------------------------ */
791 /**
792 * @param password
793 * The password for the trust store
794 */
795 public void setTrustStorePassword(String password)
796 {
797 checkNotStarted();
798
799 _trustStorePassword = Password.getPassword(PASSWORD_PROPERTY,password,null);
800 }
801
802 /* ------------------------------------------------------------ */
803 /**
804 * @return The SSL provider name, which if set is passed to
805 * {@link SSLContext#getInstance(String, String)}
806 */
807 public String getProvider()
808 {
809 return _sslProvider;
810 }
811
812 /* ------------------------------------------------------------ */
813 /**
814 * @param provider
815 * The SSL provider name, which if set is passed to
816 * {@link SSLContext#getInstance(String, String)}
817 */
818 public void setProvider(String provider)
819 {
820 checkNotStarted();
821
822 _sslProvider = provider;
823 }
824
825 /* ------------------------------------------------------------ */
826 /**
827 * @return The SSL protocol (default "TLS") passed to
828 * {@link SSLContext#getInstance(String, String)}
829 */
830 public String getProtocol()
831 {
832 return _sslProtocol;
833 }
834
835 /* ------------------------------------------------------------ */
836 /**
837 * @param protocol
838 * The SSL protocol (default "TLS") passed to
839 * {@link SSLContext#getInstance(String, String)}
840 */
841 public void setProtocol(String protocol)
842 {
843 checkNotStarted();
844
845 _sslProtocol = protocol;
846 }
847
848 /* ------------------------------------------------------------ */
849 /**
850 * @return The algorithm name, which if set is passed to
851 * {@link SecureRandom#getInstance(String)} to obtain the {@link SecureRandom} instance passed to
852 * {@link SSLContext#init(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], SecureRandom)}
853 */
854 public String getSecureRandomAlgorithm()
855 {
856 return _secureRandomAlgorithm;
857 }
858
859 /* ------------------------------------------------------------ */
860 /**
861 * @param algorithm
862 * The algorithm name, which if set is passed to
863 * {@link SecureRandom#getInstance(String)} to obtain the {@link SecureRandom} instance passed to
864 * {@link SSLContext#init(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], SecureRandom)}
865 */
866 public void setSecureRandomAlgorithm(String algorithm)
867 {
868 checkNotStarted();
869
870 _secureRandomAlgorithm = algorithm;
871 }
872
873 /* ------------------------------------------------------------ */
874 /**
875 * @return The algorithm name (default "SunX509") used by the {@link KeyManagerFactory}
876 */
877 public String getSslKeyManagerFactoryAlgorithm()
878 {
879 return (_keyManagerFactoryAlgorithm);
880 }
881
882 /* ------------------------------------------------------------ */
883 /**
884 * @param algorithm
885 * The algorithm name (default "SunX509") used by the {@link KeyManagerFactory}
886 */
887 public void setSslKeyManagerFactoryAlgorithm(String algorithm)
888 {
889 checkNotStarted();
890
891 _keyManagerFactoryAlgorithm = algorithm;
892 }
893
894 /* ------------------------------------------------------------ */
895 /**
896 * @return The algorithm name (default "SunX509") used by the {@link TrustManagerFactory}
897 */
898 public String getTrustManagerFactoryAlgorithm()
899 {
900 return (_trustManagerFactoryAlgorithm);
901 }
902
903 /* ------------------------------------------------------------ */
904 /**
905 * @return True if all certificates should be trusted if there is no KeyStore or TrustStore
906 */
907 public boolean isTrustAll()
908 {
909 return _trustAll;
910 }
911
912 /* ------------------------------------------------------------ */
913 /**
914 * @param trustAll True if all certificates should be trusted if there is no KeyStore or TrustStore
915 */
916 public void setTrustAll(boolean trustAll)
917 {
918 _trustAll = trustAll;
919 }
920
921 /* ------------------------------------------------------------ */
922 /**
923 * @param algorithm
924 * The algorithm name (default "SunX509") used by the {@link TrustManagerFactory}
925 * Use the string "TrustAll" to install a trust manager that trusts all.
926 */
927 public void setTrustManagerFactoryAlgorithm(String algorithm)
928 {
929 checkNotStarted();
930
931 _trustManagerFactoryAlgorithm = algorithm;
932 }
933
934 /* ------------------------------------------------------------ */
935 /**
936 * @return Path to file that contains Certificate Revocation List
937 */
938 public String getCrlPath()
939 {
940 return _crlPath;
941 }
942
943 /* ------------------------------------------------------------ */
944 /**
945 * @param crlPath
946 * Path to file that contains Certificate Revocation List
947 */
948 public void setCrlPath(String crlPath)
949 {
950 checkNotStarted();
951
952 _crlPath = crlPath;
953 }
954
955 /* ------------------------------------------------------------ */
956 /**
957 * @return Maximum number of intermediate certificates in
958 * the certification path (-1 for unlimited)
959 */
960 public int getMaxCertPathLength()
961 {
962 return _maxCertPathLength;
963 }
964
965 /* ------------------------------------------------------------ */
966 /**
967 * @param maxCertPathLength
968 * maximum number of intermediate certificates in
969 * the certification path (-1 for unlimited)
970 */
971 public void setMaxCertPathLength(int maxCertPathLength)
972 {
973 checkNotStarted();
974
975 _maxCertPathLength = maxCertPathLength;
976 }
977
978 /* ------------------------------------------------------------ */
979 /**
980 * @return The SSLContext
981 */
982 public SSLContext getSslContext()
983 {
984 if (!isStarted())
985 throw new IllegalStateException(getState());
986 return _context;
987 }
988
989 /* ------------------------------------------------------------ */
990 /**
991 * @param sslContext
992 * Set a preconfigured SSLContext
993 */
994 public void setSslContext(SSLContext sslContext)
995 {
996 checkNotStarted();
997
998 _context = sslContext;
999 }
1000
1001 /* ------------------------------------------------------------ */
1002 /**
1003 * Override this method to provide alternate way to load a keystore.
1004 *
1005 * @return the key store instance
1006 * @throws Exception
1007 */
1008 protected KeyStore loadKeyStore() throws Exception
1009 {
1010 return _keyStore != null ? _keyStore : getKeyStore(_keyStoreInputStream,
1011 _keyStorePath, _keyStoreType, _keyStoreProvider,
1012 _keyStorePassword==null? null: _keyStorePassword.toString());
1013 }
1014
1015 /* ------------------------------------------------------------ */
1016 /**
1017 * Override this method to provide alternate way to load a truststore.
1018 *
1019 * @return the key store instance
1020 * @throws Exception
1021 */
1022 protected KeyStore loadTrustStore() throws Exception
1023 {
1024 return _trustStore != null ? _trustStore : getKeyStore(_trustStoreInputStream,
1025 _trustStorePath, _trustStoreType, _trustStoreProvider,
1026 _trustStorePassword==null? null: _trustStorePassword.toString());
1027 }
1028
1029 /* ------------------------------------------------------------ */
1030 /**
1031 * Loads keystore using an input stream or a file path in the same
1032 * order of precedence.
1033 *
1034 * Required for integrations to be able to override the mechanism
1035 * used to load a keystore in order to provide their own implementation.
1036 *
1037 * @param storeStream keystore input stream
1038 * @param storePath path of keystore file
1039 * @param storeType keystore type
1040 * @param storeProvider keystore provider
1041 * @param storePassword keystore password
1042 * @return created keystore
1043 * @throws Exception
1044 *
1045 * @deprecated
1046 */
1047 @Deprecated
1048 protected KeyStore getKeyStore(InputStream storeStream, String storePath, String storeType, String storeProvider, String storePassword) throws Exception
1049 {
1050 return CertificateUtils.getKeyStore(storeStream, storePath, storeType, storeProvider, storePassword);
1051 }
1052
1053 /* ------------------------------------------------------------ */
1054 /**
1055 * Loads certificate revocation list (CRL) from a file.
1056 *
1057 * Required for integrations to be able to override the mechanism used to
1058 * load CRL in order to provide their own implementation.
1059 *
1060 * @param crlPath path of certificate revocation list file
1061 * @return Collection of CRL's
1062 * @throws Exception
1063 */
1064 protected Collection<? extends CRL> loadCRL(String crlPath) throws Exception
1065 {
1066 return CertificateUtils.loadCRL(crlPath);
1067 }
1068
1069 /* ------------------------------------------------------------ */
1070 protected KeyManager[] getKeyManagers(KeyStore keyStore) throws Exception
1071 {
1072 KeyManager[] managers = null;
1073
1074 if (keyStore != null)
1075 {
1076 KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(_keyManagerFactoryAlgorithm);
1077 keyManagerFactory.init(keyStore,_keyManagerPassword == null?(_keyStorePassword == null?null:_keyStorePassword.toString().toCharArray()):_keyManagerPassword.toString().toCharArray());
1078 managers = keyManagerFactory.getKeyManagers();
1079
1080 if (_certAlias != null)
1081 {
1082 for (int idx = 0; idx < managers.length; idx++)
1083 {
1084 if (managers[idx] instanceof X509KeyManager)
1085 {
1086 managers[idx] = new AliasedX509ExtendedKeyManager(_certAlias,(X509KeyManager)managers[idx]);
1087 }
1088 }
1089 }
1090 }
1091
1092 return managers;
1093 }
1094
1095 /* ------------------------------------------------------------ */
1096 protected TrustManager[] getTrustManagers(KeyStore trustStore, Collection<? extends CRL> crls) throws Exception
1097 {
1098 TrustManager[] managers = null;
1099 if (trustStore != null)
1100 {
1101 // Revocation checking is only supported for PKIX algorithm
1102 if (_validatePeerCerts && _trustManagerFactoryAlgorithm.equalsIgnoreCase("PKIX"))
1103 {
1104 PKIXBuilderParameters pbParams = new PKIXBuilderParameters(trustStore,new X509CertSelector());
1105
1106 // Set maximum certification path length
1107 pbParams.setMaxPathLength(_maxCertPathLength);
1108
1109 // Make sure revocation checking is enabled
1110 pbParams.setRevocationEnabled(true);
1111
1112 if (crls != null && !crls.isEmpty())
1113 {
1114 pbParams.addCertStore(CertStore.getInstance("Collection",new CollectionCertStoreParameters(crls)));
1115 }
1116
1117 if (_enableCRLDP)
1118 {
1119 // Enable Certificate Revocation List Distribution Points (CRLDP) support
1120 System.setProperty("com.sun.security.enableCRLDP","true");
1121 }
1122
1123 if (_enableOCSP)
1124 {
1125 // Enable On-Line Certificate Status Protocol (OCSP) support
1126 Security.setProperty("ocsp.enable","true");
1127
1128 if (_ocspResponderURL != null)
1129 {
1130 // Override location of OCSP Responder
1131 Security.setProperty("ocsp.responderURL", _ocspResponderURL);
1132 }
1133 }
1134
1135 TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(_trustManagerFactoryAlgorithm);
1136 trustManagerFactory.init(new CertPathTrustManagerParameters(pbParams));
1137
1138 managers = trustManagerFactory.getTrustManagers();
1139 }
1140 else
1141 {
1142 TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(_trustManagerFactoryAlgorithm);
1143 trustManagerFactory.init(trustStore);
1144
1145 managers = trustManagerFactory.getTrustManagers();
1146 }
1147 }
1148
1149 return managers;
1150 }
1151
1152 /* ------------------------------------------------------------ */
1153 /**
1154 * Check KeyStore Configuration. Ensures that if keystore has been
1155 * configured but there's no truststore, that keystore is
1156 * used as truststore.
1157 * @throws IllegalStateException if SslContextFactory configuration can't be used.
1158 */
1159 public void checkKeyStore()
1160 {
1161 if (_context != null)
1162 return; //nothing to check if using preconfigured context
1163
1164
1165 if (_keyStore == null && _keyStoreInputStream == null && _keyStorePath == null)
1166 throw new IllegalStateException("SSL doesn't have a valid keystore");
1167
1168 // if the keystore has been configured but there is no
1169 // truststore configured, use the keystore as the truststore
1170 if (_trustStore == null && _trustStoreInputStream == null && _trustStorePath == null)
1171 {
1172 _trustStore = _keyStore;
1173 _trustStorePath = _keyStorePath;
1174 _trustStoreInputStream = _keyStoreInputStream;
1175 _trustStoreType = _keyStoreType;
1176 _trustStoreProvider = _keyStoreProvider;
1177 _trustStorePassword = _keyStorePassword;
1178 _trustManagerFactoryAlgorithm = _keyManagerFactoryAlgorithm;
1179 }
1180
1181 // It's the same stream we cannot read it twice, so read it once in memory
1182 if (_keyStoreInputStream != null && _keyStoreInputStream == _trustStoreInputStream)
1183 {
1184 try
1185 {
1186 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1187 IO.copy(_keyStoreInputStream, baos);
1188 _keyStoreInputStream.close();
1189
1190 _keyStoreInputStream = new ByteArrayInputStream(baos.toByteArray());
1191 _trustStoreInputStream = new ByteArrayInputStream(baos.toByteArray());
1192 }
1193 catch (Exception ex)
1194 {
1195 throw new IllegalStateException(ex);
1196 }
1197 }
1198 }
1199
1200 /* ------------------------------------------------------------ */
1201 /**
1202 * Select cipher suites to be used by the connector
1203 * based on configured inclusion and exclusion lists
1204 * as well as enabled and supported cipher suite lists.
1205 * @param enabledCipherSuites Array of enabled cipher suites
1206 * @param supportedCipherSuites Array of supported cipher suites
1207 * @return Array of cipher suites to enable
1208 */
1209 public String[] selectProtocols(String[] enabledProtocols, String[] supportedProtocols)
1210 {
1211 Set<String> selected_protocols = new HashSet<String>();
1212
1213 // Set the starting protocols - either from the included or enabled list
1214 if (_includeProtocols!=null)
1215 {
1216 // Use only the supported included protocols
1217 for (String protocol : supportedProtocols)
1218 if (_includeProtocols.contains(protocol))
1219 selected_protocols.add(protocol);
1220 }
1221 else
1222 selected_protocols.addAll(Arrays.asList(enabledProtocols));
1223
1224
1225 // Remove any excluded protocols
1226 if (_excludeProtocols != null)
1227 selected_protocols.removeAll(_excludeProtocols);
1228
1229 return selected_protocols.toArray(new String[selected_protocols.size()]);
1230 }
1231
1232 /* ------------------------------------------------------------ */
1233 /**
1234 * Select cipher suites to be used by the connector
1235 * based on configured inclusion and exclusion lists
1236 * as well as enabled and supported cipher suite lists.
1237 * @param enabledCipherSuites Array of enabled cipher suites
1238 * @param supportedCipherSuites Array of supported cipher suites
1239 * @return Array of cipher suites to enable
1240 */
1241 public String[] selectCipherSuites(String[] enabledCipherSuites, String[] supportedCipherSuites)
1242 {
1243 Set<String> selected_ciphers = new HashSet<String>();
1244
1245 // Set the starting ciphers - either from the included or enabled list
1246 if (_includeCipherSuites!=null)
1247 {
1248 // Use only the supported included ciphers
1249 for (String cipherSuite : supportedCipherSuites)
1250 if (_includeCipherSuites.contains(cipherSuite))
1251 selected_ciphers.add(cipherSuite);
1252 }
1253 else
1254 selected_ciphers.addAll(Arrays.asList(enabledCipherSuites));
1255
1256
1257 // Remove any excluded ciphers
1258 if (_excludeCipherSuites != null)
1259 selected_ciphers.removeAll(_excludeCipherSuites);
1260 return selected_ciphers.toArray(new String[selected_ciphers.size()]);
1261 }
1262
1263 /* ------------------------------------------------------------ */
1264 /**
1265 * Check if the lifecycle has been started and throw runtime exception
1266 */
1267 protected void checkNotStarted()
1268 {
1269 if (isStarted())
1270 throw new IllegalStateException("Cannot modify configuration when "+getState());
1271 }
1272
1273 /* ------------------------------------------------------------ */
1274 /**
1275 * @return true if CRL Distribution Points support is enabled
1276 */
1277 public boolean isEnableCRLDP()
1278 {
1279 return _enableCRLDP;
1280 }
1281
1282 /* ------------------------------------------------------------ */
1283 /** Enables CRL Distribution Points Support
1284 * @param enableCRLDP true - turn on, false - turns off
1285 */
1286 public void setEnableCRLDP(boolean enableCRLDP)
1287 {
1288 checkNotStarted();
1289
1290 _enableCRLDP = enableCRLDP;
1291 }
1292
1293 /* ------------------------------------------------------------ */
1294 /**
1295 * @return true if On-Line Certificate Status Protocol support is enabled
1296 */
1297 public boolean isEnableOCSP()
1298 {
1299 return _enableOCSP;
1300 }
1301
1302 /* ------------------------------------------------------------ */
1303 /** Enables On-Line Certificate Status Protocol support
1304 * @param enableOCSP true - turn on, false - turn off
1305 */
1306 public void setEnableOCSP(boolean enableOCSP)
1307 {
1308 checkNotStarted();
1309
1310 _enableOCSP = enableOCSP;
1311 }
1312
1313 /* ------------------------------------------------------------ */
1314 /**
1315 * @return Location of the OCSP Responder
1316 */
1317 public String getOcspResponderURL()
1318 {
1319 return _ocspResponderURL;
1320 }
1321
1322 /* ------------------------------------------------------------ */
1323 /** Set the location of the OCSP Responder.
1324 * @param ocspResponderURL location of the OCSP Responder
1325 */
1326 public void setOcspResponderURL(String ocspResponderURL)
1327 {
1328 checkNotStarted();
1329
1330 _ocspResponderURL = ocspResponderURL;
1331 }
1332
1333 /* ------------------------------------------------------------ */
1334 /** Set the key store.
1335 * @param keyStore the key store to set
1336 */
1337 public void setKeyStore(KeyStore keyStore)
1338 {
1339 checkNotStarted();
1340
1341 _keyStore = keyStore;
1342 }
1343
1344 /* ------------------------------------------------------------ */
1345 /** Set the trust store.
1346 * @param trustStore the trust store to set
1347 */
1348 public void setTrustStore(KeyStore trustStore)
1349 {
1350 checkNotStarted();
1351
1352 _trustStore = trustStore;
1353 }
1354
1355 /* ------------------------------------------------------------ */
1356 /** Set the key store resource.
1357 * @param resource the key store resource to set
1358 */
1359 public void setKeyStoreResource(Resource resource)
1360 {
1361 checkNotStarted();
1362
1363 try
1364 {
1365 _keyStoreInputStream = resource.getInputStream();
1366 }
1367 catch (IOException e)
1368 {
1369 throw new InvalidParameterException("Unable to get resource "+
1370 "input stream for resource "+resource.toString());
1371 }
1372 }
1373
1374 /* ------------------------------------------------------------ */
1375 /** Set the trust store resource.
1376 * @param resource the trust store resource to set
1377 */
1378 public void setTrustStoreResource(Resource resource)
1379 {
1380 checkNotStarted();
1381
1382 try
1383 {
1384 _trustStoreInputStream = resource.getInputStream();
1385 }
1386 catch (IOException e)
1387 {
1388 throw new InvalidParameterException("Unable to get resource "+
1389 "input stream for resource "+resource.toString());
1390 }
1391 }
1392
1393 /* ------------------------------------------------------------ */
1394 /**
1395 * @return true if SSL Session caching is enabled
1396 */
1397 public boolean isSessionCachingEnabled()
1398 {
1399 return _sessionCachingEnabled;
1400 }
1401
1402 /* ------------------------------------------------------------ */
1403 /** Set the flag to enable SSL Session caching.
1404 * @param enableSessionCaching the value of the flag
1405 */
1406 public void setSessionCachingEnabled(boolean enableSessionCaching)
1407 {
1408 _sessionCachingEnabled = enableSessionCaching;
1409 }
1410
1411 /* ------------------------------------------------------------ */
1412 /** Get SSL session cache size.
1413 * @return SSL session cache size
1414 */
1415 public int getSslSessionCacheSize()
1416 {
1417 return _sslSessionCacheSize;
1418 }
1419
1420 /* ------------------------------------------------------------ */
1421 /** SEt SSL session cache size.
1422 * @param sslSessionCacheSize SSL session cache size to set
1423 */
1424 public void setSslSessionCacheSize(int sslSessionCacheSize)
1425 {
1426 _sslSessionCacheSize = sslSessionCacheSize;
1427 }
1428
1429 /* ------------------------------------------------------------ */
1430 /** Get SSL session timeout.
1431 * @return SSL session timeout
1432 */
1433 public int getSslSessionTimeout()
1434 {
1435 return _sslSessionTimeout;
1436 }
1437
1438 /* ------------------------------------------------------------ */
1439 /** Set SSL session timeout.
1440 * @param sslSessionTimeout SSL session timeout to set
1441 */
1442 public void setSslSessionTimeout(int sslSessionTimeout)
1443 {
1444 _sslSessionTimeout = sslSessionTimeout;
1445 }
1446
1447
1448 /* ------------------------------------------------------------ */
1449 public SSLServerSocket newSslServerSocket(String host,int port,int backlog) throws IOException
1450 {
1451 SSLServerSocketFactory factory = _context.getServerSocketFactory();
1452
1453 SSLServerSocket socket =
1454 (SSLServerSocket) (host==null ?
1455 factory.createServerSocket(port,backlog):
1456 factory.createServerSocket(port,backlog,InetAddress.getByName(host)));
1457
1458 if (getWantClientAuth())
1459 socket.setWantClientAuth(getWantClientAuth());
1460 if (getNeedClientAuth())
1461 socket.setNeedClientAuth(getNeedClientAuth());
1462
1463 socket.setEnabledCipherSuites(selectCipherSuites(
1464 socket.getEnabledCipherSuites(),
1465 socket.getSupportedCipherSuites()));
1466 socket.setEnabledProtocols(selectProtocols(socket.getEnabledProtocols(),socket.getSupportedProtocols()));
1467
1468 return socket;
1469 }
1470
1471 /* ------------------------------------------------------------ */
1472 public SSLSocket newSslSocket() throws IOException
1473 {
1474 SSLSocketFactory factory = _context.getSocketFactory();
1475
1476 SSLSocket socket = (SSLSocket)factory.createSocket();
1477
1478 if (getWantClientAuth())
1479 socket.setWantClientAuth(getWantClientAuth());
1480 if (getNeedClientAuth())
1481 socket.setNeedClientAuth(getNeedClientAuth());
1482
1483 socket.setEnabledCipherSuites(selectCipherSuites(
1484 socket.getEnabledCipherSuites(),
1485 socket.getSupportedCipherSuites()));
1486 socket.setEnabledProtocols(selectProtocols(socket.getEnabledProtocols(),socket.getSupportedProtocols()));
1487
1488 return socket;
1489 }
1490
1491 /* ------------------------------------------------------------ */
1492 public SSLEngine newSslEngine(String host,int port)
1493 {
1494 SSLEngine sslEngine=isSessionCachingEnabled()
1495 ?_context.createSSLEngine(host, port)
1496 :_context.createSSLEngine();
1497
1498 customize(sslEngine);
1499 return sslEngine;
1500 }
1501
1502 /* ------------------------------------------------------------ */
1503 public SSLEngine newSslEngine()
1504 {
1505 SSLEngine sslEngine=_context.createSSLEngine();
1506 customize(sslEngine);
1507 return sslEngine;
1508 }
1509
1510 /* ------------------------------------------------------------ */
1511 public void customize(SSLEngine sslEngine)
1512 {
1513 if (getWantClientAuth())
1514 sslEngine.setWantClientAuth(getWantClientAuth());
1515 if (getNeedClientAuth())
1516 sslEngine.setNeedClientAuth(getNeedClientAuth());
1517
1518 sslEngine.setEnabledCipherSuites(selectCipherSuites(
1519 sslEngine.getEnabledCipherSuites(),
1520 sslEngine.getSupportedCipherSuites()));
1521
1522 sslEngine.setEnabledProtocols(selectProtocols(sslEngine.getEnabledProtocols(),sslEngine.getSupportedProtocols()));
1523 }
1524
1525 }