/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.harmony.xnet.provider.jsse;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;
import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import org.apache.harmony.security.provider.cert.X509CertImpl;

/**
 * Implementation of the class OpenSSLSocketImpl
 * based on OpenSSL.
 *
 * This class only supports SSLv3 and TLSv1. This should be documented elsewhere
 * later, for example in the package.html or a separate reference document.
 */
public class OpenSSLSocketImpl
        extends javax.net.ssl.SSLSocket
        implements NativeCrypto.SSLHandshakeCallbacks {
    private int sslNativePointer;
    private InputStream is;
    private OutputStream os;
    private final Object handshakeLock = new Object();
    private final Object readLock = new Object();
    private final Object writeLock = new Object();
    private SSLParameters sslParameters;
    private String[] enabledProtocols;
    private String[] enabledCipherSuites;
    private OpenSSLSessionImpl sslSession;
    private Socket socket;
    private boolean autoClose;
    private boolean handshakeStarted = false;

    /**
     * Not set to true until the update from native that tells us the
     * full handshake is complete, since SSL_do_handshake can return
     * before the handshake is completely done due to
     * handshake_cutthrough support.
     */
    private boolean handshakeCompleted = false;

    private ArrayList<HandshakeCompletedListener> listeners;
    private int timeout = 0;
    // BEGIN android-added
    private int handshakeTimeout = -1;  // -1 = same as timeout; 0 = infinite
    // END android-added
    private String wrappedHost;
    private int wrappedPort;

    private static final AtomicInteger instanceCount = new AtomicInteger(0);

    public static int getInstanceCount() {
        return instanceCount.get();
    }

    private static void updateInstanceCount(int amount) {
        instanceCount.addAndGet(amount);
    }

    /**
     * Class constructor with 1 parameter
     *
     * @param sslParameters Parameters for the SSL
     *            context
     * @throws IOException if network fails
     */
    protected OpenSSLSocketImpl(SSLParameters sslParameters) throws IOException {
        super();
        init(sslParameters);
    }

    /**
     * Create an OpenSSLSocketImpl from an OpenSSLServerSocketImpl
     *
     * @param sslParameters Parameters for the SSL
     *            context
     * @throws IOException if network fails
     */
    protected OpenSSLSocketImpl(SSLParameters sslParameters,
                                String[] enabledProtocols,
                                String[] enabledCipherSuites) throws IOException {
        super();
        init(sslParameters, enabledProtocols, enabledCipherSuites);
    }

    /**
     * Class constructor with 3 parameters
     *
     * @throws IOException if network fails
     * @throws java.net.UnknownHostException host not defined
     */
    protected OpenSSLSocketImpl(String host, int port, SSLParameters sslParameters)
        throws IOException {
        super(host, port);
        init(sslParameters);
    }

    /**
     * Class constructor with 3 parameters: 1st is InetAddress
     *
     * @throws IOException if network fails
     * @throws java.net.UnknownHostException host not defined
     */
    protected OpenSSLSocketImpl(InetAddress address, int port, SSLParameters sslParameters)
        throws IOException {
        super(address, port);
        init(sslParameters);
    }


    /**
     * Class constructor with 5 parameters: 1st is host
     *
     * @throws IOException if network fails
     * @throws java.net.UnknownHostException host not defined
     */
    protected OpenSSLSocketImpl(String host, int port,
                                InetAddress clientAddress, int clientPort,
                                SSLParameters sslParameters)
        throws IOException {
        super(host, port, clientAddress, clientPort);
        init(sslParameters);
    }

    /**
     * Class constructor with 5 parameters: 1st is InetAddress
     *
     * @throws IOException if network fails
     * @throws java.net.UnknownHostException host not defined
     */
    protected OpenSSLSocketImpl(InetAddress address, int port,
                                InetAddress clientAddress, int clientPort,
                                SSLParameters sslParameters)
        throws IOException {
        super(address, port, clientAddress, clientPort);
        init(sslParameters);
    }

    /**
     * Constructor with 5 parameters: 1st is socket. Enhances an existing socket
     * with SSL functionality. Invoked via OpenSSLSocketImplWrapper constructor.
     *
     * @throws IOException if network fails
     */
    protected OpenSSLSocketImpl(Socket socket, String host, int port,
            boolean autoClose, SSLParameters sslParameters) throws IOException {
        super();
        this.socket = socket;
        this.timeout = socket.getSoTimeout();
        this.wrappedHost = host;
        this.wrappedPort = port;
        this.autoClose = autoClose;
        init(sslParameters);
    }

    /**
     * Initialize the SSL socket and set the certificates for the
     * future handshaking.
     */
    private void init(SSLParameters sslParameters) throws IOException {
        init(sslParameters,
             NativeCrypto.getSupportedProtocols(),
             NativeCrypto.getDefaultCipherSuites());
    }

    /**
     * Initialize the SSL socket and set the certificates for the
     * future handshaking.
     */
    private void init(SSLParameters sslParameters,
                      String[] enabledProtocols,
                      String[] enabledCipherSuites) throws IOException {
        this.sslParameters = sslParameters;
        this.enabledProtocols = enabledProtocols;
        this.enabledCipherSuites = enabledCipherSuites;
        updateInstanceCount(1);
    }

    /**
     * Gets the suitable session reference from the session cache container.
     *
     * @return OpenSSLSessionImpl
     */
    private OpenSSLSessionImpl getCachedClientSession(ClientSessionContext sessionContext) {
        if (super.getInetAddress() == null ||
                super.getInetAddress().getHostAddress() == null ||
                super.getInetAddress().getHostName() == null) {
            return null;
        }
        OpenSSLSessionImpl session = (OpenSSLSessionImpl) sessionContext.getSession(
                super.getInetAddress().getHostName(),
                super.getPort());
        if (session == null) {
            return null;
        }

        String protocol = session.getProtocol();
        boolean protocolFound = false;
        for (String enabledProtocol : enabledProtocols) {
            if (protocol.equals(enabledProtocol)) {
                protocolFound = true;
                break;
            }
        }
        if (!protocolFound) {
            return null;
        }

        String cipherSuite = session.getCipherSuite();
        boolean cipherSuiteFound = false;
        for (String enabledCipherSuite : enabledCipherSuites) {
            if (cipherSuite.equals(enabledCipherSuite)) {
                cipherSuiteFound = true;
                break;
            }
        }
        if (!cipherSuiteFound) {
            return null;
        }

        return session;
    }

    /**
     * Ensures that logger is lazily loaded. The outer class seems to load
     * before logging is ready.
     */
    static class LoggerHolder {
        static final Logger logger = Logger.getLogger(OpenSSLSocketImpl.class.getName());
    }

    /**
     * Starts a TLS/SSL handshake on this connection using some native methods
     * from the OpenSSL library. It can negotiate new encryption keys, change
     * cipher suites, or initiate a new session. The certificate chain is
     * verified if the correspondent property in java.Security is set. All
     * listeners are notified at the end of the TLS/SSL handshake.
     *
     * @throws <code>IOException</code> if network fails
     */
    public void startHandshake() throws IOException {
        startHandshake(true);
    }

    /**
     * Perform the handshake
     * @param full If true, disable handshake cutthrough for a fully synchronous handshake
     */
    public synchronized void startHandshake(boolean full) throws IOException {
        synchronized (handshakeLock) {
            if (!handshakeStarted) {
                handshakeStarted = true;
            } else {
                return;
            }
        }

        // note that this modifies the global seed, not something specific to the connection
        final int seedLengthInBytes = NativeCrypto.RAND_SEED_LENGTH_IN_BYTES;
        final SecureRandom secureRandom = sslParameters.getSecureRandomMember();
        if (secureRandom == null) {
            NativeCrypto.RAND_load_file("/dev/urandom", seedLengthInBytes);
        } else {
            NativeCrypto.RAND_seed(secureRandom.generateSeed(seedLengthInBytes));
        }

        final boolean client = sslParameters.getUseClientMode();

        final int sslCtxNativePointer = (client) ?
            sslParameters.getClientSessionContext().sslCtxNativePointer :
            sslParameters.getServerSessionContext().sslCtxNativePointer;

        this.sslNativePointer = NativeCrypto.SSL_new(sslCtxNativePointer);

        // setup server certificates and private keys.
        // clients will receive a call back to request certificates.
        if (!client) {
            for (String keyType : NativeCrypto.KEY_TYPES) {
                setCertificate(sslParameters.getKeyManager().chooseServerAlias(keyType,
                                                                               null,
                                                                               null));
            }
        }

        NativeCrypto.setEnabledProtocols(sslNativePointer, enabledProtocols);
        NativeCrypto.setEnabledCipherSuites(sslNativePointer, enabledCipherSuites);

        boolean enableSessionCreation = sslParameters.getEnableSessionCreation();
        if (!enableSessionCreation) {
            NativeCrypto.SSL_set_session_creation_enabled(sslNativePointer,
                                                          enableSessionCreation);
        }

        AbstractSessionContext sessionContext;
        OpenSSLSessionImpl session;
        if (client) {
            // look for client session to reuse
            ClientSessionContext clientSessionContext = sslParameters.getClientSessionContext();
            sessionContext = clientSessionContext;
            session = getCachedClientSession(clientSessionContext);
            if (session != null) {
                NativeCrypto.SSL_set_session(sslNativePointer,  session.sslSessionNativePointer);
            }
        } else {
            sessionContext = sslParameters.getServerSessionContext();
            session = null;
        }

        // setup peer certificate verification
        if (client) {
            // TODO support for anonymous cipher would require us to
            // conditionally use SSL_VERIFY_NONE
        } else {
            // needing client auth takes priority...
            if (sslParameters.getNeedClientAuth()) {
                NativeCrypto.SSL_set_verify(sslNativePointer,
                                            NativeCrypto.SSL_VERIFY_PEER|
                                            NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
                                            NativeCrypto.SSL_VERIFY_CLIENT_ONCE);
            // ... over just wanting it...
            } else if (sslParameters.getWantClientAuth()) {
                NativeCrypto.SSL_set_verify(sslNativePointer,
                                            NativeCrypto.SSL_VERIFY_PEER|
                                            NativeCrypto.SSL_VERIFY_CLIENT_ONCE);
            }
            // ... and it defaults properly so we don't need call SSL_set_verify in the common case.
        }

        if (client && full) {
            // we want to do a full synchronous handshake, so turn off cutthrough
            NativeCrypto.SSL_clear_mode(sslNativePointer,
                                        NativeCrypto.SSL_MODE_HANDSHAKE_CUTTHROUGH);
        }

        // BEGIN android-added
        // Temporarily use a different timeout for the handshake process
        int savedTimeout = timeout;
        if (handshakeTimeout >= 0) {
            setSoTimeout(handshakeTimeout);
        }
        // END android-added


        Socket socket = this.socket != null ? this.socket : this;
        int sslSessionNativePointer;
        try {
            sslSessionNativePointer
                = NativeCrypto.SSL_do_handshake(sslNativePointer, socket, this, timeout, client);
        } catch (CertificateException e) {
            throw new SSLPeerUnverifiedException(e.getMessage());
        }
        byte[] sessionId = NativeCrypto.SSL_SESSION_session_id(sslSessionNativePointer);
        sslSession = (OpenSSLSessionImpl) sessionContext.getSession(sessionId);
        if (sslSession != null) {
            sslSession.lastAccessedTime = System.currentTimeMillis();
            LoggerHolder.logger.fine("Reused cached session for "
                                     + getInetAddress() + ".");
            NativeCrypto.SSL_SESSION_free(sslSessionNativePointer);
        } else {
            if (!enableSessionCreation) {
                // Should have been prevented by NativeCrypto.SSL_set_session_creation_enabled
                throw new IllegalStateException("SSL Session may not be created");
            }
            byte[][] localCertificatesBytes = NativeCrypto.SSL_get_certificate(sslNativePointer);
            X509Certificate[] localCertificates;
            if (localCertificatesBytes == null) {
                localCertificates = null;
            } else {
                localCertificates = new X509Certificate[localCertificatesBytes.length];
                for (int i = 0; i < localCertificatesBytes.length; i++) {
                    try {
                        // TODO do not go through PEM decode, DER encode, DER decode
                        localCertificates[i]
                            = new X509CertImpl(
                                javax.security.cert.X509Certificate.getInstance(
                                    localCertificatesBytes[i]).getEncoded());
                    } catch (javax.security.cert.CertificateException e) {
                        throw new IOException("Problem decoding local certificate", e);
                    }
                }
            }

            if (wrappedHost == null) {
                sslSession = new OpenSSLSessionImpl(sslSessionNativePointer, localCertificates,
                                                    super.getInetAddress().getHostName(),
                                                    super.getPort(), sessionContext);
            } else  {
                sslSession = new OpenSSLSessionImpl(sslSessionNativePointer, localCertificates,
                                                    wrappedHost, wrappedPort,
                                                    sessionContext);
            }
            // if not, putSession later in handshakeCompleted() callback
            if (handshakeCompleted) {
                sessionContext.putSession(sslSession);
            }
            LoggerHolder.logger.fine("Created new session for "
                                     + getInetAddress().getHostName() + ".");
        }

        // BEGIN android-added
        // Restore the original timeout now that the handshake is complete
        if (handshakeTimeout >= 0) {
            setSoTimeout(savedTimeout);
        }
        // END android-added

        // if not, notifyHandshakeCompletedListeners later in handshakeCompleted() callback
        if (handshakeCompleted) {
            notifyHandshakeCompletedListeners();
        }

    }

    private void setCertificate (String alias) throws IOException {
        if (alias == null) {
            return;
        }

        PrivateKey privateKey = sslParameters.getKeyManager().getPrivateKey(alias);
        byte[] privateKeyBytes = privateKey.getEncoded();
        NativeCrypto.SSL_use_PrivateKey(sslNativePointer, privateKeyBytes);

        X509Certificate[] certificates = sslParameters.getKeyManager().getCertificateChain(alias);
        byte[][] certificateBytes = new byte[certificates.length][];
        for (int i = 0; i < certificates.length; i++) {
            try {
                certificateBytes[i] = certificates[i].getEncoded();
            } catch (CertificateEncodingException e) {
                throw new IOException("Problem encoding certificate " + certificates[i], e);
            }
        }
        // TODO SSL_use_certificate only looks at the first certificate in the chain.
        // It would be better to use a custom version of SSL_CTX_use_certificate_chain_file
        // to set the whole chain. Note there is no SSL_ equivalent of this SSL_CTX_ function.
        NativeCrypto.SSL_use_certificate(sslNativePointer, certificateBytes);

        // checks the last installed private key and certificate,
        // so need to do this once per loop iteration
        NativeCrypto.SSL_check_private_key(sslNativePointer);
    }

    /**
     * Implementation of NativeCrypto.SSLHandshakeCallbacks
     * invoked via JNI from client_cert_cb
     */
    public void clientCertificateRequested(String keyType) throws IOException {
        setCertificate(sslParameters.getKeyManager().chooseClientAlias(new String[] { keyType },
                                                                       null,
                                                                       null));
    }

    /**
     * Implementation of NativeCrypto.SSLHandshakeCallbacks
     * invoked via JNI from info_callback
     */
    public void handshakeCompleted() {
        handshakeCompleted = true;

        // If sslSession is null, the handshake was completed during
        // the call to NativeCrypto.SSL_do_handshake and not during a
        // later read operation. That means we do not need to fixup
        // the SSLSession and session cache or notify
        // HandshakeCompletedListeners, it will be done in
        // startHandshake.
        if (sslSession == null) {
            return;
        }

        // reset session id from the native pointer and update the
        // appropriate cache.
        sslSession.resetId();
        AbstractSessionContext sessionContext =
            (sslParameters.getUseClientMode())
            ? sslParameters.getClientSessionContext()
                : sslParameters.getServerSessionContext();
        sessionContext.putSession(sslSession);

        // let listeners know we are finally done
        notifyHandshakeCompletedListeners();
    }

    private void notifyHandshakeCompletedListeners() {
        if (listeners != null && !listeners.isEmpty()) {
            // notify the listeners
            HandshakeCompletedEvent event =
                new HandshakeCompletedEvent(this, sslSession);
            for (HandshakeCompletedListener listener : listeners) {
                try {
                    listener.handshakeCompleted(event);
                } catch (RuntimeException e) {
                    // The RI runs the handlers in a separate thread,
                    // which we do not. But we try to preserve their
                    // behavior of logging a problem and not killing
                    // the handshaking thread just because a listener
                    // has a problem.
                    Thread thread = Thread.currentThread();
                    thread.getUncaughtExceptionHandler().uncaughtException(thread, e);
                }
            }
        }
    }

    /**
     * Implementation of NativeCrypto.SSLHandshakeCallbacks
     *
     * @param bytes An array of certficates in PEM encode bytes
     * @param authMethod auth algorithm name
     *
     * @throws CertificateException if the certificate is untrusted
     */
    @SuppressWarnings("unused")
    public void verifyCertificateChain(byte[][] bytes, String authMethod)
            throws CertificateException {
        try {
            if (bytes == null || bytes.length == 0) {
                throw new SSLException("Peer sent no certificate");
            }
            X509Certificate[] peerCertificateChain = new X509Certificate[bytes.length];
            for (int i = 0; i < bytes.length; i++) {
                peerCertificateChain[i] =
                    new X509CertImpl(
                        javax.security.cert.X509Certificate.getInstance(bytes[i]).getEncoded());
            }
            boolean client = sslParameters.getUseClientMode();
            if (client) {
                sslParameters.getTrustManager().checkServerTrusted(peerCertificateChain,
                                                                   authMethod);
            } else {
                sslParameters.getTrustManager().checkClientTrusted(peerCertificateChain,
                                                                   authMethod);
            }

        } catch (CertificateException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Returns an input stream for this SSL socket using native calls to the
     * OpenSSL library.
     *
     * @return: an input stream for reading bytes from this socket.
     * @throws: <code>IOException</code> if an I/O error occurs when creating
     *          the input stream, the socket is closed, the socket is not
     *          connected, or the socket input has been shutdown.
     */
    public InputStream getInputStream() throws IOException {
        synchronized(this) {
            if (is == null) {
                is = new SSLInputStream();
            }

            return is;
        }
    }

    /**
     * Returns an output stream for this SSL socket using native calls to the
     * OpenSSL library.
     *
     * @return an output stream for writing bytes to this socket.
     * @throws <code>IOException</code> if an I/O error occurs when creating
     *             the output stream, or no connection to the socket exists.
     */
    public OutputStream getOutputStream() throws IOException {
        synchronized(this) {
            if (os == null) {
                os = new SSLOutputStream();
            }

            return os;
        }
    }

    /**
     * This method is not supported for this SSLSocket implementation
     * because reading from an SSLSocket may involve writing to the
     * network.
     */
    public void shutdownInput() throws IOException {
        throw new UnsupportedOperationException();
    }

    /**
     * This method is not supported for this SSLSocket implementation
     * because writing to an SSLSocket may involve reading from the
     * network.
     */
    public void shutdownOutput() throws IOException {
        throw new UnsupportedOperationException();
    }

    /**
     * This inner class provides input data stream functionality
     * for the OpenSSL native implementation. It is used to
     * read data received via SSL protocol.
     */
    private class SSLInputStream extends InputStream {
        SSLInputStream() throws IOException {
            /**
            /* Note: When startHandshake() throws an exception, no
             * SSLInputStream object will be created.
             */
            OpenSSLSocketImpl.this.startHandshake(false);
        }

        /**
         * Reads one byte. If there is no data in the underlying buffer,
         * this operation can block until the data will be
         * available.
         * @return read value.
         * @throws <code>IOException</code>
         */
        public int read() throws IOException {
            synchronized(readLock) {
                return NativeCrypto.SSL_read_byte(sslNativePointer, timeout);
            }
        }

        /**
         * Method acts as described in spec for superclass.
         * @see java.io.InputStream#read(byte[],int,int)
         */
        public int read(byte[] b, int off, int len) throws IOException {
            synchronized(readLock) {
                return NativeCrypto.SSL_read(sslNativePointer, b, off, len, timeout);
            }
        }
    }

    /**
     * This inner class provides output data stream functionality
     * for the OpenSSL native implementation. It is used to
     * write data according to the encryption parameters given in SSL context.
     */
    private class SSLOutputStream extends OutputStream {
        SSLOutputStream() throws IOException {
            /**
            /* Note: When startHandshake() throws an exception, no
             * SSLOutputStream object will be created.
             */
            OpenSSLSocketImpl.this.startHandshake(false);
        }

        /**
         * Method acts as described in spec for superclass.
         * @see java.io.OutputStream#write(int)
         */
        public void write(int b) throws IOException {
            synchronized(writeLock) {
                NativeCrypto.SSL_write_byte(sslNativePointer, b);
            }
        }

        /**
         * Method acts as described in spec for superclass.
         * @see java.io.OutputStream#write(byte[],int,int)
         */
        public void write(byte[] b, int start, int len) throws IOException {
            synchronized(writeLock) {
                NativeCrypto.SSL_write(sslNativePointer, b, start, len);
            }
        }
    }


    /**
     * The SSL session used by this connection is returned. The SSL session
     * determines which cipher suite should be used by all connections within
     * that session and which identities have the session's client and server.
     * This method starts the SSL handshake.
     * @return the SSLSession.
     * @throws <code>IOException</code> if the handshake fails
     */
    public SSLSession getSession() {
        try {
            startHandshake(true);
        } catch (IOException e) {
            // return an invalid session with
            // invalid cipher suite of "SSL_NULL_WITH_NULL_NULL"
            return SSLSessionImpl.NULL_SESSION;
        }
        return sslSession;
    }

    /**
     * Registers a listener to be notified that a SSL handshake
     * was successfully completed on this connection.
     * @throws <code>IllegalArgumentException</code> if listener is null.
     */
    public void addHandshakeCompletedListener(
            HandshakeCompletedListener listener) {
        if (listener == null) {
            throw new IllegalArgumentException("Provided listener is null");
        }
        if (listeners == null) {
            listeners = new ArrayList();
        }
        listeners.add(listener);
    }

    /**
     * The method removes a registered listener.
     * @throws IllegalArgumentException if listener is null or not registered
     */
    public void removeHandshakeCompletedListener(
            HandshakeCompletedListener listener) {
        if (listener == null) {
            throw new IllegalArgumentException("Provided listener is null");
        }
        if (listeners == null) {
            throw new IllegalArgumentException(
                    "Provided listener is not registered");
        }
        if (!listeners.remove(listener)) {
            throw new IllegalArgumentException(
                    "Provided listener is not registered");
        }
    }

    /**
     * Returns true if new SSL sessions may be established by this socket.
     *
     * @return true if the session may be created; false if a session already
     *         exists and must be resumed.
     */
    public boolean getEnableSessionCreation() {
        return sslParameters.getEnableSessionCreation();
    }

    /**
     * Set a flag for the socket to inhibit or to allow the creation of a new
     * SSL sessions. If the flag is set to false, and there are no actual
     * sessions to resume, then there will be no successful handshaking.
     *
     * @param flag true if session may be created; false
     *            if a session already exists and must be resumed.
     */
    public void setEnableSessionCreation(boolean flag) {
        sslParameters.setEnableSessionCreation(flag);
    }

    /**
     * The names of the cipher suites which could be used by the SSL connection
     * are returned.
     * @return an array of cipher suite names
     */
    public String[] getSupportedCipherSuites() {
        return NativeCrypto.getSupportedCipherSuites();
    }

    /**
     * The names of the cipher suites that are in use in the actual the SSL
     * connection are returned.
     *
     * @return an array of cipher suite names
     */
    public String[] getEnabledCipherSuites() {
        return enabledCipherSuites.clone();
    }

    /**
     * This method enables the cipher suites listed by
     * getSupportedCipherSuites().
     *
     * @param suites names of all the cipher suites to
     *            put on use
     * @throws IllegalArgumentException when one or more of the
     *             ciphers in array suites are not supported, or when the array
     *             is null.
     */
    public void setEnabledCipherSuites(String[] suites) {
        enabledCipherSuites = NativeCrypto.checkEnabledCipherSuites(suites);
    }

    /**
     * The names of the protocols' versions that may be used on this SSL
     * connection.
     * @return an array of protocols names
     */
    public String[] getSupportedProtocols() {
        return NativeCrypto.getSupportedProtocols();
    }

    /**
     * The names of the protocols' versions that are in use on this SSL
     * connection.
     *
     * @return an array of protocols names
     */
    @Override
    public String[] getEnabledProtocols() {
        return enabledProtocols.clone();
    }

    /**
     * This method enables the protocols' versions listed by
     * getSupportedProtocols().
     *
     * @param protocols The names of all the protocols to put on use
     *
     * @throws IllegalArgumentException when one or more of the names in the
     *             array are not supported, or when the array is null.
     */
    @Override
    public synchronized void setEnabledProtocols(String[] protocols) {
        enabledProtocols = NativeCrypto.checkEnabledProtocols(protocols);
    }

    /**
     * This method gives true back if the SSL socket is set to client mode.
     *
     * @return true if the socket should do the handshaking as client.
     */
    public boolean getUseClientMode() {
        return sslParameters.getUseClientMode();
    }

    /**
     * This method set the actual SSL socket to client mode.
     *
     * @param mode true if the socket starts in client
     *            mode
     * @throws IllegalArgumentException if mode changes during
     *             handshake.
     */
    public synchronized void setUseClientMode(boolean mode) {
        if (handshakeStarted) {
            throw new IllegalArgumentException(
            "Could not change the mode after the initial handshake has begun.");
        }
        sslParameters.setUseClientMode(mode);
    }

    /**
     * Returns true if the SSL socket requests client's authentication. Relevant
     * only for server sockets!
     *
     * @return true if client authentication is desired, false if not.
     */
    public boolean getWantClientAuth() {
        return sslParameters.getWantClientAuth();
    }

    /**
     * Returns true if the SSL socket needs client's authentication. Relevant
     * only for server sockets!
     *
     * @return true if client authentication is desired, false if not.
     */
    public boolean getNeedClientAuth() {
        return sslParameters.getNeedClientAuth();
    }

    /**
     * Sets the SSL socket to use client's authentication. Relevant only for
     * server sockets!
     *
     * @param need true if client authentication is
     *            desired, false if not.
     */
    public void setNeedClientAuth(boolean need) {
        sslParameters.setNeedClientAuth(need);
    }

    /**
     * Sets the SSL socket to use client's authentication. Relevant only for
     * server sockets! Notice that in contrast to setNeedClientAuth(..) this
     * method will continue the negotiation if the client decide not to send
     * authentication credentials.
     *
     * @param want true if client authentication is
     *            desired, false if not.
     */
    public void setWantClientAuth(boolean want) {
        sslParameters.setWantClientAuth(want);
    }

    /**
     * This method is not supported for SSLSocket implementation.
     */
    public void sendUrgentData(int data) throws IOException {
        throw new SocketException(
                "Method sendUrgentData() is not supported.");
    }

    /**
     * This method is not supported for SSLSocket implementation.
     */
    public void setOOBInline(boolean on) throws SocketException {
        throw new SocketException(
                "Methods sendUrgentData, setOOBInline are not supported.");
    }

    /**
     * Set the read timeout on this socket. The SO_TIMEOUT option, is specified
     * in milliseconds. The read operation will block indefinitely for a zero
     * value.
     *
     * @param timeout the read timeout value
     * @throws SocketException if an error occurs setting the option
     */
    public synchronized void setSoTimeout(int timeout) throws SocketException {
        super.setSoTimeout(timeout);
        this.timeout = timeout;
    }

    // BEGIN android-added
    /**
     * Set the handshake timeout on this socket.  This timeout is specified in
     * milliseconds and will be used only during the handshake process.
     *
     * @param timeout the handshake timeout value
     */
    public synchronized void setHandshakeTimeout(int timeout) throws SocketException {
        this.handshakeTimeout = timeout;
    }
    // END android-added

    /**
     * Closes the SSL socket. Once closed, a socket is not available for further
     * use anymore under any circumstance. A new socket must be created.
     *
     * @throws <code>IOException</code> if an I/O error happens during the
     *             socket's closure.
     */
    public void close() throws IOException {
        // TODO: Close SSL sockets using a background thread so they close
        // gracefully.

        synchronized (handshakeLock) {
            if (!handshakeStarted) {
                // prevent further attemps to start handshake
                handshakeStarted = true;

                synchronized (this) {
                    free();

                    if (socket != null) {
                        if (autoClose && !socket.isClosed()) socket.close();
                    } else {
                        if (!super.isClosed()) super.close();
                    }
                }

                return;
            }
        }

        NativeCrypto.SSL_interrupt(sslNativePointer);

        synchronized (this) {
            synchronized (writeLock) {
                synchronized (readLock) {

                    IOException pendingException = null;

                    // Shut down the SSL connection, per se.
                    try {
                        if (handshakeStarted) {
                            NativeCrypto.SSL_shutdown(sslNativePointer);
                        }
                    } catch (IOException ex) {
                        /*
                         * Note the exception at this point, but try to continue
                         * to clean the rest of this all up before rethrowing.
                         */
                        pendingException = ex;
                    }

                    /*
                     * Even if the above call failed, it is still safe to free
                     * the native structs, and we need to do so lest we leak
                     * memory.
                     */
                    free();

                    if (socket != null) {
                        if (autoClose && !socket.isClosed())
                            socket.close();
                    } else {
                        if (!super.isClosed())
                            super.close();
                    }

                    if (pendingException != null) {
                        throw pendingException;
                    }
                }
            }
        }
    }

    private void free() {
        if (sslNativePointer == 0) {
            return;
        }
        NativeCrypto.SSL_free(sslNativePointer);
        sslNativePointer = 0;
    }

    protected void finalize() throws IOException {
        /*
         * Just worry about our own state. Notably we do not try and
         * close anything. The SocketImpl, either our own
         * PlainSocketImpl, or the Socket we are wrapping, will do
         * that. This might mean we do not properly SSL_shutdown, but
         * if you want to do that, properly close the socket yourself.
         *
         * The reason why we don't try to SSL_shutdown, is that there
         * can be a race between finalizers where the PlainSocketImpl
         * finalizer runs first and closes the socket. However, in the
         * meanwhile, the underlying file descriptor could be reused
         * for another purpose. If we call SSL_shutdown, the
         * underlying socket BIOs still have the old file descriptor
         * and will write the close notify to some unsuspecting
         * reader.
         */
        updateInstanceCount(-1);
        free();
    }
}
