/*
 * Copyright (c) 2003, 2014, 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 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");

    private static int dummyConfigId;

    // the PKCS11 object through which we make the native calls
    final PKCS11 p11;

    // name of the configuration file
    private final String configName;

    // 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-Dummy", 1.9d, "SunPKCS11-Dummy");
        throw new ProviderException
            ("SunPKCS11 requires configuration file argument");
    }

    public SunPKCS11(String configName) {
        this(checkNull(configName), null);
    }

    public SunPKCS11(InputStream configStream) {
        this(getDummyConfigName(), checkNull(configStream));
    }

    private static <T> T checkNull(T obj) {
        if (obj == null) {
            throw new NullPointerException();
        }
        return obj;
    }

    private static synchronized String getDummyConfigName() {
        int id = ++dummyConfigId;
        return "---DummyConfig-" + id + "---";
    }

    /**
     * @deprecated use new SunPKCS11(String) or new SunPKCS11(InputStream)
     *         instead
     */
    @Deprecated
    public SunPKCS11(String configName, InputStream configStream) {
        super("SunPKCS11-" +
            Config.getConfig(configName, configStream).getName(),
            1.9d, Config.getConfig(configName, configStream).getDescription());
        this.configName = configName;
        this.config = Config.removeConfig(configName);

        if (debug != null) {
            System.out.println("SunPKCS11 loading " + configName);
        }

        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.ec.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, "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, "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;
        }
        TokenPoller poller = new TokenPoller(this);
        Thread t = new Thread(poller, "Poller " + getName());
        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), 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.ec.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.endsWith("ECDSA"))) {
                if (keyAlgorithm.equals("EC") == false) {
                    return false;
                }
                return isLocalKey(key)
                        || (key instanceof ECPrivateKey)
                        || (key instanceof ECPublicKey);
            }
            // DSA signatures
            if ((type == SIG) && algorithm.endsWith("DSA")) {
                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
     *
     * @exception LoginException if the login operation fails
     * @exception 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 {

        // 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
     *
     * @exception LoginException if the logout operation fails
     * @exception 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 {

        // 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>
     *
     * @exception 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) {

        // 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());
                        return (CallbackHandler)c.newInstance();
                    }
                });

                // 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.configName;
            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.configName.equals(configName) == false)) {
                throw new NotSerializableException("Could not find "
                        + providerName + " in installed providers");
            }
            return p;
        }
    }
}
