Path: blob/master/test/jdk/sun/security/tools/jarsigner/ConciseJarsigner.java
66645 views
/*1* Copyright (c) 2009, 2021, 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 6802846 8172529 8227758 826096026* @summary jarsigner needs enhanced cert validation(options)27* @library /test/lib28* @run main/timeout=240 ConciseJarsigner29*/3031import jdk.test.lib.Asserts;32import jdk.test.lib.SecurityTools;33import jdk.test.lib.process.OutputAnalyzer;3435import java.nio.file.Files;36import java.nio.file.Path;37import java.util.Calendar;38import java.util.List;3940public class ConciseJarsigner {4142static OutputAnalyzer kt(String cmd) throws Exception {43// Choose 2048-bit RSA to make sure it runs fine and fast. In44// fact, every keyalg/keysize combination is OK for this test.45return SecurityTools.keytool("-storepass changeit -keypass changeit "46+ "-keystore ks -keyalg rsa -keysize 2048 " + cmd);47}4849static void gencert(String owner, String cmd) throws Exception {50kt("-certreq -alias " + owner + " -file tmp.req");51kt("-gencert -infile tmp.req -outfile tmp.cert " + cmd);52kt("-import -alias " + owner + " -file tmp.cert");53}5455static OutputAnalyzer js(String cmd) throws Exception {56return SecurityTools.jarsigner("-debug " + cmd);57}5859public static void main(String[] args) throws Exception {6061Files.write(Path.of("A1"), List.of("a1"));62Files.write(Path.of("A2"), List.of("a2"));63Files.write(Path.of("A3"), List.of("a3"));64Files.write(Path.of("A4"), List.of("a4"));65Files.write(Path.of("A5"), List.of("a5"));66Files.write(Path.of("A6"), List.of("a6"));6768String year = "" + Calendar.getInstance().get(Calendar.YEAR);6970// ==========================================================71// First part: output format72// ==========================================================7374kt("-genkeypair -alias a1 -dname CN=a1 -validity 366");75kt("-genkeypair -alias a2 -dname CN=a2 -validity 366");7677// a.jar includes 8 unsigned, 2 signed by a1 and a2, 2 signed by a378SecurityTools.jar("cvf a.jar A1 A2");79js("-keystore ks -storepass changeit a.jar a1");80SecurityTools.jar("uvf a.jar A3 A4");81js("-keystore ks -storepass changeit a.jar a2");82SecurityTools.jar("uvf a.jar A5 A6");8384// Verify OK85js("-verify a.jar").shouldHaveExitValue(0);8687// 4(chainNotValidated)+16(hasUnsignedEntry)88js("-verify a.jar -strict").shouldHaveExitValue(20);8990// 16(hasUnsignedEntry)91js("-verify a.jar -strict -keystore ks -storepass changeit")92.shouldHaveExitValue(16);9394// 16(hasUnsignedEntry)+32(notSignedByAlias)95js("-verify a.jar a1 -strict -keystore ks -storepass changeit")96.shouldHaveExitValue(48);9798// 16(hasUnsignedEntry)99js("-verify a.jar a1 a2 -strict -keystore ks -storepass changeit")100.shouldHaveExitValue(16);101102// 12 entries all together103Asserts.assertTrue(js("-verify a.jar -verbose")104.asLines().stream()105.filter(s -> s.contains(year))106.count() == 12);107108// 12 entries all listed109Asserts.assertTrue(js("-verify a.jar -verbose:grouped")110.asLines().stream()111.filter(s -> s.contains(year))112.count() == 12);113114// 5 groups: MANIFEST, signature related entries, directory entries,115// signed entries, and unsigned entries.116Asserts.assertTrue(js("-verify a.jar -verbose:summary")117.asLines().stream()118.filter(s -> s.contains(year))119.count() == 5);120121// still 5 groups, but MANIFEST group and directiry entry group122// have no other file123Asserts.assertTrue(js("-verify a.jar -verbose:summary")124.asLines().stream()125.filter(s -> s.contains("more)"))126.count() == 3);127128// 6 groups: MANIFEST, signature related entries, directory entries,129// signed entries by a1/a2, signed entries by a2, and unsigned entries.130Asserts.assertTrue(js("-verify a.jar -verbose:summary -certs")131.asLines().stream()132.filter(s -> s.contains(year))133.count() == 6);134135// 2 for MANIFEST, 2*2 for A1/A2, 2 for A3/A4136Asserts.assertTrue(js("-verify a.jar -verbose -certs")137.asLines().stream()138.filter(s -> s.contains("[certificate"))139.count() == 8);140141// a1,a2 for MANIFEST, a1,a2 for A1/A2, a2 for A3/A4142Asserts.assertTrue(js("-verify a.jar -verbose:grouped -certs")143.asLines().stream()144.filter(s -> s.contains("[certificate"))145.count() == 5);146147// a1,a2 for MANIFEST, a1,a2 for A1/A2, a2 for A3/A4148Asserts.assertTrue(js("-verify a.jar -verbose:summary -certs")149.asLines().stream()150.filter(s -> s.contains("[certificate"))151.count() == 5);152153// still 6 groups, but MANIFEST group and directory entry group154// have no other file155Asserts.assertTrue(js("-verify a.jar -verbose:summary -certs")156.asLines().stream()157.filter(s -> s.contains("more)"))158.count() == 4);159160// ==========================================================161// Second part: exit code 2, 4, 8.162// 16 and 32 already covered in the first part163// ==========================================================164165kt("-genkeypair -alias ca -dname CN=ca -ext bc -validity 365");166kt("-genkeypair -alias expired -dname CN=expired");167gencert("expired", "-alias ca -startdate -10m");168kt("-genkeypair -alias notyetvalid -dname CN=notyetvalid");169gencert("notyetvalid", "-alias ca -startdate +1m");170kt("-genkeypair -alias badku -dname CN=badku");171gencert("badku", "-alias ca -ext KU=cRLSign -validity 365");172kt("-genkeypair -alias badeku -dname CN=badeku");173gencert("badeku", "-alias ca -ext EKU=sa -validity 365");174kt("-genkeypair -alias goodku -dname CN=goodku");175gencert("goodku", "-alias ca -ext KU=dig -validity 365");176kt("-genkeypair -alias goodeku -dname CN=goodeku");177gencert("goodeku", "-alias ca -ext EKU=codesign -validity 365");178179js("-strict -keystore ks -storepass changeit a.jar expired")180.shouldHaveExitValue(4);181182js("-strict -keystore ks -storepass changeit a.jar notyetvalid")183.shouldHaveExitValue(4);184185js("-strict -keystore ks -storepass changeit a.jar badku")186.shouldHaveExitValue(8);187188js("-strict -keystore ks -storepass changeit a.jar badeku")189.shouldHaveExitValue(8);190191js("-strict -keystore ks -storepass changeit a.jar goodku")192.shouldHaveExitValue(0);193194js("-strict -keystore ks -storepass changeit a.jar goodeku")195.shouldHaveExitValue(0);196197// badchain signed by ca1, but ca1 is removed later198kt("-genkeypair -alias badchain -dname CN=badchain -validity 365");199kt("-genkeypair -alias ca1 -dname CN=ca1 -ext bc -validity 365");200gencert("badchain", "-alias ca1 -validity 365");201202// save ca1.cert for easy replay203kt("-exportcert -file ca1.cert -alias ca1");204kt("-delete -alias ca1");205206js("-strict -keystore ks -storepass changeit a.jar badchain")207.shouldHaveExitValue(4);208209js("-verify a.jar").shouldHaveExitValue(0);210211// ==========================================================212// Third part: -certchain test213// ==========================================================214215// altchain signed by ca2216kt("-genkeypair -alias altchain -dname CN=altchain -validity 365");217kt("-genkeypair -alias ca2 -dname CN=ca2 -ext bc -validity 365");218kt("-certreq -alias altchain -file altchain.req");219Files.write(Path.of("certchain"), List.of(220kt("-gencert -alias ca2 -validity 365 -rfc -infile altchain.req")221.getOutput(),222kt("-exportcert -alias ca2 -rfc").getOutput()));223224// Self-signed cert does not work225js("-strict -keystore ks -storepass changeit a.jar altchain")226.shouldHaveExitValue(4);227228// -certchain works229js("-strict -keystore ks -storepass changeit -certchain certchain "230+ "a.jar altchain")231.shouldHaveExitValue(0);232233// if ca2 is removed and cert is imported, -certchain won't work234// because this certificate entry is not trusted235// save ca2.cert for easy replay236kt("-exportcert -file ca2.cert -alias ca2");237kt("-delete -alias ca2");238kt("-importcert -file certchain -alias altchain -noprompt");239js("-strict -keystore ks -storepass changeit "240+ "-certchain certchain a.jar altchain")241.shouldHaveExitValue(4);242243js("-verify a.jar").shouldHaveExitValue(0);244245// ==========================================================246// 8172529247// ==========================================================248249kt("-genkeypair -alias ee -dname CN=ee");250kt("-genkeypair -alias caone -dname CN=caone -ext bc:c");251kt("-genkeypair -alias catwo -dname CN=catwo -ext bc:c");252253kt("-certreq -alias ee -file ee.req");254kt("-certreq -alias catwo -file catwo.req");255256// This certchain contains a cross-signed weak catwo.cert257Files.write(Path.of("ee2"), List.of(258kt("-gencert -alias catwo -rfc -infile ee.req").getOutput(),259kt("-gencert -alias caone -sigalg MD5withRSA -rfc "260+ "-infile catwo.req").getOutput()));261262kt("-importcert -alias ee -file ee2");263264SecurityTools.jar("cvf a.jar A1");265js("-strict -keystore ks -storepass changeit a.jar ee")266.shouldHaveExitValue(0);267js("-strict -keystore ks -storepass changeit -verify a.jar")268.shouldHaveExitValue(0);269}270}271272273