blob: 43cba10ac8cb658cb7a72554ca5c4a71602ca895 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1999-2007 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package javax.crypto;
27
28import java.security.*;
29import java.security.spec.AlgorithmParameterSpec;
30import java.io.Serializable;
31import java.util.Enumeration;
32import java.util.Vector;
33
34import javax.crypto.spec.*;
35
36/**
37 * The CryptoPermission class extends the
38 * java.security.Permission class. A
39 * CryptoPermission object is used to represent
40 * the ability of an application/applet to use certain
41 * algorithms with certain key sizes and other
42 * restrictions in certain environments. <p>
43 *
44 * @see java.security.Permission
45 *
46 * @author Jan Luehe
47 * @author Sharon Liu
48 * @since 1.4
49 */
50class CryptoPermission extends java.security.Permission {
51
52 private static final long serialVersionUID = 8987399626114087514L;
53
54 private String alg;
55 private int maxKeySize = Integer.MAX_VALUE; // no restriction on maxKeySize
56 private String exemptionMechanism = null;
57 private AlgorithmParameterSpec algParamSpec = null;
58 private boolean checkParam = false; // no restriction on param
59
60 static final String ALG_NAME_WILDCARD = "*";
61
62 /**
63 * Constructor that takes an algorithm name.
64 *
65 * This constructor implies that the given algorithm can be
66 * used without any restrictions.
67 *
68 * @param alg the algorithm name.
69 */
70 CryptoPermission(String alg) {
71 super(null);
72 this.alg = alg;
73 }
74
75 /**
76 * Constructor that takes an algorithm name and a maximum
77 * key size.
78 *
79 * This constructor implies that the given algorithm can be
80 * used with a key size up to <code>maxKeySize</code>.
81 *
82 * @param alg the algorithm name.
83 *
84 * @param maxKeySize the maximum allowable key size,
85 * specified in number of bits.
86 */
87 CryptoPermission(String alg, int maxKeySize) {
88 super(null);
89 this.alg = alg;
90 this.maxKeySize = maxKeySize;
91 }
92
93 /**
94 * Constructor that takes an algorithm name, a maximum
95 * key size, and an AlgorithmParameterSpec object.
96 *
97 * This constructor implies that the given algorithm can be
98 * used with a key size up to <code>maxKeySize</code>, and
99 * algorithm
100 * parameters up to the limits set in <code>algParamSpec</code>.
101 *
102 * @param alg the algorithm name.
103 *
104 * @param maxKeySize the maximum allowable key size,
105 * specified in number of bits.
106 *
107 * @param algParamSpec the limits for allowable algorithm
108 * parameters.
109 */
110 CryptoPermission(String alg,
111 int maxKeySize,
112 AlgorithmParameterSpec algParamSpec) {
113 super(null);
114 this.alg = alg;
115 this.maxKeySize = maxKeySize;
116 this.checkParam = true;
117 this.algParamSpec = algParamSpec;
118 }
119
120 /**
121 * Constructor that takes an algorithm name and the name of
122 * an exemption mechanism.
123 *
124 * This constructor implies that the given algorithm can be
125 * used without any key size or algorithm parameter restrictions
126 * provided that the specified exemption mechanism is enforced.
127 *
128 * @param alg the algorithm name.
129 *
130 * @param exemptionMechanism the name of the exemption mechanism.
131 */
132 CryptoPermission(String alg,
133 String exemptionMechanism) {
134 super(null);
135 this.alg = alg;
136 this.exemptionMechanism = exemptionMechanism;
137 }
138
139 /**
140 * Constructor that takes an algorithm name, a maximum key
141 * size, and the name of an exemption mechanism.
142 *
143 * This constructor implies that the given algorithm can be
144 * used with a key size up to <code>maxKeySize</code>
145 * provided that the
146 * specified exemption mechanism is enforced.
147 *
148 * @param alg the algorithm name.
149 * @param maxKeySize the maximum allowable key size,
150 * specified in number of bits.
151 * @param exemptionMechanism the name of the exemption
152 * mechanism.
153 */
154 CryptoPermission(String alg,
155 int maxKeySize,
156 String exemptionMechanism) {
157 super(null);
158 this.alg = alg;
159 this.exemptionMechanism = exemptionMechanism;
160 this.maxKeySize = maxKeySize;
161 }
162
163 /**
164 * Constructor that takes an algorithm name, a maximum key
165 * size, the name of an exemption mechanism, and an
166 * AlgorithmParameterSpec object.
167 *
168 * This constructor implies that the given algorithm can be
169 * used with a key size up to <code>maxKeySize</code>
170 * and algorithm
171 * parameters up to the limits set in <code>algParamSpec</code>
172 * provided that
173 * the specified exemption mechanism is enforced.
174 *
175 * @param alg the algorithm name.
176 * @param maxKeySize the maximum allowable key size,
177 * specified in number of bits.
178 * @param algParamSpec the limit for allowable algorithm
179 * parameter spec.
180 * @param exemptionMechanism the name of the exemption
181 * mechanism.
182 */
183 CryptoPermission(String alg,
184 int maxKeySize,
185 AlgorithmParameterSpec algParamSpec,
186 String exemptionMechanism) {
187 super(null);
188 this.alg = alg;
189 this.exemptionMechanism = exemptionMechanism;
190 this.maxKeySize = maxKeySize;
191 this.checkParam = true;
192 this.algParamSpec = algParamSpec;
193 }
194
195 /**
196 * Checks if the specified permission is "implied" by
197 * this object.
198 * <p>
199 * More specifically, this method returns true if:<p>
200 * <ul>
201 * <li> <i>p</i> is an instance of CryptoPermission, and<p>
202 * <li> <i>p</i>'s algorithm name equals or (in the case of wildcards)
203 * is implied by this permission's algorithm name, and<p>
204 * <li> <i>p</i>'s maximum allowable key size is less or
205 * equal to this permission's maximum allowable key size, and<p>
206 * <li> <i>p</i>'s algorithm parameter spec equals or is
207 * implied by this permission's algorithm parameter spec, and<p>
208 * <li> <i>p</i>'s exemptionMechanism equals or
209 * is implied by this permission's
210 * exemptionMechanism (a <code>null</code> exemption mechanism
211 * implies any other exemption mechanism).
212 * </ul>
213 *
214 * @param p the permission to check against.
215 *
216 * @return true if the specified permission is equal to or
217 * implied by this permission, false otherwise.
218 */
219 public boolean implies(Permission p) {
220 if (!(p instanceof CryptoPermission))
221 return false;
222
223 CryptoPermission cp = (CryptoPermission)p;
224
225 if ((!alg.equalsIgnoreCase(cp.alg)) &&
226 (!alg.equalsIgnoreCase(ALG_NAME_WILDCARD))) {
227 return false;
228 }
229
230 // alg is the same as cp's alg or
231 // alg is a wildcard.
232 if (cp.maxKeySize <= this.maxKeySize) {
233 // check algParamSpec.
234 if (!impliesParameterSpec(cp.checkParam, cp.algParamSpec)) {
235 return false;
236 }
237
238 // check exemptionMechanism.
239 if (impliesExemptionMechanism(cp.exemptionMechanism)) {
240 return true;
241 }
242 }
243
244 return false;
245 }
246
247 /**
248 * Checks two CryptoPermission objects for equality. Checks that
249 * <code>obj</code> is a CryptoPermission, and has the same
250 * algorithm name,
251 * exemption mechanism name, maximum allowable key size and
252 * algorithm parameter spec
253 * as this object.
254 * <P>
255 * @param obj the object to test for equality with this object.
256 * @return true if <code>obj</code> is equal to this object.
257 */
258 public boolean equals(Object obj) {
259 if (obj == this)
260 return true;
261
262 if (!(obj instanceof CryptoPermission))
263 return false;
264
265 CryptoPermission that = (CryptoPermission) obj;
266
267 if (!(alg.equalsIgnoreCase(that.alg)) ||
268 (maxKeySize != that.maxKeySize)) {
269 return false;
270 }
271 if (this.checkParam != that.checkParam) {
272 return false;
273 }
274 return (equalObjects(this.exemptionMechanism,
275 that.exemptionMechanism) &&
276 equalObjects(this.algParamSpec,
277 that.algParamSpec));
278 }
279
280 /**
281 * Returns the hash code value for this object.
282 *
283 * @return a hash code value for this object.
284 */
285
286 public int hashCode() {
287 int retval = alg.hashCode();
288 retval ^= maxKeySize;
289 if (exemptionMechanism != null) {
290 retval ^= exemptionMechanism.hashCode();
291 }
292 if (checkParam) retval ^= 100;
293 if (algParamSpec != null) {
294 retval ^= algParamSpec.hashCode();
295 }
296 return retval;
297 }
298
299 /**
300 * There is no action defined for a CryptoPermission
301 * onject.
302 */
303 public String getActions()
304 {
305 return null;
306 }
307
308 /**
309 * Returns a new PermissionCollection object for storing
310 * CryptoPermission objects.
311 *
312 * @return a new PermissionCollection object suitable for storing
313 * CryptoPermissions.
314 */
315
316 public PermissionCollection newPermissionCollection() {
317 return new CryptoPermissionCollection();
318 }
319
320 /**
321 * Returns the algorithm name associated with
322 * this CryptoPermission object.
323 */
324 final String getAlgorithm() {
325 return alg;
326 }
327
328 /**
329 * Returns the exemption mechanism name
330 * associated with this CryptoPermission
331 * object.
332 */
333 final String getExemptionMechanism() {
334 return exemptionMechanism;
335 }
336
337 /**
338 * Returns the maximum allowable key size associated
339 * with this CryptoPermission object.
340 */
341 final int getMaxKeySize() {
342 return maxKeySize;
343 }
344
345 /**
346 * Returns true if there is a limitation on the
347 * AlgorithmParameterSpec associated with this
348 * CryptoPermission object and false if otherwise.
349 */
350 final boolean getCheckParam() {
351 return checkParam;
352 }
353
354 /**
355 * Returns the AlgorithmParameterSpec
356 * associated with this CryptoPermission
357 * object.
358 */
359 final AlgorithmParameterSpec getAlgorithmParameterSpec() {
360 return algParamSpec;
361 }
362
363 /**
364 * Returns a string describing this CryptoPermission. The convention is to
365 * specify the class name, the algorithm name, the maximum allowable
366 * key size, and the name of the exemption mechanism, in the following
367 * format: '("ClassName" "algorithm" "keysize" "exemption_mechanism")'.
368 *
369 * @return information about this CryptoPermission.
370 */
371 public String toString() {
372 StringBuilder buf = new StringBuilder(100);
373 buf.append("(CryptoPermission " + alg + " " + maxKeySize);
374 if (algParamSpec != null) {
375 if (algParamSpec instanceof RC2ParameterSpec) {
376 buf.append(" , effective " +
377 ((RC2ParameterSpec)algParamSpec).getEffectiveKeyBits());
378 } else if (algParamSpec instanceof RC5ParameterSpec) {
379 buf.append(" , rounds " +
380 ((RC5ParameterSpec)algParamSpec).getRounds());
381 }
382 }
383 if (exemptionMechanism != null) { // OPTIONAL
384 buf.append(" " + exemptionMechanism);
385 }
386 buf.append(")");
387 return buf.toString();
388 }
389
390 private boolean impliesExemptionMechanism(String exemptionMechanism) {
391 if (this.exemptionMechanism == null) {
392 return true;
393 }
394
395 if (exemptionMechanism == null) {
396 return false;
397 }
398
399 if (this.exemptionMechanism.equals(exemptionMechanism)) {
400 return true;
401 }
402
403 return false;
404 }
405
406 private boolean impliesParameterSpec(boolean checkParam,
407 AlgorithmParameterSpec algParamSpec) {
408 if ((this.checkParam) && checkParam) {
409 if (algParamSpec == null) {
410 return true;
411 } else if (this.algParamSpec == null) {
412 return false;
413 }
414
415 if (this.algParamSpec.getClass() != algParamSpec.getClass()) {
416 return false;
417 }
418
419 if (algParamSpec instanceof RC2ParameterSpec) {
420 if (((RC2ParameterSpec)algParamSpec).getEffectiveKeyBits() <=
421 ((RC2ParameterSpec)
422 (this.algParamSpec)).getEffectiveKeyBits()) {
423 return true;
424 }
425 }
426
427 if (algParamSpec instanceof RC5ParameterSpec) {
428 if (((RC5ParameterSpec)algParamSpec).getRounds() <=
429 ((RC5ParameterSpec)this.algParamSpec).getRounds()) {
430 return true;
431 }
432 }
433
434 if (algParamSpec instanceof PBEParameterSpec) {
435 if (((PBEParameterSpec)algParamSpec).getIterationCount() <=
436 ((PBEParameterSpec)this.algParamSpec).getIterationCount()) {
437 return true;
438 }
439 }
440
441 // For classes we don't know, the following
442 // may be the best try.
443 if (this.algParamSpec.equals(algParamSpec)) {
444 return true;
445 }
446 return false;
447 } else if (this.checkParam) {
448 return false;
449 } else {
450 return true;
451 }
452 }
453
454 private boolean equalObjects(Object obj1, Object obj2) {
455 if (obj1 == null) {
456 return (obj2 == null ? true : false);
457 }
458
459 return obj1.equals(obj2);
460 }
461}
462
463/**
464 * A CryptoPermissionCollection stores a set of CryptoPermission
465 * permissions.
466 *
467 * @see java.security.Permission
468 * @see java.security.Permissions
469 * @see java.security.PermissionCollection
470 *
471 * @author Sharon Liu
472 */
473final class CryptoPermissionCollection extends PermissionCollection
474implements Serializable {
475
476 private static final long serialVersionUID = -511215555898802763L;
477
478 private Vector permissions;
479
480 /**
481 * Creates an empty CryptoPermissionCollection
482 * object.
483 */
484 CryptoPermissionCollection() {
485 permissions = new Vector(3);
486 }
487
488 /**
489 * Adds a permission to the CryptoPermissionCollection.
490 *
491 * @param permission the Permission object to add.
492 *
493 * @exception SecurityException - if this CryptoPermissionCollection
494 * object has been marked <i>readOnly</i>.
495 */
496 public void add(Permission permission)
497 {
498 if (isReadOnly())
499 throw new SecurityException("attempt to add a Permission " +
500 "to a readonly PermissionCollection");
501
502 if (!(permission instanceof CryptoPermission))
503 return;
504
505 permissions.addElement(permission);
506 }
507
508 /**
509 * Check and see if this CryptoPermission object implies
510 * the given Permission object.
511 *
512 * @param p the Permission object to compare
513 *
514 * @return true if the given permission is implied by this
515 * CryptoPermissionCollection, false if not.
516 */
517 public boolean implies(Permission permission) {
518 if (!(permission instanceof CryptoPermission))
519 return false;
520
521 CryptoPermission cp = (CryptoPermission)permission;
522
523 Enumeration e = permissions.elements();
524
525 while (e.hasMoreElements()) {
526 CryptoPermission x = (CryptoPermission) e.nextElement();
527 if (x.implies(cp)) {
528 return true;
529 }
530 }
531 return false;
532 }
533
534 /**
535 * Returns an enumeration of all the CryptoPermission objects
536 * in the container.
537 *
538 * @return an enumeration of all the CryptoPermission objects.
539 */
540
541 public Enumeration elements()
542 {
543 return permissions.elements();
544 }
545}