View Javadoc

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