1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 8192988 27 * @summary keytool should support -storepasswd for pkcs12 keystores 28 * @library /test/lib 29 * @build jdk.test.lib.SecurityTools 30 * jdk.test.lib.Utils 31 * jdk.test.lib.Asserts 32 * jdk.test.lib.JDKToolFinder 33 * jdk.test.lib.JDKToolLauncher 34 * jdk.test.lib.Platform 35 * jdk.test.lib.process.* 36 * @run main JKStoPKCS12 37 */ 38 39 import jdk.test.lib.Asserts; 40 import jdk.test.lib.SecurityTools; 41 import jdk.test.lib.process.OutputAnalyzer; 42 43 import java.io.File; 44 import java.nio.file.Files; 45 import java.nio.file.Paths; 46 import java.security.KeyStore; 47 import java.util.Collections; 48 49 public class JKStoPKCS12 { 50 51 static String srcStorePass, srcKeyPass; 52 53 public static void main(String[] args) throws Exception { 54 55 // Part 1: JKS keystore with same storepass and keypass 56 genJKS("pass1111", "pass1111"); 57 58 // Change storepass, keypass also changes 59 convert("pass2222", null); 60 // You can keep storepass unchanged 61 convert("pass1111", null); 62 // Or change storepass and keypass both, explicitly 63 convert("pass2222", "pass2222"); 64 65 // Part 2: JKS keystore with different storepass and keypass 66 Files.delete(Paths.get("jks")); 67 genJKS("pass1111", "pass2222"); 68 69 // Can use old keypass as new storepass so new storepass and keypass are same 70 convert("pass2222", null); 71 // Or specify both storepass and keypass to brand new ones 72 convert("pass3333", "pass3333"); 73 // Or change storepass, keypass also changes. Remember to provide srckeypass 74 convert("pass1111", null); 75 } 76 77 // Generate JKS keystore with srcStorePass and srcKeyPass 78 static void genJKS(String storePass, String keyPass) 79 throws Exception { 80 srcStorePass = storePass; 81 srcKeyPass = keyPass; 82 kt("-genkeypair -keystore jks -storetype jks " 83 + "-alias me -dname CN=Me -keyalg rsa " 84 + "-storepass " + srcStorePass + " -keypass " + srcKeyPass) 85 .shouldHaveExitValue(0); 86 } 87 88 // Convert JKS to PKCS12 with destStorePass and destKeyPass (optional) 89 static void convert(String destStorePass, String destKeyPass) 90 throws Exception { 91 92 String cmd = "-importkeystore -noprompt" 93 + " -srcstoretype jks -srckeystore jks" 94 + " -destkeystore p12 -deststoretype pkcs12" 95 + " -srcstorepass " + srcStorePass 96 + " -deststorepass " + destStorePass; 97 98 // Must import by alias (-srckeypass not available when importing all) 99 if (!srcStorePass.equals(srcKeyPass)) { 100 cmd += " -srcalias me"; 101 cmd += " -srckeypass " + srcKeyPass; 102 } 103 if (destKeyPass != null) { 104 cmd += " -destkeypass " + destKeyPass; 105 } 106 107 kt(cmd).shouldHaveExitValue(0); 108 109 // Confirms the storepass and keypass are all correct 110 KeyStore.getInstance(new File("p12"), destStorePass.toCharArray()) 111 .getKey("me", destStorePass.toCharArray()); 112 113 Files.delete(Paths.get("p12")); 114 } 115 116 static OutputAnalyzer kt(String arg) throws Exception { 117 return SecurityTools.keytool(arg); 118 } 119 }