Skip to Main Content

Java Security

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

SSL socket close prevents SSL session reuse

843811Oct 5 2007
Hello,

I am writing an SSL client with JDK 1.6.0. My program opens SSL sockets to an SSL server (stunnel 4.20). I noticed on the server side that SSL sessions are never reused.

More precisely, I noticed that when an SSL socket is opened, read from and closed in the same thread, SSL sessions are indeed reused from one socket to the next.
But if I read from the socket and close it in different threads, there is an exception in the ssl layer that invalidates the session.

Here is a sample program:
import java.io.IOException;
import java.net.*;

import javax.net.ssl.*;

public class TestSSLReuse {

	public static void main(String[] args) {

		String sslHost = args[0];
		int sslPort = 0;
		try {
			sslPort = Integer.parseInt(args[1]);
		} catch (NumberFormatException e1) {
			System.exit(1);
		}

		try {
			Connect(sslHost, sslPort);

			// wait 5s
			tempo(5000);

			Connect(sslHost, sslPort);
		} 
		catch (IOException e) {
			e.printStackTrace();
		}

	}

	private static void Connect(String host, int port) throws IOException {
		System.out.println("\n### Open ssl socket to " + host + ":" + port);
		SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault();
		final Socket sslsocket= factory.createSocket();
		sslsocket.connect(new InetSocketAddress(host, port), 5000); 
		System.out.println("### SSL Session for socket (" + sslsocket.hashCode() + "): " + 
				((SSLSocket) sslsocket).getSession().hashCode());

		// Reader thread
		Thread t = new Thread(new Runnable() {
			public void run() {				
				System.out.println("### read thread start");
				try {
					while(true) {
						byte[] data = new byte[16384];
						int n = sslsocket.getInputStream().read(data);
						if (n < 0) {
							System.out.println("### read EOF");
							break;
						}
						else
							System.out.println("### Read " + n + " bytes: " + new String(data, 0, n));
					}
				}
				catch(Exception e) {
					System.out.println("### read error: " + e.getMessage());
				}
				System.out.println("### read thread stop");
							
			}});
		t.start();
					
		// wait 2s
		tempo(2000);

		try {
			sslsocket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println("### SSL socket closed");
}
	
	private static void tempo(long ms) {
		try {
			Thread.sleep(ms);
		} catch (InterruptedException e1) {}
  }

}
SSL traces are activated with option -Djavax.net.debug=ssl, ssl and application traces are mixed, application traces start with ###. The output reads:
### Open ssl socket to skadi:7777
[ssl init traces skipped ...]
%% No cached client session
[ssl handshake traces skipped ...]
%% Cached client session: [Session-1, SSL_RSA_WITH_RC4_128_MD5]
### SSL Session for socket (3541984): 199
### read thread start
Thread-0, READ: TLSv1 Application Data, length = 46
### Read 30 bytes: [skipped]
main, called close()
main, called closeInternal(true)
main, SEND TLSv1 ALERT:  warning, description = close_notify
main, WRITE: TLSv1 Alert, length = 18
Thread-0, handling exception: java.net.SocketException: socket closed
%% Invalidated:  [Session-1, SSL_RSA_WITH_RC4_128_MD5]
Thread-0, SEND TLSv1 ALERT:  fatal, description = unexpected_message
Thread-0, WRITE: TLSv1 Alert, length = 18
Thread-0, Exception sending alert: java.net.SocketException: Socket closed
Thread-0, called closeSocket()
### read error: socket closed
### read thread stop
### SSL socket closed
On the SSL server side (stunnel), one sees clearly the close_notify received and sent back on the ssl socket:
2007.10.04 17:05:57 LOG7[27588:6228896]: TCP_NODELAY option set on remote socket
2007.10.04 17:05:59 LOG7[27588:6228896]: SSL alert (read): warning: close notify
2007.10.04 17:05:59 LOG7[27588:6228896]: SSL closed on SSL_read
2007.10.04 17:05:59 LOG7[27588:6228896]: Socket write shutdown
2007.10.04 17:05:59 LOG7[27588:6228896]: SSL write shutdown
2007.10.04 17:05:59 LOG7[27588:6228896]: SSL alert (write): warning: close notify
2007.10.04 17:05:59 LOG6[27588:6228896]: SSL_shutdown successfully sent close_notify
2007.10.04 17:05:59 LOG5[27588:6228896]: Connection closed: 30 bytes sent to SSL, 0 bytes sent to socket
This is repeatable as long as the SSL server is distant (running on another host). If both the client and the server run on the same machine, this bug disappears, the read method returns with -1 (EOF) and the SSL session remains valid.

Thanks for any input on this matter.
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Nov 2 2007
Added on Oct 5 2007
0 comments
1,311 views