ProviderVerifier.java revision 10967:e336cbd8b15e
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
26package javax.crypto;
27
28import java.io.*;
29import java.net.*;
30import java.security.*;
31import 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 */
46final 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}
178