author | weijun |
Wed, 10 Aug 2016 11:30:53 +0800 | |
changeset 40253 | 08809866c0bc |
parent 40252 | 8f320a3f83b8 |
child 40254 | a68a0f6758df |
--- a/jdk/make/copy/Copy-java.base.gmk Wed Aug 10 11:21:01 2016 +0800 +++ b/jdk/make/copy/Copy-java.base.gmk Wed Aug 10 11:30:53 2016 +0800 @@ -203,7 +203,7 @@ ################################################################################ ifeq ($(CACERTS_FILE), ) - CACERTS_FILE := $(JDK_TOPDIR)/src/java.base/share/conf/security/cacerts + CACERTS_FILE := $(JDK_TOPDIR)/src/java.base/share/lib/security/cacerts endif CACERTS_DST := $(LIB_DST_DIR)/security/cacerts
--- a/jdk/src/java.base/share/classes/sun/security/tools/KeyStoreUtil.java Wed Aug 10 11:21:01 2016 +0800 +++ b/jdk/src/java.base/share/classes/sun/security/tools/KeyStoreUtil.java Wed Aug 10 11:30:53 2016 +0800 @@ -63,8 +63,6 @@ // this class is not meant to be instantiated } - private static final String JKS = "jks"; - private static final Collator collator = Collator.getInstance(); static { // this is for case insensitive string comparisons @@ -113,24 +111,24 @@ } /** + * Returns the file name of the keystore with the configured CA certificates. + */ + public static String getCacerts() { + String sep = File.separator; + return System.getProperty("java.home") + sep + + "lib" + sep + "security" + sep + + "cacerts"; + } + + /** * Returns the keystore with the configured CA certificates. */ - public static KeyStore getCacertsKeyStore() - throws Exception - { - String sep = File.separator; - File file = new File(System.getProperty("java.home") + sep - + "lib" + sep + "security" + sep - + "cacerts"); + public static KeyStore getCacertsKeyStore() throws Exception { + File file = new File(getCacerts()); if (!file.exists()) { return null; } - KeyStore caks = null; - try (FileInputStream fis = new FileInputStream(file)) { - caks = KeyStore.getInstance(JKS); - caks.load(fis, null); - } - return caks; + return KeyStore.getInstance(file, (char[])null); } public static char[] getPassWithModifier(String modifier, String arg,
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Wed Aug 10 11:21:01 2016 +0800 +++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Wed Aug 10 11:30:53 2016 +0800 @@ -153,6 +153,7 @@ private boolean trustcacerts = false; private boolean protectedPath = false; private boolean srcprotectedPath = false; + private boolean cacerts = false; private CertificateFactory cf = null; private KeyStore caks = null; // "cacerts" keystore private char[] srcstorePass = null; @@ -169,15 +170,15 @@ STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS, PROVIDERPATH, V, PROTECTED), CHANGEALIAS("Changes.an.entry.s.alias", - ALIAS, DESTALIAS, KEYPASS, KEYSTORE, STOREPASS, + ALIAS, DESTALIAS, KEYPASS, KEYSTORE, CACERTS, STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS, PROVIDERPATH, V, PROTECTED), DELETE("Deletes.an.entry", - ALIAS, KEYSTORE, STOREPASS, STORETYPE, + ALIAS, KEYSTORE, CACERTS, STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS, PROVIDERPATH, V, PROTECTED), EXPORTCERT("Exports.certificate", - RFC, ALIAS, FILEOUT, KEYSTORE, STOREPASS, + RFC, ALIAS, FILEOUT, KEYSTORE, CACERTS, STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS, PROVIDERPATH, V, PROTECTED), GENKEYPAIR("Generates.a.key.pair", @@ -196,7 +197,7 @@ PROVIDERCLASS, PROVIDERPATH, V, PROTECTED), IMPORTCERT("Imports.a.certificate.or.a.certificate.chain", NOPROMPT, TRUSTCACERTS, PROTECTED, ALIAS, FILEIN, - KEYPASS, KEYSTORE, STOREPASS, STORETYPE, + KEYPASS, KEYSTORE, CACERTS, STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS, PROVIDERPATH, V), IMPORTPASS("Imports.a.password", @@ -215,7 +216,7 @@ STORETYPE, PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS, PROVIDERPATH, V), LIST("Lists.entries.in.a.keystore", - RFC, ALIAS, KEYSTORE, STOREPASS, STORETYPE, + RFC, ALIAS, KEYSTORE, CACERTS, STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS, PROVIDERPATH, V, PROTECTED), PRINTCERT("Prints.the.content.of.a.certificate", @@ -225,7 +226,7 @@ PRINTCRL("Prints.the.content.of.a.CRL.file", FILEIN, V), STOREPASSWD("Changes.the.store.password.of.a.keystore", - NEW, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME, + NEW, KEYSTORE, CACERTS, STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS, PROVIDERPATH, V), // Undocumented start here, KEYCLONE is used a marker in -help; @@ -306,6 +307,7 @@ KEYPASS("keypass", "<arg>", "key.password"), KEYSIZE("keysize", "<size>", "key.bit.size"), KEYSTORE("keystore", "<keystore>", "keystore.name"), + CACERTS("cacerts", null, "access.the.cacerts.keystore"), NEW("new", "<arg>", "new.password"), NOPROMPT("noprompt", null, "do.not.prompt"), OUTFILE("outfile", "<file>", "output.file.name"), @@ -472,14 +474,16 @@ help = true; } else if (collator.compare(flags, "-conf") == 0) { i++; - } - - /* - * specifiers - */ - else if (collator.compare(flags, "-keystore") == 0 || - collator.compare(flags, "-destkeystore") == 0) { + } else if (collator.compare(flags, "-keystore") == 0) { ksfname = args[++i]; + if (new File(ksfname).getCanonicalPath().equals( + new File(KeyStoreUtil.getCacerts()).getCanonicalPath())) { + System.err.println(rb.getString("warning.cacerts.option")); + } + } else if (collator.compare(flags, "-destkeystore") == 0) { + ksfname = args[++i]; + } else if (collator.compare(flags, "-cacerts") == 0) { + cacerts = true; } else if (collator.compare(flags, "-storepass") == 0 || collator.compare(flags, "-deststorepass") == 0) { storePass = getPass(modifier, args[++i]); @@ -636,6 +640,15 @@ * Execute the commands. */ void doCommands(PrintStream out) throws Exception { + + if (cacerts) { + if (ksfname != null || storetype != null) { + throw new IllegalArgumentException(rb.getString + ("the.keystore.or.storetype.option.cannot.be.used.with.the.cacerts.option")); + } + ksfname = KeyStoreUtil.getCacerts(); + } + if (storetype == null) { storetype = KeyStore.getDefaultType(); }
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources.java Wed Aug 10 11:21:01 2016 +0800 +++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources.java Wed Aug 10 11:30:53 2016 +0800 @@ -127,6 +127,10 @@ "key bit size"}, //-keysize {"keystore.name", "keystore name"}, //-keystore + {"access.the.cacerts.keystore", + "access the cacerts keystore"}, // -cacerts + {"warning.cacerts.option", + "Warning: use -cacerts option to access cacerts keystore"}, {"new.password", "new password"}, //-new {"do.not.prompt", @@ -194,6 +198,8 @@ {"Command.option.flag.needs.an.argument.", "Command option {0} needs an argument."}, {"Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value.", "Warning: Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified {0} value."}, + {"the.keystore.or.storetype.option.cannot.be.used.with.the.cacerts.option", + "The -keystore or -storetype option cannot be used with the -cacerts option"}, {".keystore.must.be.NONE.if.storetype.is.{0}", "-keystore must be NONE if -storetype is {0}"}, {"Too.many.retries.program.terminated",
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/tools/keytool/CacertsOption.java Wed Aug 10 11:30:53 2016 +0800 @@ -0,0 +1,95 @@ +/* + * 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 8162739 + * @summary Create new keytool option to access cacerts file + * @modules java.base/sun.security.tools.keytool + * java.base/sun.security.tools + * @run main/othervm -Duser.language=en -Duser.country=US CacertsOption + */ + +import sun.security.tools.KeyStoreUtil; +import sun.security.tools.keytool.Main; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.PrintStream; +import java.security.KeyStore; +import java.util.Collections; + +public class CacertsOption { + + public static void main(String[] args) throws Exception { + + run("-help -list"); + if (!msg.contains("-cacerts")) { + throw new Exception("No cacerts in help:\n" + msg); + } + + String cacerts = KeyStoreUtil.getCacerts(); + + run("-list -keystore " + cacerts); + if (!msg.contains("Warning:")) { + throw new Exception("No warning in output:\n" + msg); + } + + run("-list -cacerts"); + KeyStore ks = KeyStore.getInstance(new File(cacerts), (char[])null); + for (String alias: Collections.list(ks.aliases())) { + if (!msg.contains(alias)) { + throw new Exception(alias + " not found in\n" + msg); + } + } + + try { + run("-list -cacerts -storetype jks"); + throw new Exception("Should fail"); + } catch (IllegalArgumentException iae) { + if (!msg.contains("cannot be used with")) { + throw new Exception("Bad error msg\n" + msg); + } + } + } + + private static String msg = null; + + private static void run(String cmd) throws Exception { + msg = null; + cmd += " -storepass changeit -debug"; + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(bout); + PrintStream oldOut = System.out; + PrintStream oldErr = System.err; + try { + System.setOut(ps); + System.setErr(ps); + Main.main(cmd.split(" ")); + } finally { + System.setErr(oldErr); + System.setOut(oldOut); + msg = new String(bout.toByteArray()); + } + } +}