Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/crypto/JceSecurityManager.java
38829 views
/*1* Copyright (c) 1999, 2013, 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.net.*;29import java.util.*;30import java.util.concurrent.ConcurrentHashMap;31import java.util.concurrent.ConcurrentMap;3233/**34* The JCE security manager.35*36* <p>The JCE security manager is responsible for determining the maximum37* allowable cryptographic strength for a given applet/application, for a given38* algorithm, by consulting the configured jurisdiction policy files and39* 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 Luehe44*45* @since 1.446*/4748final class JceSecurityManager extends SecurityManager {4950private static final CryptoPermissions defaultPolicy;51private static final CryptoPermissions exemptPolicy;52private static final CryptoAllPermission allPerm;53private static final Vector<Class<?>> TrustedCallersCache =54new Vector<>(2);55private static final ConcurrentMap<URL,CryptoPermissions> exemptCache =56new ConcurrentHashMap<>();57private static final CryptoPermissions CACHE_NULL_MARK =58new CryptoPermissions();5960// singleton instance61static final JceSecurityManager INSTANCE;6263static {64defaultPolicy = JceSecurity.getDefaultPolicy();65exemptPolicy = JceSecurity.getExemptPolicy();66allPerm = CryptoAllPermission.INSTANCE;67INSTANCE = AccessController.doPrivileged(68new PrivilegedAction<JceSecurityManager>() {69public JceSecurityManager run() {70return new JceSecurityManager();71}72});73}7475private JceSecurityManager() {76// empty77}7879/**80* Returns the maximum allowable crypto strength for the given81* applet/application, for the given algorithm.82*/83CryptoPermission getCryptoPermission(String alg) {84// Need to convert to uppercase since the crypto perm85// lookup is case sensitive.86alg = alg.toUpperCase(Locale.ENGLISH);8788// If CryptoAllPermission is granted by default, we return that.89// Otherwise, this will be the permission we return if anything goes90// wrong.91CryptoPermission defaultPerm = getDefaultPermission(alg);92if (defaultPerm == CryptoAllPermission.INSTANCE) {93return defaultPerm;94}9596// Determine the codebase of the caller of the JCE API.97// This is the codebase of the first class which is not in98// javax.crypto.* packages.99// NOTE: javax.crypto.* package maybe subject to package100// insertion, so need to check its classloader as well.101Class<?>[] context = getClassContext();102URL callerCodeBase = null;103int i;104for (i=0; i<context.length; i++) {105Class<?> cls = context[i];106callerCodeBase = JceSecurity.getCodeBase(cls);107if (callerCodeBase != null) {108break;109} else {110if (cls.getName().startsWith("javax.crypto.")) {111// skip jce classes since they aren't the callers112continue;113}114// use default permission when the caller is system classes115return defaultPerm;116}117}118119if (i == context.length) {120return defaultPerm;121}122123CryptoPermissions appPerms = exemptCache.get(callerCodeBase);124if (appPerms == null) {125// no match found in cache126synchronized (this.getClass()) {127appPerms = exemptCache.get(callerCodeBase);128if (appPerms == null) {129appPerms = getAppPermissions(callerCodeBase);130exemptCache.putIfAbsent(callerCodeBase,131(appPerms == null? CACHE_NULL_MARK:appPerms));132}133}134}135if (appPerms == null || appPerms == CACHE_NULL_MARK) {136return defaultPerm;137}138139// If the app was granted the special CryptoAllPermission, return that.140if (appPerms.implies(allPerm)) {141return allPerm;142}143144// Check if the crypto permissions granted to the app contain a145// crypto permission for the requested algorithm that does not require146// any exemption mechanism to be enforced.147// Return that permission, if present.148PermissionCollection appPc = appPerms.getPermissionCollection(alg);149if (appPc == null) {150return defaultPerm;151}152Enumeration<Permission> enum_ = appPc.elements();153while (enum_.hasMoreElements()) {154CryptoPermission cp = (CryptoPermission)enum_.nextElement();155if (cp.getExemptionMechanism() == null) {156return cp;157}158}159160// Check if the jurisdiction file for exempt applications contains161// any entries for the requested algorithm.162// If not, return the default permission.163PermissionCollection exemptPc =164exemptPolicy.getPermissionCollection(alg);165if (exemptPc == null) {166return defaultPerm;167}168169// In the jurisdiction file for exempt applications, go through the170// list of CryptoPermission entries for the requested algorithm, and171// stop at the first entry:172// - that is implied by the collection of crypto permissions granted173// to the app, and174// - whose exemption mechanism is available from one of the175// registered CSPs176enum_ = exemptPc.elements();177while (enum_.hasMoreElements()) {178CryptoPermission cp = (CryptoPermission)enum_.nextElement();179try {180ExemptionMechanism.getInstance(cp.getExemptionMechanism());181if (cp.getAlgorithm().equals(182CryptoPermission.ALG_NAME_WILDCARD)) {183CryptoPermission newCp;184if (cp.getCheckParam()) {185newCp = new CryptoPermission(186alg, cp.getMaxKeySize(),187cp.getAlgorithmParameterSpec(),188cp.getExemptionMechanism());189} else {190newCp = new CryptoPermission(191alg, cp.getMaxKeySize(),192cp.getExemptionMechanism());193}194if (appPerms.implies(newCp)) {195return newCp;196}197}198199if (appPerms.implies(cp)) {200return cp;201}202} catch (Exception e) {203continue;204}205}206return defaultPerm;207}208209private static CryptoPermissions getAppPermissions(URL callerCodeBase) {210// Check if app is exempt, and retrieve the permissions bundled with it211try {212return JceSecurity.verifyExemptJar(callerCodeBase);213} catch (Exception e) {214// Jar verification fails215return null;216}217218}219220/**221* Returns the default permission for the given algorithm.222*/223private CryptoPermission getDefaultPermission(String alg) {224Enumeration<Permission> enum_ =225defaultPolicy.getPermissionCollection(alg).elements();226return (CryptoPermission)enum_.nextElement();227}228229// See bug 4341369 & 4334690 for more info.230boolean isCallerTrusted() {231// Get the caller and its codebase.232Class<?>[] context = getClassContext();233URL callerCodeBase = null;234int i;235for (i=0; i<context.length; i++) {236callerCodeBase = JceSecurity.getCodeBase(context[i]);237if (callerCodeBase != null) {238break;239}240}241// The caller is in the JCE framework.242if (i == context.length) {243return true;244}245//The caller has been verified.246if (TrustedCallersCache.contains(context[i])) {247return true;248}249// Check whether the caller is a trusted provider.250try {251JceSecurity.verifyProviderJar(callerCodeBase);252} catch (Exception e2) {253return false;254}255TrustedCallersCache.addElement(context[i]);256return true;257}258}259260261