//========================================================================
//Copyright (c) Webtide LLC
//------------------------------------------------------------------------
//All rights reserved. This program and the accompanying materials
//are made available under the terms of the Eclipse Public License v1.0
//and Apache License v2.0 which accompanies this distribution.
//
//The Eclipse Public License is available at
//http://www.eclipse.org/legal/epl-v10.html
//
//The Apache License v2.0 is available at
//http://www.apache.org/licenses/LICENSE-2.0.txt
//
//You may elect to redistribute this code under either of these licenses.
//========================================================================

package org.eclipse.jetty.io;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.CRL;
import java.security.cert.CertStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.PKIXBuilderParameters;
import java.security.cert.X509CertSelector;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.net.ssl.CertPathTrustManagerParameters;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509KeyManager;
import javax.net.ssl.X509TrustManager;

import org.eclipse.jetty.exssl.AliasedX509ExtendedKeyManager;
import org.eclipse.jetty.http.security.Password;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.security.CertificateValidator;


public class SslContextFactory
{
    public static final String DEFAULT_KEYMANAGERFACTORY_ALGORITHM = 
        (Security.getProperty("ssl.KeyManagerFactory.algorithm") == null ?
                "SunX509" : Security.getProperty("ssl.KeyManagerFactory.algorithm"));
    public static final String DEFAULT_TRUSTMANAGERFACTORY_ALGORITHM = 
        (Security.getProperty("ssl.TrustManagerFactory.algorithm") == null ?
                "SunX509" : Security.getProperty("ssl.TrustManagerFactory.algorithm"));

    /** Default value for the keystore location path. */
    public static final String DEFAULT_KEYSTORE_PATH = 
        System.getProperty("user.home") + File.separator + ".keystore";

    /** String name of key password property. */
    public static final String KEYPASSWORD_PROPERTY = "org.eclipse.jetty.ssl.keypassword";

    /** String name of keystore password property. */
    public static final String PASSWORD_PROPERTY = "org.eclipse.jetty.ssl.password";

    /** Excluded cipher suites. */
    private Set<String> _excludeCipherSuites = null;
    /** Included cipher suites. */
    private Set<String> _includeCipherSuites = null;

    /** Keystore path. */
    private String _keystorePath;
    /** Keystore provider name */
    private String _keystoreProvider;
    /** Keystore type */
    private String _keystoreType = "JKS";
    /** Keystore input stream */
    private InputStream _keystoreInputStream;
    
    /** SSL certificate alias */
    private String _certAlias;

    /** Truststore path */
    private String _truststorePath;
    /** Truststore provider name */
    private String _truststoreProvider;
    /** Truststore type */
    private String _truststoreType = "JKS";
    /** Truststore input stream */
    private InputStream _truststoreInputStream;

    /** Set to true if client certificate authentication is required */
    private boolean _needClientAuth = false;
    /** Set to true if client certificate authentication is desired */
    private boolean _wantClientAuth = false;
    /** Set to true if SSL certificate validation is required */
    private boolean _validateCerts;
    /** Set to true if renegotiation is allowed */
    private boolean _allowRenegotiate = false;

    /** KeyStore password */
    private transient Password _keystorePassword;
    /** Key password */
    private transient Password _keymanagerPassword;
    /** TrustStore password */
    private transient Password _truststorePassword;

    /** SSL Provider name */
    private String _sslProvider;
    /** SSL Protocol name */
    private String _sslProtocol = "TLS";

    /** SecureRandom algorithm */
    private String _secureRandomAlgorithm;
    /** KeyManager factory algorithm */
    private String _keyManagerFactoryAlgorithm = DEFAULT_KEYMANAGERFACTORY_ALGORITHM;
    /** TrustManager factory algorithm */
    private String _trustManagerFactoryAlgorithm = DEFAULT_TRUSTMANAGERFACTORY_ALGORITHM;

    /** Path to file that contains Certificate Revocation List */
    private String _crlPath;
    /** Maximum certification path length (n - number of intermediate certs, -1 for unlimited) */
    private int _maxCertPathLength = -1;

    /** SSL context */
    private SSLContext _context;
    
    public SslContextFactory() {}
    
    public SslContextFactory(String keystorePath)
    {
        _keystorePath = keystorePath;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return The array of cipher suite names to exclude from
     * {@link SSLEngine#setEnabledCipherSuites(String[])}
     */
    public String[] getExcludeCipherSuites()
    {
        return _excludeCipherSuites.toArray(new String[_excludeCipherSuites.size()]);
    }

    /* ------------------------------------------------------------ */
    /**
     * @param cipherSuites
     *            The array of cipher suite names to exclude from
     *            {@link SSLEngine#setEnabledCipherSuites(String[])}
     */
    public void setExcludeCipherSuites(String[] cipherSuites)
    {
        _excludeCipherSuites = new HashSet<String>(Arrays.asList(cipherSuites));
    }

    /* ------------------------------------------------------------ */
    /**
     * @return The array of cipher suite names to include in
     * {@link SSLEngine#setEnabledCipherSuites(String[])}
     */
    public String[] getIncludeCipherSuites()
    {
        return _includeCipherSuites.toArray(new String[_includeCipherSuites.size()]);
    }

    /* ------------------------------------------------------------ */
    /**
     * @param cipherSuites
     *            The array of cipher suite names to include in
     *            {@link SSLEngine#setEnabledCipherSuites(String[])}
     */
    public void setIncludeCipherSuites(String[] cipherSuites)
    {
        _includeCipherSuites = new HashSet<String>(Arrays.asList(cipherSuites));
    }

    /* ------------------------------------------------------------ */
    /**
     * @return The file or URL of the SSL Key store.
     */
    public String getKeystore()
    {
        return _keystorePath;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param keystore
     *            The file or URL of the SSL Key store.
     */
    public void setKeystore(String keystore)
    {
        _keystorePath = keystore;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return The provider of the key store
     */
    public String getKeystoreProvider()
    {
        return _keystoreProvider;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param keystoreProvider
     *            The provider of the key store
     */
    public void setKeystoreProvider(String keystoreProvider)
    {
        _keystoreProvider = keystoreProvider;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return The type of the key store (default "JKS")
     */
    public String getKeystoreType()
    {
        return (_keystoreType);
    }

    /* ------------------------------------------------------------ */
    /**
     * @param keystoreType
     *            The type of the key store (default "JKS")
     */
    public void setKeystoreType(String keystoreType)
    {
        _keystoreType = keystoreType;
    }

    /* ------------------------------------------------------------ */
    /** Get the _keystoreInputStream.
     * @return the _keystoreInputStream
     */
    public InputStream getKeystoreInputStream()
    {
        checkConfig();
        
        return _keystoreInputStream;
    }

    /* ------------------------------------------------------------ */
    /** Set the _keystoreInputStream.
     * @param _keystoreInputStream the _keystoreInputStream to set
     */
    public void setKeystoreInputStream(InputStream keystoreInputStream)
    {
        _keystoreInputStream = keystoreInputStream;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return Alias of SSL certificate for the connector
     */
    public String getCertAlias()
    {
        return _certAlias;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param certAlias
     *            Alias of SSL certificate for the connector
     */
    public void setCertAlias(String certAlias)
    {
        _certAlias = certAlias;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return The file name or URL of the trust store location
     */
    public String getTruststore()
    {
        return _truststorePath;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param truststore
     *            The file name or URL of the trust store location
     */
    public void setTruststore(String truststore)
    {
        _truststorePath = truststore;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return The provider of the trust store
     */
    public String getTruststoreProvider()
    {
        return _truststoreProvider;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param truststoreProvider
     *            The provider of the trust store
     */
    public void setTruststoreProvider(String truststoreProvider)
    {
        _truststoreProvider = truststoreProvider;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return The type of the trust store (default "JKS")
     */
    public String getTruststoreType()
    {
        return _truststoreType;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param truststoreType
     *            The type of the trust store (default "JKS")
     */
    public void setTruststoreType(String truststoreType)
    {
        _truststoreType = truststoreType;
    }

    /* ------------------------------------------------------------ */
    /** Get the _truststoreInputStream.
     * @return the _truststoreInputStream
     */
    public InputStream getTruststoreInputStream()
    {
        checkConfig();
        
        return _truststoreInputStream;
    }

    /* ------------------------------------------------------------ */
    /** Set the _truststoreInputStream.
     * @param _truststoreInputStream the _truststoreInputStream to set
     */
    public void setTruststoreInputStream(InputStream truststoreInputStream)
    {
        _truststoreInputStream = truststoreInputStream;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return True if SSL needs client authentication.
     * @see SSLEngine#getNeedClientAuth()
     */
    public boolean getNeedClientAuth()
    {
        return _needClientAuth;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param needClientAuth
     *            True if SSL needs client authentication.
     * @see SSLEngine#getNeedClientAuth()
     */
    public void setNeedClientAuth(boolean needClientAuth)
    {
        _needClientAuth = needClientAuth;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return True if SSL wants client authentication.
     * @see SSLEngine#getWantClientAuth()
     */
    public boolean getWantClientAuth()
    {
        return _wantClientAuth;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param wantClientAuth
     *            True if SSL wants client authentication.
     * @see SSLEngine#getWantClientAuth()
     */
    public void setWantClientAuth(boolean wantClientAuth)
    {
        _wantClientAuth = wantClientAuth;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return true if SSL certificate has to be validated
     */
    public boolean getValidateCerts()
    {
        return _validateCerts;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param validateServerCert
     *            true if SSL certificate has to be validated
     */
    public void setValidateCerts(boolean validateCerts)
    {
        _validateCerts = validateCerts;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return True if SSL re-negotiation is allowed (default false)
     */
    public boolean isAllowRenegotiate()
    {
        return _allowRenegotiate;
    }

    /* ------------------------------------------------------------ */
    /**
     * Set if SSL re-negotiation is allowed. CVE-2009-3555 discovered a vulnerability
     * in SSL/TLS with re-negotiation. If your JVM does not have CVE-2009-3555 fixed,
     * then re-negotiation should not be allowed.
     * 
     * @param allowRenegotiate
     *            true if re-negotiation is allowed (default false)
     */
    public void setAllowRenegotiate(boolean allowRenegotiate)
    {
        _allowRenegotiate = allowRenegotiate;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param password
     *            The password for the key store
     */
    public void setKeystorePassword(String password)
    {
        _keystorePassword = Password.getPassword(PASSWORD_PROPERTY,password,null);
    }

    /* ------------------------------------------------------------ */
    /**
     * @param password
     *            The password (if any) for the specific key within the key store
     */
    public void setKeyManagerPassword(String password)
    {
        _keymanagerPassword = Password.getPassword(KEYPASSWORD_PROPERTY,password,null);
    }

    /* ------------------------------------------------------------ */
    /**
     * @param password
     *            The password for the trust store
     */
    public void setTruststorePassword(String password)
    {
        _truststorePassword = Password.getPassword(PASSWORD_PROPERTY,password,null);
    }

    /* ------------------------------------------------------------ */
    /**
     * @return The SSL provider name, which if set is passed to
     * {@link SSLContext#getInstance(String, String)}
     */
    public String getProvider()
    {
        return _sslProvider;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param provider
     *            The SSL provider name, which if set is passed to
     *            {@link SSLContext#getInstance(String, String)}
     */
    public void setProvider(String provider)
    {
        _sslProvider = provider;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return The SSL protocol (default "TLS") passed to
     * {@link SSLContext#getInstance(String, String)}
     */
    public String getProtocol()
    {
        return _sslProtocol;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param protocol
     *            The SSL protocol (default "TLS") passed to
     *            {@link SSLContext#getInstance(String, String)}
     */
    public void setProtocol(String protocol)
    {
        _sslProtocol = protocol;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return The algorithm name, which if set is passed to
     * {@link SecureRandom#getInstance(String)} to obtain the {@link SecureRandom} instance passed to
     * {@link SSLContext#init(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], SecureRandom)}
     */
    public String getSecureRandomAlgorithm()
    {
        return _secureRandomAlgorithm;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param algorithm
     *            The algorithm name, which if set is passed to
     *            {@link SecureRandom#getInstance(String)} to obtain the {@link SecureRandom} instance passed to
     *            {@link SSLContext#init(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], SecureRandom)}
     */
    public void setSecureRandomAlgorithm(String algorithm)
    {
        _secureRandomAlgorithm = algorithm;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return The algorithm name (default "SunX509") used by the {@link KeyManagerFactory}
     */
    public String getSslKeyManagerFactoryAlgorithm()
    {
        return (_keyManagerFactoryAlgorithm);
    }

    /* ------------------------------------------------------------ */
    /**
     * @param algorithm
     *            The algorithm name (default "SunX509") used by the {@link KeyManagerFactory}
     */
    public void setSslKeyManagerFactoryAlgorithm(String algorithm)
    {
        _keyManagerFactoryAlgorithm = algorithm;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return The algorithm name (default "SunX509") used by the {@link TrustManagerFactory}
     */
    public String getTrustManagerFactoryAlgorithm()
    {
        return (_trustManagerFactoryAlgorithm);
    }

    /* ------------------------------------------------------------ */
    /**
     * @param algorithm
     *            The algorithm name (default "SunX509") used by the {@link TrustManagerFactory}
     */
    public void setTrustManagerFactoryAlgorithm(String algorithm)
    {
        _trustManagerFactoryAlgorithm = algorithm;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return Path to file that contains Certificate Revocation List
     */
    public String getCrlPath()
    {
        return _crlPath;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param crlPath
     *            Path to file that contains Certificate Revocation List
     */
    public void setCrlPath(String crlPath)
    {
        _crlPath = crlPath;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return Maximum number of intermediate certificates in
     * the certification path (-1 for unlimited)
     */
    public int getMaxCertPathLength()
    {
        return _maxCertPathLength;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param maxCertPathLength
     *            maximum number of intermediate certificates in
     *            the certification path (-1 for unlimited)
     */
    public void setMaxCertPathLength(int maxCertPathLength)
    {
        _maxCertPathLength = maxCertPathLength;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return The SSLContext
     */
    public SSLContext getSslContext()
    {
        try
        {
            if (_context == null)
                _context = createSSLContext();
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }

        return _context;
    }

    /* ------------------------------------------------------------ */
    /**
     * @param sslContext
     *            Set a preconfigured SSLContext
     */
    public void setSslContext(SSLContext sslContext)
    {
        _context = sslContext;
    }
    
    /* ------------------------------------------------------------ */
    /**
     * @return The SSLContext
     */
    public SSLContext getClientSslContext()
    {
        try
        {
            if (_context == null)
                _context = createClientSSLContext();
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }

        return _context;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return SSL context for the client code
     */
    public SSLContext createClientSSLContext() throws Exception
    {
        SSLContext sslContext = null;
        
        if (_keystoreInputStream == null && _keystorePath == null &&
                _truststoreInputStream == null && _truststorePath == null )
        {
            // Create a trust manager that does not validate certificate chains
            TrustManager trustAllCerts = new X509TrustManager()
            {
                public java.security.cert.X509Certificate[] getAcceptedIssuers()
                {
                    return null;
                }

                public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
                {
                }

                public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
                {
                }
            };

            sslContext = SSLContext.getInstance(_sslProtocol);
            sslContext.init(null, new TrustManager[]{trustAllCerts}, null);
        }
        else
        {
            sslContext = createSSLContext();
        }
        
        return sslContext;
    }

    /* ------------------------------------------------------------ */
    public SSLContext createSSLContext() throws Exception
    {
        // verify that keystore and truststore 
        // parameters are set up correctly  
        checkConfig();
        
        KeyStore keyStore = getKeyStore(_keystoreInputStream, _keystorePath, _keystoreType, 
                _keystoreProvider, _keystorePassword==null? null: _keystorePassword.toString());
        KeyStore trustStore = getKeyStore(_truststoreInputStream, _truststorePath, _truststoreType, 
                _truststoreProvider, _truststorePassword==null? null: _truststorePassword.toString());
        Collection<? extends CRL> crls = loadCRL(_crlPath);

        if (_validateCerts && keyStore != null)
        {
            if (_certAlias == null)
            {
                List<String> aliases = Collections.list(keyStore.aliases());
                _certAlias = aliases.size() == 1 ? aliases.get(0) : null;
            }
    
            Certificate cert = _certAlias == null?null:keyStore.getCertificate(_certAlias);
            if (cert == null)
            {
                throw new Exception("No certificate found in the keystore" + (_certAlias==null ? "":" for alias " + _certAlias));
            }

            CertificateValidator validator = new CertificateValidator(trustStore,crls);
            validator.validate(keyStore, cert);
        }

        KeyManager[] keyManagers = getKeyManagers(keyStore);
        TrustManager[] trustManagers = getTrustManagers(trustStore,crls);

        SecureRandom secureRandom = _secureRandomAlgorithm == null?null:SecureRandom.getInstance(_secureRandomAlgorithm);
        SSLContext context = _sslProvider == null?SSLContext.getInstance(_sslProtocol):SSLContext.getInstance(_sslProtocol,_sslProvider);
        context.init(keyManagers,trustManagers,secureRandom);

        return context;
    }

    /* ------------------------------------------------------------ */
    protected KeyManager[] getKeyManagers(KeyStore keyStore) throws Exception
    {
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(_keyManagerFactoryAlgorithm);
        keyManagerFactory.init(keyStore,_keymanagerPassword == null?(_keystorePassword == null?null:_keystorePassword.toString().toCharArray()):_keymanagerPassword.toString().toCharArray());
        KeyManager[] managers = keyManagerFactory.getKeyManagers();

        if (_certAlias != null)
        {
            for (int idx = 0; idx < managers.length; idx++)
            {
                if (managers[idx] instanceof X509KeyManager)
                {
                    managers[idx] = new AliasedX509ExtendedKeyManager(_certAlias,(X509KeyManager)managers[idx]);
                }
            }
        }

        return managers;
    }

    /* ------------------------------------------------------------ */
    protected TrustManager[] getTrustManagers(KeyStore trustStore, Collection<? extends CRL> crls) throws Exception
    {
        TrustManager[] managers = null;
        if (trustStore != null && _validateCerts)
        {
            // Revocation checking is only supported for PKIX algorithm
            if (_trustManagerFactoryAlgorithm.equalsIgnoreCase("PKIX"))
            {
                PKIXBuilderParameters pbParams = new PKIXBuilderParameters(trustStore,new X509CertSelector());

                // Enable revocation checking
                pbParams.setRevocationEnabled(true);

                // Set maximum certification path length
                pbParams.setMaxPathLength(_maxCertPathLength);

                if (crls != null && !crls.isEmpty())
                {
                    pbParams.addCertStore(CertStore.getInstance("Collection",new CollectionCertStoreParameters(crls)));
                }

                // Enable On-Line Certificate Status Protocol (OCSP) support
                Security.setProperty("ocsp.enable","true");

                // Enable Certificate Revocation List Distribution Points (CRLDP) support
                System.setProperty("com.sun.security.enableCRLDP","true");

                TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(_trustManagerFactoryAlgorithm);
                trustManagerFactory.init(new CertPathTrustManagerParameters(pbParams));

                managers = trustManagerFactory.getTrustManagers();
            }
            else
            {
                TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(_trustManagerFactoryAlgorithm);
                trustManagerFactory.init(trustStore);

                managers = trustManagerFactory.getTrustManagers();
            }
        }

        return managers;
    }

    /* ------------------------------------------------------------ */
    protected KeyStore getKeyStore(InputStream storeStream, String storePath, String storeType, String storeProvider, String storePassword) throws Exception
    {
        KeyStore keystore = null;

        if (storeStream != null || storePath != null)
        {
            InputStream inStream = storeStream;
            try
            {
                if (inStream == null)
                {
                    inStream = Resource.newResource(storePath).getInputStream();
                }
                
                if (storeProvider != null)
                {
                    keystore = KeyStore.getInstance(storeType, storeProvider);
                }
                else
                {
                    keystore = KeyStore.getInstance(storeType);
                }
    
                keystore.load(inStream, storePassword == null ? null : storePassword.toCharArray());
            }
            finally
            {
                if (inStream != null)
                {
                    inStream.close();
                }
            }
        }
        
        return keystore;
    }

    /* ------------------------------------------------------------ */
    protected Collection<? extends CRL> loadCRL(String crlPath) throws Exception
    {
        Collection<? extends CRL> crlList = null;

        if (crlPath != null)
        {
            InputStream in = null;
            try
            {
                in = Resource.newResource(crlPath).getInputStream();
                crlList = CertificateFactory.getInstance("X.509").generateCRLs(in);
            }
            finally
            {
                if (in != null)
                {
                    in.close();
                }
            }
        }

        return crlList;
    }
    
    protected void checkConfig()
    {
        /*
         * if the keystore exists but the trust store 
         * does not, use the keystore as the trust store
         */
        if (_keystoreInputStream != null || _keystorePath != null)
        {
            if (_truststoreInputStream == null && _truststorePath == null)
            {
                _truststorePath = _keystorePath;
                _truststoreInputStream = _keystoreInputStream;
                _truststoreType = _keystoreType;
                _truststoreProvider = _keystoreProvider;
                _truststorePassword = _keystorePassword;
                _trustManagerFactoryAlgorithm = _keyManagerFactoryAlgorithm;
            }
        }
        
        // It's the same stream we cannot read it twice, so read it once in memory
        if (_keystoreInputStream != null && _keystoreInputStream == _truststoreInputStream)
        {
            try
            {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                IO.copy(_keystoreInputStream, baos);
                _keystoreInputStream.close();
    
                _keystoreInputStream = new ByteArrayInputStream(baos.toByteArray());
                _truststoreInputStream = new ByteArrayInputStream(baos.toByteArray());
            }
            catch (Exception ex)
            {
                throw new RuntimeException(ex);
            }
        }
    }

    public String[] selectCipherSuites(String[] enabledCipherSuites, String[] supportedCipherSuites)
    {
        Set<String> selectedCipherSuites = null;
        if (enabledCipherSuites != null)
        {
            selectedCipherSuites = new HashSet<String>(Arrays.asList(enabledCipherSuites));
        }
        else
        {
            selectedCipherSuites = new HashSet<String>();
        }

        if ((supportedCipherSuites != null && supportedCipherSuites.length > 0) && (_includeCipherSuites != null && _includeCipherSuites.size() > 0))
        {
            Set<String> supportedCSList = new HashSet<String>(Arrays.asList(supportedCipherSuites));
            
            for (String cipherName : _includeCipherSuites)
            {
                if ((!selectedCipherSuites.contains(cipherName)) && supportedCSList.contains(cipherName))
                {
                    selectedCipherSuites.add(cipherName);
                }
            }
        }

        if (_excludeCipherSuites != null && _excludeCipherSuites.size() > 0)
        {
            for (String cipherName : _excludeCipherSuites)
            {
                if (selectedCipherSuites.contains(cipherName))
                {
                    selectedCipherSuites.remove(cipherName);
                }
            }
        }

        return selectedCipherSuites.toArray(new String[selectedCipherSuites.size()]);
    }
}
