8192987: keytool should remember real storetype if it is not provided
authorweijun
Fri, 08 Dec 2017 09:40:14 +0800
changeset 48216 e3b6cb90d7ce
parent 48215 b8b124236073
child 48217 7a83c7afb383
8192987: keytool should remember real storetype if it is not provided Reviewed-by: mullan
src/java.base/share/classes/sun/security/tools/KeyStoreUtil.java
src/java.base/share/classes/sun/security/tools/keytool/Main.java
test/jdk/sun/security/tools/keytool/RealType.java
--- a/src/java.base/share/classes/sun/security/tools/KeyStoreUtil.java	Thu Dec 07 14:21:25 2017 -0800
+++ b/src/java.base/share/classes/sun/security/tools/KeyStoreUtil.java	Fri Dec 08 09:40:14 2017 +0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -93,8 +93,9 @@
      * MSCAPI KeyStores
      */
     public static boolean isWindowsKeyStore(String storetype) {
-        return storetype.equalsIgnoreCase("Windows-MY")
-                || storetype.equalsIgnoreCase("Windows-ROOT");
+        return storetype != null
+                && (storetype.equalsIgnoreCase("Windows-MY")
+                    || storetype.equalsIgnoreCase("Windows-ROOT"));
     }
 
     /**
--- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Thu Dec 07 14:21:25 2017 -0800
+++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Fri Dec 08 09:40:14 2017 +0800
@@ -134,8 +134,6 @@
     private Set<Pair <String, String>> providers = null;
     private Set<Pair <String, String>> providerClasses = null;
     private String storetype = null;
-    private boolean hasStoretypeOption = false;
-    private boolean hasSrcStoretypeOption = false;
     private String srcProviderName = null;
     private String providerName = null;
     private String pathlist = null;
@@ -549,14 +547,12 @@
                 passwords.add(storePass);
             } else if (collator.compare(flags, "-storetype") == 0 ||
                     collator.compare(flags, "-deststoretype") == 0) {
-                storetype = args[++i];
-                hasStoretypeOption = true;
+                storetype = KeyStoreUtil.niceStoreTypeName(args[++i]);
             } else if (collator.compare(flags, "-srcstorepass") == 0) {
                 srcstorePass = getPass(modifier, args[++i]);
                 passwords.add(srcstorePass);
             } else if (collator.compare(flags, "-srcstoretype") == 0) {
-                srcstoretype = args[++i];
-                hasSrcStoretypeOption = true;
+                srcstoretype = KeyStoreUtil.niceStoreTypeName(args[++i]);
             } else if (collator.compare(flags, "-srckeypass") == 0) {
                 srckeyPass = getPass(modifier, args[++i]);
                 passwords.add(srckeyPass);
@@ -708,16 +704,6 @@
             ksfname = KeyStoreUtil.getCacerts();
         }
 
-        if (storetype == null) {
-            storetype = KeyStore.getDefaultType();
-        }
-        storetype = KeyStoreUtil.niceStoreTypeName(storetype);
-
-        if (srcstoretype == null) {
-            srcstoretype = KeyStore.getDefaultType();
-        }
-        srcstoretype = KeyStoreUtil.niceStoreTypeName(srcstoretype);
-
         if (P11KEYSTORE.equalsIgnoreCase(storetype) ||
                 KeyStoreUtil.isWindowsKeyStore(storetype)) {
             token = true;
@@ -742,11 +728,6 @@
                         (".storepasswd.and.keypasswd.commands.not.supported.if.storetype.is.{0}"), storetype));
         }
 
-        if (P12KEYSTORE.equalsIgnoreCase(storetype) && command == KEYPASSWD) {
-            throw new UnsupportedOperationException(rb.getString
-                        (".keypasswd.commands.not.supported.if.storetype.is.PKCS12"));
-        }
-
         if (token && (keyPass != null || newPass != null || destKeyPass != null)) {
             throw new IllegalArgumentException(MessageFormat.format(rb.getString
                 (".keypass.and.new.can.not.be.specified.if.storetype.is.{0}"), storetype));
@@ -923,9 +904,13 @@
         // Create new keystore
         // Probe for keystore type when filename is available
         if (ksfile != null && ksStream != null && providerName == null &&
-                hasStoretypeOption == false && !inplaceImport) {
+                storetype == null && !inplaceImport) {
             keyStore = KeyStore.getInstance(ksfile, storePass);
+            storetype = keyStore.getType();
         } else {
+            if (storetype == null) {
+                storetype = KeyStore.getDefaultType();
+            }
             if (providerName == null) {
                 keyStore = KeyStore.getInstance(storetype);
             } else {
@@ -964,6 +949,11 @@
             }
         }
 
+        if (P12KEYSTORE.equalsIgnoreCase(storetype) && command == KEYPASSWD) {
+            throw new UnsupportedOperationException(rb.getString
+                    (".keypasswd.commands.not.supported.if.storetype.is.PKCS12"));
+        }
+
         // All commands that create or modify the keystore require a keystore
         // password.
 
@@ -2123,9 +2113,13 @@
         try {
             // Probe for keystore type when filename is available
             if (srcksfile != null && is != null && srcProviderName == null &&
-                hasSrcStoretypeOption == false) {
+                    srcstoretype == null) {
                 store = KeyStore.getInstance(srcksfile, srcstorePass);
+                srcstoretype = store.getType();
             } else {
+                if (srcstoretype == null) {
+                    srcstoretype = KeyStore.getDefaultType();
+                }
                 if (srcProviderName == null) {
                     store = KeyStore.getInstance(srcstoretype);
                 } else {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/tools/keytool/RealType.java	Fri Dec 08 09:40:14 2017 +0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017, 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 8192987
+ * @summary keytool should remember real storetype if it is not provided
+ * @library /test/lib
+ * @build jdk.test.lib.SecurityTools
+ *        jdk.test.lib.Utils
+ *        jdk.test.lib.JDKToolFinder
+ *        jdk.test.lib.JDKToolLauncher
+ *        jdk.test.lib.Platform
+ *        jdk.test.lib.process.*
+ * @run main/othervm RealType
+ */
+
+import jdk.test.lib.SecurityTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+public class RealType {
+
+    public static void main(String[] args) throws Throwable {
+
+        kt("-genkeypair -alias a -dname CN=A -keypass changeit -storetype jks")
+                .shouldHaveExitValue(0);
+
+        // -keypasswd command should be allowed on JKS
+        kt("-keypasswd -alias a -new t0ps3cr3t")
+                .shouldHaveExitValue(0);
+
+        Files.delete(Paths.get("ks"));
+
+        kt("-genkeypair -alias a -dname CN=A -keypass changeit -storetype pkcs12")
+                .shouldHaveExitValue(0);
+
+        // A pkcs12 keystore cannot be loaded as a JCEKS keystore
+        kt("-list -storetype jceks").shouldHaveExitValue(1);
+    }
+
+    static OutputAnalyzer kt(String arg) throws Exception {
+        return SecurityTools.keytool("-debug -keystore ks -storepass changeit " + arg);
+    }
+}