/* DiffieHellmanImpl.java -- implementation of the Diffie-Hellman key agreement.
   Copyright (C) 2005, 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.javax.crypto.jce;

import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;

import javax.crypto.KeyAgreementSpi;
import javax.crypto.SecretKey;
import javax.crypto.ShortBufferException;
import javax.crypto.interfaces.DHPrivateKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * The JCE implementation of a 2-party Diffie-Hellman key agreement.
 * 
 * @author Casey Marshall (csm@gnu.org)
 */
public final class DiffieHellmanImpl
    extends KeyAgreementSpi
{
  /** The private key being used for this agreement. */
  private DHPrivateKey key;

  /** The current result. */
  private byte[] result;

  /** True if the caller told us we are done. */
  private boolean last_phase_done;

  /** Trivial default constructor. */
  public DiffieHellmanImpl()
  {
    super();

    key = null;
    result = null;
    last_phase_done = false;
  }

  protected Key engineDoPhase(Key incoming, boolean lastPhase)
      throws InvalidKeyException
  {
    if (key == null)
      throw new IllegalStateException("Not initialized");

    if (last_phase_done)
      throw new IllegalStateException("Last phase already done");

    if (! (incoming instanceof DHPublicKey))
      throw new InvalidKeyException("Key MUST be a DHPublicKey");

    DHPublicKey pub = (DHPublicKey) incoming;
    DHParameterSpec s1 = key.getParams();
    DHParameterSpec s2 = pub.getParams();
    if (! s1.getG().equals(s2.getG()) || ! s1.getP().equals(s2.getP())
        || s1.getL() != s2.getL())
      throw new InvalidKeyException("Incompatible key");
    if (! lastPhase)
      throw new IllegalArgumentException(
          "This key-agreement MUST be concluded in one step only");
    BigInteger resultBI = pub.getY().modPow(key.getX(), s1.getP());
    result = resultBI.toByteArray();
    if (result[0] == 0x00)
      {
        byte[] buf = new byte[result.length - 1];
        System.arraycopy(result, 1, buf, 0, buf.length);
        result = buf;
      }
    last_phase_done = true;
    return null;
  }

  protected byte[] engineGenerateSecret()
  {
    checkState();
    byte[] res = (byte[]) result.clone();
    reset();
    return res;
  }

  protected int engineGenerateSecret(byte[] secret, int offset)
      throws ShortBufferException
  {
    checkState();
    if (result.length > secret.length - offset)
      throw new ShortBufferException();
    System.arraycopy(result, 0, secret, offset, result.length);
    int res = result.length;
    reset();
    return res;
  }

  protected SecretKey engineGenerateSecret(String algorithm)
      throws InvalidKeyException
  {
    checkState();
    byte[] s = (byte[]) result.clone();
    SecretKey res = new SecretKeySpec(s, algorithm);
    reset();
    return res;
  }

  protected void engineInit(Key key, SecureRandom random)
      throws InvalidKeyException
  {
    if (! (key instanceof DHPrivateKey))
      throw new InvalidKeyException("Key MUST be a DHPrivateKey");
    this.key = (DHPrivateKey) key;
    reset();
  }

  protected void engineInit(Key key, AlgorithmParameterSpec params,
                            SecureRandom random)
      throws InvalidKeyException
  {
    engineInit(key, random);
  }

  private void reset()
  {
    result = null;
    last_phase_done = false;
  }

  private void checkState()
  {
    if (result == null || ! last_phase_done)
      throw new IllegalStateException("Not finished");
  }
}
