Path: blob/master/test/jdk/java/security/KeyStore/PKCS12/WriteP12Test.java
41153 views
/*1* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import static java.lang.System.out;2425import java.io.ByteArrayInputStream;26import java.io.File;27import java.io.FileNotFoundException;28import java.io.FileOutputStream;29import java.io.IOException;30import java.nio.file.Files;31import java.nio.file.Paths;32import java.security.Key;33import java.security.KeyStore;34import java.security.KeyStoreException;35import java.security.NoSuchAlgorithmException;36import java.security.NoSuchProviderException;37import java.security.UnrecoverableKeyException;38import java.security.cert.Certificate;39import java.security.cert.CertificateException;40import java.security.cert.CertificateFactory;41import java.security.cert.X509Certificate;42import java.util.Arrays;43import java.util.Base64;44import java.util.Enumeration;4546/*47* @test48* @bug 804861849* @summary Write different types p12 key store to Check the write related50* APIs.51* @run main WriteP12Test52*/5354public class WriteP12Test {5556private static final String IN_KEYSTORE_TYPE = "jks";57private static final String IN_KEYSTORE_PRV = "SUN";5859private static final String IN_KEYSTORE_ENDUSER = "keystoreEU.jks.data";60private static final String IN_KEYSTORE_CA = "keystoreCA.jks.data";61private static final String OUT_KEYSTORE = "outKeyStore.p12";6263private static final String IN_STORE_PASS = "storepass";64private static final String IN_KEY_PASS = "keypass";6566private static final String CERT_PATH = System.getProperty("test.src", ".")67+ File.separator + "certs" + File.separator + "writeP12"68+ File.separator;6970private static final String CA_CERT_STR = "-----BEGIN CERTIFICATE-----\n"71+ "MIIDFzCCAf8CBD8+0nAwDQYJKoZIhvcNAQEFBQAwUDELMAkGA1UEBhMCV\n"72+ "VMxETAPBgNVBAoTCEphdmFTb2Z0MRUwEwYDVQQLEwxTZWN1cml0eSBTUU\n"73+ "UxFzAVBgNVBAMTDlBLQ1MxMiBUZXN0IENBMB4XDTAzMDgxNzAwNTUxMlo\n"74+ "XDTEzMDgxNDAwNTUxMlowUDELMAkGA1UEBhMCVVMxETAPBgNVBAoTCEph\n"75+ "dmFTb2Z0MRUwEwYDVQQLEwxTZWN1cml0eSBTUUUxFzAVBgNVBAMTDlBLQ\n"76+ "1MxMiBUZXN0IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQ\n"77+ "EAk7Sh+K/yGsmJacZnjfkZfuWxGNJCPW0q69exwoRP+eBHMQwG00yi9aL\n"78+ "SsZAqNpJSCDvpgySOAUmBd+f8WFhHqJfRVREVfv3mradDKZCjhqtsUI7I\n"79+ "wRTYYy9clFkeeK4dHaxbuFMPpUu7yQfwSTXgvOA/UJ4kJuGtaYAdTJI4e\n"80+ "f1mUASo6+dea0UZA/FHCuV7O6z3hr5VHlyhJL2/o/8M5tGBTBISODJSnn\n"81+ "GNBvtQLNHnWYvs470UAE2BtuCGYh1V/3HAH1tRirS3MBBcb1XnIkiiXR3\n"82+ "tjaBSB+XhoCfuG8KtInXXFaAnvKfY9mYFw6VJt9JYQpY2VDC7281/Pbz0\n"83+ "dQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQBzXZ8zHWrnC8/E+N/n2Czhx\n"84+ "i18YQc2LPWBDLYTTxoFEazWmYLv1k/JT7Nta1qu1quvxXJ4uV1XHbd9NF\n"85+ "AJWKwtFQEpfv4o6I7qWUPoxnfA+jyqKXxv27z25tzt+Y4xOEhqvO03G0Q\n"86+ "imhkiNt9MF7L69y2U0/U73+uFNGzdAEDiI9EibvICiOnr1TeQ5GekK3Yb\n"87+ "k5qe3lviMZPkkSXepTJI8m0AiXCji+eXj97jVLeH+RxeBchBY+uELrqUr\n"88+ "sVOVWh7IBCqC/V7FqUTkmD1IFlzkkinatpl42s1MbhJId2yQkzaeBRc\n"89+ "suE63bDEtuRWp9ynMO3QA4Yu85uBRWGzQ1Di\n"90+ "-----END CERTIFICATE-----";91private static final String LEAD_CERT = "-----BEGIN CERTIFICATE-----\n"92+ "MIICwDCCAaigAwIBAgIEPz7S1jANBgkqhkiG9w0BAQQFADBQMQswCQYDV\n"93+ "QQGEwJVUzERMA8GA1UEChMISmF2YVNvZnQxFTATBgNVBAsTDFNlY3VyaX\n"94+ "R5IFNRRTEXMBUGA1UEAxMOUEtDUzEyIFRlc3QgQ0EwHhcNMDAwODA5MDc\n"95+ "wMDAwWhcNMTAwODA3MDcwMDAwWjBSMQswCQYDVQQGEwJVUzERMA8GA1UE\n"96+ "ChMISmF2YVNvZnQxFTATBgNVBAsTDFNlY3VyaXR5IFNRRTEZMBcGA1UEA\n"97+ "xMQUEtDUzEyIFRlc3QgTGVhZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgY\n"98+ "kCgYEAzq9X2USz/WjDhT+jUyZWqB5h4A33tS11YqH5qYvqjTXjcUI6gOp\n"99+ "moXMafDG9RHRlIccvp51xLp7Ap3WMrv411lWBttqtZi5c1/DEC1cEM/Sl\n"100+ "PCk1r2zFbkJu7QKieXeMcrjZEo6LcBHMwQjIpI+up9cr3VjuyqG/olQkU\n"101+ "mXVuS0CAwEAAaMkMCIwDwYDVR0PAQH/BAUDAweAADAPBgNVHRMBAf8EBT\n"102+ "ADAQH/MA0GCSqGSIb3DQEBBAUAA4IBAQBhbuim98TWmtv9vSldRE7RvQ8\n"103+ "FlS0TyZVO7kcSNtfCUE4R76J1ElN74Koc5pQnUtduLeQJs2ao/mEcCZsE\n"104+ "zVcwI3mSZrSzPhc8s7w5gOQA4TUwVLSSjKgBCaZ7R3+qJ3QeqPJ5O6sFz\n"105+ "pvBYkgSa4MWptK41jbmT8cwZQJXFCi8WxFFJ+p97F1Ppm3LgmYmtiUP4M\n"106+ "ZQwOBvpTZWXU0WrqFXpzWQx0mg4SX19fZm4nLcJAerCEUphf8ILagtpQM\n"107+ "EErT3/jg6mfCdT3Rj055QXPfF4OiRFevPF5a1fZgrCePCukRQZcd7s8K5\n"108+ "OBIaryuM0MdFtlzxi6XWeUNpVFFHURcy\n"109+ "-----END CERTIFICATE-----";110private static final String END_CERT = "-----BEGIN CERTIFICATE-----\n"111+ "MIICNjCCAZ+gAwIBAgIEPz7WtzANBgkqhkiG9w0BAQQFADBSMQswCQYDV\n"112+ "QQGEwJVUzERMA8GA1UEChMISmF2YVNvZnQxFTATBgNVBAsTDFNlY3VyaX\n"113+ "R5IFNRRTEZMBcGA1UEAxMQUEtDUzEyIFRlc3QgTGVhZDAeFw0wMDA4MDk\n"114+ "wNzAwMDBaFw0xMDA4MDcwNzAwMDBaMFgxCzAJBgNVBAYTAlVTMREwDwYD\n"115+ "VQQKEwhKYXZhU29mdDEVMBMGA1UECxMMU2VjdXJpdHkgU1FFMR8wHQYDV\n"116+ "QQDExZQS0NTMTIgVGVzdCBFbmQgVXNlciAxMIGfMA0GCSqGSIb3DQEBAQ\n"117+ "UAA4GNADCBiQKBgQDIKomSYomDzH/V63eDQEG7od0DLcnnVZ81pbWhDss\n"118+ "8gHV2m8pADdRqdihBmnSQEaMW4D3uZ4sFE1LtkQls6hjd7SdOsG5Y24L8\n"119+ "15jot9a2JcB73H8H0VKirrObL5BZdt7BtASPDnYtW4Spt++YjDoJFxyF0\n"120+ "HchkavzXaVTlexakwIDAQABoxMwETAPBgNVHQ8BAf8EBQMDB4AAMA0GCS\n"121+ "qGSIb3DQEBBAUAA4GBAIFA3JXEmb9AXn3RD7t+Mn6DoyVDIy5jsn6xOKT\n"122+ "JV25I0obpDUzgw4QaAMmM0ZvusOmZ2wZNS8MtyTUgdANyakbzn5SdxbTy\n"123+ "TLEqQsFbX8UVC38fx5ZM6ExA5YSAvgmXudZpOVC0ATccoZS3JFU8CxSfW\n"124+ "+Q3IC2MLh+QTg3hUJ5b\n-----END CERTIFICATE-----";125126private final Certificate testerCert;127private final Certificate testLeadCert;128private final Certificate caCert;129130WriteP12Test() throws CertificateException {131CertificateFactory cf = CertificateFactory.getInstance("X.509");132caCert = cf.generateCertificate(new ByteArrayInputStream(CA_CERT_STR133.getBytes()));134testLeadCert = cf.generateCertificate(new ByteArrayInputStream(135LEAD_CERT.getBytes()));136testerCert = cf.generateCertificate(new ByteArrayInputStream(END_CERT137.getBytes()));138}139140public static void main(String[] args) throws CertificateException,141UnrecoverableKeyException, KeyStoreException,142NoSuchProviderException, NoSuchAlgorithmException, IOException {143WriteP12Test jstest = new WriteP12Test();144out.println("test WriteP12CertChain");145/*146* WriteP12CertChain: This test creates a p12 keystore contains one147* entry with private key and a certificate chains contains three148* certificates in the order of user->lead->ca. This case expects to149* pass.150*/151jstest.test(new Certificate[] { jstest.testerCert, jstest.testLeadCert,152jstest.caCert }, IN_KEYSTORE_ENDUSER, "pkcs12testenduser1",153"pass", "pass");154155/*156* WriteP12CertChainBad: same as WriteP12CertChain but chains order is157* user-ca-lead, the order is wrong so expects to fail.158*/159out.println("test WriteP12CertChainBad");160try {161jstest.test(new Certificate[] { jstest.testerCert, jstest.caCert,162jstest.testLeadCert }, IN_KEYSTORE_ENDUSER,163"pkcs12testenduser1", "pass", "pass");164throw new RuntimeException(165" Certificate chain is not valid, test should not pass."166+ " Test failed.");167} catch (KeyStoreException e) {168e.printStackTrace();169out.println(" Certificate chain is not valid,exception is"170+ " expected. Test passed.");171}172/*173* WriteP12PrivateKey:This test creates a p12 contains a self-signed174* cert and private key,expects no exception175*/176out.println("test WriteP12PrivateKey");177jstest.test(null, IN_KEYSTORE_ENDUSER, "pkcs12testenduser1", "pass",178"pass");179180/*181* WriteP12TwoEntry: This test creates a p12 keystore with different182* storepass and keypass, and contains two entries.183*/184out.println("test WriteP12TwoEntry");185jstest.testTwoEntry(IN_KEYSTORE_ENDUSER, IN_KEYSTORE_CA,186"pkcs12testenduser1", "pass", "pass");187/*188* WriteP12TwoPass: This test creates a p12 keystore with different189* storepass and keypass, and contains one entry with private key and a190* certificate191*/192out.println("test WriteP12TwoPass");193jstest.test(null, IN_KEYSTORE_CA, "pkcs12testCA", "storepass",194"keypass");195}196197private void test(Certificate certs[], String inKeyStorePath,198String userAlias, String outStorePass, String outKeyPass)199throws KeyStoreException, NoSuchProviderException, IOException,200CertificateException, UnrecoverableKeyException,201NoSuchAlgorithmException {202// init output key store203KeyStore outputKeyStore = KeyStore.getInstance("pkcs12", "SunJSSE");204outputKeyStore.load(null, null);205try (FileOutputStream fout = new FileOutputStream(OUT_KEYSTORE)) {206// KeyStore have encoded by Base64.getMimeEncoder().encode(),need207// decode first.208byte[] input = Files.readAllBytes(Paths.get(CERT_PATH,209inKeyStorePath));210ByteArrayInputStream arrayIn = new ByteArrayInputStream(Base64211.getMimeDecoder().decode(input));212// input key store213KeyStore inputKeyStore = KeyStore.getInstance(IN_KEYSTORE_TYPE,214IN_KEYSTORE_PRV);215inputKeyStore.load(arrayIn, IN_STORE_PASS.toCharArray());216// add key/certificate to output key store217Key key = inputKeyStore218.getKey(userAlias, IN_KEY_PASS.toCharArray());219out.println("Input Key Algorithm " + key.getAlgorithm());220out.println("====Input Certs=====");221if (certs == null) {222certs = new Certificate[] { inputKeyStore223.getCertificate(userAlias) };224}225for (Certificate cert : certs) {226out.println(((X509Certificate) cert).getSubjectDN());227}228outputKeyStore.setKeyEntry(userAlias, key,229outKeyPass.toCharArray(), certs);230Certificate retCerts[] = outputKeyStore231.getCertificateChain(userAlias);232out.println("====Output Certs=====");233for (Certificate retCert : retCerts) {234out.println(((X509Certificate) retCert).getSubjectDN());235}236out.println("====Output Key Algorithm=====");237Key outKey = outputKeyStore.getKey(userAlias,238outKeyPass.toCharArray());239out.println(outKey.getAlgorithm());240241if (!key.equals(outKey)) {242throw new RuntimeException("key don't match");243}244if (!Arrays.equals(certs, retCerts)) {245throw new RuntimeException("certs don't match");246}247// save output248outputKeyStore.store(fout, outStorePass.toCharArray());249// test output250testKeyStore(outputKeyStore, outKeyPass.toCharArray());251}252}253254private void testTwoEntry(String inKeyStoreOnePath,255String inKeyStoreTwoPath, String userAlias, String outStorePass,256String outKeyPass) throws KeyStoreException,257NoSuchProviderException, NoSuchAlgorithmException,258CertificateException, IOException, UnrecoverableKeyException {259// initial KeyStore260KeyStore outputKeyStore = KeyStore.getInstance("pkcs12", "SunJSSE");261try (FileOutputStream fout = new FileOutputStream(OUT_KEYSTORE);) {262outputKeyStore.load(null, null);263KeyStore inputKeyStoreOne, inputKeyStoreTwo;264inputKeyStoreOne = KeyStore.getInstance(IN_KEYSTORE_TYPE,265IN_KEYSTORE_PRV);266// KeyStore have encoded by Base64.getMimeEncoder().encode(),need267// decode first.268byte[] inputBytes = Files.readAllBytes(Paths.get(CERT_PATH,269inKeyStoreOnePath));270ByteArrayInputStream arrayIn = new ByteArrayInputStream(Base64271.getMimeDecoder().decode(inputBytes));272// input key store273inputKeyStoreOne.load(arrayIn, IN_STORE_PASS.toCharArray());274275inputBytes = Files.readAllBytes(Paths.get(CERT_PATH,276inKeyStoreTwoPath));277arrayIn = new ByteArrayInputStream(Base64.getMimeDecoder().decode(278inputBytes));279inputKeyStoreTwo = KeyStore.getInstance(IN_KEYSTORE_TYPE,280IN_KEYSTORE_PRV);281inputKeyStoreTwo.load(arrayIn, IN_STORE_PASS.toCharArray());282283// add key/certificate to output key store284out.println("====First Entry=====");285Key inputKey = inputKeyStoreOne.getKey(userAlias,286IN_KEY_PASS.toCharArray());287Certificate cert = inputKeyStoreOne.getCertificate(userAlias);288Certificate certs[] = new Certificate[1];289certs[0] = cert;290291out.println("====Input1 Key=====");292out.println(inputKey.getAlgorithm());293out.println("====Input1 Certs=====");294out.println("Certificate :");295out.println(((X509Certificate) cert).getSubjectDN());296outputKeyStore.setKeyEntry("USER", inputKey,297outKeyPass.toCharArray(), certs);298out.println("====Second Entry=====");299String caAlias = "pkcs12testca";300inputKey = inputKeyStoreTwo.getKey(caAlias,301IN_KEY_PASS.toCharArray());302cert = inputKeyStoreTwo.getCertificate(caAlias);303certs[0] = cert;304out.println("====Input2 Key=====");305out.println(inputKey.getAlgorithm());306out.println("====Input2 Certs=====");307out.println("Certificate :");308out.println(((X509Certificate) cert).getSubjectDN());309outputKeyStore.setKeyEntry("CA", inputKey,310outKeyPass.toCharArray(), certs);311// save output312outputKeyStore.store(fout, outStorePass.toCharArray());313// test output314testKeyStore(outputKeyStore, outKeyPass.toCharArray());315}316}317318private void testKeyStore(KeyStore inputKeyStore, char[] keypass)319throws KeyStoreException, UnrecoverableKeyException,320NoSuchAlgorithmException {321out.println("========== Key Store ==========");322out.println("getProvider : " + inputKeyStore.getProvider());323out.println("getType : " + inputKeyStore.getType());324out.println("getDefaultType : " + KeyStore.getDefaultType());325326int idx = 0;327Enumeration<String> e = inputKeyStore.aliases();328String alias;329while (e.hasMoreElements()) {330alias = e.nextElement();331if (!inputKeyStore.containsAlias(alias)) {332throw new RuntimeException("Alias not found");333}334out.println("Alias " + idx + " : " + alias);335out.println("getCreationDate : "336+ inputKeyStore.getCreationDate(alias));337X509Certificate cert = (X509Certificate) inputKeyStore338.getCertificate(alias);339out.println("getCertificate : " + cert.getSubjectDN());340String retAlias = inputKeyStore.getCertificateAlias(cert);341if (!retAlias.equals(alias)) {342throw new RuntimeException("Alias mismatch, actually "343+ retAlias + ", expected " + alias);344}345out.println("getCertificateAlias : " + retAlias);346Certificate[] certs = inputKeyStore.getCertificateChain(alias);347int i = 0;348for (Certificate certification : certs) {349out.println("getCertificateChain " + i350+ ((X509Certificate) certification).getSubjectDN());351i++;352}353if (inputKeyStore.isCertificateEntry(alias)) {354throw new RuntimeException(355"inputKeystore should not be certEntry because this"356+ " keystore only contain key pair entries.");357}358if (!inputKeyStore.isKeyEntry(alias)) {359throw new RuntimeException("Entry type unknown.");360}361idx++;362}363int size = inputKeyStore.size();364if (idx != size) {365throw new RuntimeException("Size not match, actually " + idx366+ ", expected " + size);367}368}369370}371372373