/*
 * Copyright 2000-2006 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package com.sun.security.auth.module;

import javax.security.auth.x500.X500Principal;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AuthProvider;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.UnrecoverableKeyException;
import java.security.cert.*;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.ResourceBundle;
import javax.security.auth.Destroyable;
import javax.security.auth.DestroyFailedException;
import javax.security.auth.Subject;
import javax.security.auth.x500.*;
import javax.security.auth.Subject;
import javax.security.auth.x500.*;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.ConfirmationCallback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.TextOutputCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

import sun.security.util.AuthResources;
import sun.security.util.Password;

/**
 * Provides a JAAS login module that prompts for a key store alias and
 * populates the subject with the alias's principal and credentials. Stores
 * an <code>X500Principal</code> for the subject distinguished name of the
 * first certificate in the alias's credentials in the subject's principals,
 * the alias's certificate path in the subject's public credentials, and a
 * <code>X500PrivateCredential</code> whose certificate is the first
 * certificate in the alias's certificate path and whose private key is the
 * alias's private key in the subject's private credentials. <p>
 *
 * Recognizes the following options in the configuration file:
 * <dl>
 *
 * <dt> <code>keyStoreURL</code> </dt>
 * <dd> A URL that specifies the location of the key store.  Defaults to
 *      a URL pointing to the .keystore file in the directory specified by the
 *      <code>user.home</code> system property.  The input stream from this
 *      URL is passed to the <code>KeyStore.load</code> method.
 *      "NONE" may be specified if a <code>null</code> stream must be
 *      passed to the <code>KeyStore.load</code> method.
 *      "NONE" should be specified if the KeyStore resides
 *      on a hardware token device, for example.</dd>
 *
 * <dt> <code>keyStoreType</code> </dt>
 * <dd> The key store type.  If not specified, defaults to the result of
 *      calling <code>KeyStore.getDefaultType()</code>.
 *      If the type is "PKCS11", then keyStoreURL must be "NONE"
 *      and privateKeyPasswordURL must not be specified.</dd>
 *
 * <dt> <code>keyStoreProvider</code> </dt>
 * <dd> The key store provider.  If not specified, uses the standard search
 *      order to find the provider. </dd>
 *
 * <dt> <code>keyStoreAlias</code> </dt>
 * <dd> The alias in the key store to login as.  Required when no callback
 *      handler is provided.  No default value. </dd>
 *
 * <dt> <code>keyStorePasswordURL</code> </dt>
 * <dd> A URL that specifies the location of the key store password.  Required
 *      when no callback handler is provided and
 *      <code>protected</code> is false.
 *      No default value. </dd>
 *
 * <dt> <code>privateKeyPasswordURL</code> </dt>
 * <dd> A URL that specifies the location of the specific private key password
 *      needed to access the private key for this alias.
 *      The keystore password
 *      is used if this value is needed and not specified. </dd>
 *
 * <dt> <code>protected</code> </dt>
 * <dd> This value should be set to "true" if the KeyStore
 *      has a separate, protected authentication path
 *      (for example, a dedicated PIN-pad attached to a smart card).
 *      Defaults to "false". If "true" keyStorePasswordURL and
 *      privateKeyPasswordURL must not be specified.</dd>
 *
 * </dl>
 */
public class KeyStoreLoginModule implements LoginModule {

   static final java.util.ResourceBundle rb =
        java.util.ResourceBundle.getBundle("sun.security.util.AuthResources");

    /* -- Fields -- */

    private static final int UNINITIALIZED = 0;
    private static final int INITIALIZED = 1;
    private static final int AUTHENTICATED = 2;
    private static final int LOGGED_IN = 3;

    private static final int PROTECTED_PATH = 0;
    private static final int TOKEN = 1;
    private static final int NORMAL = 2;

    private static final String NONE = "NONE";
    private static final String P11KEYSTORE = "PKCS11";

    private static final TextOutputCallback bannerCallback =
                new TextOutputCallback
                        (TextOutputCallback.INFORMATION,
                        rb.getString("Please enter keystore information"));
    private final ConfirmationCallback confirmationCallback =
                new ConfirmationCallback
                        (ConfirmationCallback.INFORMATION,
                        ConfirmationCallback.OK_CANCEL_OPTION,
                        ConfirmationCallback.OK);

    private Subject subject;
    private CallbackHandler callbackHandler;
    private Map sharedState;
    private Map<String, ?> options;

    private char[] keyStorePassword;
    private char[] privateKeyPassword;
    private KeyStore keyStore;

    private String keyStoreURL;
    private String keyStoreType;
    private String keyStoreProvider;
    private String keyStoreAlias;
    private String keyStorePasswordURL;
    private String privateKeyPasswordURL;
    private boolean debug;
    private javax.security.auth.x500.X500Principal principal;
    private Certificate[] fromKeyStore;
    private java.security.cert.CertPath certP = null;
    private X500PrivateCredential privateCredential;
    private int status = UNINITIALIZED;
    private boolean nullStream = false;
    private boolean token = false;
    private boolean protectedPath = false;

    /* -- Methods -- */

    /**
     * Initialize this <code>LoginModule</code>.
     *
     * <p>
     *
     * @param subject the <code>Subject</code> to be authenticated. <p>
     *
     * @param callbackHandler a <code>CallbackHandler</code> for communicating
     *                  with the end user (prompting for usernames and
     *                  passwords, for example),
     *                  which may be <code>null</code>. <p>
     *
     * @param sharedState shared <code>LoginModule</code> state. <p>
     *
     * @param options options specified in the login
     *                  <code>Configuration</code> for this particular
     *                  <code>LoginModule</code>.
     */

    public void initialize(Subject subject,
                           CallbackHandler callbackHandler,
                           Map<String,?> sharedState,
                           Map<String,?> options)
    {
        this.subject = subject;
        this.callbackHandler = callbackHandler;
        this.sharedState = sharedState;
        this.options = options;

        processOptions();
        status = INITIALIZED;
    }

    private void processOptions() {
        keyStoreURL = (String) options.get("keyStoreURL");
        if (keyStoreURL == null) {
            keyStoreURL =
                "file:" +
                System.getProperty("user.home").replace(
                    File.separatorChar, '/') +
                '/' + ".keystore";
        } else if (NONE.equals(keyStoreURL)) {
            nullStream = true;
        }
        keyStoreType = (String) options.get("keyStoreType");
        if (keyStoreType == null) {
            keyStoreType = KeyStore.getDefaultType();
        }
        if (P11KEYSTORE.equalsIgnoreCase(keyStoreType)) {
            token = true;
        }

        keyStoreProvider = (String) options.get("keyStoreProvider");

        keyStoreAlias = (String) options.get("keyStoreAlias");

        keyStorePasswordURL = (String) options.get("keyStorePasswordURL");

        privateKeyPasswordURL = (String) options.get("privateKeyPasswordURL");

        protectedPath = "true".equalsIgnoreCase((String)options.get
                                        ("protected"));

        debug = "true".equalsIgnoreCase((String) options.get("debug"));
        if (debug) {
            debugPrint(null);
            debugPrint("keyStoreURL=" + keyStoreURL);
            debugPrint("keyStoreType=" + keyStoreType);
            debugPrint("keyStoreProvider=" + keyStoreProvider);
            debugPrint("keyStoreAlias=" + keyStoreAlias);
            debugPrint("keyStorePasswordURL=" + keyStorePasswordURL);
            debugPrint("privateKeyPasswordURL=" + privateKeyPasswordURL);
            debugPrint("protectedPath=" + protectedPath);
            debugPrint(null);
        }
    }

    /**
     * Authenticate the user.
     *
     * <p> Get the Keystore alias and relevant passwords.
     * Retrieve the alias's principal and credentials from the Keystore.
     *
     * <p>
     *
     * @exception FailedLoginException if the authentication fails. <p>
     *
     * @return true in all cases (this <code>LoginModule</code>
     *          should not be ignored).
     */

    public boolean login() throws LoginException {
        switch (status) {
        case UNINITIALIZED:
        default:
            throw new LoginException("The login module is not initialized");
        case INITIALIZED:
        case AUTHENTICATED:

            if (token && !nullStream) {
                throw new LoginException
                        ("if keyStoreType is " + P11KEYSTORE +
                        " then keyStoreURL must be " + NONE);
            }

            if (token && privateKeyPasswordURL != null) {
                throw new LoginException
                        ("if keyStoreType is " + P11KEYSTORE +
                        " then privateKeyPasswordURL must not be specified");
            }

            if (protectedPath &&
                (keyStorePasswordURL != null ||
                        privateKeyPasswordURL != null)) {
                throw new LoginException
                        ("if protected is true then keyStorePasswordURL and " +
                        "privateKeyPasswordURL must not be specified");
            }

            // get relevant alias and password info

            if (protectedPath) {
                getAliasAndPasswords(PROTECTED_PATH);
            } else if (token) {
                getAliasAndPasswords(TOKEN);
            } else {
                getAliasAndPasswords(NORMAL);
            }

            // log into KeyStore to retrieve data,
            // then clear passwords

            try {
                getKeyStoreInfo();
            } finally {
                if (privateKeyPassword != null &&
                    privateKeyPassword != keyStorePassword) {
                    Arrays.fill(privateKeyPassword, '\0');
                    privateKeyPassword = null;
                }
                if (keyStorePassword != null) {
                    Arrays.fill(keyStorePassword, '\0');
                    keyStorePassword = null;
                }
            }
            status = AUTHENTICATED;
            return true;
        case LOGGED_IN:
            return true;
        }
    }

    /** Get the alias and passwords to use for looking up in the KeyStore. */
    private void getAliasAndPasswords(int env) throws LoginException {
        if (callbackHandler == null) {

            // No callback handler - check for alias and password options

            switch (env) {
            case PROTECTED_PATH:
                checkAlias();
                break;
            case TOKEN:
                checkAlias();
                checkStorePass();
                break;
            case NORMAL:
                checkAlias();
                checkStorePass();
                checkKeyPass();
                break;
            }

        } else {

            // Callback handler available - prompt for alias and passwords

            NameCallback aliasCallback;
            if (keyStoreAlias == null || keyStoreAlias.length() == 0) {
                aliasCallback = new NameCallback(
                                        rb.getString("Keystore alias: "));
            } else {
                aliasCallback =
                    new NameCallback(rb.getString("Keystore alias: "),
                                     keyStoreAlias);
            }

            PasswordCallback storePassCallback = null;
            PasswordCallback keyPassCallback = null;

            switch (env) {
            case PROTECTED_PATH:
                break;
            case NORMAL:
                keyPassCallback = new PasswordCallback
                    (rb.getString("Private key password (optional): "), false);
                // fall thru
            case TOKEN:
                storePassCallback = new PasswordCallback
                    (rb.getString("Keystore password: "), false);
                break;
            }
            prompt(aliasCallback, storePassCallback, keyPassCallback);
        }

        if (debug) {
            debugPrint("alias=" + keyStoreAlias);
        }
    }

    private void checkAlias() throws LoginException {
        if (keyStoreAlias == null) {
            throw new LoginException
                ("Need to specify an alias option to use " +
                "KeyStoreLoginModule non-interactively.");
        }
    }

    private void checkStorePass() throws LoginException {
        if (keyStorePasswordURL == null) {
            throw new LoginException
                ("Need to specify keyStorePasswordURL option to use " +
                "KeyStoreLoginModule non-interactively.");
        }
        InputStream in = null;
        try {
            in = new URL(keyStorePasswordURL).openStream();
            keyStorePassword = Password.readPassword(in);
        } catch (IOException e) {
            LoginException le = new LoginException
                ("Problem accessing keystore password \"" +
                keyStorePasswordURL + "\"");
            le.initCause(e);
            throw le;
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException ioe) {
                    LoginException le = new LoginException(
                        "Problem closing the keystore password stream");
                    le.initCause(ioe);
                    throw le;
                }
            }
        }
    }

    private void checkKeyPass() throws LoginException {
        if (privateKeyPasswordURL == null) {
            privateKeyPassword = keyStorePassword;
        } else {
            InputStream in = null;
            try {
                in = new URL(privateKeyPasswordURL).openStream();
                privateKeyPassword = Password.readPassword(in);
            } catch (IOException e) {
                LoginException le = new LoginException
                        ("Problem accessing private key password \"" +
                        privateKeyPasswordURL + "\"");
                le.initCause(e);
                throw le;
            } finally {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException ioe) {
                        LoginException le = new LoginException(
                            "Problem closing the private key password stream");
                        le.initCause(ioe);
                        throw le;
                    }
                }
            }
        }
    }

    private void prompt(NameCallback aliasCallback,
                        PasswordCallback storePassCallback,
                        PasswordCallback keyPassCallback)
                throws LoginException {

        if (storePassCallback == null) {

            // only prompt for alias

            try {
                callbackHandler.handle(
                    new Callback[] {
                        bannerCallback, aliasCallback, confirmationCallback
                    });
            } catch (IOException e) {
                LoginException le = new LoginException
                        ("Problem retrieving keystore alias");
                le.initCause(e);
                throw le;
            } catch (UnsupportedCallbackException e) {
                throw new LoginException(
                    "Error: " + e.getCallback().toString() +
                    " is not available to retrieve authentication " +
                    " information from the user");
            }

            int confirmationResult = confirmationCallback.getSelectedIndex();

            if (confirmationResult == ConfirmationCallback.CANCEL) {
                throw new LoginException("Login cancelled");
            }

            saveAlias(aliasCallback);

        } else if (keyPassCallback == null) {

            // prompt for alias and key store password

            try {
                callbackHandler.handle(
                    new Callback[] {
                        bannerCallback, aliasCallback,
                        storePassCallback, confirmationCallback
                    });
            } catch (IOException e) {
                LoginException le = new LoginException
                        ("Problem retrieving keystore alias and password");
                le.initCause(e);
                throw le;
            } catch (UnsupportedCallbackException e) {
                throw new LoginException(
                    "Error: " + e.getCallback().toString() +
                    " is not available to retrieve authentication " +
                    " information from the user");
            }

            int confirmationResult = confirmationCallback.getSelectedIndex();

            if (confirmationResult == ConfirmationCallback.CANCEL) {
                throw new LoginException("Login cancelled");
            }

            saveAlias(aliasCallback);
            saveStorePass(storePassCallback);

        } else {

            // prompt for alias, key store password, and key password

            try {
                callbackHandler.handle(
                    new Callback[] {
                        bannerCallback, aliasCallback,
                        storePassCallback, keyPassCallback,
                        confirmationCallback
                    });
            } catch (IOException e) {
                LoginException le = new LoginException
                        ("Problem retrieving keystore alias and passwords");
                le.initCause(e);
                throw le;
            } catch (UnsupportedCallbackException e) {
                throw new LoginException(
                    "Error: " + e.getCallback().toString() +
                    " is not available to retrieve authentication " +
                    " information from the user");
            }

            int confirmationResult = confirmationCallback.getSelectedIndex();

            if (confirmationResult == ConfirmationCallback.CANCEL) {
                throw new LoginException("Login cancelled");
            }

            saveAlias(aliasCallback);
            saveStorePass(storePassCallback);
            saveKeyPass(keyPassCallback);
        }
    }

    private void saveAlias(NameCallback cb) {
        keyStoreAlias = cb.getName();
    }

    private void saveStorePass(PasswordCallback c) {
        keyStorePassword = c.getPassword();
        if (keyStorePassword == null) {
            /* Treat a NULL password as an empty password */
            keyStorePassword = new char[0];
        }
        c.clearPassword();
    }

    private void saveKeyPass(PasswordCallback c) {
        privateKeyPassword = c.getPassword();
        if (privateKeyPassword == null || privateKeyPassword.length == 0) {
            /*
             * Use keystore password if no private key password is
             * specified.
             */
            privateKeyPassword = keyStorePassword;
        }
        c.clearPassword();
    }

    /** Get the credentials from the KeyStore. */
    private void getKeyStoreInfo() throws LoginException {

        /* Get KeyStore instance */
        try {
            if (keyStoreProvider == null) {
                keyStore = KeyStore.getInstance(keyStoreType);
            } else {
                keyStore =
                    KeyStore.getInstance(keyStoreType, keyStoreProvider);
            }
        } catch (KeyStoreException e) {
            LoginException le = new LoginException
                ("The specified keystore type was not available");
            le.initCause(e);
            throw le;
        } catch (NoSuchProviderException e) {
            LoginException le = new LoginException
                ("The specified keystore provider was not available");
            le.initCause(e);
            throw le;
        }

        /* Load KeyStore contents from file */
        InputStream in = null;
        try {
            if (nullStream) {
                // if using protected auth path, keyStorePassword will be null
                keyStore.load(null, keyStorePassword);
            } else {
                in = new URL(keyStoreURL).openStream();
                keyStore.load(in, keyStorePassword);
            }
        } catch (MalformedURLException e) {
            LoginException le = new LoginException
                                ("Incorrect keyStoreURL option");
            le.initCause(e);
            throw le;
        } catch (GeneralSecurityException e) {
            LoginException le = new LoginException
                                ("Error initializing keystore");
            le.initCause(e);
            throw le;
        } catch (IOException e) {
            LoginException le = new LoginException
                                ("Error initializing keystore");
            le.initCause(e);
            throw le;
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException ioe) {
                    LoginException le = new LoginException
                                ("Error initializing keystore");
                    le.initCause(ioe);
                    throw le;
                }
            }
        }

        /* Get certificate chain and create a certificate path */
        try {
            fromKeyStore =
                keyStore.getCertificateChain(keyStoreAlias);
            if (fromKeyStore == null
                || fromKeyStore.length == 0
                || !(fromKeyStore[0] instanceof X509Certificate))
            {
                throw new FailedLoginException(
                    "Unable to find X.509 certificate chain in keystore");
            } else {
                LinkedList<Certificate> certList =
                                new LinkedList<Certificate>();
                for (int i=0; i < fromKeyStore.length; i++) {
                    certList.add(fromKeyStore[i]);
                }
                CertificateFactory certF=
                    CertificateFactory.getInstance("X.509");
                certP =
                    certF.generateCertPath(certList);
            }
        } catch (KeyStoreException e) {
            LoginException le = new LoginException("Error using keystore");
            le.initCause(e);
            throw le;
        } catch (CertificateException ce) {
            LoginException le = new LoginException
                ("Error: X.509 Certificate type unavailable");
            le.initCause(ce);
            throw le;
        }

        /* Get principal and keys */
        try {
            X509Certificate certificate = (X509Certificate)fromKeyStore[0];
            principal = new javax.security.auth.x500.X500Principal
                (certificate.getSubjectDN().getName());

            // if token, privateKeyPassword will be null
            Key privateKey = keyStore.getKey(keyStoreAlias, privateKeyPassword);
            if (privateKey == null
                || !(privateKey instanceof PrivateKey))
            {
                throw new FailedLoginException(
                    "Unable to recover key from keystore");
            }

            privateCredential = new X500PrivateCredential(
                certificate, (PrivateKey) privateKey, keyStoreAlias);
        } catch (KeyStoreException e) {
            LoginException le = new LoginException("Error using keystore");
            le.initCause(e);
            throw le;
        } catch (NoSuchAlgorithmException e) {
            LoginException le = new LoginException("Error using keystore");
            le.initCause(e);
            throw le;
        } catch (UnrecoverableKeyException e) {
            FailedLoginException fle = new FailedLoginException
                                ("Unable to recover key from keystore");
            fle.initCause(e);
            throw fle;
        }
        if (debug) {
            debugPrint("principal=" + principal +
                       "\n certificate="
                       + privateCredential.getCertificate() +
                       "\n alias =" + privateCredential.getAlias());
        }
    }

    /**
     * Abstract method to commit the authentication process (phase 2).
     *
     * <p> This method is called if the LoginContext's
     * overall authentication succeeded
     * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
     * succeeded).
     *
     * <p> If this LoginModule's own authentication attempt
     * succeeded (checked by retrieving the private state saved by the
     * <code>login</code> method), then this method associates a
     * <code>X500Principal</code> for the subject distinguished name of the
     * first certificate in the alias's credentials in the subject's
     * principals,the alias's certificate path in the subject's public
     * credentials, and a<code>X500PrivateCredential</code> whose certificate
     * is the first  certificate in the alias's certificate path and whose
     * private key is the alias's private key in the subject's private
     * credentials.  If this LoginModule's own
     * authentication attempted failed, then this method removes
     * any state that was originally saved.
     *
     * <p>
     *
     * @exception LoginException if the commit fails
     *
     * @return true if this LoginModule's own login and commit
     *          attempts succeeded, or false otherwise.
     */

    public boolean commit() throws LoginException {
        switch (status) {
        case UNINITIALIZED:
        default:
            throw new LoginException("The login module is not initialized");
        case INITIALIZED:
            logoutInternal();
            throw new LoginException("Authentication failed");
        case AUTHENTICATED:
            if (commitInternal()) {
                return true;
            } else {
                logoutInternal();
                throw new LoginException("Unable to retrieve certificates");
            }
        case LOGGED_IN:
            return true;
        }
    }

    private boolean commitInternal() throws LoginException {
        /* If the subject is not readonly add to the principal and credentials
         * set; otherwise just return true
         */
        if (subject.isReadOnly()) {
            throw new LoginException ("Subject is set readonly");
        } else {
            subject.getPrincipals().add(principal);
            subject.getPublicCredentials().add(certP);
            subject.getPrivateCredentials().add(privateCredential);
            status = LOGGED_IN;
            return true;
        }
    }

    /**
     * <p> This method is called if the LoginContext's
     * overall authentication failed.
     * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
     * did not succeed).
     *
     * <p> If this LoginModule's own authentication attempt
     * succeeded (checked by retrieving the private state saved by the
     * <code>login</code> and <code>commit</code> methods),
     * then this method cleans up any state that was originally saved.
     *
     * <p> If the loaded KeyStore's provider extends
     * <code>java.security.AuthProvider</code>,
     * then the provider's <code>logout</code> method is invoked.
     *
     * <p>
     *
     * @exception LoginException if the abort fails.
     *
     * @return false if this LoginModule's own login and/or commit attempts
     *          failed, and true otherwise.
     */

    public boolean abort() throws LoginException {
        switch (status) {
        case UNINITIALIZED:
        default:
            return false;
        case INITIALIZED:
            return false;
        case AUTHENTICATED:
            logoutInternal();
            return true;
        case LOGGED_IN:
            logoutInternal();
            return true;
        }
    }
    /**
     * Logout a user.
     *
     * <p> This method removes the Principals, public credentials and the
     * private credentials that were added by the <code>commit</code> method.
     *
     * <p> If the loaded KeyStore's provider extends
     * <code>java.security.AuthProvider</code>,
     * then the provider's <code>logout</code> method is invoked.
     *
     * <p>
     *
     * @exception LoginException if the logout fails.
     *
     * @return true in all cases since this <code>LoginModule</code>
     *          should not be ignored.
     */

    public boolean logout() throws LoginException {
        if (debug)
            debugPrint("Entering logout " + status);
        switch (status) {
        case UNINITIALIZED:
            throw new LoginException
                ("The login module is not initialized");
        case INITIALIZED:
        case AUTHENTICATED:
        default:
           // impossible for LoginModule to be in AUTHENTICATED
           // state
           // assert status != AUTHENTICATED;
            return false;
        case LOGGED_IN:
            logoutInternal();
            return true;
        }
    }

    private void logoutInternal() throws LoginException {
        if (debug) {
            debugPrint("Entering logoutInternal");
        }

        // assumption is that KeyStore.load did a login -
        // perform explicit logout if possible
        LoginException logoutException = null;
        Provider provider = keyStore.getProvider();
        if (provider instanceof AuthProvider) {
            AuthProvider ap = (AuthProvider)provider;
            try {
                ap.logout();
                if (debug) {
                    debugPrint("logged out of KeyStore AuthProvider");
                }
            } catch (LoginException le) {
                // save but continue below
                logoutException = le;
            }
        }

        if (subject.isReadOnly()) {
            // attempt to destroy the private credential
            // even if the Subject is read-only
            principal = null;
            certP = null;
            status = INITIALIZED;
            // destroy the private credential
            Iterator<Object> it = subject.getPrivateCredentials().iterator();
            while (it.hasNext()) {
                Object obj = it.next();
                if (privateCredential.equals(obj)) {
                    privateCredential = null;
                    try {
                        ((Destroyable)obj).destroy();
                        if (debug)
                            debugPrint("Destroyed private credential, " +
                                       obj.getClass().getName());
                        break;
                    } catch (DestroyFailedException dfe) {
                        LoginException le = new LoginException
                            ("Unable to destroy private credential, "
                             + obj.getClass().getName());
                        le.initCause(dfe);
                        throw le;
                    }
                }
            }

            // throw an exception because we can not remove
            // the principal and public credential from this
            // read-only Subject
            throw new LoginException
                ("Unable to remove Principal ("
                 + "X500Principal "
                 + ") and public credential (certificatepath) "
                 + "from read-only Subject");
        }
        if (principal != null) {
            subject.getPrincipals().remove(principal);
            principal = null;
        }
        if (certP != null) {
            subject.getPublicCredentials().remove(certP);
            certP = null;
        }
        if (privateCredential != null) {
            subject.getPrivateCredentials().remove(privateCredential);
            privateCredential = null;
        }

        // throw pending logout exception if there is one
        if (logoutException != null) {
            throw logoutException;
        }
        status = INITIALIZED;
    }

    private void debugPrint(String message) {
        // we should switch to logging API
        if (message == null) {
            System.err.println();
        } else {
            System.err.println("Debug KeyStoreLoginModule: " + message);
        }
    }
}
