Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/crypto/CryptoPermissions.java
38829 views
1
/*
2
* Copyright (c) 1999, 2012, 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.util.Enumeration;
30
import java.util.Hashtable;
31
import java.util.Vector;
32
import java.util.NoSuchElementException;
33
import java.util.concurrent.ConcurrentHashMap;
34
import java.io.Serializable;
35
import java.io.InputStream;
36
import java.io.InputStreamReader;
37
import java.io.BufferedReader;
38
import java.io.ObjectStreamField;
39
import java.io.ObjectInputStream;
40
import java.io.ObjectInputStream.GetField;
41
import java.io.ObjectOutputStream;
42
import java.io.ObjectOutputStream.PutField;
43
import java.io.IOException;
44
45
/**
46
* This class contains CryptoPermission objects, organized into
47
* PermissionCollections according to algorithm names.
48
*
49
* <p>When the <code>add</code> method is called to add a
50
* CryptoPermission, the CryptoPermission is stored in the
51
* appropriate PermissionCollection. If no such
52
* collection exists yet, the algorithm name associated with
53
* the CryptoPermission object is
54
* determined and the <code>newPermissionCollection</code> method
55
* is called on the CryptoPermission or CryptoAllPermission class to
56
* create the PermissionCollection and add it to the Permissions object.
57
*
58
* @see javax.crypto.CryptoPermission
59
* @see java.security.PermissionCollection
60
* @see java.security.Permissions
61
*
62
* @author Sharon Liu
63
* @since 1.4
64
*/
65
final class CryptoPermissions extends PermissionCollection
66
implements Serializable {
67
68
private static final long serialVersionUID = 4946547168093391015L;
69
70
/**
71
* @serialField perms java.util.Hashtable
72
*/
73
private static final ObjectStreamField[] serialPersistentFields = {
74
new ObjectStreamField("perms", Hashtable.class),
75
};
76
77
// Switched from Hashtable to ConcurrentHashMap to improve scalability.
78
// To maintain serialization compatibility, this field is made transient
79
// and custom readObject/writeObject methods are used.
80
private transient ConcurrentHashMap<String,PermissionCollection> perms;
81
82
/**
83
* Creates a new CryptoPermissions object containing
84
* no CryptoPermissionCollections.
85
*/
86
CryptoPermissions() {
87
perms = new ConcurrentHashMap<>(7);
88
}
89
90
/**
91
* Populates the crypto policy from the specified
92
* InputStream into this CryptoPermissions object.
93
*
94
* @param in the InputStream to load from.
95
*
96
* @exception SecurityException if cannot load
97
* successfully.
98
*/
99
void load(InputStream in)
100
throws IOException, CryptoPolicyParser.ParsingException {
101
CryptoPolicyParser parser = new CryptoPolicyParser();
102
parser.read(new BufferedReader(new InputStreamReader(in, "UTF-8")));
103
104
CryptoPermission[] parsingResult = parser.getPermissions();
105
for (int i = 0; i < parsingResult.length; i++) {
106
this.add(parsingResult[i]);
107
}
108
}
109
110
/**
111
* Returns true if this CryptoPermissions object doesn't
112
* contain any CryptoPermission objects; otherwise, returns
113
* false.
114
*/
115
boolean isEmpty() {
116
return perms.isEmpty();
117
}
118
119
/**
120
* Adds a permission object to the PermissionCollection for the
121
* algorithm returned by
122
* <code>(CryptoPermission)permission.getAlgorithm()</code>.
123
*
124
* This method creates
125
* a new PermissionCollection object (and adds the permission to it)
126
* if an appropriate collection does not yet exist. <p>
127
*
128
* @param permission the Permission object to add.
129
*
130
* @exception SecurityException if this CryptoPermissions object is
131
* marked as readonly.
132
*
133
* @see isReadOnly
134
*/
135
public void add(Permission permission) {
136
137
if (isReadOnly())
138
throw new SecurityException("Attempt to add a Permission " +
139
"to a readonly CryptoPermissions " +
140
"object");
141
142
if (!(permission instanceof CryptoPermission))
143
return;
144
145
CryptoPermission cryptoPerm = (CryptoPermission)permission;
146
PermissionCollection pc =
147
getPermissionCollection(cryptoPerm);
148
pc.add(cryptoPerm);
149
String alg = cryptoPerm.getAlgorithm();
150
perms.putIfAbsent(alg, pc);
151
}
152
153
/**
154
* Checks if this object's PermissionCollection for permissons
155
* of the specified permission's algorithm implies the specified
156
* permission. Returns true if the checking succeeded.
157
*
158
* @param permission the Permission object to check.
159
*
160
* @return true if "permission" is implied by the permissions
161
* in the PermissionCollection it belongs to, false if not.
162
*
163
*/
164
public boolean implies(Permission permission) {
165
if (!(permission instanceof CryptoPermission)) {
166
return false;
167
}
168
169
CryptoPermission cryptoPerm = (CryptoPermission)permission;
170
171
PermissionCollection pc =
172
getPermissionCollection(cryptoPerm.getAlgorithm());
173
return pc.implies(cryptoPerm);
174
}
175
176
/**
177
* Returns an enumeration of all the Permission objects in all the
178
* PermissionCollections in this CryptoPermissions object.
179
*
180
* @return an enumeration of all the Permissions.
181
*/
182
public Enumeration<Permission> elements() {
183
// go through each Permissions in the hash table
184
// and call their elements() function.
185
return new PermissionsEnumerator(perms.elements());
186
}
187
188
/**
189
* Returns a CryptoPermissions object which
190
* represents the minimum of the specified
191
* CryptoPermissions object and this
192
* CryptoPermissions object.
193
*
194
* @param other the CryptoPermission
195
* object to compare with this object.
196
*/
197
CryptoPermissions getMinimum(CryptoPermissions other) {
198
if (other == null) {
199
return null;
200
}
201
202
if (this.perms.containsKey(CryptoAllPermission.ALG_NAME)) {
203
return other;
204
}
205
206
if (other.perms.containsKey(CryptoAllPermission.ALG_NAME)) {
207
return this;
208
}
209
210
CryptoPermissions ret = new CryptoPermissions();
211
212
213
PermissionCollection thatWildcard =
214
other.perms.get(CryptoPermission.ALG_NAME_WILDCARD);
215
int maxKeySize = 0;
216
if (thatWildcard != null) {
217
maxKeySize = ((CryptoPermission)
218
thatWildcard.elements().nextElement()).getMaxKeySize();
219
}
220
// For each algorithm in this CryptoPermissions,
221
// find out if there is anything we should add into
222
// ret.
223
Enumeration<String> thisKeys = this.perms.keys();
224
while (thisKeys.hasMoreElements()) {
225
String alg = thisKeys.nextElement();
226
227
PermissionCollection thisPc = this.perms.get(alg);
228
PermissionCollection thatPc = other.perms.get(alg);
229
230
CryptoPermission[] partialResult;
231
232
if (thatPc == null) {
233
if (thatWildcard == null) {
234
// The other CryptoPermissions
235
// doesn't allow this given
236
// algorithm at all. Just skip this
237
// algorithm.
238
continue;
239
}
240
partialResult = getMinimum(maxKeySize, thisPc);
241
} else {
242
partialResult = getMinimum(thisPc, thatPc);
243
}
244
245
for (int i = 0; i < partialResult.length; i++) {
246
ret.add(partialResult[i]);
247
}
248
}
249
250
PermissionCollection thisWildcard =
251
this.perms.get(CryptoPermission.ALG_NAME_WILDCARD);
252
253
// If this CryptoPermissions doesn't
254
// have a wildcard, we are done.
255
if (thisWildcard == null) {
256
return ret;
257
}
258
259
// Deal with the algorithms only appear
260
// in the other CryptoPermissions.
261
maxKeySize =
262
((CryptoPermission)
263
thisWildcard.elements().nextElement()).getMaxKeySize();
264
Enumeration<String> thatKeys = other.perms.keys();
265
while (thatKeys.hasMoreElements()) {
266
String alg = thatKeys.nextElement();
267
268
if (this.perms.containsKey(alg)) {
269
continue;
270
}
271
272
PermissionCollection thatPc = other.perms.get(alg);
273
274
CryptoPermission[] partialResult;
275
276
partialResult = getMinimum(maxKeySize, thatPc);
277
278
for (int i = 0; i < partialResult.length; i++) {
279
ret.add(partialResult[i]);
280
}
281
}
282
return ret;
283
}
284
285
/**
286
* Get the minimum of the two given PermissionCollection
287
* <code>thisPc</code> and <code>thatPc</code>.
288
*
289
* @param thisPc the first given PermissionColloection
290
* object.
291
*
292
* @param thatPc the second given PermissionCollection
293
* object.
294
*/
295
private CryptoPermission[] getMinimum(PermissionCollection thisPc,
296
PermissionCollection thatPc) {
297
Vector<CryptoPermission> permVector = new Vector<>(2);
298
299
Enumeration<Permission> thisPcPermissions = thisPc.elements();
300
301
// For each CryptoPermission in
302
// thisPc object, do the following:
303
// 1) if this CryptoPermission is implied
304
// by thatPc, this CryptoPermission
305
// should be returned, and we can
306
// move on to check the next
307
// CryptoPermission in thisPc.
308
// 2) otherwise, we should return
309
// all CryptoPermissions in thatPc
310
// which
311
// are implied by this CryptoPermission.
312
// Then we can move on to the
313
// next CryptoPermission in thisPc.
314
while (thisPcPermissions.hasMoreElements()) {
315
CryptoPermission thisCp =
316
(CryptoPermission)thisPcPermissions.nextElement();
317
318
Enumeration<Permission> thatPcPermissions = thatPc.elements();
319
while (thatPcPermissions.hasMoreElements()) {
320
CryptoPermission thatCp =
321
(CryptoPermission)thatPcPermissions.nextElement();
322
323
if (thatCp.implies(thisCp)) {
324
permVector.addElement(thisCp);
325
break;
326
}
327
if (thisCp.implies(thatCp)) {
328
permVector.addElement(thatCp);
329
}
330
}
331
}
332
333
CryptoPermission[] ret = new CryptoPermission[permVector.size()];
334
permVector.copyInto(ret);
335
return ret;
336
}
337
338
/**
339
* Returns all the CryptoPermission objects in the given
340
* PermissionCollection object
341
* whose maximum keysize no greater than <code>maxKeySize</code>.
342
* For all CryptoPermission objects with a maximum keysize greater
343
* than <code>maxKeySize</code>, this method constructs a
344
* corresponding CryptoPermission object whose maximum keysize is
345
* set to <code>maxKeySize</code>, and includes that in the result.
346
*
347
* @param maxKeySize the given maximum key size.
348
*
349
* @param pc the given PermissionCollection object.
350
*/
351
private CryptoPermission[] getMinimum(int maxKeySize,
352
PermissionCollection pc) {
353
Vector<CryptoPermission> permVector = new Vector<>(1);
354
355
Enumeration<Permission> enum_ = pc.elements();
356
357
while (enum_.hasMoreElements()) {
358
CryptoPermission cp =
359
(CryptoPermission)enum_.nextElement();
360
if (cp.getMaxKeySize() <= maxKeySize) {
361
permVector.addElement(cp);
362
} else {
363
if (cp.getCheckParam()) {
364
permVector.addElement(
365
new CryptoPermission(cp.getAlgorithm(),
366
maxKeySize,
367
cp.getAlgorithmParameterSpec(),
368
cp.getExemptionMechanism()));
369
} else {
370
permVector.addElement(
371
new CryptoPermission(cp.getAlgorithm(),
372
maxKeySize,
373
cp.getExemptionMechanism()));
374
}
375
}
376
}
377
378
CryptoPermission[] ret = new CryptoPermission[permVector.size()];
379
permVector.copyInto(ret);
380
return ret;
381
}
382
383
/**
384
* Returns the PermissionCollection for the
385
* specified algorithm. Returns null if there
386
* isn't such a PermissionCollection.
387
*
388
* @param alg the algorithm name.
389
*/
390
PermissionCollection getPermissionCollection(String alg) {
391
// If this CryptoPermissions includes CryptoAllPermission,
392
// we should return CryptoAllPermission.
393
PermissionCollection pc = perms.get(CryptoAllPermission.ALG_NAME);
394
if (pc == null) {
395
pc = perms.get(alg);
396
397
// If there isn't a PermissionCollection for
398
// the given algorithm,we should return the
399
// PermissionCollection for the wildcard
400
// if there is one.
401
if (pc == null) {
402
pc = perms.get(CryptoPermission.ALG_NAME_WILDCARD);
403
}
404
}
405
return pc;
406
}
407
408
/**
409
* Returns the PermissionCollection for the algorithm
410
* associated with the specified CryptoPermission
411
* object. Creates such a PermissionCollection
412
* if such a PermissionCollection does not
413
* exist yet.
414
*
415
* @param cryptoPerm the CryptoPermission object.
416
*/
417
private PermissionCollection getPermissionCollection(
418
CryptoPermission cryptoPerm) {
419
420
String alg = cryptoPerm.getAlgorithm();
421
422
PermissionCollection pc = perms.get(alg);
423
424
if (pc == null) {
425
pc = cryptoPerm.newPermissionCollection();
426
}
427
return pc;
428
}
429
430
private void readObject(ObjectInputStream s)
431
throws IOException, ClassNotFoundException {
432
ObjectInputStream.GetField fields = s.readFields();
433
@SuppressWarnings("unchecked")
434
Hashtable<String,PermissionCollection> permTable =
435
(Hashtable<String,PermissionCollection>)
436
(fields.get("perms", null));
437
if (permTable != null) {
438
perms = new ConcurrentHashMap<>(permTable);
439
} else {
440
perms = new ConcurrentHashMap<>();
441
}
442
}
443
444
private void writeObject(ObjectOutputStream s) throws IOException {
445
Hashtable<String,PermissionCollection> permTable =
446
new Hashtable<>(perms);
447
ObjectOutputStream.PutField fields = s.putFields();
448
fields.put("perms", permTable);
449
s.writeFields();
450
}
451
}
452
453
final class PermissionsEnumerator implements Enumeration<Permission> {
454
455
// all the perms
456
private Enumeration<PermissionCollection> perms;
457
// the current set
458
private Enumeration<Permission> permset;
459
460
PermissionsEnumerator(Enumeration<PermissionCollection> e) {
461
perms = e;
462
permset = getNextEnumWithMore();
463
}
464
465
public synchronized boolean hasMoreElements() {
466
// if we enter with permissionimpl null, we know
467
// there are no more left.
468
469
if (permset == null)
470
return false;
471
472
// try to see if there are any left in the current one
473
474
if (permset.hasMoreElements())
475
return true;
476
477
// get the next one that has something in it...
478
permset = getNextEnumWithMore();
479
480
// if it is null, we are done!
481
return (permset != null);
482
}
483
484
public synchronized Permission nextElement() {
485
// hasMoreElements will update permset to the next permset
486
// with something in it...
487
488
if (hasMoreElements()) {
489
return permset.nextElement();
490
} else {
491
throw new NoSuchElementException("PermissionsEnumerator");
492
}
493
}
494
495
private Enumeration<Permission> getNextEnumWithMore() {
496
while (perms.hasMoreElements()) {
497
PermissionCollection pc = perms.nextElement();
498
Enumeration<Permission> next = pc.elements();
499
if (next.hasMoreElements())
500
return next;
501
}
502
return null;
503
}
504
}
505
506