KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > crypto > JceSecurityManager


1 /*
2  * @(#)JceSecurityManager.java 1.17 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.net.*;
12 import java.util.*;
13 import java.util.jar.*;
14
15 /**
16  * The JCE security manager.
17  *
18  * <p>The JCE security manager is responsible for determining the maximum
19  * allowable cryptographic strength for a given applet/application, for a given
20  * algorithm, by consulting the configured jurisdiction policy files and
21  * the cryptographic permissions bundled with the applet/application.
22  *
23  * <p>Note that this security manager is never installed, only instantiated.
24  *
25  * @author Jan Luehe
26  * @version 1.17, 01/06/04
27  *
28  * @since 1.4
29  */

30
31 final class JceSecurityManager extends SecurityManager {
32
33     private static final String permsFile = "cryptoPerms";
34     private static final CryptoPermissions defaultPolicy;
35     private static final CryptoPermissions exemptPolicy;
36     private static final CryptoAllPermission allPerm;
37     private static final Vector TrustedCallersCache = new Vector(2);
38     private static final Map exemptCache = new HashMap();
39     
40     // singleton instance
41
static final JceSecurityManager INSTANCE;
42
43     static {
44     defaultPolicy = JceSecurity.getDefaultPolicy();
45     exemptPolicy = JceSecurity.getExemptPolicy();
46     allPerm = CryptoAllPermission.INSTANCE;
47     INSTANCE = (JceSecurityManager)
48           AccessController.doPrivileged(new PrivilegedAction() {
49           public Object run() {
50               return new JceSecurityManager();
51           }
52           });
53     }
54     
55     private JceSecurityManager() {
56     // empty
57
}
58
59     /**
60      * Returns the maximum allowable crypto strength for the given
61      * applet/application, for the given algorithm.
62      */

63     CryptoPermission getCryptoPermission(String alg) {
64
65     // If CryptoAllPermission is granted by default, we return that.
66
// Otherwise, this will be the permission we return if anything goes
67
// wrong.
68
CryptoPermission defaultPerm = getDefaultPermission(alg);
69     if (defaultPerm == CryptoAllPermission.INSTANCE) {
70         return defaultPerm;
71     }
72
73     // Determine the codebase of the caller of the JCE API.
74
// This is the codebase of the first class which is not in
75
// javax.crypto.* packages.
76
// NOTE: javax.crypto.* package maybe subject to package
77
// insertion, so need to check its classloader as well.
78
Class[] context = getClassContext();
79     URL callerCodeBase = null;
80     int i;
81     for (i=0; i<context.length; i++) {
82         Class cls = context[i];
83         callerCodeBase = JceSecurity.getCodeBase(cls);
84         if (callerCodeBase != null) {
85         break;
86         } else {
87         if (cls.getName().startsWith("javax.crypto.")) {
88             // skip jce classes since they aren't the callers
89
continue;
90         }
91         // use default permission when the caller is system classes
92
return defaultPerm;
93         }
94     }
95
96     if (i == context.length) {
97         return defaultPerm;
98     }
99     
100     CryptoPermissions appPerms;
101     synchronized (this.getClass()) {
102         if (exemptCache.containsKey(callerCodeBase)) {
103         appPerms = (CryptoPermissions)exemptCache.get(callerCodeBase);
104         } else {
105         appPerms = getAppPermissions(callerCodeBase);
106         exemptCache.put(callerCodeBase, appPerms);
107         }
108     }
109     
110     if (appPerms == null) {
111         return defaultPerm;
112     }
113     
114     // If the app was granted the special CryptoAllPermission, return that.
115
if (appPerms.implies(allPerm)) {
116         return allPerm;
117     }
118
119     // Check if the crypto permissions granted to the app contain a
120
// crypto permission for the requested algorithm that does not require
121
// any exemption mechanism to be enforced.
122
// Return that permission, if present.
123
PermissionCollection appPc = appPerms.getPermissionCollection(alg);
124     if (appPc == null) {
125         return defaultPerm;
126     }
127     Enumeration enum_ = appPc.elements();
128     while (enum_.hasMoreElements()) {
129         CryptoPermission cp = (CryptoPermission)enum_.nextElement();
130         if (cp.getExemptionMechanism() == null) {
131         return cp;
132         }
133     }
134
135     // Check if the jurisdiction file for exempt applications contains
136
// any entries for the requested algorithm.
137
// If not, return the default permission.
138
PermissionCollection exemptPc =
139         exemptPolicy.getPermissionCollection(alg);
140     if (exemptPc == null) {
141         return defaultPerm;
142     }
143
144     // In the jurisdiction file for exempt applications, go through the
145
// list of CryptoPermission entries for the requested algorithm, and
146
// stop at the first entry:
147
// - that is implied by the collection of crypto permissions granted
148
// to the app, and
149
// - whose exemption mechanism is available from one of the
150
// registered CSPs
151
enum_ = exemptPc.elements();
152     while (enum_.hasMoreElements()) {
153         CryptoPermission cp = (CryptoPermission)enum_.nextElement();
154         try {
155         ExemptionMechanism.getInstance(cp.getExemptionMechanism());
156         if (cp.getAlgorithm().equals(
157                       CryptoPermission.ALG_NAME_WILDCARD)) {
158             CryptoPermission newCp;
159             if (cp.getCheckParam()) {
160                 newCp = new CryptoPermission(
161                         alg, cp.getMaxKeySize(),
162                     cp.getAlgorithmParameterSpec(),
163                                 cp.getExemptionMechanism());
164             } else {
165             newCp = new CryptoPermission(
166                                 alg, cp.getMaxKeySize(),
167                                 cp.getExemptionMechanism());
168             }
169             if (appPerms.implies(newCp)) {
170             return newCp;
171             }
172         }
173
174         if (appPerms.implies(cp)) {
175             return cp;
176         }
177         } catch (Exception e) {
178         continue;
179         }
180     }
181     return defaultPerm;
182     }
183     
184     private static CryptoPermissions getAppPermissions(URL callerCodeBase) {
185     // Check if app is exempt, and retrieve the permissions bundled with it
186
JarFile jf;
187     try {
188         jf = JceSecurity.verifyExemptJar(callerCodeBase);
189     } catch (Exception e) {
190         return null;
191     }
192     JarEntry je = jf.getJarEntry(permsFile);
193     if (je == null) {
194         // app is not exempt
195
return null;
196     }
197
198     //
199
// Applet/application is exempt
200
//
201

202     CryptoPermissions appPerms = new CryptoPermissions();
203     try {
204         appPerms.load(jf.getInputStream(je));
205     } catch (Exception e) {
206         return null;
207     }
208
209     jf = null;
210
211     return appPerms;
212     }
213
214     /**
215      * Returns the default permission for the given algorithm.
216      */

217     private CryptoPermission getDefaultPermission(String alg) {
218     Enumeration enum_ =
219         defaultPolicy.getPermissionCollection(alg).elements();
220     return (CryptoPermission)enum_.nextElement();
221     }
222
223     // See bug 4341369 & 4334690 for more info.
224
boolean isCallerTrusted() {
225     // Get the caller and its codebase.
226
Class[] context = getClassContext();
227     URL callerCodeBase = null;
228     int i;
229     for (i=0; i<context.length; i++) {
230         callerCodeBase = JceSecurity.getCodeBase(context[i]);
231         if (callerCodeBase != null) {
232         break;
233         }
234     }
235     // The caller is in the JCE framework.
236
if (i == context.length) {
237         return true;
238     }
239     //The caller has been verified.
240
if (TrustedCallersCache.contains(context[i])) {
241         return true;
242     }
243     // Check whether the caller is a trusted provider.
244
try {
245         JceSecurity.verifyProviderJar(callerCodeBase);
246     } catch (Exception e2) {
247         return false;
248     }
249     TrustedCallersCache.addElement(context[i]);
250     return true;
251     }
252 }
253
Popular Tags