151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project 303d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.util.jar; 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.*; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.lang.ref.SoftReference; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.*; 3203d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniakimport java.util.stream.Stream; 3303d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniakimport java.util.stream.StreamSupport; 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.zip.*; 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.CodeSigner; 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.cert.Certificate; 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.AccessController; 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.misc.IOUtils; 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.action.GetPropertyAction; 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.util.ManifestEntryVerifier; 4103d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniakimport sun.security.util.SignatureFileVerifier; 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The <code>JarFile</code> class is used to read the contents of a jar file 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * from any file that can be opened with <code>java.io.RandomAccessFile</code>. 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * It extends the class <code>java.util.zip.ZipFile</code> with support 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for reading an optional <code>Manifest</code> entry. The 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>Manifest</code> can be used to specify meta-information about the 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * jar file and its entries. 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or method in this class will cause a {@link NullPointerException} to be 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * thrown. 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 5503d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak * If the verify flag is on when opening a signed jar file, the content of the 5603d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak * file is verified against its signature embedded inside the file. Please note 5703d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak * that the verification process does not include validating the signer's 5803d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak * certificate. A caller should inspect the return value of 5903d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak * {@link JarEntry#getCodeSigners()} to further determine if the signature 6003d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak * can be trusted. 6103d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak * 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author David Connelly 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see Manifest 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.util.zip.ZipFile 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.util.jar.JarEntry 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.2 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass JarFile extends ZipFile { 701d958dba8b5c9589e3375446045e1672eee0e1b1Piotr Jastrzebski static final String META_DIR = "META-INF/"; 7145908408e773e57f09677ab5a84fd3733e156f95Narayan Kamath private Manifest manifest; 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private JarEntry manEntry; 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private JarVerifier jv; 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean jvInitialized; 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean verify; 7603d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak 7703d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak // indicates if Class-Path attribute present (only valid if hasCheckedSpecialAttributes true) 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean hasClassPathAttribute; 7903d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak // true if manifest checked for special attributes 8003d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak private volatile boolean hasCheckedSpecialAttributes; 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 17103d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak * @throws IOException if an I/O error has occurred 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Manifest getManifest() throws IOException { 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getManifestFromReference(); 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 177592f49a571c5d093dd91c647f9df80a0dd527caeSergio Giro private synchronized Manifest getManifestFromReference() throws IOException { 17845908408e773e57f09677ab5a84fd3733e156f95Narayan Kamath if (manifest == null) { 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarEntry manEntry = getManEntry(); 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If found then load the manifest 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (manEntry != null) { 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (verify) { 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] b = getBytes(manEntry); 18645908408e773e57f09677ab5a84fd3733e156f95Narayan Kamath manifest = new Manifest(new ByteArrayInputStream(b)); 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!jvInitialized) { 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv = new JarVerifier(b); 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 19145908408e773e57f09677ab5a84fd3733e156f95Narayan Kamath manifest = new Manifest(super.getInputStream(manEntry)); 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19545908408e773e57f09677ab5a84fd3733e156f95Narayan Kamath return manifest; 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 198de81def7a777e4423771ee15b49bedd05c7fdbf5Narayan Kamath private native String[] getMetaInfEntryNames(); 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the <code>JarEntry</code> for the given entry name or 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>null</code> if not found. 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the jar file entry name 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the <code>JarEntry</code> for the given entry name or 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>null</code> if not found. 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalStateException 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * may be thrown if the jar file has been closed 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.util.jar.JarEntry 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public JarEntry getJarEntry(String name) { 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (JarEntry)getEntry(name); 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the <code>ZipEntry</code> for the given entry name or 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>null</code> if not found. 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the jar file entry name 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the <code>ZipEntry</code> for the given entry name or 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>null</code> if not found 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalStateException 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * may be thrown if the jar file has been closed 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.util.zip.ZipEntry 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public ZipEntry getEntry(String name) { 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ZipEntry ze = super.getEntry(name); 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ze != null) { 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new JarFileEntry(ze); 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23803d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak private class JarEntryIterator implements Enumeration<JarEntry>, 23903d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak Iterator<JarEntry> 24003d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak { 24103d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak final Enumeration<? extends ZipEntry> e = JarFile.super.entries(); 24203d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak 24303d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak public boolean hasNext() { 24403d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak return e.hasMoreElements(); 24503d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak } 24603d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak 24703d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak public JarEntry next() { 24803d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak ZipEntry ze = e.nextElement(); 24903d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak return new JarFileEntry(ze); 25003d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak } 25103d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak 25203d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak public boolean hasMoreElements() { 25303d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak return hasNext(); 25403d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak } 25503d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak 25603d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak public JarEntry nextElement() { 25703d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak return next(); 25803d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak } 25903d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak } 26003d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns an enumeration of the zip file entries. 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Enumeration<JarEntry> entries() { 26503d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak return new JarEntryIterator(); 26603d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak } 26703d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak 26803d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak @Override 26903d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak public Stream<JarEntry> stream() { 27003d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak return StreamSupport.stream(Spliterators.spliterator( 27103d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak new JarEntryIterator(), size(), 27203d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak Spliterator.ORDERED | Spliterator.DISTINCT | 27303d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak Spliterator.IMMUTABLE | Spliterator.NONNULL), false); 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private class JarFileEntry extends JarEntry { 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarFileEntry(ZipEntry ze) { 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(ze); 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Attributes getAttributes() throws IOException { 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Manifest man = JarFile.this.getManifest(); 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (man != null) { 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return man.getAttributes(getName()); 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Certificate[] getCertificates() { 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski maybeInstantiateVerifier(); 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException e) { 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new RuntimeException(e); 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (certs == null && jv != null) { 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski certs = jv.getCerts(JarFile.this, this); 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return certs == null ? null : certs.clone(); 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public CodeSigner[] getCodeSigners() { 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski maybeInstantiateVerifier(); 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException e) { 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new RuntimeException(e); 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (signers == null && jv != null) { 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski signers = jv.getCodeSigners(JarFile.this, this); 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return signers == null ? null : signers.clone(); 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Ensures that the JarVerifier has been created if one is 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * necessary (i.e., the jar appears to be signed.) This is done as 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a quick check to avoid processing of the manifest for unsigned 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * jars. 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void maybeInstantiateVerifier() throws IOException { 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jv != null) { 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (verify) { 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String[] names = getMetaInfEntryNames(); 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (names != null) { 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < names.length; i++) { 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String name = names[i].toUpperCase(Locale.ENGLISH); 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name.endsWith(".DSA") || 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name.endsWith(".RSA") || 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name.endsWith(".EC") || 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name.endsWith(".SF")) { 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Assume since we found a signature-related file 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // that the jar is signed and that we therefore 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // need a JarVerifier and Manifest 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getManifest(); 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // No signature-related files; don't instantiate a 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // verifier 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski verify = false; 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Initializes the verifier object by reading all the manifest 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * entries and passing them to the verifier. 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void initializeVerifier() { 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ManifestEntryVerifier mev = null; 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Verify "META-INF/" entries... 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String[] names = getMetaInfEntryNames(); 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (names != null) { 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < names.length; i++) { 35903d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak String uname = names[i].toUpperCase(Locale.ENGLISH); 36003d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak if (MANIFEST_NAME.equals(uname) 36103d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak || SignatureFileVerifier.isBlockOrSF(uname)) { 36203d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak JarEntry e = getJarEntry(names[i]); 36303d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak if (e == null) { 36403d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak throw new JarException("corrupted jar file"); 36503d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak } 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (mev == null) { 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mev = new ManifestEntryVerifier 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (getManifestFromReference()); 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] b = getBytes(e); 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (b != null && b.length > 0) { 37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv.beginEntry(e, mev); 37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv.update(b.length, b, 0, b.length, mev); 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv.update(-1, null, 0, 0, mev); 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ex) { 38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if we had an error parsing any blocks, just 38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // treat the jar file as being unsigned 38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv = null; 38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski verify = false; 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (JarVerifier.debug != null) { 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarVerifier.debug.println("jarfile parsing error!"); 38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ex.printStackTrace(); 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if after initializing the verifier we have nothing 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // signed, we null it out. 39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jv != null) { 39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv.doneWithMeta(); 39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (JarVerifier.debug != null) { 39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarVerifier.debug.println("done with meta!"); 39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jv.nothingToVerify()) { 40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (JarVerifier.debug != null) { 40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarVerifier.debug.println("nothing to verify!"); 40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv = null; 40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski verify = false; 40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads all the bytes for a given entry. Used to process the 41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * META-INF files. 41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private byte[] getBytes(ZipEntry ze) throws IOException { 41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try (InputStream is = super.getInputStream(ze)) { 41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOUtils.readFully(is, (int)ze.getSize(), true); 41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns an input stream for reading the contents of the specified 42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * zip file entry. 42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param ze the zip file entry 42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return an input stream for reading the contents of the specified 42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * zip file entry 42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws ZipException if a zip file format error has occurred 42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if an I/O error has occurred 42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SecurityException if any of the jar file entries 42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are incorrectly signed. 43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalStateException 43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * may be thrown if the jar file has been closed 43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized InputStream getInputStream(ZipEntry ze) 43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski maybeInstantiateVerifier(); 43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jv == null) { 43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return super.getInputStream(ze); 43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!jvInitialized) { 44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski initializeVerifier(); 44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jvInitialized = true; 44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // could be set to null after a call to 44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // initializeVerifier if we have nothing to 44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // verify 44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jv == null) 44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return super.getInputStream(ze); 44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // wrap a verifier stream around the real stream 45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new JarVerifier.VerifierStream( 45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getManifestFromReference(), 45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ze instanceof JarFileEntry ? 45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (JarEntry) ze : getJarEntry(ze.getName()), 45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super.getInputStream(ze), 45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jv); 45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 45903d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak // Statics for hand-coded Boyer-Moore search 46003d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak private static final char[] CLASSPATH_CHARS = {'c','l','a','s','s','-','p','a','t','h'}; 46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // The bad character shift for "class-path" 46203d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak private static final int[] CLASSPATH_LASTOCC; 46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // The good suffix shift for "class-path" 46403d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak private static final int[] CLASSPATH_OPTOSFT; 46503d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak 46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static { 46703d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak CLASSPATH_LASTOCC = new int[128]; 46803d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak CLASSPATH_OPTOSFT = new int[10]; 46903d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak CLASSPATH_LASTOCC[(int)'c'] = 1; 47003d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak CLASSPATH_LASTOCC[(int)'l'] = 2; 47103d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak CLASSPATH_LASTOCC[(int)'s'] = 5; 47203d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak CLASSPATH_LASTOCC[(int)'-'] = 6; 47303d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak CLASSPATH_LASTOCC[(int)'p'] = 7; 47403d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak CLASSPATH_LASTOCC[(int)'a'] = 8; 47503d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak CLASSPATH_LASTOCC[(int)'t'] = 9; 47603d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak CLASSPATH_LASTOCC[(int)'h'] = 10; 47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i=0; i<9; i++) 47803d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak CLASSPATH_OPTOSFT[i] = 10; 47903d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak CLASSPATH_OPTOSFT[9]=1; 48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 482592f49a571c5d093dd91c647f9df80a0dd527caeSergio Giro private synchronized JarEntry getManEntry() { 48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (manEntry == null) { 48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // First look up manifest entry using standard name 48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski manEntry = getJarEntry(MANIFEST_NAME); 48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (manEntry == null) { 48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If not found, then iterate through all the "META-INF/" 48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // entries to find a match. 48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String[] names = getMetaInfEntryNames(); 49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (names != null) { 49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < names.length; i++) { 49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (MANIFEST_NAME.equals( 49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski names[i].toUpperCase(Locale.ENGLISH))) { 49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski manEntry = getJarEntry(names[i]); 49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return manEntry; 50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 50400b71736c88addbe7cb5fa00b194695dde40a3a6Przemyslaw Szczepaniak /** 50503d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak * Returns {@code true} iff this JAR file has a manifest with the 50603d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak * Class-Path attribute 507f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski * @hide 508f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski */ 509f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski public boolean hasClassPathAttribute() throws IOException { 51003d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak checkForSpecialAttributes(); 51103d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak return hasClassPathAttribute; 51203d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak } 51303d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak 51403d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak /** 51503d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak * Returns true if the pattern {@code src} is found in {@code b}. 51603d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak * The {@code lastOcc} and {@code optoSft} arrays are the precomputed 51703d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak * bad character and good suffix shifts. 51803d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak */ 51903d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak private boolean match(char[] src, byte[] b, int[] lastOcc, int[] optoSft) { 52003d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak int len = src.length; 52103d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak int last = b.length - len; 52203d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak int i = 0; 52303d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak next: 52403d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak while (i<=last) { 52503d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak for (int j=(len-1); j>=0; j--) { 52603d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak char c = (char) b[i+j]; 52703d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak c = (((c-'A')|('Z'-c)) >= 0) ? (char)(c + 32) : c; 52803d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak if (c != src[j]) { 52903d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak i += Math.max(j + 1 - lastOcc[c&0x7F], optoSft[j]); 53003d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak continue next; 53103d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak } 53203d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak } 53303d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak return true; 53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 53503d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak return false; 53603d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak } 53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 53803d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak /** 53903d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak * On first invocation, check if the JAR file has the Class-Path 54003d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak * attribute. A no-op on subsequent calls. 54103d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak */ 54203d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak private void checkForSpecialAttributes() throws IOException { 54303d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak if (hasCheckedSpecialAttributes) return; 54403d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak // Android-changed: Doesn't make sense on android: 54503d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak //if (!isKnownNotToHaveSpecialAttributes()) { 54603d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak { 54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarEntry manEntry = getManEntry(); 54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (manEntry != null) { 54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] b = getBytes(manEntry); 55003d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak if (match(CLASSPATH_CHARS, b, CLASSPATH_LASTOCC, CLASSPATH_OPTOSFT)) 55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski hasClassPathAttribute = true; 55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55403d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak hasCheckedSpecialAttributes = true; 55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 55703d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak 55803d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak // Android-changed: Doesn't make sense on android: 55903d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak /*private static String javaHome; 56003d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak private static volatile String[] jarNames; 56103d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak private boolean isKnownNotToHaveSpecialAttributes() { 56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Optimize away even scanning of manifest for jar files we 56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // deliver which don't have a class-path attribute. If one of 56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // these jars is changed to include such an attribute this code 56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // must be changed. 56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (javaHome == null) { 56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski javaHome = AccessController.doPrivileged( 56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new GetPropertyAction("java.home")); 56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (jarNames == null) { 57103d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak String[] names = new String[11]; 57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String fileSep = File.separator; 57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int i = 0; 57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski names[i++] = fileSep + "rt.jar"; 57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski names[i++] = fileSep + "jsse.jar"; 57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski names[i++] = fileSep + "jce.jar"; 57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski names[i++] = fileSep + "charsets.jar"; 57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski names[i++] = fileSep + "dnsns.jar"; 57903d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak names[i++] = fileSep + "zipfs.jar"; 58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski names[i++] = fileSep + "localedata.jar"; 58103d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak names[i++] = fileSep = "cldrdata.jar"; 58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski names[i++] = fileSep + "sunjce_provider.jar"; 58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski names[i++] = fileSep + "sunpkcs11.jar"; 58403d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak names[i++] = fileSep + "sunec.jar"; 58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jarNames = names; 58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String name = getName(); 58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String localJavaHome = javaHome; 59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name.startsWith(localJavaHome)) { 59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String[] names = jarNames; 59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < names.length; i++) { 59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name.endsWith(names[i])) { 59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 59903d2687dfc9b84bb16ea2b5f6a85da539696b30cPrzemyslaw Szczepaniak }*/ 60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JarEntry newEntry(ZipEntry ze) { 60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new JarFileEntry(ze); 60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 605