1 /* 2 * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import jdk.testlibrary.JDKToolLauncher; 25 import jdk.test.lib.util.JarUtils; 26 import jdk.testlibrary.OutputAnalyzer; 27 import jdk.testlibrary.ProcessTools; 28 29 import java.nio.file.Files; 30 import java.nio.file.Paths; 31 import java.util.Arrays; 32 33 /** 34 * @test 35 * @bug 8024302 8026037 8130132 36 * @summary warnings, errors and -strict 37 * @library /lib/testlibrary /test/lib 38 * @build jdk.test.lib.util.JarUtils 39 * @run main Warning 40 */ 41 public class Warning { 42 43 public static void main(String[] args) throws Throwable { 44 45 Files.deleteIfExists(Paths.get("ks")); 46 47 newCert("ca", "-validity 365000"); 48 49 recreateJar(); 50 51 newCert("a"); 52 run("jarsigner", "a.jar a") 53 .shouldContain("is self-signed"); 54 run("jarsigner", "a.jar a -strict") 55 .shouldContain("is self-signed") 56 .shouldHaveExitValue(4); 57 // Trusted entry can be self-signed without a warning 58 run("jarsigner", "-verify a.jar") 59 .shouldNotContain("is self-signed") 60 .shouldNotContain("not signed by alias in this keystore"); 61 run("keytool", "-delete -alias a"); 62 // otherwise a warning will be shown 63 run("jarsigner", "-verify a.jar") 64 .shouldContain("is self-signed") 65 .shouldContain("not signed by alias in this keystore"); 66 67 recreateJar(); 68 69 newCert("b"); 70 issueCert("b"); 71 run("jarsigner", "a.jar b") 72 .shouldNotContain("is self-signed"); 73 run("jarsigner", "-verify a.jar") 74 .shouldNotContain("is self-signed"); 75 76 run("jarsigner", "a.jar b -digestalg MD5") 77 .shouldContain("-digestalg option is considered a security risk."); 78 run("jarsigner", "a.jar b -digestalg MD5 -strict") 79 .shouldHaveExitValue(4) 80 .shouldContain("-digestalg option is considered a security risk."); 81 run("jarsigner", "a.jar b -sigalg MD5withRSA") 82 .shouldContain("-sigalg option is considered a security risk"); 83 84 issueCert("b", "-sigalg MD5withRSA"); 85 run("jarsigner", "a.jar b") 86 .shouldMatch("chain is invalid. Reason:.*MD5withRSA"); 87 88 recreateJar(); 89 90 newCert("c", "-keysize 512"); 91 issueCert("c"); 92 run("jarsigner", "a.jar c") 93 .shouldContain("chain is invalid. " + 94 "Reason: Algorithm constraints check failed"); 95 96 recreateJar(); 97 98 newCert("s1"); issueCert("s1", "-startdate 2000/01/01 -validity 36525"); 99 run("jarsigner", "a.jar s1") 100 .shouldHaveExitValue(0) 101 .shouldContain("Warning:") 102 .shouldNotContain("Error:") 103 .shouldContain("timestamp").shouldContain("2100-01-01") 104 .shouldNotContain("with signer errors"); 105 run("jarsigner", "a.jar s1 -strict") 106 .shouldHaveExitValue(0) 107 .shouldContain("Warning:") 108 .shouldNotContain("Error:") 109 .shouldContain("timestamp").shouldContain("2100-01-01") 110 .shouldNotContain("with signer errors"); 111 run("jarsigner", "a.jar s1 -verify") 112 .shouldHaveExitValue(0) 113 .shouldContain("Warning:") 114 .shouldNotContain("Error:") 115 .shouldContain("timestamp").shouldContain("2100-01-01") 116 .shouldNotContain("with signer errors"); 117 run("jarsigner", "a.jar s1 -verify -strict") 118 .shouldHaveExitValue(0) 119 .shouldContain("Warning:") 120 .shouldNotContain("Error:") 121 .shouldContain("timestamp").shouldContain("2100-01-01") 122 .shouldNotContain("with signer errors"); 123 124 recreateJar(); 125 126 newCert("s2"); issueCert("s2", "-validity 100"); 127 run("jarsigner", "a.jar s2") 128 .shouldHaveExitValue(0) 129 .shouldContain("Warning:") 130 .shouldNotContain("Error:") 131 .shouldContain("timestamp") 132 .shouldContain("will expire") 133 .shouldNotContain("with signer errors"); 134 run("jarsigner", "a.jar s2 -strict") 135 .shouldHaveExitValue(0) 136 .shouldContain("Warning:") 137 .shouldNotContain("Error:") 138 .shouldContain("timestamp") 139 .shouldContain("will expire") 140 .shouldNotContain("with signer errors"); 141 run("jarsigner", "a.jar s2 -verify") 142 .shouldHaveExitValue(0) 143 .shouldContain("Warning:") 144 .shouldNotContain("Error:") 145 .shouldContain("timestamp") 146 .shouldContain("will expire") 147 .shouldNotContain("with signer errors"); 148 run("jarsigner", "a.jar s2 -verify -strict") 149 .shouldHaveExitValue(0) 150 .shouldContain("Warning:") 151 .shouldNotContain("Error:") 152 .shouldContain("timestamp") 153 .shouldContain("will expire") 154 .shouldNotContain("with signer errors"); 155 156 recreateJar(); 157 158 newCert("s3"); issueCert("s3", "-startdate -200d -validity 100"); 159 run("jarsigner", "a.jar s3") 160 .shouldHaveExitValue(0) 161 .shouldContain("Warning:") 162 .shouldContain("has expired") 163 .shouldNotContain("with signer errors") 164 .shouldNotContain("Error:"); 165 run("jarsigner", "a.jar s3 -strict") 166 .shouldHaveExitValue(4) 167 .shouldContain("with signer errors") 168 .shouldMatch("(?s).*Error:.*has expired.*Warning:.*"); 169 run("jarsigner", "a.jar s3 -verify") 170 .shouldHaveExitValue(0) 171 .shouldContain("Warning:") 172 .shouldNotContain("with signer errors") 173 .shouldNotContain("Error:"); 174 run("jarsigner", "a.jar s3 -verify -strict") 175 .shouldHaveExitValue(4) 176 .shouldContain("with signer errors") 177 .shouldMatch("(?s).*Error:.*has expired.*Warning:.*"); 178 } 179 180 // Creates a new jar without signature 181 static void recreateJar() throws Exception { 182 JarUtils.createJar("a.jar", "ks"); 183 } 184 185 // Creates a self-signed cert for alias with zero or more -genkey options 186 static void newCert(String alias, String... more) throws Exception { 187 String args = "-genkeypair -alias " + alias + " -dname CN=" + alias; 188 for (String s: more) { 189 args += " " + s; 190 } 191 run("keytool", args).shouldHaveExitValue(0); 192 } 193 194 // Asks ca to issue a cert to alias with zero or more -gencert options 195 static void issueCert(String alias, String...more) throws Exception { 196 String req = run("keytool", "-certreq -alias " + alias) 197 .shouldHaveExitValue(0).getStdout(); 198 String args = "-gencert -alias ca -rfc"; 199 for (String s: more) { 200 args += " " + s; 201 } 202 String cert = run("keytool", args, req) 203 .shouldHaveExitValue(0).getStdout(); 204 run("keytool", "-import -alias " + alias, cert).shouldHaveExitValue(0); 205 } 206 207 // Runs a java tool with command line arguments 208 static OutputAnalyzer run(String command, String args) 209 throws Exception { 210 return run(command, args, null); 211 } 212 213 // Runs a java tool with command line arguments and an optional input block 214 static OutputAnalyzer run(String command, String args, String input) 215 throws Exception { 216 JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK(command); 217 launcher.addVMArg("-Duser.language=en").addVMArg("-Duser.country=US"); 218 switch (command) { 219 case "keytool": 220 for (String s: new String[] { 221 "-keystore", "ks", "-storepass", "changeit", 222 "-storetype", "jks", 223 "-keypass", "changeit", "-keyalg", "rsa", "-debug"}) { 224 launcher.addToolArg(s); 225 } 226 break; 227 case "jarsigner": 228 for (String s: new String[] { 229 "-keystore", "ks", "-storepass", "changeit", 230 "-storetype", "jks"}) { 231 launcher.addToolArg(s); 232 } 233 break; 234 } 235 for (String arg: args.split(" ")) { 236 launcher.addToolArg(arg); 237 } 238 String[] cmd = launcher.getCommand(); 239 ProcessBuilder pb = new ProcessBuilder(cmd); 240 OutputAnalyzer out = ProcessTools.executeProcess(pb, input); 241 System.out.println("======================"); 242 System.out.println(Arrays.toString(cmd)); 243 String msg = " stdout: [" + out.getStdout() + "];\n" 244 + " stderr: [" + out.getStderr() + "]\n" 245 + " exitValue = " + out.getExitValue() + "\n"; 246 System.out.println(msg); 247 return out; 248 } 249 } 250