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