Home » apache-tomcat-6.0.26-src » org.apache » tomcat » util » net » jsse » [javadoc | source]

    1   
    2   
    3   /*
    4    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    5    * 
    6    * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
    7    * 
    8    * Portions Copyright Apache Software Foundation.
    9    * 
   10    * The contents of this file are subject to the terms of either the GNU
   11    * General Public License Version 2 only ("GPL") or the Common Development
   12    * and Distribution License("CDDL") (collectively, the "License").  You
   13    * may not use this file except in compliance with the License. You can obtain
   14    * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
   15    * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
   16    * language governing permissions and limitations under the License.
   17    * 
   18    * When distributing the software, include this License Header Notice in each
   19    * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
   20    * Sun designates this particular file as subject to the "Classpath" exception
   21    * as provided by Sun in the GPL Version 2 section of the License file that
   22    * accompanied this code.  If applicable, add the following below the License
   23    * Header, with the fields enclosed by brackets [] replaced by your own
   24    * identifying information: "Portions Copyrighted [year]
   25    * [name of copyright owner]"
   26    * 
   27    * Contributor(s):
   28    * 
   29    * If you wish your version of this file to be governed by only the CDDL or
   30    * only the GPL Version 2, indicate your decision by adding "[Contributor]
   31    * elects to include this software in this distribution under the [CDDL or GPL
   32    * Version 2] license."  If you don't indicate a single choice of license, a
   33    * recipient has the option to distribute your version of this file under
   34    * either the CDDL, the GPL Version 2 or to extend the choice of license to
   35    * its licensees as provided above.  However, if you add GPL Version 2 code
   36    * and therefore, elected the GPL Version 2 license, then the option applies
   37    * only if the new code is made subject to such option by the copyright
   38    * holder.
   39    */
   40   
   41   package org.apache.tomcat.util.net.jsse;
   42   
   43   import org.apache.tomcat.util.net.SSLSupport;
   44   import java.io;
   45   import java.net;
   46   import java.util.Vector;
   47   import java.security.cert.CertificateFactory;
   48   import java.security.cert.X509Certificate;
   49   import java.security.cert.Certificate;
   50   import javax.net.ssl.SSLSession;
   51   import javax.net.ssl.SSLSocket;
   52   import javax.net.ssl.SSLException;
   53   import javax.net.ssl.HandshakeCompletedListener;
   54   import javax.net.ssl.HandshakeCompletedEvent;
   55   import java.security.cert.CertificateFactory;
   56   // START SJSAS 6439313
   57   import javax.net.ssl.SSLEngine;
   58   // END SJSAS 6439313
   59   
   60   /* JSSESupport
   61   
   62      Concrete implementation class for JSSE
   63      Support classes.
   64   
   65      This will only work with JDK 1.2 and up since it
   66      depends on JDK 1.2's certificate support
   67   
   68      @author EKR
   69      @author Craig R. McClanahan
   70      Parts cribbed from JSSECertCompat       
   71      Parts cribbed from CertificatesValve
   72   */
   73   
   74   class JSSE14Support extends JSSESupport {
   75   
   76       private static com.sun.org.apache.commons.logging.Log logger =
   77           com.sun.org.apache.commons.logging.LogFactory.getLog(JSSE14Support.class);
   78   
   79       Listener listener = new Listener();
   80   
   81       public JSSE14Support(SSLSocket sock){
   82           super(sock);
   83           sock.addHandshakeCompletedListener(listener);
   84       }
   85   
   86       // START SJSAS 6439313
   87       public JSSE14Support(SSLEngine sslEngine){
   88           super(sslEngine);
   89       }
   90       // END SJSAS 6439313
   91       
   92       protected void handShake() throws IOException {
   93           ssl.setNeedClientAuth(true);
   94           synchronousHandshake(ssl);        
   95       }
   96   
   97       /**
   98        * JSSE in JDK 1.4 has an issue/feature that requires us to do a
   99        * read() to get the client-cert.  As suggested by Andreas
  100        * Sterbenz
  101        */
  102       private  void synchronousHandshake(SSLSocket socket) 
  103           throws IOException {
  104           InputStream in = socket.getInputStream();
  105           int oldTimeout = socket.getSoTimeout();
  106           socket.setSoTimeout(1000);
  107           byte[] b = new byte[0];
  108           listener.reset();
  109           socket.startHandshake();
  110           int maxTries = 60; // 60 * 1000 = example 1 minute time out
  111           for (int i = 0; i < maxTries; i++) {
  112   	    if(logger.isTraceEnabled())
  113   		logger.trace("Reading for try #" +i);
  114               try {
  115                   int x = in.read(b);
  116               } catch(SSLException sslex) {
  117                   logger.info("SSL Error getting client Certs",sslex);
  118                   throw sslex;
  119               } catch (IOException e) {
  120                   // ignore - presumably the timeout
  121               }
  122               if (listener.completed) {
  123                   break;
  124               }
  125           }
  126           socket.setSoTimeout(oldTimeout);
  127           if (listener.completed == false) {
  128               throw new SocketException("SSL Cert handshake timeout");
  129           }
  130       }
  131   
  132       /** Return the X509certificates or null if we can't get them.
  133        *  XXX We should allow unverified certificates 
  134        */ 
  135       protected X509Certificate [] getX509Certificates(SSLSession session) 
  136   	throws IOException 
  137       {
  138           Certificate [] certs=null;
  139           try {
  140   	    certs = session.getPeerCertificates();
  141           } catch( Throwable t ) {
  142               logger.debug("Error getting client certs",t);
  143               return null;
  144           }
  145           if( certs==null ) return null;
  146           
  147           X509Certificate [] x509Certs = new X509Certificate[certs.length];
  148   	for(int i=0; i < certs.length; i++) {
  149   	    if( certs[i] instanceof X509Certificate ) {
  150   		// always currently true with the JSSE 1.1.x
  151   		x509Certs[i] = (X509Certificate)certs[i];
  152   	    } else {
  153   		try {
  154   		    byte [] buffer = certs[i].getEncoded();
  155   		    CertificateFactory cf =
  156   			CertificateFactory.getInstance("X.509");
  157   		    ByteArrayInputStream stream =
  158   			new ByteArrayInputStream(buffer);
  159   		    x509Certs[i] = (X509Certificate)
  160   			cf.generateCertificate(stream);
  161   		} catch(Exception ex) { 
  162   		    logger.info("Error translating cert " + certs[i], ex);
  163   		    return null;
  164   		}
  165   	    }
  166   	    if(logger.isTraceEnabled())
  167   		logger.trace("Cert #" + i + " = " + x509Certs[i]);
  168   	}
  169   	if(x509Certs.length < 1)
  170   	    return null;
  171   	return x509Certs;
  172       }
  173   
  174   
  175       private static class Listener implements HandshakeCompletedListener {
  176           volatile boolean completed = false;
  177           public void handshakeCompleted(HandshakeCompletedEvent event) {
  178               completed = true;
  179           }
  180           void reset() {
  181               completed = false;
  182           }
  183       }
  184   
  185   }
  186   

Home » apache-tomcat-6.0.26-src » org.apache » tomcat » util » net » jsse » [javadoc | source]