/* Signature.java --- Signature Class
   Copyright (C) 1999, 2002, 2003, 2004  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 java.security;

import gnu.java.security.Engine;

import java.lang.reflect.InvocationTargetException;
import java.nio.ByteBuffer;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.spec.AlgorithmParameterSpec;

/**
 * <code>Signature</code> is used to provide an interface to digital signature
 * algorithms. Digital signatures provide authentication and data integrity of
 * digital data.
 * 
 * <p>The GNU provider provides the NIST standard DSA which uses DSA and SHA-1.
 * It can be specified by SHA/DSA, SHA-1/DSA or its OID. If the RSA signature
 * algorithm is provided then it could be MD2/RSA. MD5/RSA, or SHA-1/RSA. The
 * algorithm must be specified because there is no default.</p>
 * 
 * <p>Signature provides implementation-independent algorithms which are
 * requested by the user through the <code>getInstance()<?code> methods. It can
 * be requested by specifying just the algorithm name or by specifying both the
 * algorithm name and provider name.</p>
 * 
 * <p>The three phases of using <code>Signature</code> are:</p>
 * 
 * <ol>
 *   <li>Initializing:
 *     <ul>
 *       <li>It must be initialized with a private key for signing.</li>
 *       <li>It must be initialized with a public key for verifying.</li>
 *   </li>
 *   
 *   <li>Updating:
 *   <p>Update the bytes for signing or verifying with calls to update.</p>
 *   </li>
 *   
 *   <li>Signing or Verify the signature on the currently stored bytes by
 *   calling sign or verify.</li>
 * </ol>
 *
 * @author Mark Benvenuto  (ivymccough@worldnet.att.net)
 */
public abstract class Signature extends SignatureSpi
{
  /** Service name for signatures. */
  private static final String SIGNATURE = "Signature";

  /**
   * Possible state value which signifies that this instance has not yet been
   * initialized.
   */
  protected static final int UNINITIALIZED = 0;

  /**
   * Possible state value which signifies that this instance has been
   * initialized for signing purposes.
   */
  protected static final int SIGN = 2;

  /**
   * Possible state value which signifies that this instance has been
   * initialized for verification purposes.
   */
  protected static final int VERIFY = 3;

  /** Current sate of this instance. */
  protected int state = UNINITIALIZED;

  private String algorithm;
  Provider provider;

  // Constructor.
  // ------------------------------------------------------------------------

  /**
   * Constructs a new <code>Signature</code> instance for a designated digital
   * signature algorithm.
   * 
   * @param algorithm
   *          the algorithm to use.
   */
  protected Signature(String algorithm)
  {
    this.algorithm = algorithm;
    state = UNINITIALIZED;
  }

  /**
   * Returns an instance of <code>Signature</code> representing the specified
   * signature.
   * 
   * @param algorithm the algorithm to use.
   * @return a new instance repesenting the desired algorithm.
   * @throws NoSuchAlgorithmException if the algorithm is not implemented by any
   *           provider.
   * @throws IllegalArgumentException if <code>algorithm</code> is
   *           <code>null</code> or is an empty string.
   */
  public static Signature getInstance(String algorithm)
      throws NoSuchAlgorithmException
  {
    Provider[] p = Security.getProviders();
    NoSuchAlgorithmException lastException = null;
    for (int i = 0; i < p.length; i++)
      try
        {
          return getInstance(algorithm, p[i]);
        }
      catch (NoSuchAlgorithmException x)
        {
          lastException = x;
        }
    if (lastException != null)
      throw lastException;
    throw new NoSuchAlgorithmException(algorithm);
  }

  /**
   * Returns an instance of <code>Signature</code> representing the specified
   * signature from the named provider.
   * 
   * @param algorithm the algorithm to use.
   * @param provider the name of the provider to use.
   * @return a new instance repesenting the desired algorithm.
   * @throws NoSuchProviderException if the named provider was not found.
   * @throws NoSuchAlgorithmException if the algorithm is not implemented by the
   *           named provider.
   * @throws IllegalArgumentException if either <code>algorithm</code> or
   *           <code>provider</code> is <code>null</code> or empty.
   */
  public static Signature getInstance(String algorithm, String provider)
      throws NoSuchAlgorithmException, NoSuchProviderException
  {
    if (provider == null)
      throw new IllegalArgumentException("provider MUST NOT be null");
    provider = provider.trim();
    if (provider.length() == 0)
      throw new IllegalArgumentException("provider MUST NOT be empty");
    Provider p = Security.getProvider(provider);
    if (p == null)
      throw new NoSuchProviderException(provider);
    return getInstance(algorithm, p);
  }

  /**
   * Returns an instance of <code>Signature</code> representing the specified
   * signature from the specified {@link Provider}.
   * 
   * @param algorithm the algorithm to use.
   * @param provider the {@link Provider} to use.
   * @return a new instance repesenting the desired algorithm.
   * @throws NoSuchAlgorithmException if the algorithm is not implemented by the
   *           {@link Provider}.
   * @throws IllegalArgumentException if either <code>algorithm</code> or
   *           <code>provider</code> is <code>null</code>, or if
   *           <code>algorithm</code> is an empty string.
   */
  public static Signature getInstance(String algorithm, Provider provider)
    throws NoSuchAlgorithmException
  {
    StringBuilder sb = new StringBuilder("Signature algorithm [")
        .append(algorithm).append("] from provider[")
        .append(provider).append("] ");
    Object o;
    try
      {
        o = Engine.getInstance(SIGNATURE, algorithm, provider);
      }
    catch (InvocationTargetException x)
      {
        Throwable cause = x.getCause();
        if (cause instanceof NoSuchAlgorithmException)
          throw (NoSuchAlgorithmException) cause;
        if (cause == null)
          cause = x;
        sb.append("could not be created");
        NoSuchAlgorithmException y = new NoSuchAlgorithmException(sb.toString());
        y.initCause(cause);
        throw y;
      }
    Signature result;
    if (o instanceof SignatureSpi)
      result = new DummySignature((SignatureSpi) o, algorithm);
    else if (o instanceof Signature)
      {
        result = (Signature) o;
        result.algorithm = algorithm;
      }
    else
      {
        sb.append("is of an unexpected Type: ").append(o.getClass().getName());
        throw new NoSuchAlgorithmException(sb.toString());
      }
    result.provider = provider;
    return result;
  }

  /**
   * Returns the {@link Provider} of this instance.
   * 
   * @return the {@link Provider} of this instance.
   */
  public final Provider getProvider()
  {
    return provider;
  }

  /**
   * Initializes this instance with the public key for verification purposes.
   * 
   * @param publicKey
   *          the public key to verify with.
   * @throws InvalidKeyException
   *           if the key is invalid.
   */
  public final void initVerify(PublicKey publicKey) throws InvalidKeyException
  {
    state = VERIFY;
    engineInitVerify(publicKey);
  }

  /**
   * Verify a signature with a designated {@link Certificate}. This is a FIPS
   * 140-1 compatible method since it verifies a signature with a certificate.
   * 
   * <p>If the {@link Certificate} is an X.509 one, has a <i>KeyUsage</i>
   * parameter and that parameter indicates this key is not to be used for
   * signing then an exception is thrown.</p>
   * 
   * @param certificate
   *          a {@link Certificate} containing a public key to verify with.
   * @throws InvalidKeyException if the key is invalid.
   */
  public final void initVerify(Certificate certificate)
    throws InvalidKeyException
  {
    state = VERIFY;
    if (certificate.getType().equals("X509"))
      {
        X509Certificate cert = (X509Certificate) certificate;
        boolean[]array = cert.getKeyUsage();
        if (array != null && array[0] == false)
          throw new InvalidKeyException(
              "KeyUsage of this Certificate indicates it cannot be used for digital signing");
      }
    this.initVerify(certificate.getPublicKey());
  }

  /**
   * Initializes this class with the private key for signing purposes.
   * 
   * @param privateKey
   *          the private key to sign with.
   * @throws InvalidKeyException
   *           if the key is invalid.
   */
  public final void initSign(PrivateKey privateKey) throws InvalidKeyException
  {
    state = SIGN;
    engineInitSign(privateKey);
  }

  /**
   * Initializes this class with the private key and source of randomness for
   * signing purposes.
   * 
   * @param privateKey
   *          the private key to sign with.
   * @param random
   *          the {@link SecureRandom} to use.
   * @throws InvalidKeyException
   *           if the key is invalid.
   */
  public final void initSign(PrivateKey privateKey, SecureRandom random)
    throws InvalidKeyException
  {
    state = SIGN;
    engineInitSign(privateKey, random);
  }

  /**
   * Returns the signature bytes of all the data fed to this instance. The
   * format of the output depends on the underlying signature algorithm.
   * 
   * @return the signature bytes.
   * @throws SignatureException
   *           if the engine is not properly initialized.
   */
  public final byte[] sign() throws SignatureException
  {
    if (state == SIGN)
      return engineSign();
    else
      throw new SignatureException();
  }

  /**
   * Generates signature bytes of all the data fed to this instance and stores
   * it in the designated array. The format of the result depends on the
   * underlying signature algorithm.
   * 
   * <p>After calling this method, the instance is reset to its initial state
   * and can then be used to generate additional signatures.</p>
   * 
   * <p><b>IMPLEMENTATION NOTE:</b> Neither this method nor the GNU provider
   * will return partial digests. If <code>len</code> is less than the
   * signature length, this method will throw a {@link SignatureException}. If
   * it is greater than or equal then it is ignored.</p>
   * 
   * @param outbuf
   *          array of bytes of where to store the resulting signature bytes.
   * @param offset
   *          the offset to start at in the array.
   * @param len
   *          the number of the bytes to use in the array.
   * @return the real number of bytes used.
   * @throws SignatureException
   *           if the engine is not properly initialized.
   * @since 1.2
   */
  public final int sign(byte[] outbuf, int offset, int len)
    throws SignatureException
  {
    if (state == SIGN)
      return engineSign(outbuf, offset, len);
    else
      throw new SignatureException();
  }

  /**
   * Verifies a designated signature.
   * 
   * @param signature
   *          the signature bytes to verify.
   * @return <code>true</code> if verified, <code>false</code> otherwise.
   * @throws SignatureException
   *           if the engine is not properly initialized or the signature does
   *           not check.
   */
  public final boolean verify(byte[]signature) throws SignatureException
  {
    if (state == VERIFY)
      return engineVerify(signature);
    else
      throw new SignatureException();
  }

  /**
   * Verifies a designated signature.
   * 
   * @param signature
   *          the signature bytes to verify.
   * @param offset
   *          the offset to start at in the array.
   * @param length
   *          the number of the bytes to use from the array.
   * @return <code>true</code> if verified, <code>false</code> otherwise.
   * @throws IllegalArgumentException
   *           if the <code>signature</code> byte array is <code>null</code>,
   *           or the <code>offset</code> or <code>length</code> is less
   *           than <code>0</code>, or the sum of the <code>offset</code>
   *           and <code>length</code> is greater than the length of the
   *           <code>signature</code> byte array.
   * @throws SignatureException
   *           if the engine is not properly initialized or the signature does
   *           not check.
   */
  public final boolean verify(byte[] signature, int offset, int length)
    throws SignatureException
  {
    if (state != VERIFY)
      throw new SignatureException("illegal state");

    if (signature == null)
      throw new IllegalArgumentException("signature is null");
    if (offset < 0)
      throw new IllegalArgumentException("offset is less than 0");
    if (length < 0)
      throw new IllegalArgumentException("length is less than 0");
    if (offset + length < signature.length)
      throw new IllegalArgumentException("range is out of bounds");

    return engineVerify(signature, offset, length);
  }

  /**
   * Updates the data to be signed or verified with the specified byte.
   * 
   * @param b
   *          the byte to update with.
   * @throws SignatureException
   *           if the engine is not properly initialized.
   */
  public final void update(byte b) throws SignatureException
  {
    if (state != UNINITIALIZED)
      engineUpdate(b);
    else
      throw new SignatureException();
  }

  /**
   * Updates the data to be signed or verified with the specified bytes.
   * 
   * @param data
   *          the array of bytes to use.
   * @throws SignatureException
   *           if the engine is not properly initialized.
   */
  public final void update(byte[]data) throws SignatureException
  {
    if (state != UNINITIALIZED)
      engineUpdate(data, 0, data.length);
    else
      throw new SignatureException();
  }

  /**
   * Updates the data to be signed or verified with the specified bytes.
   * 
   * @param data
   *          an array of bytes to use.
   * @param off
   *          the offset to start at in the array.
   * @param len
   *          the number of bytes to use from the array.
   * @throws SignatureException
   *           if the engine is not properly initialized.
   */
  public final void update(byte[]data, int off, int len)
    throws SignatureException
  {
    if (state != UNINITIALIZED)
      engineUpdate(data, off, len);
    else
      throw new SignatureException();
  }
  
  /**
   * Update this signature with the {@link java.nio.Buffer#remaining()}
   * bytes of the input buffer.
   * 
   * @param input The input buffer.
   * @throws SignatureException If this instance was not properly
   *  initialized.
   */
  public final void update(ByteBuffer input) throws SignatureException
  {
    if (state != UNINITIALIZED)
      engineUpdate(input);
    else
      throw new SignatureException("not initialized");
  }

  /**
   * Returns the name of the algorithm currently used. The names of algorithms
   * are usually SHA/DSA or SHA/RSA.
   * 
   * @return name of algorithm.
   */
  public final String getAlgorithm()
  {
    return algorithm;
  }

  /**
   * Returns a rstring representation of this instance.
   * 
   * @return a rstring representation of this instance.
   */
  public String toString()
  {
    return (algorithm + " Signature");
  }

  /**
   * Sets the specified algorithm parameter to the specified value.
   * 
   * @param param
   *          the parameter name.
   * @param value
   *          the parameter value.
   * @throws InvalidParameterException
   *           if the parameter is invalid, the parameter is already set and
   *           can not be changed, a security exception occured, etc.
   * @deprecated use the other setParameter
   */
  public final void setParameter(String param, Object value)
    throws InvalidParameterException
  {
    engineSetParameter(param, value);
  }

  /**
   * Sets the signature engine with the specified {@link AlgorithmParameterSpec}.
   * 
   * <p>By default, and unless overriden by the concrete SPI, this method always
   * throws an {@link UnsupportedOperationException}.</p>
   * 
   * @param params
   *          the parameters to use for intializing this instance.
   * @throws InvalidParameterException
   *           if the parameter is invalid, the parameter is already set and
   *           cannot be changed, a security exception occured, etc.
   */
  public final void setParameter(AlgorithmParameterSpec params)
    throws InvalidAlgorithmParameterException
  {
    engineSetParameter(params);
  }

  /**
   * Return the parameters of the algorithm used in this instance as an
   * {@link AlgorithmParameters}.
   * 
   * @return the parameters used with this instance, or <code>null</code> if
   *         this instance does not use any parameters.
   */
  public final AlgorithmParameters getParameters()
  {
    return engineGetParameters();
  }

  /**
   * Returns the value for the specified algorithm parameter.
   * 
   * @param param
   *          the parameter name.
   * @return the parameter value.
   * @throws InvalidParameterException
   *           if the parameter is invalid.
   * @deprecated use the other getParameter
   */
  public final Object getParameter(String param)
    throws InvalidParameterException
  {
    return engineGetParameter(param);
  }

  /**
   * Returns a clone of this instance.
   * 
   * @return a clone of this instace.
   * @throws CloneNotSupportedException
   *           if the implementation does not support cloning.
   */
  public Object clone() throws CloneNotSupportedException
  {
    return super.clone();
  }
}
