//   NOTE: this is a machine generated file--editing not recommended
//
// pkcs8.cpp - class member functions for ASN.1 module PrivateKeyInformationSyntax
//
//   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:

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

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

PrivateKeyInfo::~PrivateKeyInfo()
{
  delete privateKeyAlgorithm;
  delete attributes;
}

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

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

#if SNACC_DEEP_COPY
PrivateKeyInfo &PrivateKeyInfo::operator = (const PrivateKeyInfo &that)
#else // SNACC_DEEP_COPY
PrivateKeyInfo &PrivateKeyInfo::operator = (const PrivateKeyInfo &)
#endif // SNACC_DEEP_COPY
{
#if SNACC_DEEP_COPY
  if (this != &that)
  {
    version = that.version;
    if (that.privateKeyAlgorithm)
    {
      if (!privateKeyAlgorithm)
        privateKeyAlgorithm = new AlgorithmIdentifier;
      *privateKeyAlgorithm = *that.privateKeyAlgorithm;
    }
    else
    {
      delete privateKeyAlgorithm;
      privateKeyAlgorithm = NULL;
    }
    privateKey = that.privateKey;
    if (that.attributes)
    {
      if (!attributes)
        attributes = new Attributes;
      *attributes = *that.attributes;
    }
    else
    {
      delete attributes;
      attributes = NULL;
    }
  }

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

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

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

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

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

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

      BEncEocIfNec (b);
    l = privateKeyAlgorithm->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;
} // PrivateKeyInfo::BEncContent


void PrivateKeyInfo::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(-100);
  }

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

  if ((tag1 == MAKE_TAG_ID (UNIV, PRIM, OCTETSTRING_TAG_CODE))
    || (tag1 == MAKE_TAG_ID (UNIV, CONS, OCTETSTRING_TAG_CODE)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    privateKey.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(-102);
  }

  if ((tag1 == MAKE_TAG_ID (CNTX, CONS, 0)))
  {
    elmtLen1 = BDecLen (b, seqBytesDecoded, env);
    attributes = new Attributes;
    attributes->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(-103);
  }
  else
    return;
} // PrivateKeyInfo::BDecContent

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

void PrivateKeyInfo::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 << "PrivateKeyInfo::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-104);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

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

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

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

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

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

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


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

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

EncryptedPrivateKeyInfo::~EncryptedPrivateKeyInfo()
{
  delete encryptionAlgorithm;
}

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

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

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

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

AsnLen
EncryptedPrivateKeyInfo::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 = encryptionAlgorithm->BEncContent (b);
    l += BEncConsLen (b, l);

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

  return totalLen;
} // EncryptedPrivateKeyInfo::BEncContent


void EncryptedPrivateKeyInfo::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);
    encryptionAlgorithm = new AlgorithmIdentifier;
    encryptionAlgorithm->BDecContent (b, tag1, elmtLen1, seqBytesDecoded, env);
    tag1 = BDecTag (b, seqBytesDecoded, env);
  }
  else
  {
    Asn1Error << "ERROR - SEQUENCE is missing non-optional elmt." << endl;
    SnaccExcep::throwMe(-105);
  }

  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(-106);
  }

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

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

void EncryptedPrivateKeyInfo::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 << "EncryptedPrivateKeyInfo::BDec: ERROR - wrong tag" << endl;
    SnaccExcep::throwMe(-108);
  }
  elmtLen1 = BDecLen (b, bytesDecoded, env);
  BDecContent (b, tag, elmtLen1, bytesDecoded, env);
}

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

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

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

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


