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]>

Reply via email to