Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/javax/crypto/JceSecurityManager.java
41152 views
1
/*
2
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package javax.crypto;
27
28
import java.security.*;
29
import java.net.*;
30
import java.util.*;
31
import java.util.concurrent.ConcurrentHashMap;
32
import java.util.concurrent.ConcurrentMap;
33
34
/**
35
* The JCE security manager.
36
*
37
* <p>The JCE security manager is responsible for determining the maximum
38
* allowable cryptographic strength for a given applet/application, for a given
39
* algorithm, by consulting the configured jurisdiction policy files and
40
* the cryptographic permissions bundled with the applet/application.
41
*
42
* <p>Note that this security manager is never installed, only instantiated.
43
*
44
* @author Jan Luehe
45
*
46
* @since 1.4
47
*/
48
49
@SuppressWarnings("removal")
50
final class JceSecurityManager extends SecurityManager {
51
52
private static final CryptoPermissions defaultPolicy;
53
private static final CryptoPermissions exemptPolicy;
54
private static final CryptoAllPermission allPerm;
55
private static final Vector<Class<?>> TrustedCallersCache =
56
new Vector<>(2);
57
private static final ConcurrentMap<URL,CryptoPermissions> exemptCache =
58
new ConcurrentHashMap<>();
59
private static final CryptoPermissions CACHE_NULL_MARK =
60
new CryptoPermissions();
61
62
// singleton instance
63
static final JceSecurityManager INSTANCE;
64
65
static {
66
defaultPolicy = JceSecurity.getDefaultPolicy();
67
exemptPolicy = JceSecurity.getExemptPolicy();
68
allPerm = CryptoAllPermission.INSTANCE;
69
INSTANCE = AccessController.doPrivileged(
70
new PrivilegedAction<>() {
71
public JceSecurityManager run() {
72
return new JceSecurityManager();
73
}
74
});
75
}
76
77
private JceSecurityManager() {
78
// empty
79
}
80
81
/**
82
* Returns the maximum allowable crypto strength for the given
83
* applet/application, for the given algorithm.
84
*/
85
CryptoPermission getCryptoPermission(String alg) {
86
// Need to convert to uppercase since the crypto perm
87
// lookup is case sensitive.
88
alg = alg.toUpperCase(Locale.ENGLISH);
89
90
// If CryptoAllPermission is granted by default, we return that.
91
// Otherwise, this will be the permission we return if anything goes
92
// wrong.
93
CryptoPermission defaultPerm = getDefaultPermission(alg);
94
if (defaultPerm == CryptoAllPermission.INSTANCE) {
95
return defaultPerm;
96
}
97
98
// Determine the codebase of the caller of the JCE API.
99
// This is the codebase of the first class which is not in
100
// javax.crypto.* packages.
101
// NOTE: javax.crypto.* package maybe subject to package
102
// 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
}
124
125
CryptoPermissions appPerms = exemptCache.get(callerCodeBase);
126
if (appPerms == null) {
127
// no match found in cache
128
synchronized (this.getClass()) {
129
appPerms = exemptCache.get(callerCodeBase);
130
if (appPerms == null) {
131
appPerms = getAppPermissions(callerCodeBase);
132
exemptCache.putIfAbsent(callerCodeBase,
133
(appPerms == null? CACHE_NULL_MARK:appPerms));
134
}
135
}
136
}
137
if (appPerms == null || appPerms == CACHE_NULL_MARK) {
138
return defaultPerm;
139
}
140
141
// If the app was granted the special CryptoAllPermission, return that.
142
if (appPerms.implies(allPerm)) {
143
return allPerm;
144
}
145
146
// Check if the crypto permissions granted to the app contain a
147
// crypto permission for the requested algorithm that does not require
148
// any exemption mechanism to be enforced.
149
// Return that permission, if present.
150
PermissionCollection appPc = appPerms.getPermissionCollection(alg);
151
if (appPc == null) {
152
return defaultPerm;
153
}
154
Enumeration<Permission> enum_ = appPc.elements();
155
while (enum_.hasMoreElements()) {
156
CryptoPermission cp = (CryptoPermission)enum_.nextElement();
157
if (cp.getExemptionMechanism() == null) {
158
return cp;
159
}
160
}
161
162
// Check if the jurisdiction file for exempt applications contains
163
// any entries for the requested algorithm.
164
// If not, return the default permission.
165
PermissionCollection exemptPc =
166
exemptPolicy.getPermissionCollection(alg);
167
if (exemptPc == null) {
168
return defaultPerm;
169
}
170
171
// In the jurisdiction file for exempt applications, go through the
172
// list of CryptoPermission entries for the requested algorithm, and
173
// stop at the first entry:
174
// - that is implied by the collection of crypto permissions granted
175
// to the app, and
176
// - whose exemption mechanism is available from one of the
177
// registered CSPs
178
enum_ = exemptPc.elements();
179
while (enum_.hasMoreElements()) {
180
CryptoPermission cp = (CryptoPermission)enum_.nextElement();
181
try {
182
ExemptionMechanism.getInstance(cp.getExemptionMechanism());
183
if (cp.getAlgorithm().equals(
184
CryptoPermission.ALG_NAME_WILDCARD)) {
185
CryptoPermission newCp;
186
if (cp.getCheckParam()) {
187
newCp = new CryptoPermission(
188
alg, cp.getMaxKeySize(),
189
cp.getAlgorithmParameterSpec(),
190
cp.getExemptionMechanism());
191
} else {
192
newCp = new CryptoPermission(
193
alg, cp.getMaxKeySize(),
194
cp.getExemptionMechanism());
195
}
196
if (appPerms.implies(newCp)) {
197
return newCp;
198
}
199
}
200
201
if (appPerms.implies(cp)) {
202
return cp;
203
}
204
} catch (Exception e) {
205
continue;
206
}
207
}
208
return defaultPerm;
209
}
210
211
private static CryptoPermissions getAppPermissions(URL callerCodeBase) {
212
// Check if app is exempt, and retrieve the permissions bundled with it
213
try {
214
return JceSecurity.verifyExemptJar(callerCodeBase);
215
} catch (Exception e) {
216
// Jar verification fails
217
return null;
218
}
219
220
}
221
222
/**
223
* Returns the default permission for the given algorithm.
224
*/
225
private CryptoPermission getDefaultPermission(String alg) {
226
Enumeration<Permission> enum_ =
227
defaultPolicy.getPermissionCollection(alg).elements();
228
return (CryptoPermission)enum_.nextElement();
229
}
230
231
// Only used by javax.crypto.Cipher constructor to disallow Cipher
232
// objects being constructed by untrusted code (See bug 4341369 &
233
// 4334690 for more info).
234
boolean isCallerTrusted(Provider provider) {
235
// 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];
242
URL callerCodeBase = JceSecurity.getCodeBase(caller);
243
if (callerCodeBase == null) {
244
return true;
245
}
246
// The caller has been verified.
247
if (TrustedCallersCache.contains(caller)) {
248
return true;
249
}
250
251
// Check the association between caller and provider
252
Class<?> pCls = provider.getClass();
253
Module pMod = pCls.getModule();
254
// If they are in the same named module or share
255
// the same codebase, then they are associated
256
boolean sameOrigin = (pMod.isNamed()?
257
caller.getModule().equals(pMod) :
258
callerCodeBase.equals(JceSecurity.getCodeBase(pCls)));
259
if (sameOrigin) {
260
// The caller is from trusted provider
261
if (ProviderVerifier.isTrustedCryptoProvider(provider)) {
262
TrustedCallersCache.addElement(caller);
263
return true;
264
}
265
} else {
266
// Don't include the provider in the subsequent
267
// JceSecurity.verifyProvider(...) call
268
provider = null;
269
}
270
271
// Check whether the caller is a trusted provider.
272
try {
273
JceSecurity.verifyProvider(callerCodeBase, provider);
274
} catch (Exception e2) {
275
return false;
276
}
277
TrustedCallersCache.addElement(caller);
278
return true;
279
}
280
return false;
281
}
282
}
283
284