1/* 2 * Copyright (c) 2007, 2009, 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 26package javax.crypto; 27 28import java.io.*; 29import java.net.*; 30import java.security.*; 31import 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 */ 45final 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 */ 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 */ 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 = (JarFile) 90 AccessController.doPrivileged( 91 new PrivilegedExceptionAction() { 92 public Object run() throws Exception { 93 JarURLConnection conn = 94 (JarURLConnection) url.openConnection(); 95 // You could do some caching here as 96 // an optimization. 97 conn.setUseCaches(false); 98 return conn.getJarFile(); 99 } 100 }); 101 } catch (java.security.PrivilegedActionException pae) { 102 SecurityException se = new SecurityException( 103 "Cannot load " + url.toString()); 104 se.initCause(pae); 105 throw se; 106 } 107 108 if (jf != null) { 109 JarEntry je = jf.getJarEntry("cryptoPerms"); 110 if (je == null) { 111 throw new JarException( 112 "Can not find cryptoPerms"); 113 } 114 try { 115 appPerms = new CryptoPermissions(); 116 appPerms.load(jf.getInputStream(je)); 117 } catch (Exception ex) { 118 JarException jex = 119 new JarException("Cannot load/parse" + 120 jarURL.toString()); 121 jex.initCause(ex); 122 throw jex; 123 } 124 } 125 } finally { 126 // Only call close() when caching is not enabled. 127 // Otherwise, exceptions will be thrown for all 128 // subsequent accesses of this cached jar. 129 if (jf != null) { 130 jf.close(); 131 } 132 } 133 } 134 135 /** 136 * Verify that the provided certs include the 137 * framework signing certificate. 138 * 139 * @param certs the list of certs to be checked. 140 * @throws Exception if the list of certs did not contain 141 * the framework signing certificate 142 */ 143 static void verifyPolicySigned(java.security.cert.Certificate[] certs) 144 throws Exception { 145 } 146 147 /** 148 * Returns the permissions which are bundled with the JAR file, 149 * aka the "cryptoperms" file. 150 * 151 * NOTE: if this JarVerifier instance is constructed with "savePerms" 152 * equal to false, then this method would always return null. 153 */ 154 CryptoPermissions getPermissions() { 155 return appPerms; 156 } 157} 158