//   NOTE: this is a machine generated file--editing not recommended
//
// sm_cms.cpp - class member functions for ASN.1 module CryptographicMessageSyntax
//
//   This file was generated by snacc on Mon Apr 22 22:34:19 2002
//   UBC snacc written by Mike Sample
//   A couple of enhancements made by IBM European Networking Center


#include "asn-incl.h"
#include "sm_vdatypes.h"
#include "sm_x501ud.h"
#include "sm_x411ub.h"
#include "sm_x411mtsas.h"
#include "sm_x501if.h"
#include "sm_x520sa.h"
#include "sm_x509cmn.h"
#include "sm_x509af.h"
#include "sm_x509ce.h"
#include "pkcs1oids.h"
#include "pkcs9oids.h"
#include "sm_cms.h"
#include "sm_ess.h"
#include "pkcs7.h"
#include "pkcs8.h"
#include "appleoids.h"
#include "pkcs10.h"

//------------------------------------------------------------------------------
// value defs


//------------------------------------------------------------------------------
// class member definitions:

OriginatorPublicKey::OriginatorPublicKey()
{
#if TCL
  algorithm = new AlgorithmIdentifier;
#else
  algorithm = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

OriginatorPublicKey::OriginatorPublicKey (const OriginatorPublicKey &)
{
  Asn1Error << "use of incompletely defined OriginatorPublicKey::OriginatorPublicKey (const OriginatorPublicKey &)" << endl;
  abort();
}

OriginatorPublicKey::~OriginatorPublicKey()
{
  delete algorithm;
}

AsnType *OriginatorPublicKey::Clone() const
{
  return new OriginatorPublicKey;
}

AsnType *OriginatorPublicKey::Copy() const
{
  return new OriginatorPublicKey (*this);
}

#if SNACC_DEEP_COPY
OriginatorPublicKey &OriginatorPublicKey::operator = (const OriginatorPublicKey &that)
#else // SNACC_DEEP_COPY
OriginatorPublicKey &OriginatorPublicKey::operator = (const OriginatorPublicKey &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.algorithm)
    {
      if (!algorithm)
        algorithm = new AlgorithmIdentifier;
      *algorithm = *that.algorithm;
    }
    else
    {
      delete algorithm;
      algorithm = NULL;
    }
    publicKey = that.publicKey;
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined OriginatorPublicKey &OriginatorPublicKey::operator = (const OriginatorPublicKey &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
OriginatorPublicKey::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

    l = publicKey.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = algorithm->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

  return totalLen;
} // OriginatorPublicKey::BEncContent


void OriginatorPublicKey::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    algorithm = new AlgorithmIdentifier;
    algorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-100);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    publicKey.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-101);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-102);
  }
  else
    return;
} // OriginatorPublicKey::BDecContent

AsnLen OriginatorPublicKey::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void OriginatorPublicKey::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "OriginatorPublicKey::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-103);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void OriginatorPublicKey::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  if (NOT_NULL (algorithm))
  {
    Indent (os, indentG);
    os << "algorithm ";
    os << *algorithm;
  }
  else
  {
    Indent (os, indentG);
    os << "algorithm ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "publicKey ";
    os << publicKey;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // OriginatorPublicKey::Print


AsnType *CertificateRevocationLists::Clone() const
{
  return new CertificateRevocationLists;
}

AsnType *CertificateRevocationLists::Copy() const
{
  return new CertificateRevocationLists (*this);
}

AsnLen CertificateRevocationLists::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
  return l;
}

void CertificateRevocationLists::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
  {
    Asn1Error << "CertificateRevocationLists::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-104);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

CertificateRevocationLists::CertificateRevocationLists (const CertificateRevocationLists &)
{
  Asn1Error << "use of incompletely defined CertificateRevocationLists::CertificateRevocationLists (const CertificateRevocationLists &)" << endl;
  abort();
}

CertificateRevocationLists::~CertificateRevocationLists()
{
  SetCurrToFirst();
  for (; Curr() != NULL; RemoveCurrFromList())
    ;
} // end of destructor

#if SNACC_DEEP_COPY
CertificateRevocationLists &CertificateRevocationLists::operator = (const CertificateRevocationLists &that)
#else // SNACC_DEEP_COPY
CertificateRevocationLists &CertificateRevocationLists::operator = (const CertificateRevocationLists &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    SetCurrToFirst();
    for (; Curr(); RemoveCurrFromList())
      ;

    //that.SetCurrToFirst();
    //for (; that.Curr(); that.GoNext())
    //  AppendCopy (*that.Curr());
    for (const AsnListElmt *run=that.first; run; run=run->next)
      AppendCopy (*run->elmt);
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined CertificateRevocationLists &CertificateRevocationLists::operator = (const CertificateRevocationLists &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void CertificateRevocationLists::Print (ostream &os) const
{
#ifndef NDEBUG
    os << "{ -- SEQUENCE/SET OF -- " << endl;
    indentG += stdIndentG;
    //SetCurrToFirst();
    //for (; Curr() != NULL; GoNext())
    for (const AsnListElmt *run=first; run; run=run->next)
    {
        Indent (os, indentG);
        //os << *Curr();
        os << *run->elmt;
        //if (Curr() != Last())
        if (run != last)
            os << ",";
        os << endl;
    }
    indentG -= stdIndentG;
    Indent (os, indentG);
    os << "}\n";
#endif /* NDEBUG */


} // Print


void  CertificateRevocationLists::SetCurrElmt (unsigned long int index)
{
  unsigned long int i;
  curr = first;
  if (count)
    for (i = 0; (i < (count-1)) && (i < index); i++)
      curr = curr->next;
} // CertificateRevocationLists::SetCurrElmt


unsigned long int  CertificateRevocationLists::GetCurrElmtIndex()
{
    unsigned long int i;
    AsnListElmt *tmp;
    if (curr != NULL)
    {
        for (i = 0, tmp = first; tmp != NULL; i++)
        {
            if (tmp == curr)
                return i;
            else
                tmp = tmp->next;
        }
    }
    return count;
} // CertificateRevocationLists::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
CertificateList *CertificateRevocationLists::Append()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt  = new CertificateList;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // CertificateRevocationLists::Append


// alloc new list elmt, put at begining of list
//  and return the component type
CertificateList  *CertificateRevocationLists::Prepend()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificateList;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // CertificateRevocationLists::Prepend


// alloc new list elmt, insert it before the
// current element and return the component type
// if the current element is null, the new element
// is placed at the beginning of the list.
CertificateList  *CertificateRevocationLists::InsertBefore()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificateList;
    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // CertificateRevocationLists::InsertBefore


// alloc new list elmt, insert it after the
// current element and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
CertificateList *CertificateRevocationLists::InsertAfter()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificateList;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // CertificateRevocationLists::InsertAfter


CertificateRevocationLists  &CertificateRevocationLists::AppendCopy (CertificateList &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificateList;
    *newElmt->elmt = elmt;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return *this;
} // AppendCopy


CertificateRevocationLists  &CertificateRevocationLists::PrependCopy (CertificateList &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificateList;
    *newElmt->elmt = elmt;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return *this;
} // CertificateRevocationLists::PrependCopy


// alloc new list elmt, insert it before the
// current element, copy the given elmt into the new elmt
// and return the component type.
// if the current element is null, the new element
// is placed at the beginning of the list.
CertificateRevocationLists &CertificateRevocationLists::InsertBeforeAndCopy (CertificateList &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificateList;
    *newElmt->elmt = elmt;

    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return *this;
} // CertificateRevocationLists::InsertBeforeAndCopy


// alloc new list elmt, insert it after the
// current element, copy given elmt in to new elmt
//  and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
CertificateRevocationLists  &CertificateRevocationLists::InsertAfterAndCopy (CertificateList &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificateList;
    *newElmt->elmt = elmt;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return *this;
} // CertificateRevocationLists::InsertAfterAndCopy


// remove current element from list if current element is not NULL 
// The new current element will be the next element.
// If the current element is the last element in the list
// the second but last element will become the new current element.
void CertificateRevocationLists::RemoveCurrFromList()
{
    AsnListElmt *del_elmt;

    if (curr != NULL)
    {
        del_elmt = curr;
        count--;

        if (count == 0)
            first = last = curr = NULL;
        else if (curr == first)
        {
            curr = first= first->next;
            first->prev = NULL;
        }
        else if (curr == last)
        {
            curr = last = last->prev;
            last->next = NULL;
        }
        else
        {
            curr->prev->next = curr->next;
            curr->next->prev = curr->prev;
        }

        delete del_elmt->elmt;
        delete del_elmt;
    }
}


AsnLen CertificateRevocationLists::BEncContent (BUF_TYPE b)
{
    AsnListElmt *currElmt;
    AsnLen elmtLen;
    AsnLen totalLen = 0;
    {
      int iii,icount;
      CSM_Buffer **tmpEnc=NULL;
      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
      {
      BEncEocIfNec (b);
        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
    elmtLen += BEncConsLen (outputBuf, elmtLen);

    elmtLen += BEncTag1 (outputBuf, UNIV, CONS, SEQ_TAG_CODE);
        ENCODE_BUF2(tmpEnc[iii]);
      }
      vdasnacc_sortSetOf(tmpEnc, icount);
      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
            SM_WriteToAsnBuf(tmpEnc[iii], b);
      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
       free(tmpEnc);
    }
        totalLen += elmtLen;
    return totalLen;
} // CertificateRevocationLists::BEncContent


void  CertificateRevocationLists::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
                                  AsnLen &bytesDecoded, ENV_TYPE env)
{
    CertificateList *listElmt;
    AsnTag tag1;
    AsnLen listBytesDecoded = 0;
    AsnLen elmtLen1;

    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
    {
        tag1 = BDecTag (b, listBytesDecoded, env);
        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
        {
            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
            break;
        }
        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
        {
            Asn1Error << "Unexpected Tag" << endl;
            SnaccExcep::throwMe(-105);
        }

        elmtLen1 = BDecLen (b, listBytesDecoded, env);
        listElmt = Append();
        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
    }

    bytesDecoded += listBytesDecoded;
} // CertificateRevocationLists::BDecContent


IssuerAndSerialNumber::IssuerAndSerialNumber()
{
#if TCL
  issuer = new Name;
#else
  issuer = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

IssuerAndSerialNumber::IssuerAndSerialNumber (const IssuerAndSerialNumber &)
{
  Asn1Error << "use of incompletely defined IssuerAndSerialNumber::IssuerAndSerialNumber (const IssuerAndSerialNumber &)" << endl;
  abort();
}

IssuerAndSerialNumber::~IssuerAndSerialNumber()
{
  delete issuer;
}

AsnType *IssuerAndSerialNumber::Clone() const
{
  return new IssuerAndSerialNumber;
}

AsnType *IssuerAndSerialNumber::Copy() const
{
  return new IssuerAndSerialNumber (*this);
}

#if SNACC_DEEP_COPY
IssuerAndSerialNumber &IssuerAndSerialNumber::operator = (const IssuerAndSerialNumber &that)
#else // SNACC_DEEP_COPY
IssuerAndSerialNumber &IssuerAndSerialNumber::operator = (const IssuerAndSerialNumber &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.issuer)
    {
      if (!issuer)
        issuer = new Name;
      *issuer = *that.issuer;
    }
    else
    {
      delete issuer;
      issuer = NULL;
    }
    serialNumber = that.serialNumber;
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined IssuerAndSerialNumber &IssuerAndSerialNumber::operator = (const IssuerAndSerialNumber &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
IssuerAndSerialNumber::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

    l = serialNumber.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
    totalLen += l;

    l = issuer->BEncContent (b);
    totalLen += l;

  return totalLen;
} // IssuerAndSerialNumber::BEncContent


void IssuerAndSerialNumber::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    issuer = new Name;
    issuer->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-106);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, INTEGER_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    serialNumber.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-107);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-108);
  }
  else
    return;
} // IssuerAndSerialNumber::BDecContent

AsnLen IssuerAndSerialNumber::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void IssuerAndSerialNumber::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "IssuerAndSerialNumber::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-109);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void IssuerAndSerialNumber::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  if (NOT_NULL (issuer))
  {
    Indent (os, indentG);
    os << "issuer ";
    os << *issuer;
  }
  else
  {
    Indent (os, indentG);
    os << "issuer ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "serialNumber ";
    os << serialNumber;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // IssuerAndSerialNumber::Print


OtherKeyAttribute::OtherKeyAttribute()
{
  keyAttr = NULL;
}

OtherKeyAttribute::OtherKeyAttribute (const OtherKeyAttribute &)
{
  Asn1Error << "use of incompletely defined OtherKeyAttribute::OtherKeyAttribute (const OtherKeyAttribute &)" << endl;
  abort();
}

OtherKeyAttribute::~OtherKeyAttribute()
{
  delete keyAttr;
}

AsnType *OtherKeyAttribute::Clone() const
{
  return new OtherKeyAttribute;
}

AsnType *OtherKeyAttribute::Copy() const
{
  return new OtherKeyAttribute (*this);
}

#if SNACC_DEEP_COPY
OtherKeyAttribute &OtherKeyAttribute::operator = (const OtherKeyAttribute &that)
#else // SNACC_DEEP_COPY
OtherKeyAttribute &OtherKeyAttribute::operator = (const OtherKeyAttribute &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    keyAttrId = that.keyAttrId;
    if (that.keyAttr)
    {
      if (!keyAttr)
        keyAttr = new AsnAny;
      *keyAttr = *that.keyAttr;
    }
    else
    {
      delete keyAttr;
      keyAttr = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined OtherKeyAttribute &OtherKeyAttribute::operator = (const OtherKeyAttribute &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
OtherKeyAttribute::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (keyAttr))
  {
        ENC_LOAD_ANYBUF(keyAttr, b, l);
    totalLen += l;
  }

    l = keyAttrId.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
    totalLen += l;

  return totalLen;
} // OtherKeyAttribute::BEncContent


void OtherKeyAttribute::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    keyAttrId.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = b.PeekByte();

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDecEoc (b, seqBytesDecoded, env);

        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-110);
  }

  // ANY type
    keyAttr = new AsnAny;
        DEC_LOAD_ANYBUF(keyAttr, b, seqBytesDecoded, env);


  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-111);
  }
  else
    return;
} // OtherKeyAttribute::BDecContent

AsnLen OtherKeyAttribute::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void OtherKeyAttribute::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "OtherKeyAttribute::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-112);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void OtherKeyAttribute::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "keyAttrId ";
    os << keyAttrId;
    os << "," << endl;
  }

  if (NOT_NULL (keyAttr))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "keyAttr ";
    os << *keyAttr;
  }
  else
  {
    Indent (os, indentG);
    os << "keyAttr ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // OtherKeyAttribute::Print


AsnType *DigestAlgorithmIdentifiers::Clone() const
{
  return new DigestAlgorithmIdentifiers;
}

AsnType *DigestAlgorithmIdentifiers::Copy() const
{
  return new DigestAlgorithmIdentifiers (*this);
}

AsnLen DigestAlgorithmIdentifiers::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
  return l;
}

void DigestAlgorithmIdentifiers::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
  {
    Asn1Error << "DigestAlgorithmIdentifiers::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-113);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

DigestAlgorithmIdentifiers::DigestAlgorithmIdentifiers (const DigestAlgorithmIdentifiers &)
{
  Asn1Error << "use of incompletely defined DigestAlgorithmIdentifiers::DigestAlgorithmIdentifiers (const DigestAlgorithmIdentifiers &)" << endl;
  abort();
}

DigestAlgorithmIdentifiers::~DigestAlgorithmIdentifiers()
{
  SetCurrToFirst();
  for (; Curr() != NULL; RemoveCurrFromList())
    ;
} // end of destructor

#if SNACC_DEEP_COPY
DigestAlgorithmIdentifiers &DigestAlgorithmIdentifiers::operator = (const DigestAlgorithmIdentifiers &that)
#else // SNACC_DEEP_COPY
DigestAlgorithmIdentifiers &DigestAlgorithmIdentifiers::operator = (const DigestAlgorithmIdentifiers &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    SetCurrToFirst();
    for (; Curr(); RemoveCurrFromList())
      ;

    //that.SetCurrToFirst();
    //for (; that.Curr(); that.GoNext())
    //  AppendCopy (*that.Curr());
    for (const AsnListElmt *run=that.first; run; run=run->next)
      AppendCopy (*run->elmt);
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined DigestAlgorithmIdentifiers &DigestAlgorithmIdentifiers::operator = (const DigestAlgorithmIdentifiers &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void DigestAlgorithmIdentifiers::Print (ostream &os) const
{
#ifndef NDEBUG
    os << "{ -- SEQUENCE/SET OF -- " << endl;
    indentG += stdIndentG;
    //SetCurrToFirst();
    //for (; Curr() != NULL; GoNext())
    for (const AsnListElmt *run=first; run; run=run->next)
    {
        Indent (os, indentG);
        //os << *Curr();
        os << *run->elmt;
        //if (Curr() != Last())
        if (run != last)
            os << ",";
        os << endl;
    }
    indentG -= stdIndentG;
    Indent (os, indentG);
    os << "}\n";
#endif /* NDEBUG */


} // Print


void  DigestAlgorithmIdentifiers::SetCurrElmt (unsigned long int index)
{
  unsigned long int i;
  curr = first;
  if (count)
    for (i = 0; (i < (count-1)) && (i < index); i++)
      curr = curr->next;
} // DigestAlgorithmIdentifiers::SetCurrElmt


unsigned long int  DigestAlgorithmIdentifiers::GetCurrElmtIndex()
{
    unsigned long int i;
    AsnListElmt *tmp;
    if (curr != NULL)
    {
        for (i = 0, tmp = first; tmp != NULL; i++)
        {
            if (tmp == curr)
                return i;
            else
                tmp = tmp->next;
        }
    }
    return count;
} // DigestAlgorithmIdentifiers::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
DigestAlgorithmIdentifier *DigestAlgorithmIdentifiers::Append()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt  = new DigestAlgorithmIdentifier;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // DigestAlgorithmIdentifiers::Append


// alloc new list elmt, put at begining of list
//  and return the component type
DigestAlgorithmIdentifier  *DigestAlgorithmIdentifiers::Prepend()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new DigestAlgorithmIdentifier;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // DigestAlgorithmIdentifiers::Prepend


// alloc new list elmt, insert it before the
// current element and return the component type
// if the current element is null, the new element
// is placed at the beginning of the list.
DigestAlgorithmIdentifier  *DigestAlgorithmIdentifiers::InsertBefore()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new DigestAlgorithmIdentifier;
    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // DigestAlgorithmIdentifiers::InsertBefore


// alloc new list elmt, insert it after the
// current element and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
DigestAlgorithmIdentifier *DigestAlgorithmIdentifiers::InsertAfter()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new DigestAlgorithmIdentifier;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // DigestAlgorithmIdentifiers::InsertAfter


DigestAlgorithmIdentifiers  &DigestAlgorithmIdentifiers::AppendCopy (DigestAlgorithmIdentifier &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new DigestAlgorithmIdentifier;
    *newElmt->elmt = elmt;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return *this;
} // AppendCopy


DigestAlgorithmIdentifiers  &DigestAlgorithmIdentifiers::PrependCopy (DigestAlgorithmIdentifier &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new DigestAlgorithmIdentifier;
    *newElmt->elmt = elmt;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return *this;
} // DigestAlgorithmIdentifiers::PrependCopy


// alloc new list elmt, insert it before the
// current element, copy the given elmt into the new elmt
// and return the component type.
// if the current element is null, the new element
// is placed at the beginning of the list.
DigestAlgorithmIdentifiers &DigestAlgorithmIdentifiers::InsertBeforeAndCopy (DigestAlgorithmIdentifier &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new DigestAlgorithmIdentifier;
    *newElmt->elmt = elmt;

    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return *this;
} // DigestAlgorithmIdentifiers::InsertBeforeAndCopy


// alloc new list elmt, insert it after the
// current element, copy given elmt in to new elmt
//  and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
DigestAlgorithmIdentifiers  &DigestAlgorithmIdentifiers::InsertAfterAndCopy (DigestAlgorithmIdentifier &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new DigestAlgorithmIdentifier;
    *newElmt->elmt = elmt;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return *this;
} // DigestAlgorithmIdentifiers::InsertAfterAndCopy


// remove current element from list if current element is not NULL 
// The new current element will be the next element.
// If the current element is the last element in the list
// the second but last element will become the new current element.
void DigestAlgorithmIdentifiers::RemoveCurrFromList()
{
    AsnListElmt *del_elmt;

    if (curr != NULL)
    {
        del_elmt = curr;
        count--;

        if (count == 0)
            first = last = curr = NULL;
        else if (curr == first)
        {
            curr = first= first->next;
            first->prev = NULL;
        }
        else if (curr == last)
        {
            curr = last = last->prev;
            last->next = NULL;
        }
        else
        {
            curr->prev->next = curr->next;
            curr->next->prev = curr->prev;
        }

        delete del_elmt->elmt;
        delete del_elmt;
    }
}


AsnLen DigestAlgorithmIdentifiers::BEncContent (BUF_TYPE b)
{
    AsnListElmt *currElmt;
    AsnLen elmtLen;
    AsnLen totalLen = 0;
    {
      int iii,icount;
      CSM_Buffer **tmpEnc=NULL;
      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
      {
      BEncEocIfNec (b);
        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
    elmtLen += BEncConsLen (outputBuf, elmtLen);

    elmtLen += BEncTag1 (outputBuf, UNIV, CONS, SEQ_TAG_CODE);
        ENCODE_BUF2(tmpEnc[iii]);
      }
      vdasnacc_sortSetOf(tmpEnc, icount);
      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
            SM_WriteToAsnBuf(tmpEnc[iii], b);
      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
       free(tmpEnc);
    }
        totalLen += elmtLen;
    return totalLen;
} // DigestAlgorithmIdentifiers::BEncContent


void  DigestAlgorithmIdentifiers::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
                                  AsnLen &bytesDecoded, ENV_TYPE env)
{
    DigestAlgorithmIdentifier *listElmt;
    AsnTag tag1;
    AsnLen listBytesDecoded = 0;
    AsnLen elmtLen1;

    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
    {
        tag1 = BDecTag (b, listBytesDecoded, env);
        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
        {
            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
            break;
        }
        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
        {
            Asn1Error << "Unexpected Tag" << endl;
            SnaccExcep::throwMe(-114);
        }

        elmtLen1 = BDecLen (b, listBytesDecoded, env);
        listElmt = Append();
        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
    }

    bytesDecoded += listBytesDecoded;
} // DigestAlgorithmIdentifiers::BDecContent


EncapsulatedContentInfo::EncapsulatedContentInfo()
{
  eContent = NULL;
}

EncapsulatedContentInfo::EncapsulatedContentInfo (const EncapsulatedContentInfo &)
{
  Asn1Error << "use of incompletely defined EncapsulatedContentInfo::EncapsulatedContentInfo (const EncapsulatedContentInfo &)" << endl;
  abort();
}

EncapsulatedContentInfo::~EncapsulatedContentInfo()
{
  delete eContent;
}

AsnType *EncapsulatedContentInfo::Clone() const
{
  return new EncapsulatedContentInfo;
}

AsnType *EncapsulatedContentInfo::Copy() const
{
  return new EncapsulatedContentInfo (*this);
}

#if SNACC_DEEP_COPY
EncapsulatedContentInfo &EncapsulatedContentInfo::operator = (const EncapsulatedContentInfo &that)
#else // SNACC_DEEP_COPY
EncapsulatedContentInfo &EncapsulatedContentInfo::operator = (const EncapsulatedContentInfo &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    eContentType = that.eContentType;
    if (that.eContent)
    {
      if (!eContent)
        eContent = new AsnOcts;
      *eContent = *that.eContent;
    }
    else
    {
      delete eContent;
      eContent = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined EncapsulatedContentInfo &EncapsulatedContentInfo::operator = (const EncapsulatedContentInfo &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
EncapsulatedContentInfo::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (eContent))
  {
      BEncEocIfNec (b);
    l = eContent->BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 0);
    totalLen += l;
  }

    l = eContentType.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
    totalLen += l;

  return totalLen;
} // EncapsulatedContentInfo::BEncContent


void EncapsulatedContentInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  AsnLen elmtLen2;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    eContentType.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-115);
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);

    if ((tag1 != MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
       && (tag1 != MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
    {
       Asn1Error << "Unexpected Tag" << endl;
       SnaccExcep::throwMe(-116);
    }

    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
    eContent = new AsnOcts;
    eContent->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
    if (elmtLen1 == INDEFINITE_LEN)
      BDecEoc (b, seqBytesDecoded, env);

  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-117);
  }
  else
    return;
} // EncapsulatedContentInfo::BDecContent

AsnLen EncapsulatedContentInfo::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void EncapsulatedContentInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "EncapsulatedContentInfo::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-118);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void EncapsulatedContentInfo::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "eContentType ";
    os << eContentType;
    os << "," << endl;
  }

  if (NOT_NULL (eContent))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "eContent ";
    os << *eContent;
  }
  else
  {
    Indent (os, indentG);
    os << "eContent ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // EncapsulatedContentInfo::Print


SignerIdentifier::SignerIdentifier()
{
  choiceId = issuerAndSerialNumberCid;
#if TCL
  issuerAndSerialNumber = new IssuerAndSerialNumber;
#else
  issuerAndSerialNumber = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

SignerIdentifier::SignerIdentifier (const SignerIdentifier &)
{
  Asn1Error << "use of incompletely defined SignerIdentifier::SignerIdentifier (const SignerIdentifier &)" << endl;
  abort();
}

SignerIdentifier::~SignerIdentifier()
{
  switch (choiceId)
  {
    case issuerAndSerialNumberCid:
      delete issuerAndSerialNumber;
      break;
    case subjectKeyIdentifierCid:
      delete subjectKeyIdentifier;
      break;
  } // end of switch
} // end of destructor

AsnType *SignerIdentifier::Clone() const
{
  return new SignerIdentifier;
}

AsnType *SignerIdentifier::Copy() const
{
  return new SignerIdentifier (*this);
}

#if SNACC_DEEP_COPY
SignerIdentifier &SignerIdentifier::operator = (const SignerIdentifier &that)
#else // SNACC_DEEP_COPY
SignerIdentifier &SignerIdentifier::operator = (const SignerIdentifier &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    switch (choiceId)
    {
      case issuerAndSerialNumberCid:
        delete issuerAndSerialNumber;
        break;
      case subjectKeyIdentifierCid:
        delete subjectKeyIdentifier;
        break;
    }
    switch (choiceId = that.choiceId)
    {
      case issuerAndSerialNumberCid:
        issuerAndSerialNumber = new IssuerAndSerialNumber;
        *issuerAndSerialNumber = *that.issuerAndSerialNumber;
        break;
      case subjectKeyIdentifierCid:
        subjectKeyIdentifier = new KeyIdentifier;
        *subjectKeyIdentifier = *that.subjectKeyIdentifier;
        break;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined SignerIdentifier &SignerIdentifier::operator = (const SignerIdentifier &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
SignerIdentifier::BEncContent (BUF_TYPE b)
{
  AsnLen l;
  switch (choiceId)
  {
    case issuerAndSerialNumberCid:
      BEncEocIfNec (b);
      l = issuerAndSerialNumber->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
      break;

    case subjectKeyIdentifierCid:
      l = subjectKeyIdentifier->BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, CNTX, PRIM, 0);
      break;

  } // end switch
  return l;
} // SignerIdentifier::BEncContent


void SignerIdentifier::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  switch (tag)
  {
    case MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE):
      choiceId = issuerAndSerialNumberCid;
      issuerAndSerialNumber = new IssuerAndSerialNumber;
        issuerAndSerialNumber->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
      break;

    case MAKE_TAG_ID (CNTX, PRIM, 0):
    case MAKE_TAG_ID (CNTX, CONS, 0):
      choiceId = subjectKeyIdentifierCid;
      subjectKeyIdentifier = new KeyIdentifier;
        subjectKeyIdentifier->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
      break;

    default:
      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
      SnaccExcep::throwMe(-119);
      break;
  } // end switch
} // SignerIdentifier::BDecContent


AsnLen SignerIdentifier::BEnc (BUF_TYPE b)
{
    AsnLen l;
    l = BEncContent (b);
    return l;
}

void SignerIdentifier::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
    AsnLen elmtLen;
    AsnTag tag;

    /*  CHOICEs are a special case - grab identifying tag */
    /*  this allows easier handling of nested CHOICEs */
    tag = BDecTag (b, bytesDecoded, env);
    elmtLen = BDecLen (b, bytesDecoded, env);
    BDecContent (b, tag, elmtLen, bytesDecoded, env);
}

void SignerIdentifier::Print (ostream &os) const
{
#ifndef NDEBUG
  switch (choiceId)
  {
    case issuerAndSerialNumberCid:
      os << "issuerAndSerialNumber ";
      if (issuerAndSerialNumber)
        os << *issuerAndSerialNumber;
      else
        os << "-- void3 --\n";
      break;

    case subjectKeyIdentifierCid:
      os << "subjectKeyIdentifier ";
      if (subjectKeyIdentifier)
        os << *subjectKeyIdentifier;
      else
        os << "-- void3 --\n";
      break;

  } // end of switch
#endif /* NDEBUG */
} // SignerIdentifier::Print

EncryptedContentInfo::EncryptedContentInfo()
{
#if TCL
  contentEncryptionAlgorithm = new ContentEncryptionAlgorithmIdentifier;
#else
  contentEncryptionAlgorithm = NULL; // incomplete initialization of mandatory element!
#endif // TCL
  encryptedContent = NULL;
}

EncryptedContentInfo::EncryptedContentInfo (const EncryptedContentInfo &)
{
  Asn1Error << "use of incompletely defined EncryptedContentInfo::EncryptedContentInfo (const EncryptedContentInfo &)" << endl;
  abort();
}

EncryptedContentInfo::~EncryptedContentInfo()
{
  delete contentEncryptionAlgorithm;
  delete encryptedContent;
}

AsnType *EncryptedContentInfo::Clone() const
{
  return new EncryptedContentInfo;
}

AsnType *EncryptedContentInfo::Copy() const
{
  return new EncryptedContentInfo (*this);
}

#if SNACC_DEEP_COPY
EncryptedContentInfo &EncryptedContentInfo::operator = (const EncryptedContentInfo &that)
#else // SNACC_DEEP_COPY
EncryptedContentInfo &EncryptedContentInfo::operator = (const EncryptedContentInfo &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    contentType = that.contentType;
    if (that.contentEncryptionAlgorithm)
    {
      if (!contentEncryptionAlgorithm)
        contentEncryptionAlgorithm = new ContentEncryptionAlgorithmIdentifier;
      *contentEncryptionAlgorithm = *that.contentEncryptionAlgorithm;
    }
    else
    {
      delete contentEncryptionAlgorithm;
      contentEncryptionAlgorithm = NULL;
    }
    if (that.encryptedContent)
    {
      if (!encryptedContent)
        encryptedContent = new EncryptedContent;
      *encryptedContent = *that.encryptedContent;
    }
    else
    {
      delete encryptedContent;
      encryptedContent = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined EncryptedContentInfo &EncryptedContentInfo::operator = (const EncryptedContentInfo &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
EncryptedContentInfo::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (encryptedContent))
  {
    l = encryptedContent->BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, CNTX, PRIM, 0);
    totalLen += l;
  }

      BEncEocIfNec (b);
    l = contentEncryptionAlgorithm->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

    l = contentType.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
    totalLen += l;

  return totalLen;
} // EncryptedContentInfo::BEncContent


void EncryptedContentInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    contentType.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-120);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    contentEncryptionAlgorithm = new ContentEncryptionAlgorithmIdentifier;
    contentEncryptionAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-121);
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, PRIM, 0))
    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    encryptedContent = new EncryptedContent;
    encryptedContent->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-122);
  }
  else
    return;
} // EncryptedContentInfo::BDecContent

AsnLen EncryptedContentInfo::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void EncryptedContentInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "EncryptedContentInfo::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-123);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void EncryptedContentInfo::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "contentType ";
    os << contentType;
    os << "," << endl;
  }

  if (NOT_NULL (contentEncryptionAlgorithm))
  {
    Indent (os, indentG);
    os << "contentEncryptionAlgorithm ";
    os << *contentEncryptionAlgorithm;
  }
  else
  {
    Indent (os, indentG);
    os << "contentEncryptionAlgorithm ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (encryptedContent))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "encryptedContent ";
    os << *encryptedContent;
  }
  else
  {
    Indent (os, indentG);
    os << "encryptedContent ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // EncryptedContentInfo::Print


RecipientIdentifier::RecipientIdentifier()
{
  choiceId = issuerAndSerialNumberCid;
#if TCL
  issuerAndSerialNumber = new IssuerAndSerialNumber;
#else
  issuerAndSerialNumber = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

RecipientIdentifier::RecipientIdentifier (const RecipientIdentifier &)
{
  Asn1Error << "use of incompletely defined RecipientIdentifier::RecipientIdentifier (const RecipientIdentifier &)" << endl;
  abort();
}

RecipientIdentifier::~RecipientIdentifier()
{
  switch (choiceId)
  {
    case issuerAndSerialNumberCid:
      delete issuerAndSerialNumber;
      break;
    case subjectKeyIdentifierCid:
      delete subjectKeyIdentifier;
      break;
  } // end of switch
} // end of destructor

AsnType *RecipientIdentifier::Clone() const
{
  return new RecipientIdentifier;
}

AsnType *RecipientIdentifier::Copy() const
{
  return new RecipientIdentifier (*this);
}

#if SNACC_DEEP_COPY
RecipientIdentifier &RecipientIdentifier::operator = (const RecipientIdentifier &that)
#else // SNACC_DEEP_COPY
RecipientIdentifier &RecipientIdentifier::operator = (const RecipientIdentifier &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    switch (choiceId)
    {
      case issuerAndSerialNumberCid:
        delete issuerAndSerialNumber;
        break;
      case subjectKeyIdentifierCid:
        delete subjectKeyIdentifier;
        break;
    }
    switch (choiceId = that.choiceId)
    {
      case issuerAndSerialNumberCid:
        issuerAndSerialNumber = new IssuerAndSerialNumber;
        *issuerAndSerialNumber = *that.issuerAndSerialNumber;
        break;
      case subjectKeyIdentifierCid:
        subjectKeyIdentifier = new KeyIdentifier;
        *subjectKeyIdentifier = *that.subjectKeyIdentifier;
        break;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined RecipientIdentifier &RecipientIdentifier::operator = (const RecipientIdentifier &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
RecipientIdentifier::BEncContent (BUF_TYPE b)
{
  AsnLen l;
  switch (choiceId)
  {
    case issuerAndSerialNumberCid:
      BEncEocIfNec (b);
      l = issuerAndSerialNumber->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
      break;

    case subjectKeyIdentifierCid:
      l = subjectKeyIdentifier->BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, CNTX, PRIM, 0);
      break;

  } // end switch
  return l;
} // RecipientIdentifier::BEncContent


void RecipientIdentifier::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  switch (tag)
  {
    case MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE):
      choiceId = issuerAndSerialNumberCid;
      issuerAndSerialNumber = new IssuerAndSerialNumber;
        issuerAndSerialNumber->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
      break;

    case MAKE_TAG_ID (CNTX, PRIM, 0):
    case MAKE_TAG_ID (CNTX, CONS, 0):
      choiceId = subjectKeyIdentifierCid;
      subjectKeyIdentifier = new KeyIdentifier;
        subjectKeyIdentifier->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
      break;

    default:
      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
      SnaccExcep::throwMe(-124);
      break;
  } // end switch
} // RecipientIdentifier::BDecContent


AsnLen RecipientIdentifier::BEnc (BUF_TYPE b)
{
    AsnLen l;
    l = BEncContent (b);
    return l;
}

void RecipientIdentifier::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
    AsnLen elmtLen;
    AsnTag tag;

    /*  CHOICEs are a special case - grab identifying tag */
    /*  this allows easier handling of nested CHOICEs */
    tag = BDecTag (b, bytesDecoded, env);
    elmtLen = BDecLen (b, bytesDecoded, env);
    BDecContent (b, tag, elmtLen, bytesDecoded, env);
}

void RecipientIdentifier::Print (ostream &os) const
{
#ifndef NDEBUG
  switch (choiceId)
  {
    case issuerAndSerialNumberCid:
      os << "issuerAndSerialNumber ";
      if (issuerAndSerialNumber)
        os << *issuerAndSerialNumber;
      else
        os << "-- void3 --\n";
      break;

    case subjectKeyIdentifierCid:
      os << "subjectKeyIdentifier ";
      if (subjectKeyIdentifier)
        os << *subjectKeyIdentifier;
      else
        os << "-- void3 --\n";
      break;

  } // end of switch
#endif /* NDEBUG */
} // RecipientIdentifier::Print

OriginatorIdentifierOrKey::OriginatorIdentifierOrKey()
{
  choiceId = issuerAndSerialNumberCid;
#if TCL
  issuerAndSerialNumber = new IssuerAndSerialNumber;
#else
  issuerAndSerialNumber = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

OriginatorIdentifierOrKey::OriginatorIdentifierOrKey (const OriginatorIdentifierOrKey &)
{
  Asn1Error << "use of incompletely defined OriginatorIdentifierOrKey::OriginatorIdentifierOrKey (const OriginatorIdentifierOrKey &)" << endl;
  abort();
}

OriginatorIdentifierOrKey::~OriginatorIdentifierOrKey()
{
  switch (choiceId)
  {
    case issuerAndSerialNumberCid:
      delete issuerAndSerialNumber;
      break;
    case subjectKeyIdentifierCid:
      delete subjectKeyIdentifier;
      break;
    case originatorKeyCid:
      delete originatorKey;
      break;
  } // end of switch
} // end of destructor

AsnType *OriginatorIdentifierOrKey::Clone() const
{
  return new OriginatorIdentifierOrKey;
}

AsnType *OriginatorIdentifierOrKey::Copy() const
{
  return new OriginatorIdentifierOrKey (*this);
}

#if SNACC_DEEP_COPY
OriginatorIdentifierOrKey &OriginatorIdentifierOrKey::operator = (const OriginatorIdentifierOrKey &that)
#else // SNACC_DEEP_COPY
OriginatorIdentifierOrKey &OriginatorIdentifierOrKey::operator = (const OriginatorIdentifierOrKey &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    switch (choiceId)
    {
      case issuerAndSerialNumberCid:
        delete issuerAndSerialNumber;
        break;
      case subjectKeyIdentifierCid:
        delete subjectKeyIdentifier;
        break;
      case originatorKeyCid:
        delete originatorKey;
        break;
    }
    switch (choiceId = that.choiceId)
    {
      case issuerAndSerialNumberCid:
        issuerAndSerialNumber = new IssuerAndSerialNumber;
        *issuerAndSerialNumber = *that.issuerAndSerialNumber;
        break;
      case subjectKeyIdentifierCid:
        subjectKeyIdentifier = new KeyIdentifier;
        *subjectKeyIdentifier = *that.subjectKeyIdentifier;
        break;
      case originatorKeyCid:
        originatorKey = new OriginatorPublicKey;
        *originatorKey = *that.originatorKey;
        break;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined OriginatorIdentifierOrKey &OriginatorIdentifierOrKey::operator = (const OriginatorIdentifierOrKey &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
OriginatorIdentifierOrKey::BEncContent (BUF_TYPE b)
{
  AsnLen l;
  switch (choiceId)
  {
    case issuerAndSerialNumberCid:
      BEncEocIfNec (b);
      l = issuerAndSerialNumber->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
      break;

    case subjectKeyIdentifierCid:
      l = subjectKeyIdentifier->BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, CNTX, PRIM, 0);
      break;

    case originatorKeyCid:
      BEncEocIfNec (b);
      l = originatorKey->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 1);
      break;

  } // end switch
  return l;
} // OriginatorIdentifierOrKey::BEncContent


void OriginatorIdentifierOrKey::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  switch (tag)
  {
    case MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE):
      choiceId = issuerAndSerialNumberCid;
      issuerAndSerialNumber = new IssuerAndSerialNumber;
        issuerAndSerialNumber->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
      break;

    case MAKE_TAG_ID (CNTX, PRIM, 0):
    case MAKE_TAG_ID (CNTX, CONS, 0):
      choiceId = subjectKeyIdentifierCid;
      subjectKeyIdentifier = new KeyIdentifier;
        subjectKeyIdentifier->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
      break;

    case MAKE_TAG_ID (CNTX, CONS, 1):
      choiceId = originatorKeyCid;
      originatorKey = new OriginatorPublicKey;
        originatorKey->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
      break;

    default:
      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
      SnaccExcep::throwMe(-125);
      break;
  } // end switch
} // OriginatorIdentifierOrKey::BDecContent


AsnLen OriginatorIdentifierOrKey::BEnc (BUF_TYPE b)
{
    AsnLen l;
    l = BEncContent (b);
    return l;
}

void OriginatorIdentifierOrKey::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
    AsnLen elmtLen;
    AsnTag tag;

    /*  CHOICEs are a special case - grab identifying tag */
    /*  this allows easier handling of nested CHOICEs */
    tag = BDecTag (b, bytesDecoded, env);
    elmtLen = BDecLen (b, bytesDecoded, env);
    BDecContent (b, tag, elmtLen, bytesDecoded, env);
}

void OriginatorIdentifierOrKey::Print (ostream &os) const
{
#ifndef NDEBUG
  switch (choiceId)
  {
    case issuerAndSerialNumberCid:
      os << "issuerAndSerialNumber ";
      if (issuerAndSerialNumber)
        os << *issuerAndSerialNumber;
      else
        os << "-- void3 --\n";
      break;

    case subjectKeyIdentifierCid:
      os << "subjectKeyIdentifier ";
      if (subjectKeyIdentifier)
        os << *subjectKeyIdentifier;
      else
        os << "-- void3 --\n";
      break;

    case originatorKeyCid:
      os << "originatorKey ";
      if (originatorKey)
        os << *originatorKey;
      else
        os << "-- void3 --\n";
      break;

  } // end of switch
#endif /* NDEBUG */
} // OriginatorIdentifierOrKey::Print

RecipientKeyIdentifier::RecipientKeyIdentifier()
{
  date = NULL;
  other = NULL;
}

RecipientKeyIdentifier::RecipientKeyIdentifier (const RecipientKeyIdentifier &)
{
  Asn1Error << "use of incompletely defined RecipientKeyIdentifier::RecipientKeyIdentifier (const RecipientKeyIdentifier &)" << endl;
  abort();
}

RecipientKeyIdentifier::~RecipientKeyIdentifier()
{
  delete date;
  delete other;
}

AsnType *RecipientKeyIdentifier::Clone() const
{
  return new RecipientKeyIdentifier;
}

AsnType *RecipientKeyIdentifier::Copy() const
{
  return new RecipientKeyIdentifier (*this);
}

#if SNACC_DEEP_COPY
RecipientKeyIdentifier &RecipientKeyIdentifier::operator = (const RecipientKeyIdentifier &that)
#else // SNACC_DEEP_COPY
RecipientKeyIdentifier &RecipientKeyIdentifier::operator = (const RecipientKeyIdentifier &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    subjectKeyIdentifier = that.subjectKeyIdentifier;
    if (that.date)
    {
      if (!date)
        date = new GeneralizedTime;
      *date = *that.date;
    }
    else
    {
      delete date;
      date = NULL;
    }
    if (that.other)
    {
      if (!other)
        other = new OtherKeyAttribute;
      *other = *that.other;
    }
    else
    {
      delete other;
      other = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined RecipientKeyIdentifier &RecipientKeyIdentifier::operator = (const RecipientKeyIdentifier &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
RecipientKeyIdentifier::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (other))
  {
      BEncEocIfNec (b);
    l = other->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;
  }

  if (NOT_NULL (date))
  {
    l = date->BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, GENERALIZEDTIME_TAG_CODE);
    totalLen += l;
  }

    l = subjectKeyIdentifier.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
    totalLen += l;

  return totalLen;
} // RecipientKeyIdentifier::BEncContent


void RecipientKeyIdentifier::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    subjectKeyIdentifier.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-126);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    date = new GeneralizedTime;
    date->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    other = new OtherKeyAttribute;
    other->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-127);
  }
  else
    return;
} // RecipientKeyIdentifier::BDecContent

AsnLen RecipientKeyIdentifier::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void RecipientKeyIdentifier::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "RecipientKeyIdentifier::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-128);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void RecipientKeyIdentifier::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "subjectKeyIdentifier ";
    os << subjectKeyIdentifier;
    os << "," << endl;
  }

  if (NOT_NULL (date))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "date ";
    os << *date;
  }
  else
  {
    Indent (os, indentG);
    os << "date ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (other))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "other ";
    os << *other;
  }
  else
  {
    Indent (os, indentG);
    os << "other ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // RecipientKeyIdentifier::Print


KEKIdentifier::KEKIdentifier()
{
  date = NULL;
  other = NULL;
}

KEKIdentifier::KEKIdentifier (const KEKIdentifier &)
{
  Asn1Error << "use of incompletely defined KEKIdentifier::KEKIdentifier (const KEKIdentifier &)" << endl;
  abort();
}

KEKIdentifier::~KEKIdentifier()
{
  delete date;
  delete other;
}

AsnType *KEKIdentifier::Clone() const
{
  return new KEKIdentifier;
}

AsnType *KEKIdentifier::Copy() const
{
  return new KEKIdentifier (*this);
}

#if SNACC_DEEP_COPY
KEKIdentifier &KEKIdentifier::operator = (const KEKIdentifier &that)
#else // SNACC_DEEP_COPY
KEKIdentifier &KEKIdentifier::operator = (const KEKIdentifier &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    keyIdentifier = that.keyIdentifier;
    if (that.date)
    {
      if (!date)
        date = new GeneralizedTime;
      *date = *that.date;
    }
    else
    {
      delete date;
      date = NULL;
    }
    if (that.other)
    {
      if (!other)
        other = new OtherKeyAttribute;
      *other = *that.other;
    }
    else
    {
      delete other;
      other = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined KEKIdentifier &KEKIdentifier::operator = (const KEKIdentifier &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
KEKIdentifier::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (other))
  {
      BEncEocIfNec (b);
    l = other->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;
  }

  if (NOT_NULL (date))
  {
    l = date->BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, GENERALIZEDTIME_TAG_CODE);
    totalLen += l;
  }

    l = keyIdentifier.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
    totalLen += l;

  return totalLen;
} // KEKIdentifier::BEncContent


void KEKIdentifier::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    keyIdentifier.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-129);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, GENERALIZEDTIME_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, GENERALIZEDTIME_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    date = new GeneralizedTime;
    date->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    other = new OtherKeyAttribute;
    other->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-130);
  }
  else
    return;
} // KEKIdentifier::BDecContent

AsnLen KEKIdentifier::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void KEKIdentifier::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "KEKIdentifier::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-131);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void KEKIdentifier::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "keyIdentifier ";
    os << keyIdentifier;
    os << "," << endl;
  }

  if (NOT_NULL (date))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "date ";
    os << *date;
  }
  else
  {
    Indent (os, indentG);
    os << "date ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (other))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "other ";
    os << *other;
  }
  else
  {
    Indent (os, indentG);
    os << "other ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // KEKIdentifier::Print


ExtendedCertificateInfo::ExtendedCertificateInfo()
{
#if TCL
  certificate = new Certificate;
#else
  certificate = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

ExtendedCertificateInfo::ExtendedCertificateInfo (const ExtendedCertificateInfo &)
{
  Asn1Error << "use of incompletely defined ExtendedCertificateInfo::ExtendedCertificateInfo (const ExtendedCertificateInfo &)" << endl;
  abort();
}

ExtendedCertificateInfo::~ExtendedCertificateInfo()
{
  delete certificate;
}

AsnType *ExtendedCertificateInfo::Clone() const
{
  return new ExtendedCertificateInfo;
}

AsnType *ExtendedCertificateInfo::Copy() const
{
  return new ExtendedCertificateInfo (*this);
}

#if SNACC_DEEP_COPY
ExtendedCertificateInfo &ExtendedCertificateInfo::operator = (const ExtendedCertificateInfo &that)
#else // SNACC_DEEP_COPY
ExtendedCertificateInfo &ExtendedCertificateInfo::operator = (const ExtendedCertificateInfo &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    version = that.version;
    if (that.certificate)
    {
      if (!certificate)
        certificate = new Certificate;
      *certificate = *that.certificate;
    }
    else
    {
      delete certificate;
      certificate = NULL;
    }
    attributes = that.attributes;
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined ExtendedCertificateInfo &ExtendedCertificateInfo::operator = (const ExtendedCertificateInfo &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
ExtendedCertificateInfo::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

      BEncEocIfNec (b);
    l = attributes.BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = certificate->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

    l = version.BEncContent (b);
    BEncDefLenTo127 (b, l);
    l++;

    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
    totalLen += l;

  return totalLen;
} // ExtendedCertificateInfo::BEncContent


void ExtendedCertificateInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-132);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    certificate = new Certificate;
    certificate->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-133);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    attributes.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-134);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-135);
  }
  else
    return;
} // ExtendedCertificateInfo::BDecContent

AsnLen ExtendedCertificateInfo::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void ExtendedCertificateInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "ExtendedCertificateInfo::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-136);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void ExtendedCertificateInfo::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "version ";
    os << version;
    os << "," << endl;
  }

  if (NOT_NULL (certificate))
  {
    Indent (os, indentG);
    os << "certificate ";
    os << *certificate;
  }
  else
  {
    Indent (os, indentG);
    os << "certificate ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "attributes ";
    os << attributes;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // ExtendedCertificateInfo::Print


SignerInfo::SignerInfo()
{
#if TCL
  sid = new SignerIdentifier;
#else
  sid = NULL; // incomplete initialization of mandatory element!
#endif // TCL
#if TCL
  digestAlgorithm = new DigestAlgorithmIdentifier;
#else
  digestAlgorithm = NULL; // incomplete initialization of mandatory element!
#endif // TCL
  signedAttrs = NULL;
#if TCL
  signatureAlgorithm = new SignatureAlgorithmIdentifier;
#else
  signatureAlgorithm = NULL; // incomplete initialization of mandatory element!
#endif // TCL
  unsignedAttrs = NULL;
}

SignerInfo::SignerInfo (const SignerInfo &)
{
  Asn1Error << "use of incompletely defined SignerInfo::SignerInfo (const SignerInfo &)" << endl;
  abort();
}

SignerInfo::~SignerInfo()
{
  delete sid;
  delete digestAlgorithm;
  delete signedAttrs;
  delete signatureAlgorithm;
  delete unsignedAttrs;
}

AsnType *SignerInfo::Clone() const
{
  return new SignerInfo;
}

AsnType *SignerInfo::Copy() const
{
  return new SignerInfo (*this);
}

#if SNACC_DEEP_COPY
SignerInfo &SignerInfo::operator = (const SignerInfo &that)
#else // SNACC_DEEP_COPY
SignerInfo &SignerInfo::operator = (const SignerInfo &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    version = that.version;
    if (that.sid)
    {
      if (!sid)
        sid = new SignerIdentifier;
      *sid = *that.sid;
    }
    else
    {
      delete sid;
      sid = NULL;
    }
    if (that.digestAlgorithm)
    {
      if (!digestAlgorithm)
        digestAlgorithm = new DigestAlgorithmIdentifier;
      *digestAlgorithm = *that.digestAlgorithm;
    }
    else
    {
      delete digestAlgorithm;
      digestAlgorithm = NULL;
    }
    if (that.signedAttrs)
    {
      if (!signedAttrs)
        signedAttrs = new Attributes;
      *signedAttrs = *that.signedAttrs;
    }
    else
    {
      delete signedAttrs;
      signedAttrs = NULL;
    }
    if (that.signatureAlgorithm)
    {
      if (!signatureAlgorithm)
        signatureAlgorithm = new SignatureAlgorithmIdentifier;
      *signatureAlgorithm = *that.signatureAlgorithm;
    }
    else
    {
      delete signatureAlgorithm;
      signatureAlgorithm = NULL;
    }
    signature = that.signature;
    if (that.unsignedAttrs)
    {
      if (!unsignedAttrs)
        unsignedAttrs = new Attributes;
      *unsignedAttrs = *that.unsignedAttrs;
    }
    else
    {
      delete unsignedAttrs;
      unsignedAttrs = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined SignerInfo &SignerInfo::operator = (const SignerInfo &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
SignerInfo::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (unsignedAttrs))
  {
      BEncEocIfNec (b);
    l = unsignedAttrs->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 1);
    totalLen += l;
  }

    l = signature.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = signatureAlgorithm->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

  if (NOT_NULL (signedAttrs))
  {
      BEncEocIfNec (b);
    l = signedAttrs->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 0);
    totalLen += l;
  }

      BEncEocIfNec (b);
    l = digestAlgorithm->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

    l = sid->BEncContent (b);
    totalLen += l;

    l = version.BEncContent (b);
    BEncDefLenTo127 (b, l);
    l++;

    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
    totalLen += l;

  return totalLen;
} // SignerInfo::BEncContent


void SignerInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-137);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (CNTX, PRIM, 0))
    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    sid = new SignerIdentifier;
    sid->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-138);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    digestAlgorithm = new DigestAlgorithmIdentifier;
    digestAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-139);
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    signedAttrs = new Attributes;
    signedAttrs->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    signatureAlgorithm = new SignatureAlgorithmIdentifier;
    signatureAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-140);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    signature.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-141);
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    unsignedAttrs = new Attributes;
    unsignedAttrs->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-142);
  }
  else
    return;
} // SignerInfo::BDecContent

AsnLen SignerInfo::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void SignerInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "SignerInfo::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-143);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void SignerInfo::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "version ";
    os << version;
    os << "," << endl;
  }

  if (NOT_NULL (sid))
  {
    Indent (os, indentG);
    os << "sid ";
    os << *sid;
  }
  else
  {
    Indent (os, indentG);
    os << "sid ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (digestAlgorithm))
  {
    Indent (os, indentG);
    os << "digestAlgorithm ";
    os << *digestAlgorithm;
  }
  else
  {
    Indent (os, indentG);
    os << "digestAlgorithm ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (signedAttrs))
  {
    Indent (os, indentG);
    os << "signedAttrs ";
    os << *signedAttrs;
  }
  else
  {
    Indent (os, indentG);
    os << "signedAttrs ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (signatureAlgorithm))
  {
    Indent (os, indentG);
    os << "signatureAlgorithm ";
    os << *signatureAlgorithm;
  }
  else
  {
    Indent (os, indentG);
    os << "signatureAlgorithm ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "signature ";
    os << signature;
    os << "," << endl;
  }

  if (NOT_NULL (unsignedAttrs))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "unsignedAttrs ";
    os << *unsignedAttrs;
  }
  else
  {
    Indent (os, indentG);
    os << "unsignedAttrs ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // SignerInfo::Print


KeyTransRecipientInfo::KeyTransRecipientInfo()
{
#if TCL
  rid = new RecipientIdentifier;
#else
  rid = NULL; // incomplete initialization of mandatory element!
#endif // TCL
#if TCL
  keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier;
#else
  keyEncryptionAlgorithm = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

KeyTransRecipientInfo::KeyTransRecipientInfo (const KeyTransRecipientInfo &)
{
  Asn1Error << "use of incompletely defined KeyTransRecipientInfo::KeyTransRecipientInfo (const KeyTransRecipientInfo &)" << endl;
  abort();
}

KeyTransRecipientInfo::~KeyTransRecipientInfo()
{
  delete rid;
  delete keyEncryptionAlgorithm;
}

AsnType *KeyTransRecipientInfo::Clone() const
{
  return new KeyTransRecipientInfo;
}

AsnType *KeyTransRecipientInfo::Copy() const
{
  return new KeyTransRecipientInfo (*this);
}

#if SNACC_DEEP_COPY
KeyTransRecipientInfo &KeyTransRecipientInfo::operator = (const KeyTransRecipientInfo &that)
#else // SNACC_DEEP_COPY
KeyTransRecipientInfo &KeyTransRecipientInfo::operator = (const KeyTransRecipientInfo &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    version = that.version;
    if (that.rid)
    {
      if (!rid)
        rid = new RecipientIdentifier;
      *rid = *that.rid;
    }
    else
    {
      delete rid;
      rid = NULL;
    }
    if (that.keyEncryptionAlgorithm)
    {
      if (!keyEncryptionAlgorithm)
        keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier;
      *keyEncryptionAlgorithm = *that.keyEncryptionAlgorithm;
    }
    else
    {
      delete keyEncryptionAlgorithm;
      keyEncryptionAlgorithm = NULL;
    }
    encryptedKey = that.encryptedKey;
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined KeyTransRecipientInfo &KeyTransRecipientInfo::operator = (const KeyTransRecipientInfo &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
KeyTransRecipientInfo::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

    l = encryptedKey.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = keyEncryptionAlgorithm->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

    l = rid->BEncContent (b);
    totalLen += l;

    l = version.BEncContent (b);
    BEncDefLenTo127 (b, l);
    l++;

    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
    totalLen += l;

  return totalLen;
} // KeyTransRecipientInfo::BEncContent


void KeyTransRecipientInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-144);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (CNTX, PRIM, 0))
    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    rid = new RecipientIdentifier;
    rid->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-145);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier;
    keyEncryptionAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-146);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    encryptedKey.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-147);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-148);
  }
  else
    return;
} // KeyTransRecipientInfo::BDecContent

AsnLen KeyTransRecipientInfo::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void KeyTransRecipientInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "KeyTransRecipientInfo::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-149);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void KeyTransRecipientInfo::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "version ";
    os << version;
    os << "," << endl;
  }

  if (NOT_NULL (rid))
  {
    Indent (os, indentG);
    os << "rid ";
    os << *rid;
  }
  else
  {
    Indent (os, indentG);
    os << "rid ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (keyEncryptionAlgorithm))
  {
    Indent (os, indentG);
    os << "keyEncryptionAlgorithm ";
    os << *keyEncryptionAlgorithm;
  }
  else
  {
    Indent (os, indentG);
    os << "keyEncryptionAlgorithm ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "encryptedKey ";
    os << encryptedKey;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // KeyTransRecipientInfo::Print


KeyAgreeRecipientIdentifier::KeyAgreeRecipientIdentifier()
{
  choiceId = issuerAndSerialNumberCid;
#if TCL
  issuerAndSerialNumber = new IssuerAndSerialNumber;
#else
  issuerAndSerialNumber = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

KeyAgreeRecipientIdentifier::KeyAgreeRecipientIdentifier (const KeyAgreeRecipientIdentifier &)
{
  Asn1Error << "use of incompletely defined KeyAgreeRecipientIdentifier::KeyAgreeRecipientIdentifier (const KeyAgreeRecipientIdentifier &)" << endl;
  abort();
}

KeyAgreeRecipientIdentifier::~KeyAgreeRecipientIdentifier()
{
  switch (choiceId)
  {
    case issuerAndSerialNumberCid:
      delete issuerAndSerialNumber;
      break;
    case rKeyIdCid:
      delete rKeyId;
      break;
  } // end of switch
} // end of destructor

AsnType *KeyAgreeRecipientIdentifier::Clone() const
{
  return new KeyAgreeRecipientIdentifier;
}

AsnType *KeyAgreeRecipientIdentifier::Copy() const
{
  return new KeyAgreeRecipientIdentifier (*this);
}

#if SNACC_DEEP_COPY
KeyAgreeRecipientIdentifier &KeyAgreeRecipientIdentifier::operator = (const KeyAgreeRecipientIdentifier &that)
#else // SNACC_DEEP_COPY
KeyAgreeRecipientIdentifier &KeyAgreeRecipientIdentifier::operator = (const KeyAgreeRecipientIdentifier &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    switch (choiceId)
    {
      case issuerAndSerialNumberCid:
        delete issuerAndSerialNumber;
        break;
      case rKeyIdCid:
        delete rKeyId;
        break;
    }
    switch (choiceId = that.choiceId)
    {
      case issuerAndSerialNumberCid:
        issuerAndSerialNumber = new IssuerAndSerialNumber;
        *issuerAndSerialNumber = *that.issuerAndSerialNumber;
        break;
      case rKeyIdCid:
        rKeyId = new RecipientKeyIdentifier;
        *rKeyId = *that.rKeyId;
        break;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined KeyAgreeRecipientIdentifier &KeyAgreeRecipientIdentifier::operator = (const KeyAgreeRecipientIdentifier &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
KeyAgreeRecipientIdentifier::BEncContent (BUF_TYPE b)
{
  AsnLen l;
  switch (choiceId)
  {
    case issuerAndSerialNumberCid:
      BEncEocIfNec (b);
      l = issuerAndSerialNumber->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
      break;

    case rKeyIdCid:
      BEncEocIfNec (b);
      l = rKeyId->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 0);
      break;

  } // end switch
  return l;
} // KeyAgreeRecipientIdentifier::BEncContent


void KeyAgreeRecipientIdentifier::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  switch (tag)
  {
    case MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE):
      choiceId = issuerAndSerialNumberCid;
      issuerAndSerialNumber = new IssuerAndSerialNumber;
        issuerAndSerialNumber->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
      break;

    case MAKE_TAG_ID (CNTX, CONS, 0):
      choiceId = rKeyIdCid;
      rKeyId = new RecipientKeyIdentifier;
        rKeyId->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
      break;

    default:
      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
      SnaccExcep::throwMe(-150);
      break;
  } // end switch
} // KeyAgreeRecipientIdentifier::BDecContent


AsnLen KeyAgreeRecipientIdentifier::BEnc (BUF_TYPE b)
{
    AsnLen l;
    l = BEncContent (b);
    return l;
}

void KeyAgreeRecipientIdentifier::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
    AsnLen elmtLen;
    AsnTag tag;

    /*  CHOICEs are a special case - grab identifying tag */
    /*  this allows easier handling of nested CHOICEs */
    tag = BDecTag (b, bytesDecoded, env);
    elmtLen = BDecLen (b, bytesDecoded, env);
    BDecContent (b, tag, elmtLen, bytesDecoded, env);
}

void KeyAgreeRecipientIdentifier::Print (ostream &os) const
{
#ifndef NDEBUG
  switch (choiceId)
  {
    case issuerAndSerialNumberCid:
      os << "issuerAndSerialNumber ";
      if (issuerAndSerialNumber)
        os << *issuerAndSerialNumber;
      else
        os << "-- void3 --\n";
      break;

    case rKeyIdCid:
      os << "rKeyId ";
      if (rKeyId)
        os << *rKeyId;
      else
        os << "-- void3 --\n";
      break;

  } // end of switch
#endif /* NDEBUG */
} // KeyAgreeRecipientIdentifier::Print

KEKRecipientInfo::KEKRecipientInfo()
{
#if TCL
  kekid = new KEKIdentifier;
#else
  kekid = NULL; // incomplete initialization of mandatory element!
#endif // TCL
#if TCL
  keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier;
#else
  keyEncryptionAlgorithm = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

KEKRecipientInfo::KEKRecipientInfo (const KEKRecipientInfo &)
{
  Asn1Error << "use of incompletely defined KEKRecipientInfo::KEKRecipientInfo (const KEKRecipientInfo &)" << endl;
  abort();
}

KEKRecipientInfo::~KEKRecipientInfo()
{
  delete kekid;
  delete keyEncryptionAlgorithm;
}

AsnType *KEKRecipientInfo::Clone() const
{
  return new KEKRecipientInfo;
}

AsnType *KEKRecipientInfo::Copy() const
{
  return new KEKRecipientInfo (*this);
}

#if SNACC_DEEP_COPY
KEKRecipientInfo &KEKRecipientInfo::operator = (const KEKRecipientInfo &that)
#else // SNACC_DEEP_COPY
KEKRecipientInfo &KEKRecipientInfo::operator = (const KEKRecipientInfo &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    version = that.version;
    if (that.kekid)
    {
      if (!kekid)
        kekid = new KEKIdentifier;
      *kekid = *that.kekid;
    }
    else
    {
      delete kekid;
      kekid = NULL;
    }
    if (that.keyEncryptionAlgorithm)
    {
      if (!keyEncryptionAlgorithm)
        keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier;
      *keyEncryptionAlgorithm = *that.keyEncryptionAlgorithm;
    }
    else
    {
      delete keyEncryptionAlgorithm;
      keyEncryptionAlgorithm = NULL;
    }
    encryptedKey = that.encryptedKey;
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined KEKRecipientInfo &KEKRecipientInfo::operator = (const KEKRecipientInfo &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
KEKRecipientInfo::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

    l = encryptedKey.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = keyEncryptionAlgorithm->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = kekid->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

    l = version.BEncContent (b);
    BEncDefLenTo127 (b, l);
    l++;

    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
    totalLen += l;

  return totalLen;
} // KEKRecipientInfo::BEncContent


void KEKRecipientInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-151);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    kekid = new KEKIdentifier;
    kekid->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-152);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier;
    keyEncryptionAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-153);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    encryptedKey.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-154);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-155);
  }
  else
    return;
} // KEKRecipientInfo::BDecContent

AsnLen KEKRecipientInfo::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void KEKRecipientInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "KEKRecipientInfo::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-156);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void KEKRecipientInfo::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "version ";
    os << version;
    os << "," << endl;
  }

  if (NOT_NULL (kekid))
  {
    Indent (os, indentG);
    os << "kekid ";
    os << *kekid;
  }
  else
  {
    Indent (os, indentG);
    os << "kekid ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (keyEncryptionAlgorithm))
  {
    Indent (os, indentG);
    os << "keyEncryptionAlgorithm ";
    os << *keyEncryptionAlgorithm;
  }
  else
  {
    Indent (os, indentG);
    os << "keyEncryptionAlgorithm ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "encryptedKey ";
    os << encryptedKey;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // KEKRecipientInfo::Print


ExtendedCertificate::ExtendedCertificate()
{
#if TCL
  extendedCertificateInfo = new ExtendedCertificateInfo;
#else
  extendedCertificateInfo = NULL; // incomplete initialization of mandatory element!
#endif // TCL
#if TCL
  signatureAlgorithm = new SignatureAlgorithmIdentifier;
#else
  signatureAlgorithm = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

ExtendedCertificate::ExtendedCertificate (const ExtendedCertificate &)
{
  Asn1Error << "use of incompletely defined ExtendedCertificate::ExtendedCertificate (const ExtendedCertificate &)" << endl;
  abort();
}

ExtendedCertificate::~ExtendedCertificate()
{
  delete extendedCertificateInfo;
  delete signatureAlgorithm;
}

AsnType *ExtendedCertificate::Clone() const
{
  return new ExtendedCertificate;
}

AsnType *ExtendedCertificate::Copy() const
{
  return new ExtendedCertificate (*this);
}

#if SNACC_DEEP_COPY
ExtendedCertificate &ExtendedCertificate::operator = (const ExtendedCertificate &that)
#else // SNACC_DEEP_COPY
ExtendedCertificate &ExtendedCertificate::operator = (const ExtendedCertificate &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.extendedCertificateInfo)
    {
      if (!extendedCertificateInfo)
        extendedCertificateInfo = new ExtendedCertificateInfo;
      *extendedCertificateInfo = *that.extendedCertificateInfo;
    }
    else
    {
      delete extendedCertificateInfo;
      extendedCertificateInfo = NULL;
    }
    if (that.signatureAlgorithm)
    {
      if (!signatureAlgorithm)
        signatureAlgorithm = new SignatureAlgorithmIdentifier;
      *signatureAlgorithm = *that.signatureAlgorithm;
    }
    else
    {
      delete signatureAlgorithm;
      signatureAlgorithm = NULL;
    }
    signature = that.signature;
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined ExtendedCertificate &ExtendedCertificate::operator = (const ExtendedCertificate &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
ExtendedCertificate::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

    l = signature.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, BITSTRING_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = signatureAlgorithm->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = extendedCertificateInfo->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

  return totalLen;
} // ExtendedCertificate::BEncContent


void ExtendedCertificate::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    extendedCertificateInfo = new ExtendedCertificateInfo;
    extendedCertificateInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-157);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    signatureAlgorithm = new SignatureAlgorithmIdentifier;
    signatureAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-158);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, BITSTRING_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, BITSTRING_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    signature.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-159);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-160);
  }
  else
    return;
} // ExtendedCertificate::BDecContent

AsnLen ExtendedCertificate::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void ExtendedCertificate::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "ExtendedCertificate::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-161);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void ExtendedCertificate::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  if (NOT_NULL (extendedCertificateInfo))
  {
    Indent (os, indentG);
    os << "extendedCertificateInfo ";
    os << *extendedCertificateInfo;
  }
  else
  {
    Indent (os, indentG);
    os << "extendedCertificateInfo ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (signatureAlgorithm))
  {
    Indent (os, indentG);
    os << "signatureAlgorithm ";
    os << *signatureAlgorithm;
  }
  else
  {
    Indent (os, indentG);
    os << "signatureAlgorithm ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "signature ";
    os << signature;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // ExtendedCertificate::Print


AsnType *SignerInfos::Clone() const
{
  return new SignerInfos;
}

AsnType *SignerInfos::Copy() const
{
  return new SignerInfos (*this);
}

AsnLen SignerInfos::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
  return l;
}

void SignerInfos::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
  {
    Asn1Error << "SignerInfos::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-162);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

SignerInfos::SignerInfos (const SignerInfos &)
{
  Asn1Error << "use of incompletely defined SignerInfos::SignerInfos (const SignerInfos &)" << endl;
  abort();
}

SignerInfos::~SignerInfos()
{
  SetCurrToFirst();
  for (; Curr() != NULL; RemoveCurrFromList())
    ;
} // end of destructor

#if SNACC_DEEP_COPY
SignerInfos &SignerInfos::operator = (const SignerInfos &that)
#else // SNACC_DEEP_COPY
SignerInfos &SignerInfos::operator = (const SignerInfos &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    SetCurrToFirst();
    for (; Curr(); RemoveCurrFromList())
      ;

    //that.SetCurrToFirst();
    //for (; that.Curr(); that.GoNext())
    //  AppendCopy (*that.Curr());
    for (const AsnListElmt *run=that.first; run; run=run->next)
      AppendCopy (*run->elmt);
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined SignerInfos &SignerInfos::operator = (const SignerInfos &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void SignerInfos::Print (ostream &os) const
{
#ifndef NDEBUG
    os << "{ -- SEQUENCE/SET OF -- " << endl;
    indentG += stdIndentG;
    //SetCurrToFirst();
    //for (; Curr() != NULL; GoNext())
    for (const AsnListElmt *run=first; run; run=run->next)
    {
        Indent (os, indentG);
        //os << *Curr();
        os << *run->elmt;
        //if (Curr() != Last())
        if (run != last)
            os << ",";
        os << endl;
    }
    indentG -= stdIndentG;
    Indent (os, indentG);
    os << "}\n";
#endif /* NDEBUG */


} // Print


void  SignerInfos::SetCurrElmt (unsigned long int index)
{
  unsigned long int i;
  curr = first;
  if (count)
    for (i = 0; (i < (count-1)) && (i < index); i++)
      curr = curr->next;
} // SignerInfos::SetCurrElmt


unsigned long int  SignerInfos::GetCurrElmtIndex()
{
    unsigned long int i;
    AsnListElmt *tmp;
    if (curr != NULL)
    {
        for (i = 0, tmp = first; tmp != NULL; i++)
        {
            if (tmp == curr)
                return i;
            else
                tmp = tmp->next;
        }
    }
    return count;
} // SignerInfos::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
SignerInfo *SignerInfos::Append()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt  = new SignerInfo;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // SignerInfos::Append


// alloc new list elmt, put at begining of list
//  and return the component type
SignerInfo  *SignerInfos::Prepend()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new SignerInfo;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // SignerInfos::Prepend


// alloc new list elmt, insert it before the
// current element and return the component type
// if the current element is null, the new element
// is placed at the beginning of the list.
SignerInfo  *SignerInfos::InsertBefore()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new SignerInfo;
    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // SignerInfos::InsertBefore


// alloc new list elmt, insert it after the
// current element and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
SignerInfo *SignerInfos::InsertAfter()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new SignerInfo;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // SignerInfos::InsertAfter


SignerInfos  &SignerInfos::AppendCopy (SignerInfo &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new SignerInfo;
    *newElmt->elmt = elmt;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return *this;
} // AppendCopy


SignerInfos  &SignerInfos::PrependCopy (SignerInfo &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new SignerInfo;
    *newElmt->elmt = elmt;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return *this;
} // SignerInfos::PrependCopy


// alloc new list elmt, insert it before the
// current element, copy the given elmt into the new elmt
// and return the component type.
// if the current element is null, the new element
// is placed at the beginning of the list.
SignerInfos &SignerInfos::InsertBeforeAndCopy (SignerInfo &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new SignerInfo;
    *newElmt->elmt = elmt;

    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return *this;
} // SignerInfos::InsertBeforeAndCopy


// alloc new list elmt, insert it after the
// current element, copy given elmt in to new elmt
//  and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
SignerInfos  &SignerInfos::InsertAfterAndCopy (SignerInfo &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new SignerInfo;
    *newElmt->elmt = elmt;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return *this;
} // SignerInfos::InsertAfterAndCopy


// remove current element from list if current element is not NULL 
// The new current element will be the next element.
// If the current element is the last element in the list
// the second but last element will become the new current element.
void SignerInfos::RemoveCurrFromList()
{
    AsnListElmt *del_elmt;

    if (curr != NULL)
    {
        del_elmt = curr;
        count--;

        if (count == 0)
            first = last = curr = NULL;
        else if (curr == first)
        {
            curr = first= first->next;
            first->prev = NULL;
        }
        else if (curr == last)
        {
            curr = last = last->prev;
            last->next = NULL;
        }
        else
        {
            curr->prev->next = curr->next;
            curr->next->prev = curr->prev;
        }

        delete del_elmt->elmt;
        delete del_elmt;
    }
}


AsnLen SignerInfos::BEncContent (BUF_TYPE b)
{
    AsnListElmt *currElmt;
    AsnLen elmtLen;
    AsnLen totalLen = 0;
    {
      int iii,icount;
      CSM_Buffer **tmpEnc=NULL;
      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
      {
      BEncEocIfNec (b);
        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
    elmtLen += BEncConsLen (outputBuf, elmtLen);

    elmtLen += BEncTag1 (outputBuf, UNIV, CONS, SEQ_TAG_CODE);
        ENCODE_BUF2(tmpEnc[iii]);
      }
      vdasnacc_sortSetOf(tmpEnc, icount);
      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
            SM_WriteToAsnBuf(tmpEnc[iii], b);
      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
       free(tmpEnc);
    }
        totalLen += elmtLen;
    return totalLen;
} // SignerInfos::BEncContent


void  SignerInfos::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
                                  AsnLen &bytesDecoded, ENV_TYPE env)
{
    SignerInfo *listElmt;
    AsnTag tag1;
    AsnLen listBytesDecoded = 0;
    AsnLen elmtLen1;

    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
    {
        tag1 = BDecTag (b, listBytesDecoded, env);
        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
        {
            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
            break;
        }
        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
        {
            Asn1Error << "Unexpected Tag" << endl;
            SnaccExcep::throwMe(-163);
        }

        elmtLen1 = BDecLen (b, listBytesDecoded, env);
        listElmt = Append();
        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
    }

    bytesDecoded += listBytesDecoded;
} // SignerInfos::BDecContent


RecipientEncryptedKey::RecipientEncryptedKey()
{
#if TCL
  rid = new KeyAgreeRecipientIdentifier;
#else
  rid = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

RecipientEncryptedKey::RecipientEncryptedKey (const RecipientEncryptedKey &)
{
  Asn1Error << "use of incompletely defined RecipientEncryptedKey::RecipientEncryptedKey (const RecipientEncryptedKey &)" << endl;
  abort();
}

RecipientEncryptedKey::~RecipientEncryptedKey()
{
  delete rid;
}

AsnType *RecipientEncryptedKey::Clone() const
{
  return new RecipientEncryptedKey;
}

AsnType *RecipientEncryptedKey::Copy() const
{
  return new RecipientEncryptedKey (*this);
}

#if SNACC_DEEP_COPY
RecipientEncryptedKey &RecipientEncryptedKey::operator = (const RecipientEncryptedKey &that)
#else // SNACC_DEEP_COPY
RecipientEncryptedKey &RecipientEncryptedKey::operator = (const RecipientEncryptedKey &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.rid)
    {
      if (!rid)
        rid = new KeyAgreeRecipientIdentifier;
      *rid = *that.rid;
    }
    else
    {
      delete rid;
      rid = NULL;
    }
    encryptedKey = that.encryptedKey;
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined RecipientEncryptedKey &RecipientEncryptedKey::operator = (const RecipientEncryptedKey &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
RecipientEncryptedKey::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

    l = encryptedKey.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
    totalLen += l;

    l = rid->BEncContent (b);
    totalLen += l;

  return totalLen;
} // RecipientEncryptedKey::BEncContent


void RecipientEncryptedKey::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    rid = new KeyAgreeRecipientIdentifier;
    rid->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-164);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    encryptedKey.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-165);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-166);
  }
  else
    return;
} // RecipientEncryptedKey::BDecContent

AsnLen RecipientEncryptedKey::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void RecipientEncryptedKey::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "RecipientEncryptedKey::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-167);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void RecipientEncryptedKey::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  if (NOT_NULL (rid))
  {
    Indent (os, indentG);
    os << "rid ";
    os << *rid;
  }
  else
  {
    Indent (os, indentG);
    os << "rid ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "encryptedKey ";
    os << encryptedKey;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // RecipientEncryptedKey::Print


CertificateChoices::CertificateChoices()
{
  choiceId = certificateCid;
#if TCL
  certificate = new Certificate;
#else
  certificate = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

CertificateChoices::CertificateChoices (const CertificateChoices &)
{
  Asn1Error << "use of incompletely defined CertificateChoices::CertificateChoices (const CertificateChoices &)" << endl;
  abort();
}

CertificateChoices::~CertificateChoices()
{
  switch (choiceId)
  {
    case certificateCid:
      delete certificate;
      break;
    case extendedCertificateCid:
      delete extendedCertificate;
      break;
    case attrCertCid:
      delete attrCert;
      break;
  } // end of switch
} // end of destructor

AsnType *CertificateChoices::Clone() const
{
  return new CertificateChoices;
}

AsnType *CertificateChoices::Copy() const
{
  return new CertificateChoices (*this);
}

#if SNACC_DEEP_COPY
CertificateChoices &CertificateChoices::operator = (const CertificateChoices &that)
#else // SNACC_DEEP_COPY
CertificateChoices &CertificateChoices::operator = (const CertificateChoices &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    switch (choiceId)
    {
      case certificateCid:
        delete certificate;
        break;
      case extendedCertificateCid:
        delete extendedCertificate;
        break;
      case attrCertCid:
        delete attrCert;
        break;
    }
    switch (choiceId = that.choiceId)
    {
      case certificateCid:
        certificate = new Certificate;
        *certificate = *that.certificate;
        break;
      case extendedCertificateCid:
        extendedCertificate = new ExtendedCertificate;
        *extendedCertificate = *that.extendedCertificate;
        break;
      case attrCertCid:
        attrCert = new AttributeCertificate;
        *attrCert = *that.attrCert;
        break;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined CertificateChoices &CertificateChoices::operator = (const CertificateChoices &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
CertificateChoices::BEncContent (BUF_TYPE b)
{
  AsnLen l;
  switch (choiceId)
  {
    case certificateCid:
      BEncEocIfNec (b);
      l = certificate->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
      break;

    case extendedCertificateCid:
      BEncEocIfNec (b);
      l = extendedCertificate->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 0);
      break;

    case attrCertCid:
      BEncEocIfNec (b);
      l = attrCert->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 1);
      break;

  } // end switch
  return l;
} // CertificateChoices::BEncContent


void CertificateChoices::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  switch (tag)
  {
    case MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE):
      choiceId = certificateCid;
      certificate = new Certificate;
        certificate->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
      break;

    case MAKE_TAG_ID (CNTX, CONS, 0):
      choiceId = extendedCertificateCid;
      extendedCertificate = new ExtendedCertificate;
        extendedCertificate->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
      break;

    case MAKE_TAG_ID (CNTX, CONS, 1):
      choiceId = attrCertCid;
      attrCert = new AttributeCertificate;
        attrCert->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
      break;

    default:
      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
      SnaccExcep::throwMe(-168);
      break;
  } // end switch
} // CertificateChoices::BDecContent


AsnLen CertificateChoices::BEnc (BUF_TYPE b)
{
    AsnLen l;
    l = BEncContent (b);
    return l;
}

void CertificateChoices::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
    AsnLen elmtLen;
    AsnTag tag;

    /*  CHOICEs are a special case - grab identifying tag */
    /*  this allows easier handling of nested CHOICEs */
    tag = BDecTag (b, bytesDecoded, env);
    elmtLen = BDecLen (b, bytesDecoded, env);
    BDecContent (b, tag, elmtLen, bytesDecoded, env);
}

void CertificateChoices::Print (ostream &os) const
{
#ifndef NDEBUG
  switch (choiceId)
  {
    case certificateCid:
      os << "certificate ";
      if (certificate)
        os << *certificate;
      else
        os << "-- void3 --\n";
      break;

    case extendedCertificateCid:
      os << "extendedCertificate ";
      if (extendedCertificate)
        os << *extendedCertificate;
      else
        os << "-- void3 --\n";
      break;

    case attrCertCid:
      os << "attrCert ";
      if (attrCert)
        os << *attrCert;
      else
        os << "-- void3 --\n";
      break;

  } // end of switch
#endif /* NDEBUG */
} // CertificateChoices::Print

AsnType *CertificateSet::Clone() const
{
  return new CertificateSet;
}

AsnType *CertificateSet::Copy() const
{
  return new CertificateSet (*this);
}

AsnLen CertificateSet::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
  return l;
}

void CertificateSet::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
  {
    Asn1Error << "CertificateSet::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-169);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

CertificateSet::CertificateSet (const CertificateSet &)
{
  Asn1Error << "use of incompletely defined CertificateSet::CertificateSet (const CertificateSet &)" << endl;
  abort();
}

CertificateSet::~CertificateSet()
{
  SetCurrToFirst();
  for (; Curr() != NULL; RemoveCurrFromList())
    ;
} // end of destructor

#if SNACC_DEEP_COPY
CertificateSet &CertificateSet::operator = (const CertificateSet &that)
#else // SNACC_DEEP_COPY
CertificateSet &CertificateSet::operator = (const CertificateSet &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    SetCurrToFirst();
    for (; Curr(); RemoveCurrFromList())
      ;

    //that.SetCurrToFirst();
    //for (; that.Curr(); that.GoNext())
    //  AppendCopy (*that.Curr());
    for (const AsnListElmt *run=that.first; run; run=run->next)
      AppendCopy (*run->elmt);
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined CertificateSet &CertificateSet::operator = (const CertificateSet &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void CertificateSet::Print (ostream &os) const
{
#ifndef NDEBUG
    os << "{ -- SEQUENCE/SET OF -- " << endl;
    indentG += stdIndentG;
    //SetCurrToFirst();
    //for (; Curr() != NULL; GoNext())
    for (const AsnListElmt *run=first; run; run=run->next)
    {
        Indent (os, indentG);
        //os << *Curr();
        os << *run->elmt;
        //if (Curr() != Last())
        if (run != last)
            os << ",";
        os << endl;
    }
    indentG -= stdIndentG;
    Indent (os, indentG);
    os << "}\n";
#endif /* NDEBUG */


} // Print


void  CertificateSet::SetCurrElmt (unsigned long int index)
{
  unsigned long int i;
  curr = first;
  if (count)
    for (i = 0; (i < (count-1)) && (i < index); i++)
      curr = curr->next;
} // CertificateSet::SetCurrElmt


unsigned long int  CertificateSet::GetCurrElmtIndex()
{
    unsigned long int i;
    AsnListElmt *tmp;
    if (curr != NULL)
    {
        for (i = 0, tmp = first; tmp != NULL; i++)
        {
            if (tmp == curr)
                return i;
            else
                tmp = tmp->next;
        }
    }
    return count;
} // CertificateSet::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
CertificateChoices *CertificateSet::Append()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt  = new CertificateChoices;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // CertificateSet::Append


// alloc new list elmt, put at begining of list
//  and return the component type
CertificateChoices  *CertificateSet::Prepend()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificateChoices;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // CertificateSet::Prepend


// alloc new list elmt, insert it before the
// current element and return the component type
// if the current element is null, the new element
// is placed at the beginning of the list.
CertificateChoices  *CertificateSet::InsertBefore()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificateChoices;
    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // CertificateSet::InsertBefore


// alloc new list elmt, insert it after the
// current element and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
CertificateChoices *CertificateSet::InsertAfter()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificateChoices;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // CertificateSet::InsertAfter


CertificateSet  &CertificateSet::AppendCopy (CertificateChoices &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificateChoices;
    *newElmt->elmt = elmt;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return *this;
} // AppendCopy


CertificateSet  &CertificateSet::PrependCopy (CertificateChoices &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificateChoices;
    *newElmt->elmt = elmt;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return *this;
} // CertificateSet::PrependCopy


// alloc new list elmt, insert it before the
// current element, copy the given elmt into the new elmt
// and return the component type.
// if the current element is null, the new element
// is placed at the beginning of the list.
CertificateSet &CertificateSet::InsertBeforeAndCopy (CertificateChoices &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificateChoices;
    *newElmt->elmt = elmt;

    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return *this;
} // CertificateSet::InsertBeforeAndCopy


// alloc new list elmt, insert it after the
// current element, copy given elmt in to new elmt
//  and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
CertificateSet  &CertificateSet::InsertAfterAndCopy (CertificateChoices &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new CertificateChoices;
    *newElmt->elmt = elmt;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return *this;
} // CertificateSet::InsertAfterAndCopy


// remove current element from list if current element is not NULL 
// The new current element will be the next element.
// If the current element is the last element in the list
// the second but last element will become the new current element.
void CertificateSet::RemoveCurrFromList()
{
    AsnListElmt *del_elmt;

    if (curr != NULL)
    {
        del_elmt = curr;
        count--;

        if (count == 0)
            first = last = curr = NULL;
        else if (curr == first)
        {
            curr = first= first->next;
            first->prev = NULL;
        }
        else if (curr == last)
        {
            curr = last = last->prev;
            last->next = NULL;
        }
        else
        {
            curr->prev->next = curr->next;
            curr->next->prev = curr->prev;
        }

        delete del_elmt->elmt;
        delete del_elmt;
    }
}


AsnLen CertificateSet::BEncContent (BUF_TYPE b)
{
    AsnListElmt *currElmt;
    AsnLen elmtLen;
    AsnLen totalLen = 0;
    {
      int iii,icount;
      CSM_Buffer **tmpEnc=NULL;
      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
      {
        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
        ENCODE_BUF2(tmpEnc[iii]);
      }
      vdasnacc_sortSetOf(tmpEnc, icount);
      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
            SM_WriteToAsnBuf(tmpEnc[iii], b);
      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
       free(tmpEnc);
    }
        totalLen += elmtLen;
    return totalLen;
} // CertificateSet::BEncContent


void  CertificateSet::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
                                  AsnLen &bytesDecoded, ENV_TYPE env)
{
    CertificateChoices *listElmt;
    AsnTag tag1;
    AsnLen listBytesDecoded = 0;
    AsnLen elmtLen1;

    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
    {
        tag1 = BDecTag (b, listBytesDecoded, env);
        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
        {
            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
            break;
        }
        if (!((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
         || (tag1 == MAKE_TAG_ID (CNTX, CONS, 0))
         || (tag1 == MAKE_TAG_ID (CNTX, CONS, 1))))
        {
            Asn1Error << "Unexpected Tag" << endl;
            SnaccExcep::throwMe(-170);
        }

        elmtLen1 = BDecLen (b, listBytesDecoded, env);
        listElmt = Append();
        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
    }

    bytesDecoded += listBytesDecoded;
} // CertificateSet::BDecContent


OriginatorInfo::OriginatorInfo()
{
  certs = NULL;
  crls = NULL;
}

OriginatorInfo::OriginatorInfo (const OriginatorInfo &)
{
  Asn1Error << "use of incompletely defined OriginatorInfo::OriginatorInfo (const OriginatorInfo &)" << endl;
  abort();
}

OriginatorInfo::~OriginatorInfo()
{
  delete certs;
  delete crls;
}

AsnType *OriginatorInfo::Clone() const
{
  return new OriginatorInfo;
}

AsnType *OriginatorInfo::Copy() const
{
  return new OriginatorInfo (*this);
}

#if SNACC_DEEP_COPY
OriginatorInfo &OriginatorInfo::operator = (const OriginatorInfo &that)
#else // SNACC_DEEP_COPY
OriginatorInfo &OriginatorInfo::operator = (const OriginatorInfo &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.certs)
    {
      if (!certs)
        certs = new CertificateSet;
      *certs = *that.certs;
    }
    else
    {
      delete certs;
      certs = NULL;
    }
    if (that.crls)
    {
      if (!crls)
        crls = new CertificateRevocationLists;
      *crls = *that.crls;
    }
    else
    {
      delete crls;
      crls = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined OriginatorInfo &OriginatorInfo::operator = (const OriginatorInfo &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
OriginatorInfo::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (crls))
  {
      BEncEocIfNec (b);
    l = crls->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 1);
    totalLen += l;
  }

  if (NOT_NULL (certs))
  {
      BEncEocIfNec (b);
    l = certs->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 0);
    totalLen += l;
  }

  return totalLen;
} // OriginatorInfo::BEncContent


void OriginatorInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  if (elmtLen0 == 0)
    return;
  else
  {
    tag1 = BDecTag (b, seqBytesDecoded, env);

    if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
    {
      BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
      bytesDecoded += seqBytesDecoded;
      return;
    }
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    certs = new CertificateSet;
    certs->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    crls = new CertificateRevocationLists;
    crls->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-171);
  }
  else
    return;
} // OriginatorInfo::BDecContent

AsnLen OriginatorInfo::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void OriginatorInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "OriginatorInfo::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-172);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void OriginatorInfo::Print (ostream &os) const
{
#ifndef NDEBUG
  int nonePrinted = true;
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  if (NOT_NULL (certs))
  {
    nonePrinted = false;
    Indent (os, indentG);
    os << "certs ";
    os << *certs;
  }
  else
  {
    Indent (os, indentG);
    os << "certs ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (crls))
  {
    if (!nonePrinted)
      os << "," << endl;
    nonePrinted = false;
    Indent (os, indentG);
    os << "crls ";
    os << *crls;
  }
  else
  {
    Indent (os, indentG);
    os << "crls ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // OriginatorInfo::Print


AsnType *RecipientEncryptedKeys::Clone() const
{
  return new RecipientEncryptedKeys;
}

AsnType *RecipientEncryptedKeys::Copy() const
{
  return new RecipientEncryptedKeys (*this);
}

AsnLen RecipientEncryptedKeys::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void RecipientEncryptedKeys::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "RecipientEncryptedKeys::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-173);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

RecipientEncryptedKeys::RecipientEncryptedKeys (const RecipientEncryptedKeys &)
{
  Asn1Error << "use of incompletely defined RecipientEncryptedKeys::RecipientEncryptedKeys (const RecipientEncryptedKeys &)" << endl;
  abort();
}

RecipientEncryptedKeys::~RecipientEncryptedKeys()
{
  SetCurrToFirst();
  for (; Curr() != NULL; RemoveCurrFromList())
    ;
} // end of destructor

#if SNACC_DEEP_COPY
RecipientEncryptedKeys &RecipientEncryptedKeys::operator = (const RecipientEncryptedKeys &that)
#else // SNACC_DEEP_COPY
RecipientEncryptedKeys &RecipientEncryptedKeys::operator = (const RecipientEncryptedKeys &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    SetCurrToFirst();
    for (; Curr(); RemoveCurrFromList())
      ;

    //that.SetCurrToFirst();
    //for (; that.Curr(); that.GoNext())
    //  AppendCopy (*that.Curr());
    for (const AsnListElmt *run=that.first; run; run=run->next)
      AppendCopy (*run->elmt);
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined RecipientEncryptedKeys &RecipientEncryptedKeys::operator = (const RecipientEncryptedKeys &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void RecipientEncryptedKeys::Print (ostream &os) const
{
#ifndef NDEBUG
    os << "{ -- SEQUENCE/SET OF -- " << endl;
    indentG += stdIndentG;
    //SetCurrToFirst();
    //for (; Curr() != NULL; GoNext())
    for (const AsnListElmt *run=first; run; run=run->next)
    {
        Indent (os, indentG);
        //os << *Curr();
        os << *run->elmt;
        //if (Curr() != Last())
        if (run != last)
            os << ",";
        os << endl;
    }
    indentG -= stdIndentG;
    Indent (os, indentG);
    os << "}\n";
#endif /* NDEBUG */


} // Print


void  RecipientEncryptedKeys::SetCurrElmt (unsigned long int index)
{
  unsigned long int i;
  curr = first;
  if (count)
    for (i = 0; (i < (count-1)) && (i < index); i++)
      curr = curr->next;
} // RecipientEncryptedKeys::SetCurrElmt


unsigned long int  RecipientEncryptedKeys::GetCurrElmtIndex()
{
    unsigned long int i;
    AsnListElmt *tmp;
    if (curr != NULL)
    {
        for (i = 0, tmp = first; tmp != NULL; i++)
        {
            if (tmp == curr)
                return i;
            else
                tmp = tmp->next;
        }
    }
    return count;
} // RecipientEncryptedKeys::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
RecipientEncryptedKey *RecipientEncryptedKeys::Append()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt  = new RecipientEncryptedKey;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // RecipientEncryptedKeys::Append


// alloc new list elmt, put at begining of list
//  and return the component type
RecipientEncryptedKey  *RecipientEncryptedKeys::Prepend()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new RecipientEncryptedKey;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // RecipientEncryptedKeys::Prepend


// alloc new list elmt, insert it before the
// current element and return the component type
// if the current element is null, the new element
// is placed at the beginning of the list.
RecipientEncryptedKey  *RecipientEncryptedKeys::InsertBefore()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new RecipientEncryptedKey;
    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // RecipientEncryptedKeys::InsertBefore


// alloc new list elmt, insert it after the
// current element and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
RecipientEncryptedKey *RecipientEncryptedKeys::InsertAfter()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new RecipientEncryptedKey;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // RecipientEncryptedKeys::InsertAfter


RecipientEncryptedKeys  &RecipientEncryptedKeys::AppendCopy (RecipientEncryptedKey &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new RecipientEncryptedKey;
    *newElmt->elmt = elmt;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return *this;
} // AppendCopy


RecipientEncryptedKeys  &RecipientEncryptedKeys::PrependCopy (RecipientEncryptedKey &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new RecipientEncryptedKey;
    *newElmt->elmt = elmt;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return *this;
} // RecipientEncryptedKeys::PrependCopy


// alloc new list elmt, insert it before the
// current element, copy the given elmt into the new elmt
// and return the component type.
// if the current element is null, the new element
// is placed at the beginning of the list.
RecipientEncryptedKeys &RecipientEncryptedKeys::InsertBeforeAndCopy (RecipientEncryptedKey &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new RecipientEncryptedKey;
    *newElmt->elmt = elmt;

    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return *this;
} // RecipientEncryptedKeys::InsertBeforeAndCopy


// alloc new list elmt, insert it after the
// current element, copy given elmt in to new elmt
//  and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
RecipientEncryptedKeys  &RecipientEncryptedKeys::InsertAfterAndCopy (RecipientEncryptedKey &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new RecipientEncryptedKey;
    *newElmt->elmt = elmt;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return *this;
} // RecipientEncryptedKeys::InsertAfterAndCopy


// remove current element from list if current element is not NULL 
// The new current element will be the next element.
// If the current element is the last element in the list
// the second but last element will become the new current element.
void RecipientEncryptedKeys::RemoveCurrFromList()
{
    AsnListElmt *del_elmt;

    if (curr != NULL)
    {
        del_elmt = curr;
        count--;

        if (count == 0)
            first = last = curr = NULL;
        else if (curr == first)
        {
            curr = first= first->next;
            first->prev = NULL;
        }
        else if (curr == last)
        {
            curr = last = last->prev;
            last->next = NULL;
        }
        else
        {
            curr->prev->next = curr->next;
            curr->next->prev = curr->prev;
        }

        delete del_elmt->elmt;
        delete del_elmt;
    }
}


AsnLen RecipientEncryptedKeys::BEncContent (BUF_TYPE b)
{
    AsnListElmt *currElmt;
    AsnLen elmtLen;
    AsnLen totalLen = 0;
    for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)
    {
      BEncEocIfNec (b);
        elmtLen = currElmt->elmt->BEncContent (b);
    elmtLen += BEncConsLen (b, elmtLen);

    elmtLen += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
        totalLen += elmtLen;
    }
    return totalLen;
} // RecipientEncryptedKeys::BEncContent


void  RecipientEncryptedKeys::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
                                  AsnLen &bytesDecoded, ENV_TYPE env)
{
    RecipientEncryptedKey *listElmt;
    AsnTag tag1;
    AsnLen listBytesDecoded = 0;
    AsnLen elmtLen1;

    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
    {
        tag1 = BDecTag (b, listBytesDecoded, env);
        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
        {
            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
            break;
        }
        if ((tag1 != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
        {
            Asn1Error << "Unexpected Tag" << endl;
            SnaccExcep::throwMe(-174);
        }

        elmtLen1 = BDecLen (b, listBytesDecoded, env);
        listElmt = Append();
        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
    }

    bytesDecoded += listBytesDecoded;
} // RecipientEncryptedKeys::BDecContent


KeyAgreeRecipientInfo::KeyAgreeRecipientInfo()
{
#if TCL
  originator = new OriginatorIdentifierOrKey;
#else
  originator = NULL; // incomplete initialization of mandatory element!
#endif // TCL
  ukm = NULL;
#if TCL
  keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier;
#else
  keyEncryptionAlgorithm = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

KeyAgreeRecipientInfo::KeyAgreeRecipientInfo (const KeyAgreeRecipientInfo &)
{
  Asn1Error << "use of incompletely defined KeyAgreeRecipientInfo::KeyAgreeRecipientInfo (const KeyAgreeRecipientInfo &)" << endl;
  abort();
}

KeyAgreeRecipientInfo::~KeyAgreeRecipientInfo()
{
  delete originator;
  delete ukm;
  delete keyEncryptionAlgorithm;
}

AsnType *KeyAgreeRecipientInfo::Clone() const
{
  return new KeyAgreeRecipientInfo;
}

AsnType *KeyAgreeRecipientInfo::Copy() const
{
  return new KeyAgreeRecipientInfo (*this);
}

#if SNACC_DEEP_COPY
KeyAgreeRecipientInfo &KeyAgreeRecipientInfo::operator = (const KeyAgreeRecipientInfo &that)
#else // SNACC_DEEP_COPY
KeyAgreeRecipientInfo &KeyAgreeRecipientInfo::operator = (const KeyAgreeRecipientInfo &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    version = that.version;
    if (that.originator)
    {
      if (!originator)
        originator = new OriginatorIdentifierOrKey;
      *originator = *that.originator;
    }
    else
    {
      delete originator;
      originator = NULL;
    }
    if (that.ukm)
    {
      if (!ukm)
        ukm = new UserKeyingMaterial;
      *ukm = *that.ukm;
    }
    else
    {
      delete ukm;
      ukm = NULL;
    }
    if (that.keyEncryptionAlgorithm)
    {
      if (!keyEncryptionAlgorithm)
        keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier;
      *keyEncryptionAlgorithm = *that.keyEncryptionAlgorithm;
    }
    else
    {
      delete keyEncryptionAlgorithm;
      keyEncryptionAlgorithm = NULL;
    }
    recipientEncryptedKeys = that.recipientEncryptedKeys;
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined KeyAgreeRecipientInfo &KeyAgreeRecipientInfo::operator = (const KeyAgreeRecipientInfo &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
KeyAgreeRecipientInfo::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

      BEncEocIfNec (b);
    l = recipientEncryptedKeys.BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = keyEncryptionAlgorithm->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

  if (NOT_NULL (ukm))
  {
      BEncEocIfNec (b);
    l = ukm->BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 1);
    totalLen += l;
  }

      BEncEocIfNec (b);
    l = originator->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 0);
    totalLen += l;

    l = version.BEncContent (b);
    BEncDefLenTo127 (b, l);
    l++;

    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
    totalLen += l;

  return totalLen;
} // KeyAgreeRecipientInfo::BEncContent


void KeyAgreeRecipientInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  AsnLen elmtLen2;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-175);
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
    originator = new OriginatorIdentifierOrKey;
    originator->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
    if (elmtLen1 == INDEFINITE_LEN)
      BDecEoc (b, seqBytesDecoded, env);

    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-176);
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);

    if ((tag1 != MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
       && (tag1 != MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
    {
       Asn1Error << "Unexpected Tag" << endl;
       SnaccExcep::throwMe(-177);
    }

    elmtLen2 = BDecLen (b, seqBytesDecoded, env);
    ukm = new UserKeyingMaterial;
    ukm->BDecContent (b, tag1, elmtLen2, seqBytesDecoded, env);
    if (elmtLen1 == INDEFINITE_LEN)
      BDecEoc (b, seqBytesDecoded, env);

    tag1 = BDecTag (b, seqBytesDecoded, env);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier;
    keyEncryptionAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-178);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    recipientEncryptedKeys.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-179);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-180);
  }
  else
    return;
} // KeyAgreeRecipientInfo::BDecContent

AsnLen KeyAgreeRecipientInfo::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void KeyAgreeRecipientInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "KeyAgreeRecipientInfo::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-181);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void KeyAgreeRecipientInfo::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "version ";
    os << version;
    os << "," << endl;
  }

  if (NOT_NULL (originator))
  {
    Indent (os, indentG);
    os << "originator ";
    os << *originator;
  }
  else
  {
    Indent (os, indentG);
    os << "originator ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (ukm))
  {
    Indent (os, indentG);
    os << "ukm ";
    os << *ukm;
  }
  else
  {
    Indent (os, indentG);
    os << "ukm ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (keyEncryptionAlgorithm))
  {
    Indent (os, indentG);
    os << "keyEncryptionAlgorithm ";
    os << *keyEncryptionAlgorithm;
  }
  else
  {
    Indent (os, indentG);
    os << "keyEncryptionAlgorithm ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "recipientEncryptedKeys ";
    os << recipientEncryptedKeys;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // KeyAgreeRecipientInfo::Print


RecipientInfo::RecipientInfo()
{
  choiceId = ktriCid;
#if TCL
  ktri = new KeyTransRecipientInfo;
#else
  ktri = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

RecipientInfo::RecipientInfo (const RecipientInfo &)
{
  Asn1Error << "use of incompletely defined RecipientInfo::RecipientInfo (const RecipientInfo &)" << endl;
  abort();
}

RecipientInfo::~RecipientInfo()
{
  switch (choiceId)
  {
    case ktriCid:
      delete ktri;
      break;
    case kariCid:
      delete kari;
      break;
    case kekriCid:
      delete kekri;
      break;
  } // end of switch
} // end of destructor

AsnType *RecipientInfo::Clone() const
{
  return new RecipientInfo;
}

AsnType *RecipientInfo::Copy() const
{
  return new RecipientInfo (*this);
}

#if SNACC_DEEP_COPY
RecipientInfo &RecipientInfo::operator = (const RecipientInfo &that)
#else // SNACC_DEEP_COPY
RecipientInfo &RecipientInfo::operator = (const RecipientInfo &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    switch (choiceId)
    {
      case ktriCid:
        delete ktri;
        break;
      case kariCid:
        delete kari;
        break;
      case kekriCid:
        delete kekri;
        break;
    }
    switch (choiceId = that.choiceId)
    {
      case ktriCid:
        ktri = new KeyTransRecipientInfo;
        *ktri = *that.ktri;
        break;
      case kariCid:
        kari = new KeyAgreeRecipientInfo;
        *kari = *that.kari;
        break;
      case kekriCid:
        kekri = new KEKRecipientInfo;
        *kekri = *that.kekri;
        break;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined RecipientInfo &RecipientInfo::operator = (const RecipientInfo &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
RecipientInfo::BEncContent (BUF_TYPE b)
{
  AsnLen l;
  switch (choiceId)
  {
    case ktriCid:
      BEncEocIfNec (b);
      l = ktri->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
      break;

    case kariCid:
      BEncEocIfNec (b);
      l = kari->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 1);
      break;

    case kekriCid:
      BEncEocIfNec (b);
      l = kekri->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 2);
      break;

  } // end switch
  return l;
} // RecipientInfo::BEncContent


void RecipientInfo::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  switch (tag)
  {
    case MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE):
      choiceId = ktriCid;
      ktri = new KeyTransRecipientInfo;
        ktri->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
      break;

    case MAKE_TAG_ID (CNTX, CONS, 1):
      choiceId = kariCid;
      kari = new KeyAgreeRecipientInfo;
        kari->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
      break;

    case MAKE_TAG_ID (CNTX, CONS, 2):
      choiceId = kekriCid;
      kekri = new KEKRecipientInfo;
        kekri->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
      break;

    default:
      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
      SnaccExcep::throwMe(-182);
      break;
  } // end switch
} // RecipientInfo::BDecContent


AsnLen RecipientInfo::BEnc (BUF_TYPE b)
{
    AsnLen l;
    l = BEncContent (b);
    return l;
}

void RecipientInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
    AsnLen elmtLen;
    AsnTag tag;

    /*  CHOICEs are a special case - grab identifying tag */
    /*  this allows easier handling of nested CHOICEs */
    tag = BDecTag (b, bytesDecoded, env);
    elmtLen = BDecLen (b, bytesDecoded, env);
    BDecContent (b, tag, elmtLen, bytesDecoded, env);
}

void RecipientInfo::Print (ostream &os) const
{
#ifndef NDEBUG
  switch (choiceId)
  {
    case ktriCid:
      os << "ktri ";
      if (ktri)
        os << *ktri;
      else
        os << "-- void3 --\n";
      break;

    case kariCid:
      os << "kari ";
      if (kari)
        os << *kari;
      else
        os << "-- void3 --\n";
      break;

    case kekriCid:
      os << "kekri ";
      if (kekri)
        os << *kekri;
      else
        os << "-- void3 --\n";
      break;

  } // end of switch
#endif /* NDEBUG */
} // RecipientInfo::Print

AsnType *RecipientInfos::Clone() const
{
  return new RecipientInfos;
}

AsnType *RecipientInfos::Copy() const
{
  return new RecipientInfos (*this);
}

AsnLen RecipientInfos::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
  return l;
}

void RecipientInfos::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
  {
    Asn1Error << "RecipientInfos::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-183);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

RecipientInfos::RecipientInfos (const RecipientInfos &)
{
  Asn1Error << "use of incompletely defined RecipientInfos::RecipientInfos (const RecipientInfos &)" << endl;
  abort();
}

RecipientInfos::~RecipientInfos()
{
  SetCurrToFirst();
  for (; Curr() != NULL; RemoveCurrFromList())
    ;
} // end of destructor

#if SNACC_DEEP_COPY
RecipientInfos &RecipientInfos::operator = (const RecipientInfos &that)
#else // SNACC_DEEP_COPY
RecipientInfos &RecipientInfos::operator = (const RecipientInfos &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    SetCurrToFirst();
    for (; Curr(); RemoveCurrFromList())
      ;

    //that.SetCurrToFirst();
    //for (; that.Curr(); that.GoNext())
    //  AppendCopy (*that.Curr());
    for (const AsnListElmt *run=that.first; run; run=run->next)
      AppendCopy (*run->elmt);
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined RecipientInfos &RecipientInfos::operator = (const RecipientInfos &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void RecipientInfos::Print (ostream &os) const
{
#ifndef NDEBUG
    os << "{ -- SEQUENCE/SET OF -- " << endl;
    indentG += stdIndentG;
    //SetCurrToFirst();
    //for (; Curr() != NULL; GoNext())
    for (const AsnListElmt *run=first; run; run=run->next)
    {
        Indent (os, indentG);
        //os << *Curr();
        os << *run->elmt;
        //if (Curr() != Last())
        if (run != last)
            os << ",";
        os << endl;
    }
    indentG -= stdIndentG;
    Indent (os, indentG);
    os << "}\n";
#endif /* NDEBUG */


} // Print


void  RecipientInfos::SetCurrElmt (unsigned long int index)
{
  unsigned long int i;
  curr = first;
  if (count)
    for (i = 0; (i < (count-1)) && (i < index); i++)
      curr = curr->next;
} // RecipientInfos::SetCurrElmt


unsigned long int  RecipientInfos::GetCurrElmtIndex()
{
    unsigned long int i;
    AsnListElmt *tmp;
    if (curr != NULL)
    {
        for (i = 0, tmp = first; tmp != NULL; i++)
        {
            if (tmp == curr)
                return i;
            else
                tmp = tmp->next;
        }
    }
    return count;
} // RecipientInfos::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
RecipientInfo *RecipientInfos::Append()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt  = new RecipientInfo;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // RecipientInfos::Append


// alloc new list elmt, put at begining of list
//  and return the component type
RecipientInfo  *RecipientInfos::Prepend()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new RecipientInfo;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // RecipientInfos::Prepend


// alloc new list elmt, insert it before the
// current element and return the component type
// if the current element is null, the new element
// is placed at the beginning of the list.
RecipientInfo  *RecipientInfos::InsertBefore()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new RecipientInfo;
    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // RecipientInfos::InsertBefore


// alloc new list elmt, insert it after the
// current element and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
RecipientInfo *RecipientInfos::InsertAfter()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new RecipientInfo;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // RecipientInfos::InsertAfter


RecipientInfos  &RecipientInfos::AppendCopy (RecipientInfo &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new RecipientInfo;
    *newElmt->elmt = elmt;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return *this;
} // AppendCopy


RecipientInfos  &RecipientInfos::PrependCopy (RecipientInfo &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new RecipientInfo;
    *newElmt->elmt = elmt;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return *this;
} // RecipientInfos::PrependCopy


// alloc new list elmt, insert it before the
// current element, copy the given elmt into the new elmt
// and return the component type.
// if the current element is null, the new element
// is placed at the beginning of the list.
RecipientInfos &RecipientInfos::InsertBeforeAndCopy (RecipientInfo &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new RecipientInfo;
    *newElmt->elmt = elmt;

    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return *this;
} // RecipientInfos::InsertBeforeAndCopy


// alloc new list elmt, insert it after the
// current element, copy given elmt in to new elmt
//  and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
RecipientInfos  &RecipientInfos::InsertAfterAndCopy (RecipientInfo &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new RecipientInfo;
    *newElmt->elmt = elmt;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return *this;
} // RecipientInfos::InsertAfterAndCopy


// remove current element from list if current element is not NULL 
// The new current element will be the next element.
// If the current element is the last element in the list
// the second but last element will become the new current element.
void RecipientInfos::RemoveCurrFromList()
{
    AsnListElmt *del_elmt;

    if (curr != NULL)
    {
        del_elmt = curr;
        count--;

        if (count == 0)
            first = last = curr = NULL;
        else if (curr == first)
        {
            curr = first= first->next;
            first->prev = NULL;
        }
        else if (curr == last)
        {
            curr = last = last->prev;
            last->next = NULL;
        }
        else
        {
            curr->prev->next = curr->next;
            curr->next->prev = curr->prev;
        }

        delete del_elmt->elmt;
        delete del_elmt;
    }
}


AsnLen RecipientInfos::BEncContent (BUF_TYPE b)
{
    AsnListElmt *currElmt;
    AsnLen elmtLen;
    AsnLen totalLen = 0;
    {
      int iii,icount;
      CSM_Buffer **tmpEnc=NULL;
      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
      {
        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
        ENCODE_BUF2(tmpEnc[iii]);
      }
      vdasnacc_sortSetOf(tmpEnc, icount);
      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
            SM_WriteToAsnBuf(tmpEnc[iii], b);
      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
       free(tmpEnc);
    }
        totalLen += elmtLen;
    return totalLen;
} // RecipientInfos::BEncContent


void  RecipientInfos::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
                                  AsnLen &bytesDecoded, ENV_TYPE env)
{
    RecipientInfo *listElmt;
    AsnTag tag1;
    AsnLen listBytesDecoded = 0;
    AsnLen elmtLen1;

    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
    {
        tag1 = BDecTag (b, listBytesDecoded, env);
        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
        {
            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
            break;
        }
        if (!((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
         || (tag1 == MAKE_TAG_ID (CNTX, CONS, 1))
         || (tag1 == MAKE_TAG_ID (CNTX, CONS, 2))))
        {
            Asn1Error << "Unexpected Tag" << endl;
            SnaccExcep::throwMe(-184);
        }

        elmtLen1 = BDecLen (b, listBytesDecoded, env);
        listElmt = Append();
        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
    }

    bytesDecoded += listBytesDecoded;
} // RecipientInfos::BDecContent


ContentInfo::ContentInfo()
{
}

ContentInfo::ContentInfo (const ContentInfo &)
{
  Asn1Error << "use of incompletely defined ContentInfo::ContentInfo (const ContentInfo &)" << endl;
  abort();
}

ContentInfo::~ContentInfo()
{
}

AsnType *ContentInfo::Clone() const
{
  return new ContentInfo;
}

AsnType *ContentInfo::Copy() const
{
  return new ContentInfo (*this);
}

#if SNACC_DEEP_COPY
ContentInfo &ContentInfo::operator = (const ContentInfo &that)
#else // SNACC_DEEP_COPY
ContentInfo &ContentInfo::operator = (const ContentInfo &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    contentType = that.contentType;
    content = that.content;
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined ContentInfo &ContentInfo::operator = (const ContentInfo &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
ContentInfo::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

      BEncEocIfNec (b);
        ENC_LOAD_ANYBUF(&content, b, l);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 0);
    totalLen += l;

    l = contentType.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
    totalLen += l;

  return totalLen;
} // ContentInfo::BEncContent


void ContentInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    contentType.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-185);
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
        DEC_LOAD_ANYBUF(&content, b, seqBytesDecoded, env);
    if (elmtLen1 == INDEFINITE_LEN)
      BDecEoc (b, seqBytesDecoded, env);

  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-186);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-187);
  }
  else
    return;
} // ContentInfo::BDecContent

AsnLen ContentInfo::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void ContentInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "ContentInfo::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-188);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void ContentInfo::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "contentType ";
    os << contentType;
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "content ";
    os << content;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // ContentInfo::Print


SignedData::SignedData()
{
#if TCL
  encapContentInfo = new EncapsulatedContentInfo;
#else
  encapContentInfo = NULL; // incomplete initialization of mandatory element!
#endif // TCL
  certificates = NULL;
  crls = NULL;
}

SignedData::SignedData (const SignedData &)
{
  Asn1Error << "use of incompletely defined SignedData::SignedData (const SignedData &)" << endl;
  abort();
}

SignedData::~SignedData()
{
  delete encapContentInfo;
  delete certificates;
  delete crls;
}

AsnType *SignedData::Clone() const
{
  return new SignedData;
}

AsnType *SignedData::Copy() const
{
  return new SignedData (*this);
}

#if SNACC_DEEP_COPY
SignedData &SignedData::operator = (const SignedData &that)
#else // SNACC_DEEP_COPY
SignedData &SignedData::operator = (const SignedData &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    version = that.version;
    digestAlgorithms = that.digestAlgorithms;
    if (that.encapContentInfo)
    {
      if (!encapContentInfo)
        encapContentInfo = new EncapsulatedContentInfo;
      *encapContentInfo = *that.encapContentInfo;
    }
    else
    {
      delete encapContentInfo;
      encapContentInfo = NULL;
    }
    if (that.certificates)
    {
      if (!certificates)
        certificates = new CertificateSet;
      *certificates = *that.certificates;
    }
    else
    {
      delete certificates;
      certificates = NULL;
    }
    if (that.crls)
    {
      if (!crls)
        crls = new CertificateRevocationLists;
      *crls = *that.crls;
    }
    else
    {
      delete crls;
      crls = NULL;
    }
    signerInfos = that.signerInfos;
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined SignedData &SignedData::operator = (const SignedData &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
SignedData::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

      BEncEocIfNec (b);
    l = signerInfos.BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
    totalLen += l;

  if (NOT_NULL (crls))
  {
      BEncEocIfNec (b);
    l = crls->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 1);
    totalLen += l;
  }

  if (NOT_NULL (certificates))
  {
      BEncEocIfNec (b);
    l = certificates->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 0);
    totalLen += l;
  }

      BEncEocIfNec (b);
    l = encapContentInfo->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = digestAlgorithms.BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
    totalLen += l;

    l = version.BEncContent (b);
    BEncDefLenTo127 (b, l);
    l++;

    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
    totalLen += l;

  return totalLen;
} // SignedData::BEncContent


void SignedData::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-189);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    digestAlgorithms.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-190);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    encapContentInfo = new EncapsulatedContentInfo;
    encapContentInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-191);
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    certificates = new CertificateSet;
    certificates->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    crls = new CertificateRevocationLists;
    crls->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    signerInfos.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-192);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-193);
  }
  else
    return;
} // SignedData::BDecContent

AsnLen SignedData::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void SignedData::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "SignedData::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-194);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void SignedData::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "version ";
    os << version;
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "digestAlgorithms ";
    os << digestAlgorithms;
    os << "," << endl;
  }

  if (NOT_NULL (encapContentInfo))
  {
    Indent (os, indentG);
    os << "encapContentInfo ";
    os << *encapContentInfo;
  }
  else
  {
    Indent (os, indentG);
    os << "encapContentInfo ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (certificates))
  {
    Indent (os, indentG);
    os << "certificates ";
    os << *certificates;
  }
  else
  {
    Indent (os, indentG);
    os << "certificates ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (crls))
  {
    Indent (os, indentG);
    os << "crls ";
    os << *crls;
  }
  else
  {
    Indent (os, indentG);
    os << "crls ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "signerInfos ";
    os << signerInfos;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // SignedData::Print


EnvelopedData::EnvelopedData()
{
  originatorInfo = NULL;
#if TCL
  encryptedContentInfo = new EncryptedContentInfo;
#else
  encryptedContentInfo = NULL; // incomplete initialization of mandatory element!
#endif // TCL
  unprotectedAttrs = NULL;
}

EnvelopedData::EnvelopedData (const EnvelopedData &)
{
  Asn1Error << "use of incompletely defined EnvelopedData::EnvelopedData (const EnvelopedData &)" << endl;
  abort();
}

EnvelopedData::~EnvelopedData()
{
  delete originatorInfo;
  delete encryptedContentInfo;
  delete unprotectedAttrs;
}

AsnType *EnvelopedData::Clone() const
{
  return new EnvelopedData;
}

AsnType *EnvelopedData::Copy() const
{
  return new EnvelopedData (*this);
}

#if SNACC_DEEP_COPY
EnvelopedData &EnvelopedData::operator = (const EnvelopedData &that)
#else // SNACC_DEEP_COPY
EnvelopedData &EnvelopedData::operator = (const EnvelopedData &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    version = that.version;
    if (that.originatorInfo)
    {
      if (!originatorInfo)
        originatorInfo = new OriginatorInfo;
      *originatorInfo = *that.originatorInfo;
    }
    else
    {
      delete originatorInfo;
      originatorInfo = NULL;
    }
    recipientInfos = that.recipientInfos;
    if (that.encryptedContentInfo)
    {
      if (!encryptedContentInfo)
        encryptedContentInfo = new EncryptedContentInfo;
      *encryptedContentInfo = *that.encryptedContentInfo;
    }
    else
    {
      delete encryptedContentInfo;
      encryptedContentInfo = NULL;
    }
    if (that.unprotectedAttrs)
    {
      if (!unprotectedAttrs)
        unprotectedAttrs = new Attributes;
      *unprotectedAttrs = *that.unprotectedAttrs;
    }
    else
    {
      delete unprotectedAttrs;
      unprotectedAttrs = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined EnvelopedData &EnvelopedData::operator = (const EnvelopedData &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
EnvelopedData::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (unprotectedAttrs))
  {
      BEncEocIfNec (b);
    l = unprotectedAttrs->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 1);
    totalLen += l;
  }

      BEncEocIfNec (b);
    l = encryptedContentInfo->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = recipientInfos.BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
    totalLen += l;

  if (NOT_NULL (originatorInfo))
  {
      BEncEocIfNec (b);
    l = originatorInfo->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 0);
    totalLen += l;
  }

    l = version.BEncContent (b);
    BEncDefLenTo127 (b, l);
    l++;

    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
    totalLen += l;

  return totalLen;
} // EnvelopedData::BEncContent


void EnvelopedData::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-195);
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    originatorInfo = new OriginatorInfo;
    originatorInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    recipientInfos.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-196);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    encryptedContentInfo = new EncryptedContentInfo;
    encryptedContentInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-197);
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    unprotectedAttrs = new Attributes;
    unprotectedAttrs->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-198);
  }
  else
    return;
} // EnvelopedData::BDecContent

AsnLen EnvelopedData::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void EnvelopedData::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "EnvelopedData::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-199);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void EnvelopedData::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "version ";
    os << version;
    os << "," << endl;
  }

  if (NOT_NULL (originatorInfo))
  {
    Indent (os, indentG);
    os << "originatorInfo ";
    os << *originatorInfo;
  }
  else
  {
    Indent (os, indentG);
    os << "originatorInfo ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "recipientInfos ";
    os << recipientInfos;
    os << "," << endl;
  }

  if (NOT_NULL (encryptedContentInfo))
  {
    Indent (os, indentG);
    os << "encryptedContentInfo ";
    os << *encryptedContentInfo;
  }
  else
  {
    Indent (os, indentG);
    os << "encryptedContentInfo ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (unprotectedAttrs))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "unprotectedAttrs ";
    os << *unprotectedAttrs;
  }
  else
  {
    Indent (os, indentG);
    os << "unprotectedAttrs ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // EnvelopedData::Print


DigestedData::DigestedData()
{
#if TCL
  digestAlgorithm = new DigestAlgorithmIdentifier;
#else
  digestAlgorithm = NULL; // incomplete initialization of mandatory element!
#endif // TCL
#if TCL
  encapContentInfo = new EncapsulatedContentInfo;
#else
  encapContentInfo = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

DigestedData::DigestedData (const DigestedData &)
{
  Asn1Error << "use of incompletely defined DigestedData::DigestedData (const DigestedData &)" << endl;
  abort();
}

DigestedData::~DigestedData()
{
  delete digestAlgorithm;
  delete encapContentInfo;
}

AsnType *DigestedData::Clone() const
{
  return new DigestedData;
}

AsnType *DigestedData::Copy() const
{
  return new DigestedData (*this);
}

#if SNACC_DEEP_COPY
DigestedData &DigestedData::operator = (const DigestedData &that)
#else // SNACC_DEEP_COPY
DigestedData &DigestedData::operator = (const DigestedData &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    version = that.version;
    if (that.digestAlgorithm)
    {
      if (!digestAlgorithm)
        digestAlgorithm = new DigestAlgorithmIdentifier;
      *digestAlgorithm = *that.digestAlgorithm;
    }
    else
    {
      delete digestAlgorithm;
      digestAlgorithm = NULL;
    }
    if (that.encapContentInfo)
    {
      if (!encapContentInfo)
        encapContentInfo = new EncapsulatedContentInfo;
      *encapContentInfo = *that.encapContentInfo;
    }
    else
    {
      delete encapContentInfo;
      encapContentInfo = NULL;
    }
    digest = that.digest;
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined DigestedData &DigestedData::operator = (const DigestedData &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
DigestedData::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

    l = digest.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = encapContentInfo->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = digestAlgorithm->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

    l = version.BEncContent (b);
    BEncDefLenTo127 (b, l);
    l++;

    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
    totalLen += l;

  return totalLen;
} // DigestedData::BEncContent


void DigestedData::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-200);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    digestAlgorithm = new DigestAlgorithmIdentifier;
    digestAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-201);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    encapContentInfo = new EncapsulatedContentInfo;
    encapContentInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-202);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    digest.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-203);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-204);
  }
  else
    return;
} // DigestedData::BDecContent

AsnLen DigestedData::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void DigestedData::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "DigestedData::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-205);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void DigestedData::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "version ";
    os << version;
    os << "," << endl;
  }

  if (NOT_NULL (digestAlgorithm))
  {
    Indent (os, indentG);
    os << "digestAlgorithm ";
    os << *digestAlgorithm;
  }
  else
  {
    Indent (os, indentG);
    os << "digestAlgorithm ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (encapContentInfo))
  {
    Indent (os, indentG);
    os << "encapContentInfo ";
    os << *encapContentInfo;
  }
  else
  {
    Indent (os, indentG);
    os << "encapContentInfo ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "digest ";
    os << digest;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // DigestedData::Print


EncryptedData::EncryptedData()
{
#if TCL
  encryptedContentInfo = new EncryptedContentInfo;
#else
  encryptedContentInfo = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

EncryptedData::EncryptedData (const EncryptedData &)
{
  Asn1Error << "use of incompletely defined EncryptedData::EncryptedData (const EncryptedData &)" << endl;
  abort();
}

EncryptedData::~EncryptedData()
{
  delete encryptedContentInfo;
}

AsnType *EncryptedData::Clone() const
{
  return new EncryptedData;
}

AsnType *EncryptedData::Copy() const
{
  return new EncryptedData (*this);
}

#if SNACC_DEEP_COPY
EncryptedData &EncryptedData::operator = (const EncryptedData &that)
#else // SNACC_DEEP_COPY
EncryptedData &EncryptedData::operator = (const EncryptedData &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    version = that.version;
    if (that.encryptedContentInfo)
    {
      if (!encryptedContentInfo)
        encryptedContentInfo = new EncryptedContentInfo;
      *encryptedContentInfo = *that.encryptedContentInfo;
    }
    else
    {
      delete encryptedContentInfo;
      encryptedContentInfo = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined EncryptedData &EncryptedData::operator = (const EncryptedData &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
EncryptedData::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

      BEncEocIfNec (b);
    l = encryptedContentInfo->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

    l = version.BEncContent (b);
    BEncDefLenTo127 (b, l);
    l++;

    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
    totalLen += l;

  return totalLen;
} // EncryptedData::BEncContent


void EncryptedData::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-206);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    encryptedContentInfo = new EncryptedContentInfo;
    encryptedContentInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-207);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-208);
  }
  else
    return;
} // EncryptedData::BDecContent

AsnLen EncryptedData::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void EncryptedData::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "EncryptedData::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-209);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void EncryptedData::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "version ";
    os << version;
    os << "," << endl;
  }

  if (NOT_NULL (encryptedContentInfo))
  {
    Indent (os, indentG);
    os << "encryptedContentInfo ";
    os << *encryptedContentInfo;
  }
  else
  {
    Indent (os, indentG);
    os << "encryptedContentInfo ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // EncryptedData::Print


AuthenticatedData::AuthenticatedData()
{
  originatorInfo = NULL;
#if TCL
  macAlgorithm = new MessageAuthenticationCodeAlgorithm;
#else
  macAlgorithm = NULL; // incomplete initialization of mandatory element!
#endif // TCL
  digestAlgorithm = NULL;
#if TCL
  encapContentInfo = new EncapsulatedContentInfo;
#else
  encapContentInfo = NULL; // incomplete initialization of mandatory element!
#endif // TCL
  authenctiatedAttributes = NULL;
  unauthenticatedAttributes = NULL;
}

AuthenticatedData::AuthenticatedData (const AuthenticatedData &)
{
  Asn1Error << "use of incompletely defined AuthenticatedData::AuthenticatedData (const AuthenticatedData &)" << endl;
  abort();
}

AuthenticatedData::~AuthenticatedData()
{
  delete originatorInfo;
  delete macAlgorithm;
  delete digestAlgorithm;
  delete encapContentInfo;
  delete authenctiatedAttributes;
  delete unauthenticatedAttributes;
}

AsnType *AuthenticatedData::Clone() const
{
  return new AuthenticatedData;
}

AsnType *AuthenticatedData::Copy() const
{
  return new AuthenticatedData (*this);
}

#if SNACC_DEEP_COPY
AuthenticatedData &AuthenticatedData::operator = (const AuthenticatedData &that)
#else // SNACC_DEEP_COPY
AuthenticatedData &AuthenticatedData::operator = (const AuthenticatedData &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    version = that.version;
    if (that.originatorInfo)
    {
      if (!originatorInfo)
        originatorInfo = new OriginatorInfo;
      *originatorInfo = *that.originatorInfo;
    }
    else
    {
      delete originatorInfo;
      originatorInfo = NULL;
    }
    recipientInfos = that.recipientInfos;
    if (that.macAlgorithm)
    {
      if (!macAlgorithm)
        macAlgorithm = new MessageAuthenticationCodeAlgorithm;
      *macAlgorithm = *that.macAlgorithm;
    }
    else
    {
      delete macAlgorithm;
      macAlgorithm = NULL;
    }
    if (that.digestAlgorithm)
    {
      if (!digestAlgorithm)
        digestAlgorithm = new DigestAlgorithmIdentifier;
      *digestAlgorithm = *that.digestAlgorithm;
    }
    else
    {
      delete digestAlgorithm;
      digestAlgorithm = NULL;
    }
    if (that.encapContentInfo)
    {
      if (!encapContentInfo)
        encapContentInfo = new EncapsulatedContentInfo;
      *encapContentInfo = *that.encapContentInfo;
    }
    else
    {
      delete encapContentInfo;
      encapContentInfo = NULL;
    }
    if (that.authenctiatedAttributes)
    {
      if (!authenctiatedAttributes)
        authenctiatedAttributes = new Attributes;
      *authenctiatedAttributes = *that.authenctiatedAttributes;
    }
    else
    {
      delete authenctiatedAttributes;
      authenctiatedAttributes = NULL;
    }
    mac = that.mac;
    if (that.unauthenticatedAttributes)
    {
      if (!unauthenticatedAttributes)
        unauthenticatedAttributes = new Attributes;
      *unauthenticatedAttributes = *that.unauthenticatedAttributes;
    }
    else
    {
      delete unauthenticatedAttributes;
      unauthenticatedAttributes = NULL;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined AuthenticatedData &AuthenticatedData::operator = (const AuthenticatedData &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
AuthenticatedData::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

  if (NOT_NULL (unauthenticatedAttributes))
  {
      BEncEocIfNec (b);
    l = unauthenticatedAttributes->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 3);
    totalLen += l;
  }

    l = mac.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
    totalLen += l;

  if (NOT_NULL (authenctiatedAttributes))
  {
      BEncEocIfNec (b);
    l = authenctiatedAttributes->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 2);
    totalLen += l;
  }

      BEncEocIfNec (b);
    l = encapContentInfo->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

  if (NOT_NULL (digestAlgorithm))
  {
      BEncEocIfNec (b);
    l = digestAlgorithm->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 1);
    totalLen += l;
  }

      BEncEocIfNec (b);
    l = macAlgorithm->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = recipientInfos.BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
    totalLen += l;

  if (NOT_NULL (originatorInfo))
  {
      BEncEocIfNec (b);
    l = originatorInfo->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 0);
    totalLen += l;
  }

    l = version.BEncContent (b);
    BEncDefLenTo127 (b, l);
    l++;

    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
    totalLen += l;

  return totalLen;
} // AuthenticatedData::BEncContent


void AuthenticatedData::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    version.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-210);
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    originatorInfo = new OriginatorInfo;
    originatorInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    recipientInfos.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-211);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    macAlgorithm = new MessageAuthenticationCodeAlgorithm;
    macAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-212);
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 1)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    digestAlgorithm = new DigestAlgorithmIdentifier;
    digestAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    encapContentInfo = new EncapsulatedContentInfo;
    encapContentInfo->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-213);
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 2)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    authenctiatedAttributes = new Attributes;
    authenctiatedAttributes->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    mac.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    if (seqBytesDecoded == elmtLen0)
    {
      bytesDecoded += seqBytesDecoded;
      return;
    }
    else
    {
      tag1 = BDecTag (b, seqBytesDecoded, env);

      if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))
      {
        BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)
        bytesDecoded += seqBytesDecoded;
        return;
      }
    }
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-214);
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 3)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    unauthenticatedAttributes = new Attributes;
    unauthenticatedAttributes->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-215);
  }
  else
    return;
} // AuthenticatedData::BDecContent

AsnLen AuthenticatedData::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void AuthenticatedData::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "AuthenticatedData::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-216);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void AuthenticatedData::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "version ";
    os << version;
    os << "," << endl;
  }

  if (NOT_NULL (originatorInfo))
  {
    Indent (os, indentG);
    os << "originatorInfo ";
    os << *originatorInfo;
  }
  else
  {
    Indent (os, indentG);
    os << "originatorInfo ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "recipientInfos ";
    os << recipientInfos;
    os << "," << endl;
  }

  if (NOT_NULL (macAlgorithm))
  {
    Indent (os, indentG);
    os << "macAlgorithm ";
    os << *macAlgorithm;
  }
  else
  {
    Indent (os, indentG);
    os << "macAlgorithm ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (digestAlgorithm))
  {
    Indent (os, indentG);
    os << "digestAlgorithm ";
    os << *digestAlgorithm;
  }
  else
  {
    Indent (os, indentG);
    os << "digestAlgorithm ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (encapContentInfo))
  {
    Indent (os, indentG);
    os << "encapContentInfo ";
    os << *encapContentInfo;
  }
  else
  {
    Indent (os, indentG);
    os << "encapContentInfo ";
    os << "-- void --";
    os << "," << endl;
  }

  if (NOT_NULL (authenctiatedAttributes))
  {
    Indent (os, indentG);
    os << "authenctiatedAttributes ";
    os << *authenctiatedAttributes;
  }
  else
  {
    Indent (os, indentG);
    os << "authenctiatedAttributes ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "mac ";
    os << mac;
    os << "," << endl;
  }

  if (NOT_NULL (unauthenticatedAttributes))
  {
    os << ","<< endl;
    Indent (os, indentG);
    os << "unauthenticatedAttributes ";
    os << *unauthenticatedAttributes;
  }
  else
  {
    Indent (os, indentG);
    os << "unauthenticatedAttributes ";
    os << "-- void --";
    os << endl;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // AuthenticatedData::Print


AsnType *UserKeyingMaterials::Clone() const
{
  return new UserKeyingMaterials;
}

AsnType *UserKeyingMaterials::Copy() const
{
  return new UserKeyingMaterials (*this);
}

AsnLen UserKeyingMaterials::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SET_TAG_CODE);
  return l;
}

void UserKeyingMaterials::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SET_TAG_CODE))
  {
    Asn1Error << "UserKeyingMaterials::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-217);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

UserKeyingMaterials::UserKeyingMaterials (const UserKeyingMaterials &)
{
  Asn1Error << "use of incompletely defined UserKeyingMaterials::UserKeyingMaterials (const UserKeyingMaterials &)" << endl;
  abort();
}

UserKeyingMaterials::~UserKeyingMaterials()
{
  SetCurrToFirst();
  for (; Curr() != NULL; RemoveCurrFromList())
    ;
} // end of destructor

#if SNACC_DEEP_COPY
UserKeyingMaterials &UserKeyingMaterials::operator = (const UserKeyingMaterials &that)
#else // SNACC_DEEP_COPY
UserKeyingMaterials &UserKeyingMaterials::operator = (const UserKeyingMaterials &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    SetCurrToFirst();
    for (; Curr(); RemoveCurrFromList())
      ;

    //that.SetCurrToFirst();
    //for (; that.Curr(); that.GoNext())
    //  AppendCopy (*that.Curr());
    for (const AsnListElmt *run=that.first; run; run=run->next)
      AppendCopy (*run->elmt);
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined UserKeyingMaterials &UserKeyingMaterials::operator = (const UserKeyingMaterials &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

void UserKeyingMaterials::Print (ostream &os) const
{
#ifndef NDEBUG
    os << "{ -- SEQUENCE/SET OF -- " << endl;
    indentG += stdIndentG;
    //SetCurrToFirst();
    //for (; Curr() != NULL; GoNext())
    for (const AsnListElmt *run=first; run; run=run->next)
    {
        Indent (os, indentG);
        //os << *Curr();
        os << *run->elmt;
        //if (Curr() != Last())
        if (run != last)
            os << ",";
        os << endl;
    }
    indentG -= stdIndentG;
    Indent (os, indentG);
    os << "}\n";
#endif /* NDEBUG */


} // Print


void  UserKeyingMaterials::SetCurrElmt (unsigned long int index)
{
  unsigned long int i;
  curr = first;
  if (count)
    for (i = 0; (i < (count-1)) && (i < index); i++)
      curr = curr->next;
} // UserKeyingMaterials::SetCurrElmt


unsigned long int  UserKeyingMaterials::GetCurrElmtIndex()
{
    unsigned long int i;
    AsnListElmt *tmp;
    if (curr != NULL)
    {
        for (i = 0, tmp = first; tmp != NULL; i++)
        {
            if (tmp == curr)
                return i;
            else
                tmp = tmp->next;
        }
    }
    return count;
} // UserKeyingMaterials::GetCurrElmtIndex


// alloc new list elmt, put at end of list
//  and return the component type
UserKeyingMaterial *UserKeyingMaterials::Append()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt  = new UserKeyingMaterial;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // UserKeyingMaterials::Append


// alloc new list elmt, put at begining of list
//  and return the component type
UserKeyingMaterial  *UserKeyingMaterials::Prepend()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new UserKeyingMaterial;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // UserKeyingMaterials::Prepend


// alloc new list elmt, insert it before the
// current element and return the component type
// if the current element is null, the new element
// is placed at the beginning of the list.
UserKeyingMaterial  *UserKeyingMaterials::InsertBefore()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new UserKeyingMaterial;
    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // UserKeyingMaterials::InsertBefore


// alloc new list elmt, insert it after the
// current element and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
UserKeyingMaterial *UserKeyingMaterials::InsertAfter()
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new UserKeyingMaterial;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return (curr = newElmt)->elmt;
} // UserKeyingMaterials::InsertAfter


UserKeyingMaterials  &UserKeyingMaterials::AppendCopy (UserKeyingMaterial &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new UserKeyingMaterial;
    *newElmt->elmt = elmt;
    newElmt->next = NULL;
    if (last == NULL)
    {
        newElmt->prev = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->prev = last;
        last->next    = newElmt;
        last          = newElmt;
    }
    count++;
    return *this;
} // AppendCopy


UserKeyingMaterials  &UserKeyingMaterials::PrependCopy (UserKeyingMaterial &elmt)
{
    AsnListElmt *newElmt;
    newElmt  = new AsnListElmt;
    newElmt->elmt = new UserKeyingMaterial;
    *newElmt->elmt = elmt;
    newElmt->prev = NULL;
    if (first == NULL)
    {
        newElmt->next = NULL;
        first = last  = newElmt;
    }
    else
    {
        newElmt->next = first;
        first->prev   = newElmt;
        first         = newElmt;
    }
    count++;
    return *this;
} // UserKeyingMaterials::PrependCopy


// alloc new list elmt, insert it before the
// current element, copy the given elmt into the new elmt
// and return the component type.
// if the current element is null, the new element
// is placed at the beginning of the list.
UserKeyingMaterials &UserKeyingMaterials::InsertBeforeAndCopy (UserKeyingMaterial &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new UserKeyingMaterial;
    *newElmt->elmt = elmt;

    if (curr == NULL)
    {
        newElmt->next = first;
        newElmt->prev = NULL;
        first = newElmt;
        if (last == NULL)
            last = newElmt;
    }
    else
    {
        newElmt->next = curr;
        newElmt->prev = curr->prev;
        curr->prev = newElmt;
        if (curr == first)
            first = newElmt;
        else
            newElmt->prev->next = newElmt;
    }
    count++;
    return *this;
} // UserKeyingMaterials::InsertBeforeAndCopy


// alloc new list elmt, insert it after the
// current element, copy given elmt in to new elmt
//  and return the component type
// if the current element is null, the new element
// is placed at the end of the list.
UserKeyingMaterials  &UserKeyingMaterials::InsertAfterAndCopy (UserKeyingMaterial &elmt)
{
    AsnListElmt *newElmt;

    newElmt  = new AsnListElmt;
    newElmt->elmt = new UserKeyingMaterial;
    *newElmt->elmt = elmt;
    if (curr == NULL)
    {
        newElmt->prev = last;
        newElmt->next = NULL;
        last = newElmt;
        if (first == NULL)
            first = newElmt;
    }
    else
    {
        newElmt->prev = curr;
        newElmt->next = curr->next;
        curr->next = newElmt;
        if (curr == last)
            last = newElmt;
        else
            newElmt->next->prev = newElmt;
    }
    count++;
    return *this;
} // UserKeyingMaterials::InsertAfterAndCopy


// remove current element from list if current element is not NULL 
// The new current element will be the next element.
// If the current element is the last element in the list
// the second but last element will become the new current element.
void UserKeyingMaterials::RemoveCurrFromList()
{
    AsnListElmt *del_elmt;

    if (curr != NULL)
    {
        del_elmt = curr;
        count--;

        if (count == 0)
            first = last = curr = NULL;
        else if (curr == first)
        {
            curr = first= first->next;
            first->prev = NULL;
        }
        else if (curr == last)
        {
            curr = last = last->prev;
            last->next = NULL;
        }
        else
        {
            curr->prev->next = curr->next;
            curr->next->prev = curr->prev;
        }

        delete del_elmt->elmt;
        delete del_elmt;
    }
}


AsnLen UserKeyingMaterials::BEncContent (BUF_TYPE b)
{
    AsnListElmt *currElmt;
    AsnLen elmtLen;
    AsnLen totalLen = 0;
    {
      int iii,icount;
      CSM_Buffer **tmpEnc=NULL;
      for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);
      tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);
      for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)
      {
        ENCODE_BUF1(currElmt->elmt->BEncContent, elmtLen);
    elmtLen += BEncDefLen (outputBuf, elmtLen);

    elmtLen += BEncTag1 (outputBuf, UNIV, PRIM, OCTETSTRING_TAG_CODE);
        ENCODE_BUF2(tmpEnc[iii]);
      }
      vdasnacc_sortSetOf(tmpEnc, icount);
      for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())
            SM_WriteToAsnBuf(tmpEnc[iii], b);
      for (iii=0; iii < icount; iii++) delete tmpEnc[iii];
       free(tmpEnc);
    }
        totalLen += elmtLen;
    return totalLen;
} // UserKeyingMaterials::BEncContent


void  UserKeyingMaterials::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0,
                                  AsnLen &bytesDecoded, ENV_TYPE env)
{
    UserKeyingMaterial *listElmt;
    AsnTag tag1;
    AsnLen listBytesDecoded = 0;
    AsnLen elmtLen1;

    while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))
    {
        tag1 = BDecTag (b, listBytesDecoded, env);
        if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))
        {
            BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);
            break;
        }
        if ((tag1 != MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
         && (tag1 != MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
        {
            Asn1Error << "Unexpected Tag" << endl;
            SnaccExcep::throwMe(-218);
        }

        elmtLen1 = BDecLen (b, listBytesDecoded, env);
        listElmt = Append();
        listElmt->BDecContent (b, tag1, elmtLen1, listBytesDecoded, env);
    }

    bytesDecoded += listBytesDecoded;
} // UserKeyingMaterials::BDecContent


RC2CBCParameter::RC2CBCParameter()
{
}

RC2CBCParameter::RC2CBCParameter (const RC2CBCParameter &)
{
  Asn1Error << "use of incompletely defined RC2CBCParameter::RC2CBCParameter (const RC2CBCParameter &)" << endl;
  abort();
}

RC2CBCParameter::~RC2CBCParameter()
{
}

AsnType *RC2CBCParameter::Clone() const
{
  return new RC2CBCParameter;
}

AsnType *RC2CBCParameter::Copy() const
{
  return new RC2CBCParameter (*this);
}

#if SNACC_DEEP_COPY
RC2CBCParameter &RC2CBCParameter::operator = (const RC2CBCParameter &that)
#else // SNACC_DEEP_COPY
RC2CBCParameter &RC2CBCParameter::operator = (const RC2CBCParameter &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    rc2ParameterVersion = that.rc2ParameterVersion;
    iv = that.iv;
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined RC2CBCParameter &RC2CBCParameter::operator = (const RC2CBCParameter &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
RC2CBCParameter::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

    l = iv.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
    totalLen += l;

    l = rc2ParameterVersion.BEncContent (b);
    BEncDefLenTo127 (b, l);
    l++;

    l += BEncTag1 (b, UNIV, PRIM, INTEGER_TAG_CODE);
    totalLen += l;

  return totalLen;
} // RC2CBCParameter::BEncContent


void RC2CBCParameter::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    rc2ParameterVersion.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-219);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    iv.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-220);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-221);
  }
  else
    return;
} // RC2CBCParameter::BDecContent

AsnLen RC2CBCParameter::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void RC2CBCParameter::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "RC2CBCParameter::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-222);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void RC2CBCParameter::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  {
    Indent (os, indentG);
    os << "rc2ParameterVersion ";
    os << rc2ParameterVersion;
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "iv ";
    os << iv;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // RC2CBCParameter::Print


ExtendedCertificateOrCertificate::ExtendedCertificateOrCertificate()
{
  choiceId = certificateCid;
#if TCL
  certificate = new Certificate;
#else
  certificate = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

ExtendedCertificateOrCertificate::ExtendedCertificateOrCertificate (const ExtendedCertificateOrCertificate &)
{
  Asn1Error << "use of incompletely defined ExtendedCertificateOrCertificate::ExtendedCertificateOrCertificate (const ExtendedCertificateOrCertificate &)" << endl;
  abort();
}

ExtendedCertificateOrCertificate::~ExtendedCertificateOrCertificate()
{
  switch (choiceId)
  {
    case certificateCid:
      delete certificate;
      break;
    case extendedCertificateCid:
      delete extendedCertificate;
      break;
  } // end of switch
} // end of destructor

AsnType *ExtendedCertificateOrCertificate::Clone() const
{
  return new ExtendedCertificateOrCertificate;
}

AsnType *ExtendedCertificateOrCertificate::Copy() const
{
  return new ExtendedCertificateOrCertificate (*this);
}

#if SNACC_DEEP_COPY
ExtendedCertificateOrCertificate &ExtendedCertificateOrCertificate::operator = (const ExtendedCertificateOrCertificate &that)
#else // SNACC_DEEP_COPY
ExtendedCertificateOrCertificate &ExtendedCertificateOrCertificate::operator = (const ExtendedCertificateOrCertificate &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    switch (choiceId)
    {
      case certificateCid:
        delete certificate;
        break;
      case extendedCertificateCid:
        delete extendedCertificate;
        break;
    }
    switch (choiceId = that.choiceId)
    {
      case certificateCid:
        certificate = new Certificate;
        *certificate = *that.certificate;
        break;
      case extendedCertificateCid:
        extendedCertificate = new ExtendedCertificate;
        *extendedCertificate = *that.extendedCertificate;
        break;
    }
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined ExtendedCertificateOrCertificate &ExtendedCertificateOrCertificate::operator = (const ExtendedCertificateOrCertificate &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
ExtendedCertificateOrCertificate::BEncContent (BUF_TYPE b)
{
  AsnLen l;
  switch (choiceId)
  {
    case certificateCid:
      BEncEocIfNec (b);
      l = certificate->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
      break;

    case extendedCertificateCid:
      BEncEocIfNec (b);
      l = extendedCertificate->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, CNTX, CONS, 0);
      break;

  } // end switch
  return l;
} // ExtendedCertificateOrCertificate::BEncContent


void ExtendedCertificateOrCertificate::BDecContent (BUF_TYPE b, AsnTag tag, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  switch (tag)
  {
    case MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE):
      choiceId = certificateCid;
      certificate = new Certificate;
        certificate->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
      break;

    case MAKE_TAG_ID (CNTX, CONS, 0):
      choiceId = extendedCertificateCid;
      extendedCertificate = new ExtendedCertificate;
        extendedCertificate->BDecContent (b, tag, elmtLen0, bytesDecoded, env);
      break;

    default:
      Asn1Error << "ERROR - unexpected tag in CHOICE" << endl;
      SnaccExcep::throwMe(-223);
      break;
  } // end switch
} // ExtendedCertificateOrCertificate::BDecContent


AsnLen ExtendedCertificateOrCertificate::BEnc (BUF_TYPE b)
{
    AsnLen l;
    l = BEncContent (b);
    return l;
}

void ExtendedCertificateOrCertificate::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
    AsnLen elmtLen;
    AsnTag tag;

    /*  CHOICEs are a special case - grab identifying tag */
    /*  this allows easier handling of nested CHOICEs */
    tag = BDecTag (b, bytesDecoded, env);
    elmtLen = BDecLen (b, bytesDecoded, env);
    BDecContent (b, tag, elmtLen, bytesDecoded, env);
}

void ExtendedCertificateOrCertificate::Print (ostream &os) const
{
#ifndef NDEBUG
  switch (choiceId)
  {
    case certificateCid:
      os << "certificate ";
      if (certificate)
        os << *certificate;
      else
        os << "-- void3 --\n";
      break;

    case extendedCertificateCid:
      os << "extendedCertificate ";
      if (extendedCertificate)
        os << *extendedCertificate;
      else
        os << "-- void3 --\n";
      break;

  } // end of switch
#endif /* NDEBUG */
} // ExtendedCertificateOrCertificate::Print

DigestInfo::DigestInfo()
{
#if TCL
  digestAlgorithm = new DigestAlgorithmIdentifier;
#else
  digestAlgorithm = NULL; // incomplete initialization of mandatory element!
#endif // TCL
}

DigestInfo::DigestInfo (const DigestInfo &)
{
  Asn1Error << "use of incompletely defined DigestInfo::DigestInfo (const DigestInfo &)" << endl;
  abort();
}

DigestInfo::~DigestInfo()
{
  delete digestAlgorithm;
}

AsnType *DigestInfo::Clone() const
{
  return new DigestInfo;
}

AsnType *DigestInfo::Copy() const
{
  return new DigestInfo (*this);
}

#if SNACC_DEEP_COPY
DigestInfo &DigestInfo::operator = (const DigestInfo &that)
#else // SNACC_DEEP_COPY
DigestInfo &DigestInfo::operator = (const DigestInfo &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    if (that.digestAlgorithm)
    {
      if (!digestAlgorithm)
        digestAlgorithm = new DigestAlgorithmIdentifier;
      *digestAlgorithm = *that.digestAlgorithm;
    }
    else
    {
      delete digestAlgorithm;
      digestAlgorithm = NULL;
    }
    digest = that.digest;
  }

  return *this;
#else // SNACC_DEEP_COPY
  Asn1Error << "use of incompletely defined DigestInfo &DigestInfo::operator = (const DigestInfo &)" << endl;
  abort();
  // if your compiler complains here, check the -novolat option
#endif // SNACC_DEEP_COPY
}

AsnLen
DigestInfo::BEncContent (BUF_TYPE b)
{
  AsnLen totalLen = 0;
  AsnLen l;

    l = digest.BEncContent (b);
    l += BEncDefLen (b, l);

    l += BEncTag1 (b, UNIV, PRIM, OCTETSTRING_TAG_CODE);
    totalLen += l;

      BEncEocIfNec (b);
    l = digestAlgorithm->BEncContent (b);
    l += BEncConsLen (b, l);

    l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
    totalLen += l;

  return totalLen;
} // DigestInfo::BEncContent


void DigestInfo::BDecContent (BUF_TYPE b, AsnTag /*tag0*/, AsnLen elmtLen0, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag1;
  AsnLen seqBytesDecoded = 0;
  AsnLen elmtLen1;
  tag1 = BDecTag (b, seqBytesDecoded, env);

  if ((tag1 == MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    digestAlgorithm = new DigestAlgorithmIdentifier;
    digestAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-224);
  }

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    digest.BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-225);
  }

  bytesDecoded += seqBytesDecoded;
  if (elmtLen0 == INDEFINITE_LEN)
  {
    BDecEoc (b, bytesDecoded, env);
    return;
  }
  else if (seqBytesDecoded != elmtLen0)
  {
    Asn1Error << "ERROR - Length discrepancy on sequence." << endl;
    SnaccExcep::throwMe(-226);
  }
  else
    return;
} // DigestInfo::BDecContent

AsnLen DigestInfo::BEnc (BUF_TYPE b)
{
  AsnLen l;
  l = BEncContent (b);
  l += BEncConsLen (b, l);
  l += BEncTag1 (b, UNIV, CONS, SEQ_TAG_CODE);
  return l;
}

void DigestInfo::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
{
  AsnTag tag;
  AsnLen elmtLen1;

  if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, CONS, SEQ_TAG_CODE))
  {
    Asn1Error << "DigestInfo::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-227);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

void DigestInfo::Print (ostream &os) const
{
#ifndef NDEBUG
  os << "{ -- SEQUENCE --" << endl;
  indentG += stdIndentG;

  if (NOT_NULL (digestAlgorithm))
  {
    Indent (os, indentG);
    os << "digestAlgorithm ";
    os << *digestAlgorithm;
  }
  else
  {
    Indent (os, indentG);
    os << "digestAlgorithm ";
    os << "-- void --";
    os << "," << endl;
  }

  {
    Indent (os, indentG);
    os << "digest ";
    os << digest;
  }

  os << endl;
  indentG -= stdIndentG;
  Indent (os, indentG);
  os << "}";
#endif /* NDEBUG */
} // DigestInfo::Print


