src/java.base/share/classes/sun/security/ssl/SSLServerSocketImpl.java
changeset 50768 68fa3d4026ea
parent 47216 71c04702a3d5
child 54443 dfba4e321ab3
--- a/src/java.base/share/classes/sun/security/ssl/SSLServerSocketImpl.java	Mon Jun 25 21:22:16 2018 +0300
+++ b/src/java.base/share/classes/sun/security/ssl/SSLServerSocketImpl.java	Mon Jun 25 13:41:39 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2018, 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
@@ -23,22 +23,13 @@
  * questions.
  */
 
-
 package sun.security.ssl;
 
 import java.io.IOException;
 import java.net.InetAddress;
 import java.net.Socket;
-
-import java.security.AlgorithmConstraints;
-
-import java.util.*;
-
-import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLParameters;
 import javax.net.ssl.SSLServerSocket;
-import javax.net.ssl.SSLParameters;
-import javax.net.ssl.SNIMatcher;
-
 
 /**
  * This class provides a simple way for servers to support conventional
@@ -62,301 +53,157 @@
  *
  * @author David Brownell
  */
-final
-class SSLServerSocketImpl extends SSLServerSocket
-{
-    private SSLContextImpl      sslContext;
-
-    /* Do newly accepted connections require clients to authenticate? */
-    private ClientAuthType    clientAuthType = ClientAuthType.CLIENT_AUTH_NONE;
-
-    /* Do new connections created here use the "server" mode of SSL? */
-    private boolean             useServerMode = true;
+final class SSLServerSocketImpl extends SSLServerSocket {
+    private final SSLContextImpl        sslContext;
+    private final SSLConfiguration      sslConfig;
 
-    /* Can new connections created establish new sessions? */
-    private boolean             enableSessionCreation = true;
-
-    /* what cipher suites to use by default */
-    private CipherSuiteList     enabledCipherSuites = null;
-
-    /* which protocol to use by default */
-    private ProtocolList        enabledProtocols = null;
-
-    // the endpoint identification protocol to use by default
-    private String              identificationProtocol = null;
-
-    // The cryptographic algorithm constraints
-    private AlgorithmConstraints    algorithmConstraints = null;
+    SSLServerSocketImpl(SSLContextImpl sslContext) throws IOException {
 
-    // The server name indication
-    Collection<SNIMatcher>      sniMatchers =
-                                    Collections.<SNIMatcher>emptyList();
-
-    // Configured application protocol values
-    String[] applicationProtocols = new String[0];
-
-    /*
-     * Whether local cipher suites preference in server side should be
-     * honored during handshaking?
-     */
-    private boolean             preferLocalCipherSuites = false;
+        super();
+        this.sslContext = sslContext;
+        this.sslConfig = new SSLConfiguration(sslContext, false);
+        this.sslConfig.isClientMode = false;
+    }
 
-    /**
-     * Create an SSL server socket on a port, using a non-default
-     * authentication context and a specified connection backlog.
-     *
-     * @param port the port on which to listen
-     * @param backlog how many connections may be pending before
-     *          the system should start rejecting new requests
-     * @param context authentication context for this server
-     */
-    SSLServerSocketImpl(int port, int backlog, SSLContextImpl context)
-    throws IOException, SSLException
-    {
+    SSLServerSocketImpl(SSLContextImpl sslContext,
+            int port, int backlog) throws IOException {
+
         super(port, backlog);
-        initServer(context);
+        this.sslContext = sslContext;
+        this.sslConfig = new SSLConfiguration(sslContext, false);
+        this.sslConfig.isClientMode = false;
     }
 
+    SSLServerSocketImpl(SSLContextImpl sslContext,
+            int port, int backlog, InetAddress address) throws IOException {
 
-    /**
-     * Create an SSL server socket on a port, using a specified
-     * authentication context and a specified backlog of connections
-     * as well as a particular specified network interface.  This
-     * constructor is used on multihomed hosts, such as those used
-     * for firewalls or as routers, to control through which interface
-     * a network service is provided.
-     *
-     * @param port the port on which to listen
-     * @param backlog how many connections may be pending before
-     *          the system should start rejecting new requests
-     * @param address the address of the network interface through
-     *          which connections will be accepted
-     * @param context authentication context for this server
-     */
-    SSLServerSocketImpl(
-        int             port,
-        int             backlog,
-        InetAddress     address,
-        SSLContextImpl  context)
-        throws IOException
-    {
         super(port, backlog, address);
-        initServer(context);
-    }
-
-
-    /**
-     * Creates an unbound server socket.
-     */
-    SSLServerSocketImpl(SSLContextImpl context) throws IOException {
-        super();
-        initServer(context);
+        this.sslContext = sslContext;
+        this.sslConfig = new SSLConfiguration(sslContext, false);
+        this.sslConfig.isClientMode = false;
     }
 
-
-    /**
-     * Initializes the server socket.
-     */
-    private void initServer(SSLContextImpl context) throws SSLException {
-        if (context == null) {
-            throw new SSLException("No Authentication context given");
-        }
-        sslContext = context;
-        enabledCipherSuites = sslContext.getDefaultCipherSuiteList(true);
-        enabledProtocols = sslContext.getDefaultProtocolList(true);
+    @Override
+    public synchronized String[] getEnabledCipherSuites() {
+        return CipherSuite.namesOf(sslConfig.enabledCipherSuites);
     }
 
-    /**
-     * 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
-     */
     @Override
-    public String[] getSupportedCipherSuites() {
-        return sslContext.getSupportedCipherSuiteList().toStringArray();
+    public synchronized void setEnabledCipherSuites(String[] suites) {
+        sslConfig.enabledCipherSuites =
+                CipherSuite.validValuesOf(suites);
     }
 
-    /**
-     * Returns the list of cipher suites which are currently enabled
-     * for use by newly accepted connections.  A null return indicates
-     * that the system defaults are in effect.
-     */
     @Override
-    public synchronized String[] getEnabledCipherSuites() {
-        return enabledCipherSuites.toStringArray();
-    }
-
-    /**
-     * Controls which particular SSL cipher suites are enabled for use
-     * by accepted connections.
-     *
-     * @param suites Names of all the cipher suites to enable; null
-     *  means to accept system defaults.
-     */
-    @Override
-    public synchronized void setEnabledCipherSuites(String[] suites) {
-        enabledCipherSuites = new CipherSuiteList(suites);
+    public String[] getSupportedCipherSuites() {
+        return CipherSuite.namesOf(sslContext.getSupportedCipherSuites());
     }
 
     @Override
     public String[] getSupportedProtocols() {
-        return sslContext.getSuportedProtocolList().toStringArray();
-    }
-
-    /**
-     * Controls which protocols are enabled for use.
-     * 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.
-     */
-    @Override
-    public synchronized void setEnabledProtocols(String[] protocols) {
-        enabledProtocols = new ProtocolList(protocols);
+        return ProtocolVersion.toStringArray(
+                sslContext.getSupportedProtocolVersions());
     }
 
     @Override
     public synchronized String[] getEnabledProtocols() {
-        return enabledProtocols.toStringArray();
+        return ProtocolVersion.toStringArray(sslConfig.enabledProtocols);
     }
 
-    /**
-     * Controls whether the connections which are accepted must include
-     * client authentication.
-     */
     @Override
-    public void setNeedClientAuth(boolean flag) {
-        clientAuthType = (flag ? ClientAuthType.CLIENT_AUTH_REQUIRED :
-                ClientAuthType.CLIENT_AUTH_NONE);
+    public synchronized void setEnabledProtocols(String[] protocols) {
+        if (protocols == null) {
+            throw new IllegalArgumentException("Protocols cannot be null");
+        }
+
+        sslConfig.enabledProtocols = ProtocolVersion.namesOf(protocols);
     }
 
     @Override
-    public boolean getNeedClientAuth() {
-        return (clientAuthType == ClientAuthType.CLIENT_AUTH_REQUIRED);
-    }
-
-    /**
-     * Controls whether the connections which are accepted should request
-     * client authentication.
-     */
-    @Override
-    public void setWantClientAuth(boolean flag) {
-        clientAuthType = (flag ? ClientAuthType.CLIENT_AUTH_REQUESTED :
-                ClientAuthType.CLIENT_AUTH_NONE);
+    public synchronized void setNeedClientAuth(boolean need) {
+        sslConfig.clientAuthType =
+                (need ? ClientAuthType.CLIENT_AUTH_REQUIRED :
+                        ClientAuthType.CLIENT_AUTH_NONE);
     }
 
     @Override
-    public boolean getWantClientAuth() {
-        return (clientAuthType == ClientAuthType.CLIENT_AUTH_REQUESTED);
+    public synchronized boolean getNeedClientAuth() {
+        return (sslConfig.clientAuthType ==
+                        ClientAuthType.CLIENT_AUTH_REQUIRED);
     }
 
-    /**
-     * Makes the returned sockets act in SSL "client" mode, not the usual
-     * server mode.  The canonical example of why this is needed is for
-     * FTP clients, which accept connections from servers and should be
-     * rejoining the already-negotiated SSL connection.
-     */
     @Override
-    public void setUseClientMode(boolean flag) {
-        /*
-         * If we need to change the socket mode and the enabled
-         * protocols haven't specifically been set by the user,
-         * change them to the corresponding default ones.
-         */
-        if (useServerMode != (!flag) &&
-                sslContext.isDefaultProtocolList(enabledProtocols)) {
-            enabledProtocols = sslContext.getDefaultProtocolList(!flag);
-        }
+    public synchronized void setWantClientAuth(boolean want) {
+        sslConfig.clientAuthType =
+                (want ? ClientAuthType.CLIENT_AUTH_REQUESTED :
+                        ClientAuthType.CLIENT_AUTH_NONE);
+    }
 
-        useServerMode = !flag;
+    @Override
+    public synchronized boolean getWantClientAuth() {
+        return (sslConfig.clientAuthType ==
+                        ClientAuthType.CLIENT_AUTH_REQUESTED);
     }
 
     @Override
-    public boolean getUseClientMode() {
-        return !useServerMode;
+    public synchronized void setUseClientMode(boolean useClientMode) {
+        /*
+         * If we need to change the client mode and the enabled
+         * protocols and cipher suites haven't specifically been
+         * set by the user, change them to the corresponding
+         * default ones.
+         */
+        if (sslConfig.isClientMode != useClientMode) {
+            if (sslContext.isDefaultProtocolVesions(
+                    sslConfig.enabledProtocols)) {
+                sslConfig.enabledProtocols =
+                        sslContext.getDefaultProtocolVersions(!useClientMode);
+            }
+
+            if (sslContext.isDefaultCipherSuiteList(
+                    sslConfig.enabledCipherSuites)) {
+                sslConfig.enabledCipherSuites =
+                        sslContext.getDefaultCipherSuites(!useClientMode);
+            }
+
+            sslConfig.isClientMode = useClientMode;
+        }
     }
 
-
-    /**
-     * Controls whether new connections may cause creation of new SSL
-     * sessions.
-     */
     @Override
-    public void setEnableSessionCreation(boolean flag) {
-        enableSessionCreation = flag;
+    public synchronized boolean getUseClientMode() {
+        return sslConfig.isClientMode;
     }
 
-    /**
-     * Returns true if new connections may cause creation of new SSL
-     * sessions.
-     */
     @Override
-    public boolean getEnableSessionCreation() {
-        return enableSessionCreation;
+    public synchronized void setEnableSessionCreation(boolean flag) {
+        sslConfig.enableSessionCreation = flag;
     }
 
-    /**
-     * Returns the SSLParameters in effect for newly accepted connections.
-     */
+    @Override
+    public synchronized boolean getEnableSessionCreation() {
+        return sslConfig.enableSessionCreation;
+    }
+
     @Override
     public synchronized SSLParameters getSSLParameters() {
-        SSLParameters params = super.getSSLParameters();
-
-        // the super implementation does not handle the following parameters
-        params.setEndpointIdentificationAlgorithm(identificationProtocol);
-        params.setAlgorithmConstraints(algorithmConstraints);
-        params.setSNIMatchers(sniMatchers);
-        params.setUseCipherSuitesOrder(preferLocalCipherSuites);
-        params.setApplicationProtocols(applicationProtocols);
-
-        return params;
+        return sslConfig.getSSLParameters();
     }
 
-    /**
-     * Applies SSLParameters to newly accepted connections.
-     */
     @Override
     public synchronized void setSSLParameters(SSLParameters params) {
-        super.setSSLParameters(params);
-
-        // the super implementation does not handle the following parameters
-        identificationProtocol = params.getEndpointIdentificationAlgorithm();
-        algorithmConstraints = params.getAlgorithmConstraints();
-        preferLocalCipherSuites = params.getUseCipherSuitesOrder();
-        Collection<SNIMatcher> matchers = params.getSNIMatchers();
-        if (matchers != null) {
-            sniMatchers = params.getSNIMatchers();
-        }
-        applicationProtocols = params.getApplicationProtocols();
+        sslConfig.setSSLParameters(params);
     }
 
-    /**
-     * Accept a new SSL connection.  This server identifies itself with
-     * information provided in the authentication context which was
-     * presented during construction.
-     */
     @Override
     public Socket accept() throws IOException {
-        SSLSocketImpl s = new SSLSocketImpl(sslContext, useServerMode,
-            enabledCipherSuites, clientAuthType, enableSessionCreation,
-            enabledProtocols, identificationProtocol, algorithmConstraints,
-            sniMatchers, preferLocalCipherSuites, applicationProtocols);
+        SSLSocketImpl s = new SSLSocketImpl(sslContext, sslConfig);
 
         implAccept(s);
         s.doneConnect();
         return s;
     }
 
-    /**
-     * Provides a brief description of this SSL socket.
-     */
     @Override
     public String toString() {
         return "[SSL: "+ super.toString() + "]";