Home » openjdk-7 » javax » crypto » [javadoc | source]

    1   /*
    2    * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package javax.crypto;
   27   
   28   import java.security;
   29   import java.net;
   30   import java.util;
   31   import java.util.jar;
   32   
   33   /**
   34    * The JCE security manager.
   35    *
   36    * <p>The JCE security manager is responsible for determining the maximum
   37    * allowable cryptographic strength for a given applet/application, for a given
   38    * algorithm, by consulting the configured jurisdiction policy files and
   39    * the cryptographic permissions bundled with the applet/application.
   40    *
   41    * <p>Note that this security manager is never installed, only instantiated.
   42    *
   43    * @author Jan Luehe
   44    *
   45    * @since 1.4
   46    */
   47   
   48   final class JceSecurityManager extends SecurityManager {
   49   
   50       private static final CryptoPermissions defaultPolicy;
   51       private static final CryptoPermissions exemptPolicy;
   52       private static final CryptoAllPermission allPerm;
   53       private static final Vector TrustedCallersCache = new Vector(2);
   54       private static final Map exemptCache = new HashMap();
   55   
   56       // singleton instance
   57       static final JceSecurityManager INSTANCE;
   58   
   59       static {
   60           defaultPolicy = JceSecurity.getDefaultPolicy();
   61           exemptPolicy = JceSecurity.getExemptPolicy();
   62           allPerm = CryptoAllPermission.INSTANCE;
   63           INSTANCE = (JceSecurityManager)
   64                 AccessController.doPrivileged(new PrivilegedAction() {
   65                     public Object run() {
   66                         return new JceSecurityManager();
   67                     }
   68                 });
   69       }
   70   
   71       private JceSecurityManager() {
   72           // empty
   73       }
   74   
   75       /**
   76        * Returns the maximum allowable crypto strength for the given
   77        * applet/application, for the given algorithm.
   78        */
   79       CryptoPermission getCryptoPermission(String alg) {
   80           // Need to convert to uppercase since the crypto perm
   81           // lookup is case sensitive.
   82           alg = alg.toUpperCase(Locale.ENGLISH);
   83   
   84           // If CryptoAllPermission is granted by default, we return that.
   85           // Otherwise, this will be the permission we return if anything goes
   86           // wrong.
   87           CryptoPermission defaultPerm = getDefaultPermission(alg);
   88           if (defaultPerm == CryptoAllPermission.INSTANCE) {
   89               return defaultPerm;
   90           }
   91   
   92           // Determine the codebase of the caller of the JCE API.
   93           // This is the codebase of the first class which is not in
   94           // javax.crypto.* packages.
   95           // NOTE: javax.crypto.* package maybe subject to package
   96           // insertion, so need to check its classloader as well.
   97           Class[] context = getClassContext();
   98           URL callerCodeBase = null;
   99           int i;
  100           for (i=0; i<context.length; i++) {
  101               Class cls = context[i];
  102               callerCodeBase = JceSecurity.getCodeBase(cls);
  103               if (callerCodeBase != null) {
  104                   break;
  105               } else {
  106                   if (cls.getName().startsWith("javax.crypto.")) {
  107                       // skip jce classes since they aren't the callers
  108                       continue;
  109                   }
  110                   // use default permission when the caller is system classes
  111                   return defaultPerm;
  112               }
  113           }
  114   
  115           if (i == context.length) {
  116               return defaultPerm;
  117           }
  118   
  119           CryptoPermissions appPerms;
  120           synchronized (this.getClass()) {
  121               if (exemptCache.containsKey(callerCodeBase)) {
  122                   appPerms = (CryptoPermissions)exemptCache.get(callerCodeBase);
  123               } else {
  124                   appPerms = getAppPermissions(callerCodeBase);
  125                   exemptCache.put(callerCodeBase, appPerms);
  126               }
  127           }
  128   
  129           if (appPerms == null) {
  130               return defaultPerm;
  131           }
  132   
  133           // If the app was granted the special CryptoAllPermission, return that.
  134           if (appPerms.implies(allPerm)) {
  135               return allPerm;
  136           }
  137   
  138           // Check if the crypto permissions granted to the app contain a
  139           // crypto permission for the requested algorithm that does not require
  140           // any exemption mechanism to be enforced.
  141           // Return that permission, if present.
  142           PermissionCollection appPc = appPerms.getPermissionCollection(alg);
  143           if (appPc == null) {
  144               return defaultPerm;
  145           }
  146           Enumeration enum_ = appPc.elements();
  147           while (enum_.hasMoreElements()) {
  148               CryptoPermission cp = (CryptoPermission)enum_.nextElement();
  149               if (cp.getExemptionMechanism() == null) {
  150                   return cp;
  151               }
  152           }
  153   
  154           // Check if the jurisdiction file for exempt applications contains
  155           // any entries for the requested algorithm.
  156           // If not, return the default permission.
  157           PermissionCollection exemptPc =
  158               exemptPolicy.getPermissionCollection(alg);
  159           if (exemptPc == null) {
  160               return defaultPerm;
  161           }
  162   
  163           // In the jurisdiction file for exempt applications, go through the
  164           // list of CryptoPermission entries for the requested algorithm, and
  165           // stop at the first entry:
  166           //  - that is implied by the collection of crypto permissions granted
  167           //    to the app, and
  168           //  - whose exemption mechanism is available from one of the
  169           //    registered CSPs
  170           enum_ = exemptPc.elements();
  171           while (enum_.hasMoreElements()) {
  172               CryptoPermission cp = (CryptoPermission)enum_.nextElement();
  173               try {
  174                   ExemptionMechanism.getInstance(cp.getExemptionMechanism());
  175                   if (cp.getAlgorithm().equals(
  176                                         CryptoPermission.ALG_NAME_WILDCARD)) {
  177                       CryptoPermission newCp;
  178                       if (cp.getCheckParam()) {
  179                           newCp = new CryptoPermission(
  180                                   alg, cp.getMaxKeySize(),
  181                                   cp.getAlgorithmParameterSpec(),
  182                                   cp.getExemptionMechanism());
  183                       } else {
  184                           newCp = new CryptoPermission(
  185                                   alg, cp.getMaxKeySize(),
  186                                   cp.getExemptionMechanism());
  187                       }
  188                       if (appPerms.implies(newCp)) {
  189                           return newCp;
  190                       }
  191                   }
  192   
  193                   if (appPerms.implies(cp)) {
  194                       return cp;
  195                   }
  196               } catch (Exception e) {
  197                   continue;
  198               }
  199           }
  200           return defaultPerm;
  201       }
  202   
  203       private static CryptoPermissions getAppPermissions(URL callerCodeBase) {
  204           // Check if app is exempt, and retrieve the permissions bundled with it
  205           try {
  206               return JceSecurity.verifyExemptJar(callerCodeBase);
  207           } catch (Exception e) {
  208               // Jar verification fails
  209               return null;
  210           }
  211   
  212       }
  213   
  214       /**
  215        * Returns the default permission for the given algorithm.
  216        */
  217       private CryptoPermission getDefaultPermission(String alg) {
  218           Enumeration enum_ =
  219               defaultPolicy.getPermissionCollection(alg).elements();
  220           return (CryptoPermission)enum_.nextElement();
  221       }
  222   
  223       // See  bug 4341369 & 4334690 for more info.
  224       boolean isCallerTrusted() {
  225           // Get the caller and its codebase.
  226           Class[] context = getClassContext();
  227           URL callerCodeBase = null;
  228           int i;
  229           for (i=0; i<context.length; i++) {
  230               callerCodeBase = JceSecurity.getCodeBase(context[i]);
  231               if (callerCodeBase != null) {
  232                   break;
  233               }
  234           }
  235           // The caller is in the JCE framework.
  236           if (i == context.length) {
  237               return true;
  238           }
  239           //The caller has been verified.
  240           if (TrustedCallersCache.contains(context[i])) {
  241               return true;
  242           }
  243           // Check whether the caller is a trusted provider.
  244           try {
  245               JceSecurity.verifyProviderJar(callerCodeBase);
  246           } catch (Exception e2) {
  247               return false;
  248           }
  249           TrustedCallersCache.addElement(context[i]);
  250           return true;
  251       }
  252   }

Home » openjdk-7 » javax » crypto » [javadoc | source]