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
27package sun.security.ssl;
28
29import java.io.IOException;
30import java.net.InetAddress;
31import java.net.Socket;
32
33import java.security.AlgorithmConstraints;
34
35import java.util.*;
36
37import javax.net.ssl.SSLException;
38import javax.net.ssl.SSLServerSocket;
39import javax.net.ssl.SSLParameters;
40import 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 */
65final
66class 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}
365