1 /* 2 * Copyright (c) 2007, 2011, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.crypto; 27 28 import java.io.*; 29 import java.net.*; 30 import java.security.*; 31 import java.util.jar.*; 32 33 /** 34 * This class verifies JAR files (and any supporting JAR files), and 35 * determines whether they may be used in this implementation. 36 * 37 * The JCE in OpenJDK has an open cryptographic interface, meaning it 38 * does not restrict which providers can be used. Compliance with 39 * United States export controls and with local law governing the 40 * import/export of products incorporating the JCE in the OpenJDK is 41 * the responsibility of the licensee. 42 * 43 * @since 1.7 44 */ 45 final class JarVerifier { 46 47 // The URL for the JAR file we want to verify. 48 private URL jarURL; 49 private boolean savePerms; 50 private CryptoPermissions appPerms = null; 51 52 /** 53 * Creates a JarVerifier object to verify the given URL. 54 * 55 * @param jarURL the JAR file to be verified. 56 * @param savePerms if true, save the permissions allowed by the 57 * exemption mechanism 58 */ JarVerifier(URL jarURL, boolean savePerms)59 JarVerifier(URL jarURL, boolean savePerms) { 60 this.jarURL = jarURL; 61 this.savePerms = savePerms; 62 } 63 64 /** 65 * Verify the JAR file is signed by an entity which has a certificate 66 * issued by a trusted CA. 67 * 68 * In OpenJDK, we just need to examine the "cryptoperms" file to see 69 * if any permissions were bundled together with this jar file. 70 */ verify()71 void verify() throws JarException, IOException { 72 73 // Short-circuit. If we weren't asked to save any, we're done. 74 if (!savePerms) { 75 return; 76 } 77 78 // If the protocol of jarURL isn't "jar", we should 79 // construct a JAR URL so we can open a JarURLConnection 80 // for verifying this provider. 81 final URL url = jarURL.getProtocol().equalsIgnoreCase("jar")? 82 jarURL : new URL("jar:" + jarURL.toString() + "!/"); 83 84 JarFile jf = null; 85 try { 86 87 // Get a link to the Jarfile to search. 88 try { 89 jf = AccessController.doPrivileged( 90 new PrivilegedExceptionAction<JarFile>() { 91 public JarFile run() throws Exception { 92 JarURLConnection conn = 93 (JarURLConnection) url.openConnection(); 94 // You could do some caching here as 95 // an optimization. 96 conn.setUseCaches(false); 97 return conn.getJarFile(); 98 } 99 }); 100 } catch (java.security.PrivilegedActionException pae) { 101 throw new SecurityException("Cannot load " + url.toString(), pae); 102 } 103 104 if (jf != null) { 105 JarEntry je = jf.getJarEntry("cryptoPerms"); 106 if (je == null) { 107 throw new JarException( 108 "Can not find cryptoPerms"); 109 } 110 try { 111 appPerms = new CryptoPermissions(); 112 appPerms.load(jf.getInputStream(je)); 113 } catch (Exception ex) { 114 JarException jex = 115 new JarException("Cannot load/parse" + 116 jarURL.toString()); 117 jex.initCause(ex); 118 throw jex; 119 } 120 } 121 } finally { 122 // Only call close() when caching is not enabled. 123 // Otherwise, exceptions will be thrown for all 124 // subsequent accesses of this cached jar. 125 if (jf != null) { 126 jf.close(); 127 } 128 } 129 } 130 131 /** 132 * Verify that the provided certs include the 133 * framework signing certificate. 134 * 135 * @param certs the list of certs to be checked. 136 * @throws Exception if the list of certs did not contain 137 * the framework signing certificate 138 */ verifyPolicySigned(java.security.cert.Certificate[] certs)139 static void verifyPolicySigned(java.security.cert.Certificate[] certs) 140 throws Exception { 141 } 142 143 /** 144 * Returns the permissions which are bundled with the JAR file, 145 * aka the "cryptoperms" file. 146 * 147 * NOTE: if this JarVerifier instance is constructed with "savePerms" 148 * equal to false, then this method would always return null. 149 */ getPermissions()150 CryptoPermissions getPermissions() { 151 return appPerms; 152 } 153 } 154