Path: blob/master/test/jdk/sun/security/pkcs11/Secmod/AddPrivateKey.java
41153 views
/*1* Copyright (c) 2006, 2018, 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*/2223/*24* @test25* @bug 641498026* @summary Test that the PKCS#11 KeyStore handles RSA, DSA, and EC keys27* @author Andreas Sterbenz28* @library /test/lib ..29* @modules jdk.crypto.cryptoki30* @run main/othervm AddPrivateKey31* @run main/othervm -Djava.security.manager=allow AddPrivateKey sm policy32*/3334import java.io.File;35import java.io.FileInputStream;36import java.io.InputStream;37import java.security.KeyFactory;38import java.security.KeyStore;39import java.security.KeyStore.PasswordProtection;40import java.security.KeyStore.PrivateKeyEntry;41import java.security.KeyStoreException;42import java.security.PrivateKey;43import java.security.Provider;44import java.security.PublicKey;45import java.security.Security;46import java.security.Signature;47import java.security.cert.X509Certificate;48import java.util.Arrays;49import java.util.Collections;50import java.util.List;5152// this test is currently only run for the NSS KeyStore provider, but it53// is really a generic KeyStore test so it should be modified to run for54// all providers.55public class AddPrivateKey extends SecmodTest {5657private static final String ALIAS1 = "entry1";58private static final String ALIAS2 = "entry2";59private static final String ALIAS3 = "entry3";60private static final int MAX_LINE = 85;61private static final int DATA_LENGTH = 4096;62private static final byte[] DATA = generateData(DATA_LENGTH);6364public static void main(String[] args) throws Exception {65if (args.length > 1 && "sm".equals(args[0])) {66System.setProperty("java.security.policy",67BASE + File.separator + args[1]);68}6970if (initSecmod() == false) {71return;72}7374String configName = BASE + SEP + "nss.cfg";75Provider p = getSunPKCS11(configName);7677boolean supportsEC = (p.getService("KeyFactory", "EC") != null);7879System.out.println(p);80System.out.println();81Security.addProvider(p);8283if (args.length > 1 && "sm".equals(args[0])) {84System.setSecurityManager(new SecurityManager());85}8687KeyStore ks = KeyStore.getInstance(PKCS11, p);88ks.load(null, password);89for (String alias : aliases(ks)) {90System.out.println("Deleting: " + alias);91ks.deleteEntry(alias);92}9394KeyStore jks = KeyStore.getInstance("JKS");95try (InputStream in = new FileInputStream(BASE + SEP + "keystore.jks")) {96char[] jkspass = "passphrase".toCharArray();97jks.load(in, jkspass);98for (String alias : Collections.list(jks.aliases())) {99if (jks.entryInstanceOf(alias, PrivateKeyEntry.class)) {100PrivateKeyEntry entry = (PrivateKeyEntry)jks.getEntry(alias,101new PasswordProtection(jkspass));102String algorithm = entry.getPrivateKey().getAlgorithm();103System.out.printf("-Entry %s (%s)%n", alias, algorithm);104if ((supportsEC == false) && algorithm.equals("EC")) {105System.out.println("EC not supported by provider, "106+ "skipping");107continue;108}109if ((supportsEC == false) && algorithm.equals("DSA")) {110System.out.println("Provider does not appear to have "111+ "CKA_NETSCAPE_DB fix, skipping");112continue;113}114test(p, entry);115} // else ignore116}117}118System.out.println("OK");119}120121private static List<String> aliases(KeyStore ks) throws KeyStoreException {122return Collections.list(ks.aliases());123}124125private static void test(Provider p, PrivateKeyEntry entry) throws Exception {126PrivateKey key = entry.getPrivateKey();127X509Certificate[] chain = (X509Certificate[])entry.getCertificateChain();128PublicKey publicKey = chain[0].getPublicKey();129System.out.println(toString(key));130sign(p, key, publicKey);131132KeyStore ks = KeyStore.getInstance("PKCS11", p);133ks.load(null, null);134if (ks.size() != 0) {135throw new Exception("KeyStore not empty");136}137List<String> aliases;138139// test 1: add entry140ks.setKeyEntry(ALIAS1, key, null, chain);141aliases = aliases(ks);142if (aliases.size() != 1) {143throw new Exception("size not 1: " + aliases);144}145if (aliases.get(0).equals(ALIAS1) == false) {146throw new Exception("alias mismatch: " + aliases);147}148149PrivateKey key2 = (PrivateKey)ks.getKey(ALIAS1, null);150System.out.println(toString(key2));151X509Certificate[] chain2 =152(X509Certificate[]) ks.getCertificateChain(ALIAS1);153if (Arrays.equals(chain, chain2) == false) {154throw new Exception("chain mismatch");155}156sign(p, key2, publicKey);157158ks.deleteEntry(ALIAS1);159if (ks.size() != 0) {160throw new Exception("KeyStore not empty");161}162163// test 2: translate to session object, then add entry164KeyFactory kf = KeyFactory.getInstance(key.getAlgorithm(), p);165PrivateKey key3 = (PrivateKey)kf.translateKey(key);166System.out.println(toString(key3));167sign(p, key3, publicKey);168169ks.setKeyEntry(ALIAS2, key3, null, chain);170aliases = aliases(ks);171if (aliases.size() != 1) {172throw new Exception("size not 1");173}174if (aliases.get(0).equals(ALIAS2) == false) {175throw new Exception("alias mismatch: " + aliases);176}177178PrivateKey key4 = (PrivateKey)ks.getKey(ALIAS2, null);179System.out.println(toString(key4));180X509Certificate[] chain4 = (X509Certificate[])181ks.getCertificateChain(ALIAS2);182if (Arrays.equals(chain, chain4) == false) {183throw new Exception("chain mismatch");184}185sign(p, key4, publicKey);186187// test 3: change alias188ks.setKeyEntry(ALIAS3, key3, null, chain);189aliases = aliases(ks);190if (aliases.size() != 1) {191throw new Exception("size not 1");192}193if (aliases.get(0).equals(ALIAS3) == false) {194throw new Exception("alias mismatch: " + aliases);195}196197PrivateKey key5 = (PrivateKey)ks.getKey(ALIAS3, null);198System.out.println(toString(key5));199X509Certificate[] chain5 = (X509Certificate[])200ks.getCertificateChain(ALIAS3);201if (Arrays.equals(chain, chain5) == false) {202throw new Exception("chain mismatch");203}204sign(p, key5, publicKey);205206ks.deleteEntry(ALIAS3);207if (ks.size() != 0) {208throw new Exception("KeyStore not empty");209}210211System.out.println("OK");212}213214private static void sign(Provider p, PrivateKey privateKey,215PublicKey publicKey) throws Exception {216String keyAlg = privateKey.getAlgorithm();217String alg;218switch (keyAlg) {219case "RSA":220alg = "SHA1withRSA";221break;222case "DSA":223alg = "SHA1withDSA";224break;225case "EC":226alg = "SHA1withECDSA";227break;228default:229throw new Exception("Unknown algorithm " + keyAlg);230}231Signature s = Signature.getInstance(alg, p);232s.initSign(privateKey);233s.update(DATA);234byte[] sig = s.sign();235236s.initVerify(publicKey);237s.update(DATA);238if (s.verify(sig) == false) {239throw new Exception("Signature did not verify");240}241}242243private static String toString(Object o) {244String s = String.valueOf(o).split("\n")[0];245return (s.length() <= MAX_LINE) ? s : s.substring(0, MAX_LINE);246}247248}249250251