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