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