/*
 * Copyright 1996-2007 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */


package sun.security.ssl;

import java.io.*;
import java.net.*;
import java.security.GeneralSecurityException;
import java.security.AccessController;
import java.security.AccessControlContext;
import java.security.PrivilegedAction;
import java.util.*;

import javax.crypto.BadPaddingException;

import javax.net.ssl.*;

import com.sun.net.ssl.internal.ssl.X509ExtendedTrustManager;

/**
 * Implementation of an SSL socket.  This is a normal connection type
 * socket, implementing SSL over some lower level socket, such as TCP.
 * Because it is layered over some lower level socket, it MUST override
 * all default socket methods.
 *
 * <P> This API offers a non-traditional option for establishing SSL
 * connections.  You may first establish the connection directly, then pass
 * that connection to the SSL socket constructor with a flag saying which
 * role should be taken in the handshake protocol.  (The two ends of the
 * connection must not choose the same role!)  This allows setup of SSL
 * proxying or tunneling, and also allows the kind of "role reversal"
 * that is required for most FTP data transfers.
 *
 * @see javax.net.ssl.SSLSocket
 * @see SSLServerSocket
 *
 * @author David Brownell
 */
final public class SSLSocketImpl extends BaseSSLSocketImpl {

    /*
     * ERROR HANDLING GUIDELINES
     * (which exceptions to throw and catch and which not to throw and catch)
     *
     * . if there is an IOException (SocketException) when accessing the
     *   underlying Socket, pass it through
     *
     * . do not throw IOExceptions, throw SSLExceptions (or a subclass)
     *
     * . for internal errors (things that indicate a bug in JSSE or a
     *   grossly misconfigured J2RE), throw either an SSLException or
     *   a RuntimeException at your convenience.
     *
     * . handshaking code (Handshaker or HandshakeMessage) should generally
     *   pass through exceptions, but can handle them if they know what to
     *   do.
     *
     * . exception chaining should be used for all new code. If you happen
     *   to touch old code that does not use chaining, you should change it.
     *
     * . there is a top level exception handler that sits at all entry
     *   points from application code to SSLSocket read/write code. It
     *   makes sure that all errors are handled (see handleException()).
     *
     * . JSSE internal code should generally not call close(), call
     *   closeInternal().
     */

    /*
     * There's a state machine associated with each connection, which
     * among other roles serves to negotiate session changes.
     *
     * - START with constructor, until the TCP connection's around.
     * - HANDSHAKE picks session parameters before allowing traffic.
     *          There are many substates due to sequencing requirements
     *          for handshake messages.
     * - DATA may be transmitted.
     * - RENEGOTIATE state allows concurrent data and handshaking
     *          traffic ("same" substates as HANDSHAKE), and terminates
     *          in selection of new session (and connection) parameters
     * - ERROR state immediately precedes abortive disconnect.
     * - SENT_CLOSE sent a close_notify to the peer. For layered,
     *          non-autoclose socket, must now read close_notify
     *          from peer before closing the connection. For nonlayered or
     *          non-autoclose socket, close connection and go onto
     *          cs_CLOSED state.
     * - CLOSED after sending close_notify alert, & socket is closed.
     *          SSL connection objects are not reused.
     * - APP_CLOSED once the application calls close(). Then it behaves like
     *          a closed socket, e.g.. getInputStream() throws an Exception.
     *
     * State affects what SSL record types may legally be sent:
     *
     * - Handshake ... only in HANDSHAKE and RENEGOTIATE states
     * - App Data ... only in DATA and RENEGOTIATE states
     * - Alert ... in HANDSHAKE, DATA, RENEGOTIATE
     *
     * Re what may be received:  same as what may be sent, except that
     * HandshakeRequest handshaking messages can come from servers even
     * in the application data state, to request entry to RENEGOTIATE.
     *
     * The state machine within HANDSHAKE and RENEGOTIATE states controls
     * the pending session, not the connection state, until the change
     * cipher spec and "Finished" handshake messages are processed and
     * make the "new" session become the current one.
     *
     * NOTE: details of the SMs always need to be nailed down better.
     * The text above illustrates the core ideas.
     *
     *                +---->-------+------>--------->-------+
     *                |            |                        |
     *     <-----<    ^            ^  <-----<               v
     *START>----->HANDSHAKE>----->DATA>----->RENEGOTIATE  SENT_CLOSE
     *                v            v               v        |   |
     *                |            |               |        |   v
     *                +------------+---------------+        v ERROR
     *                |                                     |   |
     *                v                                     |   |
     *               ERROR>------>----->CLOSED<--------<----+-- +
     *                                     |
     *                                     v
     *                                 APP_CLOSED
     *
     * ALSO, note that the the purpose of handshaking (renegotiation is
     * included) is to assign a different, and perhaps new, session to
     * the connection.  The SSLv3 spec is a bit confusing on that new
     * protocol feature.
     */
    private static final int    cs_START = 0;
    private static final int    cs_HANDSHAKE = 1;
    private static final int    cs_DATA = 2;
    private static final int    cs_RENEGOTIATE = 3;
    private static final int    cs_ERROR = 4;
    private static final int   cs_SENT_CLOSE = 5;
    private static final int    cs_CLOSED = 6;
    private static final int    cs_APP_CLOSED = 7;


    /*
     * Client authentication be off, requested, or required.
     *
     * Migrated to SSLEngineImpl:
     *    clauth_none/cl_auth_requested/clauth_required
     */

    /*
     * Drives the protocol state machine.
     */
    private int                 connectionState;

    /*
     * Flag indicating if the next record we receive MUST be a Finished
     * message. Temporarily set during the handshake to ensure that
     * a change cipher spec message is followed by a finished message.
     */
    private boolean             expectingFinished;

    /*
     * For improved diagnostics, we detail connection closure
     * If the socket is closed (connectionState >= cs_ERROR),
     * closeReason != null indicates if the socket was closed
     * because of an error or because or normal shutdown.
     */
    private SSLException        closeReason;

    /*
     * Per-connection private state that doesn't change when the
     * session is changed.
     */
    private byte                doClientAuth;
    private boolean             roleIsServer;
    private CipherSuiteList     enabledCipherSuites;
    private boolean             enableSessionCreation = true;
    private String              host;
    private boolean             autoClose = true;
    private AccessControlContext acc;

    // hostname identification algorithm, the hostname identification is
    // disabled by default.
    private String              identificationAlg = null;

    /*
     * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
     * IMPORTANT STUFF TO UNDERSTANDING THE SYNCHRONIZATION ISSUES.
     * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
     *
     * There are several locks here.
     *
     * The primary lock is the per-instance lock used by
     * synchronized(this) and the synchronized methods.  It controls all
     * access to things such as the connection state and variables which
     * affect handshaking.  If we are inside a synchronized method, we
     * can access the state directly, otherwise, we must use the
     * synchronized equivalents.
     *
     * The handshakeLock is used to ensure that only one thread performs
     * the *complete initial* handshake.  If someone is handshaking, any
     * stray application or startHandshake() requests who find the
     * connection state is cs_HANDSHAKE will stall on handshakeLock
     * until handshaking is done.  Once the handshake is done, we either
     * succeeded or failed, but we can never go back to the cs_HANDSHAKE
     * or cs_START state again.
     *
     * Note that the read/write() calls here in SSLSocketImpl are not
     * obviously synchronized.  In fact, it's very nonintuitive, and
     * requires careful examination of code paths.  Grab some coffee,
     * and be careful with any code changes.
     *
     * There can be only three threads active at a time in the I/O
     * subsection of this class.
     *    1.  startHandshake
     *    2.  AppInputStream
     *    3.  AppOutputStream
     * One thread could call startHandshake().
     * AppInputStream/AppOutputStream read() and write() calls are each
     * synchronized on 'this' in their respective classes, so only one
     * app. thread will be doing a SSLSocketImpl.read() or .write()'s at
     * a time.
     *
     * If handshaking is required (state cs_HANDSHAKE), and
     * getConnectionState() for some/all threads returns cs_HANDSHAKE,
     * only one can grab the handshakeLock, and the rest will stall
     * either on getConnectionState(), or on the handshakeLock if they
     * happen to successfully race through the getConnectionState().
     *
     * If a writer is doing the initial handshaking, it must create a
     * temporary reader to read the responses from the other side.  As a
     * side-effect, the writer's reader will have priority over any
     * other reader.  However, the writer's reader is not allowed to
     * consume any application data.  When handshakeLock is finally
     * released, we either have a cs_DATA connection, or a
     * cs_CLOSED/cs_ERROR socket.
     *
     * The writeLock is held while writing on a socket connection and
     * also to protect the MAC and cipher for their direction.  The
     * writeLock is package private for Handshaker which holds it while
     * writing the ChangeCipherSpec message.
     *
     * To avoid the problem of a thread trying to change operational
     * modes on a socket while handshaking is going on, we synchronize
     * on 'this'.  If handshaking has not started yet, we tell the
     * handshaker to change its mode.  If handshaking has started,
     * we simply store that request until the next pending session
     * is created, at which time the new handshaker's state is set.
     *
     * The readLock is held during readRecord(), which is responsible
     * for reading an InputRecord, decrypting it, and processing it.
     * The readLock ensures that these three steps are done atomically
     * and that once started, no other thread can block on InputRecord.read.
     * This is necessary so that processing of close_notify alerts
     * from the peer are handled properly.
     */
    private Object              handshakeLock;
    Object                      writeLock;
    private Object              readLock;

    private InputRecord         inrec;

    /*
     * Crypto state that's reinitialized when the session changes.
     */
    private MAC                 readMAC, writeMAC;
    private CipherBox           readCipher, writeCipher;
    // NOTE: compression state would be saved here

    /*
     * The authentication context holds all information used to establish
     * who this end of the connection is (certificate chains, private keys,
     * etc) and who is trusted (e.g. as CAs or websites).
     */
    private SSLContextImpl      sslContext;


    /*
     * This connection is one of (potentially) many associated with
     * any given session.  The output of the handshake protocol is a
     * new session ... although all the protocol description talks
     * about changing the cipher spec (and it does change), in fact
     * that's incidental since it's done by changing everything that
     * is associated with a session at the same time.  (TLS/IETF may
     * change that to add client authentication w/o new key exchg.)
     */
    private SSLSessionImpl      sess;
    private Handshaker          handshaker;


    /*
     * If anyone wants to get notified about handshake completions,
     * they'll show up on this list.
     */
    private HashMap<HandshakeCompletedListener, AccessControlContext>
                                                        handshakeListeners;


    /*
     * Reuse the same internal input/output streams.
     */
    private InputStream         sockInput;
    private OutputStream        sockOutput;


    /*
     * These input and output streams block their data in SSL records,
     * and usually arrange integrity and privacy protection for those
     * records.  The guts of the SSL protocol are wrapped up in these
     * streams, and in the handshaking that establishes the details of
     * that integrity and privacy protection.
     */
    private AppInputStream      input;
    private AppOutputStream     output;

    /*
     * The protocols we support are SSL Version 3.0) and
     * TLS (version 3.1).
     * In addition we support a pseudo protocol called
     * SSLv2Hello which when set will result in an SSL v2 Hello
     * being sent with SSLv3 or TLSv1 version info.
     */
    private ProtocolList enabledProtocols;

    /*
     * The SSL version associated with this connection.
     */
    private ProtocolVersion     protocolVersion = ProtocolVersion.DEFAULT;

    /* Class and subclass dynamic debugging support */
    private static final Debug debug = Debug.getInstance("ssl");

    //
    // CONSTRUCTORS AND INITIALIZATION CODE
    //

    /**
     * Constructs an SSL connection to a named host at a specified port,
     * using the authentication context provided.  This endpoint acts as
     * the client, and may rejoin an existing SSL session if appropriate.
     *
     * @param context authentication context to use
     * @param host name of the host with which to connect
     * @param port number of the server's port
     */
    SSLSocketImpl(SSLContextImpl context, String host, int port)
            throws IOException, UnknownHostException {
        super();
        this.host = host;
        init(context, false);
        SocketAddress socketAddress = new InetSocketAddress(host, port);
        connect(socketAddress, 0);
    }


    /**
     * Constructs an SSL connection to a server at a specified address.
     * and TCP port, using the authentication context provided.  This
     * endpoint acts as the client, and may rejoin an existing SSL session
     * if appropriate.
     *
     * @param context authentication context to use
     * @param address the server's host
     * @param port its port
     */
    SSLSocketImpl(SSLContextImpl context, InetAddress host, int port)
            throws IOException {
        super();
        init(context, false);
        SocketAddress socketAddress = new InetSocketAddress(host, port);
        connect(socketAddress, 0);
    }

    /**
     * Constructs an SSL connection to a named host at a specified port,
     * using the authentication context provided.  This endpoint acts as
     * the client, and may rejoin an existing SSL session if appropriate.
     *
     * @param context authentication context to use
     * @param host name of the host with which to connect
     * @param port number of the server's port
     * @param localAddr the local address the socket is bound to
     * @param localPort the local port the socket is bound to
     */
    SSLSocketImpl(SSLContextImpl context, String host, int port,
            InetAddress localAddr, int localPort)
            throws IOException, UnknownHostException {
        super();
        this.host = host;
        init(context, false);
        bind(new InetSocketAddress(localAddr, localPort));
        SocketAddress socketAddress = new InetSocketAddress(host, port);
        connect(socketAddress, 0);
    }


    /**
     * Constructs an SSL connection to a server at a specified address.
     * and TCP port, using the authentication context provided.  This
     * endpoint acts as the client, and may rejoin an existing SSL session
     * if appropriate.
     *
     * @param context authentication context to use
     * @param address the server's host
     * @param port its port
     * @param localAddr the local address the socket is bound to
     * @param localPort the local port the socket is bound to
     */
    SSLSocketImpl(SSLContextImpl context, InetAddress host, int port,
            InetAddress localAddr, int localPort)
            throws IOException {
        super();
        init(context, false);
        bind(new InetSocketAddress(localAddr, localPort));
        SocketAddress socketAddress = new InetSocketAddress(host, port);
        connect(socketAddress, 0);
    }

    /*
     * Package-private constructor used ONLY by SSLServerSocket.  The
     * java.net package accepts the TCP connection after this call is
     * made.  This just initializes handshake state to use "server mode",
     * giving control over the use of SSL client authentication.
     */
    SSLSocketImpl(SSLContextImpl context, boolean serverMode,
            CipherSuiteList suites, byte clientAuth,
            boolean sessionCreation, ProtocolList protocols)
            throws IOException {
        super();
        doClientAuth = clientAuth;
        enableSessionCreation = sessionCreation;
        init(context, serverMode);

        /*
         * Override what was picked out for us.
         */
        enabledCipherSuites = suites;
        enabledProtocols = protocols;
    }


    /**
     * Package-private constructor used to instantiate an unconnected
     * socket. The java.net package will connect it, either when the
     * connect() call is made by the application.  This instance is
     * meant to set handshake state to use "client mode".
     */
    SSLSocketImpl(SSLContextImpl context) {
        super();
        init(context, false);
    }


    /**
     * Layer SSL traffic over an existing connection, rather than creating
     * a new connection.  The existing connection may be used only for SSL
     * traffic (using this SSLSocket) until the SSLSocket.close() call
     * returns. However, if a protocol error is detected, that existing
     * connection is automatically closed.
     *
     * <P> This particular constructor always uses the socket in the
     * role of an SSL client. It may be useful in cases which start
     * using SSL after some initial data transfers, for example in some
     * SSL tunneling applications or as part of some kinds of application
     * protocols which negotiate use of a SSL based security.
     *
     * @param sock the existing connection
     * @param context the authentication context to use
     */
    SSLSocketImpl(SSLContextImpl context, Socket sock, String host,
            int port, boolean autoClose) throws IOException {
        super(sock);
        // We always layer over a connected socket
        if (!sock.isConnected()) {
            throw new SocketException("Underlying socket is not connected");
        }
        this.host = host;
        init(context, false);
        this.autoClose = autoClose;
        doneConnect();
    }

    /**
     * Initializes the client socket.
     */
    private void init(SSLContextImpl context, boolean isServer) {
        sslContext = context;
        sess = SSLSessionImpl.nullSession;

        /*
         * role is as specified, state is START until after
         * the low level connection's established.
         */
        roleIsServer = isServer;
        connectionState = cs_START;

        /*
         * default read and write side cipher and MAC support
         *
         * Note:  compression support would go here too
         */
        readCipher = CipherBox.NULL;
        readMAC = MAC.NULL;
        writeCipher = CipherBox.NULL;
        writeMAC = MAC.NULL;

        enabledCipherSuites = CipherSuiteList.getDefault();
        enabledProtocols = ProtocolList.getDefault();
        handshakeLock = new Object();
        writeLock = new Object();
        readLock = new Object();
        inrec = null;

        // save the acc
        acc = AccessController.getContext();

        input = new AppInputStream(this);
        output = new AppOutputStream(this);
    }

    /**
     * Connects this socket to the server with a specified timeout
     * value.
     *
     * This method is either called on an unconnected SSLSocketImpl by the
     * application, or it is called in the constructor of a regular
     * SSLSocketImpl. If we are layering on top on another socket, then
     * this method should not be called, because we assume that the
     * underlying socket is already connected by the time it is passed to
     * us.
     *
     * @param   endpoint the <code>SocketAddress</code>
     * @param   timeout  the timeout value to be used, 0 is no timeout
     * @throws  IOException if an error occurs during the connection
     * @throws  SocketTimeoutException if timeout expires before connecting
     */
    public void connect(SocketAddress endpoint, int timeout)
            throws IOException {

        if (self != this) {
            throw new SocketException("Already connected");
        }

        if (!(endpoint instanceof InetSocketAddress)) {
            throw new SocketException(
                                  "Cannot handle non-Inet socket addresses.");
        }

        super.connect(endpoint, timeout);
        doneConnect();
    }

    /**
     * Initialize the handshaker and socket streams.
     *
     * Called by connect, the layered constructor, and SSLServerSocket.
     */
    void doneConnect() throws IOException {
        /*
         * Save the input and output streams.  May be done only after
         * java.net actually connects using the socket "self", else
         * we get some pretty bizarre failure modes.
         */
        if (self == this) {
            sockInput = super.getInputStream();
            sockOutput = super.getOutputStream();
        } else {
            sockInput = self.getInputStream();
            sockOutput = self.getOutputStream();
        }

        /*
         * Move to handshaking state, with pending session initialized
         * to defaults and the appropriate kind of handshaker set up.
         */
        initHandshaker();
    }

    synchronized private int getConnectionState() {
        return connectionState;
    }

    synchronized private void setConnectionState(int state) {
        connectionState = state;
    }

    AccessControlContext getAcc() {
        return acc;
    }

    //
    // READING AND WRITING RECORDS
    //

    /*
     * Record Output. Application data can't be sent until the first
     * handshake establishes a session.
     *
     * NOTE:  we let empty records be written as a hook to force some
     * TCP-level activity, notably handshaking, to occur.
     */
    void writeRecord(OutputRecord r) throws IOException {
        /*
         * The loop is in case of HANDSHAKE --> ERROR transitions, etc
         */
    loop:
        while (r.contentType() == Record.ct_application_data) {
            /*
             * Not all states support passing application data.  We
             * synchronize access to the connection state, so that
             * synchronous handshakes can complete cleanly.
             */
            switch (getConnectionState()) {

            /*
             * We've deferred the initial handshaking till just now,
             * when presumably a thread's decided it's OK to block for
             * longish periods of time for I/O purposes (as well as
             * configured the cipher suites it wants to use).
             */
            case cs_HANDSHAKE:
                performInitialHandshake();
                break;

            case cs_DATA:
            case cs_RENEGOTIATE:
                break loop;

            case cs_ERROR:
                fatal(Alerts.alert_close_notify,
                    "error while writing to socket");
                break; // dummy

            case cs_SENT_CLOSE:
            case cs_CLOSED:
            case cs_APP_CLOSED:
                // we should never get here (check in AppOutputStream)
                // this is just a fallback
                if (closeReason != null) {
                    throw closeReason;
                } else {
                    throw new SocketException("Socket closed");
                }

            /*
             * Else something's goofy in this state machine's use.
             */
            default:
                throw new SSLProtocolException("State error, send app data");
            }
        }

        //
        // Don't bother to really write empty records.  We went this
        // far to drive the handshake machinery, for correctness; not
        // writing empty records improves performance by cutting CPU
        // time and network resource usage.  However, some protocol
        // implementations are fragile and don't like to see empty
        // records, so this also increases robustness.
        //
        synchronized (writeLock) {
            if (!r.isEmpty()) {
                // r.compress(c);
                r.addMAC(writeMAC);
                r.encrypt(writeCipher);
                r.write(sockOutput);
            }
        }
    }


    /*
     * Read an application data record.  Alerts and handshake
     * messages are handled directly.
     */
    void readDataRecord(InputRecord r) throws IOException {
        if (getConnectionState() == cs_HANDSHAKE) {
            performInitialHandshake();
        }
        readRecord(r, true);
    }


    /*
     * Clear the pipeline of records from the peer, optionally returning
     * application data.   Caller is responsible for knowing that it's
     * possible to do this kind of clearing, if they don't want app
     * data -- e.g. since it's the initial SSL handshake.
     *
     * Don't synchronize (this) during a blocking read() since it
     * protects data which is accessed on the write side as well.
     */
    private void readRecord(InputRecord r, boolean needAppData)
            throws IOException {
        int state;

        // readLock protects reading and processing of an InputRecord.
        // It keeps the reading from sockInput and processing of the record
        // atomic so that no two threads can be blocked on the
        // read from the same input stream at the same time.
        // This is required for example when a reader thread is
        // blocked on the read and another thread is trying to
        // close the socket. For a non-autoclose, layered socket,
        // the thread performing the close needs to read the close_notify.
        //
        // Use readLock instead of 'this' for locking because
        // 'this' also protects data accessed during writing.
      synchronized (readLock) {
        /*
         * Read and handle records ... return application data
         * ONLY if it's needed.
         */

        while (((state = getConnectionState()) != cs_CLOSED) &&
                (state != cs_ERROR) && (state != cs_APP_CLOSED)) {
            /*
             * Read a record ... maybe emitting an alert if we get a
             * comprehensible but unsupported "hello" message during
             * format checking (e.g. V2).
             */
            try {
                r.setAppDataValid(false);
                r.read(sockInput, sockOutput);
            } catch (SSLProtocolException e) {
                try {
                    fatal(Alerts.alert_unexpected_message, e);
                } catch (IOException x) {
                    // discard this exception
                }
                throw e;
            } catch (EOFException eof) {
                boolean handshaking = (getConnectionState() <= cs_HANDSHAKE);
                boolean rethrow = requireCloseNotify || handshaking;
                if ((debug != null) && Debug.isOn("ssl")) {
                    System.out.println(threadName() +
                        ", received EOFException: "
                        + (rethrow ? "error" : "ignored"));
                }
                if (rethrow) {
                    SSLException e;
                    if (handshaking) {
                        e = new SSLHandshakeException
                            ("Remote host closed connection during handshake");
                    } else {
                        e = new SSLProtocolException
                            ("Remote host closed connection incorrectly");
                    }
                    e.initCause(eof);
                    throw e;
                } else {
                    // treat as if we had received a close_notify
                    closeInternal(false);
                    continue;
                }
            }


            /*
             * The basic SSLv3 record protection involves (optional)
             * encryption for privacy, and an integrity check ensuring
             * data origin authentication.  We do them both here, and
             * throw a fatal alert if the integrity check fails.
             */
            try {
                r.decrypt(readCipher);
            } catch (BadPaddingException e) {
                // RFC 2246 states that decryption_failed should be used
                // for this purpose. However, that allows certain attacks,
                // so we just send bad record MAC. We also need to make
                // sure to always check the MAC to avoid a timing attack
                // for the same issue. See paper by Vaudenay et al.
                r.checkMAC(readMAC);
                // use the same alert types as for MAC failure below
                byte alertType = (r.contentType() == Record.ct_handshake)
                                        ? Alerts.alert_handshake_failure
                                        : Alerts.alert_bad_record_mac;
                fatal(alertType, "Invalid padding", e);
            }
            if (!r.checkMAC(readMAC)) {
                if (r.contentType() == Record.ct_handshake) {
                    fatal(Alerts.alert_handshake_failure,
                        "bad handshake record MAC");
                } else {
                    fatal(Alerts.alert_bad_record_mac, "bad record MAC");
                }
            }

            // if (!r.decompress(c))
            //     fatal(Alerts.alert_decompression_failure,
            //         "decompression failure");

            /*
             * Process the record.
             */
            synchronized (this) {
              switch (r.contentType()) {
                case Record.ct_handshake:
                    /*
                     * Handshake messages always go to a pending session
                     * handshaker ... if there isn't one, create one.  This
                     * must work asynchronously, for renegotiation.
                     *
                     * NOTE that handshaking will either resume a session
                     * which was in the cache (and which might have other
                     * connections in it already), or else will start a new
                     * session (new keys exchanged) with just this connection
                     * in it.
                     */
                    initHandshaker();

                    /*
                     * process the handshake record ... may contain just
                     * a partial handshake message or multiple messages.
                     *
                     * The handshaker state machine will ensure that it's
                     * a finished message.
                     */
                    handshaker.process_record(r, expectingFinished);
                    expectingFinished = false;

                    if (handshaker.isDone()) {
                        sess = handshaker.getSession();
                        handshaker = null;
                        connectionState = cs_DATA;

                        //
                        // Tell folk about handshake completion, but do
                        // it in a separate thread.
                        //
                        if (handshakeListeners != null) {
                            HandshakeCompletedEvent event =
                                new HandshakeCompletedEvent(this, sess);

                            Thread t = new NotifyHandshakeThread(
                                handshakeListeners.entrySet(), event);
                            t.start();
                        }
                    }
                    if (needAppData || connectionState != cs_DATA) {
                        continue;
                    } else {
                        return;
                    }

                case Record.ct_application_data:
                    // Pass this right back up to the application.
                    if (connectionState != cs_DATA
                            && connectionState != cs_RENEGOTIATE
                            && connectionState != cs_SENT_CLOSE) {
                        throw new SSLProtocolException(
                            "Data received in non-data state: " +
                            connectionState);
                    }
                    if (expectingFinished) {
                        throw new SSLProtocolException
                                ("Expecting finished message, received data");
                    }
                    if (!needAppData) {
                        throw new SSLException("Discarding app data");
                    }

                    r.setAppDataValid(true);
                    return;

                case Record.ct_alert:
                    recvAlert(r);
                    continue;

                case Record.ct_change_cipher_spec:
                    if ((connectionState != cs_HANDSHAKE
                                && connectionState != cs_RENEGOTIATE)
                            || r.available() != 1
                            || r.read() != 1) {
                        fatal(Alerts.alert_unexpected_message,
                            "illegal change cipher spec msg, state = "
                            + connectionState);
                    }

                    //
                    // The first message after a change_cipher_spec
                    // record MUST be a "Finished" handshake record,
                    // else it's a protocol violation.  We force this
                    // to be checked by a minor tweak to the state
                    // machine.
                    //
                    changeReadCiphers();
                    // next message MUST be a finished message
                    expectingFinished = true;
                    continue;

                default:
                    //
                    // TLS requires that unrecognized records be ignored.
                    //
                    if (debug != null && Debug.isOn("ssl")) {
                        System.out.println(threadName() +
                            ", Received record type: "
                            + r.contentType());
                    }
                    continue;
              } // switch
            } // synchronized (this)
        }

        //
        // couldn't read, due to some kind of error
        //
        r.close();
        return;
      }  // synchronized (readLock)
    }

    //
    // HANDSHAKE RELATED CODE
    //

    /**
     * Return the AppInputStream. For use by Handshaker only.
     */
    AppInputStream getAppInputStream() {
        return input;
    }

    /**
     * Initialize and get the server handshaker. Used by SSLServerSocketImpl
     * for the ciphersuite availability test *only*.
     */
    ServerHandshaker getServerHandshaker() throws SSLException {
        initHandshaker();
        return (ServerHandshaker)handshaker;
    }

    /**
     * Initialize the handshaker object. This means:
     *
     *  . if a handshake is already in progress (state is cs_HANDSHAKE
     *    or cs_RENEGOTIATE), do nothing and return
     *
     *  . if the socket is already closed, throw an Exception (internal error)
     *
     *  . otherwise (cs_START or cs_DATA), create the appropriate handshaker
     *    object, initialize it, and advance the connection state (to
     *    cs_HANDSHAKE or cs_RENEGOTIATE, respectively).
     *
     * This method is called right after a new socket is created, when
     * starting renegotiation, or when changing client/ server mode of the
     * socket.
     */
    private void initHandshaker() {
        switch (connectionState) {

        //
        // Starting a new handshake.
        //
        case cs_START:
        case cs_DATA:
            break;

        //
        // We're already in the middle of a handshake.
        //
        case cs_HANDSHAKE:
        case cs_RENEGOTIATE:
            return;

        //
        // Anyone allowed to call this routine is required to
        // do so ONLY if the connection state is reasonable...
        //
        default:
            throw new IllegalStateException("Internal error");
        }

        // state is either cs_START or cs_DATA
        if (connectionState == cs_START) {
            connectionState = cs_HANDSHAKE;
        } else { // cs_DATA
            connectionState = cs_RENEGOTIATE;
        }
        if (roleIsServer) {
            handshaker = new ServerHandshaker
                        (this, sslContext, enabledProtocols, doClientAuth);
        } else {
            handshaker = new ClientHandshaker
                        (this, sslContext, enabledProtocols);
        }
        handshaker.enabledCipherSuites = enabledCipherSuites;
        handshaker.setEnableSessionCreation(enableSessionCreation);
        if (connectionState == cs_RENEGOTIATE) {
            // don't use SSLv2Hello when renegotiating
            handshaker.output.r.setHelloVersion(protocolVersion);
        }
    }

    /**
     * Synchronously perform the initial handshake.
     *
     * If the handshake is already in progress, this method blocks until it
     * is completed. If the initial handshake has already been completed,
     * it returns immediately.
     */
    private void performInitialHandshake() throws IOException {
        // use handshakeLock and the state check to make sure only
        // one thread performs the handshake
        synchronized (handshakeLock) {
            if (getConnectionState() == cs_HANDSHAKE) {
                /*
                 * All initial handshaking goes through this
                 * InputRecord until we have a valid SSL connection.
                 * Once initial handshaking is finished, AppInputStream's
                 * InputRecord can handle any future renegotiation.
                 *
                 * Keep this local so that it goes out of scope and is
                 * eventually GC'd.
                 */
                if (inrec == null) {
                    inrec = new InputRecord();

                    /*
                     * Grab the characteristics already assigned to
                     * AppInputStream's InputRecord.  Enable checking for
                     * SSLv2 hellos on this first handshake.
                     */
                    inrec.setHandshakeHash(input.r.getHandshakeHash());
                    inrec.setHelloVersion(input.r.getHelloVersion());
                    inrec.enableFormatChecks();
                }

                kickstartHandshake();
                readRecord(inrec, false);
                inrec = null;
            }
        }
    }

    /**
     * Starts an SSL handshake on this connection.
     */
    public void startHandshake() throws IOException {
        // start an ssl handshake that could be resumed from timeout exception
        startHandshake(true);
    }

    /**
     * Starts an ssl handshake on this connection.
     *
     * @param resumable indicates the handshake process is resumable from a
     *          certain exception. If <code>resumable</code>, the socket will
     *          be reserved for exceptions like timeout; otherwise, the socket
     *          will be closed, no further communications could be done.
     */
    private void startHandshake(boolean resumable) throws IOException {
        checkWrite();
        try {
            if (getConnectionState() == cs_HANDSHAKE) {
                // do initial handshake
                performInitialHandshake();
            } else {
                // start renegotiation
                kickstartHandshake();
            }
        } catch (Exception e) {
            // shutdown and rethrow (wrapped) exception as appropriate
            handleException(e, resumable);
        }
    }

    /**
     * Kickstart the handshake if it is not already in progress.
     * This means:
     *
     *  . if handshaking is already underway, do nothing and return
     *
     *  . if the socket is not connected or already closed, throw an
     *    Exception.
     *
     *  . otherwise, call initHandshake() to initialize the handshaker
     *    object and progress the state. Then, send the initial
     *    handshaking message if appropriate (always on clients and
     *    on servers when renegotiating).
     */
    private synchronized void kickstartHandshake() throws IOException {
        switch (connectionState) {

        case cs_HANDSHAKE:
            // handshaker already setup, proceed
            break;

        case cs_DATA:
            // initialize the handshaker, move to cs_RENEGOTIATE
            initHandshaker();
            break;

        case cs_RENEGOTIATE:
            // handshaking already in progress, return
            return;

        /*
         * The only way to get a socket in the state is when
         * you have an unconnected socket.
         */
        case cs_START:
            throw new SocketException(
                "handshaking attempted on unconnected socket");

        default:
            throw new SocketException("connection is closed");
        }

        //
        // Kickstart handshake state machine if we need to ...
        //
        // Note that handshaker.kickstart() writes the message
        // to its HandshakeOutStream, which calls back into
        // SSLSocketImpl.writeRecord() to send it.
        //
        if (!handshaker.started()) {
            if (handshaker instanceof ClientHandshaker) {
                // send client hello
                handshaker.kickstart();
            } else {
                if (connectionState == cs_HANDSHAKE) {
                    // initial handshake, no kickstart message to send
                } else {
                    // we want to renegotiate, send hello request
                    handshaker.kickstart();
                    // hello request is not included in the handshake
                    // hashes, reset them
                    handshaker.handshakeHash.reset();
                }
            }
        }
    }

    //
    // CLOSURE RELATED CALLS
    //

    /**
     * Return whether the socket has been explicitly closed by the application.
     */
    public boolean isClosed() {
        return getConnectionState() == cs_APP_CLOSED;
    }

    /**
     * Return whether we have reached end-of-file.
     *
     * If the socket is not connected, has been shutdown because of an error
     * or has been closed, throw an Exception.
     */
    boolean checkEOF() throws IOException {
        switch (getConnectionState()) {
        case cs_START:
            throw new SocketException("Socket is not connected");

        case cs_HANDSHAKE:
        case cs_DATA:
        case cs_RENEGOTIATE:
        case cs_SENT_CLOSE:
            return false;

        case cs_APP_CLOSED:
            throw new SocketException("Socket is closed");

        case cs_ERROR:
        case cs_CLOSED:
        default:
            // either closed because of error, or normal EOF
            if (closeReason == null) {
                return true;
            }
            IOException e = new SSLException
                        ("Connection has been shutdown: " + closeReason);
            e.initCause(closeReason);
            throw e;

        }
    }

    /**
     * Check if we can write data to this socket. If not, throw an IOException.
     */
    void checkWrite() throws IOException {
        if (checkEOF() || (getConnectionState() == cs_SENT_CLOSE)) {
            // we are at EOF, write must throw Exception
            throw new SocketException("Connection closed by remote host");
        }
    }

    private void closeSocket() throws IOException {
        if ((debug != null) && Debug.isOn("ssl")) {
            System.out.println(threadName() + ", called closeSocket()");
        }
        if (self == this) {
            super.close();
        } else {
            self.close();
        }
    }

    /*
     * Closing the connection is tricky ... we can't officially close the
     * connection until we know the other end is ready to go away too,
     * and if ever the connection gets aborted we must forget session
     * state (it becomes invalid).
     */

    /**
     * Closes the SSL connection.  SSL includes an application level
     * shutdown handshake; you should close SSL sockets explicitly
     * rather than leaving it for finalization, so that your remote
     * peer does not experience a protocol error.
     */
    public void close() throws IOException {
        if ((debug != null) && Debug.isOn("ssl")) {
            System.out.println(threadName() + ", called close()");
        }
        closeInternal(true);  // caller is initiating close
        setConnectionState(cs_APP_CLOSED);
    }

    /**
     * Don't synchronize the whole method because waitForClose()
     * (which calls readRecord()) might be called.
     *
     * @param selfInitiated Indicates which party initiated the close.
     * If selfInitiated, this side is initiating a close; for layered and
     * non-autoclose socket, wait for close_notify response.
     * If !selfInitiated, peer sent close_notify; we reciprocate but
     * no need to wait for response.
     */
    private void closeInternal(boolean selfInitiated) throws IOException {
        if ((debug != null) && Debug.isOn("ssl")) {
            System.out.println(threadName() + ", called closeInternal("
                + selfInitiated + ")");
        }

        int state = getConnectionState();
        try {
            switch (state) {
            /*
             * java.net code sometimes closes sockets "early", when
             * we can't actually do I/O on them.
             */
            case cs_START:
                break;

            /*
             * If we're closing down due to error, we already sent (or else
             * received) the fatal alert ... no niceties, blow the connection
             * away as quickly as possible (even if we didn't allocate the
             * socket ourselves; it's unusable, regardless).
             */
            case cs_ERROR:
                closeSocket();
                break;

            /*
             * Sometimes close() gets called more than once.
             */
            case cs_CLOSED:
            case cs_APP_CLOSED:
                 break;

            /*
             * Otherwise we indicate clean termination.
             */
            // case cs_HANDSHAKE:
            // case cs_DATA:
            // case cs_RENEGOTIATE:
            // case cs_SENT_CLOSE:
            default:
                synchronized (this) {
                    if (((state = getConnectionState()) == cs_CLOSED) ||
                       (state == cs_ERROR) || (state == cs_APP_CLOSED)) {
                        return;  // connection was closed while we waited
                    }
                    if (state != cs_SENT_CLOSE) {
                        warning(Alerts.alert_close_notify);
                        connectionState = cs_SENT_CLOSE;
                    }
                }
                // If state was cs_SENT_CLOSE before, we don't do the actual
                // closing since it is already in progress.
                if (state == cs_SENT_CLOSE) {
                    if (debug != null && Debug.isOn("ssl")) {
                        System.out.println(threadName() +
                            ", close invoked again; state = " +
                            getConnectionState());
                    }
                    if (selfInitiated == false) {
                        // We were called because a close_notify message was
                        // received. This may be due to another thread calling
                        // read() or due to our call to waitForClose() below.
                        // In either case, just return.
                        return;
                    }
                    // Another thread explicitly called close(). We need to
                    // wait for the closing to complete before returning.
                    synchronized (this) {
                        while (connectionState < cs_CLOSED) {
                            try {
                                this.wait();
                            } catch (InterruptedException e) {
                                // ignore
                            }
                        }
                    }
                    if ((debug != null) && Debug.isOn("ssl")) {
                        System.out.println(threadName() +
                            ", after primary close; state = " +
                            getConnectionState());
                    }
                    return;
                }

                if (self == this) {
                    super.close();
                } else if (autoClose) {
                    self.close();
                } else if (selfInitiated) {
                    // layered && non-autoclose
                    // read close_notify alert to clear input stream
                    waitForClose(false);
                }

                // state will be set to cs_CLOSED in the finally block below

                break;
            }
        } finally {
            synchronized (this) {
                // Upon exit from this method, the state is always >= cs_CLOSED
                connectionState = (connectionState == cs_APP_CLOSED)
                                ? cs_APP_CLOSED : cs_CLOSED;
                // notify any threads waiting for the closing to finish
                this.notifyAll();
            }
        }
    }

    /**
     * Reads a close_notify or a fatal alert from the input stream.
     * Keep reading records until we get a close_notify or until
     * the connection is otherwise closed.  The close_notify or alert
     * might be read by another reader,
     * which will then process the close and set the connection state.
     */
    void waitForClose(boolean rethrow) throws IOException {
        if (debug != null && Debug.isOn("ssl")) {
            System.out.println(threadName() +
                ", waiting for close_notify or alert: state "
                + getConnectionState());
        }

        try {
            int state;

            while (((state = getConnectionState()) != cs_CLOSED) &&
                   (state != cs_ERROR) && (state != cs_APP_CLOSED)) {
                // create the InputRecord if it isn't intialized.
                if (inrec == null) {
                    inrec = new InputRecord();
                }

                // Ask for app data and then throw it away
                try {
                    readRecord(inrec, true);
                } catch (SocketTimeoutException e) {
                    // if time out, ignore the exception and continue
                }
            }
            inrec = null;
        } catch (IOException e) {
            if (debug != null && Debug.isOn("ssl")) {
                System.out.println(threadName() +
                    ", Exception while waiting for close " +e);
            }
            if (rethrow) {
                throw e; // pass exception up
            }
        }
    }

    //
    // EXCEPTION AND ALERT HANDLING
    //

    /**
     * Handle an exception. This method is called by top level exception
     * handlers (in read(), write()) to make sure we always shutdown the
     * connection correctly and do not pass runtime exception to the
     * application.
     */
    void handleException(Exception e) throws IOException {
        handleException(e, true);
    }

    /**
     * Handle an exception. This method is called by top level exception
     * handlers (in read(), write(), startHandshake()) to make sure we
     * always shutdown the connection correctly and do not pass runtime
     * exception to the application.
     *
     * This method never returns normally, it always throws an IOException.
     *
     * We first check if the socket has already been shutdown because of an
     * error. If so, we just rethrow the exception. If the socket has not
     * been shutdown, we sent a fatal alert and remember the exception.
     *
     * @param e the Exception
     * @param resumable indicates the caller process is resumable from the
     *          exception. If <code>resumable</code>, the socket will be
     *          reserved for exceptions like timeout; otherwise, the socket
     *          will be closed, no further communications could be done.
     */
    synchronized private void handleException(Exception e, boolean resumable)
        throws IOException {
        if ((debug != null) && Debug.isOn("ssl")) {
            System.out.println(threadName()
                        + ", handling exception: " + e.toString());
        }

        // don't close the Socket in case of timeouts or interrupts if
        // the process is resumable.
        if (e instanceof InterruptedIOException && resumable) {
            throw (IOException)e;
        }

        // if we've already shutdown because of an error,
        // there is nothing to do except rethrow the exception
        if (closeReason != null) {
            if (e instanceof IOException) { // includes SSLException
                throw (IOException)e;
            } else {
                // this is odd, not an IOException.
                // normally, this should not happen
                // if closeReason has been already been set
                throw Alerts.getSSLException(Alerts.alert_internal_error, e,
                                      "Unexpected exception");
            }
        }

        // need to perform error shutdown
        boolean isSSLException = (e instanceof SSLException);
        if ((isSSLException == false) && (e instanceof IOException)) {
            // IOException from the socket
            // this means the TCP connection is already dead
            // we call fatal just to set the error status
            try {
                fatal(Alerts.alert_unexpected_message, e);
            } catch (IOException ee) {
                // ignore (IOException wrapped in SSLException)
            }
            // rethrow original IOException
            throw (IOException)e;
        }

        // must be SSLException or RuntimeException
        byte alertType;
        if (isSSLException) {
            if (e instanceof SSLHandshakeException) {
                alertType = Alerts.alert_handshake_failure;
            } else {
                alertType = Alerts.alert_unexpected_message;
            }
        } else {
            alertType = Alerts.alert_internal_error;
        }
        fatal(alertType, e);
    }

    /*
     * Send a warning alert.
     */
    void warning(byte description) {
        sendAlert(Alerts.alert_warning, description);
    }

    synchronized void fatal(byte description, String diagnostic)
            throws IOException {
        fatal(description, diagnostic, null);
    }

    synchronized void fatal(byte description, Throwable cause)
            throws IOException {
        fatal(description, null, cause);
    }

    /*
     * Send a fatal alert, and throw an exception so that callers will
     * need to stand on their heads to accidentally continue processing.
     */
    synchronized void fatal(byte description, String diagnostic,
            Throwable cause) throws IOException {
        if ((input != null) && (input.r != null)) {
            input.r.close();
        }
        sess.invalidate();

        int oldState = connectionState;
        connectionState = cs_ERROR;

        /*
         * Has there been an error received yet?  If not, remember it.
         * By RFC 2246, we don't bother waiting for a response.
         * Fatal errors require immediate shutdown.
         */
        if (closeReason == null) {
            /*
             * Try to clear the kernel buffer to avoid TCP connection resets.
             */
            if (oldState == cs_HANDSHAKE) {
                sockInput.skip(sockInput.available());
            }
            sendAlert(Alerts.alert_fatal, description);
            if (cause instanceof SSLException) { // only true if != null
                closeReason = (SSLException)cause;
            } else {
                closeReason =
                    Alerts.getSSLException(description, cause, diagnostic);
            }
        }

        /*
         * Clean up our side.
         */
        closeSocket();
        connectionState = (oldState == cs_APP_CLOSED) ? cs_APP_CLOSED
                                                      : cs_CLOSED;
        throw closeReason;
    }


    /*
     * Process an incoming alert ... caller must already have synchronized
     * access to "this".
     */
    private void recvAlert(InputRecord r) throws IOException {
        byte level = (byte)r.read();
        byte description = (byte)r.read();
        if (description == -1) { // check for short message
            fatal(Alerts.alert_illegal_parameter, "Short alert message");
        }

        if (debug != null && (Debug.isOn("record") ||
                Debug.isOn("handshake"))) {
            synchronized (System.out) {
                System.out.print(threadName());
                System.out.print(", RECV " + protocolVersion + " ALERT:  ");
                if (level == Alerts.alert_fatal) {
                    System.out.print("fatal, ");
                } else if (level == Alerts.alert_warning) {
                    System.out.print("warning, ");
                } else {
                    System.out.print("<level " + (0x0ff & level) + ">, ");
                }
                System.out.println(Alerts.alertDescription(description));
            }
        }

        if (level == Alerts.alert_warning) {
            if (description == Alerts.alert_close_notify) {
                if (connectionState == cs_HANDSHAKE) {
                    fatal(Alerts.alert_unexpected_message,
                                "Received close_notify during handshake");
                } else {
                    closeInternal(false);  // reply to close
                }
            } else {

                //
                // The other legal warnings relate to certificates,
                // e.g. no_certificate, bad_certificate, etc; these
                // are important to the handshaking code, which can
                // also handle illegal protocol alerts if needed.
                //
                if (handshaker != null) {
                    handshaker.handshakeAlert(description);
                }
            }
        } else { // fatal or unknown level
            String reason = "Received fatal alert: "
                + Alerts.alertDescription(description);
            if (closeReason == null) {
                closeReason = Alerts.getSSLException(description, reason);
            }
            fatal(Alerts.alert_unexpected_message, reason);
        }
    }


    /*
     * Emit alerts.  Caller must have synchronized with "this".
     */
    private void sendAlert(byte level, byte description) {
        if (connectionState >= cs_CLOSED) {
            return;
        }

        OutputRecord r = new OutputRecord(Record.ct_alert);
        r.setVersion(protocolVersion);

        boolean useDebug = debug != null && Debug.isOn("ssl");
        if (useDebug) {
            synchronized (System.out) {
                System.out.print(threadName());
                System.out.print(", SEND " + protocolVersion + " ALERT:  ");
                if (level == Alerts.alert_fatal) {
                    System.out.print("fatal, ");
                } else if (level == Alerts.alert_warning) {
                    System.out.print("warning, ");
                } else {
                    System.out.print("<level = " + (0x0ff & level) + ">, ");
                }
                System.out.println("description = "
                        + Alerts.alertDescription(description));
            }
        }

        r.write(level);
        r.write(description);
        try {
            writeRecord(r);
        } catch (IOException e) {
            if (useDebug) {
                System.out.println(threadName() +
                    ", Exception sending alert: " + e);
            }
        }
    }

    //
    // VARIOUS OTHER METHODS
    //

    /*
     * When a connection finishes handshaking by enabling use of a newly
     * negotiated session, each end learns about it in two halves (read,
     * and write).  When both read and write ciphers have changed, and the
     * last handshake message has been read, the connection has joined
     * (rejoined) the new session.
     *
     * NOTE:  The SSLv3 spec is rather unclear on the concepts here.
     * Sessions don't change once they're established (including cipher
     * suite and master secret) but connections can join them (and leave
     * them).  They're created by handshaking, though sometime handshaking
     * causes connections to join up with pre-established sessions.
     */
    private void changeReadCiphers() throws SSLException {
        if (connectionState != cs_HANDSHAKE
                && connectionState != cs_RENEGOTIATE) {
            throw new SSLProtocolException(
                "State error, change cipher specs");
        }

        // ... create decompressor

        try {
            readCipher = handshaker.newReadCipher();
            readMAC = handshaker.newReadMAC();
        } catch (GeneralSecurityException e) {
            // "can't happen"
            throw (SSLException)new SSLException
                                ("Algorithm missing:  ").initCause(e);
        }
    }

    // used by Handshaker
    void changeWriteCiphers() throws SSLException {
        if (connectionState != cs_HANDSHAKE
                && connectionState != cs_RENEGOTIATE) {
            throw new SSLProtocolException(
                "State error, change cipher specs");
        }

        // ... create compressor

        try {
            writeCipher = handshaker.newWriteCipher();
            writeMAC = handshaker.newWriteMAC();
        } catch (GeneralSecurityException e) {
            // "can't happen"
            throw (SSLException)new SSLException
                                ("Algorithm missing:  ").initCause(e);
        }
    }

    /*
     * Updates the SSL version associated with this connection.
     * Called from Handshaker once it has determined the negotiated version.
     */
    synchronized void setVersion(ProtocolVersion protocolVersion) {
        this.protocolVersion = protocolVersion;
        output.r.setVersion(protocolVersion);
    }

    synchronized String getHost() {
        if (host == null) {
            host = getInetAddress().getHostName();
        }
        return host;
    }

    /**
     * Gets an input stream to read from the peer on the other side.
     * Data read from this stream was always integrity protected in
     * transit, and will usually have been confidentiality protected.
     */
    synchronized public InputStream getInputStream() throws IOException {
        if (isClosed()) {
            throw new SocketException("Socket is closed");
        }

        /*
         * Can't call isConnected() here, because the Handshakers
         * do some initialization before we actually connect.
         */
        if (connectionState == cs_START) {
            throw new SocketException("Socket is not connected");
        }

        return input;
    }

    /**
     * Gets an output stream to write to the peer on the other side.
     * Data written on this stream is always integrity protected, and
     * will usually be confidentiality protected.
     */
    synchronized public OutputStream getOutputStream() throws IOException {
        if (isClosed()) {
            throw new SocketException("Socket is closed");
        }

        /*
         * Can't call isConnected() here, because the Handshakers
         * do some initialization before we actually connect.
         */
        if (connectionState == cs_START) {
            throw new SocketException("Socket is not connected");
        }

        return output;
    }

    /**
     * Returns the the SSL Session in use by this connection.  These can
     * be long lived, and frequently correspond to an entire login session
     * for some user.
     */
    public SSLSession getSession() {
        /*
         * Force a synchronous handshake, if appropriate.
         */
        if (getConnectionState() == cs_HANDSHAKE) {
            try {
                // start handshaking, if failed, the connection will be closed.
                startHandshake(false);
            } catch (IOException e) {
                // handshake failed. log and return a nullSession
                if (debug != null && Debug.isOn("handshake")) {
                      System.out.println(threadName() +
                          ", IOException in getSession():  " + e);
                }
            }
        }
        synchronized (this) {
            return sess;
        }
    }

    /**
     * Controls whether new connections may cause creation of new SSL
     * sessions.
     *
     * As long as handshaking has not started, we can change
     * whether we enable session creations.  Otherwise,
     * we will need to wait for the next handshake.
     */
    synchronized public void setEnableSessionCreation(boolean flag) {
        enableSessionCreation = flag;

        if ((handshaker != null) && !handshaker.started()) {
            handshaker.setEnableSessionCreation(enableSessionCreation);
        }
    }

    /**
     * Returns true if new connections may cause creation of new SSL
     * sessions.
     */
    synchronized public boolean getEnableSessionCreation() {
        return enableSessionCreation;
    }


    /**
     * Sets the flag controlling whether a server mode socket
     * *REQUIRES* SSL client authentication.
     *
     * As long as handshaking has not started, we can change
     * whether client authentication is needed.  Otherwise,
     * we will need to wait for the next handshake.
     */
    synchronized public void setNeedClientAuth(boolean flag) {
        doClientAuth = (flag ?
            SSLEngineImpl.clauth_required : SSLEngineImpl.clauth_none);

        if ((handshaker != null) &&
                (handshaker instanceof ServerHandshaker) &&
                !handshaker.started()) {
            ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
        }
    }

    synchronized public boolean getNeedClientAuth() {
        return (doClientAuth == SSLEngineImpl.clauth_required);
    }

    /**
     * Sets the flag controlling whether a server mode socket
     * *REQUESTS* SSL client authentication.
     *
     * As long as handshaking has not started, we can change
     * whether client authentication is requested.  Otherwise,
     * we will need to wait for the next handshake.
     */
    synchronized public void setWantClientAuth(boolean flag) {
        doClientAuth = (flag ?
            SSLEngineImpl.clauth_requested : SSLEngineImpl.clauth_none);

        if ((handshaker != null) &&
                (handshaker instanceof ServerHandshaker) &&
                !handshaker.started()) {
            ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
        }
    }

    synchronized public boolean getWantClientAuth() {
        return (doClientAuth == SSLEngineImpl.clauth_requested);
    }


    /**
     * Sets the flag controlling whether the socket is in SSL
     * client or server mode.  Must be called before any SSL
     * traffic has started.
     */
    synchronized public void setUseClientMode(boolean flag) {
        switch (connectionState) {

        case cs_START:
            roleIsServer = !flag;
            break;

        case cs_HANDSHAKE:
            /*
             * If we have a handshaker, but haven't started
             * SSL traffic, we can throw away our current
             * handshaker, and start from scratch.  Don't
             * need to call doneConnect() again, we already
             * have the streams.
             */
            assert(handshaker != null);
            if (!handshaker.started()) {
                roleIsServer = !flag;
                connectionState = cs_START;
                initHandshaker();
                break;
            }

            // If handshake has started, that's an error.  Fall through...

        default:
            if (debug != null && Debug.isOn("ssl")) {
                System.out.println(threadName() +
                    ", setUseClientMode() invoked in state = " +
                    connectionState);
            }
            throw new IllegalArgumentException(
                "Cannot change mode after SSL traffic has started");
        }
    }

    synchronized public boolean getUseClientMode() {
        return !roleIsServer;
    }


    /**
     * Returns the names of the cipher suites which could be enabled for use
     * on an SSL connection.  Normally, only a subset of these will actually
     * be enabled by default, since this list may include cipher suites which
     * do not support the mutual authentication of servers and clients, or
     * which do not protect data confidentiality.  Servers may also need
     * certain kinds of certificates to use certain cipher suites.
     *
     * @return an array of cipher suite names
     */
    public String[] getSupportedCipherSuites() {
        CipherSuiteList.clearAvailableCache();
        return CipherSuiteList.getSupported().toStringArray();
    }

    /**
     * Controls which particular cipher suites are enabled for use on
     * this connection.  The cipher suites must have been listed by
     * getCipherSuites() as being supported.  Even if a suite has been
     * enabled, it might never be used if no peer supports it or the
     * requisite certificates (and private keys) are not available.
     *
     * @param suites Names of all the cipher suites to enable.
     */
    synchronized public void setEnabledCipherSuites(String[] suites) {
        enabledCipherSuites = new CipherSuiteList(suites);
        if ((handshaker != null) && !handshaker.started()) {
            handshaker.enabledCipherSuites = enabledCipherSuites;
        }
    }

    /**
     * Returns the names of the SSL cipher suites which are currently enabled
     * for use on this connection.  When an SSL socket is first created,
     * all enabled cipher suites <em>(a)</em> protect data confidentiality,
     * by traffic encryption, and <em>(b)</em> can mutually authenticate
     * both clients and servers.  Thus, in some environments, this value
     * might be empty.
     *
     * @return an array of cipher suite names
     */
    synchronized public String[] getEnabledCipherSuites() {
        return enabledCipherSuites.toStringArray();
    }


    /**
     * Returns the protocols that are supported by this implementation.
     * A subset of the supported protocols may be enabled for this connection
     * @ returns an array of protocol names.
     */
    public String[] getSupportedProtocols() {
        return ProtocolList.getSupported().toStringArray();
    }

    /**
     * Controls which protocols are enabled for use on
     * this connection.  The protocols must have been listed by
     * getSupportedProtocols() as being supported.
     *
     * @param protocols protocols to enable.
     * @exception IllegalArgumentException when one of the protocols
     *  named by the parameter is not supported.
     */
    synchronized public void setEnabledProtocols(String[] protocols) {
        enabledProtocols = new ProtocolList(protocols);
        if ((handshaker != null) && !handshaker.started()) {
            handshaker.setEnabledProtocols(enabledProtocols);
        }
    }

    synchronized public String[] getEnabledProtocols() {
        return enabledProtocols.toStringArray();
    }

    /**
     * Assigns the socket timeout.
     * @see java.net.Socket#setSoTimeout
     */
    public void setSoTimeout(int timeout) throws SocketException {
        if ((debug != null) && Debug.isOn("ssl")) {
            System.out.println(threadName() +
                ", setSoTimeout(" + timeout + ") called");
        }
        if (self == this) {
            super.setSoTimeout(timeout);
        } else {
            self.setSoTimeout(timeout);
        }
    }

    /**
     * Registers an event listener to receive notifications that an
     * SSL handshake has completed on this connection.
     */
    public synchronized void addHandshakeCompletedListener(
            HandshakeCompletedListener listener) {
        if (listener == null) {
            throw new IllegalArgumentException("listener is null");
        }
        if (handshakeListeners == null) {
            handshakeListeners = new
                HashMap<HandshakeCompletedListener, AccessControlContext>(4);
        }
        handshakeListeners.put(listener, AccessController.getContext());
    }


    /**
     * Removes a previously registered handshake completion listener.
     */
    public synchronized void removeHandshakeCompletedListener(
            HandshakeCompletedListener listener) {
        if (handshakeListeners == null) {
            throw new IllegalArgumentException("no listeners");
        }
        if (handshakeListeners.remove(listener) == null) {
            throw new IllegalArgumentException("listener not registered");
        }
        if (handshakeListeners.isEmpty()) {
            handshakeListeners = null;
        }
    }

    /**
     * Try to configure the endpoint identification algorithm of the socket.
     *
     * @param identificationAlgorithm the algorithm used to check the
     *        endpoint identity.
     * @return true if the identification algorithm configuration success.
     */
    synchronized public boolean trySetHostnameVerification(
        String identificationAlgorithm) {
        if (sslContext.getX509TrustManager() instanceof
                X509ExtendedTrustManager) {
            this.identificationAlg = identificationAlgorithm;
            return true;
        } else {
            return false;
        }
    }

    /**
     * Returns the endpoint identification algorithm of the socket.
     */
    synchronized public String getHostnameVerification() {
        return identificationAlg;
    }

    //
    // We allocate a separate thread to deliver handshake completion
    // events.  This ensures that the notifications don't block the
    // protocol state machine.
    //
    private static class NotifyHandshakeThread extends Thread {

        private Set<Map.Entry<HandshakeCompletedListener,AccessControlContext>>
                targets;        // who gets notified
        private HandshakeCompletedEvent event;          // the notification

        NotifyHandshakeThread(
            Set<Map.Entry<HandshakeCompletedListener,AccessControlContext>>
            entrySet, HandshakeCompletedEvent e) {

            super("HandshakeCompletedNotify-Thread");
            targets = entrySet;
            event = e;
        }

        public void run() {
            for (Map.Entry<HandshakeCompletedListener,AccessControlContext>
                entry : targets) {

                final HandshakeCompletedListener l = entry.getKey();
                AccessControlContext acc = entry.getValue();
                AccessController.doPrivileged(new PrivilegedAction<Void>() {
                    public Void run() {
                        l.handshakeCompleted(event);
                        return null;
                    }
                }, acc);
            }
        }
    }

    /**
     * Return the name of the current thread. Utility method.
     */
    private static String threadName() {
        return Thread.currentThread().getName();
    }

    /**
     * Returns a printable representation of this end of the connection.
     */
    public String toString() {
        StringBuffer retval = new StringBuffer(80);

        retval.append(Integer.toHexString(hashCode()));
        retval.append("[");
        retval.append(sess.getCipherSuite());
        retval.append(": ");

        if (self == this) {
            retval.append(super.toString());
        } else {
            retval.append(self.toString());
        }
        retval.append("]");

        return retval.toString();
    }
}
