You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
234 lines
9.6 KiB
234 lines
9.6 KiB
/* |
|
* Copyright (c) 2008, 2014, 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 static java.lang.System.out; |
|
|
|
import java.io.ByteArrayInputStream; |
|
import java.io.File; |
|
import java.io.FileOutputStream; |
|
import java.nio.file.Files; |
|
import java.nio.file.Paths; |
|
import java.security.Key; |
|
import java.security.KeyStore; |
|
import java.security.KeyStoreException; |
|
import java.security.NoSuchAlgorithmException; |
|
import java.security.UnrecoverableKeyException; |
|
import java.security.cert.Certificate; |
|
import java.util.Arrays; |
|
import java.util.Base64; |
|
import java.util.Enumeration; |
|
|
|
/* |
|
* @test |
|
* @bug 8048619 |
|
* @author Bill Situ |
|
* @summary Test converting keystore from jceks to P12 and from P12 to other |
|
* (jceks,jks). including following test cases: |
|
* Read jceks key store and convert to the p12 key store, then compare entries |
|
* in the two key stores. |
|
* Read p12 key store and convert to the jceks key store, then compare entries |
|
* in the two key stores. |
|
* Read p12 key store (contains only private key and a self-signed certificate) |
|
* and convert to the jceks key store, then compare entries of two key stores. |
|
* Read p12 key store (contains 2 entries) and convert to the jceks key store, |
|
* then compare entries in the two key stores. |
|
* Read p12 key store (entry password and key store password are different) and |
|
* convert to the jceks key store, then compare entries in the two key stores. |
|
* Read p12 key store and convert to the jks key store, then compare entries |
|
* in the two key stores. |
|
* Read p12 key store (contains only private key and a self-signed certificate) |
|
* and convert to the jks key store, then compare entries in the two key stores. |
|
* Read p12 key store (contains 2 entries) and convert to the jks key store, |
|
* then compare entries in the two key stores. |
|
* Read p12 key store (entry password and key store password are different) and |
|
* convert to the jks key store, then compare entries in the two key stores. |
|
*/ |
|
|
|
public class ConvertP12Test { |
|
|
|
private static final String SUN_JSSE = "SunJSSE"; |
|
private static final String SUN_JCE = "SunJCE"; |
|
private static final String SUN = "SUN"; |
|
private static final String PKCS12 = "pkcs12"; |
|
private static final String JCE_KS = "JceKS"; |
|
private static final String JKS = "JKS"; |
|
|
|
public static void main(String args[]) throws Exception { |
|
|
|
ConvertP12Test jstest = new ConvertP12Test(); |
|
|
|
jstest.driver("JceksToP12", "keystoreCA.jceks.data", JCE_KS, SUN_JCE, |
|
"storepass", "keypass", PKCS12, SUN_JSSE); |
|
|
|
jstest.driver("P12ToJceks_Chain", "ie_jceks_chain.pfx.data", PKCS12, |
|
SUN_JSSE, "pass", "pass", JCE_KS, SUN_JCE); |
|
|
|
jstest.driver("P12ToJceks_SelfSigned", "jdk_jceks_selfsigned.p12.data", |
|
PKCS12, SUN_JSSE, "pass", "pass", JCE_KS, SUN_JCE); |
|
|
|
jstest.driver("P12ToJceks_TwoEntry", "jdk_jceks_twoentry.p12.data", |
|
PKCS12, SUN_JSSE, "pass", "pass", JCE_KS, SUN_JCE); |
|
|
|
jstest.driver("P12ToJceks_TwoPass", "jdk_jceks_twopass.p12.data", |
|
PKCS12, SUN_JSSE, "storepass", "keypass", JCE_KS, SUN_JCE); |
|
|
|
jstest.driver("P12ToJks_Chain", "ie_jks_chain.pfx.data", PKCS12, |
|
SUN_JSSE, "pass", "pass", JKS, SUN); |
|
|
|
jstest.driver("P12ToJks_SelfSigned", "jdk_jks_selfsigned.p12.data", |
|
PKCS12, SUN_JSSE, "pass", "pass", JKS, SUN); |
|
|
|
jstest.driver("P12ToJks_TwoEntry", "jdk_jks_twoentry.p12.data", PKCS12, |
|
SUN_JSSE, "pass", "pass", JKS, SUN); |
|
|
|
jstest.driver("P12ToJks_TwoPass", "jdk_jks_twopass.p12.data", PKCS12, |
|
SUN_JSSE, "storepass", "keypass", JKS, SUN); |
|
|
|
} |
|
|
|
private void driver(String testCase, String inKeyStore, |
|
String inKeyStoreType, String inKeyStoreTypePrv, |
|
String inStorePass, String inKeyPass, String outKeyStoreType, |
|
String outKeyStorePrv) throws Exception { |
|
|
|
String outStorePass = "pass"; |
|
String outKeyPass = "pass"; |
|
KeyStore inputKeyStore, outputKeyStore; |
|
|
|
out.println("Testing " + testCase); |
|
String keystorePath = System.getProperty("test.src", ".") |
|
+ File.separator + "certs" + File.separator + "convertP12"; |
|
out.println("Output KeyStore : " + inKeyStore + ".out"); |
|
String outKeyStoreName = inKeyStore + ".out"; |
|
try (FileOutputStream fout = new FileOutputStream(outKeyStoreName);) { |
|
inputKeyStore = KeyStore.getInstance(inKeyStoreType, |
|
inKeyStoreTypePrv); |
|
|
|
// KeyStore have encoded by Base64.getMimeEncoder().encode(),need |
|
// decode first. |
|
byte[] input = Files.readAllBytes(Paths.get(keystorePath, |
|
inKeyStore)); |
|
ByteArrayInputStream arrayIn = new ByteArrayInputStream(Base64 |
|
.getMimeDecoder().decode(input)); |
|
|
|
out.println("Input KeyStore : " + inKeyStore); |
|
|
|
inputKeyStore.load(arrayIn, inStorePass.toCharArray()); |
|
|
|
outputKeyStore = KeyStore.getInstance(outKeyStoreType, |
|
outKeyStorePrv); |
|
outputKeyStore.load(null, null); |
|
|
|
run(inputKeyStore, outputKeyStore, inKeyPass, outKeyPass); |
|
|
|
outputKeyStore.store(fout, outStorePass.toCharArray()); |
|
|
|
// for P12ToJks_TwoEntry test case will test includes each other, |
|
// others just test compareKeystore |
|
if (testCase.contains("TwoEntry")) { |
|
|
|
compareKeyStore(inputKeyStore, outputKeyStore, inKeyPass, |
|
outKeyPass, 2); |
|
compareKeyStore(outputKeyStore, inputKeyStore, outKeyPass, |
|
inKeyPass, 2); |
|
} else { |
|
compareKeyStore(inputKeyStore, outputKeyStore, inKeyPass, |
|
outKeyPass, 1); |
|
} |
|
out.println("Test " + testCase + " STATUS: Pass!!"); |
|
} catch (Exception ex) { |
|
out.println("Test " + testCase + " STATUS: failed with exception: " |
|
+ ex.getMessage()); |
|
throw ex; |
|
} |
|
} |
|
|
|
private void run(KeyStore inputKeyStore, KeyStore outputKeyStore, |
|
String inKeyPass, String outKeyPass) throws Exception { |
|
Enumeration<String> e = inputKeyStore.aliases(); |
|
String alias; |
|
while (e.hasMoreElements()) { |
|
alias = e.nextElement(); |
|
Certificate[] certs = inputKeyStore.getCertificateChain(alias); |
|
|
|
boolean isCertEntry = inputKeyStore.isCertificateEntry(alias); |
|
// Test KeyStore only contain key pair entries. |
|
if (isCertEntry == true) { |
|
throw new RuntimeException( |
|
"inputKeystore should not be certEntry because test" |
|
+ " keystore only contain key pair entries" |
|
+ " for alias:" + alias); |
|
} |
|
|
|
boolean isKeyEntry = inputKeyStore.isKeyEntry(alias); |
|
Key key = null; |
|
if (isKeyEntry) { |
|
key = inputKeyStore.getKey(alias, inKeyPass.toCharArray()); |
|
} else { |
|
throw new RuntimeException("Entry type unknown for alias:" |
|
+ alias); |
|
} |
|
outputKeyStore.setKeyEntry(alias, key, outKeyPass.toCharArray(), |
|
certs); |
|
} |
|
} |
|
|
|
private void compareKeyStore(KeyStore a, KeyStore b, String inKeyPass, |
|
String outKeyPass, int keyStoreSize) throws Exception { |
|
if (a.size() != keyStoreSize || b.size() != keyStoreSize) { |
|
throw new RuntimeException("size not match or size not equal to " |
|
+ keyStoreSize); |
|
} |
|
|
|
Enumeration<String> eA = a.aliases(); |
|
while (eA.hasMoreElements()) { |
|
String aliasA = eA.nextElement(); |
|
|
|
if (!b.containsAlias(aliasA)) { |
|
throw new RuntimeException("alias not match for alias:" |
|
+ aliasA); |
|
} |
|
|
|
compareKeyEntry(a, b, inKeyPass, outKeyPass, aliasA); |
|
} |
|
} |
|
|
|
private void compareKeyEntry(KeyStore a, KeyStore b, String aPass, |
|
String bPass, String alias) throws KeyStoreException, |
|
UnrecoverableKeyException, NoSuchAlgorithmException { |
|
Certificate[] certsA = a.getCertificateChain(alias); |
|
Certificate[] certsB = b.getCertificateChain(alias); |
|
|
|
if (!Arrays.equals(certsA, certsB)) { |
|
throw new RuntimeException("Certs don't match for alias:" + alias); |
|
} |
|
|
|
Key keyA = a.getKey(alias, aPass.toCharArray()); |
|
Key keyB = b.getKey(alias, bPass.toCharArray()); |
|
|
|
if (!keyA.equals(keyB)) { |
|
throw new RuntimeException( |
|
"Key don't match for alias:" + alias); |
|
} |
|
} |
|
}
|
|
|