8267485: Remove the dependency on SecurityManager in JceSecurityManager.java

Reviewed-by: mchung
This commit is contained in:
Bradford Wetmore 2021-07-27 17:11:13 +00:00
parent ea49691f1d
commit c8af8238b4
2 changed files with 35 additions and 42 deletions

View file

@ -272,7 +272,8 @@ public class Cipher {
// See bug 4341369 & 4334690 for more info.
// If the caller is trusted, then okay.
// Otherwise throw an IllegalArgumentException.
if (!JceSecurityManager.INSTANCE.isCallerTrusted(provider)) {
if (!JceSecurityManager.INSTANCE.isCallerTrusted(
JceSecurityManager.WALKER.getCallerClass(), provider)) {
throw new IllegalArgumentException("Cannot construct cipher");
}
this.spi = cipherSpi;

View file

@ -30,6 +30,7 @@ import java.net.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.lang.StackWalker.*;
/**
* The JCE security manager.
@ -39,15 +40,11 @@ import java.util.concurrent.ConcurrentMap;
* algorithm, by consulting the configured jurisdiction policy files and
* the cryptographic permissions bundled with the applet/application.
*
* <p>Note that this security manager is never installed, only instantiated.
*
* @author Jan Luehe
*
* @since 1.4
*/
@SuppressWarnings("removal")
final class JceSecurityManager extends SecurityManager {
final class JceSecurityManager {
private static final CryptoPermissions defaultPolicy;
private static final CryptoPermissions exemptPolicy;
@ -61,17 +58,25 @@ final class JceSecurityManager extends SecurityManager {
// singleton instance
static final JceSecurityManager INSTANCE;
static final StackWalker WALKER;
static {
defaultPolicy = JceSecurity.getDefaultPolicy();
exemptPolicy = JceSecurity.getExemptPolicy();
allPerm = CryptoAllPermission.INSTANCE;
INSTANCE = AccessController.doPrivileged(
new PrivilegedAction<>() {
public JceSecurityManager run() {
return new JceSecurityManager();
}
});
PrivilegedAction<JceSecurityManager> paSM = JceSecurityManager::new;
@SuppressWarnings("removal")
JceSecurityManager dummySecurityManager =
AccessController.doPrivileged(paSM);
INSTANCE = dummySecurityManager;
PrivilegedAction<StackWalker> paWalker =
() -> StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE);
@SuppressWarnings("removal")
StackWalker dummyWalker = AccessController.doPrivileged(paWalker);
WALKER = dummyWalker;
}
private JceSecurityManager() {
@ -82,10 +87,11 @@ final class JceSecurityManager extends SecurityManager {
* Returns the maximum allowable crypto strength for the given
* applet/application, for the given algorithm.
*/
CryptoPermission getCryptoPermission(String alg) {
CryptoPermission getCryptoPermission(String theAlg) {
// Need to convert to uppercase since the crypto perm
// lookup is case sensitive.
alg = alg.toUpperCase(Locale.ENGLISH);
final String alg = theAlg.toUpperCase(Locale.ENGLISH);
// If CryptoAllPermission is granted by default, we return that.
// Otherwise, this will be the permission we return if anything goes
@ -100,28 +106,19 @@ final class JceSecurityManager extends SecurityManager {
// javax.crypto.* packages.
// NOTE: javax.crypto.* package maybe subject to package
// insertion, so need to check its classloader as well.
Class<?>[] context = getClassContext();
URL callerCodeBase = null;
int i;
for (i=0; i<context.length; i++) {
Class<?> cls = context[i];
callerCodeBase = JceSecurity.getCodeBase(cls);
if (callerCodeBase != null) {
break;
} else {
if (cls.getName().startsWith("javax.crypto.")) {
// skip jce classes since they aren't the callers
continue;
}
// use default permission when the caller is system classes
return defaultPerm;
}
}
if (i == context.length) {
return defaultPerm;
}
return WALKER.walk(s -> s.map(StackFrame::getDeclaringClass)
.filter(c -> !c.getPackageName().equals("javax.crypto"))
.map(cls -> {
URL callerCodeBase = JceSecurity.getCodeBase(cls);
return (callerCodeBase != null) ?
getCryptoPermissionFromURL(callerCodeBase,
alg, defaultPerm) : defaultPerm;})
.findFirst().get() // nulls not possible for Optional
);
}
CryptoPermission getCryptoPermissionFromURL(URL callerCodeBase,
String alg, CryptoPermission defaultPerm) {
CryptoPermissions appPerms = exemptCache.get(callerCodeBase);
if (appPerms == null) {
// no match found in cache
@ -231,14 +228,9 @@ final class JceSecurityManager extends SecurityManager {
// Only used by javax.crypto.Cipher constructor to disallow Cipher
// objects being constructed by untrusted code (See bug 4341369 &
// 4334690 for more info).
boolean isCallerTrusted(Provider provider) {
boolean isCallerTrusted(Class<?> caller, Provider provider) {
// Get the caller and its codebase.
Class<?>[] context = getClassContext();
if (context.length >= 3) {
// context[0]: class javax.crypto.JceSecurityManager
// context[1]: class javax.crypto.Cipher (or other JCE API class)
// context[2]: this is what we are gonna check
Class<?> caller = context[2];
if (caller != null) {
URL callerCodeBase = JceSecurity.getCodeBase(caller);
if (callerCodeBase == null) {
return true;