Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/security/tools/jarsigner/EntriesOrder.java
38853 views
/*1* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/**24* @test25* @bug 803157226* @summary jarsigner -verify exits with 0 when a jar file is not properly signed27* @library /lib/testlibrary28* @build jdk.testlibrary.IOUtils29* @run main EntriesOrder30*/3132import java.io.FileInputStream;33import java.io.FileOutputStream;34import java.nio.file.Files;35import java.nio.file.Paths;36import java.security.cert.Certificate;37import java.util.*;38import java.util.jar.JarEntry;39import java.util.jar.JarFile;40import java.util.jar.JarInputStream;41import java.util.zip.ZipEntry;42import java.util.zip.ZipOutputStream;4344import jdk.testlibrary.IOUtils;4546public class EntriesOrder {4748public static void main(String[] args) throws Exception {4950String[] entries = {51"META-INF/",52"META-INF/MANIFEST.MF",53"META-INF/A.RSA",54"META-INF/A.SF",55"META-INF/inf",56"a"};5758Map<String,byte[]> content = new HashMap<>();5960// We will create a jar containing entries above. Try all permutations61// and confirm 1) When opened as a JarFile, we can always get 3 signed62// ones (MANIFEST, inf, a), and 2) When opened as a JarInputStream,63// when the order is correct (MANIFEST at beginning, followed by RSA/SF,64// directory ignored), we can get 2 signed ones (inf, a).6566// Prepares raw files67Files.write(Paths.get("a"), "a".getBytes());68Files.createDirectory(Paths.get("META-INF/"));69Files.write(Paths.get("META-INF/inf"), "inf".getBytes());7071// Pack, sign, and extract to get all files72sun.tools.jar.Main m =73new sun.tools.jar.Main(System.out, System.err, "jar");74if (!m.run("cvf a.jar a META-INF/inf".split(" "))) {75throw new Exception("jar creation failed");76}77sun.security.tools.keytool.Main.main(78("-keystore jks -storepass changeit -keypass changeit -dname" +79" CN=A -alias a -genkeypair -keyalg rsa").split(" "));80sun.security.tools.jarsigner.Main.main(81"-keystore jks -storepass changeit a.jar a".split(" "));82m = new sun.tools.jar.Main(System.out, System.err, "jar");83if (!m.run("xvf a.jar".split(" "))) {84throw new Exception("jar extraction failed");85}8687// Data88for (String s: entries) {89if (!s.endsWith("/")) {90content.put(s, Files.readAllBytes(Paths.get(s)));91}92}9394// Test95for (List<String> perm: Permute(entries)) {9697// Recreate a jar98try (ZipOutputStream zos99= new ZipOutputStream(new FileOutputStream("x.jar"))) {100for (String e: perm) {101zos.putNextEntry(new ZipEntry(e));102if (Paths.get(e).toFile().isDirectory()) continue;103zos.write(content.get(e));104}105}106107// Open with JarFile, number of signed entries should be 3.108int cc = 0;109try (JarFile jf = new JarFile("x.jar")) {110Enumeration<JarEntry> jes = jf.entries();111while (jes.hasMoreElements()) {112JarEntry je = jes.nextElement();113IOUtils.readFully(jf.getInputStream(je));114Certificate[] certs = je.getCertificates();115if (certs != null && certs.length > 0) {116cc++;117}118}119}120121if (cc != 3) {122System.out.println(perm + " - jf - " + cc);123throw new Exception();124}125126// Open with JarInputStream127int signed;128129perm.remove("META-INF/");130if (perm.get(0).equals("META-INF/MANIFEST.MF") &&131perm.get(1).contains("/A.") &&132perm.get(2).contains("/A.")) {133signed = 2; // Good order134} else {135signed = 0; // Bad order. In this case, the number of signed136// entries is not documented. Just test impl.137}138139cc = 0;140try (JarInputStream jis141= new JarInputStream(new FileInputStream("x.jar"))) {142while (true) {143JarEntry je = jis.getNextJarEntry();144if (je == null) break;145IOUtils.readFully(jis);146Certificate[] certs = je.getCertificates();147if (certs != null && certs.length > 0) {148cc++;149}150}151}152153if (cc != signed) {154System.out.println(perm + " - jis - " + cc + " " + signed);155throw new Exception();156}157}158}159160// Helper method to return all permutations of an array. Each output can161// be altered without damaging the iteration process.162static Iterable<List<String>> Permute(String[] entries) {163return new Iterable<List<String>>() {164165int s = entries.length;166long c = factorial(s) - 1; // number of permutations167168private long factorial(int n) {169return (n == 1) ? 1: (n * factorial(n-1));170}171172@Override173public Iterator<List<String>> iterator() {174return new Iterator<List<String>>() {175@Override176public boolean hasNext() {177return c >= 0;178}179180@Override181public List<String> next() {182if (c < 0) return null;183List<String> result = new ArrayList<>(s);184LinkedList<String> source = new LinkedList<>(185Arrays.asList(entries));186// Treat c as a integer with different radixes at187// different digits, i.e. at digit 0, radix is s;188// at digit 1, radix is s-1. Thus a s-digit number189// is able to represent s! different values.190long n = c;191for (int i=s; i>=1; i--) {192int x = (int)(n % i);193result.add(source.remove(x));194n = n / i;195}196c--;197return result;198}199};200}201};202}203}204205206