package de.tu_dresden.diplom.richter_mirko_mat2628335.common.keystore;

import org.apache.log4j.Logger;

import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * Utility-Class to perform operations on some concrete Keystore-File.
 */
public class KeystoreUtility {

   private static final Logger logger = Logger.getLogger(KeystoreUtility.class);

   /**
    * Loads some certificate from the keystore-file (public portion).
    * @param keystoreType The type of the keystore.
    * @param keystoreFile The path to the keystore-file.
    * @param keyStorePasswd The password to load the keystore.
    * @param alias The alias of the entity to obtain the cert for.
    * @return The Certificate if successfull performed, null else.
    */
   public static Certificate getCertificate(String keystoreType, File keystoreFile, char[] keyStorePasswd, String alias) {
      Certificate result = null;
      try {
         KeyStore ks = KeyStore.getInstance(keystoreType);
         ks.load(new FileInputStream(keystoreFile), keyStorePasswd);
         result = ks.getCertificate(alias);
      } catch (KeyStoreException e) {
         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
      } catch (IOException e) {
         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
      } catch (NoSuchAlgorithmException e) {
         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
      } catch (CertificateException e) {
         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
      }
      return result;
   }

   /**
    * Loads some private key from the keystore-file (private portion).
    * @param keystoreType The type of the keystore.
    * @param keystoreFile The path to the keystore-file.
    * @param keyStorePasswd The password to load the keystore.
    * @param alias The alias of the entity to obtain the cert for.
    * @param aliasPasswd The password to load the private key of the entity.
    * @return The PrivateKey if successfull performed, null else.
    */
   public static PrivateKey getPrivateKey(String keystoreType, File keystoreFile, char[] keyStorePasswd, String alias, char[] aliasPasswd) {
      PrivateKey result = null;
      try {
         KeyStore ks = KeyStore.getInstance(keystoreType);
         ks.load(new FileInputStream(keystoreFile), keyStorePasswd);
         //result = ks.getCertificate(alias);
         result = (PrivateKey) ks.getKey(alias, aliasPasswd);
      } catch (KeyStoreException e) {
         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
      } catch (IOException e) {
         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
      } catch (NoSuchAlgorithmException e) {
         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
      } catch (CertificateException e) {
         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
      } catch (UnrecoverableKeyException e) {
         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
      }
      return result;
   }

   /**
    * Loads some private and public key from the keystore-file (public and private portion).
    * @param keystoreType The type of the keystore.
    * @param keystoreFile The path to the keystore-file.
    * @param keyStorePasswd The password to load the keystore.
    * @param alias The alias of the entity to obtain the cert for.
    * @param aliasPasswd The password to load the private key of the entity.
    * @return The KeyPair if succesfull performed, null else.
    */
   public static KeyPair getKeyPair(String keystoreType, File keystoreFile, char[] keyStorePasswd, String alias, char[] aliasPasswd){
      KeyPair result = null;
      try {
         KeyStore ks = KeyStore.getInstance(keystoreType);
         ks.load(new FileInputStream(keystoreFile), keyStorePasswd);
         // Get private key
         Key key = ks.getKey(alias, aliasPasswd);
         if (key instanceof PrivateKey) {
            // Get certificate of public key
            java.security.cert.Certificate cert = ks.getCertificate(alias);

            // Get public key
            PublicKey publicKey = cert.getPublicKey();

            // Return a key pair
            result = new KeyPair(publicKey, (PrivateKey) key);
         }
      } catch (KeyStoreException e) {
         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
      } catch (IOException e) {
         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
      } catch (NoSuchAlgorithmException e) {
         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
      } catch (CertificateException e) {
         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
      } catch (UnrecoverableKeyException e) {
         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
      }
      return result;
   }
}
