| /* |
| * Copyright (c) 2015, 2017, 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. |
| */ |
| |
| import jdk.testlibrary.JDKToolLauncher; |
| import jdk.testlibrary.JarUtils; |
| import jdk.testlibrary.OutputAnalyzer; |
| import jdk.testlibrary.ProcessTools; |
| |
| import java.nio.file.Files; |
| import java.nio.file.Paths; |
| import java.util.Arrays; |
| |
| /** |
| * @test |
| * @bug 8024302 8026037 8130132 |
| * @summary warnings, errors and -strict |
| * @library /lib/testlibrary |
| */ |
| public class Warning { |
| |
| public static void main(String[] args) throws Throwable { |
| |
| Files.deleteIfExists(Paths.get("ks")); |
| |
| newCert("ca", "-validity 365000"); |
| |
| recreateJar(); |
| |
| newCert("a"); |
| run("jarsigner", "a.jar a") |
| .shouldContain("is self-signed"); |
| run("jarsigner", "a.jar a -strict") |
| .shouldContain("is self-signed") |
| .shouldHaveExitValue(4); |
| // Trusted entry can be self-signed without a warning |
| run("jarsigner", "-verify a.jar") |
| .shouldNotContain("is self-signed") |
| .shouldNotContain("not signed by alias in this keystore"); |
| run("keytool", "-delete -alias a"); |
| // otherwise a warning will be shown |
| run("jarsigner", "-verify a.jar") |
| .shouldContain("is self-signed") |
| .shouldContain("not signed by alias in this keystore"); |
| |
| recreateJar(); |
| |
| newCert("b"); |
| issueCert("b"); |
| run("jarsigner", "a.jar b") |
| .shouldNotContain("is self-signed"); |
| run("jarsigner", "-verify a.jar") |
| .shouldNotContain("is self-signed"); |
| |
| run("jarsigner", "a.jar b -digestalg MD5") |
| .shouldContain("-digestalg option is considered a security risk."); |
| run("jarsigner", "a.jar b -digestalg MD5 -strict") |
| .shouldHaveExitValue(4) |
| .shouldContain("-digestalg option is considered a security risk."); |
| run("jarsigner", "a.jar b -sigalg MD5withRSA") |
| .shouldContain("-sigalg option is considered a security risk"); |
| |
| issueCert("b", "-sigalg MD5withRSA"); |
| run("jarsigner", "a.jar b") |
| .shouldMatch("chain is invalid. Reason:.*MD5withRSA"); |
| |
| recreateJar(); |
| |
| newCert("c", "-keysize 512"); |
| issueCert("c"); |
| run("jarsigner", "a.jar c") |
| .shouldContain("chain is invalid. " + |
| "Reason: Algorithm constraints check failed"); |
| |
| recreateJar(); |
| |
| newCert("s1"); issueCert("s1", "-startdate 2000/01/01 -validity 36525"); |
| run("jarsigner", "a.jar s1") |
| .shouldHaveExitValue(0) |
| .shouldContain("Warning:") |
| .shouldNotContain("Error:") |
| .shouldContain("timestamp").shouldContain("2100-01-01") |
| .shouldNotContain("with signer errors"); |
| run("jarsigner", "a.jar s1 -strict") |
| .shouldHaveExitValue(0) |
| .shouldContain("Warning:") |
| .shouldNotContain("Error:") |
| .shouldContain("timestamp").shouldContain("2100-01-01") |
| .shouldNotContain("with signer errors"); |
| run("jarsigner", "a.jar s1 -verify") |
| .shouldHaveExitValue(0) |
| .shouldContain("Warning:") |
| .shouldNotContain("Error:") |
| .shouldContain("timestamp").shouldContain("2100-01-01") |
| .shouldNotContain("with signer errors"); |
| run("jarsigner", "a.jar s1 -verify -strict") |
| .shouldHaveExitValue(0) |
| .shouldContain("Warning:") |
| .shouldNotContain("Error:") |
| .shouldContain("timestamp").shouldContain("2100-01-01") |
| .shouldNotContain("with signer errors"); |
| |
| recreateJar(); |
| |
| newCert("s2"); issueCert("s2", "-validity 100"); |
| run("jarsigner", "a.jar s2") |
| .shouldHaveExitValue(0) |
| .shouldContain("Warning:") |
| .shouldNotContain("Error:") |
| .shouldContain("timestamp") |
| .shouldContain("will expire") |
| .shouldNotContain("with signer errors"); |
| run("jarsigner", "a.jar s2 -strict") |
| .shouldHaveExitValue(0) |
| .shouldContain("Warning:") |
| .shouldNotContain("Error:") |
| .shouldContain("timestamp") |
| .shouldContain("will expire") |
| .shouldNotContain("with signer errors"); |
| run("jarsigner", "a.jar s2 -verify") |
| .shouldHaveExitValue(0) |
| .shouldContain("Warning:") |
| .shouldNotContain("Error:") |
| .shouldContain("timestamp") |
| .shouldContain("will expire") |
| .shouldNotContain("with signer errors"); |
| run("jarsigner", "a.jar s2 -verify -strict") |
| .shouldHaveExitValue(0) |
| .shouldContain("Warning:") |
| .shouldNotContain("Error:") |
| .shouldContain("timestamp") |
| .shouldContain("will expire") |
| .shouldNotContain("with signer errors"); |
| |
| recreateJar(); |
| |
| newCert("s3"); issueCert("s3", "-startdate -200d -validity 100"); |
| run("jarsigner", "a.jar s3") |
| .shouldHaveExitValue(0) |
| .shouldContain("Warning:") |
| .shouldContain("has expired") |
| .shouldNotContain("with signer errors") |
| .shouldNotContain("Error:"); |
| run("jarsigner", "a.jar s3 -strict") |
| .shouldHaveExitValue(4) |
| .shouldContain("with signer errors") |
| .shouldMatch("(?s).*Error:.*has expired.*Warning:.*"); |
| run("jarsigner", "a.jar s3 -verify") |
| .shouldHaveExitValue(0) |
| .shouldContain("Warning:") |
| .shouldNotContain("with signer errors") |
| .shouldNotContain("Error:"); |
| run("jarsigner", "a.jar s3 -verify -strict") |
| .shouldHaveExitValue(4) |
| .shouldContain("with signer errors") |
| .shouldMatch("(?s).*Error:.*has expired.*Warning:.*"); |
| } |
| |
| // Creates a new jar without signature |
| static void recreateJar() throws Exception { |
| JarUtils.createJar("a.jar", "ks"); |
| } |
| |
| // Creates a self-signed cert for alias with zero or more -genkey options |
| static void newCert(String alias, String... more) throws Throwable { |
| String args = "-genkeypair -alias " + alias + " -dname CN=" + alias; |
| for (String s: more) { |
| args += " " + s; |
| } |
| run("keytool", args).shouldHaveExitValue(0); |
| } |
| |
| // Asks ca to issue a cert to alias with zero or more -gencert options |
| static void issueCert(String alias, String...more) throws Throwable { |
| String req = run("keytool", "-certreq -alias " + alias) |
| .shouldHaveExitValue(0).getStdout(); |
| String args = "-gencert -alias ca -rfc"; |
| for (String s: more) { |
| args += " " + s; |
| } |
| String cert = run("keytool", args, req) |
| .shouldHaveExitValue(0).getStdout(); |
| run("keytool", "-import -alias " + alias, cert).shouldHaveExitValue(0); |
| } |
| |
| // Runs a java tool with command line arguments |
| static OutputAnalyzer run(String command, String args) |
| throws Throwable { |
| return run(command, args, null); |
| } |
| |
| // Runs a java tool with command line arguments and an optional input block |
| static OutputAnalyzer run(String command, String args, String input) |
| throws Throwable { |
| JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK(command); |
| launcher.addVMArg("-Duser.language=en").addVMArg("-Duser.country=US"); |
| switch (command) { |
| case "keytool": |
| for (String s: new String[] { |
| "-keystore", "ks", "-storepass", "changeit", |
| "-storetype", "jks", |
| "-keypass", "changeit", "-keyalg", "rsa", "-debug"}) { |
| launcher.addToolArg(s); |
| } |
| break; |
| case "jarsigner": |
| for (String s: new String[] { |
| "-keystore", "ks", "-storepass", "changeit", |
| "-storetype", "jks"}) { |
| launcher.addToolArg(s); |
| } |
| break; |
| } |
| for (String arg: args.split(" ")) { |
| launcher.addToolArg(arg); |
| } |
| String[] cmd = launcher.getCommand(); |
| ProcessBuilder pb = new ProcessBuilder(cmd); |
| OutputAnalyzer out = ProcessTools.executeProcess(pb, input); |
| System.out.println("======================"); |
| System.out.println(Arrays.toString(cmd)); |
| String msg = " stdout: [" + out.getStdout() + "];\n" |
| + " stderr: [" + out.getStderr() + "]\n" |
| + " exitValue = " + out.getExitValue() + "\n"; |
| System.out.println(msg); |
| return out; |
| } |
| } |
| |