Home | History | Annotate | Download | only in crypto
      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 
     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      */
     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