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