/*
* Copyright (c) 1996, 2016, 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.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.SSLServerSocket;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SNIMatcher;
This class provides a simple way for servers to support conventional
use of the Secure Sockets Layer (SSL). Application code uses an
SSLServerSocketImpl exactly like it uses a regular TCP ServerSocket; the
difference is that the connections established are secured using SSL.
Also, the constructors take an explicit authentication context
parameter, giving flexibility with respect to how the server socket
authenticates itself. That policy flexibility is not exposed through
the standard SSLServerSocketFactory API.
System security defaults prevent server sockets from accepting
connections if they the authentication context has not been given
a certificate chain and its matching private key. If the clients
of your application support "anonymous" cipher suites, you may be
able to configure a server socket to accept those suites.
Author: David Brownell See Also: - SSLSocketImpl
- SSLServerSocketFactoryImpl
/**
* This class provides a simple way for servers to support conventional
* use of the Secure Sockets Layer (SSL). Application code uses an
* SSLServerSocketImpl exactly like it uses a regular TCP ServerSocket; the
* difference is that the connections established are secured using SSL.
*
* <P> Also, the constructors take an explicit authentication context
* parameter, giving flexibility with respect to how the server socket
* authenticates itself. That policy flexibility is not exposed through
* the standard SSLServerSocketFactory API.
*
* <P> System security defaults prevent server sockets from accepting
* connections if they the authentication context has not been given
* a certificate chain and its matching private key. If the clients
* of your application support "anonymous" cipher suites, you may be
* able to configure a server socket to accept those suites.
*
* @see SSLSocketImpl
* @see SSLServerSocketFactoryImpl
*
* @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;
/* 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;
// 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;
Create an SSL server socket on a port, using a non-default
authentication context and a specified connection backlog.
Params: - port – the port on which to listen
- backlog – how many connections may be pending before
the system should start rejecting new requests
- context – authentication context for this server
/**
* 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
{
super(port, backlog);
initServer(context);
}
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.
Params: - port – the port on which to listen
- backlog – how many connections may be pending before
the system should start rejecting new requests
- address – the address of the network interface through
which connections will be accepted
- context – authentication context for this server
/**
* 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.
/**
* Creates an unbound server socket.
*/
SSLServerSocketImpl(SSLContextImpl context) throws IOException {
super();
initServer(context);
}
Initializes the server socket.
/**
* 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);
}
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.
Returns: an array of cipher suite names
/**
* 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();
}
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.
/**
* 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.
Params: - suites – Names of all the cipher suites to enable; null
means to accept system defaults.
/**
* 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);
}
@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.
Params: - protocols – protocols to enable.
Throws: - IllegalArgumentException – when one of the protocols
named by the parameter is not supported.
/**
* 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);
}
@Override
public synchronized String[] getEnabledProtocols() {
return enabledProtocols.toStringArray();
}
Controls whether the connections which are accepted must include
client authentication.
/**
* 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);
}
@Override
public boolean getNeedClientAuth() {
return (clientAuthType == ClientAuthType.CLIENT_AUTH_REQUIRED);
}
Controls whether the connections which are accepted should request
client authentication.
/**
* 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);
}
@Override
public boolean getWantClientAuth() {
return (clientAuthType == ClientAuthType.CLIENT_AUTH_REQUESTED);
}
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.
/**
* 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);
}
useServerMode = !flag;
}
@Override
public boolean getUseClientMode() {
return !useServerMode;
}
Controls whether new connections may cause creation of new SSL
sessions.
/**
* Controls whether new connections may cause creation of new SSL
* sessions.
*/
@Override
public void setEnableSessionCreation(boolean flag) {
enableSessionCreation = flag;
}
Returns true if new connections may cause creation of new SSL
sessions.
/**
* Returns true if new connections may cause creation of new SSL
* sessions.
*/
@Override
public boolean getEnableSessionCreation() {
return enableSessionCreation;
}
Returns the SSLParameters in effect for newly accepted connections.
/**
* Returns the SSLParameters in effect for newly accepted connections.
*/
@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;
}
Applies SSLParameters to newly accepted connections.
/**
* 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();
}
Accept a new SSL connection. This server identifies itself with
information provided in the authentication context which was
presented during construction.
/**
* 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);
implAccept(s);
s.doneConnect();
return s;
}
Provides a brief description of this SSL socket.
/**
* Provides a brief description of this SSL socket.
*/
@Override
public String toString() {
return "[SSL: "+ super.toString() + "]";
}
}