/* Command.java -- Abstract implementation of a keytool command handler
   Copyright (C) 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.classpath.tools.keytool;

import gnu.classpath.Configuration;
import gnu.classpath.SystemProperties;
import gnu.classpath.tools.common.CallbackUtil;
import gnu.classpath.tools.common.ProviderUtil;
import gnu.classpath.tools.common.SecurityProviderInfo;
import gnu.classpath.tools.getopt.Parser;
import gnu.java.security.OID;
import gnu.java.security.Registry;
import gnu.java.security.der.BitString;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
import gnu.java.security.der.DERWriter;
import gnu.java.security.hash.IMessageDigest;
import gnu.java.security.hash.MD5;
import gnu.java.security.hash.Sha160;
import gnu.java.security.util.Util;
import gnu.java.security.x509.X500DistinguishedName;
import gnu.javax.security.auth.callback.ConsoleCallbackHandler;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.net.URL;
import java.net.URLConnection;
import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
import java.security.Key;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.interfaces.DSAKey;
import java.security.interfaces.RSAKey;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.Logger;
import java.util.prefs.Preferences;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;

/**
 * A base class of the keytool command to facilitate implementation of concrete
 * keytool Handlers.
 */
abstract class Command
{
  // Fields and constants -----------------------------------------------------

  private static final Logger log = Logger.getLogger(Command.class.getName());
  /** Default value for the ALIAS argument. */
  private static final String DEFAULT_ALIAS = "mykey"; //$NON-NLS-1$
  /** Default algorithm for key-pair generation. */
  private static final String DEFAULT_KEY_ALGORITHM = "DSA"; //$NON-NLS-1$
  /** Default DSA digital signature algorithm to use with DSA keys. */
  private static final String DSA_SIGNATURE_ALGORITHM = "SHA1withDSA"; //$NON-NLS-1$
  /** Default RSA digital signature algorithm to use with RSA keys. */
  private static final String RSA_SIGNATURE_ALGORITHM = "MD5withRSA"; //$NON-NLS-1$
  /** Default validity (in days) of newly generated certificates. */
  private static final int DEFAULT_VALIDITY = 90;
  /** OID of SHA1withDSA signature algorithm as stated in RFC-2459. */
  protected static final OID SHA1_WITH_DSA = new OID("1.2.840.10040.4.3"); //$NON-NLS-1$
  /** OID of MD2withRSA signature algorithm as stated in RFC-2459. */
  private static final OID MD2_WITH_RSA = new OID("1.2.840.113549.1.1.2"); //$NON-NLS-1$
  /** OID of MD5withRSA signature algorithm as stated in RFC-2459. */
  private static final OID MD5_WITH_RSA = new OID("1.2.840.113549.1.1.4"); //$NON-NLS-1$
  /** OID of SHA1withRSA signature algorithm as stated in RFC-2459. */
  private static final OID SHA1_WITH_RSA = new OID("1.2.840.113549.1.1.5"); //$NON-NLS-1$
  /** Number of milliseconds in one day. */
  private static final long MILLIS_IN_A_DAY = 24 * 60 * 60 * 1000L;

  /** The Alias to use. */
  protected String alias;
  /** The password characters protecting a Key Entry. */
  protected char[] keyPasswordChars;
  /** A security provider to add. */
  protected Provider provider;
  /** The key store type. */
  protected String storeType;
  /** The password characters protecting the key store. */
  protected char[] storePasswordChars;
  /** The key store URL. */
  protected URL storeURL;
  /** The input stream from the key store URL. */
  protected InputStream storeStream;
  /** The key store instance to use. */
  protected KeyStore store;
  /** The output stream the concrete handler will use. */
  protected OutputStream outStream;
  /** Whether we are printing to System.out. */
  protected boolean systemOut;
  /** The key-pair generation algorithm instance to use. */
  protected KeyPairGenerator keyPairGenerator;
  /** The digital signature algorithm instance to use. */
  protected Signature signatureAlgorithm;
  /** Validity period, in number of days, to use when generating certificates. */
  protected int validityInDays;
  /** The input stream the concrete handler will use. */
  protected InputStream inStream;
  /** Whether verbose output is required or not. */
  protected boolean verbose;

  /** MD5 hash to use when generating certificate fingerprints. */
  private IMessageDigest md5 = new MD5();
  /** SHA1 hash to use when generating certificate fingerprints. */
  private IMessageDigest sha = new Sha160();
  /** The new position of a user-defined provider if it is not already installed. */
  private int providerNdx = -2;
  /** The callback handler to use when needing to interact with user. */
  private CallbackHandler handler;
  /** The shutdown hook. */
  private ShutdownHook shutdownThread;

  // Constructor(s) -----------------------------------------------------------

  protected Command()
  {
    super();
    shutdownThread = new ShutdownHook();
    Runtime.getRuntime().addShutdownHook(shutdownThread);
  }

  // Methods ------------------------------------------------------------------

  /**
   * A public method to allow using any keytool command handler programmatically
   * by using a JavaBeans style of parameter(s) initialization. The user is
   * assumed to have set individually the required options through their
   * respective setters before invoking this method.
   * <p>
   * If an exception is encountered during the processing of the command, this
   * implementation attempts to release any resources that may have been
   * allocated at the time the exception occurs, before re-throwing that
   * exception.
   * 
   * @throws Exception if an exception occurs during the processing of this
   *           command. For a more comprehensive list of exceptions that may
   *           occur, see the documentation of the {@link #setup()} and
   *           {@link #start()} methods.
   */
  public void doCommand() throws Exception
  {
    try
      {
        setup();
        start();
      }
    finally
      {
        teardown();
        if (shutdownThread != null)
          Runtime.getRuntime().removeShutdownHook(shutdownThread);
      }
  }

  /**
   * @param flag whether to use, or not, more verbose output while processing
   *          the command.
   */
  public void setVerbose(String flag)
  {
    this.verbose = Boolean.valueOf(flag).booleanValue();
  }

  // life-cycle methods -------------------------------------------------------

  /**
   * Given a potential sub-array of options for this concrete handler, starting
   * at position <code>startIndex + 1</code>, potentially followed by other
   * commands and their options, this method sets up this concrete command
   * handler with its own options and returns the index of the first unprocessed
   * argument in the array.
   * <p>
   * The general contract of this method is that it is invoked with the
   * <code>startIndex</code> argument pointing to the keyword argument that
   * uniquelly identifies the command itself; e.g. <code>-genkey</code> or
   * <code>-list</code>, etc...
   * 
   * @param args an array of options for this handler and possibly other
   *          commands and their options.
   * @return the remaining un-processed <code>args</code>.
   */
  String[] processArgs(String[] args)
  {
    if (Configuration.DEBUG)
      log.entering(this.getClass().getName(), "processArgs", args); //$NON-NLS-1$
    Parser cmdOptionsParser = getParser();
    String[] result = cmdOptionsParser.parse(args);
    if (Configuration.DEBUG)
      log.exiting(this.getClass().getName(), "processArgs", result); //$NON-NLS-1$
    return result;
  }

  /**
   * Initialize this concrete command handler for later invocation of the
   * {@link #start()} or {@link #doCommand()} methods.
   * <p>
   * Handlers usually initialize their local variables and resources within the
   * scope of this call.
   * 
   * @throws IOException if an I/O related exception, such as opening an input
   *           stream, occurs during the execution of this method.
   * @throws UnsupportedCallbackException if a requested callback handler
   *           implementation was not found, or was found but encountered an
   *           exception during its processing.
   * @throws ClassNotFoundException if a designated security provider class was
   *           not found.
   * @throws IllegalAccessException no 0-arguments constructor for the
   *           designated security provider class was found.
   * @throws InstantiationException the designated security provider class is
   *           not instantiable.
   * @throws KeyStoreException if an exception occurs during the instantiation
   *           of the KeyStore.
   * @throws CertificateException if a certificate related exception, such as
   *           expiry, occurs during the loading of the KeyStore.
   * @throws NoSuchAlgorithmException if no current security provider can
   *           provide a needed algorithm referenced by the KeyStore or one of
   *           its Key Entries or Certificates.
   */
  abstract void setup() throws Exception;

  /**
   * Do the real work this handler is supposed to do.
   * <p>
   * The code in this (abstract) class throws a <i>Not implemented yet</i>
   * runtime exception. Concrete implementations MUST override this method.
   * 
   * @throws CertificateException If no concrete implementation was found for a
   *           certificate Factory of a designated type. In this tool, the type
   *           is usually X.509 v1.
   * @throws KeyStoreException if a keys-store related exception occurs; e.g.
   *           the key store has not been initialized.
   * @throws IOException if an I/O related exception occurs during the process.
   * @throws SignatureException if a digital signature related exception occurs.
   * @throws InvalidKeyException if the genereated keys are invalid.
   * @throws UnrecoverableKeyException if the password used to unlock a key in
   *           the key store was invalid.
   * @throws NoSuchAlgorithmException if a concrete implementation of an
   *           algorithm used to store a Key Entry was not found at runtime.
   * @throws UnsupportedCallbackException if a requested callback handler
   *           implementation was not found, or was found but encountered an
   *           exception during its processing.
   */
  void start() throws Exception
  {
    throw new RuntimeException("Not implemented yet"); //$NON-NLS-1$
  }

  /**
   * Tear down the handler, releasing any resources which may have been
   * allocated at setup time.
   */
  void teardown()
  {
    if (Configuration.DEBUG)
      log.entering(this.getClass().getName(), "teardown"); //$NON-NLS-1$
    if (storeStream != null)
      try
        {
          storeStream.close();
        }
      catch (IOException ignored)
        {
          if (Configuration.DEBUG)
            log.fine("Exception while closing key store URL stream. Ignored: " //$NON-NLS-1$
                     + ignored);
        }

    if (outStream != null)
      {
        try
          {
            outStream.flush();
          }
        catch (IOException ignored)
          {
          }

        if (! systemOut)
          try
            {
              outStream.close();
            }
          catch (IOException ignored)
            {
            }
      }

    if (inStream != null)
      try
        {
          inStream.close();
        }
      catch (IOException ignored)
        {
        }

    if (providerNdx > 0)
      ProviderUtil.removeProvider(provider.getName());

    if (Configuration.DEBUG)
      log.exiting(this.getClass().getName(), "teardown"); //$NON-NLS-1$
  }

  // parameter setup and validation methods -----------------------------------

  /**
   * @return a {@link Parser} that knows how to parse the concrete command's
   *         options.
   */
  abstract Parser getParser();

  /**
   * Convenience method to setup the key store given its type, its password, its
   * location and portentially a specialized security provider.
   * <p>
   * Calls the method with the same name and 5 arguments passing
   * <code>false</code> to the first argument implying that no attempt to
   * create the keystore will be made if one was not found at the designated
   * location.
   * 
   * @param className the potentially null fully qualified class name of a
   *          security provider to add at runtime, if no installed provider is
   *          able to provide a key store implementation of the desired type.
   * @param type the potentially null type of the key store to request from the
   *          key store factory.
   * @param password the potentially null password protecting the key store.
   * @param url the URL of the key store.
   */
  protected void setKeyStoreParams(String className, String type,
                                   String password, String url)
      throws IOException, UnsupportedCallbackException, KeyStoreException,
      NoSuchAlgorithmException, CertificateException
  {
    setKeyStoreParams(false, className, type, password, url);
  }

  /**
   * Convenience method to setup the key store given its type, its password, its
   * location and portentially a specialized security provider.
   * 
   * @param createIfNotFound if <code>true</code> then create the keystore if
   *          it was not found; otherwise do not.
   * @param className the potentially null fully qualified class name of a
   *          security provider to add at runtime, if no installed provider is
   *          able to provide a key store implementation of the desired type.
   * @param type the potentially null type of the key store to request from the
   *          key store factory.
   * @param password the potentially null password protecting the key store.
   * @param url the URL of the key store.
   */
  protected void setKeyStoreParams(boolean createIfNotFound, String className,
                                   String type, String password, String url)
      throws IOException, UnsupportedCallbackException, KeyStoreException,
      NoSuchAlgorithmException, CertificateException
  {
    setProviderClassNameParam(className);
    setKeystoreTypeParam(type);
    setKeystoreURLParam(createIfNotFound, url, password);
  }

  /**
   * Set a security provider class name to (install and) use for key store
   * related operations.
   * 
   * @param className the possibly null, fully qualified class name of a
   *          security provider to add, if it is not already installed, to the
   *          set of available providers.
   */
  private void setProviderClassNameParam(String className)
  {
    if (Configuration.DEBUG)
      log.fine("setProviderClassNameParam(" + className + ")"); //$NON-NLS-1$ //$NON-NLS-2$
    if (className != null && className.trim().length() > 0)
      {
        className = className.trim();
        SecurityProviderInfo spi = ProviderUtil.addProvider(className);
        provider = spi.getProvider();
        if (provider == null)
          {
            if (Configuration.DEBUG)
              log.fine("Was unable to add provider from class " + className);
          }
        providerNdx = spi.getPosition();
      }
  }

  /**
   * Set the type of key store to initialize, load and use.
   * 
   * @param type the possibly null type of the key store. if this argument is
   *          <code>null</code>, or is an empty string, then this method sets
   *          the type of the key store to be the default value returned from
   *          the invocation of the {@link KeyStore#getDefaultType()} method.
   *          For GNU Classpath this is <i>gkr</i> which stands for the "Gnu
   *          KeyRing" specifications.
   */
  private void setKeystoreTypeParam(String type)
  {
    if (Configuration.DEBUG)
      log.fine("setKeystoreTypeParam(" + type + ")"); //$NON-NLS-1$ //$NON-NLS-2$
    if (type == null || type.trim().length() == 0)
      storeType = KeyStore.getDefaultType();
    else
      storeType = type.trim();
  }

  /**
   * Set the key password given a command line option argument. If no value was
   * present on the command line then prompt the user to provide one.
   * 
   * @param password a possibly null key password gleaned from the command line.
   * @throws IOException if an I/O related exception occurs.
   * @throws UnsupportedCallbackException if no concrete implementation of a
   *         password callback was found at runtime.
   */
  protected void setKeyPasswordParam(String password) throws IOException,
      UnsupportedCallbackException
  {
    setKeyPasswordNoPrompt(password);
    if (keyPasswordChars == null)
      setKeyPasswordParam();
  }

  /**
   * Set the Alias to use when associating Key Entries and Trusted Certificates
   * in the current key store.
   * 
   * @param name the possibly null alias to use. If this arfument is
   *          <code>null</code>, then a default value of <code>mykey</code>
   *          will be used instead.
   */
  protected void setAliasParam(String name)
  {
    alias = name == null ? DEFAULT_ALIAS : name.trim();
  }

  /**
   * Set the key password given a command line option argument.
   * 
   * @param password a possibly null key password gleaned from the command line.
   */
  protected void setKeyPasswordNoPrompt(String password)
  {
    if (password != null)
      keyPasswordChars = password.toCharArray();
  }

  /**
   * Prompt the user to provide a password to protect a Key Entry in the key
   * store.
   * 
   * @throws IOException if an I/O related exception occurs.
   * @throws UnsupportedCallbackException if no concrete implementation of a
   *           password callback was found at runtime.
   * @throws SecurityException if no password is available, even after prompting
   *           the user.
   */
  private void setKeyPasswordParam() throws IOException,
      UnsupportedCallbackException
  {
    String prompt = Messages.getFormattedString("Command.21", alias); //$NON-NLS-1$
    PasswordCallback pcb = new PasswordCallback(prompt, false);
    getCallbackHandler().handle(new Callback[] { pcb });
    keyPasswordChars = pcb.getPassword();
    pcb.clearPassword();
    if (keyPasswordChars == null)
      throw new SecurityException(Messages.getString("Command.23")); //$NON-NLS-1$
  }

  private void setKeystorePasswordParam(String password) throws IOException,
      UnsupportedCallbackException
  {
    if (password != null)
      storePasswordChars = password.toCharArray();
    else // ask the user to provide one
      {
        String prompt = Messages.getString("Command.24"); //$NON-NLS-1$
        PasswordCallback pcb = new PasswordCallback(prompt, false);
        getCallbackHandler().handle(new Callback[] { pcb });
        storePasswordChars = pcb.getPassword();
        pcb.clearPassword();
      }
  }

  /**
   * Set the key store URL to use.
   * 
   * @param createIfNotFound when <code>true</code> an attempt to create a
   *          keystore at the designated location will be made. If
   *          <code>false</code> then no file creation is carried out, which
   *          may cause an exception to be thrown later.
   * @param url the full, or partial, URL to the keystore location.
   * @param password an eventually null string to use when loading the keystore.
   * @throws IOException
   * @throws KeyStoreException
   * @throws UnsupportedCallbackException
   * @throws NoSuchAlgorithmException
   * @throws CertificateException
   */
  private void setKeystoreURLParam(boolean createIfNotFound, String url,
                                     String password) throws IOException,
      KeyStoreException, UnsupportedCallbackException, NoSuchAlgorithmException,
      CertificateException
  {
    if (Configuration.DEBUG)
      log.fine("setKeystoreURLParam(" + url + ")"); //$NON-NLS-1$ //$NON-NLS-2$
    if (url == null || url.trim().length() == 0)
      {
        String userHome = SystemProperties.getProperty("user.home"); //$NON-NLS-1$
        if (userHome == null || userHome.trim().length() == 0)
          throw new InvalidParameterException(Messages.getString("Command.36")); //$NON-NLS-1$

        url = userHome.trim() + "/.keystore"; //$NON-NLS-1$
        // if it does not exist create it if required
        if (createIfNotFound)
          new File(url).createNewFile();
        url = "file:" + url; //$NON-NLS-1$
      }
    else
      {
        url = url.trim();
        if (url.indexOf(":") == -1) // if it does not exist create it //$NON-NLS-1$
          {
            if (createIfNotFound)
              new File(url).createNewFile();
          }
        url = "file:" + url; //$NON-NLS-1$
      }

    boolean newKeyStore = false;
    storeURL = new URL(url);
    storeStream = storeURL.openStream();
    if (storeStream.available() == 0)
      {
        if (Configuration.DEBUG)
          log.fine("Store is empty. Will use <null> when loading, to create it"); //$NON-NLS-1$
        newKeyStore = true;
      }

    try
      {
        store = KeyStore.getInstance(storeType);
      }
    catch (KeyStoreException x)
      {
        if (provider != null)
          throw x;

        if (Configuration.DEBUG)
          log.fine("Exception while getting key store with default provider(s)." //$NON-NLS-1$
                   + " Will prompt user for another provider and continue"); //$NON-NLS-1$
        String prompt = Messages.getString("Command.40"); //$NON-NLS-1$
        NameCallback ncb = new NameCallback(prompt);
        getCallbackHandler().handle(new Callback[] { ncb });
        String className = ncb.getName();
        setProviderClassNameParam(className); // we may have a Provider
        if (provider == null)
          {
            x.fillInStackTrace();
            throw x;
          }
        // try again
        store = KeyStore.getInstance(storeType, provider);
      }

    setKeystorePasswordParam(password);

    // now we have a KeyStore instance. load it
    // KeyStore public API claims: "...In order to create an empty keystore,
    // you pass null as the InputStream argument to the load method.
    if (newKeyStore)
      store.load(null, storePasswordChars);
    else
      store.load(storeStream, storePasswordChars);

    // close the stream
    try
    {
      storeStream.close();
      storeStream = null;
    }
    catch (IOException x)
    {
      if (Configuration.DEBUG)
        log.fine("Exception while closing the key store input stream: " + x //$NON-NLS-1$
                 + ". Ignore"); //$NON-NLS-1$
    }
  }

  protected void setOutputStreamParam(String fileName) throws SecurityException,
      IOException
  {
    if (fileName == null || fileName.trim().length() == 0)
      {
        outStream = System.out;
        systemOut = true;
      }
    else
      {
        fileName = fileName.trim();
        File outFile = new File(fileName);
        if (! outFile.exists())
          {
            boolean ok = outFile.createNewFile();
            if (!ok)
              throw new InvalidParameterException(Messages.getFormattedString("Command.19", //$NON-NLS-1$
                                                                              fileName));
          }
        else
          {
            if (! outFile.isFile())
              throw new InvalidParameterException(Messages.getFormattedString("Command.42", //$NON-NLS-1$
                                                                              fileName));
            if (! outFile.canWrite())
              throw new InvalidParameterException(Messages.getFormattedString("Command.44", //$NON-NLS-1$
                                                                              fileName));
          }
        outStream = new FileOutputStream(outFile);
      }
  }

  protected void setInputStreamParam(String fileName)
      throws FileNotFoundException
  {
    if (fileName == null || fileName.trim().length() == 0)
      inStream = System.in;
    else
      {
        fileName = fileName.trim();
        File inFile = new File(fileName);
        if (! (inFile.exists() && inFile.isFile() && inFile.canRead()))
          throw new InvalidParameterException(Messages.getFormattedString("Command.46", //$NON-NLS-1$
                                                                          fileName));
        inStream = new FileInputStream(inFile);
      }
  }

  /**
   * Set both the key-pair generation algorithm, and the digital signature
   * algorithm instances to use when generating new entries.
   * 
   * @param kpAlg the possibly null name of a key-pair generator algorithm.
   *          if this argument is <code>null</code> or is an empty string, the
   *          "DSS" algorithm will be used.
   * @param sigAlg the possibly null name of a digital signature algorithm.
   *          If this argument is <code>null</code> or is an empty string, this
   *          method uses the "SHA1withDSA" (Digital Signature Standard, a.k.a.
   *          DSA, with the Secure Hash Algorithm function) as the default
   *          algorithm if, and only if, the key-pair generation algorithm ends
   *          up being "DSS"; otherwise, if the key-pair generation algorithm
   *          was "RSA", then the "MD5withRSA" signature algorithm will be used.
   *          If the key-pair generation algorithm is neither "DSS" (or its
   *          alias "DSA"), nor is it "RSA", then an exception is thrown.
   * @throws NoSuchAlgorithmException if no concrete implementation of the
   *           designated algorithm is available.
   */
  protected void setAlgorithmParams(String kpAlg, String sigAlg)
      throws NoSuchAlgorithmException
  {
    if (kpAlg == null || kpAlg.trim().length() == 0)
      kpAlg = DEFAULT_KEY_ALGORITHM;
    else
      kpAlg = kpAlg.trim().toLowerCase();

    keyPairGenerator = KeyPairGenerator.getInstance(kpAlg);

    if (sigAlg == null || sigAlg.trim().length() == 0)
      if (kpAlg.equalsIgnoreCase(Registry.DSS_KPG)
          || kpAlg.equalsIgnoreCase(Registry.DSA_KPG))
        sigAlg = DSA_SIGNATURE_ALGORITHM;
      else if (kpAlg.equalsIgnoreCase(Registry.RSA_KPG))
        sigAlg = RSA_SIGNATURE_ALGORITHM;
      else
        throw new IllegalArgumentException(
            Messages.getFormattedString("Command.20", //$NON-NLS-1$
                                        new String[] { sigAlg, kpAlg }));
    else
      sigAlg = sigAlg.trim().toLowerCase();

    signatureAlgorithm = Signature.getInstance(sigAlg);
  }

  /**
   * Set the signature algorithm to use when digitally signing private keys,
   * certificates, etc...
   * <p>
   * If the designated algorithm name is <code>null</code> or is an empty
   * string, this method checks the private key (the second argument) and based
   * on its type decides which algorithm to use. The keytool public
   * specification states that if the private key is a DSA key, then the
   * signature algorithm will be <code>SHA1withDSA</code>, otherwise if it is
   * an RSA private key, then the signature algorithm will be
   * <code>MD5withRSA</code>. If the private key is neither a private DSA nor
   * a private RSA key, then this method throws an
   * {@link IllegalArgumentException}.
   * 
   * @param algorithm the possibly null name of a digital signature algorithm.
   * @param privateKey an instance of a private key to use as a fal-back option
   *          when <code>algorithm</code> is invalid.
   * @throws NoSuchAlgorithmException if no concrete implementation of the
   *           designated, or default, signature algorithm is available.
   */
  protected void setSignatureAlgorithmParam(String algorithm, Key privateKey)
      throws NoSuchAlgorithmException
  {
    if (algorithm == null || algorithm.trim().length() == 0)
      if (privateKey instanceof DSAKey)
        algorithm = DSA_SIGNATURE_ALGORITHM;
      else if (privateKey instanceof RSAKey)
        algorithm = RSA_SIGNATURE_ALGORITHM;
      else
        throw new InvalidParameterException(Messages.getString("Command.48")); //$NON-NLS-1$
    else
      algorithm = algorithm.trim();

    signatureAlgorithm = Signature.getInstance(algorithm);
  }

  /**
   * Set the validity period, in number of days, to use when issuing new
   * certificates.
   * 
   * @param days the number of days, as a string, the generated certificate will
   *          be valid for, starting from today's date. if this argument is
   *          <code>null</code>, a default value of <code>90</code> days
   *          will be used.
   * @throws NumberFormatException if the designated string is not a decimal
   *           integer.
   * @throws InvalidParameterException if the integer value of the non-null
   *           string is not greater than zero.
   */
  protected void setValidityParam(String days)
  {
    if (days == null || days.trim().length() == 0)
      validityInDays = DEFAULT_VALIDITY;
    else
      {
        days = days.trim();
        validityInDays = Integer.parseInt(days);
        if (validityInDays < 1)
          throw new InvalidParameterException(Messages.getString("Command.51")); //$NON-NLS-1$
      }
  }

  /**
   * RFC-2459 (http://rfc.net/rfc2459.html) fully describes the structure and
   * semantics of X.509 certificates. The ASN.1 structures below are gleaned
   * from that reference.
   * 
   * <pre>
   *  Certificate ::= SEQUENCE {
   *    tbsCertificate      TBSCertificate,
   *    signatureAlgorithm  AlgorithmIdentifier,
   *    signatureValue      BIT STRING
   *  }
   *  
   *  TBSCertificate ::= SEQUENCE {
   *    version           [0] EXPLICIT Version DEFAULT v1,
   *    serialNumber          CertificateSerialNumber,
   *    signature             AlgorithmIdentifier,
   *    issuer                Name,
   *    validity              Validity,
   *    subject               Name,
   *    subjectPublicKeyInfo  SubjectPublicKeyInfo
   *  }
   *  
   *  Version ::= INTEGER { v1(0), v2(1), v3(2) }
   *  
   *  CertificateSerialNumber ::= INTEGER
   *  
   *  Validity ::= SEQUENCE {
   *    notBefore  Time,
   *    notAfter   Time
   *  }
   *  
   *  Time ::= CHOICE {
   *    utcTime      UTCTime,
   *    generalTime  GeneralizedTime
   *  }
   *  
   *  UniqueIdentifier ::= BIT STRING
   *  
   *  SubjectPublicKeyInfo ::= SEQUENCE {
   *    algorithm         AlgorithmIdentifier,
   *    subjectPublicKey  BIT STRING
   *  }
   * </pre>
   * 
   * @param distinguishedName the X.500 Distinguished Name to use as both the
   *          Issuer and Subject of the self-signed certificate to generate.
   * @param publicKey the public key of the issuer/subject.
   * @param privateKey the private key of the issuer/signer.
   * @return the DER encoded form of a self-signed X.509 v1 certificate.
   * @throws IOException If an I/O related exception occurs during the process.
   * @throws SignatureException If a digital signature related exception occurs.
   * @throws InvalidKeyException if the designated private key is invalid.
   * @throws InvalidParameterException if the concrete signature algorithm does
   *           not know its name, no OID is known/supported for that name, or we
   *           were unable to match the name to a known string for which we can
   *           use a standard OID.
   */
  protected byte[] getSelfSignedCertificate(X500DistinguishedName distinguishedName,
                                            PublicKey publicKey,
                                            PrivateKey privateKey)
      throws IOException, SignatureException, InvalidKeyException
  {
    if (Configuration.DEBUG)
      log.entering(this.getClass().getName(), "getSelfSignedCertificate", //$NON-NLS-1$
                   new Object[] { distinguishedName, publicKey, privateKey });
    byte[] versionBytes = new DERValue(DER.INTEGER, BigInteger.ZERO).getEncoded();
    DERValue derVersion = new DERValue(DER.CONSTRUCTED | DER.CONTEXT | 0,
                                       versionBytes.length, versionBytes, null);

    // NOTE (rsn): the next 3 lines should be atomic but they're not.
    Preferences prefs = Preferences.systemNodeForPackage(this.getClass());
    int lastSerialNumber = prefs.getInt(Main.LAST_SERIAL_NUMBER, 0) + 1;
    prefs.putInt(Main.LAST_SERIAL_NUMBER, lastSerialNumber);
    DERValue derSerialNumber = new DERValue(DER.INTEGER,
                                            BigInteger.valueOf(lastSerialNumber));

    OID signatureID = getSignatureAlgorithmOID();
    DERValue derSignatureID = new DERValue(DER.OBJECT_IDENTIFIER, signatureID);
    ArrayList signature = new ArrayList(1);
    signature.add(derSignatureID);
    // rfc-2459 states the following:
    //
    // for the DSA signature:
    // ...Where the id-dsa-with-sha1 algorithm identifier appears as the
    // algorithm field in an AlgorithmIdentifier, the encoding shall omit
    // the parameters field.  That is, the AlgorithmIdentifier shall be a
    // SEQUENCE of one component - the OBJECT IDENTIFIER id-dsa-with-sha1.
    // 
    // for RSA signatures:
    // ...When any of these three OIDs (i.e. xxxWithRSAEncryption) appears
    // within the ASN.1 type AlgorithmIdentifier, the parameters component of
    // that type shall be the ASN.1 type NULL.
    if (! signatureID.equals(SHA1_WITH_DSA))
      signature.add(new DERValue(DER.NULL, null));

    DERValue derSignature = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
                                         signature);

    DERValue derIssuer = new DERReader(distinguishedName.getDer()).read();

    long notBefore = System.currentTimeMillis();
    long notAfter = notBefore + validityInDays * MILLIS_IN_A_DAY;
    
    ArrayList validity = new ArrayList(2);
    validity.add(new DERValue(DER.UTC_TIME, new Date(notBefore)));
    validity.add(new DERValue(DER.UTC_TIME, new Date(notAfter)));
    DERValue derValidity = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
                                        validity);

    // for a self-signed certificate subject and issuer are identical
    DERValue derSubject = derIssuer;

    DERValue derSubjectPublicKeyInfo = new DERReader(publicKey.getEncoded()).read();

    ArrayList tbsCertificate = new ArrayList(7);
    tbsCertificate.add(derVersion);
    tbsCertificate.add(derSerialNumber);
    tbsCertificate.add(derSignature);
    tbsCertificate.add(derIssuer);
    tbsCertificate.add(derValidity);
    tbsCertificate.add(derSubject);
    tbsCertificate.add(derSubjectPublicKeyInfo);
    DERValue derTBSCertificate = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
                                              tbsCertificate);

    // The 'signature' field MUST contain the same algorithm identifier as the
    // 'signatureAlgorithm' field in the sequence Certificate.
    DERValue derSignatureAlgorithm = derSignature;

    signatureAlgorithm.initSign(privateKey);
    signatureAlgorithm.update(derTBSCertificate.getEncoded());
    byte[] sigBytes = signatureAlgorithm.sign();
    DERValue derSignatureValue = new DERValue(DER.BIT_STRING,
                                              new BitString(sigBytes));

    ArrayList certificate = new ArrayList(3);
    certificate.add(derTBSCertificate);
    certificate.add(derSignatureAlgorithm);
    certificate.add(derSignatureValue);
    DERValue derCertificate = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
                                           certificate);

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    DERWriter.write(baos, derCertificate);
    byte[] result = baos.toByteArray();
    if (Configuration.DEBUG)
      log.exiting(this.getClass().getName(), "getSelfSignedCertificate"); //$NON-NLS-1$
    return result;
  }

  /**
   * This method attempts to find, and return, an OID representing the digital
   * signature algorithm used to sign the certificate. The OIDs returned are
   * those described in RFC-2459. They are listed here for the sake of
   * completness.
   * 
   * <pre>
   *  id-dsa-with-sha1 OBJECT IDENTIFIER ::= {
   *    iso(1) member-body(2) us(840) x9-57 (10040) x9cm(4) 3
   *  }
   *  
   *  md2WithRSAEncryption OBJECT IDENTIFIER ::= {
   *    iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1) 2
   *  }
   *  
   *  md5WithRSAEncryption OBJECT IDENTIFIER ::= {
   *    iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1) 4
   *  }
   *  
   *  sha-1WithRSAEncryption OBJECT IDENTIFIER ::= {
   *    iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1) 5
   *  }
   * </pre>
   * 
   * <b>IMPORTANT</b>: This method checks the signature algorithm name against
   * (a) The GNU algorithm implementation's name, and (b) publicly referenced
   * names of the same algorithm. In other words this search is not
   * comprehensive and may fail for uncommon names of the same algorithms.
   * 
   * @return the OID of the signature algorithm in use.
   * @throws InvalidParameterException if the concrete signature algorithm does
   *           not know its name, no OID is known/supported for that name, or we
   *           were unable to match the name to a known string for which we can
   *           return an OID.
   */
  protected OID getSignatureAlgorithmOID()
  {
    String algorithm = signatureAlgorithm.getAlgorithm();
    // if we already have a non-null signature then the name was valid.  the
    // only case where algorithm is invalid would be if the implementation is
    // flawed.  check anyway
    if (algorithm == null || algorithm.trim().length() == 0)
      throw new InvalidParameterException(Messages.getString("Command.52")); //$NON-NLS-1$

    algorithm = algorithm.trim();
    if (algorithm.equalsIgnoreCase(Registry.DSS_SIG)
        || algorithm.equalsIgnoreCase("SHA1withDSA")) //$NON-NLS-1$
      return SHA1_WITH_DSA;
    
    if (algorithm.equalsIgnoreCase(Registry.RSA_PKCS1_V1_5_SIG + "-" //$NON-NLS-1$
                                   + Registry.MD2_HASH)
        || algorithm.equalsIgnoreCase("MD2withRSA")) //$NON-NLS-1$
      return MD2_WITH_RSA;

    if (algorithm.equalsIgnoreCase(Registry.RSA_PKCS1_V1_5_SIG + "-" //$NON-NLS-1$
                                   + Registry.MD5_HASH)
        || algorithm.equalsIgnoreCase("MD5withRSA") //$NON-NLS-1$
        || algorithm.equalsIgnoreCase("rsa")) //$NON-NLS-1$
      return MD5_WITH_RSA;

    if (algorithm.equalsIgnoreCase(Registry.RSA_PKCS1_V1_5_SIG + "-" //$NON-NLS-1$
                                   + Registry.SHA160_HASH)
        || algorithm.equalsIgnoreCase("SHA1withRSA")) //$NON-NLS-1$
      return SHA1_WITH_RSA;

    throw new InvalidParameterException(Messages.getFormattedString("Command.60", //$NON-NLS-1$
                                                                    algorithm));
  }

  /**
   * Saves the key store using the designated password. This operation is called
   * by handlers if/when the key store password has changed, or amendements have
   * been made to the contents of the store; e.g. addition of a new Key Entry or
   * a Trusted Certificate.
   * 
   * @param password the password protecting the key store.
   * @throws IOException if an I/O related exception occurs during the process.
   * @throws CertificateException if any of the certificates in the current key
   *           store could not be persisted.
   * @throws NoSuchAlgorithmException if a required data integrity algorithm
   *           implementation was not found.
   * @throws KeyStoreException if the key store has not been loaded previously.
   */
  protected void saveKeyStore(char[] password) throws IOException,
      KeyStoreException, NoSuchAlgorithmException, CertificateException
  {
    if (Configuration.DEBUG)
      log.entering(this.getClass().getName(), "saveKeyStore"); //$NON-NLS-1$
    URLConnection con = storeURL.openConnection();
    con.setDoOutput(true);
    con.setUseCaches(false);
    OutputStream out = con.getOutputStream();
    if (verbose)
      System.out.println(Messages.getFormattedString("Command.63", storeURL.getPath())); //$NON-NLS-1$

    store.store(out, password);
    out.flush();
    out.close();
    if (Configuration.DEBUG)
      log.exiting(this.getClass().getName(), "saveKeyStore"); //$NON-NLS-1$
  }

  /**
   * Convenience method. Calls the method with the same name passing it the
   * same password characters used to initially load the key-store. 
   * 
   * @throws IOException if an I/O related exception occurs during the process.
   * @throws KeyStoreException if the key store has not been loaded previously.
   * @throws NoSuchAlgorithmException if a required data integrity algorithm
   *           implementation was not found.
   * @throws CertificateException if any of the certificates in the current key
   *           store could not be persisted.
   */
  protected void saveKeyStore() throws IOException, KeyStoreException,
      NoSuchAlgorithmException, CertificateException
  {
    saveKeyStore(storePasswordChars);
  }

  /**
   * Prints a human-readable form of the designated certificate to a designated
   * {@link PrintWriter}.
   * 
   * @param certificate the certificate to process.
   * @param writer where to print it.
   * @throws CertificateEncodingException if an exception occurs while obtaining
   *           the DER encoded form <code>certificate</code>.
   */
  protected void printVerbose(Certificate certificate, PrintWriter writer)
      throws CertificateEncodingException
  {
    X509Certificate x509 = (X509Certificate) certificate;
    writer.println(Messages.getFormattedString("Command.66", x509.getSubjectDN())); //$NON-NLS-1$
    writer.println(Messages.getFormattedString("Command.67", x509.getIssuerDN())); //$NON-NLS-1$
    writer.println(Messages.getFormattedString("Command.68", x509.getSerialNumber())); //$NON-NLS-1$
    writer.println(Messages.getFormattedString("Command.69", x509.getNotBefore())); //$NON-NLS-1$
    writer.println(Messages.getFormattedString("Command.70", x509.getNotAfter())); //$NON-NLS-1$
    writer.println(Messages.getString("Command.71")); //$NON-NLS-1$
    byte[] derBytes = certificate.getEncoded();
    writer.println(Messages.getFormattedString("Command.72", digest(md5, derBytes))); //$NON-NLS-1$
    writer.println(Messages.getFormattedString("Command.73", digest(sha, derBytes))); //$NON-NLS-1$
  }

  /**
   * Convenience method. Prints a human-readable form of the designated
   * certificate to <code>System.out</code>.
   * 
   * @param certificate the certificate to process.
   * @throws CertificateEncodingException if an exception occurs while obtaining
   *           the DER encoded form <code>certificate</code>.
   */
  protected void printVerbose(Certificate certificate)
      throws CertificateEncodingException
  {
    printVerbose(certificate, new PrintWriter(System.out, true));
  }

  /**
   * Digest the designated contents with MD5 and return a string representation
   * suitable for use as a fingerprint; i.e. sequence of hexadecimal pairs of
   * characters separated by a colon.
   * 
   * @param contents the non-null contents to digest.
   * @return a sequence of hexadecimal pairs of characters separated by colons.
   */
  protected String digestWithMD5(byte[] contents)
  {
    return digest(md5, contents);
  }

  private String digest(IMessageDigest hash, byte[] encoded)
  {
    hash.update(encoded);
    byte[] b = hash.digest();
    StringBuilder sb = new StringBuilder().append(Util.toString(b, 0, 1));
    for (int i = 1; i < b.length; i++)
      sb.append(":").append(Util.toString(b, i, 1)); //$NON-NLS-1$

    String result = sb.toString();
    return result;
  }

  /**
   * Ensure that the currently set Alias is contained in the currently set key
   * store; otherwise throw an exception.
   * 
   * @throws KeyStoreException if the keystore has not been loaded.
   * @throws IllegalArgumentException if the currently set alias is not known to
   *           the currently set key store.
   */
  protected void ensureStoreContainsAlias() throws KeyStoreException
  {
    if (! store.containsAlias(alias))
      throw new IllegalArgumentException(Messages.getFormattedString("Command.75", //$NON-NLS-1$
                                                                     alias));
  }

  /**
   * Ensure that the currently set Alias is associated with a Key Entry in the
   * currently set key store; otherwise throw an exception.
   * 
   * @throws KeyStoreException if the keystore has not been loaded.
   * @throws SecurityException if the currently set alias is not a Key Entry in
   *           the currently set key store.
   */
  protected void ensureAliasIsKeyEntry() throws KeyStoreException
  {
    if (! store.isKeyEntry(alias))
      throw new SecurityException(Messages.getFormattedString("Command.77", //$NON-NLS-1$
                                                              alias));
  }

  protected Key getAliasPrivateKey() throws KeyStoreException,
      NoSuchAlgorithmException, IOException, UnsupportedCallbackException,
      UnrecoverableKeyException
  {
    ensureAliasIsKeyEntry();
    Key result;
    if (keyPasswordChars == null)
      try
        {
          result = store.getKey(alias, storePasswordChars);
          // it worked. assign to keyPasswordChars for later use
          keyPasswordChars = storePasswordChars;
        }
      catch (UnrecoverableKeyException x)
        {
          // prompt the user to provide one
          setKeyPasswordParam();
          result = store.getKey(alias, keyPasswordChars);
        }
    else
      result = store.getKey(alias, keyPasswordChars);

    return result;
  }

  /**
   * Return a CallbackHandler which uses the Console (System.in and System.out)
   * for interacting with the user.
   * <p>
   * This method first finds all currently installed security providers capable
   * of providing such service and then in turn attempts to instantiate the
   * handler from those providers. As soon as one provider returns a non-null
   * instance of the callback handler, the search stops and that instance is
   * set to be used from now on.
   * <p>
   * If no installed providers were found, this method falls back on the GNU
   * provider, by-passing the Security search mechanism. The default console
   * callback handler implementation is {@link ConsoleCallbackHandler}.
   * 
   * @return a console-based {@link CallbackHandler}.
   */
  protected CallbackHandler getCallbackHandler()
  {
    if (handler == null)
      handler = CallbackUtil.getConsoleHandler();

    return handler;
  }

  // Inner class(es) ==========================================================

  private class ShutdownHook
      extends Thread
  {
    public void run()
    {
      teardown();
    }
  }
}
