//////////////////////////////////////////////////////////////////////////// 
// 
// Copyright (C) DSTC Pty Ltd (ACN 052 372 577) 1993, 1994, 1995.
// Unpublished work.  All Rights Reserved.
// 
// The software contained on this media is the property of the
// DSTC Pty Ltd.  Use of this software is strictly in accordance
// with the license agreement in the accompanying LICENSE.DOC 
// file. If your distribution of this software does not contain 
// a LICENSE.DOC file then you have no rights to use this 
// software in any manner and should contact DSTC at the address 
// below to determine an appropriate licensing arrangement.
// 
//      DSTC Pty Ltd
//      Level 7, GP South
//      University of Queensland
//      St Lucia, 4072
//      Australia
//      Tel: +61 7 3365 4310
//      Fax: +61 7 3365 4311
//      Email: jcsi@dstc.qut.edu.au
// 
// This software is being provided "AS IS" without warranty of
// any kind.  In no event shall DSTC Pty Ltd be liable for
// damage of any kind arising out of or in connection with
// the use or performance of this software.
// 
//////////////////////////////////////////////////////////////////////////// 

package com.dstc.security.cms.v1;

import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;

import java.util.Vector;
import com.dstc.security.cms.v1.*;
import com.dstc.security.asn1.*;

/**
 * <p> Implements the ASN.1 structure EnvelopedData.
 *
 * <pre>
 *     EnvelopedData ::= SEQUENCE {
 *        version CMSVersion,
 *        originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
 *        recipientInfos RecipientInfos,
 *        encryptedContentInfo EncryptedContentInfo }
 *
 *     RecipientInfos ::= SET OF RecipientInfo
 * </pre>
 *
 * @version 0.98, 98/07/01
 * @author Ming Yung
 */
public final class EnvelopedData extends Sequence
{
  private int version;
  private OriginatorInfo originatorInfo;
  private Set recipientInfos;
  private EncryptedContentInfo encryptedContentInfo;

  /**
   * Constructs an EnvelopedData from a version number, an optional
   * OriginatorInfo, a Set of RecipientInfo and an EncryptedContentInfo
   */
  public EnvelopedData(int version, OriginatorInfo orig, Set recpts, 
                       EncryptedContentInfo eci)
  {
    this.version = version;
    addComponent(new com.dstc.security.asn1.Integer(version));

    if (orig != null)
    {
      this.originatorInfo = orig;
    }

    this.recipientInfos = recpts;
    SetOf setOf = new SetOf();
    Iterator it = recpts.iterator();
    while (it.hasNext())
    {
      setOf.addComponent((RecipientInfo)it.next());
    }
    addComponent(setOf);

    this.encryptedContentInfo = eci;
    addComponent(this.encryptedContentInfo);
  } 
    
  /**
   * Constructs an EnvelopedData from a DER encoding
   */
  public EnvelopedData(byte encoded[]) throws Asn1Exception
  {
    doDecode(encoded);
    int i = 0;

    this.version = 
      ((com.dstc.security.asn1.Integer)components.elementAt(i++)).getInt();

    Asn1 der = (Constructed)components.elementAt(i);
    if (der.getTagNumber() == 0)
    {
      this.originatorInfo = new OriginatorInfo(der.encode());
      i++;
    }
    
    this.recipientInfos = new HashSet();
    SetOf setOf = (SetOf)components.elementAt(i++);
    Vector comps = setOf.getComponents();
    for (int j=0; j<comps.size(); j++)
    {
      recipientInfos.add(new RecipientInfo(
          ((Asn1)comps.elementAt(j)).encode()));
    }

    this.encryptedContentInfo = 
      new EncryptedContentInfo(((Asn1)components.elementAt(i++)).encode());
  }

  /**
   * Returns the OriginatorInfo for this EnvelopedData
   */
  public OriginatorInfo getOriginatorInfo()
  {
    return this.originatorInfo;
  }

  /**
   * Returns the Set of RecipientInfos for this EnvelopedData
   */
  public Set getRecipientInfos()
  {
    return this.recipientInfos;
  }

  /**
   * Returns the EncryptedContentInfo for this EnvelopedData
   */
  public EncryptedContentInfo getEncryptedContentInfo()
  {
    return this.encryptedContentInfo;
  }
}
