View Javadoc

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)#%s",
1528                 getClass().getSimpleName(),
1529                 hashCode(),
1530                 _keyStorePath,
1531                 _trustStorePath,
1532                 getState());
1533     }
1534 }