You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by bi...@apache.org on 2003/04/27 07:36:51 UTC

cvs commit: jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse JSSE14SocketFactory.java JSSE14Support.java JSSEImplementation.java JSSESocketFactory.java JSSESupport.java

billbarker    2003/04/26 22:36:50

  Modified:    util/java/org/apache/tomcat/util/net Tag: coyote_10
                        SSLImplementation.java
               util/java/org/apache/tomcat/util/net/jsse Tag: coyote_10
                        JSSEImplementation.java JSSESocketFactory.java
                        JSSESupport.java
  Added:       util/java/org/apache/tomcat/util/net/jsse Tag: coyote_10
                        JSSE14SocketFactory.java JSSE14Support.java
  Log:
  Porting JSDK1.4 support from the HEAD branch.
  
  From the tomcat-users list, it seems that SSL-support doesn't work well with non-Sun 1.4.x JVMs.
  
  Reported By: alain@fbsims.com
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.2.2.1   +17 -4     jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/SSLImplementation.java
  
  Index: SSLImplementation.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/SSLImplementation.java,v
  retrieving revision 1.2
  retrieving revision 1.2.2.1
  diff -u -r1.2 -r1.2.2.1
  --- SSLImplementation.java	4 Oct 2002 20:03:10 -0000	1.2
  +++ SSLImplementation.java	27 Apr 2003 05:36:50 -0000	1.2.2.1
  @@ -69,6 +69,9 @@
      @author EKR
   */
   abstract public class SSLImplementation {
  +    private static org.apache.commons.logging.Log logger =
  +        org.apache.commons.logging.LogFactory.getLog(SSLImplementation.class);
  +
       // The default implementations in our search path
       private static final String PureTLSImplementationClass=
   	"org.apache.tomcat.util.net.puretls.PureTLSImplementation";
  @@ -77,19 +80,20 @@
       
       private static final String[] implementations=
       {
  -	PureTLSImplementationClass,
  -	JSSEImplementationClass
  +        PureTLSImplementationClass,
  +        JSSEImplementationClass
       };
   
       public static SSLImplementation getInstance() throws ClassNotFoundException
       {
   	for(int i=0;i<implementations.length;i++){
   	    try {
  -		SSLImplementation impl=
  +               SSLImplementation impl=
   		    getInstance(implementations[i]);
   		return impl;
   	    } catch (Exception e) {
  -		//e.printStackTrace();
  +		if(logger.isTraceEnabled()) 
  +		    logger.trace("Error creating " + implementations[i],e);
   	    }
   	}
   
  @@ -103,9 +107,18 @@
   	if(className==null) return getInstance();
   
   	try {
  +	    // Workaround for the J2SE 1.4.x classloading problem (under Solaris).
  +	    // Class.forName(..) fails without creating class using new.
  +	    // This is an ugly workaround. 
  +	    if( JSSEImplementationClass.equals(className) ) {
  +	    	return new org.apache.tomcat.util.net.jsse.JSSEImplementation();
  +	    }
   	    Class clazz=Class.forName(className);
   	    return (SSLImplementation)clazz.newInstance();
   	} catch (Exception e){
  +	    if(logger.isDebugEnabled())
  +		logger.debug("Error loading SSL Implementation "
  +			     +className, e);
   	    throw new ClassNotFoundException("Error loading SSL Implementation "
   				      +className+ " :" +e.toString());
   	}
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.1   +47 -5     jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java
  
  Index: JSSEImplementation.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java,v
  retrieving revision 1.1
  retrieving revision 1.1.2.1
  diff -u -r1.1 -r1.1.2.1
  --- JSSEImplementation.java	4 Oct 2002 20:03:10 -0000	1.1
  +++ JSSEImplementation.java	27 Apr 2003 05:36:50 -0000	1.1.2.1
  @@ -59,11 +59,13 @@
   
   package org.apache.tomcat.util.net.jsse;
   
  +import org.apache.tomcat.util.compat.JdkCompat;
   import org.apache.tomcat.util.net.SSLImplementation;
   import org.apache.tomcat.util.net.SSLSupport;
   import org.apache.tomcat.util.net.ServerSocketFactory;
   import java.io.*;
   import java.net.*;
  +import java.lang.reflect.Constructor;
   import javax.net.ssl.SSLSocket;
   
   /* JSSEImplementation:
  @@ -72,12 +74,21 @@
   
      @author EKR
   */
  -	
  +        
   public class JSSEImplementation extends SSLImplementation
   {
  +    static final String JSSE14SocketFactory = 
  +        "org.apache.tomcat.util.net.jsse.JSSE14SocketFactory";
  +    static final String JSSE14Support = 
  +        "org.apache.tomcat.util.net.jsse.JSSE14Support";
  +    static final String SSLSocketClass = "javax.net.ssl.SSLSocket";
  +
  +    static org.apache.commons.logging.Log logger = 
  +        org.apache.commons.logging.LogFactory.getLog(JSSEImplementation.class);
  +
       public JSSEImplementation() throws ClassNotFoundException {
  -	// Check to see if JSSE is floating around somewhere
  -	Class.forName("javax.net.ssl.SSLServerSocketFactory");
  +        // Check to see if JSSE is floating around somewhere
  +        Class.forName("javax.net.ssl.SSLServerSocketFactory");
       }
   
   
  @@ -87,12 +98,43 @@
         
       public ServerSocketFactory getServerSocketFactory()
       {
  -	return new JSSESocketFactory();
  +        ServerSocketFactory ssf = null;
  +        if( JdkCompat.isJava14() ) {
  +            try {
  +                Class ssfCl = Class.forName(JSSE14SocketFactory);
  +                ssf =(ServerSocketFactory)ssfCl.newInstance();
  +            } catch(Exception ex) {
  +                if(logger.isDebugEnabled())
  +                    logger.debug("Error finding " + JSSE14SocketFactory, ex);
  +                ssf = new JSSESocketFactory();
  +            }
  +        } else {
  +            ssf = new JSSESocketFactory();
  +        }
  +        return ssf;
       } 
   
       public SSLSupport getSSLSupport(Socket s)
       {
  -	return new JSSESupport((SSLSocket)s);
  +        SSLSupport ssls = null;
  +        if( JdkCompat.isJava14() ) {
  +            try {
  +                Class sslsCl = Class.forName(JSSE14Support);
  +                Class [] cparams = new Class[1];
  +                cparams[0] = Class.forName(SSLSocketClass);
  +                Constructor sslc = sslsCl.getConstructor(cparams);
  +                Object [] params = new Object[1];
  +                params[0] = s;
  +                ssls = (SSLSupport)sslc.newInstance(params);
  +            } catch(Exception ex) {
  +                if(logger.isDebugEnabled())
  +                    logger.debug("Unable to get " + JSSE14Support, ex);
  +                ssls = new JSSESupport((SSLSocket)s);
  +            }
  +        } else {
  +            ssls = new JSSESupport((SSLSocket)s);
  +        }
  +        return ssls;
       }
   
   
  
  
  
  1.1.2.1   +14 -6     jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java
  
  Index: JSSESocketFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java,v
  retrieving revision 1.1
  retrieving revision 1.1.2.1
  diff -u -r1.1 -r1.1.2.1
  --- JSSESocketFactory.java	4 Oct 2002 20:03:10 -0000	1.1
  +++ JSSESocketFactory.java	27 Apr 2003 05:36:50 -0000	1.1.2.1
  @@ -92,15 +92,17 @@
   public class JSSESocketFactory
       extends org.apache.tomcat.util.net.ServerSocketFactory
   {
  -    private String keystoreType;
  +    String keystoreType;
   
  +    static org.apache.commons.logging.Log logger =
  +	org.apache.commons.logging.LogFactory.getLog(JSSESocketFactory.class);
       static String defaultKeystoreType = "JKS";
       static String defaultProtocol = "TLS";
       static String defaultAlgorithm = "SunX509";
       static boolean defaultClientAuth = false;
   
  -    private boolean clientAuth = false;
  -    private SSLServerSocketFactory sslProxy = null;
  +    boolean clientAuth = false;
  +    SSLServerSocketFactory sslProxy = null;
       
       // defaults
       static String defaultKeystoreFile=System.getProperty("user.home") +
  @@ -146,7 +148,7 @@
       // -------------------- Internal methods
       /** Read the keystore, init the SSL socket factory
        */
  -    private void initProxy() throws IOException {
  +    void initProxy() throws IOException {
   	try {
   	    Security.addProvider (new sun.security.provider.Sun());
   	    Security.addProvider (new com.sun.net.ssl.internal.ssl.Provider());
  @@ -247,12 +249,18 @@
        
       /** Set server socket properties ( accepted cipher suites, etc)
        */
  -    private void initServerSocket(ServerSocket ssocket) {
  +    void initServerSocket(ServerSocket ssocket) {
   	SSLServerSocket socket=(SSLServerSocket)ssocket;
   
   	// We enable all cipher suites when the socket is
   	// connected - XXX make this configurable 
   	String cipherSuites[] = socket.getSupportedCipherSuites();
  +	if(logger.isDebugEnabled()) {
  +	    StringBuffer sb = new StringBuffer();
  +	    for(int ii=0; ii < cipherSuites.length; ii++)
  +		sb.append(cipherSuites[ii]).append(':');
  +	    logger.debug("CipherSuites: " + sb);
  +	}
   	socket.setEnabledCipherSuites(cipherSuites);
   
   	// we don't know if client auth is needed -
  @@ -260,7 +268,7 @@
   	socket.setNeedClientAuth(clientAuth);
       }
   
  -    private KeyStore initKeyStore( String keystoreFile,
  +    KeyStore initKeyStore( String keystoreFile,
   				   String keyPass)
   	throws IOException
       {
  
  
  
  1.3.2.1   +56 -87    jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSESupport.java
  
  Index: JSSESupport.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSESupport.java,v
  retrieving revision 1.3
  retrieving revision 1.3.2.1
  diff -u -r1.3 -r1.3.2.1
  --- JSSESupport.java	9 Oct 2002 15:03:21 -0000	1.3
  +++ JSSESupport.java	27 Apr 2003 05:36:50 -0000	1.3.2.1
  @@ -66,8 +66,6 @@
   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;
   
  @@ -86,8 +84,10 @@
   */
   
   class JSSESupport implements SSLSupport {
  +    private org.apache.commons.logging.Log log =
  +	org.apache.commons.logging.LogFactory.getLog(JSSESupport.class);
   
  -    private SSLSocket ssl;
  +    protected SSLSocket ssl;
   
   
       JSSESupport(SSLSocket sock){
  @@ -103,61 +103,68 @@
       }
   
       public Object[] getPeerCertificateChain() 
  -	throws IOException {
  -	return getPeerCertificateChain(false);
  +        throws IOException {
  +        return getPeerCertificateChain(false);
       }
   
  -    public Object[] getPeerCertificateChain(boolean force)
  -	throws IOException {
  -        // Look up the current SSLSession
  -        SSLSession session = ssl.getSession();
  -        if (session == null)
  -            return null;
  -
  -        // Convert JSSE's certificate format to the ones we need
  +    protected java.security.cert.X509Certificate [] 
  +	getX509Certificates(SSLSession session) throws IOException {
           X509Certificate jsseCerts[] = null;
  -        java.security.cert.X509Certificate x509Certs[] = null;
  -        try {
  +	jsseCerts = session.getPeerCertificateChain();
  +
  +	if(jsseCerts == null)
  +	    jsseCerts = new X509Certificate[0];
  +	java.security.cert.X509Certificate [] x509Certs =
  +	    new java.security.cert.X509Certificate[jsseCerts.length];
  +	for (int i = 0; i < x509Certs.length; i++) {
   	    try {
  -		jsseCerts = session.getPeerCertificateChain();
  -	    } catch(Exception bex) {
  -		// ignore.
  -	    }
  -            if (jsseCerts == null)
  -                jsseCerts = new X509Certificate[0];
  -	    if(jsseCerts.length <= 0 && force) {
  -		session.invalidate();
  -		ssl.setNeedClientAuth(true);
  -		ssl.startHandshake();
  -		if ("1.4".equals(System.getProperty("java.specification.version"))) {
  -		    synchronousHandshake(ssl);
  -		}
  -		session = ssl.getSession();
  -		jsseCerts = session.getPeerCertificateChain();
  -		if(jsseCerts == null)
  -		    jsseCerts = new X509Certificate[0];
  +		byte buffer[] = jsseCerts[i].getEncoded();
  +		CertificateFactory cf =
  +		    CertificateFactory.getInstance("X.509");
  +		ByteArrayInputStream stream =
  +		    new ByteArrayInputStream(buffer);
  +		x509Certs[i] = (java.security.cert.X509Certificate)
  +		    cf.generateCertificate(stream);
  +		if(log.isTraceEnabled())
  +		    log.trace("Cert #" + i + " = " + x509Certs[i]);
  +	    } catch(Exception ex) {
  +		log.info("Error translating " + jsseCerts[i], ex);
  +		return null;
   	    }
  -            x509Certs =
  -              new java.security.cert.X509Certificate[jsseCerts.length];
  -            for (int i = 0; i < x509Certs.length; i++) {
  -                byte buffer[] = jsseCerts[i].getEncoded();
  -                CertificateFactory cf =
  -                  CertificateFactory.getInstance("X.509");
  -                ByteArrayInputStream stream =
  -                  new ByteArrayInputStream(buffer);
  -                x509Certs[i] = (java.security.cert.X509Certificate)
  -                  cf.generateCertificate(stream);
  -            }
  -	} catch (Throwable t) {
  +	}
  +	
  +	if ( x509Certs.length < 1 )
   	    return null;
  -        }
  -
  -        if ((x509Certs == null) || (x509Certs.length < 1))
  +	return x509Certs;
  +    }
  +    public Object[] getPeerCertificateChain(boolean force)
  +        throws IOException {
  +        // Look up the current SSLSession
  +	SSLSession session = ssl.getSession();
  +        if (session == null)
               return null;
   
  -        return x509Certs;
  +        // Convert JSSE's certificate format to the ones we need
  +	X509Certificate [] jsseCerts = null;
  +	try {
  +	    jsseCerts = session.getPeerCertificateChain();
  +	} catch(Exception bex) {
  +	    // ignore.
  +	}
  +	if (jsseCerts == null)
  +	    jsseCerts = new X509Certificate[0];
  +	if(jsseCerts.length <= 0 && force) {
  +	    session.invalidate();
  +	    handShake();
  +	    session = ssl.getSession();
  +	}
  +        return getX509Certificates(session);
  +    }
  +
  +    protected void handShake() throws IOException {
  +        ssl.setNeedClientAuth(true);
  +        ssl.startHandshake();
       }
  -
       /**
        * Copied from <code>org.apache.catalina.valves.CertificateValve</code>
        */
  @@ -204,44 +211,6 @@
           return buf.toString();
       }
   
  -    /**
  -     * JSSE in JDK 1.4 has an issue/feature 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 (IOException e) {
  -                // ignore - presumably the timeout
  -            }
  -            if (listener.completed) {
  -                break;
  -            }
  -        }
  -        socket.removeHandshakeCompletedListener(listener);
  -        socket.setSoTimeout(oldTimeout);
  -        if (listener.completed == false) {
  -            throw new SocketException("SSL Cert handshake timeout");
  -        }
  -    }
  -
  -    private static class Listener implements HandshakeCompletedListener {
  -        volatile boolean completed = false;
  -        public void handshakeCompleted(HandshakeCompletedEvent event) {
  -            completed = true;
  -        }
  -    }
   
   }
   
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.2.2.1   +1 -1      jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE14SocketFactory.java
  
  Index: JSSE14SocketFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE14SocketFactory.java,v
  retrieving revision 1.2
  retrieving revision 1.2.2.1
  diff -u -r1.2 -r1.2.2.1
  --- JSSE14SocketFactory.java	15 Mar 2003 07:00:07 -0000	1.2
  +++ JSSE14SocketFactory.java	27 Apr 2003 05:36:50 -0000	1.2.2.1
  @@ -173,7 +173,7 @@
   
               // create proxy
               sslProxy = context.getServerSocketFactory();
  -
  +            logger.debug("Init done");
               return;
           } catch(Exception e) {
               if( e instanceof IOException )
  
  
  
  1.4.2.1   +0 -0      jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE14Support.java
  
  Index: JSSE14Support.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE14Support.java,v
  retrieving revision 1.4
  retrieving revision 1.4.2.1
  diff -u -r1.4 -r1.4.2.1
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org