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