--- old/test/ProblemList.txt 2016-04-28 20:02:39.021024375 +0300 +++ new/test/ProblemList.txt 2016-04-28 20:02:38.804974953 +0300 @@ -234,6 +234,9 @@ java/security/KeyPairGenerator/SolarisShortDSA.java solaris-all sun/security/tools/keytool/standard.sh solaris-all +# 8026393 +sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java generic-all + ############################################################################ # jdk_sound --- old/test/sun/security/tools/jarsigner/TimestampCheck.java 2016-04-28 20:02:39.720950239 +0300 +++ new/test/sun/security/tools/jarsigner/TimestampCheck.java 2016-04-28 20:02:39.485556469 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -58,7 +58,12 @@ static final String defaultPolicyId = "2.3.4.5"; - static class Handler implements HttpHandler { + static class Handler implements HttpHandler, AutoCloseable { + + private final HttpServer httpServer; + private final String keystore; + + @Override public void handle(HttpExchange t) throws IOException { int len = 0; for (String h: t.getRequestHeaders().keySet()) { @@ -136,7 +141,9 @@ // Write TSResponse System.err.println("\nResponse\n==================="); KeyStore ks = KeyStore.getInstance("JKS"); - ks.load(new FileInputStream(TSKS), "changeit".toCharArray()); + try (FileInputStream fis = new FileInputStream(keystore)) { + ks.load(fis, "changeit".toCharArray()); + } String alias = "ts"; if (path == 6) alias = "tsbad1"; @@ -240,35 +247,72 @@ return out.toByteArray(); } - } - public static void main(String[] args) throws Exception { + private Handler(HttpServer httpServer, String keystore) { + this.httpServer = httpServer; + this.keystore = keystore; + } + + /** + * Initialize TSA instance. + * + * Extended Key Info extension of certificate that is used for + * signing TSA responses should contain timeStamping value. + */ + static Handler init(int port, String keystore) throws IOException { + HttpServer httpServer = HttpServer.create( + new InetSocketAddress(port), 0); + Handler tsa = new Handler(httpServer, keystore); + httpServer.createContext("/", tsa); + return tsa; + } - Handler h = new Handler(); - HttpServer server = HttpServer.create(new InetSocketAddress(0), 0); - int port = server.getAddress().getPort(); - HttpContext ctx = server.createContext("/", h); - server.start(); - - String cmd = null; - // Use -J-Djava.security.egd=file:/dev/./urandom to speed up - // nonce generation in timestamping request. Not avaibale on - // Windows and defaults to thread seed generator, not too bad. - if (System.getProperty("java.home").endsWith("jre")) { - cmd = System.getProperty("java.home") + "/../bin/jarsigner" + - " -J-Djava.security.egd=file:/dev/./urandom" + - " -debug -keystore " + TSKS + " -storepass changeit" + - " -tsa http://localhost:" + port + "/%d" + - " -signedjar new_%d.jar " + JAR + " old"; - } else { - cmd = System.getProperty("java.home") + "/bin/jarsigner" + - " -J-Djava.security.egd=file:/dev/./urandom" + - " -debug -keystore " + TSKS + " -storepass changeit" + - " -tsa http://localhost:" + port + "/%d" + - " -signedjar new_%d.jar " + JAR + " old"; + /** + * Start TSA service. + */ + void start() { + httpServer.start(); } - try { + /** + * Stop TSA service. + */ + void stop() { + httpServer.stop(0); + } + + /** + * Return server port number. + */ + int getPort() { + return httpServer.getAddress().getPort(); + } + + @Override + public void close() throws Exception { + stop(); + } + } + public static void main(String[] args) throws Exception { + try (Handler tsa = Handler.init(0, TSKS);) { + tsa.start(); + int port = tsa.getPort(); + + String cmd; + // Use -J-Djava.security.egd=file:/dev/./urandom to speed up + // nonce generation in timestamping request. Not avaibale on + // Windows and defaults to thread seed generator, not too bad. + if (System.getProperty("java.home").endsWith("jre")) { + cmd = System.getProperty("java.home") + "/../bin/jarsigner"; + } else { + cmd = System.getProperty("java.home") + "/bin/jarsigner"; + } + + cmd += " -J-Djava.security.egd=file:/dev/./urandom" + + " -debug -keystore " + TSKS + " -storepass changeit" + + " -tsa http://localhost:" + port + "/%d" + + " -signedjar new_%d.jar " + JAR + " old"; + if (args.length == 0) { // Run this test jarsigner(cmd, 0, true); // Success, normal call jarsigner(cmd, 1, false); // These 4 should fail @@ -289,8 +333,6 @@ System.err.println("Press Enter to quit server"); System.in.read(); } - } finally { - server.stop(0); } } --- /dev/null 2016-04-23 21:58:04.511940756 +0300 +++ new/test/lib/testlibrary/jdk/testlibrary/JarUtils.java 2016-04-28 20:02:40.179961273 +0300 @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2016, 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. + */ + +package jdk.testlibrary; + +import java.io.*; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; + +/** + * Common library for various test jar file utility functions. + */ +public final class JarUtils { + + private static final int BUFFER_SIZE = 1024; + + /** + * Create jar file with specified files. + */ + public static void createJar(String dest, String... files) + throws IOException { + try (JarOutputStream jos = new JarOutputStream( + new FileOutputStream(dest), new Manifest())) { + for (String file : files) { + System.out.println(String.format("Adding %s to %s", + file, dest)); + + // add an archive entry, and write a file + jos.putNextEntry(new JarEntry(file)); + try (FileInputStream fis = new FileInputStream(file)) { + transferToOutputStream(fis, jos); + } + } + } + System.out.println(); + } + + /** + * Add specified files to existing jar file. + */ + public static void updateJar(String src, String dest, String... files) + throws IOException { + try (JarOutputStream jos = new JarOutputStream( + new FileOutputStream(dest))) { + + // copy each old entry into destination unless the entry name + // is in the updated list + List updatedFiles = new ArrayList<>(); + try (JarFile srcJarFile = new JarFile(src)) { + Enumeration entries = srcJarFile.entries(); + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + String name = entry.getName(); + boolean found = false; + for (String file : files) { + if (name.equals(file)) { + updatedFiles.add(file); + found = true; + break; + } + } + + if (found) { + System.out.println(String.format("Updating %s with %s", + dest, name)); + jos.putNextEntry(new JarEntry(name)); + try (FileInputStream fis = new FileInputStream(name)) { + transferToOutputStream(fis, jos); + } + } else { + System.out.println(String.format("Copying %s to %s", + name, dest)); + jos.putNextEntry(entry); + transferToOutputStream(srcJarFile.getInputStream(entry), + jos); + } + } + } + + // append new files + for (String file : files) { + if (!updatedFiles.contains(file)) { + System.out.println(String.format("Adding %s with %s", + dest, file)); + jos.putNextEntry(new JarEntry(file)); + try (FileInputStream fis = new FileInputStream(file)) { + transferToOutputStream(fis, jos); + } + } + } + } + System.out.println(); + } + + private static void transferToOutputStream(InputStream is, OutputStream os) + throws IOException { + byte[] buffer = new byte[BUFFER_SIZE]; + int read; + while ((read = is.read(buffer, 0, BUFFER_SIZE)) >= 0) { + os.write(buffer, 0, read); + } + } +} --- /dev/null 2016-04-23 21:58:04.511940756 +0300 +++ new/test/sun/security/tools/jarsigner/TsacertOptionTest.java 2016-04-28 20:02:40.742679987 +0300 @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013, 2016, 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.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.JarUtils; + +/** + * @test + * @bug 8024302 8026037 + * @summary The test signs and verifies a jar file with -tsacert option + * @library /lib/testlibrary + * @run main TsacertOptionTest + */ +public class TsacertOptionTest { + + private static final String FS = System.getProperty("file.separator"); + private static final String JAVA_HOME = System.getProperty("test.jdk"); + private static final String KEYTOOL = JAVA_HOME + FS + "bin" + FS + + "keytool"; + private static final String JARSIGNER = JAVA_HOME + FS + "bin" + FS + + "jarsigner"; + private static final String UNSIGNED_JARFILE = "unsigned.jar"; + private static final String SIGNED_JARFILE = "signed.jar"; + private static final String FILENAME = TsacertOptionTest.class.getName() + + ".txt"; + private static final String PASSWORD = "changeit"; + private static final String KEYSTORE = "ks.jks"; + private static final String SIGNING_KEY_ALIAS = "sign_alias"; + private static final String TSA_KEY_ALIAS = "ts"; + private static final String KEY_ALG = "RSA"; + private static final int KEY_SIZE = 2048; + private static final int VALIDITY = 365; + private static final String WARNING = "Warning:"; + private static final String JAR_SIGNED = "jar signed."; + private static final String JAR_VERIFIED = "jar verified."; + + /** + * The test signs and verifies a jar file with -tsacert option, + * and checks that no warning was shown. + * A certificate that is addressed in -tsacert option contains URL to TSA + * in Subject Information Access extension. + */ + public static void main(String[] args) throws Throwable { + TsacertOptionTest test = new TsacertOptionTest(); + test.start(); + } + + void start() throws Throwable { + // create a jar file that contains one file + Utils.createFiles(FILENAME); + JarUtils.createJar(UNSIGNED_JARFILE, FILENAME); + + // look for free network port for TSA service + int port = jdk.testlibrary.Utils.getFreePort(); + String host = jdk.testlibrary.Utils.getHostname(); + String tsaUrl = "http://" + host + ":" + port; + + // create key pair for jar signing + ProcessTools.executeCommand(KEYTOOL, + "-genkey", + "-alias", SIGNING_KEY_ALIAS, + "-keyalg", KEY_ALG, + "-keysize", Integer.toString(KEY_SIZE), + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-dname", "CN=Test", + "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0); + + // create key pair for TSA service + // SubjectInfoAccess extension contains URL to TSA service + ProcessTools.executeCommand(KEYTOOL, + "-genkey", + "-v", + "-alias", TSA_KEY_ALIAS, + "-keyalg", KEY_ALG, + "-keysize", Integer.toString(KEY_SIZE), + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-dname", "CN=TSA", + "-ext", "ExtendedkeyUsage:critical=timeStamping", + "-ext", "SubjectInfoAccess=timeStamping:URI:" + tsaUrl, + "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0); + + try (TimestampCheck.Handler tsa = TimestampCheck.Handler.init(port, + KEYSTORE);) { + + // start TSA + tsa.start(); + + // sign jar file + // specify -tsadigestalg option because + // TSA server uses SHA-1 digest algorithm + OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verbose", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-signedjar", SIGNED_JARFILE, + "-tsacert", TSA_KEY_ALIAS, + "-tsadigestalg", "SHA-1", + UNSIGNED_JARFILE, + SIGNING_KEY_ALIAS); + + analyzer.shouldHaveExitValue(0); + analyzer.stdoutShouldNotContain(WARNING); + analyzer.shouldContain(JAR_SIGNED); + + // verify signed jar + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verbose", + "-verify", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + SIGNED_JARFILE); + + analyzer.shouldHaveExitValue(0); + analyzer.stdoutShouldNotContain(WARNING); + analyzer.shouldContain(JAR_VERIFIED); + } + + System.out.println("Test passed"); + } + +} --- /dev/null 2016-04-23 21:58:04.511940756 +0300 +++ new/test/sun/security/tools/jarsigner/Utils.java 2016-04-28 20:02:41.363476982 +0300 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013, 2015, 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 java.io.File; +import java.io.IOException; + +/** + * Helper class. + */ +public class Utils { + + static void createFiles(String... filenames) throws IOException { + for (String filename : filenames) { + new File(filename).createNewFile(); + } + } + +} + --- /dev/null 2016-04-23 21:58:04.511940756 +0300 +++ new/test/sun/security/tools/jarsigner/warnings/AliasNotInStoreTest.java 2016-04-28 20:02:41.947347062 +0300 @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2013, 2015, 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.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.JarUtils; + +/** + * @test + * @bug 8024302 8026037 + * @summary Test for aliasNotInStore warning + * @library /lib/testlibrary ../ + * @run main AliasNotInStoreTest + */ +public class AliasNotInStoreTest extends Test { + + /** + * The test signs and verifies a jar that contains signed entries + * that are not signed by any alias in keystore (aliasNotInStore). + * Warning message is expected. + */ + public static void main(String[] args) throws Throwable { + AliasNotInStoreTest test = new AliasNotInStoreTest(); + test.start(); + } + + private void start() throws Throwable { + Utils.createFiles(FIRST_FILE, SECOND_FILE); + System.out.println(String.format("Create a %s that contains %s", + new Object[]{UNSIGNED_JARFILE, FIRST_FILE})); + JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); + + // create first key pair for signing + ProcessTools.executeCommand(KEYTOOL, + "-genkey", + "-alias", FIRST_KEY_ALIAS, + "-keyalg", KEY_ALG, + "-keysize", Integer.toString(KEY_SIZE), + "-keystore", BOTH_KEYS_KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-dname", "CN=First", + "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0); + + // create second key pair for signing + ProcessTools.executeCommand(KEYTOOL, + "-genkey", + "-alias", SECOND_KEY_ALIAS, + "-keyalg", KEY_ALG, + "-keysize", Integer.toString(KEY_SIZE), + "-keystore", BOTH_KEYS_KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-dname", "CN=Second", + "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0); + + // sign jar with first key + OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER, + "-keystore", BOTH_KEYS_KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-signedjar", SIGNED_JARFILE, + UNSIGNED_JARFILE, + FIRST_KEY_ALIAS); + + checkSigning(analyzer); + + System.out.println(String.format("Copy %s to %s, and add %s", + new Object[] {SIGNED_JARFILE, UPDATED_SIGNED_JARFILE, + SECOND_FILE})); + + JarUtils.updateJar(SIGNED_JARFILE, UPDATED_SIGNED_JARFILE, SECOND_FILE); + + // sign jar with second key + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-keystore", BOTH_KEYS_KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + UPDATED_SIGNED_JARFILE, + SECOND_KEY_ALIAS); + + checkSigning(analyzer); + + // create keystore that contains only first key + ProcessTools.executeCommand(KEYTOOL, + "-importkeystore", + "-srckeystore", BOTH_KEYS_KEYSTORE, + "-srcalias", FIRST_KEY_ALIAS, + "-srcstorepass", PASSWORD, + "-srckeypass", PASSWORD, + "-destkeystore", FIRST_KEY_KEYSTORE, + "-destalias", FIRST_KEY_ALIAS, + "-deststorepass", PASSWORD, + "-destkeypass", PASSWORD).shouldHaveExitValue(0); + + // verify jar with keystore that contains only first key in strict mode, + // so there is signed entry (FirstClass.class) that is not signed + // by any alias in the keystore + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-verbose", + "-keystore", FIRST_KEY_KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + UPDATED_SIGNED_JARFILE); + + checkVerifying(analyzer, 0, CHAIN_NOT_VALIDATED_VERIFYING_WARNING, + ALIAS_NOT_IN_STORE_VERIFYING_WARNING); + + // verify jar with keystore that contains only first key in strict mode + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-verbose", + "-strict", + "-keystore", FIRST_KEY_KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + UPDATED_SIGNED_JARFILE); + + int expectedExitCode = ALIAS_NOT_IN_STORE_EXIT_CODE + + CHAIN_NOT_VALIDATED_EXIT_CODE; + checkVerifying(analyzer, expectedExitCode, + CHAIN_NOT_VALIDATED_VERIFYING_WARNING, + ALIAS_NOT_IN_STORE_VERIFYING_WARNING); + + System.out.println("Test passed"); + } + +} --- /dev/null 2016-04-23 21:58:04.511940756 +0300 +++ new/test/sun/security/tools/jarsigner/warnings/BadExtendedKeyUsageTest.java 2016-04-28 20:02:42.535141948 +0300 @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013, 2015, 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.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.JarUtils; + +/** + * @test + * @bug 8024302 8026037 + * @summary Test for badExtendedKeyUsage warning + * @library /lib/testlibrary ../ + * @run main BadExtendedKeyUsageTest + */ +public class BadExtendedKeyUsageTest extends Test { + + /** + * The test signs and verifies a jar that contains entries + * whose signer certificate's ExtendedKeyUsage extension + * doesn't allow code signing (badExtendedKeyUsage). + * Warning message is expected. + */ + public static void main(String[] args) throws Throwable { + BadExtendedKeyUsageTest test = new BadExtendedKeyUsageTest(); + test.start(); + } + + private void start() throws Throwable { + // create a jar file that contains one class file + Utils.createFiles(FIRST_FILE); + JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); + + // create a certificate whose signer certificate's + // ExtendedKeyUsage extension doesn't allow code signing + ProcessTools.executeCommand(KEYTOOL, + "-genkey", + "-alias", KEY_ALIAS, + "-keyalg", KEY_ALG, + "-keysize", Integer.toString(KEY_SIZE), + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-dname", "CN=Test", + "-ext", "ExtendedkeyUsage=serverAuth", + "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0); + + // sign jar + OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verbose", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-signedjar", SIGNED_JARFILE, + UNSIGNED_JARFILE, + KEY_ALIAS); + + checkSigning(analyzer, BAD_EXTENDED_KEY_USAGE_SIGNING_WARNING); + + // verify signed jar + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-verbose", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + SIGNED_JARFILE); + + checkVerifying(analyzer, 0, BAD_EXTENDED_KEY_USAGE_VERIFYING_WARNING); + + // verity signed jar in strict mode + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-verbose", + "-strict", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + SIGNED_JARFILE); + + checkVerifying(analyzer, BAD_EXTENDED_KEY_USAGE_EXIT_CODE, + BAD_EXTENDED_KEY_USAGE_VERIFYING_WARNING); + + System.out.println("Test passed"); + } + +} --- /dev/null 2016-04-23 21:58:04.511940756 +0300 +++ new/test/sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java 2016-04-28 20:02:43.098042151 +0300 @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013, 2015, 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.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.JarUtils; + +/** + * @test + * @bug 8024302 8026037 + * @summary Test for badKeyUsage warning + * @library /lib/testlibrary ../ + * @ignore until 8026393 is fixed + * @run main BadKeyUsageTest + */ +public class BadKeyUsageTest extends Test { + + /** + * The test signs and verifies a jar that contains entries + * whose signer certificate's KeyUsage extension + * doesn't allow code signing (badKeyUsage). + * Warning message is expected. + */ + public static void main(String[] args) throws Throwable { + BadKeyUsageTest test = new BadKeyUsageTest(); + test.start(); + } + + private void start() throws Throwable { + // create a jar file that contains one class file + Utils.createFiles(FIRST_FILE); + JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); + + // create a certificate whose signer certificate's KeyUsage extension + // doesn't allow code signing + ProcessTools.executeCommand(KEYTOOL, + "-genkey", + "-alias", KEY_ALIAS, + "-keyalg", KEY_ALG, + "-keysize", Integer.toString(KEY_SIZE), + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-dname", "CN=Test", + "-ext", "KeyUsage=keyAgreement", + "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0); + + // sign jar + OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verbose", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-signedjar", SIGNED_JARFILE, + UNSIGNED_JARFILE, + KEY_ALIAS); + + checkSigning(analyzer, BAD_KEY_USAGE_SIGNING_WARNING); + + // verify signed jar + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-verbose", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + SIGNED_JARFILE); + + checkVerifying(analyzer, 0, BAD_KEY_USAGE_VERIFYING_WARNING); + + // verify signed jar in strict mode + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-verbose", + "-strict", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + SIGNED_JARFILE); + + checkVerifying(analyzer, BAD_KEY_USAGE_EXIT_CODE, + BAD_KEY_USAGE_VERIFYING_WARNING); + + System.out.println("Test passed"); + } + +} --- /dev/null 2016-04-23 21:58:04.511940756 +0300 +++ new/test/sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java 2016-04-28 20:02:43.737014789 +0300 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013, 2015, 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.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.JarUtils; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Base64; + +/** + * @test + * @bug 8024302 8026037 + * @summary Test for badNetscapeCertType warning + * @library /lib/testlibrary ../ + * @run main BadNetscapeCertTypeTest + */ +public class BadNetscapeCertTypeTest extends Test { + + private static final String NETSCAPE_KEYSTORE_BASE64 = TEST_SOURCES + FS + + "bad_netscape_cert_type.jks.base64"; + + private static final String NETSCAPE_KEYSTORE + = "bad_netscape_cert_type.jks"; + + /** + * The test signs and verifies a jar that contains entries + * whose signer certificate's NetscapeCertType extension + * doesn't allow code signing (badNetscapeCertType). + * Warning message is expected. + * Run bad_netscape_cert_type.sh script to create bad_netscape_cert_type.jks + */ + public static void main(String[] args) throws Throwable { + + Files.write(Paths.get(NETSCAPE_KEYSTORE), + Base64.getMimeDecoder().decode( + Files.readAllBytes(Paths.get(NETSCAPE_KEYSTORE_BASE64)))); + + BadNetscapeCertTypeTest test = new BadNetscapeCertTypeTest(); + test.start(); + } + + private void start() throws Throwable { + // create a jar file that contains one class file + Utils.createFiles(FIRST_FILE); + JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); + + // sign jar + OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verbose", + "-keystore", NETSCAPE_KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-signedjar", SIGNED_JARFILE, + UNSIGNED_JARFILE, + KEY_ALIAS); + + checkSigning(analyzer, BAD_NETSCAPE_CERT_TYPE_SIGNING_WARNING); + + // verify signed jar + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-verbose", + "-keystore", NETSCAPE_KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + SIGNED_JARFILE); + + checkVerifying(analyzer, 0, BAD_NETSCAPE_CERT_TYPE_VERIFYING_WARNING); + + // verify signed jar in strict mode + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-verbose", + "-strict", + "-keystore", NETSCAPE_KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + SIGNED_JARFILE); + + checkVerifying(analyzer, BAD_NETSCAPE_CERT_TYPE_EXIT_CODE, + BAD_NETSCAPE_CERT_TYPE_VERIFYING_WARNING); + + System.out.println("Test passed"); + } + +} --- /dev/null 2016-04-23 21:58:04.511940756 +0300 +++ new/test/sun/security/tools/jarsigner/warnings/ChainNotValidatedTest.java 2016-04-28 20:02:44.328159703 +0300 @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2013, 2015, 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 java.io.File; +import jdk.testlibrary.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.JarUtils; + +/** + * @test + * @bug 8024302 8026037 + * @summary Test for chainNotValidated warning + * @library /lib/testlibrary ../ + * @run main ChainNotValidatedTest + */ +public class ChainNotValidatedTest extends Test { + + private static final String CHAIN = "chain"; + + /** + * The test signs and verifies a jar that contains entries + * whose cert chain can't be correctly validated (chainNotValidated). + * Warning message is expected. + */ + public static void main(String[] args) throws Throwable { + ChainNotValidatedTest test = new ChainNotValidatedTest(); + test.start(); + } + + private void start() throws Throwable { + // create a jar file that contains one class file + Utils.createFiles(FIRST_FILE); + JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); + + // create self-signed certificate whose BasicConstraints extension + // is set to false, so the certificate may not be used + // as a parent certificate (certpath validation should fail) + ProcessTools.executeCommand(KEYTOOL, + "-genkeypair", + "-alias", CA_KEY_ALIAS, + "-keyalg", KEY_ALG, + "-keysize", Integer.toString(KEY_SIZE), + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-dname", "CN=CA", + "-ext", "BasicConstraints:critical=ca:false", + "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0); + + // create a certificate that is signed by self-signed certificate + // despite of it may not be used as a parent certificate + // (certpath validation should fail) + ProcessTools.executeCommand(KEYTOOL, + "-genkeypair", + "-alias", KEY_ALIAS, + "-keyalg", KEY_ALG, + "-keysize", Integer.toString(KEY_SIZE), + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-dname", "CN=Test", + "-ext", "BasicConstraints:critical=ca:false", + "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0); + + ProcessTools.executeCommand(KEYTOOL, + "-certreq", + "-alias", KEY_ALIAS, + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-file", CERT_REQUEST_FILENAME).shouldHaveExitValue(0); + + ProcessTools.executeCommand(KEYTOOL, + "-gencert", + "-alias", CA_KEY_ALIAS, + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-infile", CERT_REQUEST_FILENAME, + "-validity", Integer.toString(VALIDITY), + "-outfile", CERT_FILENAME).shouldHaveExitValue(0); + + ProcessTools.executeCommand(KEYTOOL, + "-importcert", + "-alias", KEY_ALIAS, + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-file", CERT_FILENAME).shouldHaveExitValue(0); + + ProcessBuilder pb = new ProcessBuilder(KEYTOOL, + "-export", + "-rfc", + "-alias", KEY_ALIAS, + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD); + pb.redirectOutput(ProcessBuilder.Redirect.appendTo(new File(CHAIN))); + ProcessTools.executeCommand(pb).shouldHaveExitValue(0); + + pb = new ProcessBuilder(KEYTOOL, + "-export", + "-rfc", + "-alias", CA_KEY_ALIAS, + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD); + pb.redirectOutput(ProcessBuilder.Redirect.appendTo(new File(CHAIN))); + ProcessTools.executeCommand(pb).shouldHaveExitValue(0); + + // remove CA certificate + ProcessTools.executeCommand(KEYTOOL, + "-delete", + "-alias", CA_KEY_ALIAS, + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD).shouldHaveExitValue(0); + + // sign jar + OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER, + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-certchain", CHAIN, + "-signedjar", SIGNED_JARFILE, + UNSIGNED_JARFILE, + KEY_ALIAS); + + checkSigning(analyzer, CHAIN_NOT_VALIDATED_SIGNING_WARNING); + + // verify signed jar + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-verbose", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-certchain", CHAIN, + SIGNED_JARFILE); + + checkVerifying(analyzer, 0, CHAIN_NOT_VALIDATED_VERIFYING_WARNING); + + // verify signed jar in strict mode + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-verbose", + "-strict", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-certchain", CHAIN, + SIGNED_JARFILE); + + checkVerifying(analyzer, CHAIN_NOT_VALIDATED_EXIT_CODE, + CHAIN_NOT_VALIDATED_VERIFYING_WARNING); + + System.out.println("Test passed"); + } + +} --- /dev/null 2016-04-23 21:58:04.511940756 +0300 +++ new/test/sun/security/tools/jarsigner/warnings/HasExpiredCertTest.java 2016-04-28 20:02:44.929385032 +0300 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013, 2015, 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.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.JarUtils; + +/** + * @test + * @bug 8024302 8026037 + * @summary Test for hasExpiredCert warning + * @library /lib/testlibrary ../ + * @run main HasExpiredCertTest + */ +public class HasExpiredCertTest extends Test { + + static final int SHORT_VALIDITY = 365; + + /** + * The test signs and verifies a jar that contains entries + * whose signer certificate has expired (hasExpiredCert). + * Warning message is expected. + */ + public static void main(String[] args) throws Throwable { + HasExpiredCertTest test = new HasExpiredCertTest(); + test.start(); + } + + private void start() throws Throwable { + // create a jar file that contains one class file + Utils.createFiles(FIRST_FILE); + JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); + + // create key pair for jar signing + ProcessTools.executeCommand(KEYTOOL, + "-genkey", + "-alias", KEY_ALIAS, + "-keyalg", KEY_ALG, + "-keysize", Integer.toString(KEY_SIZE), + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-dname", "CN=Test", + "-startdate", "-" + SHORT_VALIDITY * 2 + "d", + "-validity", Integer.toString(SHORT_VALIDITY)) + .shouldHaveExitValue(0); + + // sign jar + OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER, + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-signedjar", SIGNED_JARFILE, + UNSIGNED_JARFILE, + KEY_ALIAS); + + checkSigning(analyzer, HAS_EXPIRED_CERT_SIGNING_WARNING); + + // verify signed jar + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-verbose", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + SIGNED_JARFILE); + + checkVerifying(analyzer, 0, HAS_EXPIRED_CERT_VERIFYING_WARNING); + + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-strict", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + SIGNED_JARFILE); + + checkVerifying(analyzer, HAS_EXPIRED_CERT_EXIT_CODE, + HAS_EXPIRED_CERT_VERIFYING_WARNING); + + System.out.println("Test passed"); + } + +} --- /dev/null 2016-04-23 21:58:04.511940756 +0300 +++ new/test/sun/security/tools/jarsigner/warnings/HasExpiringCertTest.java 2016-04-28 20:02:45.533551791 +0300 @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013, 2015, 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.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.JarUtils; + +/** + * @test + * @bug 8024302 8026037 + * @summary Test for hasExpiringCert warning + * @library /lib/testlibrary ../ + * @run main HasExpiringCertTest + */ +public class HasExpiringCertTest extends Test { + + static final int SHORT_VALIDITY = 90; // less than 6 month + + /** + * The test signs and verifies a jar that contains entries + * whose signer certificate will expire within six months (hasExpiringCert). + * Warning message is expected. + */ + public static void main(String[] args) throws Throwable { + HasExpiringCertTest test = new HasExpiringCertTest(); + test.start(); + } + + private void start() throws Throwable { + // create a jar file that contains one class file + Utils.createFiles(FIRST_FILE); + JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); + + // create key pair for jar signing + ProcessTools.executeCommand(KEYTOOL, + "-genkey", + "-alias", KEY_ALIAS, + "-keyalg", KEY_ALG, + "-keysize", Integer.toString(KEY_SIZE), + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-dname", "CN=Test", + "-validity", Integer.toString(SHORT_VALIDITY)) + .shouldHaveExitValue(0); + + // sign jar + OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER, + "-keystore", KEYSTORE, + "-verbose", + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-signedjar", SIGNED_JARFILE, + UNSIGNED_JARFILE, + KEY_ALIAS); + + checkSigning(analyzer, HAS_EXPIRING_CERT_SIGNING_WARNING); + + // verify signed jar + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-verbose", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + SIGNED_JARFILE, + KEY_ALIAS); + + checkVerifying(analyzer, 0, HAS_EXPIRING_CERT_VERIFYING_WARNING); + + // verify signed jar in strict mode + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-verbose", + "-strict", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + SIGNED_JARFILE, + KEY_ALIAS); + + checkVerifying(analyzer, 0, HAS_EXPIRING_CERT_VERIFYING_WARNING); + + System.out.println("Test passed"); + } + +} --- /dev/null 2016-04-23 21:58:04.511940756 +0300 +++ new/test/sun/security/tools/jarsigner/warnings/HasUnsignedEntryTest.java 2016-04-28 20:02:46.144185568 +0300 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013, 2015, 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.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.JarUtils; + +/** + * @test + * @bug 8024302 8026037 + * @summary Test for hasUnsignedEntry warning + * @library /lib/testlibrary ../ + * @run main HasUnsignedEntryTest + */ +public class HasUnsignedEntryTest extends Test { + + /** + * The test signs and verifies a jar that contains unsigned entries + * which have not been integrity-checked (hasUnsignedEntry). + * Warning message is expected. + */ + public static void main(String[] args) throws Throwable { + HasUnsignedEntryTest test = new HasUnsignedEntryTest(); + test.start(); + } + + private void start() throws Throwable { + System.out.println(String.format("Create a %s that contains %s", + UNSIGNED_JARFILE, FIRST_FILE)); + Utils.createFiles(FIRST_FILE, SECOND_FILE); + JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); + + // create key pair for signing + ProcessTools.executeCommand(KEYTOOL, + "-genkey", + "-alias", KEY_ALIAS, + "-keyalg", KEY_ALG, + "-keysize", Integer.toString(KEY_SIZE), + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-dname", "CN=Test", + "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0); + + // sign jar + OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verbose", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-signedjar", SIGNED_JARFILE, + UNSIGNED_JARFILE, + KEY_ALIAS); + + checkSigning(analyzer); + + System.out.println(String.format("Copy %s to %s, and add %s.class, " + + "so it contains unsigned entry", + new Object[]{SIGNED_JARFILE, UPDATED_SIGNED_JARFILE, + SECOND_FILE})); + + JarUtils.updateJar(SIGNED_JARFILE, UPDATED_SIGNED_JARFILE, SECOND_FILE); + + // verify jar + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-verbose", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + UPDATED_SIGNED_JARFILE); + + checkVerifying(analyzer, 0, HAS_UNSIGNED_ENTRY_VERIFYING_WARNING); + + // verify jar in strict mode + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-verbose", + "-strict", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + UPDATED_SIGNED_JARFILE); + + checkVerifying(analyzer, HAS_UNSIGNED_ENTRY_EXIT_CODE, + HAS_UNSIGNED_ENTRY_VERIFYING_WARNING); + + System.out.println("Test passed"); + } + +} --- /dev/null 2016-04-23 21:58:04.511940756 +0300 +++ new/test/sun/security/tools/jarsigner/warnings/MultipleWarningsTest.java 2016-04-28 20:02:46.709137758 +0300 @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2013, 2015, 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.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.JarUtils; + +/** + * @test + * @bug 8024302 8026037 + * @summary Checks if jarsigner prints appropriate warnings + * @library /lib/testlibrary ../ + * @run main MultipleWarningsTest + */ +public class MultipleWarningsTest extends Test { + + /** + * The test signs and verifies a jar that: + * - contains entries whose signer certificate has expired + * - contains entries whose signer certificate's ExtendedKeyUsage + * extension doesn't allow code signing + * - contains unsigned entries which have not been integrity-checked + * - contains signed entries which are not signed by the specified alias + * Warning messages are expected. + */ + public static void main(String[] args) throws Throwable { + MultipleWarningsTest test = new MultipleWarningsTest(); + test.start(); + } + + private void start() throws Throwable { + Utils.createFiles(FIRST_FILE, SECOND_FILE); + + // create a jar file that contains one class file + JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); + + // create first expired certificate + // whose ExtendedKeyUsage extension does not allow code signing + ProcessTools.executeCommand(KEYTOOL, + "-genkey", + "-alias", FIRST_KEY_ALIAS, + "-keyalg", KEY_ALG, + "-keysize", Integer.toString(KEY_SIZE), + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-dname", "CN=First", + "-ext", "ExtendedkeyUsage=serverAuth", + "-startdate", "-" + VALIDITY * 2 + "d", + "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0); + + // create second expired certificate + // whose KeyUsage extension does not allow code signing + ProcessTools.executeCommand(KEYTOOL, + "-genkey", + "-alias", SECOND_KEY_ALIAS, + "-keyalg", KEY_ALG, + "-keysize", Integer.toString(KEY_SIZE), + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-dname", "CN=Second", + "-ext", "ExtendedkeyUsage=serverAuth", + "-startdate", "-" + VALIDITY * 2 + "d", + "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0); + + // sign jar with first key + OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER, + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-signedjar", SIGNED_JARFILE, + UNSIGNED_JARFILE, + FIRST_KEY_ALIAS); + + checkSigning(analyzer, HAS_EXPIRED_CERT_SIGNING_WARNING, + BAD_EXTENDED_KEY_USAGE_SIGNING_WARNING); + + // add a second class to created jar, so it contains unsigned entry + JarUtils.updateJar(SIGNED_JARFILE, UPDATED_SIGNED_JARFILE, SECOND_FILE); + + // verify jar with second key + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + UPDATED_SIGNED_JARFILE, + SECOND_KEY_ALIAS); + + checkVerifying(analyzer, 0, BAD_EXTENDED_KEY_USAGE_VERIFYING_WARNING, + HAS_EXPIRED_CERT_VERIFYING_WARNING, + HAS_UNSIGNED_ENTRY_VERIFYING_WARNING, + NOT_SIGNED_BY_ALIAS_VERIFYING_WARNING); + + // verify jar with second key in strict mode + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-strict", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + UPDATED_SIGNED_JARFILE, + SECOND_KEY_ALIAS); + + int expectedExitCode = HAS_EXPIRED_CERT_EXIT_CODE + + BAD_EXTENDED_KEY_USAGE_EXIT_CODE + + HAS_UNSIGNED_ENTRY_EXIT_CODE + + NOT_SIGNED_BY_ALIAS_EXIT_CODE; + checkVerifying(analyzer, expectedExitCode, + BAD_EXTENDED_KEY_USAGE_VERIFYING_WARNING, + HAS_EXPIRED_CERT_VERIFYING_WARNING, + HAS_UNSIGNED_ENTRY_VERIFYING_WARNING, + NOT_SIGNED_BY_ALIAS_VERIFYING_WARNING); + + // verify jar with non-exisiting alias + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + UPDATED_SIGNED_JARFILE, + "bogus"); + + checkVerifying(analyzer, 0, BAD_EXTENDED_KEY_USAGE_VERIFYING_WARNING, + HAS_EXPIRED_CERT_VERIFYING_WARNING, + HAS_UNSIGNED_ENTRY_VERIFYING_WARNING, + NOT_SIGNED_BY_ALIAS_VERIFYING_WARNING); + + // verify jar with non-exisiting alias in strict mode + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-strict", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + UPDATED_SIGNED_JARFILE, + "bogus"); + + checkVerifying(analyzer, expectedExitCode, + BAD_EXTENDED_KEY_USAGE_VERIFYING_WARNING, + HAS_EXPIRED_CERT_VERIFYING_WARNING, + HAS_UNSIGNED_ENTRY_VERIFYING_WARNING, + NOT_SIGNED_BY_ALIAS_VERIFYING_WARNING); + + System.out.println("Test passed"); + } + +} --- /dev/null 2016-04-23 21:58:04.511940756 +0300 +++ new/test/sun/security/tools/jarsigner/warnings/NoTimestampTest.java 2016-04-28 20:02:47.280756672 +0300 @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013, 2015, 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 java.util.Date; +import jdk.testlibrary.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.JarUtils; + +/** + * @test + * @bug 8024302 8026037 + * @summary Checks warnings if -tsa and -tsacert options are not specified + * @library /lib/testlibrary ../ + * @run main NoTimestampTest + */ +public class NoTimestampTest extends Test { + + /** + * The test signs and verifies a jar file without -tsa and -tsacert options, + * and checks that proper warnings are shown. + */ + public static void main(String[] args) throws Throwable { + NoTimestampTest test = new NoTimestampTest(); + test.start(); + } + + private void start() throws Throwable { + String timezone = System.getProperty("user.timezone"); + System.out.println(String.format("Timezone = %s", timezone)); + + // create a jar file that contains one class file + Utils.createFiles(FIRST_FILE); + JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); + + // calculate certificate expiration date + Date expirationDate = new Date(System.currentTimeMillis() + VALIDITY + * 24 * 60 * 60 * 1000L); + + // create key pair + ProcessTools.executeCommand(KEYTOOL, + "-genkey", + "-alias", KEY_ALIAS, + "-keyalg", KEY_ALG, + "-keysize", Integer.toString(KEY_SIZE), + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-dname", "CN=Test", + "-validity", Integer.toString(VALIDITY)); + + // sign jar file + OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER, + "-J-Duser.timezone=" + timezone, + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-signedjar", SIGNED_JARFILE, + UNSIGNED_JARFILE, + KEY_ALIAS); + + String warning = String.format(NO_TIMESTAMP_SIGNING_WARN_TEMPLATE, + expirationDate); + checkSigning(analyzer, warning); + + // verify signed jar + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-J-Duser.timezone=" + timezone, + "-verify", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + SIGNED_JARFILE, + KEY_ALIAS); + + warning = String.format(NO_TIMESTAMP_VERIFYING_WARN_TEMPLATE, expirationDate); + checkVerifying(analyzer, 0, warning); + + // verify signed jar in strict mode + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-J-Duser.timezone=" + timezone, + "-verify", + "-strict", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + SIGNED_JARFILE, + KEY_ALIAS); + + checkVerifying(analyzer, 0, warning); + + System.out.println("Test passed"); + } + +} --- /dev/null 2016-04-23 21:58:04.511940756 +0300 +++ new/test/sun/security/tools/jarsigner/warnings/NotSignedByAliasTest.java 2016-04-28 20:02:47.842924121 +0300 @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2013, 2015, 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.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.JarUtils; + +/** + * @test + * @bug 8024302 8026037 + * @summary Test for notSignedByAlias warning + * @library /lib/testlibrary ../ + * @run main NotSignedByAliasTest + */ +public class NotSignedByAliasTest extends Test { + + /** + * The test signs and verifies a jar that contains signed entries + * which are not signed by the specified alias(es) (notSignedByAlias). + * Warning message is expected. + */ + public static void main(String[] args) throws Throwable { + NotSignedByAliasTest test = new NotSignedByAliasTest(); + test.start(); + } + + protected void start() throws Throwable { + // create a jar file that contains one class file + Utils.createFiles(FIRST_FILE); + JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); + + // create first key pair for signing + ProcessTools.executeCommand(KEYTOOL, + "-genkey", + "-alias", FIRST_KEY_ALIAS, + "-keyalg", KEY_ALG, + "-keysize", Integer.toString(KEY_SIZE), + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-dname", "CN=First", + "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0); + + // create first key pair for signing + ProcessTools.executeCommand(KEYTOOL, + "-genkey", + "-alias", SECOND_KEY_ALIAS, + "-keyalg", KEY_ALG, + "-keysize", Integer.toString(KEY_SIZE), + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-dname", "CN=Second", + "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0); + + // sign jar with first key + OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER, + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-signedjar", SIGNED_JARFILE, + UNSIGNED_JARFILE, + FIRST_KEY_ALIAS); + + checkSigning(analyzer); + + // verify jar with second key + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + SIGNED_JARFILE, + SECOND_KEY_ALIAS); + + checkVerifying(analyzer, 0, NOT_SIGNED_BY_ALIAS_VERIFYING_WARNING); + + // verify jar with second key in strict mode + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-strict", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + SIGNED_JARFILE, + SECOND_KEY_ALIAS); + + checkVerifying(analyzer, NOT_SIGNED_BY_ALIAS_EXIT_CODE, + NOT_SIGNED_BY_ALIAS_VERIFYING_WARNING); + + // verify jar with non-existing alias + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + SIGNED_JARFILE, + "bogus"); + + checkVerifying(analyzer, 0, NOT_SIGNED_BY_ALIAS_VERIFYING_WARNING); + + // verify jar with non-existing alias in strict mode + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-strict", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + SIGNED_JARFILE, + "bogus"); + + checkVerifying(analyzer, NOT_SIGNED_BY_ALIAS_EXIT_CODE, + NOT_SIGNED_BY_ALIAS_VERIFYING_WARNING); + + System.out.println("Test passed"); + } + +} --- /dev/null 2016-04-23 21:58:04.511940756 +0300 +++ new/test/sun/security/tools/jarsigner/warnings/NotYetValidCertTest.java 2016-04-28 20:02:48.423329518 +0300 @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013, 2015, 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.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; +import jdk.testlibrary.JarUtils; + +/** + * @test + * @bug 8024302 8026037 + * @summary Test for notYetValidCert warning + * @library /lib/testlibrary ../ + * @run main NotYetValidCertTest + */ +public class NotYetValidCertTest extends Test { + + /** + * The test signs and verifies a jar that contains entries + * whose signer certificate is not yet valid (notYetValidCert). + * Warning message is expected. + */ + public static void main(String[] args) throws Throwable { + NotYetValidCertTest test = new NotYetValidCertTest(); + test.start(); + } + + protected void start() throws Throwable { + // create a jar file that contains one class file + Utils.createFiles(FIRST_FILE); + JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); + + // create certificate that will be valid only tomorrow + ProcessTools.executeCommand(KEYTOOL, + "-genkey", + "-alias", KEY_ALIAS, + "-keyalg", KEY_ALG, + "-keysize", Integer.toString(KEY_SIZE), + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-dname", "CN=Test", + "-startdate", "+1d", + "-validity", Integer.toString(VALIDITY)); + + // sign jar + OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER, + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + "-signedjar", SIGNED_JARFILE, + UNSIGNED_JARFILE, + KEY_ALIAS); + + checkSigning(analyzer, NOT_YET_VALID_CERT_SIGNING_WARNING); + + // verify signed jar + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-verbose", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + SIGNED_JARFILE, + KEY_ALIAS); + + checkVerifying(analyzer, 0, NOT_YET_VALID_CERT_VERIFYING_WARNING); + + // verify jar in strict mode + analyzer = ProcessTools.executeCommand(JARSIGNER, + "-verify", + "-verbose", + "-strict", + "-keystore", KEYSTORE, + "-storepass", PASSWORD, + "-keypass", PASSWORD, + SIGNED_JARFILE, + KEY_ALIAS); + + checkVerifying(analyzer, HAS_EXPIRED_CERT_EXIT_CODE, + NOT_YET_VALID_CERT_VERIFYING_WARNING); + + System.out.println("Test passed"); + } + +} --- /dev/null 2016-04-23 21:58:04.511940756 +0300 +++ new/test/sun/security/tools/jarsigner/warnings/Test.java 2016-04-28 20:02:48.987837983 +0300 @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2013, 2016, 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.OutputAnalyzer; + +/** + * Base class. + */ +public abstract class Test { + + static final String TEST_SOURCES = System.getProperty("test.src", "."); + static final String TEST_CLASSES = System.getProperty("test.classes"); + static final String FS = System.getProperty("file.separator"); + static final String JAVA_HOME = System.getProperty("test.jdk"); + static final String KEYTOOL = JAVA_HOME + FS + "bin" + FS + "keytool"; + static final String JARSIGNER = JAVA_HOME + FS + "bin" + FS + "jarsigner"; + static final String UNSIGNED_JARFILE = "unsigned.jar"; + static final String SIGNED_JARFILE = "signed.jar"; + static final String UPDATED_SIGNED_JARFILE = "updated_signed.jar"; + static final String FIRST_FILE = "first.txt"; + static final String SECOND_FILE = "second.txt"; + static final String PASSWORD = "password"; + static final String BOTH_KEYS_KEYSTORE = "both_keys.jks"; + static final String FIRST_KEY_KEYSTORE = "first_key.jks"; + static final String KEYSTORE = "keystore.jks"; + static final String FIRST_KEY_ALIAS = "first"; + static final String SECOND_KEY_ALIAS = "second"; + static final String KEY_ALG = "RSA"; + static final String KEY_ALIAS = "alias"; + static final String CERT_REQUEST_FILENAME = "test.req"; + static final String CERT_FILENAME = "test.crt"; + static final String CA_KEY_ALIAS = "ca"; + static final int KEY_SIZE = 2048; + static final int TIMEOUT = 6 * 60 * 1000; // in millis + static final int VALIDITY = 365; + + static final String WARNING = "Warning:"; + + static final String CHAIN_NOT_VALIDATED_VERIFYING_WARNING + = "This jar contains entries " + + "whose certificate chain is not validated."; + + static final String ALIAS_NOT_IN_STORE_VERIFYING_WARNING + = "This jar contains signed entries " + + "that are not signed by alias in this keystore."; + + static final String BAD_EXTENDED_KEY_USAGE_SIGNING_WARNING + = "The signer certificate's ExtendedKeyUsage extension " + + "doesn't allow code signing."; + + static final String BAD_EXTENDED_KEY_USAGE_VERIFYING_WARNING + = "This jar contains entries whose signer certificate's " + + "ExtendedKeyUsage extension doesn't allow code signing."; + + static final String BAD_KEY_USAGE_SIGNING_WARNING + = "The signer certificate's KeyUsage extension " + + "doesn't allow code signing."; + + static final String BAD_KEY_USAGE_VERIFYING_WARNING + = "This jar contains entries whose signer certificate's KeyUsage " + + "extension doesn't allow code signing."; + + static final String BAD_NETSCAPE_CERT_TYPE_SIGNING_WARNING + = "The signer certificate's NetscapeCertType extension " + + "doesn't allow code signing."; + + static final String BAD_NETSCAPE_CERT_TYPE_VERIFYING_WARNING + = "This jar contains entries " + + "whose signer certificate's NetscapeCertType extension " + + "doesn't allow code signing."; + + static final String CHAIN_NOT_VALIDATED_SIGNING_WARNING + = "The signer's certificate chain is not validated."; + + static final String HAS_EXPIRING_CERT_SIGNING_WARNING + = "The signer certificate will expire within six months."; + + static final String HAS_EXPIRING_CERT_VERIFYING_WARNING + = "This jar contains entries " + + "whose signer certificate will expire within six months."; + + static final String HAS_EXPIRED_CERT_SIGNING_WARNING + = "The signer certificate has expired."; + + static final String HAS_EXPIRED_CERT_VERIFYING_WARNING + = "This jar contains entries whose signer certificate has expired."; + + static final String HAS_UNSIGNED_ENTRY_VERIFYING_WARNING + = "This jar contains unsigned entries " + + "which have not been integrity-checked."; + + static final String NOT_SIGNED_BY_ALIAS_VERIFYING_WARNING + = "This jar contains signed entries " + + "which are not signed by the specified alias(es)."; + + static final String NO_TIMESTAMP_SIGNING_WARN_TEMPLATE + = "No -tsa or -tsacert is provided " + + "and this jar is not timestamped. " + + "Without a timestamp, users may not be able to validate this jar " + + "after the signer certificate's expiration date " + + "(%1$tY-%1$tm-%1$td) or after any future revocation date."; + + static final String NO_TIMESTAMP_VERIFYING_WARN_TEMPLATE + = "This jar contains signatures that does not include a timestamp. " + + "Without a timestamp, users may not be able to validate this jar " + + "after the signer certificate's expiration date " + + "(%1$tY-%1$tm-%1$td) or after any future revocation date."; + + static final String NOT_YET_VALID_CERT_SIGNING_WARNING + = "The signer certificate is not yet valid."; + + static final String NOT_YET_VALID_CERT_VERIFYING_WARNING + = "This jar contains entries " + + "whose signer certificate is not yet valid."; + + static final String JAR_SIGNED = "jar signed."; + + static final String JAR_VERIFIED = "jar verified."; + + static final String JAR_VERIFIED_WITH_SIGNER_ERRORS + = "jar verified, with signer errors."; + + static final int CHAIN_NOT_VALIDATED_EXIT_CODE = 4; + static final int HAS_EXPIRED_CERT_EXIT_CODE = 4; + static final int BAD_KEY_USAGE_EXIT_CODE = 8; + static final int BAD_EXTENDED_KEY_USAGE_EXIT_CODE = 8; + static final int BAD_NETSCAPE_CERT_TYPE_EXIT_CODE = 8; + static final int HAS_UNSIGNED_ENTRY_EXIT_CODE = 16; + static final int ALIAS_NOT_IN_STORE_EXIT_CODE = 32; + static final int NOT_SIGNED_BY_ALIAS_EXIT_CODE = 32; + + protected void checkVerifying(OutputAnalyzer analyzer, int expectedExitCode, + String... warnings) { + analyzer.shouldHaveExitValue(expectedExitCode); + for (String warning : warnings) { + analyzer.shouldContain(warning); + } + if (warnings.length > 0) { + analyzer.shouldContain(WARNING); + } + if (expectedExitCode == 0) { + analyzer.shouldContain(JAR_VERIFIED); + } else { + analyzer.shouldContain(JAR_VERIFIED_WITH_SIGNER_ERRORS); + } + } + + protected void checkSigning(OutputAnalyzer analyzer, String... warnings) { + analyzer.shouldHaveExitValue(0); + for (String warning : warnings) { + analyzer.shouldContain(warning); + } + if (warnings.length > 0) { + analyzer.shouldContain(WARNING); + } + analyzer.shouldContain(JAR_SIGNED); + } +} --- /dev/null 2016-04-23 21:58:04.511940756 +0300 +++ new/test/sun/security/tools/jarsigner/warnings/bad_netscape_cert_type.jks.base64 2016-04-28 20:02:49.657442308 +0300 @@ -0,0 +1,26 @@ +/u3+7QAAAAIAAAABAAAAAQAFYWxpYXMAAAFBpkwW0gAAAr0wggK5MA4GCisGAQQB +KgIRAQEFAASCAqWkGJ3PPjYmWNKrV23Y1u413RMAkrRZ+1OLWYRcQt4jtxtIyEH5 +Ho5b9dy9XN9FBKlTOD4c2Pc1T43BLKXeuLu3uLLeIxgXFt0z9CLyGwdYZZ751kXr +DQ99qY6aNQUO6SeE4Wdty0KPAqid6ZJ8bF7T6wsTZSvNhaBRzyFydEfG7bbUYjOl +mWC44nlsu6VEU3o9RQpcm1gIMwradOaIVT/HoB2bKmAv8gHqI6kreiEZwTdZkSAI +IRi2vt1RPllXt5hgjDxUfZe8XOYYweR4Vt2/jVuKLJ80DNTu/9SeUD88zQAz53k4 +r3nRhv6TRcPm6tV/Fh92XLHiskL+TAzTfm+bUAudPCCVxN+yRtxvAgA+UhdV/SuM +Zn5F6nrmP+YJG1hmprgCJIJJaCEXa9RXYC+vIVpO0WVNRuGlGm+/1afnOuQC8Wss +ShXwjkaqTwAhqBFq7eYmmP8BK3gflYrt2zDLXvhl4ndVvMhMthFJ3ZvLh2LWpqLI +/n8EMCf8US3lIEFk9DTHBZjffiHkqK2e7+FXEpG3xrgE6ZYLMdbd5Pb3YjZfhQx+ +ZTtiEFzYSaEGhacek/m7dRq1qmwgFsytng2OdWZe2ln8LJY0odr1dGUfJHfgafvi +tlfbkg/rgjONtwliChDggbkUwnerrj/D/zrdEufUvfyltSshhHXRNDD3fH6spmEk +hHKgxEc4yvxqJxzdMGtuib355aSfNegyl+GsnsKzXQCVEK2h3BLTQObzaD+8NZ12 +LQHvbrCiaS34vxJ3rEC+a+SW7itZp0aCdXMWdMJNkRKqyLBD3vG3zN05sN3XrhEM +8BRT020TWY00tbVFbbBFheYLQRgTjrQtr0Yt6UHWBZc4N20crDLcSH5gqcCOVpla +1Y2uqFEn8yqrGRwn/kgfNgAAAAEABVguNTA5AAABtTCCAbEwggEaoAMCAQICCQDH +cEuVvzCuqzANBgkqhkiG9w0BAQUFADAPMQ0wCwYDVQQDDARUZXN0MB4XDTEzMTAx +MTA2NTUwNloXDTIzMTAwOTA2NTUwNlowDzENMAsGA1UEAwwEVGVzdDCBnzANBgkq +hkiG9w0BAQEFAAOBjQAwgYkCgYEA8hOfp2Dcnvt//ZZQAja9TRiwKqXVS+TiYE3S +gngCBjIi+YYdo0DsUeO5MBfE6uvCWOr5lwAR/u1iaJOhIoGJDiGoPasZlt+yIgtR +LzA7j2q+1q6kcwiVxfikI3aUgHV/QsybTriT4Bf7TQNKtJG23MQa4sD7+PjtCWD7 +p3cHTfkCAwEAAaMVMBMwEQYJYIZIAYb4QgEBBAQDAgeAMA0GCSqGSIb3DQEBBQUA +A4GBAKoDlTJ8wLRA7G8XdGm4gv733n1cSQzlkcsjfOO6/mA5Jvu8tyFNq9HTf9AT +VXbrbGcUYJjhzSSY3w5apXK1kXyqTB1LUNEJ45WnmciqSSecVTpJz9TuegyoX0Zf +HScSgqfDmjqoiiFiNCgn3ZEJ85ykGvoFYGH+php+BVi3S0bj5E/jRpyV3vNnii/S +wJDSAXF6bYU= --- /dev/null 2016-04-23 21:58:04.511940756 +0300 +++ new/test/sun/security/tools/jarsigner/warnings/bad_netscape_cert_type.sh 2016-04-28 20:02:50.305385480 +0300 @@ -0,0 +1,48 @@ +# +# Copyright (c) 2013, 2015, 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. +# + +#!/bin/sh + +# This script creates JKS keystore with a certificate +# that contains Netscape Certificate Type extension +# that does not allow code signing +# The keystore is used by BadNetscapeCertTypeTest.java test + +rm -rf keystore.jks +echo "nsCertType = client" > ext.cfg + +openssl req -new -out cert.req -keyout key.pem -days 3650 \ + -passin pass:password -passout pass:password -subj "/CN=Test" +openssl x509 -in cert.req -out cert.pem -req -signkey key.pem -days 3650 \ + -passin pass:password -extfile ext.cfg +openssl pkcs12 -export -in cert.pem -inkey key.pem -out keystore.p12 \ + -passin pass:password -passout pass:password -name alias + +${JAVA_HOME}/bin/keytool -importkeystore \ + -srckeystore keystore.p12 -srcstoretype pkcs12 \ + -srcstorepass password -alias alias \ + -destkeystore bad_netscape_cert_type.jks -deststoretype jks \ + -deststorepass password -destalias alias \ + +openssl base64 < bad_netscape_cert_type.jks > bad_netscape_cert_type.jks.base64 +rm -rf cert.req key.pem cert.pem keystore.p12 ext.cfg bad_netscape_cert_type.jks