Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/security/KeyStore/TestKeyStoreBasic.java
38811 views
/*1* Copyright (c) 2001, 2016, 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 java.io.BufferedInputStream;24import java.io.ByteArrayInputStream;25import java.io.ByteArrayOutputStream;26import java.io.IOException;27import java.io.InputStream;28import java.security.KeyFactory;29import java.security.KeyStore;30import java.security.KeyStoreException;31import java.security.NoSuchProviderException;32import java.security.PrivateKey;33import java.security.UnrecoverableKeyException;34import java.security.cert.Certificate;35import java.security.cert.CertificateFactory;36import java.security.spec.KeySpec;37import java.security.spec.PKCS8EncodedKeySpec;38import java.util.Base64;3940/*41* @test42* @bug 8048621 813309043* @summary Test basic operations with keystores (jks, jceks, pkcs12)44* @author Yu-Ching Valerie PENG45*/46public class TestKeyStoreBasic {4748private static final String PRIVATE_KEY_PKCS8_BASE64 = ""49+ "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCpyz97liuWPDYcLH9TX8BiT78o"50+ "lCmAfmevvch6ncXUVuCzbdaKuKXwn4EVbDszsVJLoK5zdtP+X3iDhutj+IgKmLhuczF3M9VIcWr+"51+ "JJUyTH4+3h/RT8cjCDZOmk9iXkb5ifruVsLqzb9g+Vp140Oz7leikne7KmclHvTfvFd0WDI7Gb9v"52+ "o4f5rT717BXJ/n+M6pNk8DLpLiEu6eziYvXRv5x+t5Go3x0eCXdaxEQUf2j876Wfr2qHRJK7lDfF"53+ "e1DDsMg/KpKGiILYZ+g2qtVMZSxtp5BZEtfB5qV/IE5kWO+mCIAGpXSZIdbERR6pZUq8GLEe1T9e"54+ "+sO6H24w2F19AgMBAAECggEBAId/12187dO6wUPCjumuJA1QrrBnbKdKONyai36uoc1Od4s5QFj7"55+ "+hEIeS7rbGNYQuBvnkgusAbzkW0FIpxpHce3EJez/emux6pEOKoP77BwMt9gy+txyu0+BHi91FQg"56+ "AGvrnQDO5EYVY4Cz/WjOsJzKu8zVLg+DS0Toa2qRFwmUe9mVAXPNOCZ3Oae/Q6tCDsaINNw0fmjj"57+ "jn6uohPbS+n6xENG3FkQXB36getXy310xTGED2J27cmAQH6gLR6Kl2iROzNPbbpBqbuemI9kbcld"58+ "EwBS1jRfZWeaPstYA1niVrE9UgUBzemnoh4TDkG076sYthHMr5QFGjPswnwtJ4ECgYEA0sURQ5+v"59+ "baH4tdaemI3qpnknXTlzSpuZZmAoyvY0Id0mlduwKwmZ3Y5989wHfnnhFfyNO4IkTKjI2Wp97qP5"60+ "4eqUNpA7FtNU7KUzMcFDTtwtNZuRYMrKlqo2lLbA+gVrAYpYZFL4b7tcwtX4DnYorDsmude6W8sG"61+ "4Mx2VdFJC9UCgYEAzjsdXCYH5doWUHb0dvn9ID7IikffEMRM720MRjrnnnVbpzx6ACntkPDNZg7p"62+ "TRE/mx7iBz81ZaUWE+V0wd0JvCHEdpAz3mksyvDFhU4Bgs6xzf2pSul5muhsx3hHcvvPezz5Bnxs"63+ "faJlzkxfwotyGmvWN15GA/pyfsZjsbbTpwkCgYAO6NnbysQCIV8SnegCKqfatt9N/O5m7LLhRxQb"64+ "p2bwrlA4cZ34rWkw/w9x3LK7A6wkfgUPnJkswxPSLXJTG05l6M4rPfCwIKr1Qopojp9QSMr569NQ"65+ "4YeLOOc7heIIzbFQHpU6I5Rncv2Q2sn9W+ZsqJKIuvX34FjQNiZ406EzMQKBgHSxOGS61D84DuZK"66+ "2Ps1awhC3kB4eHzJRms3vflDPWoJJ+pSKwpKrzUTPHXiPBqyhtYkPGszVeiE6CAr9sv3YZnFVaBs"67+ "6hyQUJsob+uE/w/gGvXe8VsFDx0bJOodYfhrCbTHBHWqE81nBcocpxayxsayfAzqWB3KKd0YLrMR"68+ "K2PZAoGAcZa8915R2m0KZ6HVJUt/JDR85jCbN71kcVDFY2XSFkOJvOdFoHNfRckfLzjq9Y2MSSTV"69+ "+QDWbDo2doUQCejJUTaN8nP79tfyir24X5uVPvQaeVoGTKYb+LfUqK0F60lStmjuddIGSZH55y3v"70+ "+9XjmxbVERtd1lqgQg3VlmKlEXY=";7172/*73* Certificate:74* Data:75* Version: 3 (0x2)76* Serial Number: 7 (0x7)77* Signature Algorithm: sha512WithRSAEncryption78* Issuer: CN=Root79* Validity80* Not Before: Sep 1 18:03:59 2015 GMT81* Not After : Jan 17 18:03:59 2043 GMT82* Subject: CN=EE83*/84private static final String CERTIFICATE = ""85+ "-----BEGIN CERTIFICATE-----\n"86+ "MIIDHTCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQ0FADAPMQ0wCwYDVQQDDARSb290\n"87+ "MB4XDTE1MDkwMTE4MDM1OVoXDTQzMDExNzE4MDM1OVowDTELMAkGA1UEAwwCRUUw\n"88+ "ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpyz97liuWPDYcLH9TX8Bi\n"89+ "T78olCmAfmevvch6ncXUVuCzbdaKuKXwn4EVbDszsVJLoK5zdtP+X3iDhutj+IgK\n"90+ "mLhuczF3M9VIcWr+JJUyTH4+3h/RT8cjCDZOmk9iXkb5ifruVsLqzb9g+Vp140Oz\n"91+ "7leikne7KmclHvTfvFd0WDI7Gb9vo4f5rT717BXJ/n+M6pNk8DLpLiEu6eziYvXR\n"92+ "v5x+t5Go3x0eCXdaxEQUf2j876Wfr2qHRJK7lDfFe1DDsMg/KpKGiILYZ+g2qtVM\n"93+ "ZSxtp5BZEtfB5qV/IE5kWO+mCIAGpXSZIdbERR6pZUq8GLEe1T9e+sO6H24w2F19\n"94+ "AgMBAAGjgYUwgYIwNAYDVR0fBC0wKzApoCegJYYjbGRhcDovL2xkYXAuaG9zdC5m\n"95+ "b3IuY3JsZHAvbWFpbi5jcmwwSgYIKwYBBQUHAQEEPjA8MDoGCCsGAQUFBzAChi5s\n"96+ "ZGFwOi8vbGRhcC5ob3N0LmZvci5haWEvZGM9Um9vdD9jQUNlcnRpZmljYXRlMA0G\n"97+ "CSqGSIb3DQEBDQUAA4IBAQBWDfZHpuUx0yn5d3+BuztFqoks1MkGdk+USlH0TB1/\n"98+ "gWWBd+4S4PCKlpSur0gj2rMW4fP5HQfNlHci8JV8/bG4KuKRAXW56dg1818Hl3pc\n"99+ "iIrUSRn8uUjH3p9qb+Rb/u3mmVQRyJjN2t/zceNsO8/+Dd808OB9aEwGs8lMT0nn\n"100+ "ZYaaAqYz1GIY/Ecyx1vfEZEQ1ljo6i/r70C3igbypBUShxSiGsleiVTLOGNA+MN1\n"101+ "/a/Qh0bkaQyTGqK3bwvzzMeQVqWu2EWTBD/PmND5ExkpRICdv8LBVXfLnpoBr4lL\n"102+ "hnxn9+e0Ah+t8dS5EKfn44w5bI5PCu2bqxs6RCTxNjcY\n"103+ "-----END CERTIFICATE-----\n";104105private static final char[] PASSWD2 = new char[] {106'b', 'o', 'r', 'e', 'd'107};108private static final char[] PASSWDK = "cannot be null"109.toCharArray();110private static final String[] KS_Type = {111"jks", "jceks", "pkcs12", "PKCS11KeyStore"112};113private static final String[] PROVIDERS = {114"SUN", "SunJCE", "SunJSSE", "SunPKCS11-Solaris"115};116private static final String ALIAS_HEAD = "test";117118public static void main(String args[]) throws Exception {119TestKeyStoreBasic jstest = new TestKeyStoreBasic();120jstest.run();121}122123public void run() throws Exception {124for (String provider : PROVIDERS) {125try {126runTest(provider);127System.out.println("Test with provider " + provider + "passed");128} catch (java.security.KeyStoreException e) {129if (provider.equals("SunPKCS11-Solaris")) {130System.out.println("KeyStoreException is expected: "131+ "PKCS11KeyStore is invalid keystore type: " + e);132} else {133throw e;134}135} catch (NoSuchProviderException e) {136String osName = System.getProperty("os.name");137if (provider.equals("SunPKCS11-Solaris")138&& !osName.equals("SunOS")) {139System.out.println("Skip SunPKCS11-Solaris provider on "140+ osName);141} else {142throw e;143}144}145}146}147148public void runTest(String provider) throws Exception {149150// load private key151// all keystore types should support private keys152KeySpec spec = new PKCS8EncodedKeySpec(153Base64.getMimeDecoder().decode(PRIVATE_KEY_PKCS8_BASE64));154PrivateKey privateKey = KeyFactory.getInstance("RSA")155.generatePrivate(spec);156157// load x509 certificate158Certificate cert;159try (InputStream is = new BufferedInputStream(160new ByteArrayInputStream(CERTIFICATE.getBytes()))) {161cert = CertificateFactory.getInstance("X.509")162.generateCertificate(is);163}164165int numEntries = 5;166String type = null;167for (int i = 0; i < PROVIDERS.length; i++) {168if (provider.compareTo(PROVIDERS[i]) == 0) {169type = KS_Type[i];170break;171}172}173174System.out.printf("Test %s provider and %s keystore%n", provider, type);175KeyStore ks = KeyStore.getInstance(type, provider);176KeyStore ks2 = KeyStore.getInstance(type, ks.getProvider().getName());177178// create an empty key store179ks.load(null, null);180181// store the secret keys182for (int j = 0; j < numEntries; j++) {183ks.setKeyEntry(ALIAS_HEAD + j, privateKey, PASSWDK,184new Certificate[] { cert });185}186187// initialize the 2nd key store object with the 1st one188ByteArrayOutputStream baos = new ByteArrayOutputStream();189ks.store(baos, PASSWDK);190byte[] bArr = baos.toByteArray();191ByteArrayInputStream bais = new ByteArrayInputStream(bArr);192ks2.load(bais, null);193194// check 2nd key store type195checkType(ks2, type);196// check the existing aliases for the 2nd key store197checkAlias(ks2, numEntries);198199// compare the creation date of the 2 key stores for all aliases200compareCreationDate(ks, ks2, numEntries);201// remove the last entry from the 2nd key store202numEntries--;203ks2.deleteEntry(ALIAS_HEAD + numEntries);204205// re-initialize the 1st key store with the 2nd key store206baos.reset();207ks2.store(baos, PASSWD2);208bais = new ByteArrayInputStream(baos.toByteArray());209try {210// expect an exception since the password is incorrect211ks.load(bais, PASSWDK);212throw new RuntimeException(213"ERROR: passed the loading with incorrect password");214} catch (IOException ex) {215System.out.println("Expected exception: " + ex);216if (!causedBy(ex, UnrecoverableKeyException.class)) {217ex.printStackTrace(System.out);218throw new RuntimeException("Unexpected cause");219}220System.out.println("Expected cause: "221+ UnrecoverableKeyException.class.getName());222223bais.reset();224ks.load(bais, PASSWD2);225bais.reset();226ks.load(bais, null);227}228229// check key store type230checkType(ks, type);231232// check the existing aliases233checkAlias(ks, numEntries);234235// compare the creation date of the 2 key stores for all aliases236compareCreationDate(ks, ks2, numEntries);237238}239240// check key store type241private void checkType(KeyStore obj, String type) {242if (!obj.getType().equals(type)) {243throw new RuntimeException("ERROR: wrong key store type");244}245}246247// check the existing aliases248private void checkAlias(KeyStore obj, int range) throws KeyStoreException {249for (int k = 0; k < range; k++) {250if (!obj.containsAlias(ALIAS_HEAD + k)) {251throw new RuntimeException("ERROR: alias (" + k252+ ") should exist");253}254}255}256257// compare the creation dates - true if all the same258private void compareCreationDate(KeyStore o1, KeyStore o2, int range)259throws KeyStoreException {260String alias;261for (int k = 0; k < range; k++) {262alias = ALIAS_HEAD + k;263if (!o1.getCreationDate(alias).equals(o2.getCreationDate(alias))) {264throw new RuntimeException("ERROR: entry creation time (" + k265+ ") differs");266}267}268}269270// checks if an exception was caused by specified exception class271private static boolean causedBy(Exception e, Class klass) {272Throwable cause = e;273while ((cause = cause.getCause()) != null) {274if (cause.getClass().equals(klass)) {275return true;276}277}278return false;279}280281}282283284