--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SunPKCS11.java Wed Dec 14 19:46:21 2016 +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> 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<Module> 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<Integer,List<Descriptor>> descriptors =
- new HashMap<Integer,List<Descriptor>>();
-
- 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<Descriptor> list = descriptors.get(key);
- if (list == null) {
- list = new ArrayList<Descriptor>();
- 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<Object>() {
- 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<Descriptor,Integer> supportedAlgs =
- new HashMap<Descriptor,Integer>();
- 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<Descriptor> 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<Object>() {
- public Object run() {
- for (Map.Entry<Descriptor,Integer> 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<String> 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.
- *
- * <p> If the token expects a PIN to be supplied by the caller,
- * the <code>handler</code> implementation must support
- * a <code>PasswordCallback</code>.
- *
- * <p> 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 <code>CallbackHandler</code> 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
- * <code>SecurityPermission("authProvider.<i>name</i>")</code>,
- * where <i>name</i> is the value returned by
- * this provider's <code>getName</code> 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
- * <code>SecurityPermission("authProvider.<i>name</i>")</code>,
- * where <i>name</i> is the value returned by
- * this provider's <code>getName</code> 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 <code>CallbackHandler</code>
- *
- * <p> The provider uses this handler if one is not passed to the
- * <code>login</code> method. The provider also uses this handler
- * if it invokes <code>login</code> on behalf of callers.
- * In either case if a handler is not set via this method,
- * the provider queries the
- * <i>auth.login.defaultCallbackHandler</i> 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 <code>CallbackHandler</code> for obtaining
- * authentication information, which may be <code>null</code>
- *
- * @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
- * <code>SecurityPermission("authProvider.<i>name</i>")</code>,
- * where <i>name</i> is the value returned by
- * this provider's <code>getName</code> 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<CallbackHandler>() {
- 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;
- }
- }
-}