/* EME_PKCS1_V1_5.java -- 
   Copyright (C) 2003, 2006 Free Software Foundation, Inc.

This file is a 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 of the License, 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; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, 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.java.security.sig.rsa;

import gnu.java.security.prng.IRandom;
import gnu.java.security.prng.LimitReachedException;
import gnu.java.security.util.PRNG;

import java.io.ByteArrayOutputStream;
import java.security.interfaces.RSAKey;
import java.util.Random;

/**
 * An implementation of the EME-PKCS1-V1.5 encoding and decoding methods.
 * <p>
 * EME-PKCS1-V1.5 is parameterised by the entity <code>k</code> which is the
 * byte count of an RSA public shared modulus.
 * <p>
 * References:
 * <ol>
 * <li><a href="http://www.ietf.org/rfc/rfc3447.txt">Public-Key Cryptography
 * Standards (PKCS) #1:</a><br>
 * RSA Cryptography Specifications Version 2.1.<br>
 * Jakob Jonsson and Burt Kaliski.</li>
 * </ol>
 */
public class EME_PKCS1_V1_5
{
  private int k;

  private ByteArrayOutputStream baos = new ByteArrayOutputStream();

  /** Our default source of randomness. */
  private PRNG prng = PRNG.getInstance();

  private EME_PKCS1_V1_5(final int k)
  {
    super();

    this.k = k;
  }

  public static final EME_PKCS1_V1_5 getInstance(final int k)
  {
    if (k < 0)
      throw new IllegalArgumentException("k must be a positive integer");

    return new EME_PKCS1_V1_5(k);
  }

  public static final EME_PKCS1_V1_5 getInstance(final RSAKey key)
  {
    final int modBits = key.getModulus().bitLength();
    final int k = (modBits + 7) / 8;
    return EME_PKCS1_V1_5.getInstance(k);
  }

  /**
   * Generates an octet string <code>PS</code> of length <code>k - mLen -
   * 3</code> consisting of pseudo-randomly generated nonzero octets. The length
   * of <code>PS</code> will be at least eight octets.
   * <p>
   * The method then concatenates <code>PS</code>, the message <code>M</code>,
   * and other padding to form an encoded message <code>EM</code> of length
   * <code>k</code> octets as:
   * <pre>
   *     EM = 0x00 || 0x02 || PS || 0x00 || M.
   * </pre>
   * <p>
   * This method uses a default PRNG to obtain the padding bytes.
   * 
   * @param M the message to encode.
   * @return the encoded message <code>EM</code>.
   */
  public byte[] encode(final byte[] M)
  {
    // a. Generate an octet string PS of length k - mLen - 3 consisting
    // of pseudo-randomly generated nonzero octets. The length of PS
    // will be at least eight octets.
    final byte[] PS = new byte[k - M.length - 3];
    // FIXME. This should be configurable, somehow.
    prng.nextBytes(PS);
    int i = 0;
    for (; i < PS.length; i++)
      {
        if (PS[i] == 0)
          PS[i] = 1;
      }
    // b. Concatenate PS, the message M, and other padding to form an
    // encoded message EM of length k octets as
    //
    // EM = 0x00 || 0x02 || PS || 0x00 || M.
    return assembleEM(PS, M);
  }

  /**
   * Similar to {@link #encode(byte[])} method, except that the source of
   * randomness to use for obtaining the padding bytes (an instance of
   * {@link IRandom}) is given as a parameter.
   * 
   * @param M the message to encode.
   * @param irnd the {@link IRandom} instance to use as a source of randomness.
   * @return the encoded message <code>EM</code>.
   */
  public byte[] encode(final byte[] M, final IRandom irnd)
  {
    final byte[] PS = new byte[k - M.length - 3];
    try
      {
        irnd.nextBytes(PS, 0, PS.length);
        int i = 0;
        outer: while (true)
          {
            for (; i < PS.length; i++)
              {
                if (PS[i] == 0x00)
                  {
                    System.arraycopy(PS, i + 1, PS, i, PS.length - i - 1);
                    irnd.nextBytes(PS, PS.length - 1, 1);
                    continue outer;
                  }
              }
            break;
          }
      }
    catch (IllegalStateException x)
      {
        throw new RuntimeException("encode(): " + String.valueOf(x));
      }
    catch (LimitReachedException x)
      {
        throw new RuntimeException("encode(): " + String.valueOf(x));
      }
    return assembleEM(PS, M);
  }

  /**
   * Similar to the {@link #encode(byte[], IRandom)} method, except that the
   * source of randmoness is an instance of {@link Random}.
   * 
   * @param M the message to encode.
   * @param rnd the {@link Random} instance to use as a source of randomness.
   * @return the encoded message <code>EM</code>.
   */
  public byte[] encode(final byte[] M, final Random rnd)
  {
    final byte[] PS = new byte[k - M.length - 3];
    rnd.nextBytes(PS);
    int i = 0;
    outer: while (true)
      {
        for (; i < PS.length; i++)
          {
            if (PS[i] == 0x00)
              {
                System.arraycopy(PS, i + 1, PS, i, PS.length - i - 1);
                PS[PS.length - 1] = (byte) rnd.nextInt();
                continue outer;
              }
          }
        break;
      }
    return assembleEM(PS, M);
  }

  /**
   * Separate the encoded message <code>EM</code> into an octet string
   * <code>PS</code> consisting of nonzero octets and a message <code>M</code>
   * as:
   * <pre>
   *     EM = 0x00 || 0x02 || PS || 0x00 || M.
   * </pre>
   * <p>
   * If the first octet of <code>EM</code> does not have hexadecimal value
   * <code>0x00</code>, if the second octet of <code>EM</code> does not
   * have hexadecimal value <code>0x02</code>, if there is no octet with
   * hexadecimal value <code>0x00</code> to separate <code>PS</code> from
   * <code>M</code>, or if the length of <code>PS</code> is less than
   * <code>8</code> octets, output "decryption error" and stop.
   * 
   * @param EM the designated encoded message.
   * @return the decoded message <code>M</code> framed in the designated
   *         <code>EM</code> value.
   * @throws IllegalArgumentException if the length of the designated entity
   *           <code>EM</code> is different than <code>k</code> (the length
   *           in bytes of the public shared modulus), or if any of the
   *           conditions described above is detected.
   */
  public byte[] decode(final byte[] EM)
  {
    // Separate the encoded message EM into an
    // octet string PS consisting of nonzero octets and a message M as
    //
    // EM = 0x00 || 0x02 || PS || 0x00 || M.
    //
    // If the first octet of EM does not have hexadecimal value 0x00, if
    // the second octet of EM does not have hexadecimal value 0x02, if
    // there is no octet with hexadecimal value 0x00 to separate PS from
    // M, or if the length of PS is less than 8 octets, output
    // "decryption error" and stop. (See the note below.)
    final int emLen = EM.length;
    if (emLen != k)
      throw new IllegalArgumentException("decryption error");
    if (EM[0] != 0x00)
      throw new IllegalArgumentException("decryption error");
    if (EM[1] != 0x02)
      throw new IllegalArgumentException("decryption error");
    int i = 2;
    for (; i < emLen; i++)
      {
        if (EM[i] == 0x00)
          break;
      }
    if (i >= emLen || i < 11)
      throw new IllegalArgumentException("decryption error");
    i++;
    final byte[] result = new byte[emLen - i];
    System.arraycopy(EM, i, result, 0, result.length);
    return result;
  }

  private byte[] assembleEM(final byte[] PS, final byte[] M)
  {
    // b. Concatenate PS, the message M, and other padding to form an
    // encoded message EM of length k octets as
    //
    // EM = 0x00 || 0x02 || PS || 0x00 || M.
    baos.reset();
    baos.write(0x00);
    baos.write(0x02);
    baos.write(PS, 0, PS.length);
    baos.write(0x00);
    baos.write(M, 0, M.length);
    final byte[] result = baos.toByteArray();
    baos.reset();
    return result;
  }
}
