View Javadoc

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