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