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.util.Enumeration;
   30   import java.util.Hashtable;
   31   import java.util.Vector;
   32   import java.util.NoSuchElementException;
   33   import java.io.Serializable;
   34   import java.io.InputStream;
   35   import java.io.InputStreamReader;
   36   import java.io.BufferedReader;
   37   import java.io.IOException;
   38   
   39   /**
   40    * This class contains CryptoPermission objects, organized into
   41    * PermissionCollections according to algorithm names.
   42    *
   43    * <p>When the <code>add</code> method is called to add a
   44    * CryptoPermission, the CryptoPermission is stored in the
   45    * appropriate PermissionCollection. If no such
   46    * collection exists yet, the algorithm name associated with
   47    * the CryptoPermission object is
   48    * determined and the <code>newPermissionCollection</code> method
   49    * is called on the CryptoPermission or CryptoAllPermission class to
   50    * create the PermissionCollection and add it to the Permissions object.
   51    *
   52    * @see javax.crypto.CryptoPermission
   53    * @see java.security.PermissionCollection
   54    * @see java.security.Permissions
   55    *
   56    * @author Sharon Liu
   57    * @since 1.4
   58    */
   59   final class CryptoPermissions extends PermissionCollection
   60   implements Serializable {
   61   
   62       private static final long serialVersionUID = 4946547168093391015L;
   63   
   64       // This class is similar to java.security.Permissions
   65       private Hashtable perms;
   66   
   67       /**
   68        * Creates a new CryptoPermissions object containing
   69        * no CryptoPermissionCollections.
   70        */
   71       CryptoPermissions() {
   72           perms = new Hashtable(7);
   73       }
   74   
   75       /**
   76        * Populates the crypto policy from the specified
   77        * InputStream into this CryptoPermissions object.
   78        *
   79        * @param in the InputStream to load from.
   80        *
   81        * @exception SecurityException if cannot load
   82        * successfully.
   83        */
   84       void load(InputStream in)
   85           throws IOException, CryptoPolicyParser.ParsingException {
   86           CryptoPolicyParser parser = new CryptoPolicyParser();
   87           parser.read(new BufferedReader(new InputStreamReader(in, "UTF-8")));
   88   
   89           CryptoPermission[] parsingResult = parser.getPermissions();
   90           for (int i = 0; i < parsingResult.length; i++) {
   91               this.add(parsingResult[i]);
   92           }
   93       }
   94   
   95       /**
   96        * Returns true if this CryptoPermissions object doesn't
   97        * contain any CryptoPermission objects; otherwise, returns
   98        * false.
   99        */
  100       boolean isEmpty() {
  101           return perms.isEmpty();
  102       }
  103   
  104       /**
  105        * Adds a permission object to the PermissionCollection for the
  106        * algorithm returned by
  107        * <code>(CryptoPermission)permission.getAlgorithm()</code>.
  108        *
  109        * This method creates
  110        * a new PermissionCollection object (and adds the permission to it)
  111        * if an appropriate collection does not yet exist. <p>
  112        *
  113        * @param permission the Permission object to add.
  114        *
  115        * @exception SecurityException if this CryptoPermissions object is
  116        * marked as readonly.
  117        *
  118        * @see isReadOnly
  119        */
  120       public void add(Permission permission) {
  121   
  122           if (isReadOnly())
  123               throw new SecurityException("Attempt to add a Permission " +
  124                                           "to a readonly CryptoPermissions " +
  125                                           "object");
  126   
  127           if (!(permission instanceof CryptoPermission))
  128               return;
  129   
  130           CryptoPermission cryptoPerm = (CryptoPermission)permission;
  131           PermissionCollection pc =
  132                           getPermissionCollection(cryptoPerm);
  133           pc.add(cryptoPerm);
  134           String alg = cryptoPerm.getAlgorithm();
  135           if (!perms.containsKey(alg)) {
  136               perms.put(alg, pc);
  137           }
  138       }
  139   
  140       /**
  141        * Checks if this object's PermissionCollection for permissons
  142        * of the specified permission's algorithm implies the specified
  143        * permission. Returns true if the checking succeeded.
  144        *
  145        * @param permission the Permission object to check.
  146        *
  147        * @return true if "permission" is implied by the permissions
  148        * in the PermissionCollection it belongs to, false if not.
  149        *
  150        */
  151       public boolean implies(Permission permission) {
  152           if (!(permission instanceof CryptoPermission)) {
  153               return false;
  154           }
  155   
  156           CryptoPermission cryptoPerm = (CryptoPermission)permission;
  157   
  158           PermissionCollection pc =
  159               getPermissionCollection(cryptoPerm.getAlgorithm());
  160           return pc.implies(cryptoPerm);
  161       }
  162   
  163       /**
  164        * Returns an enumeration of all the Permission objects in all the
  165        * PermissionCollections in this CryptoPermissions object.
  166        *
  167        * @return an enumeration of all the Permissions.
  168        */
  169       public Enumeration elements() {
  170           // go through each Permissions in the hash table
  171           // and call their elements() function.
  172           return new PermissionsEnumerator(perms.elements());
  173       }
  174   
  175       /**
  176        * Returns a CryptoPermissions object which
  177        * represents the minimum of the specified
  178        * CryptoPermissions object and this
  179        * CryptoPermissions object.
  180        *
  181        * @param other the CryptoPermission
  182        * object to compare with this object.
  183        */
  184       CryptoPermissions getMinimum(CryptoPermissions other) {
  185           if (other == null) {
  186               return null;
  187           }
  188   
  189           if (this.perms.containsKey(CryptoAllPermission.ALG_NAME)) {
  190               return other;
  191           }
  192   
  193           if (other.perms.containsKey(CryptoAllPermission.ALG_NAME)) {
  194               return this;
  195           }
  196   
  197           CryptoPermissions ret = new CryptoPermissions();
  198   
  199   
  200           PermissionCollection thatWildcard =
  201               (PermissionCollection)other.perms.get(
  202                                           CryptoPermission.ALG_NAME_WILDCARD);
  203           int maxKeySize = 0;
  204           if (thatWildcard != null) {
  205               maxKeySize = ((CryptoPermission)
  206                       thatWildcard.elements().nextElement()).getMaxKeySize();
  207           }
  208           // For each algorithm in this CryptoPermissions,
  209           // find out if there is anything we should add into
  210           // ret.
  211           Enumeration thisKeys = this.perms.keys();
  212           while (thisKeys.hasMoreElements()) {
  213               String alg = (String)thisKeys.nextElement();
  214   
  215               PermissionCollection thisPc =
  216                   (PermissionCollection)this.perms.get(alg);
  217               PermissionCollection thatPc =
  218                   (PermissionCollection)other.perms.get(alg);
  219   
  220               CryptoPermission[] partialResult;
  221   
  222               if (thatPc == null) {
  223                   if (thatWildcard == null) {
  224                       // The other CryptoPermissions
  225                       // doesn't allow this given
  226                       // algorithm at all. Just skip this
  227                       // algorithm.
  228                       continue;
  229                   }
  230                   partialResult = getMinimum(maxKeySize, thisPc);
  231               } else {
  232                   partialResult = getMinimum(thisPc, thatPc);
  233               }
  234   
  235               for (int i = 0; i < partialResult.length; i++) {
  236                   ret.add(partialResult[i]);
  237               }
  238           }
  239   
  240           PermissionCollection thisWildcard =
  241               (PermissionCollection)this.perms.get(
  242                                         CryptoPermission.ALG_NAME_WILDCARD);
  243   
  244           // If this CryptoPermissions doesn't
  245           // have a wildcard, we are done.
  246           if (thisWildcard == null) {
  247               return ret;
  248           }
  249   
  250           // Deal with the algorithms only appear
  251           // in the other CryptoPermissions.
  252           maxKeySize =
  253               ((CryptoPermission)
  254                       thisWildcard.elements().nextElement()).getMaxKeySize();
  255           Enumeration thatKeys = other.perms.keys();
  256           while (thatKeys.hasMoreElements()) {
  257               String alg = (String)thatKeys.nextElement();
  258   
  259               if (this.perms.containsKey(alg)) {
  260                   continue;
  261               }
  262   
  263               PermissionCollection thatPc =
  264                   (PermissionCollection)other.perms.get(alg);
  265   
  266               CryptoPermission[] partialResult;
  267   
  268               partialResult = getMinimum(maxKeySize, thatPc);
  269   
  270               for (int i = 0; i < partialResult.length; i++) {
  271                   ret.add(partialResult[i]);
  272               }
  273           }
  274           return ret;
  275       }
  276   
  277       /**
  278        * Get the minimum of the two given PermissionCollection
  279        * <code>thisPc</code> and <code>thatPc</code>.
  280        *
  281        * @param thisPc the first given PermissionColloection
  282        * object.
  283        *
  284        * @param thatPc the second given PermissionCollection
  285        * object.
  286        */
  287       private CryptoPermission[] getMinimum(PermissionCollection thisPc,
  288                                             PermissionCollection thatPc) {
  289           Vector permVector = new Vector(2);
  290   
  291           Enumeration thisPcPermissions = thisPc.elements();
  292   
  293           // For each CryptoPermission in
  294           // thisPc object, do the following:
  295           // 1) if this CryptoPermission is implied
  296           //     by thatPc, this CryptoPermission
  297           //     should be returned, and we can
  298           //     move on to check the next
  299           //     CryptoPermission in thisPc.
  300           // 2) otherwise, we should return
  301           //     all CryptoPermissions in thatPc
  302           //     which
  303           //     are implied by this CryptoPermission.
  304           //     Then we can move on to the
  305           //     next CryptoPermission in thisPc.
  306           while (thisPcPermissions.hasMoreElements()) {
  307               CryptoPermission thisCp =
  308                   (CryptoPermission)thisPcPermissions.nextElement();
  309   
  310               Enumeration thatPcPermissions = thatPc.elements();
  311               while (thatPcPermissions.hasMoreElements()) {
  312                   CryptoPermission thatCp =
  313                       (CryptoPermission)thatPcPermissions.nextElement();
  314   
  315                   if (thatCp.implies(thisCp)) {
  316                       permVector.addElement(thisCp);
  317                       break;
  318                   }
  319                   if (thisCp.implies(thatCp)) {
  320                       permVector.addElement(thatCp);
  321                   }
  322               }
  323           }
  324   
  325           CryptoPermission[] ret = new CryptoPermission[permVector.size()];
  326           permVector.copyInto(ret);
  327           return ret;
  328       }
  329   
  330       /**
  331        * Returns all the CryptoPermission objects in the given
  332        * PermissionCollection object
  333        * whose maximum keysize no greater than <code>maxKeySize</code>.
  334        * For all CryptoPermission objects with a maximum keysize greater
  335        * than <code>maxKeySize</code>, this method constructs a
  336        * corresponding CryptoPermission object whose maximum keysize is
  337        * set to <code>maxKeySize</code>, and includes that in the result.
  338        *
  339        * @param maxKeySize the given maximum key size.
  340        *
  341        * @param pc the given PermissionCollection object.
  342        */
  343       private CryptoPermission[] getMinimum(int maxKeySize,
  344                                             PermissionCollection pc) {
  345           Vector permVector = new Vector(1);
  346   
  347           Enumeration enum_ = pc.elements();
  348   
  349           while (enum_.hasMoreElements()) {
  350               CryptoPermission cp =
  351                   (CryptoPermission)enum_.nextElement();
  352               if (cp.getMaxKeySize() <= maxKeySize) {
  353                   permVector.addElement(cp);
  354               } else {
  355                   if (cp.getCheckParam()) {
  356                       permVector.addElement(
  357                              new CryptoPermission(cp.getAlgorithm(),
  358                                                   maxKeySize,
  359                                                   cp.getAlgorithmParameterSpec(),
  360                                                   cp.getExemptionMechanism()));
  361                   } else {
  362                       permVector.addElement(
  363                              new CryptoPermission(cp.getAlgorithm(),
  364                                                   maxKeySize,
  365                                                   cp.getExemptionMechanism()));
  366                   }
  367               }
  368           }
  369   
  370           CryptoPermission[] ret = new CryptoPermission[permVector.size()];
  371           permVector.copyInto(ret);
  372           return ret;
  373       }
  374   
  375       /**
  376        * Returns the PermissionCollection for the
  377        * specified algorithm. Returns null if there
  378        * isn't such a PermissionCollection.
  379        *
  380        * @param alg the algorithm name.
  381        */
  382       PermissionCollection getPermissionCollection(String alg) {
  383           // If this CryptoPermissions includes CryptoAllPermission,
  384           // we should return CryptoAllPermission.
  385           if (perms.containsKey(CryptoAllPermission.ALG_NAME)) {
  386               return
  387                   (PermissionCollection)(perms.get(CryptoAllPermission.ALG_NAME));
  388           }
  389   
  390           PermissionCollection pc = (PermissionCollection)perms.get(alg);
  391   
  392           // If there isn't a PermissionCollection for
  393           // the given algorithm,we should return the
  394           // PermissionCollection for the wildcard
  395           // if there is one.
  396           if (pc == null) {
  397               pc = (PermissionCollection)perms.get(
  398                                          CryptoPermission.ALG_NAME_WILDCARD);
  399           }
  400           return pc;
  401       }
  402   
  403       /**
  404        * Returns the PermissionCollection for the algorithm
  405        * associated with the specified CryptoPermission
  406        * object. Creates such a PermissionCollection
  407        * if such a PermissionCollection does not
  408        * exist yet.
  409        *
  410        * @param cryptoPerm the CryptoPermission object.
  411        */
  412       private PermissionCollection getPermissionCollection(
  413                                             CryptoPermission cryptoPerm) {
  414   
  415           String alg = cryptoPerm.getAlgorithm();
  416   
  417           PermissionCollection pc = (PermissionCollection)perms.get(alg);
  418   
  419           if (pc == null) {
  420               pc = cryptoPerm.newPermissionCollection();
  421           }
  422           return pc;
  423       }
  424   }
  425   
  426   final class PermissionsEnumerator implements Enumeration {
  427   
  428       // all the perms
  429       private Enumeration perms;
  430       // the current set
  431       private Enumeration permset;
  432   
  433       PermissionsEnumerator(Enumeration e) {
  434           perms = e;
  435           permset = getNextEnumWithMore();
  436       }
  437   
  438       public synchronized boolean hasMoreElements() {
  439           // if we enter with permissionimpl null, we know
  440           // there are no more left.
  441   
  442           if (permset == null)
  443               return  false;
  444   
  445           // try to see if there are any left in the current one
  446   
  447           if (permset.hasMoreElements())
  448               return true;
  449   
  450           // get the next one that has something in it...
  451           permset = getNextEnumWithMore();
  452   
  453           // if it is null, we are done!
  454           return (permset != null);
  455       }
  456   
  457       public synchronized Object nextElement() {
  458           // hasMoreElements will update permset to the next permset
  459           // with something in it...
  460   
  461           if (hasMoreElements()) {
  462               return permset.nextElement();
  463           } else {
  464               throw new NoSuchElementException("PermissionsEnumerator");
  465           }
  466   
  467       }
  468   
  469       private Enumeration getNextEnumWithMore() {
  470           while (perms.hasMoreElements()) {
  471               PermissionCollection pc =
  472                   (PermissionCollection) perms.nextElement();
  473               Enumeration next = pc.elements();
  474               if (next.hasMoreElements())
  475                   return next;
  476           }
  477           return null;
  478       }
  479   }

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