Path: blob/master/src/java.base/share/classes/javax/crypto/CryptoPermission.java
41152 views
/*1* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.crypto;2627import java.security.*;28import java.security.spec.AlgorithmParameterSpec;29import java.io.Serializable;30import java.util.Enumeration;31import java.util.Vector;3233import javax.crypto.spec.*;3435/**36* The CryptoPermission class extends the37* java.security.Permission class. A38* CryptoPermission object is used to represent39* the ability of an application/applet to use certain40* algorithms with certain key sizes and other41* restrictions in certain environments.42*43* @see java.security.Permission44*45* @author Jan Luehe46* @author Sharon Liu47* @since 1.448*/49class CryptoPermission extends java.security.Permission {5051@java.io.Serial52private static final long serialVersionUID = 8987399626114087514L;5354private String alg;55private int maxKeySize = Integer.MAX_VALUE; // no restriction on maxKeySize56private String exemptionMechanism = null;57@SuppressWarnings("serial") // Not statically typed as Serializable58private AlgorithmParameterSpec algParamSpec = null;59private boolean checkParam = false; // no restriction on param6061static final String ALG_NAME_WILDCARD = "*";6263/**64* Constructor that takes an algorithm name.65*66* This constructor implies that the given algorithm can be67* used without any restrictions.68*69* @param alg the algorithm name.70*/71CryptoPermission(String alg) {72super(null);73this.alg = alg;74}7576/**77* Constructor that takes an algorithm name and a maximum78* key size.79*80* This constructor implies that the given algorithm can be81* used with a key size up to <code>maxKeySize</code>.82*83* @param alg the algorithm name.84*85* @param maxKeySize the maximum allowable key size,86* specified in number of bits.87*/88CryptoPermission(String alg, int maxKeySize) {89super(null);90this.alg = alg;91this.maxKeySize = maxKeySize;92}9394/**95* Constructor that takes an algorithm name, a maximum96* key size, and an AlgorithmParameterSpec object.97*98* This constructor implies that the given algorithm can be99* used with a key size up to <code>maxKeySize</code>, and100* algorithm101* parameters up to the limits set in <code>algParamSpec</code>.102*103* @param alg the algorithm name.104*105* @param maxKeySize the maximum allowable key size,106* specified in number of bits.107*108* @param algParamSpec the limits for allowable algorithm109* parameters.110*/111CryptoPermission(String alg,112int maxKeySize,113AlgorithmParameterSpec algParamSpec) {114super(null);115this.alg = alg;116this.maxKeySize = maxKeySize;117this.checkParam = true;118this.algParamSpec = algParamSpec;119}120121/**122* Constructor that takes an algorithm name and the name of123* an exemption mechanism.124*125* This constructor implies that the given algorithm can be126* used without any key size or algorithm parameter restrictions127* provided that the specified exemption mechanism is enforced.128*129* @param alg the algorithm name.130*131* @param exemptionMechanism the name of the exemption mechanism.132*/133CryptoPermission(String alg,134String exemptionMechanism) {135super(null);136this.alg = alg;137this.exemptionMechanism = exemptionMechanism;138}139140/**141* Constructor that takes an algorithm name, a maximum key142* size, and the name of an exemption mechanism.143*144* This constructor implies that the given algorithm can be145* used with a key size up to <code>maxKeySize</code>146* provided that the147* specified exemption mechanism is enforced.148*149* @param alg the algorithm name.150* @param maxKeySize the maximum allowable key size,151* specified in number of bits.152* @param exemptionMechanism the name of the exemption153* mechanism.154*/155CryptoPermission(String alg,156int maxKeySize,157String exemptionMechanism) {158super(null);159this.alg = alg;160this.exemptionMechanism = exemptionMechanism;161this.maxKeySize = maxKeySize;162}163164/**165* Constructor that takes an algorithm name, a maximum key166* size, the name of an exemption mechanism, and an167* AlgorithmParameterSpec object.168*169* This constructor implies that the given algorithm can be170* used with a key size up to <code>maxKeySize</code>171* and algorithm172* parameters up to the limits set in <code>algParamSpec</code>173* provided that174* the specified exemption mechanism is enforced.175*176* @param alg the algorithm name.177* @param maxKeySize the maximum allowable key size,178* specified in number of bits.179* @param algParamSpec the limit for allowable algorithm180* parameter spec.181* @param exemptionMechanism the name of the exemption182* mechanism.183*/184CryptoPermission(String alg,185int maxKeySize,186AlgorithmParameterSpec algParamSpec,187String exemptionMechanism) {188super(null);189this.alg = alg;190this.exemptionMechanism = exemptionMechanism;191this.maxKeySize = maxKeySize;192this.checkParam = true;193this.algParamSpec = algParamSpec;194}195196/**197* Checks if the specified permission is "implied" by198* this object.199* <p>200* More specifically, this method returns true if:201* <ul>202* <li> <i>p</i> is an instance of CryptoPermission, and</li>203* <li> <i>p</i>'s algorithm name equals or (in the case of wildcards)204* is implied by this permission's algorithm name, and</li>205* <li> <i>p</i>'s maximum allowable key size is less or206* equal to this permission's maximum allowable key size, and</li>207* <li> <i>p</i>'s algorithm parameter spec equals or is208* implied by this permission's algorithm parameter spec, and</li>209* <li> <i>p</i>'s exemptionMechanism equals or210* is implied by this permission's211* exemptionMechanism (a <code>null</code> exemption mechanism212* implies any other exemption mechanism).</li>213* </ul>214*215* @param p the permission to check against.216*217* @return true if the specified permission is equal to or218* implied by this permission, false otherwise.219*/220public boolean implies(Permission p) {221if (!(p instanceof CryptoPermission))222return false;223224CryptoPermission cp = (CryptoPermission)p;225226if ((!alg.equalsIgnoreCase(cp.alg)) &&227(!alg.equalsIgnoreCase(ALG_NAME_WILDCARD))) {228return false;229}230231// alg is the same as cp's alg or232// alg is a wildcard.233if (cp.maxKeySize <= this.maxKeySize) {234// check algParamSpec.235if (!impliesParameterSpec(cp.checkParam, cp.algParamSpec)) {236return false;237}238239// check exemptionMechanism.240if (impliesExemptionMechanism(cp.exemptionMechanism)) {241return true;242}243}244245return false;246}247248/**249* Checks two CryptoPermission objects for equality. Checks that250* <code>obj</code> is a CryptoPermission, and has the same251* algorithm name,252* exemption mechanism name, maximum allowable key size and253* algorithm parameter spec254* as this object.255* <P>256* @param obj the object to test for equality with this object.257* @return true if <code>obj</code> is equal to this object.258*/259public boolean equals(Object obj) {260if (obj == this)261return true;262263if (!(obj instanceof CryptoPermission))264return false;265266CryptoPermission that = (CryptoPermission) obj;267268if (!(alg.equalsIgnoreCase(that.alg)) ||269(maxKeySize != that.maxKeySize)) {270return false;271}272if (this.checkParam != that.checkParam) {273return false;274}275return (equalObjects(this.exemptionMechanism,276that.exemptionMechanism) &&277equalObjects(this.algParamSpec,278that.algParamSpec));279}280281/**282* Returns the hash code value for this object.283*284* @return a hash code value for this object.285*/286287public int hashCode() {288int retval = alg.hashCode();289retval ^= maxKeySize;290if (exemptionMechanism != null) {291retval ^= exemptionMechanism.hashCode();292}293if (checkParam) retval ^= 100;294if (algParamSpec != null) {295retval ^= algParamSpec.hashCode();296}297return retval;298}299300/**301* There is no action defined for a CryptoPermission302* onject.303*/304public String getActions()305{306return null;307}308309/**310* Returns a new PermissionCollection object for storing311* CryptoPermission objects.312*313* @return a new PermissionCollection object suitable for storing314* CryptoPermissions.315*/316317public PermissionCollection newPermissionCollection() {318return new CryptoPermissionCollection();319}320321/**322* Returns the algorithm name associated with323* this CryptoPermission object.324*/325final String getAlgorithm() {326return alg;327}328329/**330* Returns the exemption mechanism name331* associated with this CryptoPermission332* object.333*/334final String getExemptionMechanism() {335return exemptionMechanism;336}337338/**339* Returns the maximum allowable key size associated340* with this CryptoPermission object.341*/342final int getMaxKeySize() {343return maxKeySize;344}345346/**347* Returns true if there is a limitation on the348* AlgorithmParameterSpec associated with this349* CryptoPermission object and false if otherwise.350*/351final boolean getCheckParam() {352return checkParam;353}354355/**356* Returns the AlgorithmParameterSpec357* associated with this CryptoPermission358* object.359*/360final AlgorithmParameterSpec getAlgorithmParameterSpec() {361return algParamSpec;362}363364/**365* Returns a string describing this CryptoPermission. The convention is to366* specify the class name, the algorithm name, the maximum allowable367* key size, and the name of the exemption mechanism, in the following368* format: '("ClassName" "algorithm" "keysize" "exemption_mechanism")'.369*370* @return information about this CryptoPermission.371*/372public String toString() {373StringBuilder buf = new StringBuilder(100);374buf.append("(CryptoPermission " + alg + " " + maxKeySize);375if (algParamSpec != null) {376if (algParamSpec instanceof RC2ParameterSpec) {377buf.append(" , effective " +378((RC2ParameterSpec)algParamSpec).getEffectiveKeyBits());379} else if (algParamSpec instanceof RC5ParameterSpec) {380buf.append(" , rounds " +381((RC5ParameterSpec)algParamSpec).getRounds());382}383}384if (exemptionMechanism != null) { // OPTIONAL385buf.append(" " + exemptionMechanism);386}387buf.append(")");388return buf.toString();389}390391private boolean impliesExemptionMechanism(String exemptionMechanism) {392if (this.exemptionMechanism == null) {393return true;394}395396if (exemptionMechanism == null) {397return false;398}399400if (this.exemptionMechanism.equals(exemptionMechanism)) {401return true;402}403404return false;405}406407private boolean impliesParameterSpec(boolean checkParam,408AlgorithmParameterSpec algParamSpec) {409if ((this.checkParam) && checkParam) {410if (algParamSpec == null) {411return true;412} else if (this.algParamSpec == null) {413return false;414}415416if (this.algParamSpec.getClass() != algParamSpec.getClass()) {417return false;418}419420if (algParamSpec instanceof RC2ParameterSpec) {421if (((RC2ParameterSpec)algParamSpec).getEffectiveKeyBits() <=422((RC2ParameterSpec)423(this.algParamSpec)).getEffectiveKeyBits()) {424return true;425}426}427428if (algParamSpec instanceof RC5ParameterSpec) {429if (((RC5ParameterSpec)algParamSpec).getRounds() <=430((RC5ParameterSpec)this.algParamSpec).getRounds()) {431return true;432}433}434435if (algParamSpec instanceof PBEParameterSpec) {436if (((PBEParameterSpec)algParamSpec).getIterationCount() <=437((PBEParameterSpec)this.algParamSpec).getIterationCount()) {438return true;439}440}441442// For classes we don't know, the following443// may be the best try.444if (this.algParamSpec.equals(algParamSpec)) {445return true;446}447return false;448} else if (this.checkParam) {449return false;450} else {451return true;452}453}454455private boolean equalObjects(Object obj1, Object obj2) {456if (obj1 == null) {457return (obj2 == null ? true : false);458}459460return obj1.equals(obj2);461}462}463464/**465* A CryptoPermissionCollection stores a set of CryptoPermission466* permissions.467*468* @see java.security.Permission469* @see java.security.Permissions470* @see java.security.PermissionCollection471*472* @author Sharon Liu473*/474final class CryptoPermissionCollection extends PermissionCollection475implements Serializable476{477private static final long serialVersionUID = -511215555898802763L;478479private Vector<Permission> permissions;480481/**482* Creates an empty CryptoPermissionCollection483* object.484*/485CryptoPermissionCollection() {486permissions = new Vector<Permission>(3);487}488489/**490* Adds a permission to the CryptoPermissionCollection.491*492* @param permission the Permission object to add.493*494* @exception SecurityException - if this CryptoPermissionCollection495* object has been marked <i>readOnly</i>.496*/497public void add(Permission permission) {498if (isReadOnly())499throw new SecurityException("attempt to add a Permission " +500"to a readonly PermissionCollection");501502if (!(permission instanceof CryptoPermission))503return;504505permissions.addElement(permission);506}507508/**509* Check and see if this CryptoPermission object implies510* the given Permission object.511*512* @param permission the Permission object to compare513*514* @return true if the given permission is implied by this515* CryptoPermissionCollection, false if not.516*/517public boolean implies(Permission permission) {518if (!(permission instanceof CryptoPermission))519return false;520521CryptoPermission cp = (CryptoPermission)permission;522523Enumeration<Permission> e = permissions.elements();524525while (e.hasMoreElements()) {526CryptoPermission x = (CryptoPermission) e.nextElement();527if (x.implies(cp)) {528return true;529}530}531return false;532}533534/**535* Returns an enumeration of all the CryptoPermission objects536* in the container.537*538* @return an enumeration of all the CryptoPermission objects.539*/540541public Enumeration<Permission> elements() {542return permissions.elements();543}544}545546547