diff --git a/src/share/classes/java/util/jar/JarInputStream.java b/src/share/classes/java/util/jar/JarInputStream.java index a22c9372bc8f15537c3508d532b2d8b7ef7bc546..15818c932a6841653c722db34696959c43dd323f 100644 --- a/src/share/classes/java/util/jar/JarInputStream.java +++ b/src/share/classes/java/util/jar/JarInputStream.java @@ -28,6 +28,7 @@ package java.util.jar; import java.util.zip.*; import java.io.*; import sun.security.util.ManifestEntryVerifier; +import sun.misc.JarIndex; /** * The JarInputStream class is used to read the contents of @@ -47,7 +48,8 @@ class JarInputStream extends ZipInputStream { private JarEntry first; private JarVerifier jv; private ManifestEntryVerifier mev; - + private final boolean doVerify; + private boolean tryManifest; /** * Creates a new JarInputStream and reads the optional @@ -72,25 +74,33 @@ class JarInputStream extends ZipInputStream { */ public JarInputStream(InputStream in, boolean verify) throws IOException { super(in); - JarEntry e = (JarEntry)super.getNextEntry(); + this.doVerify = verify; + // This implementation assumes the META-INF/MANIFEST.MF entry + // should be either the first or the second entry (when preceded + // by the dir META-INF/). It skips the META-INF/ and then + // "consumes" the MANIFEST.MF to initialize the Manifest object. + JarEntry e = (JarEntry)super.getNextEntry(); if (e != null && e.getName().equalsIgnoreCase("META-INF/")) e = (JarEntry)super.getNextEntry(); + first = checkManifest(e); + } + private JarEntry checkManifest(JarEntry e) + throws IOException + { if (e != null && JarFile.MANIFEST_NAME.equalsIgnoreCase(e.getName())) { man = new Manifest(); byte bytes[] = getBytes(new BufferedInputStream(this)); man.read(new ByteArrayInputStream(bytes)); - //man.read(new BufferedInputStream(this)); closeEntry(); - if (verify) { + if (doVerify) { jv = new JarVerifier(bytes); mev = new ManifestEntryVerifier(man); } - first = getNextJarEntry(); - } else { - first = e; + return (JarEntry)super.getNextEntry(); } + return e; } private byte[] getBytes(InputStream is) @@ -98,10 +108,7 @@ class JarInputStream extends ZipInputStream { { byte[] buffer = new byte[8192]; ByteArrayOutputStream baos = new ByteArrayOutputStream(2048); - int n; - - baos.reset(); while ((n = is.read(buffer, 0, buffer.length)) != -1) { baos.write(buffer, 0, n); } @@ -133,8 +140,14 @@ class JarInputStream extends ZipInputStream { JarEntry e; if (first == null) { e = (JarEntry)super.getNextEntry(); + if (tryManifest) { + e = checkManifest(e); + tryManifest = false; + } } else { e = first; + if (first.getName().equalsIgnoreCase(JarIndex.INDEX_NAME)) + tryManifest = true; first = null; } if (jv != null && e != null) { diff --git a/test/java/util/jar/JarInputStream/BadSignedJar.jar b/test/java/util/jar/JarInputStream/BadSignedJar.jar new file mode 100644 index 0000000000000000000000000000000000000000..651c9ff3dd08818a97f506c1389a473fed1aab8b Binary files /dev/null and b/test/java/util/jar/JarInputStream/BadSignedJar.jar differ diff --git a/test/java/util/jar/JarInputStream/TestIndexedJarWithBadSignature.java b/test/java/util/jar/JarInputStream/TestIndexedJarWithBadSignature.java new file mode 100644 index 0000000000000000000000000000000000000000..977c10121dad0d19aba947a19a222e4136a1122a --- /dev/null +++ b/test/java/util/jar/JarInputStream/TestIndexedJarWithBadSignature.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6544278 + * @summary Confirm the JarInputStream throws the SecurityException when + * verifying an indexed jar file with corrupted signature + */ + +import java.io.IOException; +import java.io.FileInputStream; +import java.util.jar.JarEntry; +import java.util.jar.JarInputStream; + +public class TestIndexedJarWithBadSignature { + + public static void main(String...args) throws Throwable { + try (JarInputStream jis = new JarInputStream( + new FileInputStream(System.getProperty("tst.src", ".") + + System.getProperty("file.separator") + + "BadSignedJar.jar"))) + { + JarEntry je1 = jis.getNextJarEntry(); + while(je1!=null){ + System.out.println("Jar Entry1==>"+je1.getName()); + je1 = jis.getNextJarEntry(); // This should throw Security Exception + } + throw new RuntimeException( + "Test Failed:Security Exception not being thrown"); + } catch (IOException ie){ + ie.printStackTrace(); + } catch (SecurityException e) { + System.out.println("Test passed: Security Exception thrown as expected"); + } + } +}