1/* 2 * Copyright (c) 1996, 2012, 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; 32import java.net.ServerSocket; 33 34import java.security.AlgorithmConstraints; 35 36import java.util.*; 37 38import javax.net.ServerSocketFactory; 39import javax.net.ssl.SSLException; 40import javax.net.ssl.SSLServerSocket; 41import javax.net.ssl.SSLParameters; 42 43 44/** 45 * This class provides a simple way for servers to support conventional 46 * use of the Secure Sockets Layer (SSL). Application code uses an 47 * SSLServerSocketImpl exactly like it uses a regular TCP ServerSocket; the 48 * difference is that the connections established are secured using SSL. 49 * 50 * <P> Also, the constructors take an explicit authentication context 51 * parameter, giving flexibility with respect to how the server socket 52 * authenticates itself. That policy flexibility is not exposed through 53 * the standard SSLServerSocketFactory API. 54 * 55 * <P> System security defaults prevent server sockets from accepting 56 * connections if they the authentication context has not been given 57 * a certificate chain and its matching private key. If the clients 58 * of your application support "anonymous" cipher suites, you may be 59 * able to configure a server socket to accept those suites. 60 * 61 * @see SSLSocketImpl 62 * @see SSLServerSocketFactoryImpl 63 * 64 * @author David Brownell 65 */ 66final 67class SSLServerSocketImpl extends SSLServerSocket 68{ 69 private SSLContextImpl sslContext; 70 71 /* Do newly accepted connections require clients to authenticate? */ 72 private byte doClientAuth = SSLEngineImpl.clauth_none; 73 74 /* Do new connections created here use the "server" mode of SSL? */ 75 private boolean useServerMode = true; 76 77 /* Can new connections created establish new sessions? */ 78 private boolean enableSessionCreation = true; 79 80 /* what cipher suites to use by default */ 81 private CipherSuiteList enabledCipherSuites = null; 82 83 /* which protocol to use by default */ 84 private ProtocolList enabledProtocols = null; 85 86 /* could enabledCipherSuites ever complete handshaking? */ 87 private boolean checkedEnabled = false; 88 89 // the endpoint identification protocol to use by default 90 private String identificationProtocol = null; 91 92 // The cryptographic algorithm constraints 93 private AlgorithmConstraints algorithmConstraints = null; 94 95 /** 96 * Create an SSL server socket on a port, using a non-default 97 * authentication context and a specified connection backlog. 98 * 99 * @param port the port on which to listen 100 * @param backlog how many connections may be pending before 101 * the system should start rejecting new requests 102 * @param context authentication context for this server 103 */ 104 SSLServerSocketImpl(int port, int backlog, SSLContextImpl context) 105 throws IOException, SSLException 106 { 107 super(port, backlog); 108 initServer(context); 109 } 110 111 112 /** 113 * Create an SSL server socket on a port, using a specified 114 * authentication context and a specified backlog of connections 115 * as well as a particular specified network interface. This 116 * constructor is used on multihomed hosts, such as those used 117 * for firewalls or as routers, to control through which interface 118 * a network service is provided. 119 * 120 * @param port the port on which to listen 121 * @param backlog how many connections may be pending before 122 * the system should start rejecting new requests 123 * @param address the address of the network interface through 124 * which connections will be accepted 125 * @param context authentication context for this server 126 */ 127 SSLServerSocketImpl( 128 int port, 129 int backlog, 130 InetAddress address, 131 SSLContextImpl context) 132 throws IOException 133 { 134 super(port, backlog, address); 135 initServer(context); 136 } 137 138 139 /** 140 * Creates an unbound server socket. 141 */ 142 SSLServerSocketImpl(SSLContextImpl context) throws IOException { 143 super(); 144 initServer(context); 145 } 146 147 148 /** 149 * Initializes the server socket. 150 */ 151 private void initServer(SSLContextImpl context) throws SSLException { 152 if (context == null) { 153 throw new SSLException("No Authentication context given"); 154 } 155 sslContext = context; 156 enabledCipherSuites = sslContext.getDefaultCipherSuiteList(true); 157 enabledProtocols = sslContext.getDefaultProtocolList(true); 158 } 159 160 /** 161 * Returns the names of the cipher suites which could be enabled for use 162 * on an SSL connection. Normally, only a subset of these will actually 163 * be enabled by default, since this list may include cipher suites which 164 * do not support the mutual authentication of servers and clients, or 165 * which do not protect data confidentiality. Servers may also need 166 * certain kinds of certificates to use certain cipher suites. 167 * 168 * @return an array of cipher suite names 169 */ 170 public String[] getSupportedCipherSuites() { 171 return sslContext.getSupportedCipherSuiteList().toStringArray(); 172 } 173 174 /** 175 * Returns the list of cipher suites which are currently enabled 176 * for use by newly accepted connections. A null return indicates 177 * that the system defaults are in effect. 178 */ 179 synchronized public String[] getEnabledCipherSuites() { 180 return enabledCipherSuites.toStringArray(); 181 } 182 183 /** 184 * Controls which particular SSL cipher suites are enabled for use 185 * by accepted connections. 186 * 187 * @param suites Names of all the cipher suites to enable; null 188 * means to accept system defaults. 189 */ 190 synchronized public void setEnabledCipherSuites(String[] suites) { 191 enabledCipherSuites = new CipherSuiteList(suites); 192 checkedEnabled = false; 193 } 194 195 public String[] getSupportedProtocols() { 196 return sslContext.getSuportedProtocolList().toStringArray(); 197 } 198 199 /** 200 * Controls which protocols are enabled for use. 201 * The protocols must have been listed by 202 * getSupportedProtocols() as being supported. 203 * 204 * @param protocols protocols to enable. 205 * @exception IllegalArgumentException when one of the protocols 206 * named by the parameter is not supported. 207 */ 208 synchronized public void setEnabledProtocols(String[] protocols) { 209 enabledProtocols = new ProtocolList(protocols); 210 } 211 212 synchronized public String[] getEnabledProtocols() { 213 return enabledProtocols.toStringArray(); 214 } 215 216 /** 217 * Controls whether the connections which are accepted must include 218 * client authentication. 219 */ 220 public void setNeedClientAuth(boolean flag) { 221 doClientAuth = (flag ? 222 SSLEngineImpl.clauth_required : SSLEngineImpl.clauth_none); 223 } 224 225 public boolean getNeedClientAuth() { 226 return (doClientAuth == SSLEngineImpl.clauth_required); 227 } 228 229 /** 230 * Controls whether the connections which are accepted should request 231 * client authentication. 232 */ 233 public void setWantClientAuth(boolean flag) { 234 doClientAuth = (flag ? 235 SSLEngineImpl.clauth_requested : SSLEngineImpl.clauth_none); 236 } 237 238 public boolean getWantClientAuth() { 239 return (doClientAuth == SSLEngineImpl.clauth_requested); 240 } 241 242 /** 243 * Makes the returned sockets act in SSL "client" mode, not the usual 244 * server mode. The canonical example of why this is needed is for 245 * FTP clients, which accept connections from servers and should be 246 * rejoining the already-negotiated SSL connection. 247 */ 248 public void setUseClientMode(boolean flag) { 249 /* 250 * If we need to change the socket mode and the enabled 251 * protocols haven't specifically been set by the user, 252 * change them to the corresponding default ones. 253 */ 254 if (useServerMode != (!flag) && 255 sslContext.isDefaultProtocolList(enabledProtocols)) { 256 enabledProtocols = sslContext.getDefaultProtocolList(!flag); 257 } 258 259 useServerMode = !flag; 260 } 261 262 public boolean getUseClientMode() { 263 return !useServerMode; 264 } 265 266 267 /** 268 * Controls whether new connections may cause creation of new SSL 269 * sessions. 270 */ 271 public void setEnableSessionCreation(boolean flag) { 272 enableSessionCreation = flag; 273 } 274 275 /** 276 * Returns true if new connections may cause creation of new SSL 277 * sessions. 278 */ 279 public boolean getEnableSessionCreation() { 280 return enableSessionCreation; 281 } 282 283 /** 284 * Returns the SSLParameters in effect for newly accepted connections. 285 */ 286 synchronized public SSLParameters getSSLParameters() { 287 SSLParameters params = super.getSSLParameters(); 288 289 // the super implementation does not handle the following parameters 290 params.setEndpointIdentificationAlgorithm(identificationProtocol); 291 params.setAlgorithmConstraints(algorithmConstraints); 292 293 return params; 294 } 295 296 /** 297 * Applies SSLParameters to newly accepted connections. 298 */ 299 synchronized public void setSSLParameters(SSLParameters params) { 300 super.setSSLParameters(params); 301 302 // the super implementation does not handle the following parameters 303 identificationProtocol = params.getEndpointIdentificationAlgorithm(); 304 algorithmConstraints = params.getAlgorithmConstraints(); 305 } 306 307 /** 308 * Accept a new SSL connection. This server identifies itself with 309 * information provided in the authentication context which was 310 * presented during construction. 311 */ 312 public Socket accept() throws IOException { 313 SSLSocketImpl s = new SSLSocketImpl(sslContext, useServerMode, 314 enabledCipherSuites, doClientAuth, enableSessionCreation, 315 enabledProtocols, identificationProtocol, algorithmConstraints); 316 317 implAccept(s); 318 s.doneConnect(); 319 return s; 320 } 321 322 /** 323 * Provides a brief description of this SSL socket. 324 */ 325 public String toString() { 326 return "[SSL: "+ super.toString() + "]"; 327 } 328} 329