/* | 
|
 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. | 
|
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 
|
 * | 
|
 * This code is free software; you can redistribute it and/or modify it | 
|
 * under the terms of the GNU General Public License version 2 only, as | 
|
 * published by the Free Software Foundation.  Oracle designates this | 
|
 * particular file as subject to the "Classpath" exception as provided | 
|
 * by Oracle in the LICENSE file that accompanied this code. | 
|
 * | 
|
 * This code is distributed in the hope that it will be useful, but WITHOUT | 
|
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 
|
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License | 
|
 * version 2 for more details (a copy is included in the LICENSE file that | 
|
 * accompanied this code). | 
|
 * | 
|
 * You should have received a copy of the GNU General Public License version | 
|
 * 2 along with this work; if not, write to the Free Software Foundation, | 
|
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | 
|
 * | 
|
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | 
|
 * or visit www.oracle.com if you need additional information or have any | 
|
 * questions. | 
|
*/  | 
|
package javax.crypto;  | 
|
import java.security.*;  | 
|
import java.security.spec.AlgorithmParameterSpec;  | 
|
import java.io.Serializable;  | 
|
import java.util.Enumeration;  | 
|
import java.util.Vector;  | 
|
import javax.crypto.spec.*;  | 
|
/** | 
|
 * The CryptoPermission class extends the | 
|
 * java.security.Permission class. A | 
|
 * CryptoPermission object is used to represent | 
|
 * the ability of an application/applet to use certain | 
|
 * algorithms with certain key sizes and other | 
|
 * restrictions in certain environments. <p> | 
|
 * | 
|
 * @see java.security.Permission | 
|
 * | 
|
 * @author Jan Luehe | 
|
 * @author Sharon Liu | 
|
 * @since 1.4 | 
|
*/  | 
|
class CryptoPermission extends java.security.Permission {  | 
|
private static final long serialVersionUID = 8987399626114087514L;  | 
|
private String alg;  | 
|
    private int maxKeySize = Integer.MAX_VALUE; // no restriction on maxKeySize | 
|
private String exemptionMechanism = null;  | 
|
private AlgorithmParameterSpec algParamSpec = null;  | 
|
    private boolean checkParam = false; // no restriction on param | 
|
static final String ALG_NAME_WILDCARD = "*";  | 
|
    /** | 
|
     * Constructor that takes an algorithm name. | 
|
     * | 
|
     * This constructor implies that the given algorithm can be | 
|
     * used without any restrictions. | 
|
     * | 
|
     * @param alg the algorithm name. | 
|
*/  | 
|
CryptoPermission(String alg) {  | 
|
super(null);  | 
|
this.alg = alg;  | 
|
}  | 
|
    /** | 
|
     * Constructor that takes an algorithm name and a maximum | 
|
     * key size. | 
|
     * | 
|
     * This constructor implies that the given algorithm can be | 
|
     * used with a key size up to <code>maxKeySize</code>. | 
|
     * | 
|
     * @param alg the algorithm name. | 
|
     * | 
|
     * @param maxKeySize the maximum allowable key size, | 
|
     * specified in number of bits. | 
|
*/  | 
|
CryptoPermission(String alg, int maxKeySize) {  | 
|
super(null);  | 
|
this.alg = alg;  | 
|
this.maxKeySize = maxKeySize;  | 
|
}  | 
|
    /** | 
|
     * Constructor that takes an algorithm name, a maximum | 
|
     * key size, and an AlgorithmParameterSpec object. | 
|
     * | 
|
     * This constructor implies that the given algorithm can be | 
|
     * used with a key size up to <code>maxKeySize</code>, and | 
|
     * algorithm | 
|
     * parameters up to the limits set in <code>algParamSpec</code>. | 
|
     * | 
|
     * @param alg the algorithm name. | 
|
     * | 
|
     * @param maxKeySize the maximum allowable key size, | 
|
     * specified in number of bits. | 
|
     * | 
|
     * @param algParamSpec the limits for allowable algorithm | 
|
     * parameters. | 
|
*/  | 
|
CryptoPermission(String alg,  | 
|
int maxKeySize,  | 
|
AlgorithmParameterSpec algParamSpec) {  | 
|
super(null);  | 
|
this.alg = alg;  | 
|
this.maxKeySize = maxKeySize;  | 
|
this.checkParam = true;  | 
|
this.algParamSpec = algParamSpec;  | 
|
}  | 
|
    /** | 
|
     * Constructor that takes an algorithm name and the name of | 
|
     * an exemption mechanism. | 
|
     * | 
|
     * This constructor implies that the given algorithm can be | 
|
     * used without any key size or algorithm parameter restrictions | 
|
     * provided that the specified exemption mechanism is enforced. | 
|
     * | 
|
     * @param alg the algorithm name. | 
|
     * | 
|
     * @param exemptionMechanism the name of the exemption mechanism. | 
|
*/  | 
|
CryptoPermission(String alg,  | 
|
String exemptionMechanism) {  | 
|
super(null);  | 
|
this.alg = alg;  | 
|
this.exemptionMechanism = exemptionMechanism;  | 
|
}  | 
|
    /** | 
|
     * Constructor that takes an algorithm name, a maximum key | 
|
     * size, and the name of an exemption mechanism. | 
|
     * | 
|
     * This constructor implies that the given algorithm can be | 
|
     * used with a key size up to <code>maxKeySize</code> | 
|
     * provided that the | 
|
     * specified exemption mechanism is enforced. | 
|
     * | 
|
     * @param alg the algorithm name. | 
|
     * @param maxKeySize the maximum allowable key size, | 
|
     * specified in number of bits. | 
|
     * @param exemptionMechanism the name of the exemption | 
|
     * mechanism. | 
|
*/  | 
|
CryptoPermission(String alg,  | 
|
int maxKeySize,  | 
|
String exemptionMechanism) {  | 
|
super(null);  | 
|
this.alg = alg;  | 
|
this.exemptionMechanism = exemptionMechanism;  | 
|
this.maxKeySize = maxKeySize;  | 
|
}  | 
|
    /** | 
|
     * Constructor that takes an algorithm name, a maximum key | 
|
     * size, the name of an exemption mechanism, and an | 
|
     * AlgorithmParameterSpec object. | 
|
     * | 
|
     * This constructor implies that the given algorithm can be | 
|
     * used with a key size up to <code>maxKeySize</code> | 
|
     * and algorithm | 
|
     * parameters up to the limits set in <code>algParamSpec</code> | 
|
     * provided that | 
|
     * the specified exemption mechanism is enforced. | 
|
     * | 
|
     * @param alg the algorithm name. | 
|
     * @param maxKeySize the maximum allowable key size, | 
|
     * specified in number of bits. | 
|
     * @param algParamSpec the limit for allowable algorithm | 
|
     *  parameter spec. | 
|
     * @param exemptionMechanism the name of the exemption | 
|
     * mechanism. | 
|
*/  | 
|
CryptoPermission(String alg,  | 
|
int maxKeySize,  | 
|
AlgorithmParameterSpec algParamSpec,  | 
|
String exemptionMechanism) {  | 
|
super(null);  | 
|
this.alg = alg;  | 
|
this.exemptionMechanism = exemptionMechanism;  | 
|
this.maxKeySize = maxKeySize;  | 
|
this.checkParam = true;  | 
|
this.algParamSpec = algParamSpec;  | 
|
}  | 
|
    /** | 
|
     * Checks if the specified permission is "implied" by | 
|
     * this object. | 
|
     * <p> | 
|
     * More specifically, this method returns true if:<p> | 
|
     * <ul> | 
|
     * <li> <i>p</i> is an instance of CryptoPermission, and<p> | 
|
     * <li> <i>p</i>'s algorithm name equals or (in the case of wildcards) | 
|
     *       is implied by this permission's algorithm name, and<p> | 
|
     * <li> <i>p</i>'s maximum allowable key size is less or | 
|
     *       equal to this permission's maximum allowable key size, and<p> | 
|
     * <li> <i>p</i>'s algorithm parameter spec equals or is | 
|
     *        implied by this permission's algorithm parameter spec, and<p> | 
|
     * <li> <i>p</i>'s exemptionMechanism equals or | 
|
     *        is implied by this permission's | 
|
     *        exemptionMechanism (a <code>null</code> exemption mechanism | 
|
     *        implies any other exemption mechanism). | 
|
     * </ul> | 
|
     * | 
|
     * @param p the permission to check against. | 
|
     * | 
|
     * @return true if the specified permission is equal to or | 
|
     * implied by this permission, false otherwise. | 
|
*/  | 
|
public boolean implies(Permission p) {  | 
|
if (!(p instanceof CryptoPermission))  | 
|
return false;  | 
|
CryptoPermission cp = (CryptoPermission)p;  | 
|
if ((!alg.equalsIgnoreCase(cp.alg)) &&  | 
|
(!alg.equalsIgnoreCase(ALG_NAME_WILDCARD))) {  | 
|
return false;  | 
|
}  | 
|
// alg is the same as cp's alg or  | 
|
        // alg is a wildcard. | 
|
if (cp.maxKeySize <= this.maxKeySize) {  | 
|
            // check algParamSpec. | 
|
if (!impliesParameterSpec(cp.checkParam, cp.algParamSpec)) {  | 
|
return false;  | 
|
}  | 
|
            // check exemptionMechanism. | 
|
if (impliesExemptionMechanism(cp.exemptionMechanism)) {  | 
|
return true;  | 
|
}  | 
|
}  | 
|
return false;  | 
|
}  | 
|
    /** | 
|
     * Checks two CryptoPermission objects for equality. Checks that | 
|
     * <code>obj</code> is a CryptoPermission, and has the same | 
|
     * algorithm name, | 
|
     * exemption mechanism name, maximum allowable key size and | 
|
     * algorithm parameter spec | 
|
     * as this object. | 
|
     * <P> | 
|
     * @param obj the object to test for equality with this object. | 
|
     * @return true if <code>obj</code> is equal to this object. | 
|
*/  | 
|
public boolean equals(Object obj) {  | 
|
if (obj == this)  | 
|
return true;  | 
|
if (!(obj instanceof CryptoPermission))  | 
|
return false;  | 
|
CryptoPermission that = (CryptoPermission) obj;  | 
|
if (!(alg.equalsIgnoreCase(that.alg)) ||  | 
|
(maxKeySize != that.maxKeySize)) {  | 
|
return false;  | 
|
}  | 
|
if (this.checkParam != that.checkParam) {  | 
|
return false;  | 
|
}  | 
|
return (equalObjects(this.exemptionMechanism,  | 
|
that.exemptionMechanism) &&  | 
|
equalObjects(this.algParamSpec,  | 
|
that.algParamSpec));  | 
|
}  | 
|
/**  | 
|
* Returns the hash code value for this object.  | 
|
*  | 
|
* @return a hash code value for this object.  | 
|
*/  | 
|
    public int hashCode() { | 
|
int retval = alg.hashCode();  | 
|
retval ^= maxKeySize;  | 
|
if (exemptionMechanism != null) {  | 
|
retval ^= exemptionMechanism.hashCode();  | 
|
}  | 
|
if (checkParam) retval ^= 100;  | 
|
if (algParamSpec != null) {  | 
|
retval ^= algParamSpec.hashCode();  | 
|
}  | 
|
return retval;  | 
|
}  | 
|
    /** | 
|
     * There is no action defined for a CryptoPermission | 
|
     * onject. | 
|
*/  | 
|
public String getActions()  | 
|
    { | 
|
return null;  | 
|
}  | 
|
/**  | 
|
* Returns a new PermissionCollection object for storing  | 
|
* CryptoPermission objects.  | 
|
*  | 
|
* @return a new PermissionCollection object suitable for storing  | 
|
* CryptoPermissions.  | 
|
*/  | 
|
public PermissionCollection newPermissionCollection() {  | 
|
return new CryptoPermissionCollection();  | 
|
}  | 
|
    /** | 
|
     * Returns the algorithm name associated with | 
|
     * this CryptoPermission object. | 
|
*/  | 
|
final String getAlgorithm() {  | 
|
return alg;  | 
|
}  | 
|
    /** | 
|
     * Returns the exemption mechanism name | 
|
     * associated with this CryptoPermission | 
|
     * object. | 
|
*/  | 
|
final String getExemptionMechanism() {  | 
|
return exemptionMechanism;  | 
|
}  | 
|
    /** | 
|
     * Returns the maximum allowable key size associated | 
|
     * with this CryptoPermission object. | 
|
*/  | 
|
    final int getMaxKeySize() { | 
|
return maxKeySize;  | 
|
}  | 
|
    /** | 
|
     * Returns true if there is a limitation on the | 
|
     * AlgorithmParameterSpec associated with this | 
|
     * CryptoPermission object and false if otherwise. | 
|
*/  | 
|
    final boolean getCheckParam() { | 
|
return checkParam;  | 
|
}  | 
|
    /** | 
|
     * Returns the AlgorithmParameterSpec | 
|
     * associated with this CryptoPermission | 
|
     * object. | 
|
*/  | 
|
final AlgorithmParameterSpec getAlgorithmParameterSpec() {  | 
|
return algParamSpec;  | 
|
}  | 
|
    /** | 
|
     * Returns a string describing this CryptoPermission.  The convention is to | 
|
     * specify the class name, the algorithm name, the maximum allowable | 
|
     * key size, and the name of the exemption mechanism, in the following | 
|
     * format: '("ClassName" "algorithm" "keysize" "exemption_mechanism")'. | 
|
     * | 
|
     * @return information about this CryptoPermission. | 
|
*/  | 
|
public String toString() {  | 
|
StringBuilder buf = new StringBuilder(100);  | 
|
buf.append("(CryptoPermission " + alg + " " + maxKeySize);  | 
|
if (algParamSpec != null) {  | 
|
if (algParamSpec instanceof RC2ParameterSpec) {  | 
|
buf.append(" , effective " +  | 
|
((RC2ParameterSpec)algParamSpec).getEffectiveKeyBits());  | 
|
} else if (algParamSpec instanceof RC5ParameterSpec) {  | 
|
buf.append(" , rounds " +  | 
|
((RC5ParameterSpec)algParamSpec).getRounds());  | 
|
}  | 
|
}  | 
|
if (exemptionMechanism != null) { // OPTIONAL  | 
|
buf.append(" " + exemptionMechanism);  | 
|
}  | 
|
buf.append(")");  | 
|
return buf.toString();  | 
|
}  | 
|
private boolean impliesExemptionMechanism(String exemptionMechanism) {  | 
|
        if (this.exemptionMechanism == null) { | 
|
return true;  | 
|
}  | 
|
if (exemptionMechanism == null) {  | 
|
return false;  | 
|
}  | 
|
if (this.exemptionMechanism.equals(exemptionMechanism)) {  | 
|
return true;  | 
|
}  | 
|
return false;  | 
|
}  | 
|
private boolean impliesParameterSpec(boolean checkParam,  | 
|
AlgorithmParameterSpec algParamSpec) {  | 
|
if ((this.checkParam) && checkParam) {  | 
|
if (algParamSpec == null) {  | 
|
return true;  | 
|
            } else if (this.algParamSpec == null) { | 
|
return false;  | 
|
}  | 
|
if (this.algParamSpec.getClass() != algParamSpec.getClass()) {  | 
|
return false;  | 
|
}  | 
|
if (algParamSpec instanceof RC2ParameterSpec) {  | 
|
if (((RC2ParameterSpec)algParamSpec).getEffectiveKeyBits() <=  | 
|
((RC2ParameterSpec)  | 
|
                     (this.algParamSpec)).getEffectiveKeyBits()) { | 
|
return true;  | 
|
}  | 
|
}  | 
|
if (algParamSpec instanceof RC5ParameterSpec) {  | 
|
if (((RC5ParameterSpec)algParamSpec).getRounds() <=  | 
|
((RC5ParameterSpec)this.algParamSpec).getRounds()) {  | 
|
return true;  | 
|
}  | 
|
}  | 
|
if (algParamSpec instanceof PBEParameterSpec) {  | 
|
if (((PBEParameterSpec)algParamSpec).getIterationCount() <=  | 
|
((PBEParameterSpec)this.algParamSpec).getIterationCount()) {  | 
|
return true;  | 
|
}  | 
|
}  | 
|
// For classes we don't know, the following  | 
|
            // may be the best try. | 
|
if (this.algParamSpec.equals(algParamSpec)) {  | 
|
return true;  | 
|
}  | 
|
return false;  | 
|
        } else if (this.checkParam) { | 
|
return false;  | 
|
        } else { | 
|
return true;  | 
|
}  | 
|
}  | 
|
private boolean equalObjects(Object obj1, Object obj2) {  | 
|
if (obj1 == null) {  | 
|
return (obj2 == null ? true : false);  | 
|
}  | 
|
return obj1.equals(obj2);  | 
|
}  | 
|
}  | 
|
/** | 
|
 * A CryptoPermissionCollection stores a set of CryptoPermission | 
|
 * permissions. | 
|
 * | 
|
 * @see java.security.Permission | 
|
 * @see java.security.Permissions | 
|
 * @see java.security.PermissionCollection | 
|
 * | 
|
 * @author Sharon Liu | 
|
*/  | 
|
final class CryptoPermissionCollection extends PermissionCollection  | 
|
implements Serializable  | 
|
{ | 
|
private static final long serialVersionUID = -511215555898802763L;  | 
|
private Vector<Permission> permissions;  | 
|
    /** | 
|
     * Creates an empty CryptoPermissionCollection | 
|
     * object. | 
|
*/  | 
|
    CryptoPermissionCollection() { | 
|
permissions = new Vector<Permission>(3);  | 
|
}  | 
|
    /** | 
|
     * Adds a permission to the CryptoPermissionCollection. | 
|
     * | 
|
     * @param permission the Permission object to add. | 
|
     * | 
|
     * @exception SecurityException - if this CryptoPermissionCollection | 
|
     * object has been marked <i>readOnly</i>. | 
|
*/  | 
|
public void add(Permission permission) {  | 
|
if (isReadOnly())  | 
|
throw new SecurityException("attempt to add a Permission " +  | 
|
                                        "to a readonly PermissionCollection"); | 
|
if (!(permission instanceof CryptoPermission))  | 
|
return;  | 
|
permissions.addElement(permission);  | 
|
}  | 
|
    /** | 
|
     * Check and see if this CryptoPermission object implies | 
|
     * the given Permission object. | 
|
     * | 
|
     * @param permission the Permission object to compare | 
|
     * | 
|
     * @return true if the given permission  is implied by this | 
|
     * CryptoPermissionCollection, false if not. | 
|
*/  | 
|
public boolean implies(Permission permission) {  | 
|
if (!(permission instanceof CryptoPermission))  | 
|
return false;  | 
|
CryptoPermission cp = (CryptoPermission)permission;  | 
|
Enumeration<Permission> e = permissions.elements();  | 
|
while (e.hasMoreElements()) {  | 
|
CryptoPermission x = (CryptoPermission) e.nextElement();  | 
|
if (x.implies(cp)) {  | 
|
return true;  | 
|
}  | 
|
}  | 
|
return false;  | 
|
}  | 
|
/**  | 
|
* Returns an enumeration of all the CryptoPermission objects  | 
|
* in the container.  | 
|
*  | 
|
* @return an enumeration of all the CryptoPermission objects.  | 
|
*/  | 
|
public Enumeration<Permission> elements() {  | 
|
return permissions.elements();  | 
|
}  | 
|
}  |