JarFile.java revision 1d958dba8b5c9589e3375446045e1672eee0e1b1
151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.util.jar; 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.*; 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.lang.ref.SoftReference; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.net.URL; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.*; 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.zip.*; 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.CodeSigner; 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.cert.Certificate; 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.AccessController; 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.CodeSource; 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.misc.IOUtils; 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.action.GetPropertyAction; 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.util.ManifestEntryVerifier; 401d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski/* ----- BEGIN android ----- 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.misc.SharedSecrets; 421d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski----- END android ----- */ 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The <code>JarFile</code> class is used to read the contents of a jar file 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * from any file that can be opened with <code>java.io.RandomAccessFile</code>. 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * It extends the class <code>java.util.zip.ZipFile</code> with support 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for reading an optional <code>Manifest</code> entry. The 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>Manifest</code> can be used to specify meta-information about the 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * jar file and its entries. 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or method in this class will cause a {@link NullPointerException} to be 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * thrown. 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author David Connelly 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see Manifest 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.util.zip.ZipFile 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.util.jar.JarEntry 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.2 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass JarFile extends ZipFile { 641d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski // ----- BEGIN android ----- 651d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski static final String META_DIR = "META-INF/"; 661d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski // ----- END android ----- 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private SoftReference<Manifest> manRef; 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private JarEntry manEntry; 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private JarVerifier jv; 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean jvInitialized; 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean verify; 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean computedHasClassPathAttribute; 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean hasClassPathAttribute; 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Set up JavaUtilJarAccess in SharedSecrets 761d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski /* ----- BEGIN android ----- 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static { 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SharedSecrets.setJavaUtilJarAccess(new JavaUtilJarAccessImpl()); 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 801d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski ----- END android ----- */ 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The JAR manifest file name. 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final String MANIFEST_NAME = "META-INF/MANIFEST.MF"; 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a new <code>JarFile</code> to read from the specified 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * file <code>name</code>. The <code>JarFile</code> will be verified if 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * it is signed. 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the name of the jar file to be opened for reading 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if an I/O error has occurred 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SecurityException if access to the file is denied 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by the SecurityManager 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public JarFile(String name) throws IOException { 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(new File(name), true, ZipFile.OPEN_READ); 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a new <code>JarFile</code> to read from the specified 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * file <code>name</code>. 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the name of the jar file to be opened for reading 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param verify whether or not to verify the jar file if 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * it is signed. 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if an I/O error has occurred 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SecurityException if access to the file is denied 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by the SecurityManager 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public JarFile(String name, boolean verify) throws IOException { 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(new File(name), verify, ZipFile.OPEN_READ); 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a new <code>JarFile</code> to read from the specified 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>File</code> object. The <code>JarFile</code> will be verified if 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * it is signed. 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param file the jar file to be opened for reading 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if an I/O error has occurred 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SecurityException if access to the file is denied 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by the SecurityManager 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public JarFile(File file) throws IOException { 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(file, true, ZipFile.OPEN_READ); 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a new <code>JarFile</code> to read from the specified 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>File</code> object. 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param file the jar file to be opened for reading 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param verify whether or not to verify the jar file if 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * it is signed. 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if an I/O error has occurred 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SecurityException if access to the file is denied 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by the SecurityManager. 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public JarFile(File file, boolean verify) throws IOException { 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(file, verify, ZipFile.OPEN_READ); 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a new <code>JarFile</code> to read from the specified 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>File</code> object in the specified mode. The mode argument 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * must be either <tt>OPEN_READ</tt> or <tt>OPEN_READ | OPEN_DELETE</tt>. 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param file the jar file to be opened for reading 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param verify whether or not to verify the jar file if 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * it is signed. 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param mode the mode in which the file is to be opened 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if an I/O error has occurred 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalArgumentException 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * if the <tt>mode</tt> argument is invalid 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SecurityException if access to the file is denied 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by the SecurityManager 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.3 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public JarFile(File file, boolean verify, int mode) throws IOException { 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(file, mode); 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.verify = verify; 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the jar file manifest, or <code>null</code> if none. 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the jar file manifest, or <code>null</code> if none 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalStateException 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * may be thrown if the jar file has been closed 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Manifest getManifest() throws IOException { 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getManifestFromReference(); 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Manifest getManifestFromReference() throws IOException { 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Manifest man = manRef != null ? manRef.get() : null; 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (man == null) { 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarEntry manEntry = getManEntry(); 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If found then load the manifest 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (manEntry != null) { 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (verify) { 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] b = getBytes(manEntry); 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski man = new Manifest(new ByteArrayInputStream(b)); 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!jvInitialized) { 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv = new JarVerifier(b); 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski man = new Manifest(super.getInputStream(manEntry)); 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski manRef = new SoftReference(man); 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return man; 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2001d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski /* ----- BEGIN android ----- 2011d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski private native String[] getMetaInfEntryNames();*/ 2021d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski 2031d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski private String[] getMetaInfEntryNames() { 2041d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski List<String> list = new ArrayList<String>(8); 2051d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski 2061d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski Enumeration<? extends ZipEntry> allEntries = entries(); 2071d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski while (allEntries.hasMoreElements()) { 2081d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski ZipEntry ze = allEntries.nextElement(); 2091d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski if (ze.getName().startsWith(META_DIR) 2101d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski && ze.getName().length() > META_DIR.length()) { 2111d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski list.add(ze.getName()); 2121d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski } 2131d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski } 2141d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski return list.toArray(new String[list.size()]); 2151d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski } 2161d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski // ----- END android ----- 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the <code>JarEntry</code> for the given entry name or 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>null</code> if not found. 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the jar file entry name 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the <code>JarEntry</code> for the given entry name or 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>null</code> if not found. 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalStateException 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * may be thrown if the jar file has been closed 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.util.jar.JarEntry 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public JarEntry getJarEntry(String name) { 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (JarEntry)getEntry(name); 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the <code>ZipEntry</code> for the given entry name or 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>null</code> if not found. 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the jar file entry name 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the <code>ZipEntry</code> for the given entry name or 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>null</code> if not found 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalStateException 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * may be thrown if the jar file has been closed 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.util.zip.ZipEntry 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public ZipEntry getEntry(String name) { 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ZipEntry ze = super.getEntry(name); 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ze != null) { 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new JarFileEntry(ze); 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns an enumeration of the zip file entries. 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Enumeration<JarEntry> entries() { 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final Enumeration enum_ = super.entries(); 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new Enumeration<JarEntry>() { 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean hasMoreElements() { 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return enum_.hasMoreElements(); 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public JarFileEntry nextElement() { 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ZipEntry ze = (ZipEntry)enum_.nextElement(); 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new JarFileEntry(ze); 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski }; 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private class JarFileEntry extends JarEntry { 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarFileEntry(ZipEntry ze) { 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(ze); 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Attributes getAttributes() throws IOException { 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Manifest man = JarFile.this.getManifest(); 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (man != null) { 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return man.getAttributes(getName()); 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Certificate[] getCertificates() { 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski maybeInstantiateVerifier(); 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException e) { 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new RuntimeException(e); 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (certs == null && jv != null) { 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski certs = jv.getCerts(JarFile.this, this); 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return certs == null ? null : certs.clone(); 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public CodeSigner[] getCodeSigners() { 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski maybeInstantiateVerifier(); 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException e) { 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new RuntimeException(e); 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (signers == null && jv != null) { 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signers = jv.getCodeSigners(JarFile.this, this); 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return signers == null ? null : signers.clone(); 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Ensures that the JarVerifier has been created if one is 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * necessary (i.e., the jar appears to be signed.) This is done as 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a quick check to avoid processing of the manifest for unsigned 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * jars. 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void maybeInstantiateVerifier() throws IOException { 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jv != null) { 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (verify) { 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String[] names = getMetaInfEntryNames(); 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (names != null) { 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < names.length; i++) { 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String name = names[i].toUpperCase(Locale.ENGLISH); 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name.endsWith(".DSA") || 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name.endsWith(".RSA") || 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name.endsWith(".EC") || 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name.endsWith(".SF")) { 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Assume since we found a signature-related file 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // that the jar is signed and that we therefore 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // need a JarVerifier and Manifest 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getManifest(); 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // No signature-related files; don't instantiate a 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // verifier 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski verify = false; 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Initializes the verifier object by reading all the manifest 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * entries and passing them to the verifier. 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void initializeVerifier() { 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ManifestEntryVerifier mev = null; 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Verify "META-INF/" entries... 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String[] names = getMetaInfEntryNames(); 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (names != null) { 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < names.length; i++) { 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarEntry e = getJarEntry(names[i]); 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (e == null) { 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new JarException("corrupted jar file"); 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!e.isDirectory()) { 36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (mev == null) { 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mev = new ManifestEntryVerifier 36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (getManifestFromReference()); 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] b = getBytes(e); 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (b != null && b.length > 0) { 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv.beginEntry(e, mev); 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv.update(b.length, b, 0, b.length, mev); 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv.update(-1, null, 0, 0, mev); 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ex) { 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if we had an error parsing any blocks, just 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // treat the jar file as being unsigned 37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv = null; 37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski verify = false; 37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (JarVerifier.debug != null) { 37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarVerifier.debug.println("jarfile parsing error!"); 38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ex.printStackTrace(); 38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if after initializing the verifier we have nothing 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // signed, we null it out. 38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jv != null) { 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv.doneWithMeta(); 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (JarVerifier.debug != null) { 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarVerifier.debug.println("done with meta!"); 39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jv.nothingToVerify()) { 39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (JarVerifier.debug != null) { 39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarVerifier.debug.println("nothing to verify!"); 39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv = null; 39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski verify = false; 40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads all the bytes for a given entry. Used to process the 40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * META-INF files. 40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private byte[] getBytes(ZipEntry ze) throws IOException { 40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try (InputStream is = super.getInputStream(ze)) { 41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOUtils.readFully(is, (int)ze.getSize(), true); 41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns an input stream for reading the contents of the specified 41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * zip file entry. 41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param ze the zip file entry 41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return an input stream for reading the contents of the specified 41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * zip file entry 42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws ZipException if a zip file format error has occurred 42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if an I/O error has occurred 42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SecurityException if any of the jar file entries 42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are incorrectly signed. 42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalStateException 42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * may be thrown if the jar file has been closed 42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized InputStream getInputStream(ZipEntry ze) 42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski maybeInstantiateVerifier(); 43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jv == null) { 43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return super.getInputStream(ze); 43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!jvInitialized) { 43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski initializeVerifier(); 43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jvInitialized = true; 43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // could be set to null after a call to 43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // initializeVerifier if we have nothing to 43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // verify 44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jv == null) 44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return super.getInputStream(ze); 44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // wrap a verifier stream around the real stream 44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new JarVerifier.VerifierStream( 44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getManifestFromReference(), 44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ze instanceof JarFileEntry ? 44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (JarEntry) ze : getJarEntry(ze.getName()), 44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super.getInputStream(ze), 45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv); 45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Statics for hand-coded Boyer-Moore search in hasClassPathAttribute() 45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // The bad character shift for "class-path" 45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static int[] lastOcc; 45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // The good suffix shift for "class-path" 45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static int[] optoSft; 45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Initialize the shift arrays to search for "class-path" 45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static char[] src = {'c','l','a','s','s','-','p','a','t','h'}; 46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static { 46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastOcc = new int[128]; 46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski optoSft = new int[10]; 46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastOcc[(int)'c']=1; 46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastOcc[(int)'l']=2; 46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastOcc[(int)'s']=5; 46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastOcc[(int)'-']=6; 46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastOcc[(int)'p']=7; 46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastOcc[(int)'a']=8; 46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastOcc[(int)'t']=9; 47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lastOcc[(int)'h']=10; 47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i=0; i<9; i++) 47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski optoSft[i]=10; 47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski optoSft[9]=1; 47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private JarEntry getManEntry() { 47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (manEntry == null) { 47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // First look up manifest entry using standard name 47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski manEntry = getJarEntry(MANIFEST_NAME); 48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (manEntry == null) { 48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If not found, then iterate through all the "META-INF/" 48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // entries to find a match. 48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String[] names = getMetaInfEntryNames(); 48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (names != null) { 48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < names.length; i++) { 48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (MANIFEST_NAME.equals( 48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski names[i].toUpperCase(Locale.ENGLISH))) { 48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski manEntry = getJarEntry(names[i]); 48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return manEntry; 49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Returns true iff this jar file has a manifest with a class path 49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // attribute. Returns false if there is no manifest or the manifest 50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // does not contain a "Class-Path" attribute. Currently exported to 50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // core libraries via sun.misc.SharedSecrets. 50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean hasClassPathAttribute() throws IOException { 50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (computedHasClassPathAttribute) { 50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return hasClassPathAttribute; 50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski hasClassPathAttribute = false; 50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isKnownToNotHaveClassPathAttribute()) { 50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarEntry manEntry = getManEntry(); 51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (manEntry != null) { 51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] b = getBytes(manEntry); 51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int last = b.length - src.length; 51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int i = 0; 51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski next: 51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (i<=last) { 51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int j=9; j>=0; j--) { 51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char c = (char) b[i+j]; 51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c = (((c-'A')|('Z'-c)) >= 0) ? (char)(c + 32) : c; 51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (c != src[j]) { 52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski i += Math.max(j + 1 - lastOcc[c&0x7F], optoSft[j]); 52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue next; 52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski hasClassPathAttribute = true; 52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski computedHasClassPathAttribute = true; 53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return hasClassPathAttribute; 53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static String javaHome; 53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static String[] jarNames; 53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean isKnownToNotHaveClassPathAttribute() { 53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Optimize away even scanning of manifest for jar files we 53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // deliver which don't have a class-path attribute. If one of 53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // these jars is changed to include such an attribute this code 53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // must be changed. 54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (javaHome == null) { 54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski javaHome = AccessController.doPrivileged( 54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new GetPropertyAction("java.home")); 54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jarNames == null) { 54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String[] names = new String[10]; 54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String fileSep = File.separator; 54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int i = 0; 54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski names[i++] = fileSep + "rt.jar"; 54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski names[i++] = fileSep + "sunrsasign.jar"; 55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski names[i++] = fileSep + "jsse.jar"; 55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski names[i++] = fileSep + "jce.jar"; 55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski names[i++] = fileSep + "charsets.jar"; 55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski names[i++] = fileSep + "dnsns.jar"; 55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski names[i++] = fileSep + "ldapsec.jar"; 55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski names[i++] = fileSep + "localedata.jar"; 55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski names[i++] = fileSep + "sunjce_provider.jar"; 55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski names[i++] = fileSep + "sunpkcs11.jar"; 55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jarNames = names; 55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String name = getName(); 56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String localJavaHome = javaHome; 56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name.startsWith(localJavaHome)) { 56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String[] names = jarNames; 56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < names.length; i++) { 56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name.endsWith(names[i])) { 56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private synchronized void ensureInitialization() { 57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski maybeInstantiateVerifier(); 57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException e) { 57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new RuntimeException(e); 57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jv != null && !jvInitialized) { 58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski initializeVerifier(); 58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jvInitialized = true; 58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarEntry newEntry(ZipEntry ze) { 58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new JarFileEntry(ze); 58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Enumeration<String> entryNames(CodeSource[] cs) { 59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureInitialization(); 59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jv != null) { 59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return jv.entryNames(this, cs); 59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * JAR file has no signed content. Is there a non-signing 59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * code source? 59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean includeUnsigned = false; 60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < cs.length; i++) { 60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cs[i].getCodeSigners() == null) { 60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski includeUnsigned = true; 60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 60551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (includeUnsigned) { 60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return unsignedEntryNames(); 60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new Enumeration<String>() { 61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean hasMoreElements() { 61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String nextElement() { 61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NoSuchElementException(); 61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 61951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski }; 62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 62151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 62251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 62351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 62451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns an enumeration of the zip file entries 62551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * excluding internal JAR mechanism entries and including 62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * signed entries missing from the ZIP directory. 62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 62851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Enumeration<JarEntry> entries2() { 62951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureInitialization(); 63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jv != null) { 63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return jv.entries2(this, super.entries()); 63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // screen out entries which are never signed 63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final Enumeration enum_ = super.entries(); 63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new Enumeration<JarEntry>() { 63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ZipEntry entry; 63951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean hasMoreElements() { 64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (entry != null) { 64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (enum_.hasMoreElements()) { 64551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ZipEntry ze = (ZipEntry) enum_.nextElement(); 64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (JarVerifier.isSigningRelated(ze.getName())) { 64751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 64851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski entry = ze; 65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 65151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 65251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 65351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 65551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public JarFileEntry nextElement() { 65651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (hasMoreElements()) { 65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ZipEntry ze = entry; 65851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski entry = null; 65951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new JarFileEntry(ze); 66051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NoSuchElementException(); 66251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 66351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski }; 66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 66651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CodeSource[] getCodeSources(URL url) { 66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureInitialization(); 66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jv != null) { 66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return jv.getCodeSources(this, url); 67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * JAR file has no signed content. Is there a non-signing 67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * code source? 67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Enumeration unsigned = unsignedEntryNames(); 67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (unsigned.hasMoreElements()) { 67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new CodeSource[]{JarVerifier.getUnsignedCS(url)}; 67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 68051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 68151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 68251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 68351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 68451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Enumeration<String> unsignedEntryNames() { 68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final Enumeration entries = entries(); 68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new Enumeration<String>() { 68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String name; 68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Grab entries from ZIP directory but screen out 69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * metadata. 69351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean hasMoreElements() { 69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name != null) { 69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 69751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (entries.hasMoreElements()) { 69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String value; 70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ZipEntry e = (ZipEntry) entries.nextElement(); 70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value = e.getName(); 70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (e.isDirectory() || JarVerifier.isSigningRelated(value)) { 70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name = value; 70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 71151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String nextElement() { 71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (hasMoreElements()) { 71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String value = name; 71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name = null; 71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return value; 71651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 71751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NoSuchElementException(); 71851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 71951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski }; 72051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 72151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 72251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CodeSource getCodeSource(URL url, String name) { 72351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureInitialization(); 72451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jv != null) { 72551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jv.eagerValidation) { 72651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CodeSource cs = null; 72751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarEntry je = getJarEntry(name); 72851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (je != null) { 72951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cs = jv.getCodeSource(url, this, je); 73051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 73151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cs = jv.getCodeSource(url, name); 73251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return cs; 73451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 73551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return jv.getCodeSource(url, name); 73651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 73951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return JarVerifier.getUnsignedCS(url); 74051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 74151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 74251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void setEagerValidation(boolean eager) { 74351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 74451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski maybeInstantiateVerifier(); 74551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException e) { 74651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new RuntimeException(e); 74751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 74851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jv != null) { 74951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv.setEagerValidation(eager); 75051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 75151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 75251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 75351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List getManifestDigests() { 75451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureInitialization(); 75551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jv != null) { 75651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return jv.getManifestDigests(); 75751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 75851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new ArrayList(); 75951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 76051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 761