jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
changeset 7043 5e2d1edeb2c7
parent 7039 6464c8e62a18
child 9246 c459f79af46b
equal deleted inserted replaced
7042:56e990297bc5 7043:5e2d1edeb2c7
    30 import java.net.*;
    30 import java.net.*;
    31 import java.security.GeneralSecurityException;
    31 import java.security.GeneralSecurityException;
    32 import java.security.AccessController;
    32 import java.security.AccessController;
    33 import java.security.AccessControlContext;
    33 import java.security.AccessControlContext;
    34 import java.security.PrivilegedAction;
    34 import java.security.PrivilegedAction;
       
    35 import java.security.AlgorithmConstraints;
    35 import java.util.*;
    36 import java.util.*;
    36 import java.util.concurrent.TimeUnit;
    37 import java.util.concurrent.TimeUnit;
    37 import java.util.concurrent.locks.ReentrantLock;
    38 import java.util.concurrent.locks.ReentrantLock;
    38 
    39 
    39 import javax.crypto.BadPaddingException;
    40 import javax.crypto.BadPaddingException;
   197     private boolean             enableSessionCreation = true;
   198     private boolean             enableSessionCreation = true;
   198     private String              host;
   199     private String              host;
   199     private boolean             autoClose = true;
   200     private boolean             autoClose = true;
   200     private AccessControlContext acc;
   201     private AccessControlContext acc;
   201 
   202 
       
   203     /*
       
   204      * We cannot use the hostname resolved from name services.  For
       
   205      * virtual hosting, multiple hostnames may be bound to the same IP
       
   206      * address, so the hostname resolved from name services is not
       
   207      * reliable.
       
   208      */
       
   209     private String              rawHostname;
       
   210 
   202     // The cipher suites enabled for use on this connection.
   211     // The cipher suites enabled for use on this connection.
   203     private CipherSuiteList     enabledCipherSuites;
   212     private CipherSuiteList     enabledCipherSuites;
   204 
   213 
   205     // hostname identification algorithm, the hostname identification is
   214     // The endpoint identification protocol
   206     // disabled by default.
   215     private String              identificationProtocol = null;
   207     private String              identificationAlg = null;
   216 
       
   217     // The cryptographic algorithm constraints
       
   218     private AlgorithmConstraints    algorithmConstraints = null;
   208 
   219 
   209     /*
   220     /*
   210      * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
   221      * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
   211      * IMPORTANT STUFF TO UNDERSTANDING THE SYNCHRONIZATION ISSUES.
   222      * IMPORTANT STUFF TO UNDERSTANDING THE SYNCHRONIZATION ISSUES.
   212      * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
   223      * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
   312      * about changing the cipher spec (and it does change), in fact
   323      * about changing the cipher spec (and it does change), in fact
   313      * that's incidental since it's done by changing everything that
   324      * that's incidental since it's done by changing everything that
   314      * is associated with a session at the same time.  (TLS/IETF may
   325      * is associated with a session at the same time.  (TLS/IETF may
   315      * change that to add client authentication w/o new key exchg.)
   326      * change that to add client authentication w/o new key exchg.)
   316      */
   327      */
   317     private SSLSessionImpl      sess;
   328     private Handshaker                  handshaker;
   318     private Handshaker          handshaker;
   329     private SSLSessionImpl              sess;
       
   330     private volatile SSLSessionImpl     handshakeSession;
   319 
   331 
   320 
   332 
   321     /*
   333     /*
   322      * If anyone wants to get notified about handshake completions,
   334      * If anyone wants to get notified about handshake completions,
   323      * they'll show up on this list.
   335      * they'll show up on this list.
   374      */
   386      */
   375     SSLSocketImpl(SSLContextImpl context, String host, int port)
   387     SSLSocketImpl(SSLContextImpl context, String host, int port)
   376             throws IOException, UnknownHostException {
   388             throws IOException, UnknownHostException {
   377         super();
   389         super();
   378         this.host = host;
   390         this.host = host;
       
   391         this.rawHostname = host;
   379         init(context, false);
   392         init(context, false);
   380         SocketAddress socketAddress =
   393         SocketAddress socketAddress =
   381                host != null ? new InetSocketAddress(host, port) :
   394                host != null ? new InetSocketAddress(host, port) :
   382                new InetSocketAddress(InetAddress.getByName(null), port);
   395                new InetSocketAddress(InetAddress.getByName(null), port);
   383         connect(socketAddress, 0);
   396         connect(socketAddress, 0);
   416     SSLSocketImpl(SSLContextImpl context, String host, int port,
   429     SSLSocketImpl(SSLContextImpl context, String host, int port,
   417             InetAddress localAddr, int localPort)
   430             InetAddress localAddr, int localPort)
   418             throws IOException, UnknownHostException {
   431             throws IOException, UnknownHostException {
   419         super();
   432         super();
   420         this.host = host;
   433         this.host = host;
       
   434         this.rawHostname = host;
   421         init(context, false);
   435         init(context, false);
   422         bind(new InetSocketAddress(localAddr, localPort));
   436         bind(new InetSocketAddress(localAddr, localPort));
   423         SocketAddress socketAddress =
   437         SocketAddress socketAddress =
   424                host != null ? new InetSocketAddress(host, port) :
   438                host != null ? new InetSocketAddress(host, port) :
   425                new InetSocketAddress(InetAddress.getByName(null), port);
   439                new InetSocketAddress(InetAddress.getByName(null), port);
   455      * made.  This just initializes handshake state to use "server mode",
   469      * made.  This just initializes handshake state to use "server mode",
   456      * giving control over the use of SSL client authentication.
   470      * giving control over the use of SSL client authentication.
   457      */
   471      */
   458     SSLSocketImpl(SSLContextImpl context, boolean serverMode,
   472     SSLSocketImpl(SSLContextImpl context, boolean serverMode,
   459             CipherSuiteList suites, byte clientAuth,
   473             CipherSuiteList suites, byte clientAuth,
   460             boolean sessionCreation, ProtocolList protocols)
   474             boolean sessionCreation, ProtocolList protocols,
   461             throws IOException {
   475             String identificationProtocol,
       
   476             AlgorithmConstraints algorithmConstraints) throws IOException {
       
   477 
   462         super();
   478         super();
   463         doClientAuth = clientAuth;
   479         doClientAuth = clientAuth;
   464         enableSessionCreation = sessionCreation;
   480         enableSessionCreation = sessionCreation;
       
   481         this.identificationProtocol = identificationProtocol;
       
   482         this.algorithmConstraints = algorithmConstraints;
   465         init(context, serverMode);
   483         init(context, serverMode);
   466 
   484 
   467         /*
   485         /*
   468          * Override what was picked out for us.
   486          * Override what was picked out for us.
   469          */
   487          */
   506         // We always layer over a connected socket
   524         // We always layer over a connected socket
   507         if (!sock.isConnected()) {
   525         if (!sock.isConnected()) {
   508             throw new SocketException("Underlying socket is not connected");
   526             throw new SocketException("Underlying socket is not connected");
   509         }
   527         }
   510         this.host = host;
   528         this.host = host;
       
   529         this.rawHostname = host;
   511         init(context, false);
   530         init(context, false);
   512         this.autoClose = autoClose;
   531         this.autoClose = autoClose;
   513         doneConnect();
   532         doneConnect();
   514     }
   533     }
   515 
   534 
   517      * Initializes the client socket.
   536      * Initializes the client socket.
   518      */
   537      */
   519     private void init(SSLContextImpl context, boolean isServer) {
   538     private void init(SSLContextImpl context, boolean isServer) {
   520         sslContext = context;
   539         sslContext = context;
   521         sess = SSLSessionImpl.nullSession;
   540         sess = SSLSessionImpl.nullSession;
       
   541         handshakeSession = null;
   522 
   542 
   523         /*
   543         /*
   524          * role is as specified, state is START until after
   544          * role is as specified, state is START until after
   525          * the low level connection's established.
   545          * the low level connection's established.
   526          */
   546          */
   955                                         handshaker.isSecureRenegotiation();
   975                                         handshaker.isSecureRenegotiation();
   956                         clientVerifyData = handshaker.getClientVerifyData();
   976                         clientVerifyData = handshaker.getClientVerifyData();
   957                         serverVerifyData = handshaker.getServerVerifyData();
   977                         serverVerifyData = handshaker.getServerVerifyData();
   958 
   978 
   959                         sess = handshaker.getSession();
   979                         sess = handshaker.getSession();
       
   980                         handshakeSession = null;
   960                         handshaker = null;
   981                         handshaker = null;
   961                         connectionState = cs_DATA;
   982                         connectionState = cs_DATA;
   962 
   983 
   963                         //
   984                         //
   964                         // Tell folk about handshake completion, but do
   985                         // Tell folk about handshake completion, but do
  1730             Throwable cause) throws IOException {
  1751             Throwable cause) throws IOException {
  1731         if ((input != null) && (input.r != null)) {
  1752         if ((input != null) && (input.r != null)) {
  1732             input.r.close();
  1753             input.r.close();
  1733         }
  1754         }
  1734         sess.invalidate();
  1755         sess.invalidate();
       
  1756         if (handshakeSession != null) {
       
  1757             handshakeSession.invalidate();
       
  1758         }
  1735 
  1759 
  1736         int oldState = connectionState;
  1760         int oldState = connectionState;
  1737         connectionState = cs_ERROR;
  1761         connectionState = cs_ERROR;
  1738 
  1762 
  1739         /*
  1763         /*
  1970             host = getInetAddress().getHostName();
  1994             host = getInetAddress().getHostName();
  1971         }
  1995         }
  1972         return host;
  1996         return host;
  1973     }
  1997     }
  1974 
  1998 
       
  1999     synchronized String getRawHostname() {
       
  2000         return rawHostname;
       
  2001     }
       
  2002 
  1975     // ONLY used by HttpsClient to setup the URI specified hostname
  2003     // ONLY used by HttpsClient to setup the URI specified hostname
  1976     synchronized public void setHost(String host) {
  2004     synchronized public void setHost(String host) {
  1977         this.host = host;
  2005         this.host = host;
       
  2006         this.rawHostname = host;
  1978     }
  2007     }
  1979 
  2008 
  1980     /**
  2009     /**
  1981      * Gets an input stream to read from the peer on the other side.
  2010      * Gets an input stream to read from the peer on the other side.
  1982      * Data read from this stream was always integrity protected in
  2011      * Data read from this stream was always integrity protected in
  2041             }
  2070             }
  2042         }
  2071         }
  2043         synchronized (this) {
  2072         synchronized (this) {
  2044             return sess;
  2073             return sess;
  2045         }
  2074         }
       
  2075     }
       
  2076 
       
  2077     @Override
       
  2078     synchronized public SSLSession getHandshakeSession() {
       
  2079         return handshakeSession;
       
  2080     }
       
  2081 
       
  2082     synchronized void setHandshakeSession(SSLSessionImpl session) {
       
  2083         handshakeSession = session;
  2046     }
  2084     }
  2047 
  2085 
  2048     /**
  2086     /**
  2049      * Controls whether new connections may cause creation of new SSL
  2087      * Controls whether new connections may cause creation of new SSL
  2050      * sessions.
  2088      * sessions.
  2228 
  2266 
  2229 
  2267 
  2230     /**
  2268     /**
  2231      * Returns the protocols that are supported by this implementation.
  2269      * Returns the protocols that are supported by this implementation.
  2232      * A subset of the supported protocols may be enabled for this connection
  2270      * A subset of the supported protocols may be enabled for this connection
  2233      * @ returns an array of protocol names.
  2271      * @return an array of protocol names.
  2234      */
  2272      */
  2235     public String[] getSupportedProtocols() {
  2273     public String[] getSupportedProtocols() {
  2236         return ProtocolList.getSupported().toStringArray();
  2274         return ProtocolList.getSupported().toStringArray();
  2237     }
  2275     }
  2238 
  2276 
  2304             handshakeListeners = null;
  2342             handshakeListeners = null;
  2305         }
  2343         }
  2306     }
  2344     }
  2307 
  2345 
  2308     /**
  2346     /**
  2309      * Try to configure the endpoint identification algorithm of the socket.
  2347      * Returns the SSLParameters in effect for this SSLSocket.
  2310      *
  2348      */
  2311      * @param identificationAlgorithm the algorithm used to check the
  2349     synchronized public SSLParameters getSSLParameters() {
  2312      *        endpoint identity.
  2350         SSLParameters params = super.getSSLParameters();
  2313      * @return true if the identification algorithm configuration success.
  2351 
  2314      */
  2352         // the super implementation does not handle the following parameters
  2315     synchronized public boolean trySetHostnameVerification(
  2353         params.setEndpointIdentificationAlgorithm(identificationProtocol);
  2316         String identificationAlgorithm) {
  2354         params.setAlgorithmConstraints(algorithmConstraints);
  2317         if (sslContext.getX509TrustManager() instanceof
  2355 
  2318                 X509ExtendedTrustManager) {
  2356         return params;
  2319             this.identificationAlg = identificationAlgorithm;
  2357     }
  2320             return true;
  2358 
  2321         } else {
  2359     /**
  2322             return false;
  2360      * Applies SSLParameters to this socket.
  2323         }
  2361      */
  2324     }
  2362     synchronized public void setSSLParameters(SSLParameters params) {
  2325 
  2363         super.setSSLParameters(params);
  2326     /**
  2364 
  2327      * Returns the endpoint identification algorithm of the socket.
  2365         // the super implementation does not handle the following parameters
  2328      */
  2366         identificationProtocol = params.getEndpointIdentificationAlgorithm();
  2329     synchronized public String getHostnameVerification() {
  2367         algorithmConstraints = params.getAlgorithmConstraints();
  2330         return identificationAlg;
  2368         if ((handshaker != null) && !handshaker.started()) {
       
  2369             handshaker.setIdentificationProtocol(identificationProtocol);
       
  2370             handshaker.setAlgorithmConstraints(algorithmConstraints);
       
  2371         }
  2331     }
  2372     }
  2332 
  2373 
  2333     //
  2374     //
  2334     // We allocate a separate thread to deliver handshake completion
  2375     // We allocate a separate thread to deliver handshake completion
  2335     // events.  This ensures that the notifications don't block the
  2376     // events.  This ensures that the notifications don't block the