KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > crypto > CryptoPermissions


1 /*
2  * @(#)CryptoPermissions.java 1.14 04/01/06
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.crypto;
9
10 import java.security.*;
11 import java.util.Enumeration;
12 import java.util.Hashtable;
13 import java.util.Vector;
14 import java.util.NoSuchElementException;
15 import java.io.Serializable;
16 import java.io.InputStream;
17 import java.io.InputStreamReader;
18 import java.io.BufferedReader;
19 import java.io.IOException;
20
21 /**
22  * This class contains CryptoPermission objects, organized into
23  * PermissionCollections according to algorithm names.
24  *
25  * <p>When the <code>add</code> method is called to add a
26  * CryptoPermission, the CryptoPermission is stored in the
27  * appropriate PermissionCollection. If no such
28  * collection exists yet, the algorithm name associated with
29  * the CryptoPermission object is
30  * determined and the <code>newPermissionCollection</code> method
31  * is called on the CryptoPermission or CryptoAllPermission class to
32  * create the PermissionCollection and add it to the Permissions object.
33  *
34  * @see javax.crypto.CryptoPermission
35  * @see java.security.PermissionCollection
36  * @see java.security.Permissions
37  *
38  * @version 1.14 01/06/04
39  * @author Sharon Liu
40  * @since 1.4
41  */

42 final class CryptoPermissions extends PermissionCollection
43 implements Serializable {
44
45     private static final long serialVersionUID = 4946547168093391015L;
46
47     // This class is similar to java.security.Permissions
48
private Hashtable perms;
49
50     /**
51      * Creates a new CryptoPermissions object containing
52      * no CryptoPermissionCollections.
53      */

54     CryptoPermissions() {
55     perms = new Hashtable(7);
56     }
57
58     /**
59      * Populates the crypto policy from the specified
60      * InputStream into this CryptoPermissions object.
61      *
62      * @param in the InputStream to load from.
63      *
64      * @exception SecurityException if cannot load
65      * successfully.
66      */

67     void load(InputStream in)
68     throws IOException, CryptoPolicyParser.ParsingException {
69     CryptoPolicyParser parser = new CryptoPolicyParser();
70     parser.read(new BufferedReader(new InputStreamReader(in, "UTF-8")));
71     
72     CryptoPermission[] parsingResult = parser.getPermissions();
73     for (int i = 0; i < parsingResult.length; i++) {
74         this.add(parsingResult[i]);
75     }
76     }
77
78     /**
79      * Returns true if this CryptoPermissions object doesn't
80      * contain any CryptoPermission objects; otherwise, returns
81      * false.
82      */

83     boolean isEmpty() {
84     return perms.isEmpty();
85     }
86
87     /**
88      * Adds a permission object to the PermissionCollection for the
89      * algorithm returned by
90      * <code>(CryptoPermission)permission.getAlgorithm()</code>.
91      *
92      * This method creates
93      * a new PermissionCollection object (and adds the permission to it)
94      * if an appropriate collection does not yet exist. <p>
95      *
96      * @param permission the Permission object to add.
97      *
98      * @exception SecurityException if this CryptoPermissions object is
99      * marked as readonly.
100      *
101      * @see isReadOnly
102      */

103     public void add(Permission permission) {
104
105     if (isReadOnly())
106         throw new SecurityException("Attempt to add a Permission " +
107                     "to a readonly CryptoPermissions " +
108                     "object");
109
110         if (!(permission instanceof CryptoPermission))
111             return;
112
113         CryptoPermission cryptoPerm = (CryptoPermission)permission;
114     PermissionCollection pc =
115                     getPermissionCollection(cryptoPerm);
116     pc.add(cryptoPerm);
117     String alg = cryptoPerm.getAlgorithm();
118     if (!perms.containsKey(alg)) {
119         perms.put(alg, pc);
120     }
121     }
122
123     /**
124      * Checks if this object's PermissionCollection for permissons
125      * of the specified permission's algorithm implies the specified
126      * permission. Returns true if the checking succeeded.
127      *
128      * @param permission the Permission object to check.
129      *
130      * @return true if "permission" is implied by the permissions
131      * in the PermissionCollection it belongs to, false if not.
132      *
133      */

134     public boolean implies(Permission permission) {
135     if (!(permission instanceof CryptoPermission)) {
136         return false;
137     }
138
139     CryptoPermission cryptoPerm = (CryptoPermission)permission;
140
141     PermissionCollection pc =
142         getPermissionCollection(cryptoPerm.getAlgorithm());
143     return pc.implies(cryptoPerm);
144     }
145
146     /**
147      * Returns an enumeration of all the Permission objects in all the
148      * PermissionCollections in this CryptoPermissions object.
149      *
150      * @return an enumeration of all the Permissions.
151      */

152     public Enumeration elements() {
153     // go through each Permissions in the hash table
154
// and call their elements() function.
155
return new PermissionsEnumerator(perms.elements());
156     }
157
158     /**
159      * Returns a CryptoPermissions object which
160      * represents the minimum of the specified
161      * CryptoPermissions object and this
162      * CryptoPermissions object.
163      *
164      * @param other the CryptoPermission
165      * object to compare with this object.
166      */

167     CryptoPermissions getMinimum(CryptoPermissions other) {
168     if (other == null) {
169         return null;
170     }
171
172     if (this.perms.containsKey(CryptoAllPermission.ALG_NAME)) {
173         return other;
174     }
175
176     if (other.perms.containsKey(CryptoAllPermission.ALG_NAME)) {
177         return this;
178     }
179
180     CryptoPermissions ret = new CryptoPermissions();
181
182     
183     PermissionCollection thatWildcard =
184         (PermissionCollection)other.perms.get(
185                         CryptoPermission.ALG_NAME_WILDCARD);
186     int maxKeySize = 0;
187     if (thatWildcard != null) {
188         maxKeySize = ((CryptoPermission)
189             thatWildcard.elements().nextElement()).getMaxKeySize();
190     }
191     // For each algorithm in this CryptoPermissions,
192
// find out if there is anything we should add into
193
// ret.
194
Enumeration thisKeys = this.perms.keys();
195     while (thisKeys.hasMoreElements()) {
196         String alg = (String)thisKeys.nextElement();
197
198         PermissionCollection thisPc =
199         (PermissionCollection)this.perms.get(alg);
200         PermissionCollection thatPc =
201         (PermissionCollection)other.perms.get(alg);
202         
203         CryptoPermission[] partialResult;
204
205         if (thatPc == null) {
206         if (thatWildcard == null) {
207             // The other CryptoPermissions
208
// doesn't allow this given
209
// algorithm at all. Just skip this
210
// algorithm.
211
continue;
212         }
213         partialResult = getMinimum(maxKeySize, thisPc);
214         } else {
215         partialResult = getMinimum(thisPc, thatPc);
216         }
217
218         for (int i = 0; i < partialResult.length; i++) {
219         ret.add(partialResult[i]);
220         }
221     }
222     
223     PermissionCollection thisWildcard =
224         (PermissionCollection)this.perms.get(
225                       CryptoPermission.ALG_NAME_WILDCARD);
226
227     // If this CryptoPermissions doesn't
228
// have a wildcard, we are done.
229
if (thisWildcard == null) {
230         return ret;
231     }
232
233     // Deal with the algorithms only appear
234
// in the other CryptoPermissions.
235
maxKeySize =
236         ((CryptoPermission)
237             thisWildcard.elements().nextElement()).getMaxKeySize();
238     Enumeration thatKeys = other.perms.keys();
239     while (thatKeys.hasMoreElements()) {
240         String alg = (String)thatKeys.nextElement();
241
242         if (this.perms.containsKey(alg)) {
243         continue;
244         }
245
246         PermissionCollection thatPc =
247         (PermissionCollection)other.perms.get(alg);
248
249         CryptoPermission[] partialResult;
250         
251         partialResult = getMinimum(maxKeySize, thatPc);
252
253         for (int i = 0; i < partialResult.length; i++) {
254         ret.add(partialResult[i]);
255         }
256     }
257     return ret;
258     }
259
260     /**
261      * Get the minimum of the two given PermissionCollection
262      * <code>thisPc</code> and <code>thatPc</code>.
263      *
264      * @param thisPc the first given PermissionColloection
265      * object.
266      *
267      * @param thatPc the second given PermissionCollection
268      * object.
269      */

270     private CryptoPermission[] getMinimum(PermissionCollection thisPc,
271                       PermissionCollection thatPc) {
272     Vector permVector = new Vector(2);
273
274     Enumeration thisPcPermissions = thisPc.elements();
275
276     // For each CryptoPermission in
277
// thisPc object, do the following:
278
// 1) if this CryptoPermission is implied
279
// by thatPc, this CryptoPermission
280
// should be returned, and we can
281
// move on to check the next
282
// CryptoPermission in thisPc.
283
// 2) otherwise, we should return
284
// all CryptoPermissions in thatPc
285
// which
286
// are implied by this CryptoPermission.
287
// Then we can move on to the
288
// next CryptoPermission in thisPc.
289
while (thisPcPermissions.hasMoreElements()) {
290         CryptoPermission thisCp =
291         (CryptoPermission)thisPcPermissions.nextElement();
292
293         Enumeration thatPcPermissions = thatPc.elements();
294         while (thatPcPermissions.hasMoreElements()) {
295         CryptoPermission thatCp =
296             (CryptoPermission)thatPcPermissions.nextElement();
297
298         if (thatCp.implies(thisCp)) {
299             permVector.addElement(thisCp);
300             break;
301         }
302         if (thisCp.implies(thatCp)) {
303             permVector.addElement(thatCp);
304         }
305         }
306     }
307
308     CryptoPermission[] ret = new CryptoPermission[permVector.size()];
309     permVector.copyInto(ret);
310     return ret;
311     }
312
313     /**
314      * Returns all the CryptoPermission objects in the given
315      * PermissionCollection object
316      * whose maximum keysize no greater than <code>maxKeySize</code>.
317      * For all CryptoPermission objects with a maximum keysize greater
318      * than <code>maxKeySize</code>, this method constructs a
319      * corresponding CryptoPermission object whose maximum keysize is
320      * set to <code>maxKeySize</code>, and includes that in the result.
321      *
322      * @param maxKeySize the given maximum key size.
323      *
324      * @param pc the given PermissionCollection object.
325      */

326     private CryptoPermission[] getMinimum(int maxKeySize,
327                       PermissionCollection pc) {
328     Vector permVector = new Vector(1);
329
330     Enumeration enum_ = pc.elements();
331
332     while (enum_.hasMoreElements()) {
333         CryptoPermission cp =
334         (CryptoPermission)enum_.nextElement();
335         if (cp.getMaxKeySize() <= maxKeySize) {
336         permVector.addElement(cp);
337         } else {
338         if (cp.getCheckParam()) {
339             permVector.addElement(
340                new CryptoPermission(cp.getAlgorithm(),
341                         maxKeySize,
342                         cp.getAlgorithmParameterSpec(),
343                         cp.getExemptionMechanism()));
344         } else {
345             permVector.addElement(
346                            new CryptoPermission(cp.getAlgorithm(),
347                                                 maxKeySize,
348                                                 cp.getExemptionMechanism()));
349         }
350         }
351     }
352
353     CryptoPermission[] ret = new CryptoPermission[permVector.size()];
354     permVector.copyInto(ret);
355     return ret;
356     }
357
358     /**
359      * Returns the PermissionCollection for the
360      * specified algorithm. Returns null if there
361      * isn't such a PermissionCollection.
362      *
363      * @param alg the algorithm name.
364      */

365     PermissionCollection getPermissionCollection(String alg) {
366     // If this CryptoPermissions includes CryptoAllPermission,
367
// we should return CryptoAllPermission.
368
if (perms.containsKey(CryptoAllPermission.ALG_NAME)) {
369         return
370         (PermissionCollection)(perms.get(CryptoAllPermission.ALG_NAME));
371     }
372
373     PermissionCollection pc = (PermissionCollection)perms.get(alg);
374
375     // If there isn't a PermissionCollection for
376
// the given algorithm,we should return the
377
// PermissionCollection for the wildcard
378
// if there is one.
379
if (pc == null) {
380         pc = (PermissionCollection)perms.get(
381                        CryptoPermission.ALG_NAME_WILDCARD);
382     }
383     return pc;
384     }
385
386     /**
387      * Returns the PermissionCollection for the algorithm
388      * associated with the specified CryptoPermission
389      * object. Creates such a PermissionCollection
390      * if such a PermissionCollection does not
391      * exist yet.
392      *
393      * @param cryptoPerm the CryptoPermission object.
394      */

395     private PermissionCollection getPermissionCollection(
396                       CryptoPermission cryptoPerm) {
397     
398     String alg = cryptoPerm.getAlgorithm();
399
400     PermissionCollection pc = (PermissionCollection)perms.get(alg);
401
402     if (pc == null) {
403         pc = cryptoPerm.newPermissionCollection();
404     }
405     return pc;
406     }
407 }
408
409 final class PermissionsEnumerator implements Enumeration {
410
411     // all the perms
412
private Enumeration perms;
413     // the current set
414
private Enumeration permset;
415    
416     PermissionsEnumerator(Enumeration e) {
417     perms = e;
418     permset = getNextEnumWithMore();
419     }
420
421     public synchronized boolean hasMoreElements() {
422     // if we enter with permissionimpl null, we know
423
// there are no more left.
424

425     if (permset == null)
426         return false;
427
428     // try to see if there are any left in the current one
429

430     if (permset.hasMoreElements())
431         return true;
432
433     // get the next one that has something in it...
434
permset = getNextEnumWithMore();
435
436     // if it is null, we are done!
437
return (permset != null);
438     }
439
440     public synchronized Object nextElement() {
441     // hasMoreElements will update permset to the next permset
442
// with something in it...
443

444     if (hasMoreElements()) {
445         return permset.nextElement();
446     } else {
447         throw new NoSuchElementException("PermissionsEnumerator");
448     }
449
450     }
451   
452     private Enumeration getNextEnumWithMore() {
453     while (perms.hasMoreElements()) {
454         PermissionCollection pc =
455         (PermissionCollection) perms.nextElement();
456         Enumeration next = pc.elements();
457         if (next.hasMoreElements())
458         return next;
459     }
460     return null;
461     }
462 }
463
Popular Tags