/* SignerInfo.java -- a SignerInfo object, from PKCS #7
   Copyright (C) 2004, 2005  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.pkcs;

import gnu.java.security.Configuration;
import gnu.java.security.OID;
import gnu.java.security.ber.BER;
import gnu.java.security.ber.BEREncodingException;
import gnu.java.security.ber.BERReader;
import gnu.java.security.ber.BERValue;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERValue;
import gnu.java.security.der.DERWriter;
import gnu.java.security.util.Util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.logging.Logger;

import javax.security.auth.x500.X500Principal;

public class SignerInfo
{
  private static final Logger log = Logger.getLogger(SignerInfo.class.getName());

  private final BigInteger version;
  private final BigInteger serialNumber;
  private final X500Principal issuer;
  private final OID digestAlgorithmId;
  private final byte[] digestAlgorithmParams;
  private final byte[] authenticatedAttributes;
  private final OID digestEncryptionAlgorithmId;
  private final byte[] digestEncryptionAlgorithmParams;
  private final byte[] encryptedDigest;
  private final byte[] unauthenticatedAttributes;

  /**
   * Parse a SignerInfo object.
   * <p>
   * A SignerInfo is a structure with the following ASN.1 syntax:
   * <pre>
   * SignerInfo ::= SEQUENCE {
   *   version                       Version, -- always 1 for PKCS7 v1.5
   *   issuerAndSerialNumber         IssuerAndSerialNumber, -- an INTEGER
   *   digestAlgorithm               DigestAlgorithmIdentifier,
   *   authenticatedAttributes   [0] IMPLICIT Attributes OPTIONAL,
   *   digestEncryptionAlgorithm     DigestEncryptionAlgorithmIdentifier,
   *   encryptedDigest               EncryptedDigest,
   *   unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL }
   *
   * IssuerAndSerialNumber ::= SEQUENCE {
   *   issuer       Name,
   *   serialNumber CertificateSerialNumber
   * }
   *
   * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
   *
   * DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
   *
   * EncryptedDigest ::= OCTET STRING
   * </pre>
   */
  public SignerInfo(BERReader ber) throws IOException
  {
    DERValue val = ber.read();
    if (Configuration.DEBUG)
      log.fine("SignerInfo: " + val);
    if (!val.isConstructed())
      throw new BEREncodingException("malformed SignerInfo");

    val = ber.read();
    if (val.getTag() != BER.INTEGER)
      throw new BEREncodingException("malformed Version");

    version = (BigInteger) val.getValue();
    log.fine("  Version: " + version);

    val = ber.read();
    if (!val.isConstructed())
      throw new BEREncodingException("malformed IssuerAndSerialNumber");
    if (Configuration.DEBUG)
      log.fine("  IssuerAndSerialNumber: " + val);

    val = ber.read();
    if (!val.isConstructed())
      throw new BEREncodingException("malformed Issuer");

    issuer = new X500Principal(val.getEncoded());
    ber.skip(val.getLength());
    if (Configuration.DEBUG)
      log.fine("    Issuer: " + issuer);

    val = ber.read();
    if (val.getTag() != BER.INTEGER)
      throw new BEREncodingException("malformed SerialNumber");

    serialNumber = (BigInteger) val.getValue();
    if (Configuration.DEBUG)
      log.fine("    SerialNumber: " + serialNumber);

    val = ber.read();
    if (!val.isConstructed())
      throw new BEREncodingException("malformed DigestAlgorithmIdentifier");
    if (Configuration.DEBUG)
      log.fine("  DigestAlgorithmIdentifier: " + val);

    int count = 0;
    DERValue val2 = ber.read();
    if (val2.getTag() != BER.OBJECT_IDENTIFIER)
      throw new BEREncodingException("malformed AlgorithmIdentifier");

    digestAlgorithmId = (OID) val2.getValue();
    if (Configuration.DEBUG)
      log.fine("    digestAlgorithm OID: " + digestAlgorithmId);

    if (BERValue.isIndefinite(val))
      {
        val2 = ber.read();
        if (val2 != BER.END_OF_SEQUENCE)
          {
            digestAlgorithmParams = val2.getEncoded();
            val2 = ber.read();
            if (val2 != BER.END_OF_SEQUENCE)
              throw new BEREncodingException("expecting BER end-of-sequence");
          }
        else
          digestAlgorithmParams = null;
      }
    else if (val2.getEncodedLength() < val.getLength())
      {
        val2 = ber.read();
        digestAlgorithmParams = val2.getEncoded();
        if (val2.isConstructed())
          ber.skip(val2.getLength());
      }
    else
      digestAlgorithmParams = null;

    if (Configuration.DEBUG)
      {
        log.fine("    digestAlgorithm params: ");
        log.fine(Util.dumpString(digestAlgorithmParams,
                                 "    digestAlgorithm params: "));
      }
    val = ber.read();
    if (val.getTag() == 0)
      {
        authenticatedAttributes = val.getEncoded();
        val = ber.read();
        if (val.isConstructed())
          ber.skip(val.getLength());

        val = ber.read();
      }
    else
      authenticatedAttributes = null;

    if (Configuration.DEBUG)
      {
        log.fine("  AuthenticatedAttributes: ");
        log.fine(Util.dumpString(authenticatedAttributes,
                                 "  AuthenticatedAttributes: "));
      }
    if (!val.isConstructed())
      throw new BEREncodingException("malformed DigestEncryptionAlgorithmIdentifier");
    if (Configuration.DEBUG)
      log.fine("  DigestEncryptionAlgorithmIdentifier: " + val);
    count = 0;
    val2 = ber.read();
    if (val2.getTag() != BER.OBJECT_IDENTIFIER)
      throw new BEREncodingException("malformed AlgorithmIdentifier");

    digestEncryptionAlgorithmId = (OID) val2.getValue();
    if (Configuration.DEBUG)
      log.fine("    digestEncryptionAlgorithm OID: " + digestEncryptionAlgorithmId);

    if (BERValue.isIndefinite(val))
      {
        val2 = ber.read();
        if (val2 != BER.END_OF_SEQUENCE)
          {
            digestEncryptionAlgorithmParams = val2.getEncoded();
            val2 = ber.read();
            if (val2 != BER.END_OF_SEQUENCE)
              throw new BEREncodingException("expecting BER end-of-sequence");
          }
        else
          digestEncryptionAlgorithmParams = null;
      }
    else if (val2.getEncodedLength() < val.getLength())
      {
        val2 = ber.read();
        digestEncryptionAlgorithmParams = val2.getEncoded();
        if (val2.isConstructed())
          ber.skip(val2.getLength());
      }
    else
      digestEncryptionAlgorithmParams = null;

    if (Configuration.DEBUG)
      {
        log.fine("    digestEncryptionAlgorithm params: ");
        log.fine(Util.dumpString(digestEncryptionAlgorithmParams,
                                 "    digestEncryptionAlgorithm params: "));
      }
    val = ber.read();
    if (val.getTag() != BER.OCTET_STRING)
      throw new BEREncodingException("malformed EncryptedDigest");

    encryptedDigest = (byte[]) val.getValue();
    if (Configuration.DEBUG)
      {
        log.fine("  EncryptedDigest: ");
        log.fine(Util.dumpString(encryptedDigest, "  EncryptedDigest: "));
      }
    if (ber.peek() == 1)
      unauthenticatedAttributes = ber.read().getEncoded();
    else
      unauthenticatedAttributes = null;

    if (Configuration.DEBUG)
      {
        log.fine("  UnauthenticatedAttributes: ");
        log.fine(Util.dumpString(unauthenticatedAttributes,
                                 "  UnauthenticatedAttributes: "));
      }
    if (ber.peek() == 0)
      ber.read();
  }

  /**
   * Constructs a new instance of <code>SignerInfo</code> given a designated
   * set of fields.
   *
   * @param issuer the X.500 Principal name of the signer referenced by this
   *          instance.
   * @param serialNumber the serial number of the certificate being used. Both
   *          this and the previous arguments are gleaned from the signer's
   *          certificate.
   * @param digestAlgorithmOID the OID of the digest algorithm. When
   *          constructing the DigestAlgorithmIdentifier with this OID, the
   *          parameters part will be NULL.
   * @param authenticatedAttributes the encoding of the set of authenticated
   *          attributes to use.
   * @param digestEncryptionAlgorithmOID the OID of the digest encryption
   *          algorithm. When constructing the
   *          DigestEncryptionAlgorithmIdentifier with this OID, the parameters
   *          part will be NULL.
   * @param encryptedDigest the encrypted hash generated with this signer's
   *          private key.
   * @param unauthenticatedAttributes the encoding of the set of
   *          unauthencticated attributes.
   */
  public SignerInfo(X500Principal issuer, BigInteger serialNumber,
                    OID digestAlgorithmOID, byte[] authenticatedAttributes,
                    OID digestEncryptionAlgorithmOID,
                    byte[] encryptedDigest, byte[] unauthenticatedAttributes)
  {
    super();

    this.version = BigInteger.ONE;
    this.issuer = issuer;
    this.serialNumber = serialNumber;
    this.digestAlgorithmId = digestAlgorithmOID;
    this.digestAlgorithmParams = null;
    this.authenticatedAttributes = authenticatedAttributes;
    this.digestEncryptionAlgorithmId = digestEncryptionAlgorithmOID;
    this.digestEncryptionAlgorithmParams = null;
    this.encryptedDigest = encryptedDigest;
    this.unauthenticatedAttributes = unauthenticatedAttributes;
  }

  public BigInteger getVersion()
  {
    return version;
  }

  public BigInteger getSerialNumber()
  {
    return serialNumber;
  }

  public X500Principal getIssuer()
  {
    return issuer;
  }

  public OID getDigestAlgorithmId()
  {
    return digestAlgorithmId;
  }

  public byte[] getDigestAlgorithmParams()
  {
    return (digestAlgorithmParams != null
            ? (byte[]) digestAlgorithmParams.clone()
            : null);
  }

  public byte[] getAuthenticatedAttributes()
  {
    return (authenticatedAttributes != null
            ? (byte[]) authenticatedAttributes.clone()
            : null);
  }

  public OID getDigestEncryptionAlgorithmId()
  {
    return digestEncryptionAlgorithmId;
  }

  public byte[] getDigestEncryptionAlgorithmParams()
  {
    return (digestEncryptionAlgorithmParams != null
            ? (byte[]) digestEncryptionAlgorithmParams.clone()
            : null);
  }

  public byte[] getEncryptedDigest()
  {
    return (encryptedDigest != null ? (byte[]) encryptedDigest.clone() : null);
  }

  public byte[] getUnauthenticatedAttributes()
  {
    return (unauthenticatedAttributes != null
            ? (byte[]) unauthenticatedAttributes.clone()
            : null);
  }

  /**
   * Writes to the designated output stream the DER encoding of the current
   * contents of this instance.
   *
   * @param out the destination output stream.
   * @throws IOException if an I/O related exception occurs during the process.
   */
  public void encode(OutputStream out) throws IOException
  {
    DERValue derVersion = new DERValue(DER.INTEGER, version);

    ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
    baos.write(issuer.getEncoded());
    DERValue derSerialNumber = new DERValue(DER.INTEGER, serialNumber);
    DERWriter.write(baos, derSerialNumber);
    baos.flush();
    byte[] b = baos.toByteArray();
    DERValue derIssuerAndSerialNumber =
        new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, b.length, b, null);

    DERValue derDigestAlgorithmOID = new DERValue(DER.OBJECT_IDENTIFIER,
                                                  digestAlgorithmId);
    ArrayList digestAlgorithmIdentifier = new ArrayList(1);
    digestAlgorithmIdentifier.add(derDigestAlgorithmOID);
    DERValue derDigestAlgorithmIdentifier =
        new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, digestAlgorithmIdentifier);

    DERValue derAuthenticatedAttributes;
    if (authenticatedAttributes == null)
      derAuthenticatedAttributes = new DERValue(DER.NULL, null);
    else
      derAuthenticatedAttributes = new DERValue(DER.CONSTRUCTED | DER.SET,
                                                authenticatedAttributes);

    DERValue derDigestEncryptionAlgorithmOID =
        new DERValue(DER.OBJECT_IDENTIFIER, digestEncryptionAlgorithmId);
    ArrayList digestEncryptionAlgorithmIdentifier = new ArrayList(1);
    digestEncryptionAlgorithmIdentifier.add(derDigestEncryptionAlgorithmOID);
    DERValue derDigestEncryptionAlgorithmIdentifier =
        new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, digestEncryptionAlgorithmIdentifier);

    DERValue derEncryptedDigest = new DERValue(DER.OCTET_STRING, encryptedDigest);

    DERValue derUnauthenticatedAttributes;
    if (unauthenticatedAttributes == null)
      derUnauthenticatedAttributes = new DERValue(DER.NULL, null);
    else
      derUnauthenticatedAttributes = new DERValue(DER.CONSTRUCTED | DER.SET,
                                                  unauthenticatedAttributes);

    ArrayList signerInfo = new ArrayList(5);
    signerInfo.add(derVersion);
    signerInfo.add(derIssuerAndSerialNumber);
    signerInfo.add(derDigestAlgorithmIdentifier);
    signerInfo.add(derDigestEncryptionAlgorithmIdentifier);
    signerInfo.add(derEncryptedDigest);
    DERValue derSignerInfo = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
                                          signerInfo);
    DERWriter.write(out, derSignerInfo);
  }
}
