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