/* * Copyright (c) 1996, 2011, Oracle and/or its affiliates. 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.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.security.AlgorithmConstraints;import java.util.*;import java.util.concurrent.TimeUnit;import java.util.concurrent.locks.ReentrantLock; 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 boolean enableSessionCreation = true; private String host; private boolean autoClose = true; private AccessControlContext acc; /* * We cannot use the hostname resolved from name services. For * virtual hosting, multiple hostnames may be bound to the same IP * address, so the hostname resolved from name services is not * reliable. */ private String rawHostname; // The cipher suites enabled for use on this connection. private CipherSuiteList enabledCipherSuites; // The endpoint identification protocol private String identificationProtocol = null; // The cryptographic algorithm constraints private AlgorithmConstraints algorithmConstraints = 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. */ final private Object handshakeLock = new Object(); final ReentrantLock writeLock = new ReentrantLock(); final private Object readLock = new Object(); 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 /* * security parameters for secure renegotiation. */ private boolean secureRenegotiation; private byte[] clientVerifyData; private byte[] serverVerifyData; /* * 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 Handshaker handshaker; private SSLSessionImpl sess; private volatile SSLSessionImpl handshakeSession; /* * 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 protocol versions enabled for use on this connection. * * Note: we support a pseudo protocol called SSLv2Hello which when * set will result in an SSL v2 Hello being sent with SSL (version 3.0) * or TLS (version 3.1, 3.2, etc.) 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; this.rawHostname = host; init(context, false); SocketAddress socketAddress = host != null ? new InetSocketAddress(host, port) : new InetSocketAddress(InetAddress.getByName(null), 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; this.rawHostname = host; init(context, false); bind(new InetSocketAddress(localAddr, localPort)); SocketAddress socketAddress = host != null ? new InetSocketAddress(host, port) : new InetSocketAddress(InetAddress.getByName(null), 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, String identificationProtocol, AlgorithmConstraints algorithmConstraints) throws IOException { super(); doClientAuth = clientAuth; enableSessionCreation = sessionCreation; this.identificationProtocol = identificationProtocol; this.algorithmConstraints = algorithmConstraints; 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();Lines 1–500 of 2493. Load more
/* * Copyright (c) 1996, 2011, Oracle and/or its affiliates. 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.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.security.AlgorithmConstraints; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; 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 boolean enableSessionCreation = true; private String host; private boolean autoClose = true; private AccessControlContext acc; /* * We cannot use the hostname resolved from name services. For * virtual hosting, multiple hostnames may be bound to the same IP * address, so the hostname resolved from name services is not * reliable. */ private String rawHostname; // The cipher suites enabled for use on this connection. private CipherSuiteList enabledCipherSuites; // The endpoint identification protocol private String identificationProtocol = null; // The cryptographic algorithm constraints private AlgorithmConstraints algorithmConstraints = 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. */ final private Object handshakeLock = new Object(); final ReentrantLock writeLock = new ReentrantLock(); final private Object readLock = new Object(); 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 /* * security parameters for secure renegotiation. */ private boolean secureRenegotiation; private byte[] clientVerifyData; private byte[] serverVerifyData; /* * 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 Handshaker handshaker; private SSLSessionImpl sess; private volatile SSLSessionImpl handshakeSession; /* * 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 protocol versions enabled for use on this connection. * * Note: we support a pseudo protocol called SSLv2Hello which when * set will result in an SSL v2 Hello being sent with SSL (version 3.0) * or TLS (version 3.1, 3.2, etc.) 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; this.rawHostname = host; init(context, false); SocketAddress socketAddress = host != null ? new InetSocketAddress(host, port) : new InetSocketAddress(InetAddress.getByName(null), 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; this.rawHostname = host; init(context, false); bind(new InetSocketAddress(localAddr, localPort)); SocketAddress socketAddress = host != null ? new InetSocketAddress(host, port) : new InetSocketAddress(InetAddress.getByName(null), 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, String identificationProtocol, AlgorithmConstraints algorithmConstraints) throws IOException { super(); doClientAuth = clientAuth; enableSessionCreation = sessionCreation; this.identificationProtocol = identificationProtocol; this.algorithmConstraints = algorithmConstraints; 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();