1 /*
   2  * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 
  27 package sun.security.ssl;
  28 
  29 import java.io.IOException;
  30 import java.net.InetAddress;
  31 import java.net.Socket;
  32 
  33 import java.security.AlgorithmConstraints;
  34 
  35 import java.util.*;
  36 
  37 import javax.net.ssl.SSLException;
  38 import javax.net.ssl.SSLServerSocket;
  39 import javax.net.ssl.SSLParameters;
  40 import javax.net.ssl.SNIMatcher;
  41 
  42 
  43 /**
  44  * This class provides a simple way for servers to support conventional
  45  * use of the Secure Sockets Layer (SSL).  Application code uses an
  46  * SSLServerSocketImpl exactly like it uses a regular TCP ServerSocket; the
  47  * difference is that the connections established are secured using SSL.
  48  *
  49  * <P> Also, the constructors take an explicit authentication context
  50  * parameter, giving flexibility with respect to how the server socket
  51  * authenticates itself.  That policy flexibility is not exposed through
  52  * the standard SSLServerSocketFactory API.
  53  *
  54  * <P> System security defaults prevent server sockets from accepting
  55  * connections if they the authentication context has not been given
  56  * a certificate chain and its matching private key.  If the clients
  57  * of your application support "anonymous" cipher suites, you may be
  58  * able to configure a server socket to accept those suites.
  59  *
  60  * @see SSLSocketImpl
  61  * @see SSLServerSocketFactoryImpl
  62  *
  63  * @author David Brownell
  64  */
  65 final
  66 class SSLServerSocketImpl extends SSLServerSocket
  67 {
  68     private SSLContextImpl      sslContext;
  69 
  70     /* Do newly accepted connections require clients to authenticate? */
  71     private ClientAuthType    clientAuthType = ClientAuthType.CLIENT_AUTH_NONE;
  72 
  73     /* Do new connections created here use the "server" mode of SSL? */
  74     private boolean             useServerMode = true;
  75 
  76     /* Can new connections created establish new sessions? */
  77     private boolean             enableSessionCreation = true;
  78 
  79     /* what cipher suites to use by default */
  80     private CipherSuiteList     enabledCipherSuites = null;
  81 
  82     /* which protocol to use by default */
  83     private ProtocolList        enabledProtocols = null;
  84 
  85     // the endpoint identification protocol to use by default
  86     private String              identificationProtocol = null;
  87 
  88     // The cryptographic algorithm constraints
  89     private AlgorithmConstraints    algorithmConstraints = null;
  90 
  91     // The server name indication
  92     Collection<SNIMatcher>      sniMatchers =
  93                                     Collections.<SNIMatcher>emptyList();
  94 
  95     // Configured application protocol values
  96     String[] applicationProtocols = new String[0];
  97 
  98     /*
  99      * Whether local cipher suites preference in server side should be
 100      * honored during handshaking?
 101      */
 102     private boolean             preferLocalCipherSuites = false;
 103 
 104     /**
 105      * Create an SSL server socket on a port, using a non-default
 106      * authentication context and a specified connection backlog.
 107      *
 108      * @param port the port on which to listen
 109      * @param backlog how many connections may be pending before
 110      *          the system should start rejecting new requests
 111      * @param context authentication context for this server
 112      */
 113     SSLServerSocketImpl(int port, int backlog, SSLContextImpl context)
 114     throws IOException, SSLException
 115     {
 116         super(port, backlog);
 117         initServer(context);
 118     }
 119 
 120 
 121     /**
 122      * Create an SSL server socket on a port, using a specified
 123      * authentication context and a specified backlog of connections
 124      * as well as a particular specified network interface.  This
 125      * constructor is used on multihomed hosts, such as those used
 126      * for firewalls or as routers, to control through which interface
 127      * a network service is provided.
 128      *
 129      * @param port the port on which to listen
 130      * @param backlog how many connections may be pending before
 131      *          the system should start rejecting new requests
 132      * @param address the address of the network interface through
 133      *          which connections will be accepted
 134      * @param context authentication context for this server
 135      */
 136     SSLServerSocketImpl(
 137         int             port,
 138         int             backlog,
 139         InetAddress     address,
 140         SSLContextImpl  context)
 141         throws IOException
 142     {
 143         super(port, backlog, address);
 144         initServer(context);
 145     }
 146 
 147 
 148     /**
 149      * Creates an unbound server socket.
 150      */
 151     SSLServerSocketImpl(SSLContextImpl context) throws IOException {
 152         super();
 153         initServer(context);
 154     }
 155 
 156 
 157     /**
 158      * Initializes the server socket.
 159      */
 160     private void initServer(SSLContextImpl context) throws SSLException {
 161         if (context == null) {
 162             throw new SSLException("No Authentication context given");
 163         }
 164         sslContext = context;
 165         enabledCipherSuites = sslContext.getDefaultCipherSuiteList(true);
 166         enabledProtocols = sslContext.getDefaultProtocolList(true);
 167     }
 168 
 169     /**
 170      * Returns the names of the cipher suites which could be enabled for use
 171      * on an SSL connection.  Normally, only a subset of these will actually
 172      * be enabled by default, since this list may include cipher suites which
 173      * do not support the mutual authentication of servers and clients, or
 174      * which do not protect data confidentiality.  Servers may also need
 175      * certain kinds of certificates to use certain cipher suites.
 176      *
 177      * @return an array of cipher suite names
 178      */
 179     @Override
 180     public String[] getSupportedCipherSuites() {
 181         return sslContext.getSupportedCipherSuiteList().toStringArray();
 182     }
 183 
 184     /**
 185      * Returns the list of cipher suites which are currently enabled
 186      * for use by newly accepted connections.  A null return indicates
 187      * that the system defaults are in effect.
 188      */
 189     @Override
 190     public synchronized String[] getEnabledCipherSuites() {
 191         return enabledCipherSuites.toStringArray();
 192     }
 193 
 194     /**
 195      * Controls which particular SSL cipher suites are enabled for use
 196      * by accepted connections.
 197      *
 198      * @param suites Names of all the cipher suites to enable; null
 199      *  means to accept system defaults.
 200      */
 201     @Override
 202     public synchronized void setEnabledCipherSuites(String[] suites) {
 203         enabledCipherSuites = new CipherSuiteList(suites);
 204     }
 205 
 206     @Override
 207     public String[] getSupportedProtocols() {
 208         return sslContext.getSuportedProtocolList().toStringArray();
 209     }
 210 
 211     /**
 212      * Controls which protocols are enabled for use.
 213      * The protocols must have been listed by
 214      * getSupportedProtocols() as being supported.
 215      *
 216      * @param protocols protocols to enable.
 217      * @exception IllegalArgumentException when one of the protocols
 218      *  named by the parameter is not supported.
 219      */
 220     @Override
 221     public synchronized void setEnabledProtocols(String[] protocols) {
 222         enabledProtocols = new ProtocolList(protocols);
 223     }
 224 
 225     @Override
 226     public synchronized String[] getEnabledProtocols() {
 227         return enabledProtocols.toStringArray();
 228     }
 229 
 230     /**
 231      * Controls whether the connections which are accepted must include
 232      * client authentication.
 233      */
 234     @Override
 235     public void setNeedClientAuth(boolean flag) {
 236         clientAuthType = (flag ? ClientAuthType.CLIENT_AUTH_REQUIRED :
 237                 ClientAuthType.CLIENT_AUTH_NONE);
 238     }
 239 
 240     @Override
 241     public boolean getNeedClientAuth() {
 242         return (clientAuthType == ClientAuthType.CLIENT_AUTH_REQUIRED);
 243     }
 244 
 245     /**
 246      * Controls whether the connections which are accepted should request
 247      * client authentication.
 248      */
 249     @Override
 250     public void setWantClientAuth(boolean flag) {
 251         clientAuthType = (flag ? ClientAuthType.CLIENT_AUTH_REQUESTED :
 252                 ClientAuthType.CLIENT_AUTH_NONE);
 253     }
 254 
 255     @Override
 256     public boolean getWantClientAuth() {
 257         return (clientAuthType == ClientAuthType.CLIENT_AUTH_REQUESTED);
 258     }
 259 
 260     /**
 261      * Makes the returned sockets act in SSL "client" mode, not the usual
 262      * server mode.  The canonical example of why this is needed is for
 263      * FTP clients, which accept connections from servers and should be
 264      * rejoining the already-negotiated SSL connection.
 265      */
 266     @Override
 267     public void setUseClientMode(boolean flag) {
 268         /*
 269          * If we need to change the socket mode and the enabled
 270          * protocols haven't specifically been set by the user,
 271          * change them to the corresponding default ones.
 272          */
 273         if (useServerMode != (!flag) &&
 274                 sslContext.isDefaultProtocolList(enabledProtocols)) {
 275             enabledProtocols = sslContext.getDefaultProtocolList(!flag);
 276         }
 277 
 278         useServerMode = !flag;
 279     }
 280 
 281     @Override
 282     public boolean getUseClientMode() {
 283         return !useServerMode;
 284     }
 285 
 286 
 287     /**
 288      * Controls whether new connections may cause creation of new SSL
 289      * sessions.
 290      */
 291     @Override
 292     public void setEnableSessionCreation(boolean flag) {
 293         enableSessionCreation = flag;
 294     }
 295 
 296     /**
 297      * Returns true if new connections may cause creation of new SSL
 298      * sessions.
 299      */
 300     @Override
 301     public boolean getEnableSessionCreation() {
 302         return enableSessionCreation;
 303     }
 304 
 305     /**
 306      * Returns the SSLParameters in effect for newly accepted connections.
 307      */
 308     @Override
 309     public synchronized SSLParameters getSSLParameters() {
 310         SSLParameters params = super.getSSLParameters();
 311 
 312         // the super implementation does not handle the following parameters
 313         params.setEndpointIdentificationAlgorithm(identificationProtocol);
 314         params.setAlgorithmConstraints(algorithmConstraints);
 315         params.setSNIMatchers(sniMatchers);
 316         params.setUseCipherSuitesOrder(preferLocalCipherSuites);
 317         params.setApplicationProtocols(applicationProtocols);
 318 
 319         return params;
 320     }
 321 
 322     /**
 323      * Applies SSLParameters to newly accepted connections.
 324      */
 325     @Override
 326     public synchronized void setSSLParameters(SSLParameters params) {
 327         super.setSSLParameters(params);
 328 
 329         // the super implementation does not handle the following parameters
 330         identificationProtocol = params.getEndpointIdentificationAlgorithm();
 331         algorithmConstraints = params.getAlgorithmConstraints();
 332         preferLocalCipherSuites = params.getUseCipherSuitesOrder();
 333         Collection<SNIMatcher> matchers = params.getSNIMatchers();
 334         if (matchers != null) {
 335             sniMatchers = params.getSNIMatchers();
 336         }
 337         applicationProtocols = params.getApplicationProtocols();
 338     }
 339 
 340     /**
 341      * Accept a new SSL connection.  This server identifies itself with
 342      * information provided in the authentication context which was
 343      * presented during construction.
 344      */
 345     @Override
 346     public Socket accept() throws IOException {
 347         SSLSocketImpl s = new SSLSocketImpl(sslContext, useServerMode,
 348             enabledCipherSuites, clientAuthType, enableSessionCreation,
 349             enabledProtocols, identificationProtocol, algorithmConstraints,
 350             sniMatchers, preferLocalCipherSuites, applicationProtocols);
 351 
 352         implAccept(s);
 353         s.doneConnect();
 354         return s;
 355     }
 356 
 357     /**
 358      * Provides a brief description of this SSL socket.
 359      */
 360     @Override
 361     public String toString() {
 362         return "[SSL: "+ super.toString() + "]";
 363     }
 364 }