diff -r 8d242299a219 -r 5e15de85a1a0 jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/SunPKCS11.java --- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/SunPKCS11.java Mon Jan 23 14:04:44 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1506 +0,0 @@ -/* - * Copyright (c) 2003, 2016, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -package sun.security.pkcs11; - -import java.io.*; -import java.util.*; - -import java.security.*; -import java.security.interfaces.*; - -import javax.crypto.interfaces.*; - -import javax.security.auth.Subject; -import javax.security.auth.login.LoginException; -import javax.security.auth.login.FailedLoginException; -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.ConfirmationCallback; -import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.callback.TextOutputCallback; - -import sun.security.util.Debug; -import sun.security.util.ResourcesMgr; -import static sun.security.util.SecurityConstants.PROVIDER_VER; - -import sun.security.pkcs11.Secmod.*; - -import sun.security.pkcs11.wrapper.*; -import static sun.security.pkcs11.wrapper.PKCS11Constants.*; - -/** - * PKCS#11 provider main class. - * - * @author Andreas Sterbenz - * @since 1.5 - */ -public final class SunPKCS11 extends AuthProvider { - - private static final long serialVersionUID = -1354835039035306505L; - - static final Debug debug = Debug.getInstance("sunpkcs11"); - - // the PKCS11 object through which we make the native calls - final PKCS11 p11; - - // configuration information - final Config config; - - // id of the PKCS#11 slot we are using - final long slotID; - - private CallbackHandler pHandler; - private final Object LOCK_HANDLER = new Object(); - - final boolean removable; - - final Module nssModule; - - final boolean nssUseSecmodTrust; - - private volatile Token token; - - private TokenPoller poller; - - Token getToken() { - return token; - } - - public SunPKCS11() { - super("SunPKCS11", PROVIDER_VER, - "Unconfigured and unusable PKCS11 provider"); - p11 = null; - config = null; - slotID = 0; - pHandler = null; - removable = false; - nssModule = null; - nssUseSecmodTrust = false; - token = null; - poller = null; - } - - @Override - public Provider configure(String configArg) throws InvalidParameterException { - final String newConfigName = checkNull(configArg); - try { - return AccessController.doPrivileged(new PrivilegedExceptionAction<>() { - @Override - public SunPKCS11 run() throws Exception { - return new SunPKCS11(new Config(newConfigName)); - } - }); - } catch (PrivilegedActionException pae) { - InvalidParameterException ipe = - new InvalidParameterException("Error configuring SunPKCS11 provider"); - throw (InvalidParameterException) ipe.initCause(pae.getException()); - } - } - - @Override - public boolean isConfigured() { - return (config != null); - } - - private static T checkNull(T obj) { - if (obj == null) { - throw new NullPointerException(); - } - return obj; - } - - // Used by Secmod - SunPKCS11(Config c) { - super("SunPKCS11-" + c.getName(), PROVIDER_VER, c.getDescription()); - this.config = c; - - if (debug != null) { - System.out.println("SunPKCS11 loading " + config.getFileName()); - } - - String library = config.getLibrary(); - String functionList = config.getFunctionList(); - long slotID = config.getSlotID(); - int slotListIndex = config.getSlotListIndex(); - - boolean useSecmod = config.getNssUseSecmod(); - boolean nssUseSecmodTrust = config.getNssUseSecmodTrust(); - Module nssModule = null; - - // - // Initialization via Secmod. The way this works is as follows: - // SunPKCS11 is either in normal mode or in NSS Secmod mode. - // Secmod is activated by specifying one or more of the following - // options in the config file: - // nssUseSecmod, nssSecmodDirectory, nssLibrary, nssModule - // - // XXX add more explanation here - // - // If we are in Secmod mode and configured to use either the - // nssKeyStore or the nssTrustAnchors module, we automatically - // switch to using the NSS trust attributes for trusted certs - // (KeyStore). - // - - if (useSecmod) { - // note: Config ensures library/slot/slotListIndex not specified - // in secmod mode. - Secmod secmod = Secmod.getInstance(); - DbMode nssDbMode = config.getNssDbMode(); - try { - String nssLibraryDirectory = config.getNssLibraryDirectory(); - String nssSecmodDirectory = config.getNssSecmodDirectory(); - boolean nssOptimizeSpace = config.getNssOptimizeSpace(); - - if (secmod.isInitialized()) { - if (nssSecmodDirectory != null) { - String s = secmod.getConfigDir(); - if ((s != null) && - (s.equals(nssSecmodDirectory) == false)) { - throw new ProviderException("Secmod directory " - + nssSecmodDirectory - + " invalid, NSS already initialized with " - + s); - } - } - if (nssLibraryDirectory != null) { - String s = secmod.getLibDir(); - if ((s != null) && - (s.equals(nssLibraryDirectory) == false)) { - throw new ProviderException("NSS library directory " - + nssLibraryDirectory - + " invalid, NSS already initialized with " - + s); - } - } - } else { - if (nssDbMode != DbMode.NO_DB) { - if (nssSecmodDirectory == null) { - throw new ProviderException( - "Secmod not initialized and " - + "nssSecmodDirectory not specified"); - } - } else { - if (nssSecmodDirectory != null) { - throw new ProviderException( - "nssSecmodDirectory must not be " - + "specified in noDb mode"); - } - } - secmod.initialize(nssDbMode, nssSecmodDirectory, - nssLibraryDirectory, nssOptimizeSpace); - } - } catch (IOException e) { - // XXX which exception to throw - throw new ProviderException("Could not initialize NSS", e); - } - List modules = secmod.getModules(); - if (config.getShowInfo()) { - System.out.println("NSS modules: " + modules); - } - - String moduleName = config.getNssModule(); - if (moduleName == null) { - nssModule = secmod.getModule(ModuleType.FIPS); - if (nssModule != null) { - moduleName = "fips"; - } else { - moduleName = (nssDbMode == DbMode.NO_DB) ? - "crypto" : "keystore"; - } - } - if (moduleName.equals("fips")) { - nssModule = secmod.getModule(ModuleType.FIPS); - nssUseSecmodTrust = true; - functionList = "FC_GetFunctionList"; - } else if (moduleName.equals("keystore")) { - nssModule = secmod.getModule(ModuleType.KEYSTORE); - nssUseSecmodTrust = true; - } else if (moduleName.equals("crypto")) { - nssModule = secmod.getModule(ModuleType.CRYPTO); - } else if (moduleName.equals("trustanchors")) { - // XXX should the option be called trustanchor or trustanchors?? - nssModule = secmod.getModule(ModuleType.TRUSTANCHOR); - nssUseSecmodTrust = true; - } else if (moduleName.startsWith("external-")) { - int moduleIndex; - try { - moduleIndex = Integer.parseInt - (moduleName.substring("external-".length())); - } catch (NumberFormatException e) { - moduleIndex = -1; - } - if (moduleIndex < 1) { - throw new ProviderException - ("Invalid external module: " + moduleName); - } - int k = 0; - for (Module module : modules) { - if (module.getType() == ModuleType.EXTERNAL) { - if (++k == moduleIndex) { - nssModule = module; - break; - } - } - } - if (nssModule == null) { - throw new ProviderException("Invalid module " + moduleName - + ": only " + k + " external NSS modules available"); - } - } else { - throw new ProviderException( - "Unknown NSS module: " + moduleName); - } - if (nssModule == null) { - throw new ProviderException( - "NSS module not available: " + moduleName); - } - if (nssModule.hasInitializedProvider()) { - throw new ProviderException("Secmod module already configured"); - } - library = nssModule.libraryName; - slotListIndex = nssModule.slot; - } - this.nssUseSecmodTrust = nssUseSecmodTrust; - this.nssModule = nssModule; - - File libraryFile = new File(library); - // if the filename is a simple filename without path - // (e.g. "libpkcs11.so"), it may refer to a library somewhere on the - // OS library search path. Omit the test for file existance as that - // only looks in the current directory. - if (libraryFile.getName().equals(library) == false) { - if (new File(library).isFile() == false) { - String msg = "Library " + library + " does not exist"; - if (config.getHandleStartupErrors() == Config.ERR_HALT) { - throw new ProviderException(msg); - } else { - throw new UnsupportedOperationException(msg); - } - } - } - - try { - if (debug != null) { - debug.println("Initializing PKCS#11 library " + library); - } - CK_C_INITIALIZE_ARGS initArgs = new CK_C_INITIALIZE_ARGS(); - String nssArgs = config.getNssArgs(); - if (nssArgs != null) { - initArgs.pReserved = nssArgs; - } - // request multithreaded access first - initArgs.flags = CKF_OS_LOCKING_OK; - PKCS11 tmpPKCS11; - try { - tmpPKCS11 = PKCS11.getInstance( - library, functionList, initArgs, - config.getOmitInitialize()); - } catch (PKCS11Exception e) { - if (debug != null) { - debug.println("Multi-threaded initialization failed: " + e); - } - if (config.getAllowSingleThreadedModules() == false) { - throw e; - } - // fall back to single threaded access - if (nssArgs == null) { - // if possible, use null initArgs for better compatibility - initArgs = null; - } else { - initArgs.flags = 0; - } - tmpPKCS11 = PKCS11.getInstance(library, - functionList, initArgs, config.getOmitInitialize()); - } - p11 = tmpPKCS11; - - CK_INFO p11Info = p11.C_GetInfo(); - if (p11Info.cryptokiVersion.major < 2) { - throw new ProviderException("Only PKCS#11 v2.0 and later " - + "supported, library version is v" + p11Info.cryptokiVersion); - } - boolean showInfo = config.getShowInfo(); - if (showInfo) { - System.out.println("Information for provider " + getName()); - System.out.println("Library info:"); - System.out.println(p11Info); - } - - if ((slotID < 0) || showInfo) { - long[] slots = p11.C_GetSlotList(false); - if (showInfo) { - System.out.println("All slots: " + toString(slots)); - slots = p11.C_GetSlotList(true); - System.out.println("Slots with tokens: " + toString(slots)); - } - if (slotID < 0) { - if ((slotListIndex < 0) - || (slotListIndex >= slots.length)) { - throw new ProviderException("slotListIndex is " - + slotListIndex - + " but token only has " + slots.length + " slots"); - } - slotID = slots[slotListIndex]; - } - } - this.slotID = slotID; - CK_SLOT_INFO slotInfo = p11.C_GetSlotInfo(slotID); - removable = (slotInfo.flags & CKF_REMOVABLE_DEVICE) != 0; - initToken(slotInfo); - if (nssModule != null) { - nssModule.setProvider(this); - } - } catch (Exception e) { - if (config.getHandleStartupErrors() == Config.ERR_IGNORE_ALL) { - throw new UnsupportedOperationException - ("Initialization failed", e); - } else { - throw new ProviderException - ("Initialization failed", e); - } - } - } - - private static String toString(long[] longs) { - if (longs.length == 0) { - return "(none)"; - } - StringBuilder sb = new StringBuilder(); - sb.append(longs[0]); - for (int i = 1; i < longs.length; i++) { - sb.append(", "); - sb.append(longs[i]); - } - return sb.toString(); - } - - public boolean equals(Object obj) { - return this == obj; - } - - public int hashCode() { - return System.identityHashCode(this); - } - - private static String[] s(String ...aliases) { - return aliases; - } - - private static final class Descriptor { - final String type; - final String algorithm; - final String className; - final String[] aliases; - final int[] mechanisms; - - private Descriptor(String type, String algorithm, String className, - String[] aliases, int[] mechanisms) { - this.type = type; - this.algorithm = algorithm; - this.className = className; - this.aliases = aliases; - this.mechanisms = mechanisms; - } - private P11Service service(Token token, int mechanism) { - return new P11Service - (token, type, algorithm, className, aliases, mechanism); - } - public String toString() { - return type + "." + algorithm; - } - } - - // Map from mechanism to List of Descriptors that should be - // registered if the mechanism is supported - private final static Map> descriptors = - new HashMap>(); - - private static int[] m(long m1) { - return new int[] {(int)m1}; - } - - private static int[] m(long m1, long m2) { - return new int[] {(int)m1, (int)m2}; - } - - private static int[] m(long m1, long m2, long m3) { - return new int[] {(int)m1, (int)m2, (int)m3}; - } - - private static int[] m(long m1, long m2, long m3, long m4) { - return new int[] {(int)m1, (int)m2, (int)m3, (int)m4}; - } - - private static void d(String type, String algorithm, String className, - int[] m) { - register(new Descriptor(type, algorithm, className, null, m)); - } - - private static void d(String type, String algorithm, String className, - String[] aliases, int[] m) { - register(new Descriptor(type, algorithm, className, aliases, m)); - } - - private static void register(Descriptor d) { - for (int i = 0; i < d.mechanisms.length; i++) { - int m = d.mechanisms[i]; - Integer key = Integer.valueOf(m); - List list = descriptors.get(key); - if (list == null) { - list = new ArrayList(); - descriptors.put(key, list); - } - list.add(d); - } - } - - private final static String MD = "MessageDigest"; - - private final static String SIG = "Signature"; - - private final static String KPG = "KeyPairGenerator"; - - private final static String KG = "KeyGenerator"; - - private final static String AGP = "AlgorithmParameters"; - - private final static String KF = "KeyFactory"; - - private final static String SKF = "SecretKeyFactory"; - - private final static String CIP = "Cipher"; - - private final static String MAC = "Mac"; - - private final static String KA = "KeyAgreement"; - - private final static String KS = "KeyStore"; - - private final static String SR = "SecureRandom"; - - static { - // names of all the implementation classes - // use local variables, only used here - String P11Digest = "sun.security.pkcs11.P11Digest"; - String P11MAC = "sun.security.pkcs11.P11MAC"; - String P11KeyPairGenerator = "sun.security.pkcs11.P11KeyPairGenerator"; - String P11KeyGenerator = "sun.security.pkcs11.P11KeyGenerator"; - String P11RSAKeyFactory = "sun.security.pkcs11.P11RSAKeyFactory"; - String P11DSAKeyFactory = "sun.security.pkcs11.P11DSAKeyFactory"; - String P11DHKeyFactory = "sun.security.pkcs11.P11DHKeyFactory"; - String P11KeyAgreement = "sun.security.pkcs11.P11KeyAgreement"; - String P11SecretKeyFactory = "sun.security.pkcs11.P11SecretKeyFactory"; - String P11Cipher = "sun.security.pkcs11.P11Cipher"; - String P11RSACipher = "sun.security.pkcs11.P11RSACipher"; - String P11Signature = "sun.security.pkcs11.P11Signature"; - - // XXX register all aliases - - d(MD, "MD2", P11Digest, - m(CKM_MD2)); - d(MD, "MD5", P11Digest, - m(CKM_MD5)); - d(MD, "SHA1", P11Digest, - s("SHA", "SHA-1", "1.3.14.3.2.26", "OID.1.3.14.3.2.26"), - m(CKM_SHA_1)); - - d(MD, "SHA-224", P11Digest, - s("2.16.840.1.101.3.4.2.4", "OID.2.16.840.1.101.3.4.2.4"), - m(CKM_SHA224)); - d(MD, "SHA-256", P11Digest, - s("2.16.840.1.101.3.4.2.1", "OID.2.16.840.1.101.3.4.2.1"), - m(CKM_SHA256)); - d(MD, "SHA-384", P11Digest, - s("2.16.840.1.101.3.4.2.2", "OID.2.16.840.1.101.3.4.2.2"), - m(CKM_SHA384)); - d(MD, "SHA-512", P11Digest, - s("2.16.840.1.101.3.4.2.3", "OID.2.16.840.1.101.3.4.2.3"), - m(CKM_SHA512)); - - d(MAC, "HmacMD5", P11MAC, - m(CKM_MD5_HMAC)); - d(MAC, "HmacSHA1", P11MAC, - s("1.2.840.113549.2.7", "OID.1.2.840.113549.2.7"), - m(CKM_SHA_1_HMAC)); - d(MAC, "HmacSHA224", P11MAC, - s("1.2.840.113549.2.8", "OID.1.2.840.113549.2.8"), - m(CKM_SHA224_HMAC)); - d(MAC, "HmacSHA256", P11MAC, - s("1.2.840.113549.2.9", "OID.1.2.840.113549.2.9"), - m(CKM_SHA256_HMAC)); - d(MAC, "HmacSHA384", P11MAC, - s("1.2.840.113549.2.10", "OID.1.2.840.113549.2.10"), - m(CKM_SHA384_HMAC)); - d(MAC, "HmacSHA512", P11MAC, - s("1.2.840.113549.2.11", "OID.1.2.840.113549.2.11"), - m(CKM_SHA512_HMAC)); - d(MAC, "SslMacMD5", P11MAC, - m(CKM_SSL3_MD5_MAC)); - d(MAC, "SslMacSHA1", P11MAC, - m(CKM_SSL3_SHA1_MAC)); - - d(KPG, "RSA", P11KeyPairGenerator, - m(CKM_RSA_PKCS_KEY_PAIR_GEN)); - d(KPG, "DSA", P11KeyPairGenerator, - s("1.3.14.3.2.12", "1.2.840.10040.4.1", "OID.1.2.840.10040.4.1"), - m(CKM_DSA_KEY_PAIR_GEN)); - d(KPG, "DH", P11KeyPairGenerator, s("DiffieHellman"), - m(CKM_DH_PKCS_KEY_PAIR_GEN)); - d(KPG, "EC", P11KeyPairGenerator, - m(CKM_EC_KEY_PAIR_GEN)); - - d(KG, "ARCFOUR", P11KeyGenerator, s("RC4"), - m(CKM_RC4_KEY_GEN)); - d(KG, "DES", P11KeyGenerator, - m(CKM_DES_KEY_GEN)); - d(KG, "DESede", P11KeyGenerator, - m(CKM_DES3_KEY_GEN, CKM_DES2_KEY_GEN)); - d(KG, "AES", P11KeyGenerator, - m(CKM_AES_KEY_GEN)); - d(KG, "Blowfish", P11KeyGenerator, - m(CKM_BLOWFISH_KEY_GEN)); - - // register (Secret)KeyFactories if there are any mechanisms - // for a particular algorithm that we support - d(KF, "RSA", P11RSAKeyFactory, - m(CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_RSA_PKCS, CKM_RSA_X_509)); - d(KF, "DSA", P11DSAKeyFactory, - s("1.3.14.3.2.12", "1.2.840.10040.4.1", "OID.1.2.840.10040.4.1"), - m(CKM_DSA_KEY_PAIR_GEN, CKM_DSA, CKM_DSA_SHA1)); - d(KF, "DH", P11DHKeyFactory, s("DiffieHellman"), - m(CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE)); - d(KF, "EC", P11DHKeyFactory, - m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE, - CKM_ECDSA, CKM_ECDSA_SHA1)); - - // AlgorithmParameters for EC. - // Only needed until we have an EC implementation in the SUN provider. - d(AGP, "EC", "sun.security.util.ECParameters", - s("1.2.840.10045.2.1"), - m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE, - CKM_ECDSA, CKM_ECDSA_SHA1)); - - d(KA, "DH", P11KeyAgreement, s("DiffieHellman"), - m(CKM_DH_PKCS_DERIVE)); - d(KA, "ECDH", "sun.security.pkcs11.P11ECDHKeyAgreement", - m(CKM_ECDH1_DERIVE)); - - d(SKF, "ARCFOUR", P11SecretKeyFactory, s("RC4"), - m(CKM_RC4)); - d(SKF, "DES", P11SecretKeyFactory, - m(CKM_DES_CBC)); - d(SKF, "DESede", P11SecretKeyFactory, - m(CKM_DES3_CBC)); - d(SKF, "AES", P11SecretKeyFactory, - s("2.16.840.1.101.3.4.1", "OID.2.16.840.1.101.3.4.1"), - m(CKM_AES_CBC)); - d(SKF, "Blowfish", P11SecretKeyFactory, - m(CKM_BLOWFISH_CBC)); - - // XXX attributes for Ciphers (supported modes, padding) - d(CIP, "ARCFOUR", P11Cipher, s("RC4"), - m(CKM_RC4)); - d(CIP, "DES/CBC/NoPadding", P11Cipher, - m(CKM_DES_CBC)); - d(CIP, "DES/CBC/PKCS5Padding", P11Cipher, - m(CKM_DES_CBC_PAD, CKM_DES_CBC)); - d(CIP, "DES/ECB/NoPadding", P11Cipher, - m(CKM_DES_ECB)); - d(CIP, "DES/ECB/PKCS5Padding", P11Cipher, s("DES"), - m(CKM_DES_ECB)); - - d(CIP, "DESede/CBC/NoPadding", P11Cipher, - m(CKM_DES3_CBC)); - d(CIP, "DESede/CBC/PKCS5Padding", P11Cipher, - m(CKM_DES3_CBC_PAD, CKM_DES3_CBC)); - d(CIP, "DESede/ECB/NoPadding", P11Cipher, - m(CKM_DES3_ECB)); - d(CIP, "DESede/ECB/PKCS5Padding", P11Cipher, s("DESede"), - m(CKM_DES3_ECB)); - d(CIP, "AES/CBC/NoPadding", P11Cipher, - m(CKM_AES_CBC)); - d(CIP, "AES_128/CBC/NoPadding", P11Cipher, - s("2.16.840.1.101.3.4.1.2", "OID.2.16.840.1.101.3.4.1.2"), - m(CKM_AES_CBC)); - d(CIP, "AES_192/CBC/NoPadding", P11Cipher, - s("2.16.840.1.101.3.4.1.22", "OID.2.16.840.1.101.3.4.1.22"), - m(CKM_AES_CBC)); - d(CIP, "AES_256/CBC/NoPadding", P11Cipher, - s("2.16.840.1.101.3.4.1.42", "OID.2.16.840.1.101.3.4.1.42"), - m(CKM_AES_CBC)); - d(CIP, "AES/CBC/PKCS5Padding", P11Cipher, - m(CKM_AES_CBC_PAD, CKM_AES_CBC)); - d(CIP, "AES/ECB/NoPadding", P11Cipher, - m(CKM_AES_ECB)); - d(CIP, "AES_128/ECB/NoPadding", P11Cipher, - s("2.16.840.1.101.3.4.1.1", "OID.2.16.840.1.101.3.4.1.1"), - m(CKM_AES_ECB)); - d(CIP, "AES_192/ECB/NoPadding", P11Cipher, - s("2.16.840.1.101.3.4.1.21", "OID.2.16.840.1.101.3.4.1.21"), - m(CKM_AES_ECB)); - d(CIP, "AES_256/ECB/NoPadding", P11Cipher, - s("2.16.840.1.101.3.4.1.41", "OID.2.16.840.1.101.3.4.1.41"), - m(CKM_AES_ECB)); - d(CIP, "AES/ECB/PKCS5Padding", P11Cipher, s("AES"), - m(CKM_AES_ECB)); - d(CIP, "AES/CTR/NoPadding", P11Cipher, - m(CKM_AES_CTR)); - d(CIP, "Blowfish/CBC/NoPadding", P11Cipher, - m(CKM_BLOWFISH_CBC)); - d(CIP, "Blowfish/CBC/PKCS5Padding", P11Cipher, - m(CKM_BLOWFISH_CBC)); - - // XXX RSA_X_509, RSA_OAEP not yet supported - d(CIP, "RSA/ECB/PKCS1Padding", P11RSACipher, s("RSA"), - m(CKM_RSA_PKCS)); - d(CIP, "RSA/ECB/NoPadding", P11RSACipher, - m(CKM_RSA_X_509)); - - d(SIG, "RawDSA", P11Signature, s("NONEwithDSA"), - m(CKM_DSA)); - d(SIG, "DSA", P11Signature, - s("SHA1withDSA", "1.3.14.3.2.13", "1.3.14.3.2.27", - "1.2.840.10040.4.3", "OID.1.2.840.10040.4.3"), - m(CKM_DSA_SHA1, CKM_DSA)); - d(SIG, "RawDSAinP1363Format", P11Signature, - s("NONEwithDSAinP1363Format"), - m(CKM_DSA)); - d(SIG, "DSAinP1363Format", P11Signature, - s("SHA1withDSAinP1363Format"), - m(CKM_DSA_SHA1, CKM_DSA)); - d(SIG, "NONEwithECDSA", P11Signature, - m(CKM_ECDSA)); - d(SIG, "SHA1withECDSA", P11Signature, - s("ECDSA", "1.2.840.10045.4.1", "OID.1.2.840.10045.4.1"), - m(CKM_ECDSA_SHA1, CKM_ECDSA)); - d(SIG, "SHA224withECDSA", P11Signature, - s("1.2.840.10045.4.3.1", "OID.1.2.840.10045.4.3.1"), - m(CKM_ECDSA)); - d(SIG, "SHA256withECDSA", P11Signature, - s("1.2.840.10045.4.3.2", "OID.1.2.840.10045.4.3.2"), - m(CKM_ECDSA)); - d(SIG, "SHA384withECDSA", P11Signature, - s("1.2.840.10045.4.3.3", "OID.1.2.840.10045.4.3.3"), - m(CKM_ECDSA)); - d(SIG, "SHA512withECDSA", P11Signature, - s("1.2.840.10045.4.3.4", "OID.1.2.840.10045.4.3.4"), - m(CKM_ECDSA)); - d(SIG, "NONEwithECDSAinP1363Format", P11Signature, - m(CKM_ECDSA)); - d(SIG, "SHA1withECDSAinP1363Format", P11Signature, - m(CKM_ECDSA_SHA1, CKM_ECDSA)); - d(SIG, "SHA224withECDSAinP1363Format", P11Signature, - m(CKM_ECDSA)); - d(SIG, "SHA256withECDSAinP1363Format", P11Signature, - m(CKM_ECDSA)); - d(SIG, "SHA384withECDSAinP1363Format", P11Signature, - m(CKM_ECDSA)); - d(SIG, "SHA512withECDSAinP1363Format", P11Signature, - m(CKM_ECDSA)); - d(SIG, "MD2withRSA", P11Signature, - s("1.2.840.113549.1.1.2", "OID.1.2.840.113549.1.1.2"), - m(CKM_MD2_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); - d(SIG, "MD5withRSA", P11Signature, - s("1.2.840.113549.1.1.4", "OID.1.2.840.113549.1.1.4"), - m(CKM_MD5_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); - d(SIG, "SHA1withRSA", P11Signature, - s("1.2.840.113549.1.1.5", "OID.1.2.840.113549.1.1.5", - "1.3.14.3.2.29"), - m(CKM_SHA1_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); - d(SIG, "SHA224withRSA", P11Signature, - s("1.2.840.113549.1.1.14", "OID.1.2.840.113549.1.1.14"), - m(CKM_SHA224_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); - d(SIG, "SHA256withRSA", P11Signature, - s("1.2.840.113549.1.1.11", "OID.1.2.840.113549.1.1.11"), - m(CKM_SHA256_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); - d(SIG, "SHA384withRSA", P11Signature, - s("1.2.840.113549.1.1.12", "OID.1.2.840.113549.1.1.12"), - m(CKM_SHA384_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); - d(SIG, "SHA512withRSA", P11Signature, - s("1.2.840.113549.1.1.13", "OID.1.2.840.113549.1.1.13"), - m(CKM_SHA512_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); - - /* - * TLS 1.2 uses a different hash algorithm than 1.0/1.1 for the - * PRF calculations. As of 2010, there is no PKCS11-level - * support for TLS 1.2 PRF calculations, and no known OS's have - * an internal variant we could use. Therefore for TLS 1.2, we - * are updating JSSE to request different provider algorithms - * (e.g. "SunTls12Prf"), and currently only SunJCE has these - * TLS 1.2 algorithms. - * - * If we reused the names such as "SunTlsPrf", the PKCS11 - * providers would need be updated to fail correctly when - * presented with the wrong version number (via - * Provider.Service.supportsParameters()), and we would also - * need to add the appropriate supportsParamters() checks into - * KeyGenerators (not currently there). - * - * In the future, if PKCS11 support is added, we will restructure - * this. - */ - d(KG, "SunTlsRsaPremasterSecret", - "sun.security.pkcs11.P11TlsRsaPremasterSecretGenerator", - m(CKM_SSL3_PRE_MASTER_KEY_GEN, CKM_TLS_PRE_MASTER_KEY_GEN)); - d(KG, "SunTlsMasterSecret", - "sun.security.pkcs11.P11TlsMasterSecretGenerator", - m(CKM_SSL3_MASTER_KEY_DERIVE, CKM_TLS_MASTER_KEY_DERIVE, - CKM_SSL3_MASTER_KEY_DERIVE_DH, - CKM_TLS_MASTER_KEY_DERIVE_DH)); - d(KG, "SunTlsKeyMaterial", - "sun.security.pkcs11.P11TlsKeyMaterialGenerator", - m(CKM_SSL3_KEY_AND_MAC_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE)); - d(KG, "SunTlsPrf", "sun.security.pkcs11.P11TlsPrfGenerator", - m(CKM_TLS_PRF, CKM_NSS_TLS_PRF_GENERAL)); - } - - // background thread that periodically checks for token insertion - // if no token is present. We need to do that in a separate thread because - // the insertion check may block for quite a long time on some tokens. - private static class TokenPoller implements Runnable { - private final SunPKCS11 provider; - private volatile boolean enabled; - private TokenPoller(SunPKCS11 provider) { - this.provider = provider; - enabled = true; - } - public void run() { - int interval = provider.config.getInsertionCheckInterval(); - while (enabled) { - try { - Thread.sleep(interval); - } catch (InterruptedException e) { - break; - } - if (enabled == false) { - break; - } - try { - provider.initToken(null); - } catch (PKCS11Exception e) { - // ignore - } - } - } - void disable() { - enabled = false; - } - } - - // create the poller thread, if not already active - private void createPoller() { - if (poller != null) { - return; - } - final TokenPoller poller = new TokenPoller(this); - Thread t = new Thread(null, poller, "Poller " + getName(), 0, false); - t.setContextClassLoader(null); - t.setDaemon(true); - t.setPriority(Thread.MIN_PRIORITY); - t.start(); - this.poller = poller; - } - - // destroy the poller thread, if active - private void destroyPoller() { - if (poller != null) { - poller.disable(); - poller = null; - } - } - - private boolean hasValidToken() { - /* Commented out to work with Solaris softtoken impl which - returns 0-value flags, e.g. both REMOVABLE_DEVICE and - TOKEN_PRESENT are false, when it can't access the token. - if (removable == false) { - return true; - } - */ - Token token = this.token; - return (token != null) && token.isValid(); - } - - // destroy the token. Called if we detect that it has been removed - synchronized void uninitToken(Token token) { - if (this.token != token) { - // mismatch, our token must already be destroyed - return; - } - destroyPoller(); - this.token = null; - // unregister all algorithms - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - clear(); - return null; - } - }); - createPoller(); - } - - // test if a token is present and initialize this provider for it if so. - // does nothing if no token is found - // called from constructor and by poller - private void initToken(CK_SLOT_INFO slotInfo) throws PKCS11Exception { - if (slotInfo == null) { - slotInfo = p11.C_GetSlotInfo(slotID); - } - if (removable && (slotInfo.flags & CKF_TOKEN_PRESENT) == 0) { - createPoller(); - return; - } - destroyPoller(); - boolean showInfo = config.getShowInfo(); - if (showInfo) { - System.out.println("Slot info for slot " + slotID + ":"); - System.out.println(slotInfo); - } - final Token token = new Token(this); - if (showInfo) { - System.out.println - ("Token info for token in slot " + slotID + ":"); - System.out.println(token.tokenInfo); - } - long[] supportedMechanisms = p11.C_GetMechanismList(slotID); - - // Create a map from the various Descriptors to the "most - // preferred" mechanism that was defined during the - // static initialization. For example, DES/CBC/PKCS5Padding - // could be mapped to CKM_DES_CBC_PAD or CKM_DES_CBC. Prefer - // the earliest entry. When asked for "DES/CBC/PKCS5Padding", we - // return a CKM_DES_CBC_PAD. - final Map supportedAlgs = - new HashMap(); - for (int i = 0; i < supportedMechanisms.length; i++) { - long longMech = supportedMechanisms[i]; - boolean isEnabled = config.isEnabled(longMech); - if (showInfo) { - CK_MECHANISM_INFO mechInfo = - p11.C_GetMechanismInfo(slotID, longMech); - System.out.println("Mechanism " + - Functions.getMechanismName(longMech) + ":"); - if (isEnabled == false) { - System.out.println("DISABLED in configuration"); - } - System.out.println(mechInfo); - } - if (isEnabled == false) { - continue; - } - // we do not know of mechs with the upper 32 bits set - if (longMech >>> 32 != 0) { - continue; - } - int mech = (int)longMech; - Integer integerMech = Integer.valueOf(mech); - List ds = descriptors.get(integerMech); - if (ds == null) { - continue; - } - for (Descriptor d : ds) { - Integer oldMech = supportedAlgs.get(d); - if (oldMech == null) { - supportedAlgs.put(d, integerMech); - continue; - } - // See if there is something "more preferred" - // than what we currently have in the supportedAlgs - // map. - int intOldMech = oldMech.intValue(); - for (int j = 0; j < d.mechanisms.length; j++) { - int nextMech = d.mechanisms[j]; - if (mech == nextMech) { - supportedAlgs.put(d, integerMech); - break; - } else if (intOldMech == nextMech) { - break; - } - } - } - - } - - // register algorithms in provider - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - for (Map.Entry entry - : supportedAlgs.entrySet()) { - Descriptor d = entry.getKey(); - int mechanism = entry.getValue().intValue(); - Service s = d.service(token, mechanism); - putService(s); - } - if (((token.tokenInfo.flags & CKF_RNG) != 0) - && config.isEnabled(PCKM_SECURERANDOM) - && !token.sessionManager.lowMaxSessions()) { - // do not register SecureRandom if the token does - // not support many sessions. if we did, we might - // run out of sessions in the middle of a - // nextBytes() call where we cannot fail over. - putService(new P11Service(token, SR, "PKCS11", - "sun.security.pkcs11.P11SecureRandom", null, - PCKM_SECURERANDOM)); - } - if (config.isEnabled(PCKM_KEYSTORE)) { - putService(new P11Service(token, KS, "PKCS11", - "sun.security.pkcs11.P11KeyStore", - s("PKCS11-" + config.getName()), - PCKM_KEYSTORE)); - } - return null; - } - }); - - this.token = token; - } - - private static final class P11Service extends Service { - - private final Token token; - - private final long mechanism; - - P11Service(Token token, String type, String algorithm, - String className, String[] al, long mechanism) { - super(token.provider, type, algorithm, className, toList(al), - type.equals(SR) ? Map.of("ThreadSafe", "true") : null); - this.token = token; - this.mechanism = mechanism & 0xFFFFFFFFL; - } - - private static List toList(String[] aliases) { - return (aliases == null) ? null : Arrays.asList(aliases); - } - - public Object newInstance(Object param) - throws NoSuchAlgorithmException { - if (token.isValid() == false) { - throw new NoSuchAlgorithmException("Token has been removed"); - } - try { - return newInstance0(param); - } catch (PKCS11Exception e) { - throw new NoSuchAlgorithmException(e); - } - } - - public Object newInstance0(Object param) throws - PKCS11Exception, NoSuchAlgorithmException { - String algorithm = getAlgorithm(); - String type = getType(); - if (type == MD) { - return new P11Digest(token, algorithm, mechanism); - } else if (type == CIP) { - if (algorithm.startsWith("RSA")) { - return new P11RSACipher(token, algorithm, mechanism); - } else { - return new P11Cipher(token, algorithm, mechanism); - } - } else if (type == SIG) { - return new P11Signature(token, algorithm, mechanism); - } else if (type == MAC) { - return new P11Mac(token, algorithm, mechanism); - } else if (type == KPG) { - return new P11KeyPairGenerator(token, algorithm, mechanism); - } else if (type == KA) { - if (algorithm.equals("ECDH")) { - return new P11ECDHKeyAgreement(token, algorithm, mechanism); - } else { - return new P11KeyAgreement(token, algorithm, mechanism); - } - } else if (type == KF) { - return token.getKeyFactory(algorithm); - } else if (type == SKF) { - return new P11SecretKeyFactory(token, algorithm); - } else if (type == KG) { - // reference equality - if (algorithm == "SunTlsRsaPremasterSecret") { - return new P11TlsRsaPremasterSecretGenerator( - token, algorithm, mechanism); - } else if (algorithm == "SunTlsMasterSecret") { - return new P11TlsMasterSecretGenerator( - token, algorithm, mechanism); - } else if (algorithm == "SunTlsKeyMaterial") { - return new P11TlsKeyMaterialGenerator( - token, algorithm, mechanism); - } else if (algorithm == "SunTlsPrf") { - return new P11TlsPrfGenerator(token, algorithm, mechanism); - } else { - return new P11KeyGenerator(token, algorithm, mechanism); - } - } else if (type == SR) { - return token.getRandom(); - } else if (type == KS) { - return token.getKeyStore(); - } else if (type == AGP) { - return new sun.security.util.ECParameters(); - } else { - throw new NoSuchAlgorithmException("Unknown type: " + type); - } - } - - public boolean supportsParameter(Object param) { - if ((param == null) || (token.isValid() == false)) { - return false; - } - if (param instanceof Key == false) { - throw new InvalidParameterException("Parameter must be a Key"); - } - String algorithm = getAlgorithm(); - String type = getType(); - Key key = (Key)param; - String keyAlgorithm = key.getAlgorithm(); - // RSA signatures and cipher - if (((type == CIP) && algorithm.startsWith("RSA")) - || (type == SIG) && algorithm.endsWith("RSA")) { - if (keyAlgorithm.equals("RSA") == false) { - return false; - } - return isLocalKey(key) - || (key instanceof RSAPrivateKey) - || (key instanceof RSAPublicKey); - } - // EC - if (((type == KA) && algorithm.equals("ECDH")) - || ((type == SIG) && algorithm.contains("ECDSA"))) { - if (keyAlgorithm.equals("EC") == false) { - return false; - } - return isLocalKey(key) - || (key instanceof ECPrivateKey) - || (key instanceof ECPublicKey); - } - // DSA signatures - if ((type == SIG) && algorithm.contains("DSA") && - !algorithm.contains("ECDSA")) { - if (keyAlgorithm.equals("DSA") == false) { - return false; - } - return isLocalKey(key) - || (key instanceof DSAPrivateKey) - || (key instanceof DSAPublicKey); - } - // MACs and symmetric ciphers - if ((type == CIP) || (type == MAC)) { - // do not check algorithm name, mismatch is unlikely anyway - return isLocalKey(key) || "RAW".equals(key.getFormat()); - } - // DH key agreement - if (type == KA) { - if (keyAlgorithm.equals("DH") == false) { - return false; - } - return isLocalKey(key) - || (key instanceof DHPrivateKey) - || (key instanceof DHPublicKey); - } - // should not reach here, - // unknown engine type or algorithm - throw new AssertionError - ("SunPKCS11 error: " + type + ", " + algorithm); - } - - private boolean isLocalKey(Key key) { - return (key instanceof P11Key) && (((P11Key)key).token == token); - } - - public String toString() { - return super.toString() + - " (" + Functions.getMechanismName(mechanism) + ")"; - } - - } - - /** - * Log in to this provider. - * - *

If the token expects a PIN to be supplied by the caller, - * the handler implementation must support - * a PasswordCallback. - * - *

To determine if the token supports a protected authentication path, - * the CK_TOKEN_INFO flag, CKF_PROTECTED_AUTHENTICATION_PATH, is consulted. - * - * @param subject this parameter is ignored - * @param handler the CallbackHandler used by - * this provider to communicate with the caller - * - * @throws IllegalStateException if the provider requires configuration - * and Provider.configure has not been called - * @throws LoginException if the login operation fails - * @throws SecurityException if the does not pass a security check for - * SecurityPermission("authProvider.name"), - * where name is the value returned by - * this provider's getName method - */ - public void login(Subject subject, CallbackHandler handler) - throws LoginException { - - if (!isConfigured()) { - throw new IllegalStateException("Configuration is required"); - } - - // security check - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - if (debug != null) { - debug.println("checking login permission"); - } - sm.checkPermission(new SecurityPermission - ("authProvider." + this.getName())); - } - - if (hasValidToken() == false) { - throw new LoginException("No token present"); - } - - // see if a login is required - - if ((token.tokenInfo.flags & CKF_LOGIN_REQUIRED) == 0) { - if (debug != null) { - debug.println("login operation not required for token - " + - "ignoring login request"); - } - return; - } - - // see if user already logged in - - try { - if (token.isLoggedInNow(null)) { - // user already logged in - if (debug != null) { - debug.println("user already logged in"); - } - return; - } - } catch (PKCS11Exception e) { - // ignore - fall thru and attempt login - } - - // get the pin if necessary - - char[] pin = null; - if ((token.tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) == 0) { - - // get password - - CallbackHandler myHandler = getCallbackHandler(handler); - if (myHandler == null) { - // XXX PolicyTool is dependent on this message text - throw new LoginException - ("no password provided, and no callback handler " + - "available for retrieving password"); - } - - java.text.MessageFormat form = new java.text.MessageFormat - (ResourcesMgr.getString - ("PKCS11.Token.providerName.Password.")); - Object[] source = { getName() }; - - PasswordCallback pcall = new PasswordCallback(form.format(source), - false); - Callback[] callbacks = { pcall }; - try { - myHandler.handle(callbacks); - } catch (Exception e) { - LoginException le = new LoginException - ("Unable to perform password callback"); - le.initCause(e); - throw le; - } - - pin = pcall.getPassword(); - pcall.clearPassword(); - if (pin == null) { - if (debug != null) { - debug.println("caller passed NULL pin"); - } - } - } - - // perform token login - - Session session = null; - try { - session = token.getOpSession(); - - // pin is NULL if using CKF_PROTECTED_AUTHENTICATION_PATH - p11.C_Login(session.id(), CKU_USER, pin); - if (debug != null) { - debug.println("login succeeded"); - } - } catch (PKCS11Exception pe) { - if (pe.getErrorCode() == CKR_USER_ALREADY_LOGGED_IN) { - // let this one go - if (debug != null) { - debug.println("user already logged in"); - } - return; - } else if (pe.getErrorCode() == CKR_PIN_INCORRECT) { - FailedLoginException fle = new FailedLoginException(); - fle.initCause(pe); - throw fle; - } else { - LoginException le = new LoginException(); - le.initCause(pe); - throw le; - } - } finally { - token.releaseSession(session); - if (pin != null) { - Arrays.fill(pin, ' '); - } - } - - // we do not store the PIN in the subject for now - } - - /** - * Log out from this provider - * - * @throws IllegalStateException if the provider requires configuration - * and Provider.configure has not been called - * @throws LoginException if the logout operation fails - * @throws SecurityException if the does not pass a security check for - * SecurityPermission("authProvider.name"), - * where name is the value returned by - * this provider's getName method - */ - public void logout() throws LoginException { - - if (!isConfigured()) { - throw new IllegalStateException("Configuration is required"); - } - - // security check - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission - (new SecurityPermission("authProvider." + this.getName())); - } - - if (hasValidToken() == false) { - // app may call logout for cleanup, allow - return; - } - - if ((token.tokenInfo.flags & CKF_LOGIN_REQUIRED) == 0) { - if (debug != null) { - debug.println("logout operation not required for token - " + - "ignoring logout request"); - } - return; - } - - try { - if (token.isLoggedInNow(null) == false) { - if (debug != null) { - debug.println("user not logged in"); - } - return; - } - } catch (PKCS11Exception e) { - // ignore - } - - // perform token logout - - Session session = null; - try { - session = token.getOpSession(); - p11.C_Logout(session.id()); - if (debug != null) { - debug.println("logout succeeded"); - } - } catch (PKCS11Exception pe) { - if (pe.getErrorCode() == CKR_USER_NOT_LOGGED_IN) { - // let this one go - if (debug != null) { - debug.println("user not logged in"); - } - return; - } - LoginException le = new LoginException(); - le.initCause(pe); - throw le; - } finally { - token.releaseSession(session); - } - } - - /** - * Set a CallbackHandler - * - *

The provider uses this handler if one is not passed to the - * login method. The provider also uses this handler - * if it invokes login on behalf of callers. - * In either case if a handler is not set via this method, - * the provider queries the - * auth.login.defaultCallbackHandler security property - * for the fully qualified class name of a default handler implementation. - * If the security property is not set, - * the provider is assumed to have alternative means - * for obtaining authentication information. - * - * @param handler a CallbackHandler for obtaining - * authentication information, which may be null - * - * @throws IllegalStateException if the provider requires configuration - * and Provider.configure has not been called - * @throws SecurityException if the caller does not pass a - * security check for - * SecurityPermission("authProvider.name"), - * where name is the value returned by - * this provider's getName method - */ - public void setCallbackHandler(CallbackHandler handler) { - - if (!isConfigured()) { - throw new IllegalStateException("Configuration is required"); - } - - // security check - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission - (new SecurityPermission("authProvider." + this.getName())); - } - - synchronized (LOCK_HANDLER) { - pHandler = handler; - } - } - - private CallbackHandler getCallbackHandler(CallbackHandler handler) { - - // get default handler if necessary - - if (handler != null) { - return handler; - } - - if (debug != null) { - debug.println("getting provider callback handler"); - } - - synchronized (LOCK_HANDLER) { - // see if handler was set via setCallbackHandler - if (pHandler != null) { - return pHandler; - } - - try { - if (debug != null) { - debug.println("getting default callback handler"); - } - - CallbackHandler myHandler = AccessController.doPrivileged - (new PrivilegedExceptionAction() { - public CallbackHandler run() throws Exception { - - String defaultHandler = - java.security.Security.getProperty - ("auth.login.defaultCallbackHandler"); - - if (defaultHandler == null || - defaultHandler.length() == 0) { - - // ok - if (debug != null) { - debug.println("no default handler set"); - } - return null; - } - - Class c = Class.forName - (defaultHandler, - true, - Thread.currentThread().getContextClassLoader()); - if (!javax.security.auth.callback.CallbackHandler.class.isAssignableFrom(c)) { - // not the right subtype - if (debug != null) { - debug.println("default handler " + defaultHandler + - " is not a CallbackHandler"); - } - return null; - } - @SuppressWarnings("deprecation") - Object result = c.newInstance(); - return (CallbackHandler)result; - } - }); - // save it - pHandler = myHandler; - return myHandler; - - } catch (PrivilegedActionException pae) { - // ok - if (debug != null) { - debug.println("Unable to load default callback handler"); - pae.printStackTrace(); - } - } - } - return null; - } - - private Object writeReplace() throws ObjectStreamException { - return new SunPKCS11Rep(this); - } - - /** - * Serialized representation of the SunPKCS11 provider. - */ - private static class SunPKCS11Rep implements Serializable { - - static final long serialVersionUID = -2896606995897745419L; - - private final String providerName; - - private final String configName; - - SunPKCS11Rep(SunPKCS11 provider) throws NotSerializableException { - providerName = provider.getName(); - configName = provider.config.getFileName(); - if (Security.getProvider(providerName) != provider) { - throw new NotSerializableException("Only SunPKCS11 providers " - + "installed in java.security.Security can be serialized"); - } - } - - private Object readResolve() throws ObjectStreamException { - SunPKCS11 p = (SunPKCS11)Security.getProvider(providerName); - if ((p == null) || (p.config.getFileName().equals(configName) == false)) { - throw new NotSerializableException("Could not find " - + providerName + " in installed providers"); - } - return p; - } - } -}