8168882: keytool doesn't print certificate info if disabled algorithm was used for signing a jar

Reviewed-by: weijun, mullan
This commit is contained in:
Artem Smotrakov 2016-11-08 15:55:11 -08:00
parent 398942a17f
commit 31c4b07045
6 changed files with 244 additions and 66 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
@ -84,8 +84,10 @@ import sun.security.util.Pem;
import sun.security.x509.*;
import static java.security.KeyStore.*;
import java.security.Security;
import static sun.security.tools.keytool.Main.Command.*;
import static sun.security.tools.keytool.Main.Option.*;
import sun.security.util.DisabledAlgorithmConstraints;
/**
* This tool manages keystores.
@ -2428,6 +2430,10 @@ public final class Main {
private void doPrintCert(final PrintStream out) throws Exception {
if (jarfile != null) {
// reset "jdk.certpath.disabledAlgorithms" security property
// to be able to read jars which were signed with weak algorithms
Security.setProperty(DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS, "");
JarFile jf = new JarFile(jarfile, true);
Enumeration<JarEntry> entries = jf.entries();
Set<CodeSigner> ss = new HashSet<>();

View File

@ -0,0 +1,122 @@
/*
* 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.
*/
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import jdk.testlibrary.JDKToolLauncher;
import jdk.testlibrary.OutputAnalyzer;
import jdk.testlibrary.ProcessTools;
public class SecurityTools {
public static final String NO_ALIAS = null;
// keytool
public static OutputAnalyzer keytool(List<String> options)
throws Throwable {
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("keytool")
.addVMArg("-Duser.language=en")
.addVMArg("-Duser.country=US");
for (String option : options) {
if (option.startsWith("-J")) {
launcher.addVMArg(option.substring(2));
} else {
launcher.addToolArg(option);
}
}
return ProcessTools.executeCommand(launcher.getCommand());
}
public static OutputAnalyzer keytool(String options) throws Throwable {
return keytool(options.split("\\s+"));
}
public static OutputAnalyzer keytool(String... options) throws Throwable {
return keytool(List.of(options));
}
// jarsigner
public static OutputAnalyzer jarsigner(String jar, String alias,
List<String> options) throws Throwable {
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jarsigner")
.addVMArg("-Duser.language=en")
.addVMArg("-Duser.country=US");
for (String option : options) {
if (option.startsWith("-J")) {
launcher.addVMArg(option.substring(2));
} else {
launcher.addToolArg(option);
}
}
launcher.addToolArg(jar);
if (alias != null) {
launcher.addToolArg(alias);
}
return ProcessTools.executeCommand(launcher.getCommand());
}
public static OutputAnalyzer jarsigner(String jar, String alias,
String options) throws Throwable {
return jarsigner(jar, alias, options.split("\\s+"));
}
public static OutputAnalyzer jarsigner(String jar, String alias,
String... options) throws Throwable {
return jarsigner(jar, alias, List.of(options));
}
public static OutputAnalyzer sign(String jar, String alias, String... options)
throws Throwable {
return jarsigner(jar, alias,
mergeOptions("-J-Djava.security.egd=file:/dev/./urandom", options));
}
public static OutputAnalyzer verify(String jar, String... options)
throws Throwable {
return jarsigner(jar, NO_ALIAS, mergeOptions("-verify", options));
}
// helper methods
private static List<String> mergeOptions(
String firstOption, String... secondPart) {
return mergeOptions(List.of(firstOption), secondPart);
}
private static List<String> mergeOptions(
List<String> firstPart, String... secondPart) {
List<String> options = new ArrayList<>(firstPart);
Collections.addAll(options, secondPart);
return options;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 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
@ -1211,18 +1211,26 @@ public class KeyToolTest {
void sqePrintcertTest() throws Exception {
remove("x.jks");
remove("mykey.cert");
remove("myweakkey.cert");
testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -dname CN=olala");
testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
"-export -file mykey.cert -alias mykey");
testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -dname CN=weak -keyalg rsa " +
"-keysize 512 -sigalg MD5withRSA -alias myweakkey");
testOK("", "-keystore x.jks -storetype JKS -storepass changeit " +
"-export -file myweakkey.cert -alias myweakkey");
testFail("", "-printcert -file badkeystore");
testFail("", "-printcert -file a/b/c/d");
testOK("", "-printcert -file mykey.cert");
testOK("", "-printcert -file myweakkey.cert");
FileInputStream fin = new FileInputStream("mykey.cert");
testOK(fin, "-printcert");
fin.close();
remove("x.jks");
remove("mykey.cert");
remove("myweakkey.cert");
}
// 8074935: jdk8 keytool doesn't validate pem files for RFC 1421 correctness

View File

@ -24,20 +24,32 @@
/*
* @test
* @bug 6480981 8160624
* @modules java.base/sun.security.tools.keytool
* @summary keytool should be able to import certificates from remote SSL server
* @library /lib/security
* @library /lib/testlibrary
* @run main/othervm PrintSSL
*/
import java.io.IOException;
import java.net.ServerSocket;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.concurrent.CountDownLatch;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import jdk.testlibrary.OutputAnalyzer;
public class PrintSSL {
public static void main(String[] args) throws Exception {
public static void main(String[] args) throws Throwable {
Files.deleteIfExists(Paths.get("keystore"));
// make sure that "-printcert" works with weak algorithms
OutputAnalyzer out = SecurityTools.keytool("-genkeypair "
+ "-keystore keystore -storepass passphrase "
+ "-keypass passphrase -keyalg rsa -keysize 512 "
+ "-sigalg MD5withRSA -alias rsa_alias -dname CN=Server");
System.out.println(out.getOutput());
out.shouldHaveExitValue(0);
int port = new Server().start();
if(port == -1) {
@ -47,7 +59,10 @@ public class PrintSSL {
String cmd = String.format(
"-debug %s -printcert -sslserver localhost:%s",
((vmOpt == null) ? "" : vmOpt ), port);
sun.security.tools.keytool.Main.main(cmd.split("\\s+"));
out = SecurityTools.keytool(cmd);
System.out.println(out.getOutput());
out.shouldHaveExitValue(0);
}
private static class Server implements Runnable {
@ -68,9 +83,7 @@ public class PrintSSL {
public void run() {
System.setProperty("javax.net.ssl.keyStorePassword", "passphrase");
System.setProperty("javax.net.ssl.keyStore",
System.getProperty("test.src", "./")
+ "/../../../../javax/net/ssl/etc/keystore");
System.setProperty("javax.net.ssl.keyStore", "keystore");
SSLServerSocketFactory sslssf =
(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
try (ServerSocket server = sslssf.createServerSocket(0)) {

View File

@ -0,0 +1,86 @@
/*
* 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.
*/
/**
* @test
* @bug 6890872 8168882
* @summary keytool -printcert to recognize signed jar files
* @library /lib/security
* @library /lib/testlibrary
*/
import java.nio.file.Files;
import java.nio.file.Paths;
import jdk.testlibrary.JarUtils;
import jdk.testlibrary.OutputAnalyzer;
public class ReadJar {
public static void main(String[] args) throws Throwable {
testWithMD5();
}
// make sure that -printcert option works
// if a weak algorithm was used for signing a jar
private static void testWithMD5() throws Throwable {
// create jar files
JarUtils.createJar("test_md5.jar", "test");
JarUtils.createJar("test_rsa.jar", "test");
// create a keystore and generate keys for jar signing
Files.deleteIfExists(Paths.get("keystore"));
OutputAnalyzer out = SecurityTools.keytool("-genkeypair "
+ "-keystore keystore -storepass password "
+ "-keypass password -keyalg rsa -alias rsa_alias -dname CN=A");
System.out.println(out.getOutput());
out.shouldHaveExitValue(0);
out = SecurityTools.jarsigner("test_rsa.jar", "rsa_alias",
"-keystore keystore -storepass password ");
System.out.println(out.getOutput());
out.shouldHaveExitValue(0);
printCert("test_rsa.jar");
out = SecurityTools.jarsigner("test_md5.jar", "rsa_alias",
"-keystore keystore -storepass password "
+ "-sigalg MD5withRSA -digestalg MD5");
System.out.println(out.getOutput());
out.shouldHaveExitValue(0);
printCert("test_md5.jar");
}
private static void printCert(String jar) throws Throwable {
OutputAnalyzer out = SecurityTools.keytool("-printcert -jarfile " + jar);
System.out.println(out.getOutput());
out.shouldHaveExitValue(0);
out.shouldNotContain("Not a signed jar file");
out = SecurityTools.keytool("-printcert -rfc -jarfile " + jar);
System.out.println(out.getOutput());
out.shouldHaveExitValue(0);
out.shouldNotContain("Not a signed jar file");
}
}

View File

@ -1,57 +0,0 @@
#
# Copyright (c) 2009, 2013, 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.
#
# @test
# @bug 6890872
# @summary keytool -printcert to recognize signed jar files
#
if [ "${TESTJAVA}" = "" ] ; then
JAVAC_CMD=`which javac`
TESTJAVA=`dirname $JAVAC_CMD`/..
COMPILEJAVA=${TESTJAVA}
fi
# set platform-dependent variables
OS=`uname -s`
case "$OS" in
Windows_* )
FS="\\"
;;
* )
FS="/"
;;
esac
KS=readjar.jks
rm $KS
$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit -keypass changeit -keystore $KS \
-keyalg rsa -alias x -dname CN=X -genkeypair
$COMPILEJAVA${FS}bin${FS}jar ${TESTTOOLVMOPTS} cvf readjar.jar $KS
$COMPILEJAVA${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} -storepass changeit -keystore $KS readjar.jar x
$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -printcert -jarfile readjar.jar || exit 1
$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -printcert -jarfile readjar.jar -rfc || exit 1
exit 0