mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			432 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			432 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Java
		
	
	
	
/* SignerInfo.java -- a SignerInfo object, from PKCS #7
 | 
						|
   Copyright (C) 2004, 2005, 2010  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 = Configuration.DEBUG ?
 | 
						|
                        Logger.getLogger(SignerInfo.class.getName()) : null;
 | 
						|
 | 
						|
  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();
 | 
						|
    if (Configuration.DEBUG)
 | 
						|
      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);
 | 
						|
  }
 | 
						|
}
 |