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