59 // value is failure cause Exception in error case
60 private final static Map<Provider, Object> verificationResults =
61 new IdentityHashMap<>();
62
63 // Map<Provider,?> of the providers currently being verified
64 private final static Map<Provider, Object> verifyingProviders =
65 new IdentityHashMap<>();
66
67 // Set the default value. May be changed in the static initializer.
68 private static boolean isRestricted = true;
69
70 /*
71 * Don't let anyone instantiate this.
72 */
73 private JceSecurity() {
74 }
75
76 static {
77 try {
78 AccessController.doPrivileged(
79 new PrivilegedExceptionAction<Object>() {
80 public Object run() throws Exception {
81 setupJurisdictionPolicies();
82 return null;
83 }
84 });
85
86 isRestricted = defaultPolicy.implies(
87 CryptoAllPermission.INSTANCE) ? false : true;
88 } catch (Exception e) {
89 throw new SecurityException(
90 "Can not initialize cryptographic mechanism", e);
91 }
92 }
93
94 static Instance getInstance(String type, Class<?> clazz, String algorithm,
95 String provider) throws NoSuchAlgorithmException,
96 NoSuchProviderException {
97 Service s = GetInstance.getService(type, algorithm, provider);
98 Exception ve = getVerificationResult(s.getProvider());
99 if (ve != null) {
100 String msg = "JCE cannot authenticate the provider " + provider;
101 throw (NoSuchProviderException)
102 new NoSuchProviderException(msg).initCause(ve);
103 }
126 continue;
127 }
128 try {
129 Instance instance = GetInstance.getInstance(s, clazz);
130 return instance;
131 } catch (NoSuchAlgorithmException e) {
132 failure = e;
133 }
134 }
135 throw new NoSuchAlgorithmException("Algorithm " + algorithm
136 + " not available", failure);
137 }
138
139 /**
140 * Verify if the JAR at URL codeBase is a signed exempt application
141 * JAR file and returns the permissions bundled with the JAR.
142 *
143 * @throws Exception on error
144 */
145 static CryptoPermissions verifyExemptJar(URL codeBase) throws Exception {
146 JarVerifier jv = new JarVerifier(codeBase, true);
147 jv.verify();
148 return jv.getPermissions();
149 }
150
151 /**
152 * Verify if the JAR at URL codeBase is a signed provider JAR file.
153 *
154 * @throws Exception on error
155 */
156 static void verifyProviderJar(URL codeBase) throws Exception {
157 // Verify the provider JAR file and all
158 // supporting JAR files if there are any.
159 JarVerifier jv = new JarVerifier(codeBase, false);
160 jv.verify();
161 }
162
163 private final static Object PROVIDER_VERIFIED = Boolean.TRUE;
164
165 /*
166 * Verify that the provider JAR files are signed properly, which
167 * means the signer's certificate can be traced back to a
168 * JCE trusted CA.
169 * Return null if ok, failure Exception if verification failed.
170 */
171 static synchronized Exception getVerificationResult(Provider p) {
172 Object o = verificationResults.get(p);
173 if (o == PROVIDER_VERIFIED) {
174 return null;
175 } else if (o != null) {
176 return (Exception)o;
177 }
178 if (verifyingProviders.get(p) != null) {
179 // this method is static synchronized, must be recursion
180 // return failure now but do not save the result
181 return new NoSuchProviderException("Recursion during verification");
182 }
183 try {
184 verifyingProviders.put(p, Boolean.FALSE);
185 URL providerURL = getCodeBase(p.getClass());
186 verifyProviderJar(providerURL);
187 // Verified ok, cache result
188 verificationResults.put(p, PROVIDER_VERIFIED);
189 return null;
190 } catch (Exception e) {
191 verificationResults.put(p, e);
192 return e;
193 } finally {
194 verifyingProviders.remove(p);
195 }
196 }
197
198 // return whether this provider is properly signed and can be used by JCE
199 static boolean canUseProvider(Provider p) {
200 return getVerificationResult(p) == null;
201 }
202
203 // dummy object to represent null
204 private static final URL NULL_URL;
205
206 static {
207 try {
208 NULL_URL = new URL("http://null.sun.com/");
209 } catch (Exception e) {
210 throw new RuntimeException(e);
211 }
212 }
213
214 // reference to a Map we use as a cache for codebases
215 private static final Map<Class<?>, URL> codeBaseCacheRef =
216 new WeakHashMap<>();
217
218 /*
219 * Returns the CodeBase for the given class.
220 */
221 static URL getCodeBase(final Class<?> clazz) {
222 synchronized (codeBaseCacheRef) {
223 URL url = codeBaseCacheRef.get(clazz);
224 if (url == null) {
225 url = AccessController.doPrivileged(new PrivilegedAction<URL>() {
226 public URL run() {
227 ProtectionDomain pd = clazz.getProtectionDomain();
228 if (pd != null) {
229 CodeSource cs = pd.getCodeSource();
230 if (cs != null) {
231 return cs.getLocation();
232 }
233 }
234 return NULL_URL;
235 }
236 });
237 codeBaseCacheRef.put(clazz, url);
238 }
239 return (url == NULL_URL) ? null : url;
240 }
241 }
242
243 private static void setupJurisdictionPolicies() throws Exception {
244 String javaHomeDir = System.getProperty("java.home");
245 String sep = File.separator;
246 String pathToPolicyJar = javaHomeDir + sep + "lib" + sep +
247 "security" + sep;
248
249 File exportJar = new File(pathToPolicyJar, "US_export_policy.jar");
250 File importJar = new File(pathToPolicyJar, "local_policy.jar");
251 URL jceCipherURL = ClassLoader.getSystemResource
252 ("javax/crypto/Cipher.class");
253
254 if ((jceCipherURL == null) ||
255 !exportJar.exists() || !importJar.exists()) {
298 InputStream is = null;
299 try {
300 if (je.getName().startsWith("default_")) {
301 is = jf.getInputStream(je);
302 defaultPolicy.load(is);
303 } else if (je.getName().startsWith("exempt_")) {
304 is = jf.getInputStream(je);
305 exemptPolicy.load(is);
306 } else {
307 continue;
308 }
309 } finally {
310 if (is != null) {
311 is.close();
312 }
313 }
314
315 // Enforce the signer restraint, i.e. signer of JCE framework
316 // jar should also be the signer of the two jurisdiction policy
317 // jar files.
318 JarVerifier.verifyPolicySigned(je.getCertificates());
319 }
320 // Close and nullify the JarFile reference to help GC.
321 jf.close();
322 jf = null;
323 }
324
325 static CryptoPermissions getDefaultPolicy() {
326 return defaultPolicy;
327 }
328
329 static CryptoPermissions getExemptPolicy() {
330 return exemptPolicy;
331 }
332
333 static boolean isRestricted() {
334 return isRestricted;
335 }
336 }
|
59 // value is failure cause Exception in error case
60 private final static Map<Provider, Object> verificationResults =
61 new IdentityHashMap<>();
62
63 // Map<Provider,?> of the providers currently being verified
64 private final static Map<Provider, Object> verifyingProviders =
65 new IdentityHashMap<>();
66
67 // Set the default value. May be changed in the static initializer.
68 private static boolean isRestricted = true;
69
70 /*
71 * Don't let anyone instantiate this.
72 */
73 private JceSecurity() {
74 }
75
76 static {
77 try {
78 AccessController.doPrivileged(
79 (PrivilegedExceptionAction<Object>) () -> {
80 setupJurisdictionPolicies();
81 return null;
82 });
83
84 isRestricted = defaultPolicy.implies(
85 CryptoAllPermission.INSTANCE) ? false : true;
86 } catch (Exception e) {
87 throw new SecurityException(
88 "Can not initialize cryptographic mechanism", e);
89 }
90 }
91
92 static Instance getInstance(String type, Class<?> clazz, String algorithm,
93 String provider) throws NoSuchAlgorithmException,
94 NoSuchProviderException {
95 Service s = GetInstance.getService(type, algorithm, provider);
96 Exception ve = getVerificationResult(s.getProvider());
97 if (ve != null) {
98 String msg = "JCE cannot authenticate the provider " + provider;
99 throw (NoSuchProviderException)
100 new NoSuchProviderException(msg).initCause(ve);
101 }
124 continue;
125 }
126 try {
127 Instance instance = GetInstance.getInstance(s, clazz);
128 return instance;
129 } catch (NoSuchAlgorithmException e) {
130 failure = e;
131 }
132 }
133 throw new NoSuchAlgorithmException("Algorithm " + algorithm
134 + " not available", failure);
135 }
136
137 /**
138 * Verify if the JAR at URL codeBase is a signed exempt application
139 * JAR file and returns the permissions bundled with the JAR.
140 *
141 * @throws Exception on error
142 */
143 static CryptoPermissions verifyExemptJar(URL codeBase) throws Exception {
144 URLVerifier jv = new URLVerifier(codeBase, true);
145 jv.verify();
146 return jv.getPermissions();
147 }
148
149 /**
150 * Verify if the JAR at URL codeBase is a signed provider JAR file.
151 *
152 * @throws Exception on error
153 */
154 static void verifyProviderJar(URL codeBase, Provider p) throws Exception {
155 // Verify the provider JAR file and all
156 // supporting JAR files if there are any.
157 URLVerifier uv = new URLVerifier(codeBase, p, false);
158 uv.verify();
159 }
160
161 private final static Object PROVIDER_VERIFIED = Boolean.TRUE;
162
163 /*
164 * Verify that the provider JAR files are signed properly, which
165 * means the signer's certificate can be traced back to a
166 * JCE trusted CA.
167 * Return null if ok, failure Exception if verification failed.
168 */
169 static synchronized Exception getVerificationResult(Provider p) {
170 Object o = verificationResults.get(p);
171 if (o == PROVIDER_VERIFIED) {
172 return null;
173 } else if (o != null) {
174 return (Exception)o;
175 }
176 if (verifyingProviders.get(p) != null) {
177 // this method is static synchronized, must be recursion
178 // return failure now but do not save the result
179 return new NoSuchProviderException("Recursion during verification");
180 }
181 try {
182 verifyingProviders.put(p, Boolean.FALSE);
183 URL providerURL = getCodeBase(p.getClass());
184 verifyProviderJar(providerURL, p);
185 // Verified ok, cache result
186 verificationResults.put(p, PROVIDER_VERIFIED);
187 return null;
188 } catch (Exception e) {
189 verificationResults.put(p, e);
190 return e;
191 } finally {
192 verifyingProviders.remove(p);
193 }
194 }
195
196 // return whether this provider is properly signed and can be used by JCE
197 static boolean canUseProvider(Provider p) {
198 return getVerificationResult(p) == null;
199 }
200
201 // dummy object to represent null
202 private static final URL NULL_URL;
203
204 static {
205 try {
206 NULL_URL = new URL("http://null.sun.com/");
207 } catch (Exception e) {
208 throw new RuntimeException(e);
209 }
210 }
211
212 // reference to a Map we use as a cache for codebases
213 private static final Map<Class<?>, URL> codeBaseCacheRef =
214 new WeakHashMap<>();
215
216 /*
217 * Returns the CodeBase for the given class.
218 */
219 static URL getCodeBase(final Class<?> clazz) {
220 synchronized (codeBaseCacheRef) {
221 URL url = codeBaseCacheRef.get(clazz);
222 if (url == null) {
223 url = AccessController.doPrivileged(
224 (PrivilegedAction<URL>) () -> {
225 ProtectionDomain pd = clazz.getProtectionDomain();
226 if (pd != null) {
227 CodeSource cs = pd.getCodeSource();
228 if (cs != null) {
229 return cs.getLocation();
230 }
231 }
232 return NULL_URL;
233 });
234 codeBaseCacheRef.put(clazz, url);
235 }
236 return (url == NULL_URL) ? null : url;
237 }
238 }
239
240 private static void setupJurisdictionPolicies() throws Exception {
241 String javaHomeDir = System.getProperty("java.home");
242 String sep = File.separator;
243 String pathToPolicyJar = javaHomeDir + sep + "lib" + sep +
244 "security" + sep;
245
246 File exportJar = new File(pathToPolicyJar, "US_export_policy.jar");
247 File importJar = new File(pathToPolicyJar, "local_policy.jar");
248 URL jceCipherURL = ClassLoader.getSystemResource
249 ("javax/crypto/Cipher.class");
250
251 if ((jceCipherURL == null) ||
252 !exportJar.exists() || !importJar.exists()) {
295 InputStream is = null;
296 try {
297 if (je.getName().startsWith("default_")) {
298 is = jf.getInputStream(je);
299 defaultPolicy.load(is);
300 } else if (je.getName().startsWith("exempt_")) {
301 is = jf.getInputStream(je);
302 exemptPolicy.load(is);
303 } else {
304 continue;
305 }
306 } finally {
307 if (is != null) {
308 is.close();
309 }
310 }
311
312 // Enforce the signer restraint, i.e. signer of JCE framework
313 // jar should also be the signer of the two jurisdiction policy
314 // jar files.
315 URLVerifier.verifyPolicySigned(je.getCertificates());
316 }
317 // Close and nullify the JarFile reference to help GC.
318 jf.close();
319 jf = null;
320 }
321
322 static CryptoPermissions getDefaultPolicy() {
323 return defaultPolicy;
324 }
325
326 static CryptoPermissions getExemptPolicy() {
327 return exemptPolicy;
328 }
329
330 static boolean isRestricted() {
331 return isRestricted;
332 }
333 }
|