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