equal
deleted
inserted
replaced
62 * @see javax.net.ssl.SSLSocket |
62 * @see javax.net.ssl.SSLSocket |
63 * @see SSLServerSocket |
63 * @see SSLServerSocket |
64 * |
64 * |
65 * @author David Brownell |
65 * @author David Brownell |
66 */ |
66 */ |
67 final public class SSLSocketImpl extends BaseSSLSocketImpl { |
67 public final class SSLSocketImpl extends BaseSSLSocketImpl { |
68 |
68 |
69 /* |
69 /* |
70 * ERROR HANDLING GUIDELINES |
70 * ERROR HANDLING GUIDELINES |
71 * (which exceptions to throw and catch and which not to throw and catch) |
71 * (which exceptions to throw and catch and which not to throw and catch) |
72 * |
72 * |
279 * The readLock ensures that these three steps are done atomically |
279 * The readLock ensures that these three steps are done atomically |
280 * and that once started, no other thread can block on SSLInputRecord.read. |
280 * and that once started, no other thread can block on SSLInputRecord.read. |
281 * This is necessary so that processing of close_notify alerts |
281 * This is necessary so that processing of close_notify alerts |
282 * from the peer are handled properly. |
282 * from the peer are handled properly. |
283 */ |
283 */ |
284 final private Object handshakeLock = new Object(); |
284 private final Object handshakeLock = new Object(); |
285 final ReentrantLock writeLock = new ReentrantLock(); |
285 final ReentrantLock writeLock = new ReentrantLock(); |
286 final private Object readLock = new Object(); |
286 private final Object readLock = new Object(); |
287 |
287 |
288 InputRecord inputRecord; |
288 InputRecord inputRecord; |
289 OutputRecord outputRecord; |
289 OutputRecord outputRecord; |
290 |
290 |
291 /* |
291 /* |
671 * to defaults and the appropriate kind of handshaker set up. |
671 * to defaults and the appropriate kind of handshaker set up. |
672 */ |
672 */ |
673 initHandshaker(); |
673 initHandshaker(); |
674 } |
674 } |
675 |
675 |
676 synchronized private int getConnectionState() { |
676 private synchronized int getConnectionState() { |
677 return connectionState; |
677 return connectionState; |
678 } |
678 } |
679 |
679 |
680 synchronized private void setConnectionState(int state) { |
680 private synchronized void setConnectionState(int state) { |
681 connectionState = state; |
681 connectionState = state; |
682 } |
682 } |
683 |
683 |
684 AccessControlContext getAcc() { |
684 AccessControlContext getAcc() { |
685 return acc; |
685 return acc; |
1800 * @param resumable indicates the caller process is resumable from the |
1800 * @param resumable indicates the caller process is resumable from the |
1801 * exception. If <code>resumable</code>, the socket will be |
1801 * exception. If <code>resumable</code>, the socket will be |
1802 * reserved for exceptions like timeout; otherwise, the socket |
1802 * reserved for exceptions like timeout; otherwise, the socket |
1803 * will be closed, no further communications could be done. |
1803 * will be closed, no further communications could be done. |
1804 */ |
1804 */ |
1805 synchronized private void handleException(Exception e, boolean resumable) |
1805 private synchronized void handleException(Exception e, boolean resumable) |
1806 throws IOException { |
1806 throws IOException { |
1807 if ((debug != null) && Debug.isOn("ssl")) { |
1807 if ((debug != null) && Debug.isOn("ssl")) { |
1808 System.out.println(Thread.currentThread().getName() + |
1808 System.out.println(Thread.currentThread().getName() + |
1809 ", handling exception: " + e.toString()); |
1809 ", handling exception: " + e.toString()); |
1810 } |
1810 } |
2112 // ONLY used by HttpsClient to setup the URI specified hostname |
2112 // ONLY used by HttpsClient to setup the URI specified hostname |
2113 // |
2113 // |
2114 // Please NOTE that this method MUST be called before calling to |
2114 // Please NOTE that this method MUST be called before calling to |
2115 // SSLSocket.setSSLParameters(). Otherwise, the {@code host} parameter |
2115 // SSLSocket.setSSLParameters(). Otherwise, the {@code host} parameter |
2116 // may override SNIHostName in the customized server name indication. |
2116 // may override SNIHostName in the customized server name indication. |
2117 synchronized public void setHost(String host) { |
2117 public synchronized void setHost(String host) { |
2118 this.host = host; |
2118 this.host = host; |
2119 this.serverNames = |
2119 this.serverNames = |
2120 Utilities.addToSNIServerNameList(this.serverNames, this.host); |
2120 Utilities.addToSNIServerNameList(this.serverNames, this.host); |
2121 } |
2121 } |
2122 |
2122 |
2124 * Gets an input stream to read from the peer on the other side. |
2124 * Gets an input stream to read from the peer on the other side. |
2125 * Data read from this stream was always integrity protected in |
2125 * Data read from this stream was always integrity protected in |
2126 * transit, and will usually have been confidentiality protected. |
2126 * transit, and will usually have been confidentiality protected. |
2127 */ |
2127 */ |
2128 @Override |
2128 @Override |
2129 synchronized public InputStream getInputStream() throws IOException { |
2129 public synchronized InputStream getInputStream() throws IOException { |
2130 if (isClosed()) { |
2130 if (isClosed()) { |
2131 throw new SocketException("Socket is closed"); |
2131 throw new SocketException("Socket is closed"); |
2132 } |
2132 } |
2133 |
2133 |
2134 /* |
2134 /* |
2146 * Gets an output stream to write to the peer on the other side. |
2146 * Gets an output stream to write to the peer on the other side. |
2147 * Data written on this stream is always integrity protected, and |
2147 * Data written on this stream is always integrity protected, and |
2148 * will usually be confidentiality protected. |
2148 * will usually be confidentiality protected. |
2149 */ |
2149 */ |
2150 @Override |
2150 @Override |
2151 synchronized public OutputStream getOutputStream() throws IOException { |
2151 public synchronized OutputStream getOutputStream() throws IOException { |
2152 if (isClosed()) { |
2152 if (isClosed()) { |
2153 throw new SocketException("Socket is closed"); |
2153 throw new SocketException("Socket is closed"); |
2154 } |
2154 } |
2155 |
2155 |
2156 /* |
2156 /* |
2190 return sess; |
2190 return sess; |
2191 } |
2191 } |
2192 } |
2192 } |
2193 |
2193 |
2194 @Override |
2194 @Override |
2195 synchronized public SSLSession getHandshakeSession() { |
2195 public synchronized SSLSession getHandshakeSession() { |
2196 return handshakeSession; |
2196 return handshakeSession; |
2197 } |
2197 } |
2198 |
2198 |
2199 synchronized void setHandshakeSession(SSLSessionImpl session) { |
2199 synchronized void setHandshakeSession(SSLSessionImpl session) { |
2200 // update the fragment size, which may be negotiated during handshaking |
2200 // update the fragment size, which may be negotiated during handshaking |
2211 * As long as handshaking has not started, we can change |
2211 * As long as handshaking has not started, we can change |
2212 * whether we enable session creations. Otherwise, |
2212 * whether we enable session creations. Otherwise, |
2213 * we will need to wait for the next handshake. |
2213 * we will need to wait for the next handshake. |
2214 */ |
2214 */ |
2215 @Override |
2215 @Override |
2216 synchronized public void setEnableSessionCreation(boolean flag) { |
2216 public synchronized void setEnableSessionCreation(boolean flag) { |
2217 enableSessionCreation = flag; |
2217 enableSessionCreation = flag; |
2218 |
2218 |
2219 if ((handshaker != null) && !handshaker.activated()) { |
2219 if ((handshaker != null) && !handshaker.activated()) { |
2220 handshaker.setEnableSessionCreation(enableSessionCreation); |
2220 handshaker.setEnableSessionCreation(enableSessionCreation); |
2221 } |
2221 } |
2224 /** |
2224 /** |
2225 * Returns true if new connections may cause creation of new SSL |
2225 * Returns true if new connections may cause creation of new SSL |
2226 * sessions. |
2226 * sessions. |
2227 */ |
2227 */ |
2228 @Override |
2228 @Override |
2229 synchronized public boolean getEnableSessionCreation() { |
2229 public synchronized boolean getEnableSessionCreation() { |
2230 return enableSessionCreation; |
2230 return enableSessionCreation; |
2231 } |
2231 } |
2232 |
2232 |
2233 |
2233 |
2234 /** |
2234 /** |
2238 * As long as handshaking has not started, we can change |
2238 * As long as handshaking has not started, we can change |
2239 * whether client authentication is needed. Otherwise, |
2239 * whether client authentication is needed. Otherwise, |
2240 * we will need to wait for the next handshake. |
2240 * we will need to wait for the next handshake. |
2241 */ |
2241 */ |
2242 @Override |
2242 @Override |
2243 synchronized public void setNeedClientAuth(boolean flag) { |
2243 public synchronized void setNeedClientAuth(boolean flag) { |
2244 doClientAuth = (flag ? ClientAuthType.CLIENT_AUTH_REQUIRED : |
2244 doClientAuth = (flag ? ClientAuthType.CLIENT_AUTH_REQUIRED : |
2245 ClientAuthType.CLIENT_AUTH_NONE); |
2245 ClientAuthType.CLIENT_AUTH_NONE); |
2246 |
2246 |
2247 if ((handshaker != null) && |
2247 if ((handshaker != null) && |
2248 (handshaker instanceof ServerHandshaker) && |
2248 (handshaker instanceof ServerHandshaker) && |
2250 ((ServerHandshaker) handshaker).setClientAuth(doClientAuth); |
2250 ((ServerHandshaker) handshaker).setClientAuth(doClientAuth); |
2251 } |
2251 } |
2252 } |
2252 } |
2253 |
2253 |
2254 @Override |
2254 @Override |
2255 synchronized public boolean getNeedClientAuth() { |
2255 public synchronized boolean getNeedClientAuth() { |
2256 return (doClientAuth == ClientAuthType.CLIENT_AUTH_REQUIRED); |
2256 return (doClientAuth == ClientAuthType.CLIENT_AUTH_REQUIRED); |
2257 } |
2257 } |
2258 |
2258 |
2259 /** |
2259 /** |
2260 * Sets the flag controlling whether a server mode socket |
2260 * Sets the flag controlling whether a server mode socket |
2263 * As long as handshaking has not started, we can change |
2263 * As long as handshaking has not started, we can change |
2264 * whether client authentication is requested. Otherwise, |
2264 * whether client authentication is requested. Otherwise, |
2265 * we will need to wait for the next handshake. |
2265 * we will need to wait for the next handshake. |
2266 */ |
2266 */ |
2267 @Override |
2267 @Override |
2268 synchronized public void setWantClientAuth(boolean flag) { |
2268 public synchronized void setWantClientAuth(boolean flag) { |
2269 doClientAuth = (flag ? ClientAuthType.CLIENT_AUTH_REQUESTED : |
2269 doClientAuth = (flag ? ClientAuthType.CLIENT_AUTH_REQUESTED : |
2270 ClientAuthType.CLIENT_AUTH_NONE); |
2270 ClientAuthType.CLIENT_AUTH_NONE); |
2271 |
2271 |
2272 if ((handshaker != null) && |
2272 if ((handshaker != null) && |
2273 (handshaker instanceof ServerHandshaker) && |
2273 (handshaker instanceof ServerHandshaker) && |
2275 ((ServerHandshaker) handshaker).setClientAuth(doClientAuth); |
2275 ((ServerHandshaker) handshaker).setClientAuth(doClientAuth); |
2276 } |
2276 } |
2277 } |
2277 } |
2278 |
2278 |
2279 @Override |
2279 @Override |
2280 synchronized public boolean getWantClientAuth() { |
2280 public synchronized boolean getWantClientAuth() { |
2281 return (doClientAuth == ClientAuthType.CLIENT_AUTH_REQUESTED); |
2281 return (doClientAuth == ClientAuthType.CLIENT_AUTH_REQUESTED); |
2282 } |
2282 } |
2283 |
2283 |
2284 |
2284 |
2285 /** |
2285 /** |
2287 * client or server mode. Must be called before any SSL |
2287 * client or server mode. Must be called before any SSL |
2288 * traffic has started. |
2288 * traffic has started. |
2289 */ |
2289 */ |
2290 @Override |
2290 @Override |
2291 @SuppressWarnings("fallthrough") |
2291 @SuppressWarnings("fallthrough") |
2292 synchronized public void setUseClientMode(boolean flag) { |
2292 public synchronized void setUseClientMode(boolean flag) { |
2293 switch (connectionState) { |
2293 switch (connectionState) { |
2294 |
2294 |
2295 case cs_START: |
2295 case cs_START: |
2296 /* |
2296 /* |
2297 * If we need to change the socket mode and the enabled |
2297 * If we need to change the socket mode and the enabled |
2361 "Cannot change mode after SSL traffic has started"); |
2361 "Cannot change mode after SSL traffic has started"); |
2362 } |
2362 } |
2363 } |
2363 } |
2364 |
2364 |
2365 @Override |
2365 @Override |
2366 synchronized public boolean getUseClientMode() { |
2366 public synchronized boolean getUseClientMode() { |
2367 return !roleIsServer; |
2367 return !roleIsServer; |
2368 } |
2368 } |
2369 |
2369 |
2370 |
2370 |
2371 /** |
2371 /** |
2391 * requisite certificates (and private keys) are not available. |
2391 * requisite certificates (and private keys) are not available. |
2392 * |
2392 * |
2393 * @param suites Names of all the cipher suites to enable. |
2393 * @param suites Names of all the cipher suites to enable. |
2394 */ |
2394 */ |
2395 @Override |
2395 @Override |
2396 synchronized public void setEnabledCipherSuites(String[] suites) { |
2396 public synchronized void setEnabledCipherSuites(String[] suites) { |
2397 enabledCipherSuites = new CipherSuiteList(suites); |
2397 enabledCipherSuites = new CipherSuiteList(suites); |
2398 if ((handshaker != null) && !handshaker.activated()) { |
2398 if ((handshaker != null) && !handshaker.activated()) { |
2399 handshaker.setEnabledCipherSuites(enabledCipherSuites); |
2399 handshaker.setEnabledCipherSuites(enabledCipherSuites); |
2400 } |
2400 } |
2401 } |
2401 } |
2409 * might be empty. |
2409 * might be empty. |
2410 * |
2410 * |
2411 * @return an array of cipher suite names |
2411 * @return an array of cipher suite names |
2412 */ |
2412 */ |
2413 @Override |
2413 @Override |
2414 synchronized public String[] getEnabledCipherSuites() { |
2414 public synchronized String[] getEnabledCipherSuites() { |
2415 return enabledCipherSuites.toStringArray(); |
2415 return enabledCipherSuites.toStringArray(); |
2416 } |
2416 } |
2417 |
2417 |
2418 |
2418 |
2419 /** |
2419 /** |
2434 * @param protocols protocols to enable. |
2434 * @param protocols protocols to enable. |
2435 * @exception IllegalArgumentException when one of the protocols |
2435 * @exception IllegalArgumentException when one of the protocols |
2436 * named by the parameter is not supported. |
2436 * named by the parameter is not supported. |
2437 */ |
2437 */ |
2438 @Override |
2438 @Override |
2439 synchronized public void setEnabledProtocols(String[] protocols) { |
2439 public synchronized void setEnabledProtocols(String[] protocols) { |
2440 enabledProtocols = new ProtocolList(protocols); |
2440 enabledProtocols = new ProtocolList(protocols); |
2441 if ((handshaker != null) && !handshaker.activated()) { |
2441 if ((handshaker != null) && !handshaker.activated()) { |
2442 handshaker.setEnabledProtocols(enabledProtocols); |
2442 handshaker.setEnabledProtocols(enabledProtocols); |
2443 } |
2443 } |
2444 } |
2444 } |
2445 |
2445 |
2446 @Override |
2446 @Override |
2447 synchronized public String[] getEnabledProtocols() { |
2447 public synchronized String[] getEnabledProtocols() { |
2448 return enabledProtocols.toStringArray(); |
2448 return enabledProtocols.toStringArray(); |
2449 } |
2449 } |
2450 |
2450 |
2451 /** |
2451 /** |
2452 * Assigns the socket timeout. |
2452 * Assigns the socket timeout. |
2499 |
2499 |
2500 /** |
2500 /** |
2501 * Returns the SSLParameters in effect for this SSLSocket. |
2501 * Returns the SSLParameters in effect for this SSLSocket. |
2502 */ |
2502 */ |
2503 @Override |
2503 @Override |
2504 synchronized public SSLParameters getSSLParameters() { |
2504 public synchronized SSLParameters getSSLParameters() { |
2505 SSLParameters params = super.getSSLParameters(); |
2505 SSLParameters params = super.getSSLParameters(); |
2506 |
2506 |
2507 // the super implementation does not handle the following parameters |
2507 // the super implementation does not handle the following parameters |
2508 params.setEndpointIdentificationAlgorithm(identificationProtocol); |
2508 params.setEndpointIdentificationAlgorithm(identificationProtocol); |
2509 params.setAlgorithmConstraints(algorithmConstraints); |
2509 params.setAlgorithmConstraints(algorithmConstraints); |
2519 |
2519 |
2520 /** |
2520 /** |
2521 * Applies SSLParameters to this socket. |
2521 * Applies SSLParameters to this socket. |
2522 */ |
2522 */ |
2523 @Override |
2523 @Override |
2524 synchronized public void setSSLParameters(SSLParameters params) { |
2524 public synchronized void setSSLParameters(SSLParameters params) { |
2525 super.setSSLParameters(params); |
2525 super.setSSLParameters(params); |
2526 |
2526 |
2527 // the super implementation does not handle the following parameters |
2527 // the super implementation does not handle the following parameters |
2528 identificationProtocol = params.getEndpointIdentificationAlgorithm(); |
2528 identificationProtocol = params.getEndpointIdentificationAlgorithm(); |
2529 algorithmConstraints = params.getAlgorithmConstraints(); |
2529 algorithmConstraints = params.getAlgorithmConstraints(); |