/*
 * Copyright (c) 2010, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.enterprise.security.store;

import static com.sun.enterprise.util.CULoggerInfo.errorCreatingDirectory;
import static com.sun.enterprise.util.SystemPropertyConstants.CLIENT_TRUSTSTORE_PASSWORD_PROPERTY;
import static com.sun.enterprise.util.SystemPropertyConstants.KEYSTORE_PROPERTY;
import static java.util.logging.Level.FINE;

import java.io.BufferedInputStream;
import java.io.Console;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.logging.Logger;

import com.sun.enterprise.universal.i18n.LocalStringsImpl;
import com.sun.enterprise.util.CULoggerInfo;

/**
 * Various utility methods related to certificate-based security.
 * <p>
 * In particular, this class opens both the client-side keystore and the client-side truststore when either one is requested.
 * This allows us to prompt only once for the master password (if necessary) without storing the password the user responds with
 * which would be a security risk.
 *
 * @author Tim Quinn (with portions refactored from elsewhere)
 */
public class AsadminSecurityUtil {

    private static final File DEFAULT_CLIENT_DIR = new File(System.getProperty("user.home"), ".gfclient");

    private static final Logger logger = CULoggerInfo.getLogger();
    private static final LocalStringsImpl strmgr = new LocalStringsImpl(AsadminSecurityUtil.class);

    private static AsadminSecurityUtil instance;

    private AsadminTruststore asadminTruststore;
    private KeyStore asadminKeystore;


    /**
     * Returns the usable instance, creating it if needed.
     *
     * @param commandLineMasterPassword password provided via the command line
     * @param isPromptable if the command requiring the object was run by a human who is present to respond to a prompt for the
     * master password
     * @return the usable instance
     */
    public synchronized static AsadminSecurityUtil getInstance(final char[] commandLineMasterPassword, final boolean isPromptable) {
        if (instance == null) {
            instance = new AsadminSecurityUtil(commandLineMasterPassword, isPromptable);
        }

        return instance;
    }

    /**
     * Returns the usable instance, creating it if needed.
     *
     * @param isPromptable if the command requiring the object was run by a human who is present to respond to a prompt for the
     * master password
     * @return
     */
    public synchronized static AsadminSecurityUtil getInstance(final boolean isPromptable) {
        return getInstance(null, isPromptable);
    }



    /**
     * Returns the master password for the keystore and truststore, as set by the system property (defaulted if the property is not
     * set).
     *
     * @return
     */
    public static char[] getAsadminTruststorePassword() {
        return System.getProperty(CLIENT_TRUSTSTORE_PASSWORD_PROPERTY, "changeit").toCharArray();
    }

    /**
     * Get the default location for client related files
     */
    public static File getDefaultClientDir() {
        if (!DEFAULT_CLIENT_DIR.isDirectory()) {
            if (DEFAULT_CLIENT_DIR.mkdirs() == false) {
                logger.log(FINE, errorCreatingDirectory, DEFAULT_CLIENT_DIR);
                // return the File anyway, the user of the file will report the failure
            }
        }

        return DEFAULT_CLIENT_DIR;
    }

    private AsadminSecurityUtil(final char[] commandLineMasterPassword, final boolean isPromptable) {
        try {
            init(commandLineMasterPassword, isPromptable);
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    /**
     * If we fail to open the client database using the default password (changeit) or the password found in
     * "javax.net.ssl.trustStorePassword" system property, then the fallback behavior is to prompt the user for the password by
     * calling this method.
     *
     * @return the password to the client side truststore
     */
    private char[] promptForPassword() throws IOException {
        Console console = System.console();
        if (console != null) {
            return console.readPassword(strmgr.get("certificateDbPrompt"));
        }

        return null;
    }

    /**
     * Returns the opened AsadminTruststore object.
     *
     * @return the AsadminTruststore object
     */
    public AsadminTruststore getAsadminTruststore() {
        return asadminTruststore;
    }

    public KeyStore getAsadminKeystore() {
        return asadminKeystore;
    }

    private void init(final char[] commandLineMasterPassword, final boolean isPromptable)
        throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException {
        char[] passwordToUse = chooseMasterPassword(commandLineMasterPassword);
        try {

            /*
             * Open the keystore if the user has specified one using
             * the standard system property.  That would allow users to add a
             * key to a client-side keystore and use SSL client auth from
             * asadmin to the DAS (if they have added the corresponding cert to
             * the DAS truststore).
             */
            asadminKeystore = openKeystore(passwordToUse);
            if (asadminKeystore == null) {
                logger.finer("Skipped loading keystore - location null");
            } else {
                logger.finer("Loaded keystore using command or default master password");
            }
        } catch (IOException ex) {
            if (ex.getCause() instanceof UnrecoverableKeyException) {
                /*
                 * The password did not allow access to the keystore.  Prompt
                 * the user if possible.
                 */
                if (!isPromptable) {
                    throw ex;
                }

                passwordToUse = promptForPassword();
                if (passwordToUse == null) {
                    throw new IllegalArgumentException();
                }

                asadminKeystore = openKeystore(passwordToUse);
                logger.finer("Loaded keystore using prompted master password");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        /*
         * The keystore has been opened successfully, using passwordToUse.
         * Open the truststore with that password.
         */
        asadminTruststore = openTruststore(passwordToUse);
    }

    private AsadminTruststore openTruststore(final char[] password)
        throws CertificateException, KeyStoreException, NoSuchAlgorithmException, IOException {
        return new AsadminTruststore(password);
    }

    /**
     * Open the keystore, using the password provided.
     *
     * @param candidateMasterPassword password to use in opening the keystore
     * @return opened keystore
     * @throws KeyStoreException
     * @throws IOException
     * @throws NoSuchAlgorithmException
     * @throws CertificateException
     */
    private KeyStore openKeystore(final char[] candidateMasterPassword)
        throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
        final KeyStore permanentKS = KeyStore.getInstance("JKS");

        try (InputStream keyStoreStream = asadminKeyStoreStream()) {
            if (keyStoreStream == null) {
                return null;
            }
            permanentKS.load(keyStoreStream, candidateMasterPassword);
            return permanentKS;
        }
    }

    /**
     * Returns the master password passed on the command line or, if none, the default master password.
     *
     * @param commandMasterPassword master password passed on the command line; null if none
     * @return master password to use
     */
    private char[] chooseMasterPassword(final char[] commandMasterPassword) {
        return commandMasterPassword == null ? defaultMasterPassword() : commandMasterPassword;
    }

    /**
     * Returns an open stream to the keystore.
     *
     * @return stream to the keystore
     * @throws FileNotFoundException
     */
    private InputStream asadminKeyStoreStream() throws FileNotFoundException {
        String location = System.getProperty(KEYSTORE_PROPERTY);
        if (location == null) {
            return null;
        }

        return new BufferedInputStream(new FileInputStream(location));
    }

    private char[] defaultMasterPassword() {
        return System.getProperty(CLIENT_TRUSTSTORE_PASSWORD_PROPERTY, "changeit").toCharArray();
    }

}
