60 * @see SSLSocketImpl |
51 * @see SSLSocketImpl |
61 * @see SSLServerSocketFactoryImpl |
52 * @see SSLServerSocketFactoryImpl |
62 * |
53 * |
63 * @author David Brownell |
54 * @author David Brownell |
64 */ |
55 */ |
65 final |
56 final class SSLServerSocketImpl extends SSLServerSocket { |
66 class SSLServerSocketImpl extends SSLServerSocket |
57 private final SSLContextImpl sslContext; |
67 { |
58 private final SSLConfiguration sslConfig; |
68 private SSLContextImpl sslContext; |
59 |
69 |
60 SSLServerSocketImpl(SSLContextImpl sslContext) throws IOException { |
70 /* Do newly accepted connections require clients to authenticate? */ |
61 |
71 private ClientAuthType clientAuthType = ClientAuthType.CLIENT_AUTH_NONE; |
62 super(); |
72 |
63 this.sslContext = sslContext; |
73 /* Do new connections created here use the "server" mode of SSL? */ |
64 this.sslConfig = new SSLConfiguration(sslContext, false); |
74 private boolean useServerMode = true; |
65 this.sslConfig.isClientMode = false; |
75 |
66 } |
76 /* Can new connections created establish new sessions? */ |
67 |
77 private boolean enableSessionCreation = true; |
68 SSLServerSocketImpl(SSLContextImpl sslContext, |
78 |
69 int port, int backlog) throws IOException { |
79 /* what cipher suites to use by default */ |
70 |
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); |
71 super(port, backlog); |
117 initServer(context); |
72 this.sslContext = sslContext; |
118 } |
73 this.sslConfig = new SSLConfiguration(sslContext, false); |
119 |
74 this.sslConfig.isClientMode = false; |
120 |
75 } |
121 /** |
76 |
122 * Create an SSL server socket on a port, using a specified |
77 SSLServerSocketImpl(SSLContextImpl sslContext, |
123 * authentication context and a specified backlog of connections |
78 int port, int backlog, InetAddress address) throws IOException { |
124 * as well as a particular specified network interface. This |
79 |
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); |
80 super(port, backlog, address); |
144 initServer(context); |
81 this.sslContext = sslContext; |
145 } |
82 this.sslConfig = new SSLConfiguration(sslContext, false); |
146 |
83 this.sslConfig.isClientMode = false; |
147 |
84 } |
148 /** |
85 |
149 * Creates an unbound server socket. |
86 @Override |
150 */ |
87 public synchronized String[] getEnabledCipherSuites() { |
151 SSLServerSocketImpl(SSLContextImpl context) throws IOException { |
88 return CipherSuite.namesOf(sslConfig.enabledCipherSuites); |
152 super(); |
89 } |
153 initServer(context); |
90 |
154 } |
91 @Override |
155 |
92 public synchronized void setEnabledCipherSuites(String[] suites) { |
156 |
93 sslConfig.enabledCipherSuites = |
157 /** |
94 CipherSuite.validValuesOf(suites); |
158 * Initializes the server socket. |
95 } |
159 */ |
96 |
160 private void initServer(SSLContextImpl context) throws SSLException { |
97 @Override |
161 if (context == null) { |
98 public String[] getSupportedCipherSuites() { |
162 throw new SSLException("No Authentication context given"); |
99 return CipherSuite.namesOf(sslContext.getSupportedCipherSuites()); |
|
100 } |
|
101 |
|
102 @Override |
|
103 public String[] getSupportedProtocols() { |
|
104 return ProtocolVersion.toStringArray( |
|
105 sslContext.getSupportedProtocolVersions()); |
|
106 } |
|
107 |
|
108 @Override |
|
109 public synchronized String[] getEnabledProtocols() { |
|
110 return ProtocolVersion.toStringArray(sslConfig.enabledProtocols); |
|
111 } |
|
112 |
|
113 @Override |
|
114 public synchronized void setEnabledProtocols(String[] protocols) { |
|
115 if (protocols == null) { |
|
116 throw new IllegalArgumentException("Protocols cannot be null"); |
163 } |
117 } |
164 sslContext = context; |
118 |
165 enabledCipherSuites = sslContext.getDefaultCipherSuiteList(true); |
119 sslConfig.enabledProtocols = ProtocolVersion.namesOf(protocols); |
166 enabledProtocols = sslContext.getDefaultProtocolList(true); |
120 } |
167 } |
121 |
168 |
122 @Override |
169 /** |
123 public synchronized void setNeedClientAuth(boolean need) { |
170 * Returns the names of the cipher suites which could be enabled for use |
124 sslConfig.clientAuthType = |
171 * on an SSL connection. Normally, only a subset of these will actually |
125 (need ? ClientAuthType.CLIENT_AUTH_REQUIRED : |
172 * be enabled by default, since this list may include cipher suites which |
126 ClientAuthType.CLIENT_AUTH_NONE); |
173 * do not support the mutual authentication of servers and clients, or |
127 } |
174 * which do not protect data confidentiality. Servers may also need |
128 |
175 * certain kinds of certificates to use certain cipher suites. |
129 @Override |
176 * |
130 public synchronized boolean getNeedClientAuth() { |
177 * @return an array of cipher suite names |
131 return (sslConfig.clientAuthType == |
178 */ |
132 ClientAuthType.CLIENT_AUTH_REQUIRED); |
179 @Override |
133 } |
180 public String[] getSupportedCipherSuites() { |
134 |
181 return sslContext.getSupportedCipherSuiteList().toStringArray(); |
135 @Override |
182 } |
136 public synchronized void setWantClientAuth(boolean want) { |
183 |
137 sslConfig.clientAuthType = |
184 /** |
138 (want ? ClientAuthType.CLIENT_AUTH_REQUESTED : |
185 * Returns the list of cipher suites which are currently enabled |
139 ClientAuthType.CLIENT_AUTH_NONE); |
186 * for use by newly accepted connections. A null return indicates |
140 } |
187 * that the system defaults are in effect. |
141 |
188 */ |
142 @Override |
189 @Override |
143 public synchronized boolean getWantClientAuth() { |
190 public synchronized String[] getEnabledCipherSuites() { |
144 return (sslConfig.clientAuthType == |
191 return enabledCipherSuites.toStringArray(); |
145 ClientAuthType.CLIENT_AUTH_REQUESTED); |
192 } |
146 } |
193 |
147 |
194 /** |
148 @Override |
195 * Controls which particular SSL cipher suites are enabled for use |
149 public synchronized void setUseClientMode(boolean useClientMode) { |
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 /* |
150 /* |
269 * If we need to change the socket mode and the enabled |
151 * If we need to change the client mode and the enabled |
270 * protocols haven't specifically been set by the user, |
152 * protocols and cipher suites haven't specifically been |
271 * change them to the corresponding default ones. |
153 * set by the user, change them to the corresponding |
|
154 * default ones. |
272 */ |
155 */ |
273 if (useServerMode != (!flag) && |
156 if (sslConfig.isClientMode != useClientMode) { |
274 sslContext.isDefaultProtocolList(enabledProtocols)) { |
157 if (sslContext.isDefaultProtocolVesions( |
275 enabledProtocols = sslContext.getDefaultProtocolList(!flag); |
158 sslConfig.enabledProtocols)) { |
|
159 sslConfig.enabledProtocols = |
|
160 sslContext.getDefaultProtocolVersions(!useClientMode); |
|
161 } |
|
162 |
|
163 if (sslContext.isDefaultCipherSuiteList( |
|
164 sslConfig.enabledCipherSuites)) { |
|
165 sslConfig.enabledCipherSuites = |
|
166 sslContext.getDefaultCipherSuites(!useClientMode); |
|
167 } |
|
168 |
|
169 sslConfig.isClientMode = useClientMode; |
276 } |
170 } |
277 |
171 } |
278 useServerMode = !flag; |
172 |
279 } |
173 @Override |
280 |
174 public synchronized boolean getUseClientMode() { |
281 @Override |
175 return sslConfig.isClientMode; |
282 public boolean getUseClientMode() { |
176 } |
283 return !useServerMode; |
177 |
284 } |
178 @Override |
285 |
179 public synchronized void setEnableSessionCreation(boolean flag) { |
286 |
180 sslConfig.enableSessionCreation = flag; |
287 /** |
181 } |
288 * Controls whether new connections may cause creation of new SSL |
182 |
289 * sessions. |
183 @Override |
290 */ |
184 public synchronized boolean getEnableSessionCreation() { |
291 @Override |
185 return sslConfig.enableSessionCreation; |
292 public void setEnableSessionCreation(boolean flag) { |
186 } |
293 enableSessionCreation = flag; |
187 |
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 |
188 @Override |
309 public synchronized SSLParameters getSSLParameters() { |
189 public synchronized SSLParameters getSSLParameters() { |
310 SSLParameters params = super.getSSLParameters(); |
190 return sslConfig.getSSLParameters(); |
311 |
191 } |
312 // the super implementation does not handle the following parameters |
192 |
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 |
193 @Override |
326 public synchronized void setSSLParameters(SSLParameters params) { |
194 public synchronized void setSSLParameters(SSLParameters params) { |
327 super.setSSLParameters(params); |
195 sslConfig.setSSLParameters(params); |
328 |
196 } |
329 // the super implementation does not handle the following parameters |
197 |
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 |
198 @Override |
346 public Socket accept() throws IOException { |
199 public Socket accept() throws IOException { |
347 SSLSocketImpl s = new SSLSocketImpl(sslContext, useServerMode, |
200 SSLSocketImpl s = new SSLSocketImpl(sslContext, sslConfig); |
348 enabledCipherSuites, clientAuthType, enableSessionCreation, |
|
349 enabledProtocols, identificationProtocol, algorithmConstraints, |
|
350 sniMatchers, preferLocalCipherSuites, applicationProtocols); |
|
351 |
201 |
352 implAccept(s); |
202 implAccept(s); |
353 s.doneConnect(); |
203 s.doneConnect(); |
354 return s; |
204 return s; |
355 } |
205 } |
356 |
206 |
357 /** |
|
358 * Provides a brief description of this SSL socket. |
|
359 */ |
|
360 @Override |
207 @Override |
361 public String toString() { |
208 public String toString() { |
362 return "[SSL: "+ super.toString() + "]"; |
209 return "[SSL: "+ super.toString() + "]"; |
363 } |
210 } |
364 } |
211 } |