Ejemplo n.º 1
0
ByteSeq UserStateFilterManagerI::getStateGuideMinMax(int min, int max, const Ice::Current& current){
	ByteSeq result;
	if (max <= min) {
		MCE_WARN("UserStateFilterManagerI::getStateGuideMinMax -> min >= max"
                	<< " " << current.con->toString().substr(current.con->toString().find("remote", 25)));
		return result;
	}
	int n=(max-min)/8;
	for (int i=0;i<n;i++){
		result.push_back(Ice::Byte());
	}
	for(int i = min; i < max; ++i) {
		if (_user_state_guide[i]) {
			result[(i-min)/8]|=(1<<(i-min)%8);
		}
	}
	MCE_INFO("UserStateFilterManagerI::getStateGuideMinMax -> min: "<<min << " max: "<<max<<" size:"<<result.size()
                << " " << current.con->toString().substr(current.con->toString().find("remote", 25)));
	return result;
}
Ejemplo n.º 2
0
ByteSeq OnlineStateFilterManagerI::getOnlineStateMinMax(int min, int max, const Ice::Current& current) {
    MCE_INFO("OnlineStateFilterManagerI::getOnlineStateMinMax -> min: "<<min << " max: "<<max
             << " " << current.con->toString().substr(current.con->toString().find("remote", 25)));
    ByteSeq result;
    if (max <= min) {
        MCE_WARN("OnlineStateFilterManagerI::getOnlineStateMinMax -> min >= max");
        return result;
    }
    int n=(max-min)/8;
    MCE_DEBUG("OnlineStateFilterManagerI::getOnlineStateMinMax -> n: "<<n);
    for (int i=0; i<n; i++) {
        result.push_back(Ice::Byte());
    }
    for(int i = min; i < max; ++i) {
        if (_online_state[i]) {
            result[(i-min)/8]|=(1<<(i-min)%8);
        }
    }
    MCE_DEBUG("OnlineStateFilterManagerI::getOnlineStateMinMax -> size: "<<result.size());
    return result;
}
Ejemplo n.º 3
0
ByteSeq StatusCacheManagerI::getStatusMinMax(int min, int max, const Ice::Current& current){

	ostringstream inMsg;
	inMsg<<"StatusCacheManagerI::getStatusMinMax min: " <<min << " max: "<< max << " " << current.con->toString().substr(current.con->toString().find("remote",25));
	TimeCost tc = TimeCost::create(inMsg.str(), TimeCost::LOG_LEVEL_INFO);
	
	ByteSeq result;
	if (max <= min) {
		MCE_WARN("StatusCacheManagerI::getStatusMinMax -> min >= max");
		return result;
	}
	int n=(max-min)/8;
	MCE_DEBUG("StatusCacheManagerI::getStatusMinMax -> n: "<<n);
	for (int i=0;i<n;i++){
		result.push_back(Ice::Byte());
	}
	for(int i = min; i < max; ++i) {
		if (_status[i]) {
			result[(i-min)/8]|=(1<<(i-min)%8);
		}
	}
	MCE_DEBUG("StatusCacheManagerI::getStatusMinMax -> size: "<<result.size());
	return result;
}
Ejemplo n.º 4
0
bool
IcePatch2::Patcher::updateFilesInternal(const FileInfoSeq& files, const DecompressorPtr& decompressor)
{
    Long total = 0;
    Long updated = 0;
    
    for(FileInfoSeq::const_iterator p = files.begin(); p != files.end(); ++p)
    {
        if(p->size > 0) // Regular, non-empty file?
        {
            total += p->size;
        }
    }
    
    AsyncResultPtr curCB;
    AsyncResultPtr nxtCB;

    for(FileInfoSeq::const_iterator p = files.begin(); p != files.end(); ++p)
    {
        if(p->size < 0) // Directory?
        {
            createDirectoryRecursive(_dataDir + '/' + p->path);
            if(fputc('+', _log) == EOF || !writeFileInfo(_log, *p))
            {
                throw "error writing log file:\n" + IceUtilInternal::lastErrorToString();
            }
        }
        else // Regular file.
        {
            if(!_feedback->patchStart(p->path, p->size, updated, total))
            {
                return false;
            }

            if(p->size == 0)
            {
                string path = simplify(_dataDir + '/' + p->path);
                FILE* fp = IceUtilInternal::fopen(path, "wb");
                if(fp == 0)
                {
                    throw "cannot open `" + path +"' for writing:\n" + IceUtilInternal::lastErrorToString();
                }
                fclose(fp);
            }
            else
            {
                string pathBZ2 = simplify(_dataDir + '/' + p->path + ".bz2");
            
                string dir = getDirname(pathBZ2);
                if(!dir.empty())
                {
                    createDirectoryRecursive(dir);
                }
                
                try
                {
                    removeRecursive(pathBZ2);
                }
                catch(...)
                {
                }
                
                FILE* fileBZ2 = IceUtilInternal::fopen(pathBZ2, "wb");
                if(fileBZ2 == 0)
                {
                    throw "cannot open `" + pathBZ2 + "' for writing:\n" + IceUtilInternal::lastErrorToString();
                }

                try
                {
                    Int pos = 0;

                    while(pos < p->size)
                    {
                        if(!curCB)
                        {
                            assert(!nxtCB);
                            curCB = _serverNoCompress->begin_getFileCompressed(p->path, pos, _chunkSize);
                        }
                        else
                        {
                            assert(nxtCB);
                            swap(nxtCB, curCB);
                        }

                        if(pos + _chunkSize < p->size)
                        {
                            nxtCB = _serverNoCompress->begin_getFileCompressed(p->path, pos + _chunkSize, _chunkSize);
                        }
                        else
                        {
                            FileInfoSeq::const_iterator q = p + 1;

                            while(q != files.end() && q->size <= 0)
                            {
                                ++q;
                            }

                            if(q != files.end())
                            {
                                nxtCB = _serverNoCompress->begin_getFileCompressed(q->path, 0, _chunkSize);
                            }
                        }

                        ByteSeq bytes;

                        try
                        {
                            bytes = _serverNoCompress->end_getFileCompressed(curCB);
                        }
                        catch(const FileAccessException& ex)
                        {
                            throw "error from IcePatch2 server for `" + p->path + "': " + ex.reason;
                        }

                        if(bytes.empty())
                        {
                            throw "size mismatch for `" + p->path + "'";
                        }

                        if(fwrite(reinterpret_cast<char*>(&bytes[0]), bytes.size(), 1, fileBZ2) != 1)
                        {
                            throw ": cannot write `" + pathBZ2 + "':\n" + IceUtilInternal::lastErrorToString();
                        }

                        pos += static_cast<int>(bytes.size());
                        updated += bytes.size();

                        if(!_feedback->patchProgress(pos, p->size, updated, total))
                        {
                            fclose(fileBZ2);
                            return false;
                        }
                    }
                }
                catch(...)
                {
                    fclose(fileBZ2);
                    throw;
                }
                
                fclose(fileBZ2);
                
                decompressor->log(_log);
                decompressor->add(*p);
            }
            
            if(!_feedback->patchEnd())
            {
                return false;
            }
        }
    }

    FileInfoSeq newLocalFiles;
    newLocalFiles.reserve(_localFiles.size());
        
    set_union(_localFiles.begin(),
              _localFiles.end(),
              files.begin(),
              files.end(),
              back_inserter(newLocalFiles),
              FileInfoLess());
        
    _localFiles.swap(newLocalFiles);

    FileInfoSeq newUpdateFiles;

    set_difference(_updateFiles.begin(),
                   _updateFiles.end(),
                   files.begin(),
                   files.end(),
                   back_inserter(newUpdateFiles),
                   FileInfoLess());
        
    _updateFiles.swap(newUpdateFiles);

    return true;
}
Ejemplo n.º 5
0
/*! \brief  Add DRM information to MPEG2 program stream.

    IMPEG2IPMPXDRMEncoder will use the functionality of the IMPEG2IPMPXPStreamEncoder
    to add DRM information.

    \param  psEncoder       input, program stream encoder.

    \returns  Boolean indicating success or failure.
*/
bool MPEG2IPMPXDRMEncoder::AddDRMInfo(IMPEG2IPMPXPStreamEncoder* psEncoder) {
  ByteSeq cInfos;
  std::vector<MPEG2IPMPXDRMEncryptor*>::iterator iter = encryptors.begin();

  //  First we create all the IPMP control infos of all encryptors.
  while (iter != encryptors.end()) {
    ByteSeq cInfo;
    if ((*iter)->CreateControlInfo(cInfo) == false) {
      return false;
    }
    cInfos += cInfo;
    iter++;
  }

  //  Now we must create correctly sized control info parts.
  /*  First we must calculate the size of signature/certificate part, if we
      want to sign control info classes. Size is given by the following formula:
      size =  1 (signed flag) + signature size + (certificate type +
              certificate size of all certificates) + 16 (verifying tool ID).
  */
  int sigCertSize = 0;
  if (false) {
    //  We're signing control info classes.
    sigCertSize = 1 + 128 + 1024 + 16;
  } else {
    //  We're not signing control info classes.
    sigCertSize = 0;
  }
  /*  Now we need to calculate size of the control info part size without
      control info classes and signature/certificate part. Size is given by the
      following formula:
      cInfoSize = 3 (packet start code prefix) + 1 (stream id) + 2 (packet length)
                  + 2 (constant + PES extension flag) + 1 (PES header data length)
                  + 1 (constant + PES extension flag 2) + 1 (constant) + 1 (stream
                  id extension flag + stream id extension) + 1 (IPMP control info
                  version + current next indicator + reserved) + 1 (IPMP control
                  info packet number) + 1 (last packet number) + 2 (control info
                  classes length in a part) + 4 (CRC size).
  */
  int cInfoSize = 21;
  //  Maximal part size.
  int maxSize = ((1 << 16) - 1);
  /*  Since we need to set last part number, we must save all the created
      parts pointers, cause we don't know the last part number till we're
      done with packing. We shall also add CRCs then, cause we cannot
      calculate them without last part number.
  */
  std::vector<IInterPStreamIPMPControlInfoPart*> interParts;
  ByteT partNumber = 0;
  UInt16T totalLen = (UInt16T)cInfos.GetLength();
  while ((maxSize - sigCertSize - cInfoSize - (long int)cInfos.GetLength()) < 0) {
    //  Add new intermediate part.
    IInterPStreamIPMPControlInfoPart* interPart;
    if (psEncoder->CreateInterIPMPControlInfoPart(&interPart) == false) {
      return false;
    }
    if (interPart->SetPacketStartCodePrefix(0x000001) == false) {
      return false;
    }
    if (interPart->SetStreamID(0xfd) == false) {
      return false;
    }
    if (interPart->SetPESExtensionFlag(true) == false) {
      return false;
    }
    if (interPart->SetPESExtensionFlag2(true) == false) {
      return false;
    }
    if (interPart->SetStreamIDExtensionFlag(true) == false) {
      return false;
    }
    //  Check this!
    if (interPart->SetStreamIDExtension(0x0) == false) {
      return false;
    }
    if (interPart->SetIPMPControlInfoVersion(0x0) == false) {
      return false;
    }
    if (interPart->SetCurrentNextIndicator(true) == false) {
      return false;
    }
    if (interPart->SetPartNumber(partNumber++) == false) {
      return false;
    }
    ByteSeq tmp = cInfos.GetBytes(maxSize - cInfoSize);
    if (interPart->SetIPMPControlInfos(tmp) == false) {
      return false;
    }
  }
  /*  Now we only have to add last part, so we can set last part number for
      all intermediate parts, and calculate CRCs.
  */
  std::vector<IInterPStreamIPMPControlInfoPart*>::iterator interIter =
    interParts.begin();
  while (interIter != interParts.end()) {
    if ((*interIter)->SetLastPartNumber(partNumber) == false) {
      return false;
    }
    ByteSeq encoded;
    if ((*interIter)->MPEG2Encode(encoded) == false) {
      return false;
    }
    CRC32Calculator calc;
    UInt32T crc = calc.GetCRC(encoded.GetFirst(), encoded.GetLength());
    if ((*interIter)->SetCRC32Code(crc) == false) {
      return false;
    }
    interIter++;
  }
  //  Add last part.
  ILastPStreamIPMPControlInfoPart* lastPart;
  if (psEncoder->CreateLastIPMPControlInfoPart(&lastPart) == false) {
    return false;
  }
  if (lastPart->SetPacketStartCodePrefix(0x000001) == false) {
    return false;
  }
  if (lastPart->SetStreamID(0xfd) == false) {
    return false;
  }
  if (lastPart->SetPESExtensionFlag(true) == false) {
    return false;
  }
  if (lastPart->SetPESExtensionFlag2(true) == false) {
    return false;
  }
  if (lastPart->SetStreamIDExtensionFlag(true) == false) {
    return false;
  }
  //  Check this!
  if (lastPart->SetStreamIDExtension(0x0) == false) {
    return false;
  }
  if (lastPart->SetIPMPControlInfoVersion(0x0) == false) {
    return false;
  }
  if (lastPart->SetCurrentNextIndicator(true) == false) {
    return false;
  }
  if (lastPart->SetPartNumber(partNumber) == false) {
    return false;
  }
  if (lastPart->SetIPMPControlInfos(cInfos) == false) {
    return false;
  }
  //  Add CRC code.
  ByteSeq encoded;
  if (lastPart->MPEG2Encode(encoded) == false) {
    return false;
  }
  CRC32Calculator calc;
  UInt32T crc = calc.GetCRC(encoded.GetFirst(), encoded.GetLength());
  if (lastPart->SetCRC32Code(crc) == false) {
    return false;
  }
  return true;
}
Ejemplo n.º 6
0
/*! \brief  Add DRM information to MPEG2 transport stream.

    IMPEG2IPMPXDRMEncoder will use the functionality of the IMPEG2IPMPXTStreamEncoder
    to add DRM information.

    \param  tsEncoder       input, transport stream encoder.

    \returns  Boolean indicating success or failure.
*/
bool MPEG2IPMPXDRMEncoder::AddDRMInfo(IMPEG2IPMPXTStreamEncoder* tsEncoder) {
  ByteSeq cInfos;
  std::vector<MPEG2IPMPXDRMEncryptor*>::iterator iter = encryptors.begin();

  //  First we create all the IPMP control infos of all encryptors.
  while (iter != encryptors.end()) {
    ByteSeq cInfo;
    if ((*iter)->CreateControlInfo(cInfo) == false) {
      return false;
    }
    cInfos += cInfo;
    iter++;
  }
  /*  Check if 16-bit value is enough for holding the control infos. If not,
      then it's an error.
  */
  if (cInfos.GetLength() >= (1 << 16)) {
    return false;
  }

  //  Now we must create correctly sized control info parts.
  /*  First we must calculate the size of signature/certificate part, if we
      want to sign control info classes. Size is given by the following formula:
      size =  1 (signed flag) + signature size + (certificate type +
              certificate size of all certificates) + 16 (verifying tool ID).
  */
  int sigCertSize = 0;
  if (false) {
    //  We're signing control info classes.
    sigCertSize = 1 + 128 + 1024 + 16;
  } else {
    //  We're not signing control info classes.
    sigCertSize = 0;
  }
  /*  Now we need to calculate size of the control info part size without
      control info classes and signature/certificate part. Size is given by the
      following formula:
      cInfoSize = 1 (table ID) + 2 (section syntax indicator + 0 + reserved +
                  section length) + 1 (reserved + control info version + current
                  next indicator) + 1 (section number) + 1 + (last section number)
                  + 2 (control info classes total length) + 2 (control info
                  classes length in a part) + 4 (CRC size).
  */
  int cInfoSize = 14;
  //  Maximal part size.
  int maxSize = 4093;
  /*  Since we need to set last part number, we must save all the created
      parts pointers, cause we don't know the last part number till we're
      done with packing. We shall also add CRCs then, cause we cannot
      calculate them without last part number.
  */
  std::vector<IInterTStreamIPMPControlInfoPart*> interParts;
  ByteT partNumber = 0;
  UInt16T totalLen = (UInt16T)cInfos.GetLength();
  while ((maxSize - sigCertSize - cInfoSize - (long int)cInfos.GetLength()) < 0) {
    //  Add new intermediate part.
    IInterTStreamIPMPControlInfoPart* interPart;
    if (tsEncoder->CreateInterIPMPControlInfoPart(&interPart) == false) {
      return false;
    }
    if (interPart->SetTableID(0x07) == false) {
      return false;
    }
    if (interPart->SetSectionSyntaxIndicator(true) == false) {
      return false;
    }
    if (interPart->SetIPMPControlInfoVersion(0x0) == false) {
      return false;
    }
    if (interPart->SetCurrentNextIndicator(true) == false) {
      return false;
    }
    if (interPart->SetPartNumber(partNumber++) == false) {
      return false;
    }
    if (interPart->SetTotalControlInfoClassesLen(totalLen) == false) {
      return false;
    }
    ByteSeq tmp = cInfos.GetBytes(maxSize - cInfoSize);
    if (interPart->SetIPMPControlInfos(tmp) == false) {
      return false;
    }
  }
  /*  Now we only have to add last part, so we can set last part number for
      all intermediate parts, and calculate CRCs.
  */
  std::vector<IInterTStreamIPMPControlInfoPart*>::iterator interIter =
    interParts.begin();
  while (interIter != interParts.end()) {
    if ((*interIter)->SetLastPartNumber(partNumber) == false) {
      return false;
    }
    ByteSeq encoded;
    if ((*interIter)->MPEG2Encode(encoded) == false) {
      return false;
    }
    CRC32Calculator calc;
    UInt32T crc = calc.GetCRC(encoded.GetFirst(), encoded.GetLength());
    if ((*interIter)->SetCRC32Code(crc) == false) {
      return false;
    }
    interIter++;
  }
  //  Add last part.
  ILastTStreamIPMPControlInfoPart* lastPart;
  if (tsEncoder->CreateLastIPMPControlInfoPart(&lastPart) == false) {
    return false;
  }
  if (lastPart->SetTableID(0x07) == false) {
    return false;
  }
  if (lastPart->SetSectionSyntaxIndicator(true) == false) {
    return false;
  }
  if (lastPart->SetIPMPControlInfoVersion(0x0) == false) {
    return false;
  }
  if (lastPart->SetCurrentNextIndicator(true) == false) {
    return false;
  }
  if (lastPart->SetPartNumber(partNumber) == false) {
    return false;
  }
  if (lastPart->SetTotalControlInfoClassesLen(totalLen) == false) {
    return false;
  }
  if (lastPart->SetIPMPControlInfos(cInfos) == false) {
    return false;
  }
  //  Add CRC code.
  ByteSeq encoded;
  if (lastPart->MPEG2Encode(encoded) == false) {
    return false;
  }
  CRC32Calculator calc;
  UInt32T crc = calc.GetCRC(encoded.GetFirst(), encoded.GetLength());
  if (lastPart->SetCRC32Code(crc) == false) {
    return false;
  }
  return true;
}
Ejemplo n.º 7
0
/*! \brief  Parse key descriptor.

    \warning  Encoded data is modified during parsing.
    \warning  In case of an error, throws either ByteSeqException or
              IPMPDataException.

    \param  encoded     input, encoded data.

    \returns  Key descriptor.
*/
KeyDescriptor IPMPDataParser::ParseKeyDescriptor(ByteSeq& encoded) {
  ByteSeq keyBody = encoded.GetBytes((UInt32T)(encoded.GetSizeOfInstance(0)));
  return KeyDescriptor(keyBody);
}
Ejemplo n.º 8
0
/*! \brief  Parse IPMP data message, call handling function and return it's
            response.

    \warning  Encoded data is modified during parsing.
    \warning  Response can be empty, depending on whether any response is
              needed and whether an error occured during the processing.

    \param  sender    input, sender's code.
    \param  encoded   input, encoded message.
    \param  agent     input, IPMP agent which will handle parsed message.
    \param  resp      output, response message data.

    \returns  Boolean indicating success or failure.
*/
bool IPMPDataParser::ParseMessage(const Bit32T& sender, ByteSeq& encoded,
    IPMPAgent* agent, ByteSeq& resp) {
  try {
    ByteT tag = encoded.GetByte();
    ByteSeq data(encoded.GetBytes((UInt32T)(encoded.GetSizeOfInstance(0xfffffff))));
    switch (tag) {
    case 0x01:
      //  Opaque data.
      if (agent->HandleOpaqueIPMPData(sender, ParseOpaqueData(data), resp) == false) {
        return false;
      }
      break;
    case 0x08:
      //  Rights data.
      if (agent->HandleRightsIPMPData(sender, ParseRightsData(data), resp) == false) {
        return false;
      }
      break;
    case 0x09:
      //  Secure container.
      if (agent->HandleSecureContainerIPMPData(sender, ParseSecureContainer(data), resp) == false) {
        return false;
      }
      break;
    case 0x0c:
      //  Init authentication.
      if (agent->HandleInitAuthenticationIPMPData(sender, ParseInitAuthentication(data), resp) == false) {
        return false;
      }
      break;
    case 0x0d:
      //  Mutual authentication.
      if (agent->HandleMutualAuthenticationIPMPData(sender, ParseMutualAuthentication(data), resp) == false) {
        return false;
      }
      break;
    case 0x17:
      //  Can process.
      if (agent->HandleCanProcessIPMPData(sender, ParseCanProcess(data), resp) == false) {
        return false;
      }
      break;
    case 0x0e:
      //  User query.
      if (agent->HandleUserQueryIPMPData(sender, ParseUserQueryData(data), resp) == false) {
        return false;
      }
      break;
    case 0x0f:
      //  User response.
      if (agent->HandleUserQueryResponseIPMPData(sender, ParseUserQueryResponseData(data), resp) == false) {
        return false;
      }
      break;
    default:
      return false;
    }
    return true;
  }
  catch (ByteSeqException) {
    return false;
  }
  catch (IPMPDataException) {
    return false;
  }
  catch (IPMPDataParserException) {
    return false;
  }
//  catch (...) {
//    return false;
//  }
}
Ejemplo n.º 9
0
/*! \brief  Parse IPMP mutual authentication message.

    \warning  Encoded data is modified during parsing.
    \warning  In case of an error, throws either ByteSeqException or
              IPMPDataException.

    \param  encoded   input, encoded message.

    \returns  IPMP mutual authentication message.
*/
MutualAuthenticationIPMPData* IPMPDataParser::ParseMutualAuthentication(ByteSeq& encoded) {
  //  Get version.
  ByteT version = encoded.GetByte();
  //  Get data identifier.
  Bit32T dataID = encoded.GetBit32();
  //  Get flags.
  ByteT tmp = encoded.GetByte();

  bool requestNegotiation = ((tmp & 0x80) == 0)? (false): (true);
  bool successNegotiation =  ((tmp & 0x40) == 0)? (false): (true);
  bool failedNegotiation =  ((tmp & 0x20) == 0)? (false): (true);
  bool inclAuthenticationData =  ((tmp & 0x10) == 0)? (false): (true);
  bool inclAuthCodes =  ((tmp & 0x08) == 0)? (false): (true);

  ByteSeq tmpArray;
  std::vector<AlgorithmDescriptor*> candidate;
  std::vector<AlgorithmDescriptor*> agreed;
  ByteSeq authenticationData;
  AuthCodes* codes = 0;
  try {
    if (requestNegotiation) {
      //  Get number of candidate algorithms.
      tmp = encoded.GetByte();
      while (tmp > 0) {
        //  Get encoded algorithm descriptor data.
        if (encoded.GetByte() != 0x01) {
          throw IPMPDataParserException();
        }
        tmpArray = encoded.GetBytes((UInt32T)(encoded.GetSizeOfInstance(0xfffffff)));
        candidate.push_back(ParseAlgorithmDescriptor(tmpArray));
        tmp--;
      }
    }
    if (successNegotiation) {
      //  Get number of agreed algorithms.
      tmp = encoded.GetByte();
      while (tmp > 0) {
        //  Get encoded algorithm descriptor data.
        if (encoded.GetByte() != 0x01) {
          throw IPMPDataParserException();
        }
        tmpArray = encoded.GetBytes((UInt32T)(encoded.GetSizeOfInstance(0xfffffff)));
        agreed.push_back(ParseAlgorithmDescriptor(tmpArray));
        tmp--;
      }
    }
    if (inclAuthenticationData) {
      authenticationData = encoded.GetBytes((UInt32T)(encoded.GetSizeOfInstance(0)));
    }
    if (inclAuthCodes) {
      tmp = encoded.GetByte();
      if (tmp == 0x01) {
        //  Parse certificates.
        ByteT nCert = encoded.GetByte();
        ByteT certType = encoded.GetByte();
        std::vector<ByteSeq> certs;
        while (nCert > 0) {
          certs.push_back(encoded.GetBytes((UInt32T)(encoded.GetSizeOfInstance(0))));
          nCert--;
        }
        //  Parse trust security metadata.
        if (encoded.GetByte() != 0x18) {
          throw IPMPDataParserException();
        }
        tmpArray = encoded.GetBytes((UInt32T)(encoded.GetSizeOfInstance(0xfffffff)));
        TrustSecurityMetadataIPMPData* trustData = ParseTrustSecurityMetadata(tmpArray);
        tmpArray = encoded.GetBytes((UInt32T)(encoded.GetSizeOfInstance(0)));
        PublicAuthContext* context = new CertPublicAuthContext(
          std::vector<AlgorithmDescriptor*>(),trustData, certType, certs);
        codes = new AuthCodes(context, tmpArray);
      } else if (tmp == 0x02) {
        if (encoded.GetByte() != 0x02) {
          throw IPMPDataParserException();
        }
        tmpArray = encoded.GetBytes((UInt32T)(encoded.GetSizeOfInstance(0xfffffff)));
        KeyDescriptor descriptor = ParseKeyDescriptor(tmpArray);
        //  Parse trust security metadata.
        if (encoded.GetByte() != 0x18) {
          throw IPMPDataParserException();
        }
        tmpArray = encoded.GetBytes((UInt32T)(encoded.GetSizeOfInstance(0xfffffff)));
        TrustSecurityMetadataIPMPData* trustData = ParseTrustSecurityMetadata(tmpArray);
        tmpArray = encoded.GetBytes((UInt32T)(encoded.GetSizeOfInstance(0)));
        PublicAuthContext* context = new KeyPublicAuthContext(
          std::vector<AlgorithmDescriptor*>(), trustData, descriptor);
        codes = new AuthCodes(context, tmpArray);
      } else if (tmp = 0xfe) {
        //  Parse opaque.
        ByteSeq opaque = encoded.GetBytes((UInt32T)(encoded.GetSizeOfInstance(0)));
        //  Parse trust security metadata.
        if (encoded.GetByte() != 0x18) {
          throw IPMPDataParserException();
        }
        tmpArray = encoded.GetBytes((UInt32T)(encoded.GetSizeOfInstance(0xfffffff)));
        TrustSecurityMetadataIPMPData* trustData = ParseTrustSecurityMetadata(tmpArray);
        tmpArray = encoded.GetBytes((UInt32T)(encoded.GetSizeOfInstance(0)));
        PublicAuthContext* context = new OpaquePublicAuthContext(
          std::vector<AlgorithmDescriptor*>(), trustData, opaque);
        codes = new AuthCodes(context, tmpArray);
      } else {
        throw IPMPDataParserException();
      }
    }
  }
  catch (ByteSeqException) {
    ClearVector(candidate);
    ClearVector(agreed);
    if (codes != 0) delete codes;
    throw ByteSeqException();
  }
  catch (IPMPDataParserException) {
    ClearVector(candidate);
    ClearVector(agreed);
    if (codes != 0) delete codes;
    throw IPMPDataParserException();
  }

  if (authenticationData.GetLength() > 0) {
    return new MutualAuthenticationIPMPData(version, dataID, failedNegotiation,
      candidate, agreed, authenticationData, codes);
  } else {
    return new MutualAuthenticationIPMPData(version, dataID, failedNegotiation,
      candidate, agreed, codes);
  }
}