You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Bob Herrmann <bo...@jadn.com> on 2002/10/07 22:23:57 UTC

[PATCH] SSLSocket, CLIENT-AUTH, and JDK1.4

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:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] SSLSocket, CLIENT-AUTH, and JDK1.4

Posted by Bill Barker <wb...@wilshire.com>.
----- Original Message -----
From: "Remy Maucherat" <re...@apache.org>
To: "Tomcat Developers List" <to...@jakarta.apache.org>
Sent: Monday, October 07, 2002 1:44 PM
Subject: Re: [PATCH] SSLSocket, CLIENT-AUTH, and JDK1.4


> Bob Herrmann wrote:
> > 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?
>
> How expensive is that performance wise ?
> The code is only used when client cert is on, right ?

It's only called for CLIENT-CERT authorization, and then only on the first
call to a protected page.  I'm guessing it's pretty expensive, but the
webapp has to specifically request it, and it only happens once.

>
> Remy
>
>
> --
> To unsubscribe, e-mail:
<ma...@jakarta.apache.org>
> For additional commands, e-mail:
<ma...@jakarta.apache.org>
>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] SSLSocket, CLIENT-AUTH, and JDK1.4

Posted by Remy Maucherat <re...@apache.org>.
Bob Herrmann wrote:
> 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?  

How expensive is that performance wise ?
The code is only used when client cert is on, right ?

Remy


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] SSLSocket, CLIENT-AUTH, and JDK1.4

Posted by Bill Barker <wb...@wilshire.com>.
----- Original Message -----
From: "Bob Herrmann" <bo...@jadn.com>
To: "Tomcat Developers List" <to...@jakarta.apache.org>
Sent: Monday, October 07, 2002 1:23 PM
Subject: [PATCH] SSLSocket, CLIENT-AUTH, and JDK1.4


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

Probably we'll need something like 3.3's o.a.t.u.compat.Jdk11Compat at some
point.  For now, something like (taken from Ant):

  static boolean isJava14;

  static {
     isJava14=false;
     try {
           Class.forName("java.lang.CharSequence");
            isJava14=true;
    } catch(Exception ex) {
    }
 }

is more reliable.


>
> 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/jss
e/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:
<ma...@jakarta.apache.org>
> For additional commands, e-mail:
<ma...@jakarta.apache.org>
>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] SSLSocket, CLIENT-AUTH, and JDK1.4

Posted by Patrick Luby <pa...@sun.com>.
Bob,

You can check the JVM version more accurately using the 
"java.specification.version" system property. It will always be "1.4" 
for J2SE 1.4.x so you can do the following:

   if ("1.4".equals(System.getProperty("java.specification.version")))
      ...

Patrick

Bob Herrmann wrote:
> 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:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>

-- 
________________________________________________________________
Patrick Luby                     Email: patrick.luby@sun.com
Sun Microsystems                         Phone: 408-276-7471
901 San Antonio Road, USCA14-303
Palo Alto, CA 94303-4900
________________________________________________________________


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>