/* RSAPKCS1V1_5SignatureRawCodec.java -- Raw RSA PKCS1 v1.5 signature codeec
   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.java.security.sig.rsa;

import java.io.ByteArrayOutputStream;

import gnu.java.security.Registry;
import gnu.java.security.sig.ISignatureCodec;

/**
 * An object that implements the {@link ISignatureCodec} operations for the
 * <i>Raw</i> format to use with RSA-PKCS#1 v1.5 signatures.
 */
public class RSAPKCS1V1_5SignatureRawCodec
    implements ISignatureCodec
{
  public int getFormatID()
  {
    return RAW_FORMAT;
  }

  /**
   * Returns the encoded form of the designated RSA-PKCS#1 (v1.5) signature
   * object according to the <i>Raw</i> format supported by this library.
   * <p>
   * The <i>Raw</i> format for such a signature, in this implementation, is a
   * byte sequence consisting of the following:
   * <p>
   * <ol>
   * <li>4-byte magic consisting of the value of the literal
   * {@link Registry#MAGIC_RAW_RSA_PKCS1V1_5_SIGNATURE},
   * <li>
   * <li>1-byte version consisting of the constant: 0x01,</li>
   * <li>4-byte count of following bytes representing the RSA-PKCS#1 (v1.5)
   * signature bytes in internet order,</li>
   * <li>the RSA-PKCS#1 (v1.5) signature bytes in internet order.</li>
   * </ol>
   * 
   * @param signature the signature to encode, consisting of the output of the
   *          <code>sign()</code> method of a {@link RSAPKCS1V1_5Signature}
   *          instance --a byte array.
   * @return the <i>Raw</i> format encoding of the designated signature.
   * @exception IllegalArgumentException if the designated signature is not an
   *              RSA-PKCS#1 (v1.5) one.
   */
  public byte[] encodeSignature(Object signature)
  {
    byte[] buffer;
    try
      {
        buffer = (byte[]) signature;
      }
    catch (Exception x)
      {
        throw new IllegalArgumentException("Signature/codec mismatch");
      }

    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    // magic
    baos.write(Registry.MAGIC_RAW_RSA_PKCS1V1_5_SIGNATURE[0]);
    baos.write(Registry.MAGIC_RAW_RSA_PKCS1V1_5_SIGNATURE[1]);
    baos.write(Registry.MAGIC_RAW_RSA_PKCS1V1_5_SIGNATURE[2]);
    baos.write(Registry.MAGIC_RAW_RSA_PKCS1V1_5_SIGNATURE[3]);

    // version
    baos.write(0x01);

    // signature bytes
    int length = buffer.length;
    baos.write( length >>> 24);
    baos.write((length >>> 16) & 0xFF);
    baos.write((length >>>  8) & 0xFF);
    baos.write( length         & 0xFF);
    baos.write(buffer, 0, length);

    return baos.toByteArray();
  }

  /**
   * Returns the decoded object from a designated input assumed to have been
   * generated by the {@link #encodeSignature(Object)} method.
   * 
   * @param input the input bytes of a previously Raw-encoded RSA PKCS1 (v1.5)
   *          signature.
   * @return the signature object.
   * @throws IllegalArgumentException if the designated input does not start
   *           with the right <i>magic</i> characters, or if the <i>version</i>
   *           is not supported.
   */
  public Object decodeSignature(byte[] input)
  {
    // magic
    if (input[0] != Registry.MAGIC_RAW_RSA_PKCS1V1_5_SIGNATURE[0]
        || input[1] != Registry.MAGIC_RAW_RSA_PKCS1V1_5_SIGNATURE[1]
        || input[2] != Registry.MAGIC_RAW_RSA_PKCS1V1_5_SIGNATURE[2]
        || input[3] != Registry.MAGIC_RAW_RSA_PKCS1V1_5_SIGNATURE[3])
      throw new IllegalArgumentException("Signature/codec mismatch");

    // version
    if (input[4] != 0x01)
      throw new IllegalArgumentException("Wrong or unsupported format version");

    int i = 5;
    int l;

    // signature bytes
    l =    input[i++]         << 24
        | (input[i++] & 0xFF) << 16
        | (input[i++] & 0xFF) <<  8
        | (input[i++] & 0xFF);
    byte[] result = new byte[l];
    System.arraycopy(input, i, result, 0, l);

    return result;
  }
}
