Before I commit this diff, I would like some eyes. This fixes a problem with JSSE doing request for CERTS on an already established SSL Socket.
I am concerned that this change may not pass the sniff test as I check a System.getProperty("java.vm").startsWith("1.4") to see if the extra jiggle is needed on the SSLSocket - but my instincts tell me that is colorfully kludgey. Ideas? Index: util/java/org/apache/tomcat/util/net/jsse/JSSESupport.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSESupport.java,v retrieving revision 1.1 diff -u -r1.1 JSSESupport.java --- util/java/org/apache/tomcat/util/net/jsse/JSSESupport.java 4 Oct 2002 20:03:10 -0000 1.1 +++ util/java/org/apache/tomcat/util/net/jsse/JSSESupport.java 7 Oct 2002 20:15:14 -0000 @@ -66,6 +66,8 @@ import java.security.cert.CertificateFactory; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; +import javax.net.ssl.HandshakeCompletedListener; +import javax.net.ssl.HandshakeCompletedEvent; import java.security.cert.CertificateFactory; import javax.security.cert.X509Certificate; @@ -127,6 +129,9 @@ session.invalidate(); ssl.setNeedClientAuth(true); ssl.startHandshake(); + if ( System.getProperty("java.version").startsWith("1.4") ){ + synchronousHandshake(ssl); + } session = ssl.getSession(); jsseCerts = session.getPeerCertificateChain(); if(jsseCerts == null) @@ -198,5 +203,44 @@ } return buf.toString(); } + + /** + * JSSE in JDK 1.4 has an issue that requires us to do a read() to + * get the client-cert. As suggested by Andreas Sterbenz + */ + private static void synchronousHandshake(SSLSocket socket) + throws IOException { + InputStream in = socket.getInputStream(); + int oldTimeout = socket.getSoTimeout(); + socket.setSoTimeout(100); + Listener listener = new Listener(); + socket.addHandshakeCompletedListener(listener); + byte[] b = new byte[0]; + socket.startHandshake(); + int maxTries = 50; // 50 * 100 = example 5 second rehandshake timeout + for (int i = 0; i < maxTries; i++) { + try { + int x = in.read(b); + } catch (SocketTimeoutException e) { + // ignore + } + if (listener.completed) { + break; + } + } + socket.removeHandshakeCompletedListener(listener); + socket.setSoTimeout(oldTimeout); + if (listener.completed == false) { + throw new SocketTimeoutException("SSL Cert handshake timeout"); + } + } + + private static class Listener implements HandshakeCompletedListener { + volatile boolean completed = false; + public void handshakeCompleted(HandshakeCompletedEvent event) { + completed = true; + } + } + } -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>