JDK-4282681 : IOException/SocketException with startHandshake() call
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Affected Version: 1.0
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 1999-10-19
  • Updated: 1999-11-02
  • Resolved: 1999-11-02
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.0 1.0Fixed
Related Reports
Duplicate :  
Description
daniel.daugherty@Eng 1999-10-19

In the exportable version of the JSSE1.0 Beta-H build, four of the
SessionIds test cases fail only on Win* platforms:

	tcList[0] = new SessionTC(
	    // begin base test case elements:
	    "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",	// cipher suite name
	    false,			// disjoint cipher suites?
	    false,			// keystore enabled?
	    false,			// mutual authentication enabled?
	    EXP_PASS,			// expected test result
	    // end base test case elements
	    
	    // begin session management test case elements:
	    true,		// server socket session creation enabled?
	    true,		// client session creation enabled?
	    true,		// invalidate the current session?
	    true);		// start a new handshake?

	tcList[1] = new SessionTC(
	    // begin base test case elements:
	    "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",	// cipher suite name
	    false,			// disjoint cipher suites?
	    true,			// keystore enabled?
	    true,			// mutual authentication enabled?
	    EXP_PASS,			// expected test result
	    // end base test case elements
	    
	    // begin session management test case elements:
	    true,		// server socket session creation enabled?
	    true,		// client session creation enabled?
	    true,		// invalidate the current session?
	    true);		// start a new handshake?

	tcList[2] = new SessionTC(
	    // begin base test case elements:
	    "SSL_RSA_EXPORT_WITH_RC4_40_MD5",	// cipher suite name
	    false,			// disjoint cipher suites?
	    true,			// keystore enabled?
	    false,			// mutual authentication enabled?
	    EXP_PASS,			// expected test result
	    // end base test case elements
	    
	    // begin session management test case elements:
	    true,		// server socket session creation enabled?
	    true,		// client session creation enabled?
	    true,		// invalidate the current session?
	    true);		// start a new handshake?

	tcList[3] = new SessionTC(
	    // begin base test case elements:
	    "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",	// cipher suite name
	    false,			// disjoint cipher suites?
	    false,			// keystore enabled?
	    false,			// mutual authentication enabled?
	    EXP_PASS,			// expected test result
	    // end base test case elements
	    
	    // begin session management test case elements:
	    true,		// server socket session creation enabled?
	    true,		// client session creation enabled?
	    true,		// invalidate the current session?
	    true);		// start a new handshake?

All of the above test cases fail with the following exception:

    ERROR: 0/0/0: java.net.SocketException: Connection reset by peer: socket write error
    java.net.SocketException: Connection reset by peer: socket write error
	    at java.net.SocketOutputStream.socketWrite(Native Method)
	    at java.net.SocketOutputStream.write(SocketOutputStream.java:87)
	    at com.sun.net.ssl.internal.ssl.OutputRecord.a([DashoPro-V1.2-120198])
	    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a([DashoPro-V1.2-120198])
	    at com.sun.net.ssl.internal.ssl.Handshaker.sendChangeCipherSpec([DashoPro-V1.2-120198])
	    at com.sun.net.ssl.internal.ssl.ClientHandshaker.e([DashoPro-V1.2-120198])
	    at com.sun.net.ssl.internal.ssl.ClientHandshaker.a([DashoPro-V1.2-120198])
	    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage([DashoPro-V1.2-120198])
	    at com.sun.net.ssl.internal.ssl.Handshaker.process_record([DashoPro-V1.2-120198])
	    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a([DashoPro-V1.2-120198])
	    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a([DashoPro-V1.2-120198])
	    at com.sun.net.ssl.internal.ssl.AppInputStream.read([DashoPro-V1.2-120198])
	    at SSLDataComm.recvMesg(SSLDataComm.java:206)
	    at SSLDataComm.doClientWork(SSLDataComm.java:94)
	    at SSLDataComm.run(SSLDataComm.java:61)
	    at java.lang.Thread.run(Thread.java:485)
    ERROR: 0/0: wrong number of SSL sessions: expect=2 actual=1

These test case failures are in *addition* to the failures documented in

    4282645 2/2 session management with startHandshake() call is unreliable

This bug is reproducible on the following configurations:

    S2.6 server with Win98 and WinNT clients (Kestrel on all)
    WinNT server with Win98 client (Kestrel on both)

This bug is *not* reproducible on the following configurations:

    S2.6 server with S7 client (Kestrel on both)

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: generic FIXED IN: 1.0 INTEGRATED IN: 1.0 VERIFIED IN: 1.0
02-09-2004

SUGGESTED FIX daniel.daugherty@Eng 1999-10-28 Here are the suggested changes after some experimentation: SSLSocket management clean-up: - Change doTestCase() to save all of the SSLSocket(s) instead of just the last SSLsocket. - Change the finally logic in doTestCase() to close all the SSLSocket(s). - Delete SSLSocket.close() calls from SSLDataComm. SSLDataComm logic changes: - Change SSLDataComm to accept a constructor parameter that indicates the number of handshakes to expect. - Modify SSLDataComm's handshake completed listener to count the number of handshake completed events. - Change SSLDataComm to send/receive pairs of messages until the right number of handshakes have been completed or a timer expires. SessionClient and SessionServer changes: - update to use the new SSLDataComm constructor. daniel.daugherty@Eng 1999-11-01 Update the test protocol to the following: Client side: // Do the work necessary to communicate with the server: // // while we need more handshakes // - send a message to the server // - the server will verify the message that it received // - receive a message from the server // - verify the received message // end-while // while the server is not done // - send a client done message to the server // - receive a message from the server // - verify the received message // end-while Server side: // Do the work necessary to communicate with the client: // // while the client is not done // - receive a message from the client // - verify the received message // - send a message to the client // - the client will verify the message that it received // end-while // while we need more handshakes // - receive a message from the client // - verify the received message // - if we got the right number of handshakes // send a server done message to the client and break // else // send a message to the client // end-while // wait for a client message and expect EOF
02-09-2004

EVALUATION daniel.daugherty@Eng 1999-10-28 Yingxian tracked the immediate cause of this bug down to the closing of the SSLSocket in the SSLDataComm thread. In cases where a second handshake is initiated, that second handshake occurs asynchronously. If the second handshake accesses the SSLSocket after the SSLDataComm thread closes it, then an exception is thrown. On Solaris, "java.io.IOException: Broken pipe" is thrown and on WinNT, a "java.net.SocketException: Connection reset by peer: socket write error" is thrown. During e-mail discussions about the bug a number of issues came up. I'm going to document those issues and their resolutions here: My current thinking is that the code that allocates the client SSLSocket(s), doTestCase(), should also be responsible for closing it. I will go ahead and remove the client SSLSocket.close() from the SSLDataComm thread and fix the doTestCase() code. This change will apply to almost all of the tests (not just the SessionIds feature). Here is the current understanding of how the handshake stuff works: - When the first handshake is completed, the HandshakeCompleted listener is called in a separate thread *and* data begins to flow. These two events occur in parallel. - Subsequent handshakes occur asynchronously to data flow so I need to change the tests to send data until that second handshake (if needed) is completed. - The startHandshake() call returns when the requested handshake is complete according to the java doc. This code doesn't work this way, but this issue is being tracked by: 4229603 4/4 handshakeCompleted event delivered only on first handshake Here are the proposed test changes: - Change doTestCase() to save all of the SSLSocket(s) instead of just the last SSLsocket. - Change the finally logic in doTestCase() to close all the SSLSocket(s). - Delete SSLSocket.close() calls from SSLDataComm. - Change SSLDataComm to send/receive pairs of messages until a done-sending-data flag is set. - Figure out a way to indicate when it is okay to stop sending data. The last one is probably a little obscure. Since startHandshake() is not always synchronous we don't have an easy indicator of when it is okay to stop sending data. Jeff suggested having the client try to read something from the server and then have the server send some data when it receives the second handshake completed event. If the second handshake fails to happen, then a socket read timeout exception will be thrown. daniel.daugherty@Eng 1999-10-29 It is still possible for the client to get it's handshakes and close the streams before the server get's all of it's handshakes. More work to do.
29-10-1999