KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > crypto > JceSecurity


1 /*
2  * @(#)JceSecurity.java 1.50 04/04/14
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.lang.ref.*;
11 import java.util.*;
12 import java.util.jar.*;
13 import java.io.*;
14 import java.net.InetAddress;
15 import java.net.URL;
16 import java.security.*;
17 import java.security.cert.Certificate;
18 import java.security.cert.CertificateFactory;
19 import java.security.cert.X509Certificate;
20
21 import java.security.Provider.Service;
22
23 import sun.security.validator.Validator;
24
25 import sun.security.jca.*;
26 import sun.security.jca.GetInstance.Instance;
27
28 /**
29  * This class instantiates implementations of JCE engine classes from
30  * providers registered with the java.security.Security object.
31  *
32  * @author Jan Luehe
33  * @author Sharon Liu
34  * @version 1.50, 04/14/04
35  * @since 1.4
36  */

37
38 final class JceSecurity {
39     
40     // Are we debugging? -- for developers
41
static final boolean debug = false;
42
43     static final SecureRandom RANDOM = new SecureRandom();
44
45     // The defaultPolicy and exemptPolicy will be set up
46
// in the static initializer.
47
private static CryptoPermissions defaultPolicy = null;
48     private static CryptoPermissions exemptPolicy = null;
49     
50     // Map<Provider,?> of the providers we already have verified
51
// value == PROVIDER_VERIFIED is successfully verified
52
// value is failure cause Exception in error case
53
private final static Map verificationResults = new IdentityHashMap();
54     
55     // Map<Provider,?> of the providers currently being verified
56
private final static Map verifyingProviders = new IdentityHashMap();
57
58     // Set the default value. May be changed in the static initializer.
59
private static boolean isRestricted = true;
60
61     // X.509 certificate factory used to setup the certificates
62
private static CertificateFactory certificateFactory;
63     
64     // certificate used to sign the framework and the policy files
65
private static X509Certificate jceCertificate;
66     
67     // validator instance to verify provider JAR files
68
private static Validator providerValidator;
69     
70     // validator instance to verify exempt application JAR files
71
// or null if the providerValidator should be used
72
private static Validator exemptValidator;
73     
74     /*
75      * Don't let anyone instantiate this.
76      */

77     private JceSecurity() {
78     }
79     
80     static {
81 /* FIRST CA CERTIFICATE TRUSTED TO SIGN JCE PROVIDERS
82 Owner: CN=JCE Code Signing CA, OU=Java Software Code Signing,
83 O=Sun Microsystems Inc, L=Palo Alto, ST=CA, C=US
84 Issuer: CN=JCE Code Signing CA, OU=Java Software Code Signing,
85 O=Sun Microsystems Inc, L=Palo Alto, ST=CA, C=US
86 Serial number: 10
87 Valid from: Wed Apr 25 00:00:00 PDT 2001 until: Sat Apr 25 00:00:00 PDT 2020
88 Certificate fingerprints:
89          MD5: 66:25:5A:78:3E:1A:CA:06:C1:43:A6:15:AE:BE:A5:92
90          SHA1: 57:37:D1:E1:16:2F:F6:FE:26:B9:87:88:D2:86:DA:66:7F:98:54:3C
91 */

92     final String CACERT1 =
93 "-----BEGIN CERTIFICATE-----\n" +
94 "MIIDwDCCA36gAwIBAgIBEDALBgcqhkjOOAQDBQAwgZAxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJD" +
95 "QTESMBAGA1UEBxMJUGFsbyBBbHRvMR0wGwYDVQQKExRTdW4gTWljcm9zeXN0ZW1zIEluYzEjMCEG" +
96 "A1UECxMaSmF2YSBTb2Z0d2FyZSBDb2RlIFNpZ25pbmcxHDAaBgNVBAMTE0pDRSBDb2RlIFNpZ25p" +
97 "bmcgQ0EwHhcNMDEwNDI1MDcwMDAwWhcNMjAwNDI1MDcwMDAwWjCBkDELMAkGA1UEBhMCVVMxCzAJ" +
98 "BgNVBAgTAkNBMRIwEAYDVQQHEwlQYWxvIEFsdG8xHTAbBgNVBAoTFFN1biBNaWNyb3N5c3RlbXMg" +
99 "SW5jMSMwIQYDVQQLExpKYXZhIFNvZnR3YXJlIENvZGUgU2lnbmluZzEcMBoGA1UEAxMTSkNFIENv" +
100 "ZGUgU2lnbmluZyBDQTCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQDrrzcEHspRHmldsPKP9rVJH8ak" +
101 "mQXXKb90t2r1Gdge5Bv4CgGamP9wq+JKVoZsU7P84ciBjDHwxPOwi+ZwBuz3aWjbg0xyKYkpNhdc" +
102 "O0oHoCACKkaXUR1wyAgYC84Mbpt29wXj5/vTYXnhYJokjQaVgzxRIOEwzzhXgqYacg3O0wIVAIQl" +
103 "ReG6ualiq3noWzC4iWsb/3t1AoGBAKvJdHt07+5CtWpTTTvdkAZyaJEPC6Qpdi5VO9WuTWVcfio6" +
104 "BKZnptBxqqXXt+LBcg2k0aoeklRMIAAJorAJQRkzALLDXK5C+LGLynyW2BB/N0Rbqsx4yNdydjdr" +
105 "QJmoVWb6qAMei0oRAmnLTLglBhygd9LJrNI96QoQ+nZwt/vcA4GEAAKBgC0JmFysuJzHmX7uIBkq" +
106 "NJD516urrt1rcpUNZvjvJ49Esu0oRMf+r7CmJ28AZ0WCWweoVlY70ilRYV5pOdcudHcSzxlK9S3I" +
107 "y3JhxE5v+kdDPxS7+rwYZijC2WaLei0vwmCSSxT+WD4hf2hivmxISfmgS16FnRkQ+RVFURtx1PcL" +
108 "o2YwZDARBglghkgBhvhCAQEEBAMCAAcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRl4vSG" +
109 "ydNO8JFOWKJq9dh4WprBpjAdBgNVHQ4EFgQUZeL0hsnTTvCRTliiavXYeFqawaYwCwYHKoZIzjgE" +
110 "AwUAAy8AMCwCFCr3zzyXXfl4tgjXQbTZDUVM5LScAhRFzXVpDiH6HdazKbLp9zMdM/38SQ==" +
111 "\n-----END CERTIFICATE-----";
112
113 /* SECOND CA CERTIFICATE TRUSTED TO SIGN JCE PROVIDERS
114 Owner: CN=JCE Code Signing CA, OU=IBM Code Signing, O=IBM Corporation, C=US
115 Issuer: CN=JCE Code Signing CA, OU=IBM Code Signing, O=IBM Corporation, C=US
116 Serial number: 40216811
117 Valid from: Wed Feb 04 13:45:53 PST 2004 until: Tue May 26 13:45:53 PDT 2020
118 Certificate fingerprints:
119          MD5: 54:20:F8:E9:FA:65:28:DE:87:7A:60:74:3D:44:77:9E
120          SHA1: 5F:DB:A9:62:8E:35:09:D0:DB:10:04:58:2D:62:11:B8:1A:AE:56:44
121 */

122     final String CACERT2 =
123 "-----BEGIN CERTIFICATE-----\n" +
124 "MIIDUTCCAw2gAwIBAgIEQCFoETALBgcqhkjOOAQDBQAwYDELMAkGA1UEBhMCVVMxGDAWBgNVBAoT" +
125 "D0lCTSBDb3Jwb3JhdGlvbjEZMBcGA1UECxMQSUJNIENvZGUgU2lnbmluZzEcMBoGA1UEAxMTSkNF" +
126 "IENvZGUgU2lnbmluZyBDQTAeFw0wNDAyMDQyMTQ1NTNaFw0yMDA1MjYyMDQ1NTNaMGAxCzAJBgNV" +
127 "BAYTAlVTMRgwFgYDVQQKEw9JQk0gQ29ycG9yYXRpb24xGTAXBgNVBAsTEElCTSBDb2RlIFNpZ25p" +
128 "bmcxHDAaBgNVBAMTE0pDRSBDb2RlIFNpZ25pbmcgQ0EwggG4MIIBLAYHKoZIzjgEATCCAR8CgYEA" +
129 "/X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzXgTuA" +
130 "HTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOu" +
131 "K2HXKu/yIgMZndFIAccCFQCXYFCPFSMLzLKSuYKi64QL8Fgc9QKBgQD34aCF1ps93su8q1w2uFe5" +
132 "eZSvu/o66oL5V0wLPQeCZ1FZV4661FlP5nEHEIGAtEkWcSPoTCgWE7fPCTKMyKbhPBZ6i1R8jSjg" +
133 "o64eK7OmdZFuo38L+iE1YvH7YnoBJDvMpPG+qFGQiaiD3+Fa5Z8GkotmXoB7VSVkAUw7/s9JKgOB" +
134 "hQACgYEA6msAx98QO7l0NafhbWaCTfdbVnHCJkUncj1REGL/s9wQyftRE9Sti6glbl3JeNJbJ9MT" +
135 "QUcUBnzLgjhexgthoEyDLZTMjC6EkDqPQgppUtN0JnekFH0qcUGIiXemLWKaoViYbWzPzqjqut3o" +
136 "oRBEjIRCwbgfK7S8s110YICNQlSjUzBRMB0GA1UdDgQWBBR+PU1NzBBZuvmuQj3lyVdaUgt+hzAf" +
137 "BgNVHSMEGDAWgBR+PU1NzBBZuvmuQj3lyVdaUgt+hzAPBgNVHRMBAf8EBTADAQH/MAsGByqGSM44" +
138 "BAMFAAMxADAuAhUAi5ncRzk0NqFYt4yWsnlcVBPt+zsCFQCM9M0mv0t9iodsOOHJhqUrW1QjAA==" +
139 "\n-----END CERTIFICATE-----";
140
141 /* RSA CERTIFICATE USED TO SIGN ALL FOUR JCE JAR FILES
142 Owner: CN=Sun Microsystems Inc, OU=Java Software Code Signing,
143 O=Sun Microsystems Inc
144 Issuer: CN=JCE Code Signing CA, OU=Java Software Code Signing,
145 O=Sun Microsystems Inc, L=Palo Alto, ST=CA, C=US
146 Serial number: 15d
147 Valid from: Fri Oct 25 12:05:10 PDT 2002 until: Mon Oct 29 11:05:10 PST 2007
148 Certificate fingerprints:
149          MD5: 63:AA:AA:43:78:9F:86:BC:AA:78:40:36:2D:6E:66:6D
150          SHA1: 9D:F7:A6:11:C5:C1:F5:5D:61:01:F2:1D:A2:22:D7:58:79:6A:52:23
151 */

152     final String JCECERT =
153 "-----BEGIN CERTIFICATE-----\n" +
154 "MIICnjCCAlugAwIBAgICAV0wCwYHKoZIzjgEAwUAMIGQMQswCQYDVQQGEwJVUzELMAkGA1UECBMC" +
155 "Q0ExEjAQBgNVBAcTCVBhbG8gQWx0bzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxIzAh" +
156 "BgNVBAsTGkphdmEgU29mdHdhcmUgQ29kZSBTaWduaW5nMRwwGgYDVQQDExNKQ0UgQ29kZSBTaWdu" +
157 "aW5nIENBMB4XDTAyMTAyNTE5MDUxMFoXDTA3MTAyOTE5MDUxMFowYzEdMBsGA1UEChMUU3VuIE1p" +
158 "Y3Jvc3lzdGVtcyBJbmMxIzAhBgNVBAsTGkphdmEgU29mdHdhcmUgQ29kZSBTaWduaW5nMR0wGwYD" +
159 "VQQDExRTdW4gTWljcm9zeXN0ZW1zIEluYzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA16bK" +
160 "o6tC3OHFDNfPXLKXMCMtIyeubNnsEtlvrH34HhfF+ZmpSliLCvQ15ms705vy4XgZUbZ3mgSOlLRM" +
161 "AGRo6596ePhc+0Z6yeKhbb3LZ8iz97ZIptkHGOshj9cfcSRPYmorUug9OsybMdIfQXazxT9mZJ9Y" +
162 "x5IDw6xak7kVbpUCAwEAAaOBiDCBhTARBglghkgBhvhCAQEEBAMCBBAwDgYDVR0PAQH/BAQDAgXg" +
163 "MB0GA1UdDgQWBBRI319jCbhc9DWJVltXgfrMybHNjzAfBgNVHSMEGDAWgBRl4vSGydNO8JFOWKJq" +
164 "9dh4WprBpjAgBgNVHREEGTAXgRV5dS1jaGluZy5wZW5nQHN1bi5jb20wCwYHKoZIzjgEAwUAAzAA" +
165 "MC0CFFmXXV97KWezNwPFiAJt5IWpPGVqAhUAggVpunP/Bo8BOcwIoUpgYYQ7ruY=" +
166 "\n-----END CERTIFICATE-----";
167
168     try {
169         AccessController.doPrivileged(new PrivilegedExceptionAction() {
170             public Object run() throws Exception {
171             certificateFactory = CertificateFactory.getInstance("X.509");
172             jceCertificate = parseCertificate(JCECERT);
173             X509Certificate[] providerCaCerts = new X509Certificate[] {
174             parseCertificate(CACERT1),
175             parseCertificate(CACERT2),
176             // as an optimization, add our EE certs to the trusted
177
// certs. this saves us the signature verification
178
jceCertificate,
179             };
180             providerValidator = Validator.getInstance(
181                             Validator.TYPE_SIMPLE,
182                         Validator.VAR_JCE_SIGNING,
183                         Arrays.asList(providerCaCerts));
184             // Trust the JCE provider CAs for exempt JCE applications.
185
// If this changes, setup the validator for exempt apps here
186
exemptValidator = null;
187             testSignatures(providerCaCerts[0]);
188             setupJurisdictionPolicies();
189             certificateFactory = null;
190             return null;
191         }
192         });
193
194         isRestricted = defaultPolicy.implies(CryptoAllPermission.INSTANCE)?
195                     false : true;
196     } catch (Exception e) {
197         SecurityException se = new
198         SecurityException("Cannot set up certs for trusted CAs");
199         se.initCause(e);
200         throw se;
201         
202     }
203     }
204     
205     /**
206      * Parse a PEM encoded X.509 certificate.
207      */

208     private static X509Certificate parseCertificate(String s) throws Exception {
209     InputStream in = new ByteArrayInputStream(s.getBytes("UTF8"));
210     return (X509Certificate)certificateFactory.generateCertificate(in);
211     }
212     
213     static Instance getInstance(String type, Class clazz, String algorithm,
214         String provider) throws NoSuchAlgorithmException,
215         NoSuchProviderException {
216     Service s = GetInstance.getService(type, algorithm, provider);
217     Exception ve = getVerificationResult(s.getProvider());
218     if (ve != null) {
219         String msg = "JCE cannot authenticate the provider " + provider;
220         throw (NoSuchProviderException)
221                     new NoSuchProviderException(msg).initCause(ve);
222     }
223     return GetInstance.getInstance(s, clazz);
224     }
225
226     static Instance getInstance(String type, Class clazz, String algorithm,
227         Provider provider) throws NoSuchAlgorithmException {
228     Service s = GetInstance.getService(type, algorithm, provider);
229     Exception ve = JceSecurity.getVerificationResult(provider);
230     if (ve != null) {
231         String msg = "JCE cannot authenticate the provider "
232             + provider.getName();
233         throw new SecurityException(msg, ve);
234     }
235     return GetInstance.getInstance(s, clazz);
236     }
237     
238     static Instance getInstance(String type, Class clazz, String algorithm)
239         throws NoSuchAlgorithmException {
240     List services = GetInstance.getServices(type, algorithm);
241     NoSuchAlgorithmException failure = null;
242     for (Iterator t = services.iterator(); t.hasNext(); ) {
243         Service s = (Service)t.next();
244         if (canUseProvider(s.getProvider()) == false) {
245         // allow only signed providers
246
continue;
247         }
248         try {
249         Instance instance = GetInstance.getInstance(s, clazz);
250         return instance;
251         } catch (NoSuchAlgorithmException e) {
252         failure = e;
253         }
254     }
255     throw new NoSuchAlgorithmException("Algorithm " + algorithm
256         + " not available", failure);
257     }
258
259     /**
260      * Verify if the JAR at URL codeBase is a signed exempt application
261      * JAR file.
262      *
263      * @return the JarFile on success
264      * @throws Exception on error
265      */

266     static JarFile verifyExemptJar(URL codeBase) throws Exception {
267     if (exemptValidator != null) {
268         try {
269         JarVerifier jv = new JarVerifier(codeBase, exemptValidator);
270         jv.verify();
271         return jv.getJarFile();
272         } catch (Exception e) {
273         // ignore, also try provider CA certs
274
}
275     }
276     return verifyProviderJar(codeBase);
277     }
278     
279     /**
280      * Verify if the JAR at URL codeBase is a signed provider JAR file.
281      *
282      * @return the JarFile on success
283      * @throws Exception on error
284      */

285     static JarFile verifyProviderJar(URL codeBase) throws Exception {
286     // Verify the provider JAR file and all
287
// supporting JAR files if there are any.
288
JarVerifier jv = new JarVerifier(codeBase, providerValidator);
289     jv.verify();
290     return jv.getJarFile();
291     }
292     
293     private final static Object PROVIDER_VERIFIED = Boolean.TRUE;
294     
295     /*
296      * Verify that the provider JAR files are signed properly, which
297      * means the signer's certificate can be traced back to a
298      * JCE trusted CA.
299      * Return null if ok, failure Exception if verification failed.
300      */

301     static synchronized Exception getVerificationResult(Provider p) {
302     Object o = verificationResults.get(p);
303     if (o == PROVIDER_VERIFIED) {
304         return null;
305     } else if (o != null) {
306         return (Exception)o;
307     }
308     if (verifyingProviders.get(p) != null) {
309         // this method is static synchronized, must be recursion
310
// return failure now but do not save the result
311
return new NoSuchProviderException("Recursion during verification");
312     }
313     try {
314         verifyingProviders.put(p, Boolean.FALSE);
315         URL providerURL = getCodeBase(p.getClass());
316         verifyProviderJar(providerURL);
317         // Verified ok, cache result
318
verificationResults.put(p, PROVIDER_VERIFIED);
319         return null;
320     } catch (Exception e) {
321         verificationResults.put(p, e);
322         return e;
323     } finally {
324         verifyingProviders.remove(p);
325     }
326     }
327     
328     // return whether this provider is properly signed and can be used by JCE
329
static boolean canUseProvider(Provider p) {
330     return getVerificationResult(p) == null;
331     }
332     
333     // dummy object to represent null
334
private static final URL NULL_URL;
335     
336     static {
337     try {
338         NULL_URL = new URL("http://null.sun.com/");
339     } catch (Exception e) {
340         throw new RuntimeException(e);
341     }
342     }
343     
344     // reference to a Map we use as a cache for codebases
345
private static final Map codeBaseCacheRef = new WeakHashMap();
346     
347     /*
348      * Retuns the CodeBase for the given class.
349      */

350     static URL getCodeBase(final Class clazz) {
351     URL url = (URL)codeBaseCacheRef.get(clazz);
352     if (url == null) {
353             url = (URL)AccessController.doPrivileged(new PrivilegedAction() {
354         public Object run() {
355             ProtectionDomain pd = clazz.getProtectionDomain();
356             if (pd != null) {
357             CodeSource cs = pd.getCodeSource();
358             if (cs != null) {
359                 return cs.getLocation();
360             }
361             }
362             return NULL_URL;
363         }
364         });
365         codeBaseCacheRef.put(clazz, url);
366     }
367     return (url == NULL_URL) ? null : url;
368     }
369
370     private static void setupJurisdictionPolicies() throws Exception {
371     String javaHomeDir = System.getProperty("java.home");
372         String sep = File.separator;
373     String pathToPolicyJar = javaHomeDir + sep + "lib" + sep +
374             "security" + sep;
375
376     File exportJar = new File(pathToPolicyJar, "US_export_policy.jar");
377     File importJar = new File(pathToPolicyJar, "local_policy.jar");
378         URL jceCipherURL = ClassLoader.getSystemResource
379         ("javax/crypto/Cipher.class");
380
381     if ((jceCipherURL == null) || !exportJar.exists() || !importJar.exists()) {
382         throw new SecurityException
383                     ("Cannot locate policy or framework files!");
384     }
385     
386     URL exportPolicyURL = exportJar.toURI().toURL();
387         URL importPolicyURL = importJar.toURI().toURL();
388         
389         if (debug) {
390         System.out.println("export policy at:" + exportPolicyURL);
391         System.out.println("import policy at:" + importPolicyURL);
392         System.out.println("jce Cipher class at:" + jceCipherURL);
393         }
394     
395     // Enforce the signer restraint, i.e. signer of JCE framework
396
// jar should also be the signer of the two jurisdiction policy
397
// jar files.
398
List signers = JarVerifier.getSignersOfJarEntry(jceCipherURL);
399     for (Iterator t = signers.iterator(); t.hasNext(); ) {
400         X509Certificate[] chain = (X509Certificate[])t.next();
401         if (chain[0].equals(jceCertificate)) {
402         // use signers as a success flag
403
signers = null;
404         break;
405         }
406     }
407     if (signers != null) {
408         throw new SecurityException("Jurisdiction policy files are " +
409                     "not signed by trusted signers!");
410     }
411
412     // Read jurisdiction policies.
413
CryptoPermissions defaultExport = new CryptoPermissions();
414     CryptoPermissions exemptExport = new CryptoPermissions();
415     loadPolicies(exportJar, defaultExport, exemptExport, jceCertificate);
416
417     CryptoPermissions defaultImport = new CryptoPermissions();
418     CryptoPermissions exemptImport = new CryptoPermissions();
419     loadPolicies(importJar, defaultImport, exemptImport, jceCertificate);
420
421     // Merge the export and import policies for default applications.
422
if (defaultExport.isEmpty() || defaultImport.isEmpty()) {
423         throw new SecurityException("Missing mandatory jurisdiction " +
424                     "policy files");
425     }
426     defaultPolicy = defaultExport.getMinimum(defaultImport);
427
428     // Merge the export and import policies for exempt applications.
429
if (exemptExport.isEmpty()) {
430         exemptPolicy = exemptImport.isEmpty() ? null : exemptImport;
431     } else {
432         exemptPolicy = exemptExport.getMinimum(exemptImport);
433     }
434     }
435     
436     /**
437      * Load the policies from the specified file. Also checks that the policies
438      * are signed by the certificate <code>signer</code>.
439      */

440     private static void loadPolicies(File jarPathName,
441                      CryptoPermissions defaultPolicy,
442                      CryptoPermissions exemptPolicy,
443                      X509Certificate signer)
444     throws Exception {
445
446     JarFile jf = new JarFile(jarPathName);
447
448     Enumeration entries = jf.entries();
449     while (entries.hasMoreElements()) {
450         JarEntry je = (JarEntry)entries.nextElement();
451         InputStream is = null;
452         try {
453             if (je.getName().startsWith("default_")) {
454             is = jf.getInputStream(je);
455             defaultPolicy.load(is);
456             } else if (je.getName().startsWith("exempt_")) {
457             is = jf.getInputStream(je);
458             exemptPolicy.load(is);
459             } else {
460             continue;
461         }
462         } finally {
463         if (is != null) {
464             is.close();
465         }
466         }
467         Certificate[] certChains = je.getCertificates();
468         List paths = JarVerifier.convertCertsToChains(certChains);
469         boolean found = false;
470         for (Iterator t = paths.iterator(); t.hasNext(); ) {
471         X509Certificate[] path = (X509Certificate[])t.next();
472         X509Certificate cert = path[0];
473         if (cert.equals(signer)) {
474             found = true;
475             break;
476         }
477         }
478         if (found == false) {
479         throw new SecurityException("Jurisdiction policy files are " +
480                         "not signed by trusted signers!");
481         }
482     }
483     jf = null;
484     }
485
486     static CryptoPermissions getDefaultPolicy() {
487     return defaultPolicy;
488     }
489
490     static CryptoPermissions getExemptPolicy() {
491     return exemptPolicy;
492     }
493
494     static boolean isRestricted() {
495     return isRestricted;
496     }
497
498     /**
499      * Retrieve some system information, hashed.
500      */

501     private static byte[] getSystemEntropy() {
502     final MessageDigest md;
503
504     try {
505             md = MessageDigest.getInstance("SHA");
506         } catch (NoSuchAlgorithmException nsae) {
507             throw new InternalError("internal error: SHA-1 not available.");
508     }
509
510     // The current time in millis
511
byte b = (byte)System.currentTimeMillis();
512     md.update(b);
513
514     try {
515         // System properties can change from machine to machine
516
String s;
517         Properties p = System.getProperties();
518         Enumeration e = p.propertyNames();
519         while (e.hasMoreElements()) {
520         s =(String)e.nextElement();
521         md.update(s.getBytes());
522         md.update(p.getProperty(s).getBytes());
523         }
524         
525         md.update
526         (InetAddress.getLocalHost().toString().getBytes());
527         
528         // The temporary dir
529
File f = new File(p.getProperty("java.io.tmpdir"));
530         String[] sa = f.list();
531         for(int i = 0; i < sa.length; i++)
532         md.update(sa[i].getBytes());
533         
534     } catch (Exception ex) {
535         md.update((byte)ex.hashCode());
536     }
537     
538     // get Runtime memory stats
539
Runtime rt = Runtime.getRuntime();
540     byte[] memBytes = longToByteArray(rt.totalMemory());
541     md.update(memBytes, 0, memBytes.length);
542     memBytes = longToByteArray(rt.freeMemory());
543     md.update(memBytes, 0, memBytes.length);
544     
545     return md.digest();
546     }
547
548     /**
549      * Helper function to convert a long into a byte array (least significant
550      * byte first).
551      */

552     private static byte[] longToByteArray(long l) {
553     byte[] retVal = new byte[8];
554  
555     for (int i=0; i<8; i++) {
556         retVal[i] = (byte) l;
557         l >>= 8;
558     }
559  
560     return retVal;
561     }
562
563     private static void testSignatures(X509Certificate providerCert)
564         throws Exception {
565 /* DSA CERTIFICATE
566 Owner: CN=JCE Development, OU=Java Software, O=Sun Microsystems, L=Cupertino,
567 ST=CA, C=US
568 Issuer: CN=JCE Development, OU=Java Software, O=Sun Microsystems, L=Cupertino,
569 ST=CA, C=US
570 Serial number: 37f939e5
571 Valid from: Mon Oct 04 16:36:05 PDT 1999 until: Tue Oct 03 16:36:05 PDT 2000
572 Certificate fingerprints:
573          MD5: F2:F9:D1:18:F3:CC:E5:67:39:48:2C:15:98:03:ED:28
574          SHA1: 28:E5:32:F3:FD:AF:8E:01:97:66:47:61:92:90:F9:8D:1B:E4:59:D5
575 */

576     String DSA =
577 "-----BEGIN CERTIFICATE-----\n" +
578 "MIIDLDCCAukCBDf5OeUwCwYHKoZIzjgEAwUAMHsxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTES" +
579 "MBAGA1UEBxMJQ3VwZXJ0aW5vMRkwFwYDVQQKExBTdW4gTWljcm9zeXN0ZW1zMRYwFAYDVQQLEw1K" +
580 "YXZhIFNvZnR3YXJlMRgwFgYDVQQDEw9KQ0UgRGV2ZWxvcG1lbnQwHhcNOTkxMDA0MjMzNjA1WhcN" +
581 "MDAxMDAzMjMzNjA1WjB7MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCUN1cGVy" +
582 "dGlubzEZMBcGA1UEChMQU3VuIE1pY3Jvc3lzdGVtczEWMBQGA1UECxMNSmF2YSBTb2Z0d2FyZTEY" +
583 "MBYGA1UEAxMPSkNFIERldmVsb3BtZW50MIIBuDCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIp" +
584 "Ut9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdr" +
585 "mVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iID" +
586 "GZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC" +
587 "+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWR" +
588 "bqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYUAAoGBAOGs" +
589 "R8waR5aiuOk1yBLemRlVCY+APJv3xqmPRxWAF6nwV2xrFUB8ghSEMFcHywoe4vBDvkGSoAFzeB5j" +
590 "y5wjDiFsN5AFPEVRfveS4NNZ1dgRdHbbh3h5O1dZE4MAKQwQfUoh9Oa3aahlB+orRzKOHLlGDpbN" +
591 "RQLST5BClvohramCMAsGByqGSM44BAMFAAMwADAtAhRF46T3nS+inP9TA1pLd3LIV0NNDQIVAIaf" +
592 "i+1/+JKxu0rcoXWMFSxNaRb3\n" +
593 "-----END CERTIFICATE-----";
594
595 /* SELF SIGNED RSA CERTIFICATE 1
596 Owner: CN=JCE Development, OU=Java Software, O=Sun Microsystems, L=Cupertino,
597 ST=CA, C=US
598 Issuer: CN=JCE Development, OU=Java Software, O=Sun Microsystems, L=Cupertino,
599 ST=CA, C=US
600 Serial number: 1
601 Valid from: Thu Oct 31 15:27:44 GMT 2002 until: Wed Oct 31 15:27:44 GMT 2007
602 Certificate fingerprints:
603          MD5: 62:D2:99:B7:5C:20:A7:9D:B1:4A:64:06:8D:31:B8:70
604          SHA1: 53:B9:A1:1F:D5:9F:53:27:99:5D:6A:DF:E0:D3:59:9B:67:8B:5C:7F
605 */

606     final String RSA1 =
607 "-----BEGIN CERTIFICATE-----\n" +
608 "MIIB4DCCAYoCAQEwDQYJKoZIhvcNAQEEBQAwezELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIw" +
609 "EAYDVQQHEwlDdXBlcnRpbm8xGTAXBgNVBAoTEFN1biBNaWNyb3N5c3RlbXMxFjAUBgNVBAsTDUph" +
610 "dmEgU29mdHdhcmUxGDAWBgNVBAMTD0pDRSBEZXZlbG9wbWVudDAeFw0wMjEwMzExNTI3NDRaFw0w" +
611 "NzEwMzExNTI3NDRaMHsxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTESMBAGA1UEBxMJQ3VwZXJ0" +
612 "aW5vMRkwFwYDVQQKExBTdW4gTWljcm9zeXN0ZW1zMRYwFAYDVQQLEw1KYXZhIFNvZnR3YXJlMRgw" +
613 "FgYDVQQDEw9KQ0UgRGV2ZWxvcG1lbnQwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAo/4CddEOa3M6" +
614 "v9JFAhnBYgTq54Y30++F8yzCK9EeYaG3AzvzZqNshDy579647p0cOM/4VO6rU2PgbzgKXPcs8wID" +
615 "AQABMA0GCSqGSIb3DQEBBAUAA0EACqPlFmVdKdYSCTNltXKQnBqss9GNjbnB+CitvWrwN+oOK8qQ" +
616 "pvV+5LB6LruvRy6zCedCV95Z2kXKg/Fnj0gvsg==\n" +
617 "-----END CERTIFICATE-----";
618
619 /* SELF SIGNED RSA CERTIFICATE 2
620 Owner: CN=JCE Development, OU=Java Software, O=Sun Microsystems, L=Cupertino,
621 ST=CA, C=US
622 Issuer: CN=JCE Development, OU=Java Software, O=Sun Microsystems, L=Cupertino,
623 ST=CA, C=US
624 Serial number: 2
625 Valid from: Thu Oct 31 15:27:44 GMT 2002 until: Wed Oct 31 15:27:44 GMT 2007
626 Certificate fingerprints:
627          MD5: A5:18:04:0E:29:DB:2B:24:19:FE:0F:12:E8:0C:A7:CC
628          SHA1: A9:3B:F5:AE:AC:92:5B:0B:EC:7E:FD:E6:59:28:07:F2:2C:2C:8A:2D
629 */

630     final String RSA2 =
631 "-----BEGIN CERTIFICATE-----\n" +
632 "MIIB4DCCAYoCAQIwDQYJKoZIhvcNAQEEBQAwezELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIw" +
633 "EAYDVQQHEwlDdXBlcnRpbm8xGTAXBgNVBAoTEFN1biBNaWNyb3N5c3RlbXMxFjAUBgNVBAsTDUph" +
634 "dmEgU29mdHdhcmUxGDAWBgNVBAMTD0pDRSBEZXZlbG9wbWVudDAeFw0wMjEwMzExNTI3NDRaFw0w" +
635 "NzEwMzExNTI3NDRaMHsxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTESMBAGA1UEBxMJQ3VwZXJ0" +
636 "aW5vMRkwFwYDVQQKExBTdW4gTWljcm9zeXN0ZW1zMRYwFAYDVQQLEw1KYXZhIFNvZnR3YXJlMRgw" +
637 "FgYDVQQDEw9KQ0UgRGV2ZWxvcG1lbnQwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAr1OSXaOzpnVo" +
638 "qL2LqS5+HLy1kVvBwiM/E5iYT9eZaghE8qvF+4fETipWUNTWCQzHR4cDJGJOl9Nm77tELhES4QID" +
639 "AQABMA0GCSqGSIb3DQEBBAUAA0EAL+WcVFyj+iXlEVNVQbNOOUlWmlmXGiNKKXnIdNcc1ZUyi+JW" +
640 "0zmlfZ7iU/eRYhEEJBwdrUoyiGOGLo7pi6JzAA==\n" +
641 "-----END CERTIFICATE-----";
642      
643     final int NUM_TESTS = 12;
644     byte[] randomBytes = getSystemEntropy();
645     int random = (randomBytes[0] & 0xff)
646                | (randomBytes[1] & 0xff) << 8
647                | (randomBytes[2] & 0xff) << 16
648                | randomBytes[3] << 24;
649
650     X509Certificate[] certs = new X509Certificate[] {
651         providerCert,
652         parseCertificate(DSA),
653         parseCertificate(RSA1),
654         parseCertificate(RSA2),
655     };
656     
657     PublicKey[] publicKeys = new PublicKey[4];
658     publicKeys[0] = providerCert.getPublicKey();
659     publicKeys[1] = publicKeys[0];
660     publicKeys[2] = certs[2].getPublicKey();
661     publicKeys[3] = publicKeys[2];
662     
663     boolean[] expectedResult = new boolean[] {
664         true,
665         false,
666         true,
667         false,
668     };
669
670     for (int i = 0; i < NUM_TESTS; i++) {
671         int k = random & 3;
672         random >>= 2;
673         boolean result;
674         try {
675         certs[k].verify(publicKeys[k]);
676         result = true;
677         } catch (SignatureException e) {
678         result = false;
679         }
680         if (result != expectedResult[k]) {
681         throw new SecurityException("Signature classes have " +
682                         "been tampered with");
683         }
684     }
685     }
686 }
687
Popular Tags