JAAS Login Module

This is the preferred method. This method can be done either before the provider is created or after. The login module class is:
com.ibm.crypto.pkcs11impl.module.PKCS11LoginModule
This module uses a TextInputCallback with a label of PKCS11 DLL name: to get the hardware device PKCS #11 library, and slot number. The format of the string is:
<hardware device PKCS #11 library name>:<slot #>

To get the PIN, the module uses PasswordCallback with a label of password:. This password is received as a character array and is cleared as soon as possible.

The entry in the login configuration file entry for this module should look like:
com.ibm.crypto.pkcs11impl.module.PKCS11LoginModule required;
The following example shows how to use the login module before the provider instance is created:
        String pswd = "PASSWORD";
        char [] passwd = new char[pswd.length()];
        pswd.getChars(0,pswd.length(),passwd,0);
        LoginContext lc = null;
        
        // This class is used to pass the needed information into the login module.
        // Note that cryptoki.dll would be replaced by your PKCS#11 library
        // name and 0 is be replaced with the slot # you want.
        NullPrompter np = new NullPrompter("cryptoki.dll:0",passwd);

        // Create the login context.
        lc = new LoginContext("active", np);

        // This creates the needed principal that the provider needs.
        lc.login();

        // Get the associated subject.
        Subject whoami = lc.getSubject();
        
        // Creates the privileged action needed to finish
        PrivilegedAction doIt =
            (PrivilegedAction)Class.forName("testAction").newInstance();

        // Execute the action.
        Subject.doAs(whoami, doIt);

class testAction implements PrivilegedAction {
    public Object run() {
        com.ibm.crypto.pkcs11impl.provider.IBMPKCS11Impl p1 = null;

        // Create the provider and make it use the PKCS11Principal.
        p1 = new com.ibm.crypto.pkcs11impl.provider.IBMPKCS11Impl();

        //Add the provider to the Java Provider List after the IBMJCE provider. Note
        //that the IBMJCE provider should be in the provider list for JCE framework
        //verification.
        Security.addProvider(p1);

        return (Object) null;
    }
}

class NullPrompter implements javax.security.auth.callback.CallbackHandler {
    private String userName;
    private char[] authenticator;
    private NullPrompter() { // hide the null constructor, since we're not prompting!
    }

    public NullPrompter(String userName, char authenticator[]) {
        this.userName = userName;
        this.authenticator = authenticator;
    }

    public void nukeEm() {
        this.userName = null;
        for (int i = 0; i < authenticator.length; i++)
                    authenticator[i] = ' ';
    }

    public void handle(Callback[] callbacks)
    throws IOException, UnsupportedCallbackException {

            for (int i = 0; i < callbacks.length; i++) {
            if (callbacks[i] instanceof TextOutputCallback) {

            } else if (callbacks[i] instanceof TextInputCallback) {
                ((TextInputCallback)callbacks[i]).setText(userName);

            } else if (callbacks[i] instanceof PasswordCallback) {
            ((PasswordCallback)callbacks[i]).setPassword(authenticator);
            } else {
                throw new UnsupportedCallbackException
                        (callbacks[i], "Unrecognized Callback");
            }
        }
    } 
}
The following example shows how to use the login module after the provider is created. The only difference is in testAction code. Note that this example assumes that the provider has already been added to Java™ Provider List:
        String pswd = "PASSWORD";
        char [] passwd = new char[pswd.length()];
        pswd.getChars(0,pswd.length(),passwd,0);
        LoginContext lc = null;
        
        // This class is used to pass the needed information into the login module.
        // Please note that cryptoki.dll would be replaced by your PKCS#11 library
        // name and 0 is be replaced with the slot # you want.
        NullPrompter np = new NullPrompter("cryptoki.dll:0",passwd);

        // Create the login context.
        lc = new LoginContext("active", np);

        // This creates the needed principal that the provider needs.
        lc.login();

        // Get the associated subject.
        Subject whoami = lc.getSubject();
        
        // Creates the privileged action needed to finish
        PrivilegedAction doIt =
            (PrivilegedAction)Class.forName("testAction").newInstance();

        // Execute the action.
        Subject.doAs(whoami, doIt);

        
class testAction implements PrivilegedAction {
    public Object run() {
        Provider p = null;

        p = Security.getProvider("IBMPKCS11Impl");

        if (p != null) {
            ((com.ibm.crypto.pkcs11impl.provider.IBMPKCS11Impl)p).Init(null,null);
        } else {
            System.out.println("not found.");
        }

        return (Object) null;
    }
}