30 import java.net.*; |
30 import java.net.*; |
31 import java.security.GeneralSecurityException; |
31 import java.security.GeneralSecurityException; |
32 import java.security.AccessController; |
32 import java.security.AccessController; |
33 import java.security.AccessControlContext; |
33 import java.security.AccessControlContext; |
34 import java.security.PrivilegedAction; |
34 import java.security.PrivilegedAction; |
|
35 import java.security.AlgorithmConstraints; |
35 import java.util.*; |
36 import java.util.*; |
36 import java.util.concurrent.TimeUnit; |
37 import java.util.concurrent.TimeUnit; |
37 import java.util.concurrent.locks.ReentrantLock; |
38 import java.util.concurrent.locks.ReentrantLock; |
38 |
39 |
39 import javax.crypto.BadPaddingException; |
40 import javax.crypto.BadPaddingException; |
197 private boolean enableSessionCreation = true; |
198 private boolean enableSessionCreation = true; |
198 private String host; |
199 private String host; |
199 private boolean autoClose = true; |
200 private boolean autoClose = true; |
200 private AccessControlContext acc; |
201 private AccessControlContext acc; |
201 |
202 |
|
203 /* |
|
204 * We cannot use the hostname resolved from name services. For |
|
205 * virtual hosting, multiple hostnames may be bound to the same IP |
|
206 * address, so the hostname resolved from name services is not |
|
207 * reliable. |
|
208 */ |
|
209 private String rawHostname; |
|
210 |
202 // The cipher suites enabled for use on this connection. |
211 // The cipher suites enabled for use on this connection. |
203 private CipherSuiteList enabledCipherSuites; |
212 private CipherSuiteList enabledCipherSuites; |
204 |
213 |
205 // hostname identification algorithm, the hostname identification is |
214 // The endpoint identification protocol |
206 // disabled by default. |
215 private String identificationProtocol = null; |
207 private String identificationAlg = null; |
216 |
|
217 // The cryptographic algorithm constraints |
|
218 private AlgorithmConstraints algorithmConstraints = null; |
208 |
219 |
209 /* |
220 /* |
210 * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME * |
221 * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME * |
211 * IMPORTANT STUFF TO UNDERSTANDING THE SYNCHRONIZATION ISSUES. |
222 * IMPORTANT STUFF TO UNDERSTANDING THE SYNCHRONIZATION ISSUES. |
212 * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME * |
223 * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME * |
312 * about changing the cipher spec (and it does change), in fact |
323 * about changing the cipher spec (and it does change), in fact |
313 * that's incidental since it's done by changing everything that |
324 * that's incidental since it's done by changing everything that |
314 * is associated with a session at the same time. (TLS/IETF may |
325 * is associated with a session at the same time. (TLS/IETF may |
315 * change that to add client authentication w/o new key exchg.) |
326 * change that to add client authentication w/o new key exchg.) |
316 */ |
327 */ |
317 private SSLSessionImpl sess; |
328 private Handshaker handshaker; |
318 private Handshaker handshaker; |
329 private SSLSessionImpl sess; |
|
330 private volatile SSLSessionImpl handshakeSession; |
319 |
331 |
320 |
332 |
321 /* |
333 /* |
322 * If anyone wants to get notified about handshake completions, |
334 * If anyone wants to get notified about handshake completions, |
323 * they'll show up on this list. |
335 * they'll show up on this list. |
374 */ |
386 */ |
375 SSLSocketImpl(SSLContextImpl context, String host, int port) |
387 SSLSocketImpl(SSLContextImpl context, String host, int port) |
376 throws IOException, UnknownHostException { |
388 throws IOException, UnknownHostException { |
377 super(); |
389 super(); |
378 this.host = host; |
390 this.host = host; |
|
391 this.rawHostname = host; |
379 init(context, false); |
392 init(context, false); |
380 SocketAddress socketAddress = |
393 SocketAddress socketAddress = |
381 host != null ? new InetSocketAddress(host, port) : |
394 host != null ? new InetSocketAddress(host, port) : |
382 new InetSocketAddress(InetAddress.getByName(null), port); |
395 new InetSocketAddress(InetAddress.getByName(null), port); |
383 connect(socketAddress, 0); |
396 connect(socketAddress, 0); |
416 SSLSocketImpl(SSLContextImpl context, String host, int port, |
429 SSLSocketImpl(SSLContextImpl context, String host, int port, |
417 InetAddress localAddr, int localPort) |
430 InetAddress localAddr, int localPort) |
418 throws IOException, UnknownHostException { |
431 throws IOException, UnknownHostException { |
419 super(); |
432 super(); |
420 this.host = host; |
433 this.host = host; |
|
434 this.rawHostname = host; |
421 init(context, false); |
435 init(context, false); |
422 bind(new InetSocketAddress(localAddr, localPort)); |
436 bind(new InetSocketAddress(localAddr, localPort)); |
423 SocketAddress socketAddress = |
437 SocketAddress socketAddress = |
424 host != null ? new InetSocketAddress(host, port) : |
438 host != null ? new InetSocketAddress(host, port) : |
425 new InetSocketAddress(InetAddress.getByName(null), port); |
439 new InetSocketAddress(InetAddress.getByName(null), port); |
455 * made. This just initializes handshake state to use "server mode", |
469 * made. This just initializes handshake state to use "server mode", |
456 * giving control over the use of SSL client authentication. |
470 * giving control over the use of SSL client authentication. |
457 */ |
471 */ |
458 SSLSocketImpl(SSLContextImpl context, boolean serverMode, |
472 SSLSocketImpl(SSLContextImpl context, boolean serverMode, |
459 CipherSuiteList suites, byte clientAuth, |
473 CipherSuiteList suites, byte clientAuth, |
460 boolean sessionCreation, ProtocolList protocols) |
474 boolean sessionCreation, ProtocolList protocols, |
461 throws IOException { |
475 String identificationProtocol, |
|
476 AlgorithmConstraints algorithmConstraints) throws IOException { |
|
477 |
462 super(); |
478 super(); |
463 doClientAuth = clientAuth; |
479 doClientAuth = clientAuth; |
464 enableSessionCreation = sessionCreation; |
480 enableSessionCreation = sessionCreation; |
|
481 this.identificationProtocol = identificationProtocol; |
|
482 this.algorithmConstraints = algorithmConstraints; |
465 init(context, serverMode); |
483 init(context, serverMode); |
466 |
484 |
467 /* |
485 /* |
468 * Override what was picked out for us. |
486 * Override what was picked out for us. |
469 */ |
487 */ |
506 // We always layer over a connected socket |
524 // We always layer over a connected socket |
507 if (!sock.isConnected()) { |
525 if (!sock.isConnected()) { |
508 throw new SocketException("Underlying socket is not connected"); |
526 throw new SocketException("Underlying socket is not connected"); |
509 } |
527 } |
510 this.host = host; |
528 this.host = host; |
|
529 this.rawHostname = host; |
511 init(context, false); |
530 init(context, false); |
512 this.autoClose = autoClose; |
531 this.autoClose = autoClose; |
513 doneConnect(); |
532 doneConnect(); |
514 } |
533 } |
515 |
534 |
517 * Initializes the client socket. |
536 * Initializes the client socket. |
518 */ |
537 */ |
519 private void init(SSLContextImpl context, boolean isServer) { |
538 private void init(SSLContextImpl context, boolean isServer) { |
520 sslContext = context; |
539 sslContext = context; |
521 sess = SSLSessionImpl.nullSession; |
540 sess = SSLSessionImpl.nullSession; |
|
541 handshakeSession = null; |
522 |
542 |
523 /* |
543 /* |
524 * role is as specified, state is START until after |
544 * role is as specified, state is START until after |
525 * the low level connection's established. |
545 * the low level connection's established. |
526 */ |
546 */ |
955 handshaker.isSecureRenegotiation(); |
975 handshaker.isSecureRenegotiation(); |
956 clientVerifyData = handshaker.getClientVerifyData(); |
976 clientVerifyData = handshaker.getClientVerifyData(); |
957 serverVerifyData = handshaker.getServerVerifyData(); |
977 serverVerifyData = handshaker.getServerVerifyData(); |
958 |
978 |
959 sess = handshaker.getSession(); |
979 sess = handshaker.getSession(); |
|
980 handshakeSession = null; |
960 handshaker = null; |
981 handshaker = null; |
961 connectionState = cs_DATA; |
982 connectionState = cs_DATA; |
962 |
983 |
963 // |
984 // |
964 // Tell folk about handshake completion, but do |
985 // Tell folk about handshake completion, but do |
1970 host = getInetAddress().getHostName(); |
1994 host = getInetAddress().getHostName(); |
1971 } |
1995 } |
1972 return host; |
1996 return host; |
1973 } |
1997 } |
1974 |
1998 |
|
1999 synchronized String getRawHostname() { |
|
2000 return rawHostname; |
|
2001 } |
|
2002 |
1975 // ONLY used by HttpsClient to setup the URI specified hostname |
2003 // ONLY used by HttpsClient to setup the URI specified hostname |
1976 synchronized public void setHost(String host) { |
2004 synchronized public void setHost(String host) { |
1977 this.host = host; |
2005 this.host = host; |
|
2006 this.rawHostname = host; |
1978 } |
2007 } |
1979 |
2008 |
1980 /** |
2009 /** |
1981 * Gets an input stream to read from the peer on the other side. |
2010 * Gets an input stream to read from the peer on the other side. |
1982 * Data read from this stream was always integrity protected in |
2011 * Data read from this stream was always integrity protected in |
2228 |
2266 |
2229 |
2267 |
2230 /** |
2268 /** |
2231 * Returns the protocols that are supported by this implementation. |
2269 * Returns the protocols that are supported by this implementation. |
2232 * A subset of the supported protocols may be enabled for this connection |
2270 * A subset of the supported protocols may be enabled for this connection |
2233 * @ returns an array of protocol names. |
2271 * @return an array of protocol names. |
2234 */ |
2272 */ |
2235 public String[] getSupportedProtocols() { |
2273 public String[] getSupportedProtocols() { |
2236 return ProtocolList.getSupported().toStringArray(); |
2274 return ProtocolList.getSupported().toStringArray(); |
2237 } |
2275 } |
2238 |
2276 |
2304 handshakeListeners = null; |
2342 handshakeListeners = null; |
2305 } |
2343 } |
2306 } |
2344 } |
2307 |
2345 |
2308 /** |
2346 /** |
2309 * Try to configure the endpoint identification algorithm of the socket. |
2347 * Returns the SSLParameters in effect for this SSLSocket. |
2310 * |
2348 */ |
2311 * @param identificationAlgorithm the algorithm used to check the |
2349 synchronized public SSLParameters getSSLParameters() { |
2312 * endpoint identity. |
2350 SSLParameters params = super.getSSLParameters(); |
2313 * @return true if the identification algorithm configuration success. |
2351 |
2314 */ |
2352 // the super implementation does not handle the following parameters |
2315 synchronized public boolean trySetHostnameVerification( |
2353 params.setEndpointIdentificationAlgorithm(identificationProtocol); |
2316 String identificationAlgorithm) { |
2354 params.setAlgorithmConstraints(algorithmConstraints); |
2317 if (sslContext.getX509TrustManager() instanceof |
2355 |
2318 X509ExtendedTrustManager) { |
2356 return params; |
2319 this.identificationAlg = identificationAlgorithm; |
2357 } |
2320 return true; |
2358 |
2321 } else { |
2359 /** |
2322 return false; |
2360 * Applies SSLParameters to this socket. |
2323 } |
2361 */ |
2324 } |
2362 synchronized public void setSSLParameters(SSLParameters params) { |
2325 |
2363 super.setSSLParameters(params); |
2326 /** |
2364 |
2327 * Returns the endpoint identification algorithm of the socket. |
2365 // the super implementation does not handle the following parameters |
2328 */ |
2366 identificationProtocol = params.getEndpointIdentificationAlgorithm(); |
2329 synchronized public String getHostnameVerification() { |
2367 algorithmConstraints = params.getAlgorithmConstraints(); |
2330 return identificationAlg; |
2368 if ((handshaker != null) && !handshaker.started()) { |
|
2369 handshaker.setIdentificationProtocol(identificationProtocol); |
|
2370 handshaker.setAlgorithmConstraints(algorithmConstraints); |
|
2371 } |
2331 } |
2372 } |
2332 |
2373 |
2333 // |
2374 // |
2334 // We allocate a separate thread to deliver handshake completion |
2375 // We allocate a separate thread to deliver handshake completion |
2335 // events. This ensures that the notifications don't block the |
2376 // events. This ensures that the notifications don't block the |