/*
 * Copyright (c) 2002, 2018 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.appserver.sqe.security.ssl.util;

import java.security.Security;
import java.security.Provider;

import sun.security.tools.*;
import java.io.*;
import java.util.*;
import java.security.cert.*;
import java.security.KeyStore;
import java.security.Key;
import com.sun.enterprise.util.*;
/**
 * Wraps the J2SE's keytool after adding our provider.
 * Provides the PKCS12 functionality - read a PKCS12 format
 * keystore and replicate it into a "JKS" type keystore.
 * @author Harish Prabandham
 * @author Harpreet Singh
 */
public final class KeyTool {
    private static final String JSSE_PROVIDER = "com.sun.net.ssl.internal.ssl.Provider";
    private boolean debug = false;
    // The PKCS12 file to be replicated
    private File inputFile=null;
    // The JKS file output from the replication
    private File outputFile=null;
    private char[] jksKeyStorePass;
    private char[] pkcsKeyStorePass = null;
    // Password of the key
    private char[] jksKeyPass = null;
    private char[] pkcsKeyPass = null;

    private String provider = null;
    // The respective in-memory keystores
    private KeyStore pkcs12KeyStore = null;
    private KeyStore jksKeyStore = null;

    private static String PKCS12 = "-pkcs12";
    private static String INFILE = "-pkcsFile";
    private static String OUTFILE = "-jksFile";
    private static String PKCSKEYSTOREPASS = "-pkcsKeyStorePass";
    private static String PKCSKEYPASS = "-pkcsKeyPass";
    // following 2 options not used currently - set to default
    private static String JKSKEYSTOREPASS = "-jksKeyStorePass";
    private static String JKSKEYPASS = "-jksKeyPass";
    private static LocalStringManagerImpl localStrings =
        new LocalStringManagerImpl(KeyTool.class);

    /**
     * The class is only instantiated for PKCS12 - all other
     * keytool functionality is passed to the sun.security.tools.KeyTool
     * @param the file name of the PKCS12 file
     * @param the output file name of the JKS file
     * @param the provider - In this case SunJSSE
     * @param password to the PKCS12 keystore
     * @param password to the key in the PKCS12 keystore
     * @param password to the JKS keystore
     * @param password to the key in the JKS keystore
     * currently it has to be the same as the JKS keystore password
     * @exception Problem in loading the keystores
     */
    public KeyTool (String infile, String outfile, String pkcsKeyStorePass,
        String pkcsKeyPass, String jksKeyStorePass,
        String jksKeyPass,
        String provider) throws IOException {
        inputFile = new File (infile);
        outputFile = new File (outfile);
        this.pkcsKeyStorePass = pkcsKeyStorePass.toCharArray ();
        this.pkcsKeyPass = pkcsKeyPass.toCharArray ();
        this.jksKeyStorePass = jksKeyStorePass.toCharArray ();
        this.jksKeyPass = jksKeyPass.toCharArray ();
        this.provider = provider;
        // if the output file exists delete it and create a new file
        try{
            if (outputFile.exists ()){
                throw new IOException ("Output file already exists!");
            }
            // Get the keystores from the engines.
            pkcs12KeyStore = KeyStore.getInstance ("PKCS12", provider);
            jksKeyStore = KeyStore.getInstance ("JKS");

        } catch (Exception e) {
            // catch possible security and io exceptions
            throw new IOException (e.getMessage ());
        }
        readKeyStores ();
    }
    /**
     * Load both the keystore's into memory.
     * The PKCS12 is loaded from the file and the JKS file
     * is created.
     */
    public void readKeyStores() throws IOException {
        FileInputStream pkcsFis = null;
        FileInputStream jksFis = null;
        try {
            pkcsFis = new FileInputStream(inputFile);
            jksFis = new FileInputStream (outputFile);
        } catch(Exception e) {
            // No problem we'll create one....
            // e.printStackTrace();
        } finally {
            try {
                pkcs12KeyStore.load(pkcsFis, pkcsKeyStorePass);
                // Dont need a password as creating a new
                // keystore.
                jksKeyStore.load (jksFis, null);
            } catch(Exception ce) {
                // Can't do much... too bad.
                ce.printStackTrace();
            }
            if(pkcsFis != null)
                pkcsFis.close();
            if (jksFis != null)
                jksFis.close ();
        }
    }
    /**
     * Write the JKS keystore that is populated with values from
     * the PKCS12 keystore to the outputfile.
     */
    public void writeJksKeyStore() throws IOException {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(outputFile);
        } catch(Exception e) {
            // No problem we'll create one....
            // e.printStackTrace();
        } finally {
            try {
                jksKeyStore.store (fos, jksKeyStorePass);
            } catch(Exception ce) {
                // Can't do much... too bad.
                ce.printStackTrace();
            }
            if(fos != null)
                fos.close();
        }
    }
    /**
     * Copies the keys and certificates in the PKCS12 file to
     * the in-memory JKS keystore
     * @exception If the keystore has not been instantiated or
     * the password to the key is'nt proper
     */
    public void replicatePkcs12ToJks () throws Exception {
        Enumeration e = pkcs12KeyStore.aliases ();
        for (; e.hasMoreElements (); ){
            String alias = (String)e.nextElement ();
            if (pkcs12KeyStore.isKeyEntry (alias)){
                if (debug)
                    System.out.println ("Alias "+alias+ " is a key entry ");

                /* Get the key and associated certificate chain
                 * from PKCS12 keystore and put in JKS keystore
                 */
                Key key = pkcs12KeyStore.getKey (alias, pkcsKeyPass);
                Certificate[] certs =
                    pkcs12KeyStore.getCertificateChain (alias);
                jksKeyStore.setKeyEntry (alias,  key, jksKeyPass, certs);
            } else if (pkcs12KeyStore.isCertificateEntry (alias)){
                if (debug)
                    System.out.println (" Alias "+alias +
                        " is a certificate entry");
                jksKeyStore.setCertificateEntry
                (alias, pkcs12KeyStore.getCertificate (alias));
            }
        }
    }
    /**
     * Prints the information in the PKCS12 keystore
     */
    public void info () throws Exception{
        System.out.println (" Keystore Information");
        System.out.println (" Type = " + pkcs12KeyStore.getType ());
        System.out.println (" Provider = "+ pkcs12KeyStore.getProvider ());
        System.out.println (" KeyStore size = "+pkcs12KeyStore.size ());
        Enumeration e = pkcs12KeyStore.aliases ();
        System.out.println (" Kstore Aliases ");
        for (; e.hasMoreElements (); ){
            String alias = (String)e.nextElement ();
            System.out.println (" Alias = "+ alias);
            if (pkcs12KeyStore.isKeyEntry (alias)){
                System.out.println ("Alias is a key entry ");
                Key key = pkcs12KeyStore.getKey (alias, pkcsKeyPass);
                System.out.println (" Format = "+key.getFormat ());
            } else if (pkcs12KeyStore.isCertificateEntry (alias)){
                System.out.println (" Alias is a certificate entry");
            }
        }
        System.out.println (" End of Information");
    }
    /**
     * Initializes the provider to be the JSSE provider
     */
    public static void initProvider() {
        try {
            Provider p =
                (Provider) Class.forName(JSSE_PROVIDER).newInstance();
            Security.addProvider(p);

        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * Gets the provider name for JSSE
     */
    public static String getProviderName (){
        try{
            Provider p =
                (Provider) Class.forName(JSSE_PROVIDER).newInstance();
            return p.getName ();
        } catch (Exception e) {
            e.printStackTrace ();
        }
        return null;
    }
    public static void help (boolean exit){

        System.out.println
        (localStrings.getLocalString ("enterprise.security.keytool",
            "keytool"));
        System.out.println
        (localStrings.getLocalString
            ("enterprise.security.keytooloptions", "PKCS Options:"));
        System.out.println (" "+ PKCS12 +
            " "+ INFILE + " fileName" +
            " "+ PKCSKEYSTOREPASS + " password" +
            " "+PKCSKEYPASS +" password" +
            " "+OUTFILE+ " outputFileName"+
            " "+JKSKEYSTOREPASS + " password");
        /* uncomment when support for this present in JSSE
       System.Out.Println (" "+JKSKEYPASS+ " password");
         */
        if (exit)
            System.exit (-1);
    }
    public static void main(String[] args) {
        boolean pkcs = false;
        initProvider();
        String provider = null;
        String inFile = null;
        String outFile = null;
        String jksKeyPass  = null;
        String jksKeyStorePass = null;
        String pkcsKeyPass = null;
        String pkcsKeyStorePass = null;
        try{
            if (args.length == 0){
                help (false);
                sun.security.tools.KeyTool.main (args);
            }
            if (args[0].equalsIgnoreCase (PKCS12)){
                pkcs = true;
                if (args.length != 11)
                    help (true);
                if (!args[1].equalsIgnoreCase (INFILE))
                    help (true);
                inFile = args[2];
                if (!args[3].equalsIgnoreCase (PKCSKEYSTOREPASS))
                    help (true);
                pkcsKeyStorePass = args[4];
                if (!args[5].equalsIgnoreCase (PKCSKEYPASS))
                    help (true);
                pkcsKeyPass = args[6];
                if (!args[7].equalsIgnoreCase (OUTFILE))
                    help (true);
                outFile = args[8];
                if (!args[9].equalsIgnoreCase (JKSKEYSTOREPASS))
                    help (true);

                jksKeyStorePass = args[10];
                jksKeyPass = jksKeyStorePass;
                /*
        // Uncomment the following when support
        // for different keystore and key pass present in JSSE

        if (!args[11].equalsIgnoreCase (JKSKEYPASS))
            help ();
        jksKeyPass = args[12];
                 */
            }
            if (!pkcs){
                sun.security.tools.KeyTool.main(args);
            } else{
                provider = getProviderName ();
                KeyTool kt = new KeyTool (inFile, outFile, pkcsKeyStorePass,
                    pkcsKeyPass, jksKeyStorePass,
                    jksKeyPass,
                    provider);
                kt.replicatePkcs12ToJks ();
                kt.writeJksKeyStore ();
            }
        } catch (Exception e){
            System.out.println (e.getMessage ());
            e.printStackTrace ();
        }
    }
}



