Skip to content

Commit c8af823

Browse files
author
Bradford Wetmore
committed
8267485: Remove the dependency on SecurityManager in JceSecurityManager.java
Reviewed-by: mchung
1 parent ea49691 commit c8af823

File tree

2 files changed

+35
-42
lines changed

2 files changed

+35
-42
lines changed

src/java.base/share/classes/javax/crypto/Cipher.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,8 @@ protected Cipher(CipherSpi cipherSpi,
272272
// See bug 4341369 & 4334690 for more info.
273273
// If the caller is trusted, then okay.
274274
// Otherwise throw an IllegalArgumentException.
275-
if (!JceSecurityManager.INSTANCE.isCallerTrusted(provider)) {
275+
if (!JceSecurityManager.INSTANCE.isCallerTrusted(
276+
JceSecurityManager.WALKER.getCallerClass(), provider)) {
276277
throw new IllegalArgumentException("Cannot construct cipher");
277278
}
278279
this.spi = cipherSpi;

src/java.base/share/classes/javax/crypto/JceSecurityManager.java

Lines changed: 33 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.util.*;
3131
import java.util.concurrent.ConcurrentHashMap;
3232
import java.util.concurrent.ConcurrentMap;
33+
import java.lang.StackWalker.*;
3334

3435
/**
3536
* The JCE security manager.
@@ -39,15 +40,11 @@
3940
* algorithm, by consulting the configured jurisdiction policy files and
4041
* the cryptographic permissions bundled with the applet/application.
4142
*
42-
* <p>Note that this security manager is never installed, only instantiated.
43-
*
4443
* @author Jan Luehe
4544
*
4645
* @since 1.4
4746
*/
48-
49-
@SuppressWarnings("removal")
50-
final class JceSecurityManager extends SecurityManager {
47+
final class JceSecurityManager {
5148

5249
private static final CryptoPermissions defaultPolicy;
5350
private static final CryptoPermissions exemptPolicy;
@@ -61,17 +58,25 @@ final class JceSecurityManager extends SecurityManager {
6158

6259
// singleton instance
6360
static final JceSecurityManager INSTANCE;
61+
static final StackWalker WALKER;
6462

6563
static {
6664
defaultPolicy = JceSecurity.getDefaultPolicy();
6765
exemptPolicy = JceSecurity.getExemptPolicy();
6866
allPerm = CryptoAllPermission.INSTANCE;
69-
INSTANCE = AccessController.doPrivileged(
70-
new PrivilegedAction<>() {
71-
public JceSecurityManager run() {
72-
return new JceSecurityManager();
73-
}
74-
});
67+
68+
PrivilegedAction<JceSecurityManager> paSM = JceSecurityManager::new;
69+
@SuppressWarnings("removal")
70+
JceSecurityManager dummySecurityManager =
71+
AccessController.doPrivileged(paSM);
72+
INSTANCE = dummySecurityManager;
73+
74+
PrivilegedAction<StackWalker> paWalker =
75+
() -> StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE);
76+
@SuppressWarnings("removal")
77+
StackWalker dummyWalker = AccessController.doPrivileged(paWalker);
78+
79+
WALKER = dummyWalker;
7580
}
7681

7782
private JceSecurityManager() {
@@ -82,10 +87,11 @@ private JceSecurityManager() {
8287
* Returns the maximum allowable crypto strength for the given
8388
* applet/application, for the given algorithm.
8489
*/
85-
CryptoPermission getCryptoPermission(String alg) {
90+
CryptoPermission getCryptoPermission(String theAlg) {
91+
8692
// Need to convert to uppercase since the crypto perm
8793
// lookup is case sensitive.
88-
alg = alg.toUpperCase(Locale.ENGLISH);
94+
final String alg = theAlg.toUpperCase(Locale.ENGLISH);
8995

9096
// If CryptoAllPermission is granted by default, we return that.
9197
// Otherwise, this will be the permission we return if anything goes
@@ -100,28 +106,19 @@ CryptoPermission getCryptoPermission(String alg) {
100106
// javax.crypto.* packages.
101107
// NOTE: javax.crypto.* package maybe subject to package
102108
// insertion, so need to check its classloader as well.
103-
Class<?>[] context = getClassContext();
104-
URL callerCodeBase = null;
105-
int i;
106-
for (i=0; i<context.length; i++) {
107-
Class<?> cls = context[i];
108-
callerCodeBase = JceSecurity.getCodeBase(cls);
109-
if (callerCodeBase != null) {
110-
break;
111-
} else {
112-
if (cls.getName().startsWith("javax.crypto.")) {
113-
// skip jce classes since they aren't the callers
114-
continue;
115-
}
116-
// use default permission when the caller is system classes
117-
return defaultPerm;
118-
}
119-
}
120-
121-
if (i == context.length) {
122-
return defaultPerm;
123-
}
109+
return WALKER.walk(s -> s.map(StackFrame::getDeclaringClass)
110+
.filter(c -> !c.getPackageName().equals("javax.crypto"))
111+
.map(cls -> {
112+
URL callerCodeBase = JceSecurity.getCodeBase(cls);
113+
return (callerCodeBase != null) ?
114+
getCryptoPermissionFromURL(callerCodeBase,
115+
alg, defaultPerm) : defaultPerm;})
116+
.findFirst().get() // nulls not possible for Optional
117+
);
118+
}
124119

120+
CryptoPermission getCryptoPermissionFromURL(URL callerCodeBase,
121+
String alg, CryptoPermission defaultPerm) {
125122
CryptoPermissions appPerms = exemptCache.get(callerCodeBase);
126123
if (appPerms == null) {
127124
// no match found in cache
@@ -231,14 +228,9 @@ private CryptoPermission getDefaultPermission(String alg) {
231228
// Only used by javax.crypto.Cipher constructor to disallow Cipher
232229
// objects being constructed by untrusted code (See bug 4341369 &
233230
// 4334690 for more info).
234-
boolean isCallerTrusted(Provider provider) {
231+
boolean isCallerTrusted(Class<?> caller, Provider provider) {
235232
// Get the caller and its codebase.
236-
Class<?>[] context = getClassContext();
237-
if (context.length >= 3) {
238-
// context[0]: class javax.crypto.JceSecurityManager
239-
// context[1]: class javax.crypto.Cipher (or other JCE API class)
240-
// context[2]: this is what we are gonna check
241-
Class<?> caller = context[2];
233+
if (caller != null) {
242234
URL callerCodeBase = JceSecurity.getCodeBase(caller);
243235
if (callerCodeBase == null) {
244236
return true;

0 commit comments

Comments
 (0)