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 java.io;
   44   import java.net;
   45   import java.util.Collection;
   46   import java.util.Vector;
   47   import java.security.KeyStore;
   48   import java.security.SecureRandom;
   49   import java.security.cert.CRL;
   50   import java.security.cert.CRLException;
   51   import java.security.cert.CertPathParameters;
   52   import java.security.cert.CertStore;
   53   import java.security.cert.CertStoreParameters;
   54   import java.security.cert.CertificateException;
   55   import java.security.cert.CertificateFactory;
   56   import java.security.cert.CollectionCertStoreParameters;
   57   import java.security.cert.PKIXBuilderParameters;
   58   import java.security.cert.X509CertSelector;
   59   import javax.net.ssl.CertPathTrustManagerParameters;
   60   import javax.net.ssl.SSLServerSocket;
   61   import javax.net.ssl.SSLContext;
   62   import javax.net.ssl.SSLSessionContext;
   63   import javax.net.ssl.KeyManager;
   64   import javax.net.ssl.KeyManagerFactory;
   65   import javax.net.ssl.ManagerFactoryParameters;
   66   import javax.net.ssl.X509KeyManager;
   67   import javax.net.ssl.TrustManager;
   68   import javax.net.ssl.TrustManagerFactory;
   69   
   70   import org.apache.tomcat.util.res.StringManager;
   71   
   72   /*
   73     1. Make the JSSE's jars available, either as an installed
   74        extension (copy them into jre/lib/ext) or by adding
   75        them to the Tomcat classpath.
   76     2. keytool -genkey -alias tomcat -keyalg RSA
   77        Use "changeit" as password ( this is the default we use )
   78    */
   79   
   80   /**
   81    * SSL server socket factory. It _requires_ a valid RSA key and
   82    * JSSE. 
   83    *
   84    * @author Harish Prabandham
   85    * @author Costin Manolache
   86    * @author Stefan Freyr Stefansson
   87    * @author EKR -- renamed to JSSESocketFactory
   88    * @author Jan Luehe
   89    */
   90   public class JSSE14SocketFactory  extends JSSESocketFactory {
   91   
   92       private static StringManager sm =
   93           StringManager.getManager("org.apache.tomcat.util.net.jsse.res");
   94   
   95       public JSSE14SocketFactory () {
   96       }
   97   
   98       
   99       /**
  100        * Reads the keystore and initializes the SSL socket factory.
  101        */
  102       /* SJSAS 6439313
  103       void init() throws IOException{
  104        */
  105       // START SJSAS 6439313
  106       public void init() throws IOException{
  107       // END SJSAS 6439313
  108           try {
  109   
  110               String clientAuthStr = (String) attributes.get("clientauth");
  111               if (clientAuthStr != null){
  112                   clientAuth = Boolean.valueOf(clientAuthStr).booleanValue();
  113               }
  114   
  115               // SSL protocol variant (e.g., TLS, SSL v3, etc.)
  116               String protocol = (String) attributes.get("protocol");
  117               if (protocol == null) {
  118                   protocol = defaultProtocol;
  119               }
  120   
  121               // Certificate encoding algorithm (e.g., SunX509)
  122               String algorithm = (String) attributes.get("algorithm");
  123               if (algorithm == null) {
  124                   algorithm = defaultAlgorithm;
  125               }
  126   
  127               // Create and init SSLContext
  128               /* SJSAS 6439313
  129               SSLContext context = SSLContext.getInstance(protocol);
  130                */
  131               
  132               // START SJSAS 6439313
  133               context = SSLContext.getInstance(protocol);
  134               // END SJSAS 6439313 
  135               
  136               // Configure SSL session timeout and cache size
  137               configureSSLSessionContext(context.getServerSessionContext());
  138                   
  139               String trustAlgorithm = (String)attributes.get("truststoreAlgorithm");
  140               if (trustAlgorithm == null) {
  141                   trustAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
  142               }
  143   
  144               context.init(getKeyManagers(algorithm,
  145                                           (String) attributes.get("keyAlias")),
  146                            getTrustManagers(trustAlgorithm),
  147                            new SecureRandom());
  148   
  149               // create proxy
  150               sslProxy = context.getServerSocketFactory();
  151   
  152               // Determine which cipher suites to enable
  153               String requestedCiphers = (String)attributes.get("ciphers");
  154               if (requestedCiphers != null) {
  155                   enabledCiphers = getEnabledCiphers(requestedCiphers,
  156                                                      sslProxy.getSupportedCipherSuites());
  157               }
  158   
  159           } catch(Exception e) {
  160               if( e instanceof IOException )
  161                   throw (IOException)e;
  162               throw new IOException(e.getMessage());
  163           }
  164       }
  165   
  166       /**
  167        * Gets the initialized key managers.
  168        */
  169       protected KeyManager[] getKeyManagers(String algorithm,
  170                                             String keyAlias)
  171                   throws Exception {
  172   
  173           KeyManager[] kms = null;
  174   
  175           String keystorePass = getKeystorePassword();
  176   
  177           KeyStore ks = getKeystore(keystorePass);
  178           if (keyAlias != null && !ks.isKeyEntry(keyAlias)) {
  179               throw new IOException(sm.getString("jsse.alias_no_key_entry", keyAlias));
  180           }
  181   
  182           KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
  183           kmf.init(ks, keystorePass.toCharArray());
  184   
  185           kms = kmf.getKeyManagers();
  186           if (keyAlias != null) {
  187               // START SJSAS 6266949
  188               /*
  189               if (JSSESocketFactory.defaultKeystoreType.equals(keystoreType)) {
  190                   keyAlias = keyAlias.toLowerCase();
  191               }
  192               */
  193               //END SJSAS 6266949
  194               
  195               for(int i=0; i<kms.length; i++) {
  196                   kms[i] = new JSSEKeyManager((X509KeyManager)kms[i], keyAlias);
  197               }
  198           }
  199   
  200           return kms;
  201       }
  202   
  203       /**
  204        * Gets the intialized trust managers.
  205        */
  206       protected TrustManager[] getTrustManagers(String algorithm)
  207                   throws Exception {
  208   
  209           String crlf = (String) attributes.get("crlFile");
  210   
  211           TrustManager[] tms = null;
  212   
  213           KeyStore trustStore = getTrustStore();
  214           if (trustStore != null) {
  215               if (crlf == null) {
  216                   TrustManagerFactory tmf =
  217                       TrustManagerFactory.getInstance(algorithm);
  218                   tmf.init(trustStore);
  219                   tms = tmf.getTrustManagers();
  220               } else {
  221                   TrustManagerFactory tmf =
  222                       TrustManagerFactory.getInstance(algorithm);
  223                   CertPathParameters params = getParameters(algorithm, crlf,
  224                                                             trustStore);
  225                   ManagerFactoryParameters mfp = 
  226                       new CertPathTrustManagerParameters(params);
  227                   tmf.init(mfp);
  228                   tms = tmf.getTrustManagers();
  229               }
  230           }
  231   
  232           return tms;
  233       }
  234   
  235   
  236       /**
  237        * Return the initialization parameters for the TrustManager.
  238        * Currently, only the default <code>PKIX</code> is supported.
  239        * 
  240        * @param algorithm The algorithm to get parameters for.
  241        * @param crlf The path to the CRL file.
  242        * @param trustStore The configured TrustStore.
  243        * @return The parameters including the CRLs and TrustStore.
  244        */
  245       protected CertPathParameters getParameters(String algorithm, 
  246                                                  String crlf, 
  247                                                  KeyStore trustStore)
  248               throws Exception {
  249   
  250           CertPathParameters params = null;
  251           if ("PKIX".equalsIgnoreCase(algorithm)) {
  252               PKIXBuilderParameters xparams =
  253                   new PKIXBuilderParameters(trustStore, 
  254                                             new X509CertSelector());
  255               Collection crls = getCRLs(crlf);
  256               CertStoreParameters csp = new CollectionCertStoreParameters(crls);
  257               CertStore store = CertStore.getInstance("Collection", csp);
  258               xparams.addCertStore(store);
  259               xparams.setRevocationEnabled(true);
  260               String trustLength = (String)attributes.get("trustMaxCertLength");
  261               if (trustLength != null) {
  262                   try {
  263                       xparams.setMaxPathLength(Integer.parseInt(trustLength));
  264                   } catch(Exception ex) {
  265                       log.warn("Bad maxCertLength: " + trustLength);
  266                   }
  267               }
  268               params = xparams;
  269           } else {
  270               throw new CRLException("CRLs not supported for type: "
  271                                      + algorithm);
  272           }
  273           return params;
  274       }
  275   
  276   
  277       /**
  278        * Load the collection of CRLs.
  279        */
  280       protected Collection<? extends CRL> getCRLs(String crlf) 
  281               throws IOException, CRLException, CertificateException {
  282   
  283           File crlFile = new File(crlf);
  284           if (!crlFile.isAbsolute()) {
  285               crlFile = new File(System.getProperty("catalina.base"), crlf);
  286           }
  287           Collection<? extends CRL> crls = null;
  288           InputStream is = null;
  289           try {
  290               CertificateFactory cf = CertificateFactory.getInstance("X.509");
  291               is = new FileInputStream(crlFile);
  292               crls = cf.generateCRLs(is);
  293           } catch(IOException iex) {
  294               throw iex;
  295           } catch(CRLException crle) {
  296               throw crle;
  297           } catch(CertificateException ce) {
  298               throw ce;
  299           } finally { 
  300               if (is != null) {
  301                   try {
  302                       is.close();
  303                   } catch (Exception ex) {
  304                   }
  305               }
  306           }
  307   
  308           return crls;
  309       }
  310   
  311   
  312       protected void setEnabledProtocols(SSLServerSocket socket, String []protocols){
  313           if (protocols != null) {
  314               socket.setEnabledProtocols(protocols);
  315           }
  316       }
  317   
  318       protected String[] getEnabledProtocols(SSLServerSocket socket,
  319                                              String requestedProtocols){
  320           String[] supportedProtocols = socket.getSupportedProtocols();
  321   
  322           String[] enabledProtocols = null;
  323   
  324           if (requestedProtocols != null) {
  325               Vector vec = null;
  326               String protocol = requestedProtocols;
  327               int index = requestedProtocols.indexOf(',');
  328               if (index != -1) {
  329                   int fromIndex = 0;
  330                   while (index != -1) {
  331                       protocol = requestedProtocols.substring(fromIndex, index).trim();
  332                       if (protocol.length() > 0) {
  333                           /*
  334                            * Check to see if the requested protocol is among the
  335                            * supported protocols, i.e., may be enabled
  336                            */
  337                           for (int i=0; supportedProtocols != null
  338                                        && i<supportedProtocols.length; i++) {
  339                               if (supportedProtocols[i].equals(protocol)) {
  340                                   if (vec == null) {
  341                                       vec = new Vector();
  342                                   }
  343                                   vec.addElement(protocol);
  344                                   break;
  345                               }
  346                           }
  347                       }
  348                       fromIndex = index+1;
  349                       index = requestedProtocols.indexOf(',', fromIndex);
  350                   } // while
  351                   protocol = requestedProtocols.substring(fromIndex);
  352               }
  353   
  354               if (protocol != null) {
  355                   protocol = protocol.trim();
  356                   if (protocol.length() > 0) {
  357                       /*
  358                        * Check to see if the requested protocol is among the
  359                        * supported protocols, i.e., may be enabled
  360                        */
  361                       for (int i=0; supportedProtocols != null
  362                                    && i<supportedProtocols.length; i++) {
  363                           if (supportedProtocols[i].equals(protocol)) {
  364                               if (vec == null) {
  365                                   vec = new Vector();
  366                               }
  367                               vec.addElement(protocol);
  368                               break;
  369                           }
  370                       }
  371                   }
  372               }           
  373   
  374               if (vec != null) {
  375                   enabledProtocols = new String[vec.size()];
  376                   vec.copyInto(enabledProtocols);
  377               }
  378           }
  379   
  380           return enabledProtocols;
  381       }
  382   
  383   
  384       /*
  385        * Configures the given SSLSessionContext.
  386        *
  387        * @param sslSessionCtxt The SSLSessionContext to configure
  388        */
  389       private void configureSSLSessionContext(SSLSessionContext sslSessionCtxt) {
  390   
  391           String attrValue = (String) attributes.get("sslSessionTimeout");
  392           if (attrValue != null) {
  393               sslSessionCtxt.setSessionTimeout(
  394                   Integer.valueOf(attrValue).intValue());
  395           }
  396   
  397           attrValue = (String) attributes.get("ssl3SessionTimeout");
  398           if (attrValue != null) {
  399               sslSessionCtxt.setSessionTimeout(
  400                   Integer.valueOf(attrValue).intValue());
  401           }
  402        
  403           attrValue = (String) attributes.get("sslSessionCacheSize");
  404           if (attrValue != null) {
  405               sslSessionCtxt.setSessionCacheSize(
  406                   Integer.valueOf(attrValue).intValue());
  407           }
  408       }
  409   
  410   }

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