1 /* 2 * Copyright (c) 2015, 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.testlibrary.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 38 */ 39 public class Warning { 40 41 public static void main(String[] args) throws Throwable { 42 43 Files.deleteIfExists(Paths.get("ks")); 44 45 newCert("ca", "-validity 365000"); 46 47 recreateJar(); 48 49 newCert("a"); 50 run("jarsigner", "a.jar a") 51 .shouldContain("is self-signed"); 52 run("jarsigner", "a.jar a -strict") 53 .shouldContain("is self-signed") 54 .shouldHaveExitValue(4); 55 // Trusted entry can be self-signed without a warning 56 run("jarsigner", "-verify a.jar") 57 .shouldNotContain("is self-signed") 58 .shouldNotContain("not signed by alias in this keystore"); 59 run("keytool", "-delete -alias a"); 60 // otherwise a warning will be shown 61 run("jarsigner", "-verify a.jar") 62 .shouldContain("is self-signed") 63 .shouldContain("not signed by alias in this keystore"); 64 65 recreateJar(); 66 67 newCert("b"); 68 issueCert("b"); 69 run("jarsigner", "a.jar b") 70 .shouldNotContain("is self-signed"); 71 run("jarsigner", "-verify a.jar") 72 .shouldNotContain("is self-signed"); 73 74 run("jarsigner", "a.jar b -digestalg MD5") 75 .shouldContain("-digestalg option is considered a security risk."); 76 run("jarsigner", "a.jar b -digestalg MD5 -strict") 77 .shouldHaveExitValue(4) 78 .shouldContain("-digestalg option is considered a security risk."); 79 run("jarsigner", "a.jar b -sigalg MD5withRSA") 80 .shouldContain("-sigalg option is considered a security risk"); 81 82 issueCert("b", "-sigalg MD5withRSA"); 83 run("jarsigner", "a.jar b") 84 .shouldMatch("chain is not validated. Reason:.*MD5withRSA"); 85 86 recreateJar(); 87 88 newCert("c", "-keysize 512"); 89 issueCert("c"); 90 run("jarsigner", "a.jar c") 91 .shouldContain("chain is not validated. " + 92 "Reason: Algorithm constraints check failed"); 93 94 recreateJar(); 95 96 newCert("s1"); issueCert("s1", "-startdate 2000/01/01 -validity 36525"); 97 run("jarsigner", "a.jar s1") 98 .shouldHaveExitValue(0) 99 .shouldContain("Warning:") 100 .shouldNotContain("Error:") 101 .shouldContain("timestamp").shouldContain("2100-01-01") 102 .shouldNotContain("with signer errors"); 103 run("jarsigner", "a.jar s1 -strict") 104 .shouldHaveExitValue(0) 105 .shouldContain("Warning:") 106 .shouldNotContain("Error:") 107 .shouldContain("timestamp").shouldContain("2100-01-01") 108 .shouldNotContain("with signer errors"); 109 run("jarsigner", "a.jar s1 -verify") 110 .shouldHaveExitValue(0) 111 .shouldContain("Warning:") 112 .shouldNotContain("Error:") 113 .shouldContain("timestamp").shouldContain("2100-01-01") 114 .shouldNotContain("with signer errors"); 115 run("jarsigner", "a.jar s1 -verify -strict") 116 .shouldHaveExitValue(0) 117 .shouldContain("Warning:") 118 .shouldNotContain("Error:") 119 .shouldContain("timestamp").shouldContain("2100-01-01") 120 .shouldNotContain("with signer errors"); 121 122 recreateJar(); 123 124 newCert("s2"); issueCert("s2", "-validity 100"); 125 run("jarsigner", "a.jar s2") 126 .shouldHaveExitValue(0) 127 .shouldContain("Warning:") 128 .shouldNotContain("Error:") 129 .shouldContain("timestamp") 130 .shouldContain("will expire") 131 .shouldNotContain("with signer errors"); 132 run("jarsigner", "a.jar s2 -strict") 133 .shouldHaveExitValue(0) 134 .shouldContain("Warning:") 135 .shouldNotContain("Error:") 136 .shouldContain("timestamp") 137 .shouldContain("will expire") 138 .shouldNotContain("with signer errors"); 139 run("jarsigner", "a.jar s2 -verify") 140 .shouldHaveExitValue(0) 141 .shouldContain("Warning:") 142 .shouldNotContain("Error:") 143 .shouldContain("timestamp") 144 .shouldContain("will expire") 145 .shouldNotContain("with signer errors"); 146 run("jarsigner", "a.jar s2 -verify -strict") 147 .shouldHaveExitValue(0) 148 .shouldContain("Warning:") 149 .shouldNotContain("Error:") 150 .shouldContain("timestamp") 151 .shouldContain("will expire") 152 .shouldNotContain("with signer errors"); 153 154 recreateJar(); 155 156 newCert("s3"); issueCert("s3", "-startdate -200d -validity 100"); 157 run("jarsigner", "a.jar s3") 158 .shouldHaveExitValue(0) 159 .shouldContain("Warning:") 160 .shouldContain("has expired") 161 .shouldNotContain("with signer errors") 162 .shouldNotContain("Error:"); 163 run("jarsigner", "a.jar s3 -strict") 164 .shouldHaveExitValue(4) 165 .shouldContain("with signer errors") 166 .shouldMatch("(?s).*Error:.*has expired.*Warning:.*"); 167 run("jarsigner", "a.jar s3 -verify") 168 .shouldHaveExitValue(0) 169 .shouldContain("Warning:") 170 .shouldNotContain("with signer errors") 171 .shouldNotContain("Error:"); 172 run("jarsigner", "a.jar s3 -verify -strict") 173 .shouldHaveExitValue(4) 174 .shouldContain("with signer errors") 175 .shouldMatch("(?s).*Error:.*has expired.*Warning:.*"); 176 } 177 178 // Creates a new jar without signature 179 static void recreateJar() throws Exception { 180 JarUtils.createJar("a.jar", "ks"); 181 } 182 183 // Creates a self-signed cert for alias with zero or more -genkey options 184 static void newCert(String alias, String... more) throws Exception { 185 String args = "-genkeypair -alias " + alias + " -dname CN=" + alias; 186 for (String s: more) { 187 args += " " + s; 188 } 189 run("keytool", args).shouldHaveExitValue(0); 190 } 191 192 // Asks ca to issue a cert to alias with zero or more -gencert options 193 static void issueCert(String alias, String...more) throws Exception { 194 String req = run("keytool", "-certreq -alias " + alias) 195 .shouldHaveExitValue(0).getStdout(); 196 String args = "-gencert -alias ca -rfc"; 197 for (String s: more) { 198 args += " " + s; 199 } 200 String cert = run("keytool", args, req) 201 .shouldHaveExitValue(0).getStdout(); 202 run("keytool", "-import -alias " + alias, cert).shouldHaveExitValue(0); 203 } 204 205 // Runs a java tool with command line arguments 206 static OutputAnalyzer run(String command, String args) 207 throws Exception { 208 return run(command, args, null); 209 } 210 211 // Runs a java tool with command line arguments and an optional input block 212 static OutputAnalyzer run(String command, String args, String input) 213 throws Exception { 214 JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK(command); 215 launcher.addVMArg("-Duser.language=en").addVMArg("-Duser.country=US"); 216 switch (command) { 217 case "keytool": 218 for (String s: new String[] { 219 "-keystore", "ks", "-storepass", "changeit", 220 "-storetype", "jks", 221 "-keypass", "changeit", "-keyalg", "rsa", "-debug"}) { 222 launcher.addToolArg(s); 223 } 224 break; 225 case "jarsigner": 226 for (String s: new String[] { 227 "-keystore", "ks", "-storepass", "changeit", 228 "-storetype", "jks"}) { 229 launcher.addToolArg(s); 230 } 231 break; 232 } 233 for (String arg: args.split(" ")) { 234 launcher.addToolArg(arg); 235 } 236 String[] cmd = launcher.getCommand(); 237 ProcessBuilder pb = new ProcessBuilder(cmd); 238 OutputAnalyzer out = ProcessTools.executeProcess(pb, input); 239 System.out.println("======================"); 240 System.out.println(Arrays.toString(cmd)); 241 String msg = " stdout: [" + out.getStdout() + "];\n" 242 + " stderr: [" + out.getStderr() + "]\n" 243 + " exitValue = " + out.getExitValue() + "\n"; 244 System.out.println(msg); 245 return out; 246 } 247 } 248