/* GenKeyCmd.java -- The genkey command handler of the keytool
   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.tools.getopt.ClasspathToolParser;
import gnu.classpath.tools.getopt.Option;
import gnu.classpath.tools.getopt.OptionException;
import gnu.classpath.tools.getopt.OptionGroup;
import gnu.classpath.tools.getopt.Parser;
import gnu.java.security.util.Util;
import gnu.java.security.x509.X500DistinguishedName;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.logging.Logger;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.TextInputCallback;
import javax.security.auth.callback.TextOutputCallback;
import javax.security.auth.callback.UnsupportedCallbackException;

/**
 * The <b>-genkey</b> keytool command handler is used to generate a key pair (a
 * public, and associated private keys). It then generates a self-signed X509 v1
 * certificate (authenticating the public key) and stores this certificate and
 * the private key in the key store associating both to a designated alias.
 * <p>
 * Possible options for this command are:
 * <p>
 * <dl>
 *      <dt>-alias ALIAS</dt>
 *      <dd>Every entry, be it a <i>Key Entry</i> or a <i>Trusted
 *      Certificate</i>, in a key store is uniquely identified by a user-defined
 *      <i>Alias</i> string. Use this option to specify the <i>Alias</i> to use
 *      when referring to an entry in the key store. Unless specified otherwise,
 *      a default value of <code>mykey</code> shall be used when this option is
 *      omitted from the command line.
 *      <p></dd>
 *      
 *      <dt>-keyalg ALGORITHM</dt>
 *      <dd>Use this option to specify the canonical name of the key-pair
 *      generation algorithm. The default value for this option is
 *      <code>DSS</code> (a synonym for the Digital Signature Algorithm also
 *      known as <code>DSA</code>).
 *      <p></dd>
 *      
 *      <dt>-keysize KEY_SIZE</dt>
 *      <dd>Use this option to specify the number of bits of the shared modulus
 *      (for both the public and private keys) to use when generating new keys.
 *      A default value of <code>1024</code> will be used if this option is
 *      omitted from the command line.
 *      <p></dd>
 *      
 *      <dt>-sigalg ALGORITHM</dt>
 *      <dd>The canonical name of the digital signature algorithm to use for
 *      signing certificates. If this option is omitted, a default value will be
 *      chosen based on the type of the key-pair; i.e. the algorithm that ends
 *      up being used by the <code>-keyalg</code> option. If the key-pair
 *      generation algorithm is <code>DSA</code>, the value for the signature
 *      algorithm will be <code>SHA1withDSA</code>. If on the other hand the
 *      key-pair generation algorithm is <code>RSA</code>, then the tool will
 *      use <code>MD5withRSA</code> as the signature algorithm.
 *      <p></dd>
 *      
 *      <dt>-dname NAME</dt>
 *      <dd>This a mandatory value for this command. If this option is omitted
 *      the tool will prompt you to enter a <i>Distinguished Name</i> to use as
 *      both the <i>Owner</i> and <i>Issuer</i> of the generated self-signed
 *      certificate.
 *      <p>
 *      The syntax of a valid value for this option MUST follow RFC-2253
 *      specifications. Namely the following components (with their accepted
 *      meaning) will be recognized. Note that the component name is case-
 *      insensitive:
 *      <dl>
 *              <dt>CN</dt>
 *              <dd>The Common Name; e.g. "host.domain.com"</dd>
 *              
 *              <dt>OU</dt>
 *              <dd>The Organizational Unit; e.g. "IT Department"</dd>
 *              
 *              <dt>O</dt>
 *              <dd>The Organization Name; e.g. "The Sample Company"</dd>
 *              
 *              <dt>L</dt>
 *              <dd>The Locality Name; e.g. "Sydney"</dd>
 *              
 *              <dt>ST</dt>
 *              <dd>The State Name; e.g. "New South Wales"</dd>
 *              
 *              <dt>C</dt>
 *              <dd>The 2-letter Country identifier; e.g. "AU"</dd>
 *      </dl>
 *      <p>
 *      When specified with a <code>-dname</code> option, each pair of component
 *      / value will be separated from the other with a comma. Each component
 *      and value pair MUST be separated by an equal sign. For example, the
 *      following is a valid DN value:
 *      <pre>
 *        CN=host.domain.com, O=The Sample Company, L=Sydney, ST=NSW, C=AU
 *      </pre>
 *      If this option is omitted, the tool will prompt you to enter the
 *      information through the console.
 *      <p></dd>
 *      
 *      <dt>-keypass PASSWORD</dt>
 *      <dd>Use this option to specify the password which the tool will use to
 *      protect the newly created Key Entry.
 *      <p>
 *      If this option is omitted, you will be prompted to provide a password.
 *      <p></dd>
 *      
 *      <dt>-validity DAY_COUNT</dt>
 *      
 *      <dt>-storetype STORE_TYPE</dt>
 *      <dd>Use this option to specify the type of the key store to use. The
 *      default value, if this option is omitted, is that of the property
 *      <code>keystore.type</code> in the security properties file, which is
 *      obtained by invoking the {@link java.security.KeyStore#getDefaultType()}
 *      static method.
 *      <p></dd>
 *      
 *      <dt>-keystore URL</dt>
 *      <dd>Use this option to specify the location of the key store to use.
 *      The default value is a file {@link java.net.URL} referencing the file
 *      named <code>.keystore</code> located in the path returned by the call to
 *      {@link java.lang.System#getProperty(String)} using <code>user.home</code>
 *      as argument.
 *      <p>
 *      If a URL was specified, but was found to be malformed --e.g. missing
 *      protocol element-- the tool will attempt to use the URL value as a file-
 *      name (with absolute or relative path-name) of a key store --as if the
 *      protocol was <code>file:</code>.
 *      <p></dd>
 *      
 *      <dt>-storepass PASSWORD</dt>
 *      <dd>Use this option to specify the password protecting the key store. If
 *      this option is omitted from the command line, you will be prompted to
 *      provide a password.
 *      <p></dd>
 *      
 *      <dt>-provider PROVIDER_CLASS_NAME</dt>
 *      <dd>A fully qualified class name of a Security Provider to add to the
 *      current list of Security Providers already installed in the JVM in-use.
 *      If a provider class is specified with this option, and was successfully
 *      added to the runtime --i.e. it was not already installed-- then the tool
 *      will attempt to removed this Security Provider before exiting.
 *      <p></dd>
 *      
 *      <dt>-v</dt>
 *      <dd>Use this option to enable more verbose output.</dd>
 * </dl>
 */
class GenKeyCmd extends Command
{
  private static final Logger log = Logger.getLogger(GenKeyCmd.class.getName());
  /** Default key size in bits. */
  private static final int DEFAULT_KEY_SIZE = 1024;

  protected String _alias;
  protected String _keyAlgorithm;
  protected String _keySizeStr;
  protected String _sigAlgorithm;
  protected String _dName;
  protected String _password;
  protected String _validityStr;
  protected String _ksType;
  protected String _ksURL;
  protected String _ksPassword;
  protected String _providerClassName;
  private int keySize;
  private X500DistinguishedName distinguishedName;
  private Parser cmdOptionsParser;

  // default 0-arguments constructor

  // public setters -----------------------------------------------------------

  /** @param alias the alias to use. */
  public void setAlias(String alias)
  {
    this._alias = alias;
  }

  /** @param algorithm the canonical name of the key-pair algorithm to use. */
  public void setKeyalg(String algorithm)
  {
    this._keyAlgorithm = algorithm;
  }

  /**
   * @param bits the string representation of the number of bits (a decimal
   *          positive integer) the modulus of the generated keys (private and
   *          public) should have.
   */
  public void setKeysize(String bits)
  {
    this._validityStr = bits;
  }

  /**
   * @param algorithm the canonical name of the digital signature algorithm to
   *          use.
   */
  public void setSigalg(String algorithm)
  {
    this._sigAlgorithm = algorithm;
  }

  /** @param name the distiniguished name to use. */
  public void setDname(String name)
  {
    this._dName = name;
  }

  /** @param password the (private) key password to use. */
  public void setKeypass(String password)
  {
    this._password = password;
  }

  /**
   * @param days the string representation of the number of days (a decimal,
   *          positive integer) to assign to the generated certificate.
   */
  public void setValidity(String days)
  {
    this._validityStr = days;
  }

  /** @param type the key-store type to use. */
  public void setStoretype(String type)
  {
    this._ksType = type;
  }

  /** @param url the key-store URL to use. */
  public void setKeystore(String url)
  {
    this._ksURL = url;
  }

  /** @param password the key-store password to use. */
  public void setStorepass(String password)
  {
    this._ksPassword = password;
  }

  /** @param className a security provider fully qualified class name to use. */
  public void setProvider(String className)
  {
    this._providerClassName = className;
  }

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

  void setup() throws Exception
  {
    setKeyStoreParams(true, _providerClassName, _ksType, _ksPassword, _ksURL);
    setAliasParam(_alias);
    setKeyPasswordParam(_password);
    setAlgorithmParams(_keyAlgorithm, _sigAlgorithm);
    setKeySize(_keySizeStr);
    setDName(_dName);
    setValidityParam(_validityStr);
    if (Configuration.DEBUG)
      {
        log.fine("-genkey handler will use the following options:"); //$NON-NLS-1$
        log.fine("  -alias=" + alias); //$NON-NLS-1$
        log.fine("  -keyalg=" + keyPairGenerator.getAlgorithm()); //$NON-NLS-1$
        log.fine("  -keysize=" + keySize); //$NON-NLS-1$
        log.fine("  -sigalg=" + signatureAlgorithm.getAlgorithm()); //$NON-NLS-1$
        log.fine("  -dname=" + distinguishedName); //$NON-NLS-1$
        log.fine("  -validity=" + validityInDays); //$NON-NLS-1$
        log.fine("  -storetype=" + storeType); //$NON-NLS-1$
        log.fine("  -keystore=" + storeURL); //$NON-NLS-1$
        log.fine("  -provider=" + provider); //$NON-NLS-1$
        log.fine("  -v=" + verbose); //$NON-NLS-1$
      }
  }

  void start() throws CertificateException, KeyStoreException,
      InvalidKeyException, SignatureException, IOException,
      NoSuchAlgorithmException
  {
    if (Configuration.DEBUG)
      {
        log.entering(this.getClass().getName(), "start"); //$NON-NLS-1$
        log.fine("About to generate key-pair..."); //$NON-NLS-1$
      }
    // 1. generate a new key-pair
    keyPairGenerator.initialize(keySize);
    KeyPair kp = keyPairGenerator.generateKeyPair();
    PublicKey publicKey = kp.getPublic();
    PrivateKey privateKey = kp.getPrivate();

    // 2. generate a self-signed certificate
    if (Configuration.DEBUG)
      log.fine("About to generate a self-signed certificate..."); //$NON-NLS-1$
    byte[] derBytes = getSelfSignedCertificate(distinguishedName,
                                               publicKey,
                                               privateKey);
    if (Configuration.DEBUG)
      log.fine(Util.dumpString(derBytes, "derBytes ")); //$NON-NLS-1$
    CertificateFactory x509Factory = CertificateFactory.getInstance(Main.X_509);
    ByteArrayInputStream bais = new ByteArrayInputStream(derBytes);
    Certificate certificate = x509Factory.generateCertificate(bais);
    if (Configuration.DEBUG)
      log.fine("certificate = " + certificate); //$NON-NLS-1$

    // 3. store it, w/ its private key, associating them to alias
    Certificate[] chain = new Certificate[] { certificate };
    if (Configuration.DEBUG)
      log.fine("About to store newly generated material in key store..."); //$NON-NLS-1$
    store.setKeyEntry(alias, privateKey, keyPasswordChars, chain);

    // 4. persist the key store
    saveKeyStore();
    if (Configuration.DEBUG)
      log.exiting(this.getClass().getName(), "start"); //$NON-NLS-1$
  }

  // own methods --------------------------------------------------------------

  Parser getParser()
  {
    if (Configuration.DEBUG)
      log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$
    Parser result = new ClasspathToolParser(Main.GENKEY_CMD, true);
    result.setHeader(Messages.getString("GenKeyCmd.57")); //$NON-NLS-1$
    result.setFooter(Messages.getString("GenKeyCmd.58")); //$NON-NLS-1$
    OptionGroup options = new OptionGroup(Messages.getString("GenKeyCmd.59")); //$NON-NLS-1$
    options.add(new Option(Main.ALIAS_OPT,
                           Messages.getString("GenKeyCmd.60"), //$NON-NLS-1$
                           Messages.getString("GenKeyCmd.61")) //$NON-NLS-1$
    {
      public void parsed(String argument) throws OptionException
      {
        _alias = argument;
      }
    });
    options.add(new Option(Main.KEYALG_OPT,
                           Messages.getString("GenKeyCmd.62"), //$NON-NLS-1$
                           Messages.getString("GenKeyCmd.63")) //$NON-NLS-1$
    {
      public void parsed(String argument) throws OptionException
      {
        _keyAlgorithm = argument;
      }
    });
    options.add(new Option(Main.KEYSIZE_OPT,
                           Messages.getString("GenKeyCmd.64"), //$NON-NLS-1$
                           Messages.getString("GenKeyCmd.65")) //$NON-NLS-1$
    {
      public void parsed(String argument) throws OptionException
      {
        _keySizeStr = argument;
      }
    });
    options.add(new Option(Main.SIGALG_OPT,
                           Messages.getString("GenKeyCmd.66"), //$NON-NLS-1$
                           Messages.getString("GenKeyCmd.63")) //$NON-NLS-1$
    {
      public void parsed(String argument) throws OptionException
      {
        _sigAlgorithm = argument;
      }
    });
    options.add(new Option(Main.DNAME_OPT,
                           Messages.getString("GenKeyCmd.68"), //$NON-NLS-1$
                           Messages.getString("GenKeyCmd.69")) //$NON-NLS-1$
    {
      public void parsed(String argument) throws OptionException
      {
        _dName = argument;
      }
    });
    options.add(new Option(Main.KEYPASS_OPT,
                           Messages.getString("GenKeyCmd.70"), //$NON-NLS-1$
                           Messages.getString("GenKeyCmd.71")) //$NON-NLS-1$
    {
      public void parsed(String argument) throws OptionException
      {
        _password = argument;
      }
    });
    options.add(new Option(Main.VALIDITY_OPT,
                           Messages.getString("GenKeyCmd.72"), //$NON-NLS-1$
                           Messages.getString("GenKeyCmd.73")) //$NON-NLS-1$
    {
      public void parsed(String argument) throws OptionException
      {
        _validityStr = argument;
      }
    });
    options.add(new Option(Main.STORETYPE_OPT,
                           Messages.getString("GenKeyCmd.74"), //$NON-NLS-1$
                           Messages.getString("GenKeyCmd.75")) //$NON-NLS-1$
    {
      public void parsed(String argument) throws OptionException
      {
        _ksType = argument;
      }
    });
    options.add(new Option(Main.KEYSTORE_OPT,
                           Messages.getString("GenKeyCmd.76"), //$NON-NLS-1$
                           Messages.getString("GenKeyCmd.77")) //$NON-NLS-1$
    {
      public void parsed(String argument) throws OptionException
      {
        _ksURL = argument;
      }
    });
    options.add(new Option(Main.STOREPASS_OPT,
                           Messages.getString("GenKeyCmd.78"), //$NON-NLS-1$
                           Messages.getString("GenKeyCmd.71")) //$NON-NLS-1$
    {
      public void parsed(String argument) throws OptionException
      {
        _ksPassword = argument;
      }
    });
    options.add(new Option(Main.PROVIDER_OPT,
                           Messages.getString("GenKeyCmd.80"), //$NON-NLS-1$
                           Messages.getString("GenKeyCmd.81")) //$NON-NLS-1$
    {
      public void parsed(String argument) throws OptionException
      {
        _providerClassName = argument;
      }
    });
    options.add(new Option(Main.VERBOSE_OPT,
                           Messages.getString("GenKeyCmd.82")) //$NON-NLS-1$
    {
      public void parsed(String argument) throws OptionException
      {
        verbose = true;
      }
    });
    result.add(options);
    if (Configuration.DEBUG)
      log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$
    return result;
  }

  /**
   * @param size the desired key size as a string.
   * @throws NumberFormatException if the string does not represent a valid
   *           decimal integer value.
   */
  private void setKeySize(String size)
  {
    if (size == null || size.trim().length() == 0)
      this.keySize = DEFAULT_KEY_SIZE;
    else
      {
        size = size.trim();
        keySize = Integer.parseInt(size);
        // When generating a DSA key pair, the key size must be in the range
        // from 512 to 1024 bits, and must be a multiple of 64. The default
        // key size for any algorithm is 1024 bits
        if (keySize < 1)
          throw new IllegalArgumentException(Messages.getString("GenKeyCmd.54")); //$NON-NLS-1$
      }
  }

  /**
   * @param name the X.500 distinguished name of the principal for whom the
   *          key/certificate are being generated.
   * @throws UnsupportedCallbackException if no implementation of a name
   *           callback is available.
   * @throws IOException if an I/O related exception occurs during the process.
   * @throws IllegalArgumentException if the designated, or captured, value is
   *           not a valid X.500 distinguished name.
   */
  private void setDName(String name) throws IOException,
      UnsupportedCallbackException
  {
    if (name != null && name.trim().length() > 0)
      name = name.trim();
    else
      {
        // prompt user to provide one
        String dnTxt = Messages.getString("GenKeyCmd.0"); //$NON-NLS-1$
        String oDefault =  Messages.getString("GenKeyCmd.6"); //$NON-NLS-1$
        String lDefault =  Messages.getString("GenKeyCmd.7"); //$NON-NLS-1$
        String stDefault = Messages.getString("GenKeyCmd.8"); //$NON-NLS-1$
        String cDefault =  Messages.getString("GenKeyCmd.9"); //$NON-NLS-1$
        String cnPrompt = Messages.getString("GenKeyCmd.10"); //$NON-NLS-1$
        String oPrompt =  Messages.getFormattedString("GenKeyCmd.11", oDefault); //$NON-NLS-1$
        String ouPrompt = Messages.getString("GenKeyCmd.13"); //$NON-NLS-1$
        String lPrompt =  Messages.getFormattedString("GenKeyCmd.14", lDefault); //$NON-NLS-1$
        String stPrompt = Messages.getFormattedString("GenKeyCmd.16", stDefault); //$NON-NLS-1$
        String cPrompt =  Messages.getFormattedString("GenKeyCmd.18", cDefault); //$NON-NLS-1$

        TextOutputCallback dnCB = new TextOutputCallback(TextOutputCallback.INFORMATION,
                                                         dnTxt);
        TextInputCallback cnCB = new TextInputCallback(cnPrompt);
        TextInputCallback oCB =  new TextInputCallback(oPrompt, oDefault);
        TextInputCallback ouCB = new TextInputCallback(ouPrompt);
        TextInputCallback lCB =  new TextInputCallback(lPrompt, lDefault);
        TextInputCallback sCB =  new TextInputCallback(stPrompt, stDefault);
        TextInputCallback cCB =  new TextInputCallback(cPrompt, cDefault);
        getCallbackHandler().handle(new Callback[] { dnCB, cnCB, oCB, ouCB, lCB, sCB, cCB });
        StringBuilder sb = new StringBuilder();

        // handle CN
        name = parseUserPrompt(cnCB);
        if (name != null && name.length() > 0)
          sb.append("CN=").append(name); //$NON-NLS-1$

        // handle O
        name = parseUserPrompt(oCB);
        if (name != null && name.length() > 0)
          sb.append(",O=").append(name); //$NON-NLS-1$

        // handle OU
        name = parseUserPrompt(ouCB);
        if (name != null && name.length() > 0)
          sb.append(",OU=").append(name.trim()); //$NON-NLS-1$

        // handle L
        name = parseUserPrompt(lCB);
        if (name != null && name.length() > 0)
          sb.append(",L=").append(name.trim()); //$NON-NLS-1$

        // handle ST
        name = parseUserPrompt(sCB);
        if (name != null && name.length() > 0)
          sb.append(",ST=").append(name.trim()); //$NON-NLS-1$

        // handle C
        name = parseUserPrompt(cCB);
        if (name != null && name.length() > 0)
          sb.append(",C=").append(name.trim()); //$NON-NLS-1$

        name = sb.toString().trim();
      }
    if (Configuration.DEBUG)
      log.fine("dName=[" + name + "]"); //$NON-NLS-1$ //$NON-NLS-2$
    distinguishedName = new X500DistinguishedName(name);
  }

  private String parseUserPrompt(TextInputCallback ticb)
  {
    String result = ticb.getText();
    if (result == null || result.trim().length() == 0)
      result = ticb.getDefaultText();
    else if (result.trim().equals(".")) //$NON-NLS-1$
      result = null;
    else
      result = result.trim();

    return result;
  }
}
