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 if (suites == null) { |
157 /** |
94 throw new IllegalArgumentException("CipherSuites cannot be null"); |
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 } |
95 } |
164 sslContext = context; |
96 |
165 enabledCipherSuites = sslContext.getDefaultCipherSuiteList(true); |
97 sslConfig.enabledCipherSuites = |
166 enabledProtocols = sslContext.getDefaultProtocolList(true); |
98 CipherSuite.validValuesOf(suites); |
167 } |
99 } |
168 |
100 |
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 |
101 @Override |
180 public String[] getSupportedCipherSuites() { |
102 public String[] getSupportedCipherSuites() { |
181 return sslContext.getSupportedCipherSuiteList().toStringArray(); |
103 return CipherSuite.namesOf(sslContext.getSupportedCipherSuites()); |
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 } |
104 } |
205 |
105 |
206 @Override |
106 @Override |
207 public String[] getSupportedProtocols() { |
107 public String[] getSupportedProtocols() { |
208 return sslContext.getSuportedProtocolList().toStringArray(); |
108 return ProtocolVersion.toStringArray( |
209 } |
109 sslContext.getSuportedProtocolVersions()); |
210 |
110 } |
211 /** |
111 |
212 * Controls which protocols are enabled for use. |
112 @Override |
213 * The protocols must have been listed by |
113 public synchronized String[] getEnabledProtocols() { |
214 * getSupportedProtocols() as being supported. |
114 return ProtocolVersion.toStringArray(sslConfig.enabledProtocols); |
215 * |
115 } |
216 * @param protocols protocols to enable. |
116 |
217 * @exception IllegalArgumentException when one of the protocols |
|
218 * named by the parameter is not supported. |
|
219 */ |
|
220 @Override |
117 @Override |
221 public synchronized void setEnabledProtocols(String[] protocols) { |
118 public synchronized void setEnabledProtocols(String[] protocols) { |
222 enabledProtocols = new ProtocolList(protocols); |
119 if (protocols == null) { |
223 } |
120 throw new IllegalArgumentException("Protocols cannot be null"); |
224 |
121 } |
225 @Override |
122 |
226 public synchronized String[] getEnabledProtocols() { |
123 sslConfig.enabledProtocols = ProtocolVersion.namesOf(protocols); |
227 return enabledProtocols.toStringArray(); |
124 } |
228 } |
125 |
229 |
126 @Override |
230 /** |
127 public synchronized void setNeedClientAuth(boolean need) { |
231 * Controls whether the connections which are accepted must include |
128 sslConfig.clientAuthType = |
232 * client authentication. |
129 (need ? ClientAuthType.CLIENT_AUTH_REQUIRED : |
233 */ |
130 ClientAuthType.CLIENT_AUTH_NONE); |
234 @Override |
131 } |
235 public void setNeedClientAuth(boolean flag) { |
132 |
236 clientAuthType = (flag ? ClientAuthType.CLIENT_AUTH_REQUIRED : |
133 @Override |
237 ClientAuthType.CLIENT_AUTH_NONE); |
134 public synchronized boolean getNeedClientAuth() { |
238 } |
135 return (sslConfig.clientAuthType == |
239 |
136 ClientAuthType.CLIENT_AUTH_REQUIRED); |
240 @Override |
137 } |
241 public boolean getNeedClientAuth() { |
138 |
242 return (clientAuthType == ClientAuthType.CLIENT_AUTH_REQUIRED); |
139 @Override |
243 } |
140 public synchronized void setWantClientAuth(boolean want) { |
244 |
141 sslConfig.clientAuthType = |
245 /** |
142 (want ? ClientAuthType.CLIENT_AUTH_REQUESTED : |
246 * Controls whether the connections which are accepted should request |
143 ClientAuthType.CLIENT_AUTH_NONE); |
247 * client authentication. |
144 } |
248 */ |
145 |
249 @Override |
146 @Override |
250 public void setWantClientAuth(boolean flag) { |
147 public synchronized boolean getWantClientAuth() { |
251 clientAuthType = (flag ? ClientAuthType.CLIENT_AUTH_REQUESTED : |
148 return (sslConfig.clientAuthType == |
252 ClientAuthType.CLIENT_AUTH_NONE); |
149 ClientAuthType.CLIENT_AUTH_REQUESTED); |
253 } |
150 } |
254 |
151 |
255 @Override |
152 @Override |
256 public boolean getWantClientAuth() { |
153 public synchronized void setUseClientMode(boolean useClientMode) { |
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 /* |
154 /* |
269 * If we need to change the socket mode and the enabled |
155 * If we need to change the client mode and the enabled |
270 * protocols haven't specifically been set by the user, |
156 * protocols and cipher suites haven't specifically been |
271 * change them to the corresponding default ones. |
157 * set by the user, change them to the corresponding |
|
158 * default ones. |
272 */ |
159 */ |
273 if (useServerMode != (!flag) && |
160 if (sslConfig.isClientMode != useClientMode) { |
274 sslContext.isDefaultProtocolList(enabledProtocols)) { |
161 if (sslContext.isDefaultProtocolVesions( |
275 enabledProtocols = sslContext.getDefaultProtocolList(!flag); |
162 sslConfig.enabledProtocols)) { |
|
163 sslConfig.enabledProtocols = |
|
164 sslContext.getDefaultProtocolVersions(!useClientMode); |
|
165 } |
|
166 |
|
167 if (sslContext.isDefaultCipherSuiteList( |
|
168 sslConfig.enabledCipherSuites)) { |
|
169 sslConfig.enabledCipherSuites = |
|
170 sslContext.getDefaultCipherSuites(!useClientMode); |
|
171 } |
|
172 |
|
173 sslConfig.isClientMode = useClientMode; |
276 } |
174 } |
277 |
175 } |
278 useServerMode = !flag; |
176 |
279 } |
177 @Override |
280 |
178 public synchronized boolean getUseClientMode() { |
281 @Override |
179 return sslConfig.isClientMode; |
282 public boolean getUseClientMode() { |
180 } |
283 return !useServerMode; |
181 |
284 } |
182 @Override |
285 |
183 public synchronized void setEnableSessionCreation(boolean flag) { |
286 |
184 sslConfig.enableSessionCreation = flag; |
287 /** |
185 } |
288 * Controls whether new connections may cause creation of new SSL |
186 |
289 * sessions. |
187 @Override |
290 */ |
188 public synchronized boolean getEnableSessionCreation() { |
291 @Override |
189 return sslConfig.enableSessionCreation; |
292 public void setEnableSessionCreation(boolean flag) { |
190 } |
293 enableSessionCreation = flag; |
191 |
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 |
192 @Override |
309 public synchronized SSLParameters getSSLParameters() { |
193 public synchronized SSLParameters getSSLParameters() { |
310 SSLParameters params = super.getSSLParameters(); |
194 return sslConfig.getSSLParameters(); |
311 |
195 } |
312 // the super implementation does not handle the following parameters |
196 |
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 |
197 @Override |
326 public synchronized void setSSLParameters(SSLParameters params) { |
198 public synchronized void setSSLParameters(SSLParameters params) { |
327 super.setSSLParameters(params); |
199 sslConfig.setSSLParameters(params); |
328 |
200 } |
329 // the super implementation does not handle the following parameters |
201 |
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 |
202 @Override |
346 public Socket accept() throws IOException { |
203 public Socket accept() throws IOException { |
347 SSLSocketImpl s = new SSLSocketImpl(sslContext, useServerMode, |
204 SSLSocketImpl s = new SSLSocketImpl(sslContext, sslConfig); |
348 enabledCipherSuites, clientAuthType, enableSessionCreation, |
|
349 enabledProtocols, identificationProtocol, algorithmConstraints, |
|
350 sniMatchers, preferLocalCipherSuites, applicationProtocols); |
|
351 |
205 |
352 implAccept(s); |
206 implAccept(s); |
353 s.doneConnect(); |
207 s.doneConnect(); |
354 return s; |
208 return s; |
355 } |
209 } |
356 |
210 |
357 /** |
|
358 * Provides a brief description of this SSL socket. |
|
359 */ |
|
360 @Override |
211 @Override |
361 public String toString() { |
212 public String toString() { |
362 return "[SSL: "+ super.toString() + "]"; |
213 return "[SSL: "+ super.toString() + "]"; |
363 } |
214 } |
364 } |
215 } |