///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2018 Ericsson Telecom AB Telecom AB
//
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v2.0
// which accompanies this distribution, and is available at
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
//                                                                           
///////////////////////////////////////////////////////////////////////////////
//
//  File:           TLS_EncDec.cc
//  Description:    Encode/decode functions for TLS messages
//  Rev:            R4A
//  Prodnr:         CNL 113 806
//  Updated:        2014-06-20
//  Contact:        http://ttcn.ericsson.se

#include "TLS_Types.hh"
#include "memory.h"
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <exception>
#include <stdint.h>

namespace TLS__Types{

struct TLS_Exception {
	const char* what;
	const char* file;
	int line;
	const char* func;
};


uint32_t dec_int(int len, const unsigned char* buf){
  uint32_t ret_val=0;
  while(len){
    ret_val= (ret_val<<8) + (*buf);
    len--;
    buf++;
  }
  return ret_val;
}

void enc_int(int len, const INTEGER& val, TTCN_Buffer& buf){
  buf.put_os(int2oct(val, len));
}

void enc_int(int len, size_t val, TTCN_Buffer& buf){
  buf.put_os(int2oct(val, len));
}


void enc_str(int size_len, const OCTETSTRING& os, TTCN_Buffer& buf){
  enc_int(size_len,os.lengthof(),buf);
  buf.put_os(os);
}

void enc_str(int size_len, const CHARSTRING& os, TTCN_Buffer& buf){
  enc_int(size_len,os.lengthof(),buf);
  buf.put_cs(os);
}

int dec_string(int size_len, CHARSTRING& os, const unsigned char* buf){
  uint32_t len=dec_int(size_len,buf);
  buf+=size_len;
  os=CHARSTRING(len,(const char*) buf);
  return size_len+len;
}

int dec_string(int size_len, OCTETSTRING& os, const unsigned char* buf){
  uint32_t len=dec_int(size_len,buf);
  buf+=size_len;
  os=OCTETSTRING(len,buf);
  return size_len+len;
}

OCTETSTRING padd_os_to_len(const OCTETSTRING& os, const INTEGER& len) throw(TLS_Exception){
  if(len < os.lengthof()) {
		  TLS_Exception e;
		  e.what = (const char*)"Invalid CompressionMethod";
		  e.file = (const char*)__FILE__;
		  e.line = __LINE__-4;
		  e.func = __func__;
	    throw e;
  }
  return int2oct(0, len-os.lengthof()) + os ;
}

// Extension encoder/decoder

OCTETSTRING enc__TLS__Extensions( const TLS__Extensions& pl_ext ){
  TTCN_Buffer buf;
  for(int i=0;i<pl_ext.lengthof();i++){
    switch(pl_ext[i].get_selection()){
      case TLS__Extension::ALT_protocol__name__list:
{
          enc_int(1,16,buf); // RFC6066 application_layer_protocol_negotiation(16)

          TTCN_Buffer bsnlist;
          for(int k=0;k<pl_ext[i].protocol__name__list().lengthof();k++){
            enc_str(1,pl_ext[i].protocol__name__list()[k],bsnlist);
          }
          OCTETSTRING bsn;
          bsnlist.get_string(bsn);
          enc_int(2,bsn.lengthof(),buf);
          buf.put_os(bsn);
        }

        break;
      case TLS__Extension::ALT_server__name__list:{
          enc_int(1,0,buf); // RFC6066 10.2: 0 server_name

          TTCN_Buffer bsnlist;
          for(int k=0;k<pl_ext[i].server__name__list().lengthof();k++){
            enc_int(1,0,bsnlist); // RFC6066 3: host_name(0)
            enc_str(2,pl_ext[i].server__name__list()[k].hostname(),bsnlist);
          }
          OCTETSTRING bsn;
          bsnlist.get_string(bsn);
          enc_int(2,bsn.lengthof(),buf);
          buf.put_os(bsn);
        }
        break;
      case TLS__Extension::ALT_future__extensions:
          buf.put_os(pl_ext[i].future__extensions());
      
        break;
      default:
        ;// WTF?
    }
  }
  OCTETSTRING ret_val;
  buf.get_string(ret_val);
  return int2oct(ret_val.lengthof(),2) + ret_val;
}


INTEGER dec__TLS__Extensions( const OCTETSTRING& pl_stream, TLS__Extensions& pl_ext ){
  const unsigned char* ptr=(const unsigned char*)pl_stream;
  int len=pl_stream.lengthof();

  int rec_len= dec_int(2,ptr);
  if(len<(rec_len+2)) {
    TTCN_warning("dec__TLS__Extensions: too short string");
    return 0;
  }
  
  ptr+=2;
  pl_ext=NULL_VALUE;

  int idx=0;

  while(rec_len>0){
    int ext_type=dec_int(1,ptr);
    ptr++;
    rec_len--;
    int ext_length=dec_int(2,ptr);
    ptr+=2;
    rec_len-=2;
    switch(ext_type){
      case 0:  // RFC6066 10.2: 0 server_name
        pl_ext[idx].server__name__list()=NULL_VALUE;
        while(ext_length>0){
          ptr++;           // skip name type, only hostname is supported
          rec_len--;
          ext_length--;
          int os_len=dec_string(2,pl_ext[idx].server__name__list()[pl_ext[idx].server__name__list().lengthof()].hostname(),ptr);
          ptr+=os_len;
          rec_len-=os_len;
          ext_length-=os_len;
        }
        break;
      case 16:// RFC6066 application_layer_protocol_negotiation(16)
        pl_ext[idx].protocol__name__list()=NULL_VALUE;
        while(ext_length>0){
          int os_len=dec_string(1,pl_ext[idx].protocol__name__list()[pl_ext[idx].protocol__name__list().lengthof()],ptr);
          ptr+=os_len;
          rec_len-=os_len;
          ext_length-=os_len;
        }
        break;
      default: {
        pl_ext[idx].future__extensions()=OCTETSTRING(ext_length+2+1,ptr-3);
        ptr+=ext_length+2;
      }
    }
    idx++;
  } 
   
  return 1;
}



/////////////////////////////////////
//// Protocol Version EncDec
/////////////////////////////////////

void enc__TLS__ProtocolVersion(const TLS__Types::ProtocolVersion& version, TTCN_Buffer& buf) {
	buf.put_os(int2oct(version.major__(), 1));
	buf.put_os(int2oct(version.minor__(), 1));
}

ProtocolVersion dec__TLS__ProtocolVersion(const OCTETSTRING& stream) throw(TLS_Exception) {
	ProtocolVersion ret;

  ret.major__() = oct2int(substr(stream, 0, 1));
  ret.minor__() = oct2int(substr(stream, 1, 1));
  
  return ret;
}

/////////////////////////////////////
//// Content Type EncDec
/////////////////////////////////////

void enc__TLS__ContentType(const TLS__Types::ContentType& ctype, TTCN_Buffer& buf) {
  buf.put_os(int2oct(ctype, 1));
}

ContentType dec__TLS__ContentType(const OCTETSTRING& stream) throw(TLS_Exception){
  if(!ContentType::is_valid_enum(oct2int(stream))){
	  TLS_Exception e;
	  e.what = (const char*)"Invalid ComponentType";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
    throw e;
  }
  
  return (ContentType) oct2int(stream);
}

/////////////////////////////////////
//// Compression Method EncDec
/////////////////////////////////////

void enc__TLS__CompressionMethod(const TLS__Types::CompressionMethod& method, TTCN_Buffer& buf) {
  buf.put_os(int2oct(method, 1));
}

CompressionMethod dec__TLS__CompressionMethod(const OCTETSTRING& stream) throw(TLS_Exception){
	  if(!CompressionMethod::is_valid_enum(oct2int(stream))){
		  TLS_Exception e;
		  e.what = (const char*)"Invalid CompressionMethod";
		  e.file = (const char*)__FILE__;
		  e.line = __LINE__-4;
		  e.func = __func__;
	    throw e;
	  }

  return (CompressionMethod) oct2int(stream);
}

/////////////////////////////////////
//// Connection End EncDec
/////////////////////////////////////

void enc__TLS__ConnectionEnd(const TLS__Types::ConnectionEnd& ce, TTCN_Buffer& buf) {
  buf.put_os(int2oct(ce, 1));
}

ConnectionEnd dec__TLS__ConnectionEnd(const OCTETSTRING& stream) throw(TLS_Exception){
 	if(!ConnectionEnd::is_valid_enum(oct2int(stream))){
	  TLS_Exception e;
	  e.what = (const char*)"Invalid ConnectionEnd";
		e.file = (const char*)__FILE__;
		e.line = __LINE__-4;
		e.func = __func__;
	  throw e;
	}

	return (ConnectionEnd) oct2int(stream);;
}

/////////////////////////////////////
//// Bulk Cipher Algorithm EncDec
/////////////////////////////////////

void enc__TLS__BulkCipherAlgorithm(const TLS__Types::BulkCipherAlgorithm& bca, TTCN_Buffer& buf) throw(TLS_Exception){
  buf.put_os(int2oct(bca, 1));
}

BulkCipherAlgorithm dec__TLS__BulkCipherAlgorithm(const OCTETSTRING& stream) throw(TLS_Exception){
 	if(!BulkCipherAlgorithm::is_valid_enum(oct2int(stream))){
	  TLS_Exception e;
	  e.what = (const char*)"Invalid BulkCipherAlgorithm";
		e.file = (const char*)__FILE__;
		e.line = __LINE__-4;
		e.func = __func__;
	  throw e;
	}
	return (BulkCipherAlgorithm) oct2int(stream);
}

/////////////////////////////////////
//// Cipher Type EncDec
/////////////////////////////////////

void enc__TLS__CipherType(const TLS__Types::CipherType& ct, TTCN_Buffer& buf) {
  buf.put_os(int2oct(ct, 1));
}

CipherType dec__TLS__CipherType(const OCTETSTRING& stream) throw(TLS_Exception){
 	if(!CipherType::is_valid_enum(oct2int(stream))){
	  TLS_Exception e;
	  e.what = (const char*)"Invalid CipherType";
		e.file = (const char*)__FILE__;
		e.line = __LINE__-4;
		e.func = __func__;
	  throw e;
	}

	return (CipherType) oct2int(stream);
}

/////////////////////////////////////
//// MAC Algorithm EncDec
/////////////////////////////////////

void enc__TLS__MACAlgorithm(const TLS__Types::MACAlgorithm& ct, TTCN_Buffer& buf) {
  buf.put_os(int2oct(ct, 1));
}

MACAlgorithm dec__TLS__MACAlgorithm(const OCTETSTRING& stream) throw(TLS_Exception){
 	if(!MACAlgorithm::is_valid_enum(oct2int(stream))){
	  TLS_Exception e;
	  e.what = (const char*)"Invalid MACAlgorithm";
		e.file = (const char*)__FILE__;
		e.line = __LINE__-4;
		e.func = __func__;
	  throw e;
	}

	return (MACAlgorithm) oct2int(stream);
}

/////////////////////////////////////
//// Security Parameters EncDec
/////////////////////////////////////

OCTETSTRING enc__TLS__SecurityParameters(const TLS__Types::SecurityParameters& sp) {
  TTCN_Buffer buf;
  OCTETSTRING ret;

  enc__TLS__ConnectionEnd(sp.entity(), buf);
  enc__TLS__BulkCipherAlgorithm(sp.bulk__cipher__algorithm(), buf);
  enc__TLS__CipherType(sp.cipher__type(), buf);
  buf.put_os(int2oct(sp.key__size(), 1));
  buf.put_os(int2oct(sp.key__material__length(), 1));
  enc__TLS__MACAlgorithm(sp.mac__algorithm(),buf);
  buf.put_os(int2oct(sp.hash__size(), 1));
  enc__TLS__CompressionMethod(sp.compression__algorithm(), buf);
  buf.put_os(sp.master__secret());
  buf.put_os(sp.client__random());
  buf.put_os(sp.server__random());

  buf.get_string(ret);

  return ret;
}

INTEGER dec__TLS__SecurityParameters(const OCTETSTRING& stream, TLS__Types::SecurityParameters& ret) {
  if(stream.lengthof() < 120) {
	  TLS_Exception e;
	  e.what = (const char*)"Invalid length";
		e.file = (const char*)__FILE__;
		e.line = __LINE__-4;
		e.func = __func__;
	  throw e;
	}
  try {
    ret.entity() = dec__TLS__ConnectionEnd(substr(stream, 0, 1));
    ret.bulk__cipher__algorithm() = dec__TLS__BulkCipherAlgorithm(substr(stream, 1, 1));
    ret.cipher__type() = dec__TLS__CipherType(substr(stream, 2 , 1));
    ret.key__size() = oct2int(substr(stream, 3, 1));
    ret.key__material__length() = oct2int(substr(stream, 4, 1));
    ret.mac__algorithm() = dec__TLS__MACAlgorithm(substr(stream, 5, 1));
    ret.hash__size() = oct2int(substr(stream, 6, 1));
    ret.compression__algorithm() = dec__TLS__CompressionMethod(substr(stream, 7, 1));
    ret.master__secret() = substr(stream, 8, 48);
    ret.client__random() = substr(stream, 56, 32);
    ret.server__random() = substr(stream, 88, 32);
  } catch (TLS_Exception e) {
   TTCN_Logger::begin_event(TTCN_WARNING);
   TTCN_Logger::log_event("***Error has occured: %s. In file: %s in function: %s at line: %d", e.what, e.file, e.func, e.line);
   TTCN_Logger::end_event();
   return 0; 
 }   

  return 1;
}

/////////////////////////////////////
//// Change Cipher Specs Enum EncDec
/////////////////////////////////////

void enc__TLS__ChangeCipherSpecEnum(const TLS__Types::ChangeCipherSpecEnum& ccse, TTCN_Buffer& buf) {
  buf.put_os(int2oct(ccse, 1));
}

ChangeCipherSpecEnum dec__TLS__ChangeCipherSpecEnum(const OCTETSTRING& stream) throw(TLS_Exception){
 	if(!ChangeCipherSpecEnum::is_valid_enum(oct2int(stream))){
	  TLS_Exception e;
	  e.what = (const char*)"Invalid ChangeCipherSpecEnum";
		e.file = (const char*)__FILE__;
		e.line = __LINE__-4;
		e.func = __func__;
	  throw e;
	}  
	return (ChangeCipherSpecEnum) oct2int(stream);;	
}

/////////////////////////////////////
//// Change Cipher Specs EncDec
/////////////////////////////////////

void enc__TLS__ChangeCipherSpec(const TLS__Types::ChangeCipherSpec& ccs, TTCN_Buffer& buf) {
  enc__TLS__ChangeCipherSpecEnum(ccs.type__(), buf);
}

ChangeCipherSpec dec__TLS__ChangeCipherSpec(const OCTETSTRING& stream){
  ChangeCipherSpec ret;
  ret.type__() = dec__TLS__ChangeCipherSpecEnum(stream);
  
	return ret;	
}

/////////////////////////////////////
//// Alert Level EncDec
/////////////////////////////////////

void enc__TLS__AlertLevel(const TLS__Types::AlertLevel& al, TTCN_Buffer& buf) {
  buf.put_os(int2oct(al, 1));
}

AlertLevel dec__TLS__AlertLevel(const OCTETSTRING& stream) throw(TLS_Exception){
 	if(!AlertLevel::is_valid_enum(oct2int(stream))){
	  TLS_Exception e;
	  e.what = (const char*)"Invalid AlertLevel";
		e.file = (const char*)__FILE__;
		e.line = __LINE__-4;
		e.func = __func__;
	  throw e;
	}    
	return (AlertLevel) oct2int(stream);	
}

/////////////////////////////////////
//// Alert Description EncDec
/////////////////////////////////////

void enc__TLS__AlertDescription(const TLS__Types::AlertDescription& ald, TTCN_Buffer& buf) {
  buf.put_os(int2oct(ald, 1));
}

AlertDescription dec__TLS__AlertDescription(const OCTETSTRING& stream) throw(TLS_Exception){
 	if(!AlertDescription::is_valid_enum(oct2int(stream))){
	  TLS_Exception e;
	  e.what = (const char*)"Invalid AlertDescription";
		e.file = (const char*)__FILE__;
		e.line = __LINE__-4;
		e.func = __func__;
	  throw e;
	} 
  
	return (AlertDescription) oct2int(stream);
}

/////////////////////////////////////
//// Alert  EncDec
/////////////////////////////////////

void enc__TLS__Alert(const TLS__Types::Alert& alert, TTCN_Buffer& buf) {
	enc__TLS__AlertLevel(alert.level(), buf);
  enc__TLS__AlertDescription(alert.description(),buf);
}

Alert dec__TLS__Alert(const OCTETSTRING& stream) {
  Alert ret;
  
  ret.level() = dec__TLS__AlertLevel(substr(stream, 0, 1));
  ret.description() = dec__TLS__AlertDescription(substr(stream, 1, 1));
  
	return ret;	
}

/////////////////////////////////////
//// Handshake Type EncDec
/////////////////////////////////////

void enc__TLS__HandshakeType(const TLS__Types::HandshakeType& ht, TTCN_Buffer& buf) {
	buf.put_os(int2oct(ht, 1));
}

INTEGER dec__TLS__HandshakeType(const OCTETSTRING& stream, TLS__Types::HandshakeType& ret) {
	if(!HandshakeType::is_valid_enum(oct2int(stream))){
		return 0;
	}
	ret = (HandshakeType) oct2int(stream);
	return 1;
}

/////////////////////////////////////
//// Hello Request  EncDec
/////////////////////////////////////

void enc__TLS__HelloRequest(const HelloRequest& hr, TTCN_Buffer& buf) {
  buf.put_os(OCTETSTRING(0, (const unsigned char*)""));
}

HelloRequest dec__TLS__HelloRequest(const OCTETSTRING& stream) {
  HelloRequest ret = HelloRequest(NULL_VALUE);
 
  return ret;
}

/////////////////////////////////////
//// Random  EncDec
/////////////////////////////////////

void enc__TLS__Random(const TLS__Types::Random& rnd, TTCN_Buffer& buf) {
  buf.put_os(int2oct(rnd.gmt__unix__time(), 4));
  buf.put_os(rnd.random__bytes());

}

Random dec__TLS__Random(const OCTETSTRING& stream) throw(TLS_Exception){
  Random ret;
  
  ret.gmt__unix__time() = oct2int(substr(stream, 0, 4));
  ret.random__bytes() = substr(stream, 4, 28);
  
	return ret;	
}

/////////////////////////////////////
//// SessionID  EncDec
/////////////////////////////////////

void enc__TLS__SessionID(const TLS__Types::SessionID& sid, TTCN_Buffer& buf) {
	buf.put_os(int2oct(sid.lengthof(), 1));
  buf.put_os((OCTETSTRING) sid);
}

SessionID dec__TLS__SessionID(const OCTETSTRING& stream) {
  SessionID ret = (SessionID) stream;
  	
	return ret;
}

/////////////////////////////////////
//// Cipher Suite  EncDec
/////////////////////////////////////

void enc__TLS__CipherSuite(const TLS__Types::CipherSuite& cs, TTCN_Buffer& buf) {
  buf.put_os(cs.field1());
  buf.put_os(cs.field2());
}

CipherSuite dec__TLS__CipherSuite(const OCTETSTRING& stream) throw(TLS_Exception){
	CipherSuite ret;	
	
	if(stream.lengthof() < 2) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
		e.file = (const char*)__FILE__;
		e.line = __LINE__-4;
		e.func = __func__;
	  throw e;
	}
	
	ret.field1() =  substr(stream, 0, 1);
	ret.field2() =  substr(stream, 1, 1);
	
	return ret;
}

/////////////////////////////////////
//// Cipher Suite List EncDec
/////////////////////////////////////

void enc__TLS__CipherSuiteList(const TLS__Types::CipherSuiteList& csl, TTCN_Buffer& buf) {
  int size = csl.size_of();
  
  buf.put_os(int2oct(size*2, 2));
  for(int i = 0; i < size; i++){
    enc__TLS__CipherSuite(csl[i], buf);
  }
}

CipherSuiteList dec__TLS__CipherSuiteList(const OCTETSTRING& stream, const INTEGER& len) throw(TLS_Exception){
	CipherSuiteList ret;
  int size = len/2;
  if(stream.lengthof() != len) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
		e.file = (const char*)__FILE__;
		e.line = __LINE__-4;
		e.func = __func__;
	  throw e;
	}
  for(int i = 0; i < size; i++){
	  ret[i] = dec__TLS__CipherSuite(substr(stream, (i*2), 2));
	}
	
	return ret;
}

/////////////////////////////////////
//// Compression Method List EncDec
/////////////////////////////////////

void enc__TLS__CompressionMethodList(const TLS__Types::CompressionMethodList& cml, TTCN_Buffer& buf) {
  int size = (cml.size_of());
  
  buf.put_os(int2oct(size, 1));
  for(int i = 0; i < size; i++){
    enc__TLS__CompressionMethod(cml[i], buf);
  }
}

CompressionMethodList dec__TLS__CompressionMethodList(const OCTETSTRING& stream, const INTEGER& len) throw(TLS_Exception){
	CompressionMethodList ret;
	
  if(stream.lengthof() != len) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
		e.file = (const char*)__FILE__;
		e.line = __LINE__-4;
		e.func = __func__;
	  throw e;
	}
	
  for(int i = 0; i < len; i++){
	  ret[i] = dec__TLS__CompressionMethod(substr(stream, i, 1));
	}
	
	return ret;
}

/////////////////////////////////////
//// Client Hello  EncDec
/////////////////////////////////////

void enc__TLS__ClientHello(const TLS__Types::ClientHello& hello, TTCN_Buffer& buf) {
  enc__TLS__ProtocolVersion(hello.client__version(), buf);
  enc__TLS__Random(hello.random(), buf);
  if(hello.session__id().ispresent()){
    enc__TLS__SessionID(hello.session__id(), buf);
  } else {
	buf.put_c(0);
  } 
  enc__TLS__CipherSuiteList(hello.cipher__suites(), buf);
  enc__TLS__CompressionMethodList(hello.compression__methods(), buf);
  
  if(hello.extension__().ispresent()) {
	  buf.put_os(hello.extension__()());
	}
}

ClientHello dec__TLS__ClientHello(const OCTETSTRING& stream) throw(TLS_Exception){
  ClientHello ret;
  int offset = 0;
  int len = 0;
  int str_len = stream.lengthof();

  if(str_len < offset + 2) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  ret.client__version() = dec__TLS__ProtocolVersion(substr(stream, offset, 2));
  offset += 2;

  if(str_len < offset + 32) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  ret.random() = dec__TLS__Random(substr(stream, offset, 32));
  offset += 32;

  if(str_len < offset + 1) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  len = oct2int(substr(stream, offset, 1));
  offset += 1;
  
  if(len != 0) {
    if(str_len < offset + len) {
    	TLS_Exception e;
	    e.what = (const char*)"Invalid length";
		  e.file = (const char*)__FILE__;
		  e.line = __LINE__-4;
		  e.func = __func__;
	    throw e;
	  }
    ret.session__id() = dec__TLS__SessionID(substr(stream, offset, len));
    offset += len;
  } else {
    ret.session__id() = OMIT_VALUE;
  }  

  if(str_len < offset + 2) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  len = oct2int(substr(stream, offset, 2));
  offset += 2;

  if(str_len < offset + len) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  ret.cipher__suites() = dec__TLS__CipherSuiteList(substr(stream, offset, len), len);
  offset += len;

  if(str_len < offset + 1) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  len = oct2int(substr(stream,offset, 1));
  offset += 1;
  
  if(str_len < offset + len) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  ret.compression__methods() = dec__TLS__CompressionMethodList(substr(stream, offset, len), len);
  offset += len;
  
  if(str_len == offset){
	  ret.extension__() = OMIT_VALUE;
	} else {
	  ret.extension__()() = substr(stream, offset, str_len-offset);
	}


  return ret;
}

/////////////////////////////////////
//// Server Hello  EncDec
/////////////////////////////////////

void enc__TLS__ServerHello(const TLS__Types::ServerHello& hello, TTCN_Buffer& buf) {
  enc__TLS__ProtocolVersion(hello.server__version(), buf);
  enc__TLS__Random(hello.random(), buf);
  if(hello.session__id().ispresent()){
    enc__TLS__SessionID(hello.session__id(), buf);
  } else {
	  buf.put_c(0);
  }
  enc__TLS__CipherSuite(hello.cipher__suite(), buf);
  enc__TLS__CompressionMethod(hello.compression__method(), buf);
}

ServerHello dec__TLS__ServerHello(const OCTETSTRING& stream) throw(TLS_Exception){
  ServerHello ret;
  int offset = 0;
  int len;
  int str_len = stream.lengthof();

  if(str_len < offset + 2) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  ret.server__version() = dec__TLS__ProtocolVersion(substr(stream, offset, 2));
  offset += 2;

  if(str_len < offset + 32) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  ret.random() = dec__TLS__Random(substr(stream, offset, 32));
  offset += 32;

  if(str_len < offset + 1) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}  
  len = oct2int(substr(stream, offset, 1));
  offset += 1;
  
  if(len != 0) {
    if(str_len < offset + len) {
    	TLS_Exception e;
	    e.what = (const char*)"Invalid length";
	    e.file = (const char*)__FILE__;
	    e.line = __LINE__-4;
	    e.func = __func__;
	    throw e;
	  }
    ret.session__id() = dec__TLS__SessionID(substr(stream, offset, len));
    offset += len;
  } else {
    ret.session__id() = OMIT_VALUE;
  }  

  if(str_len < offset + 2) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}  
  ret.cipher__suite() = dec__TLS__CipherSuite(substr(stream, offset, 2));
  offset += 2;

  if(str_len < offset + 1) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  ret.compression__method() = dec__TLS__CompressionMethod(substr(stream, offset, 1));

  return ret;
}

/////////////////////////////////////
//// Certificate List EncDec
/////////////////////////////////////

void enc__TLS__CertificateList(const TLS__Types::CertificateList& certl, TTCN_Buffer& buf) {
  int size = certl.size_of();
  
  for(int i = 0; i < size; i++){
    buf.put_os(int2oct(certl[i].lengthof(), 3));
    buf.put_os(certl[i]);
  }
}

CertificateList dec__TLS__CertificateList(const OCTETSTRING& stream, const INTEGER& stream_len) throw(TLS_Exception){
	CertificateList ret;
  int len;
  int i = 0;
  int offset = 0;
  if(stream_len != stream.lengthof()) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  do {
    len = oct2int(substr(stream, offset, 3));
    offset += 3;
    if(stream_len < offset + len) {
    	TLS_Exception e;
	    e.what = (const char*)"Invalid length";
	    e.file = (const char*)__FILE__;
	    e.line = __LINE__-4;
	    e.func = __func__;
	    throw e;
	  }
    ret[i] = substr(stream, offset, len);
    offset += len;
    i++;
 } while(offset + 3 <= stream_len);
	
	return ret;
}

/////////////////////////////////////
//// Certificate EncDec
/////////////////////////////////////

void enc__TLS__Certificate(const TLS__Types::Certificate& cert, TTCN_Buffer& buf) {
  int len=0;
  int size = cert.certificate__list()().size_of();
  
  for(int i = 0; i < size; i++){
    len += cert.certificate__list()()[i].lengthof();
  }
  
  buf.put_os(int2oct(len+3*size, 3));
  enc__TLS__CertificateList(cert.certificate__list(), buf);
}

Certificate dec__TLS__Certificate(const OCTETSTRING& stream) throw(TLS_Exception){
	Certificate ret;
  int len;
  int str_len = stream.lengthof();
  
  if(str_len < 3) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  len = oct2int(substr(stream, 0, 3));
  
  if(str_len < len + 3) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  ret.certificate__list() = dec__TLS__CertificateList(substr(stream, 3, len), len);
	
	return ret;
}

/////////////////////////////////////
//// Key Exchange Algorithm EncDec
/////////////////////////////////////

void enc__TLS__KeyExchangeAlgorithm(const TLS__Types::KeyExchangeAlgorithm& kea, TTCN_Buffer& buf) {
  buf.put_os(int2oct(kea, 1));
}

KeyExchangeAlgorithm dec__TLS__KeyExchangeAlgorithm(const OCTETSTRING& stream) throw(TLS_Exception){
 	if(!KeyExchangeAlgorithm::is_valid_enum(oct2int(stream))){
	  TLS_Exception e;
	  e.what = (const char*)"Invalid KeyExchangeAlgorithm";
		e.file = (const char*)__FILE__;
		e.line = __LINE__-4;
		e.func = __func__;
	  throw e;
	} 
  KeyExchangeAlgorithm ret = (KeyExchangeAlgorithm) oct2int(stream);  
  
	return ret;	
}

/////////////////////////////////////
//// Server RSA Params EncDec
/////////////////////////////////////

void enc__TLS__ServerRSAParams(const TLS__Types::ServerRSAParams& srsap, TTCN_Buffer& buf) {
  buf.put_os(int2oct(srsap.rsa__modulus().lengthof(), 2));
  buf.put_os(srsap.rsa__modulus());
  buf.put_os(int2oct(srsap.rsa__exponent().lengthof(), 2));
  buf.put_os(srsap.rsa__exponent());
}

ServerRSAParams dec__TLS__ServerRSAParams(const OCTETSTRING& stream) throw(TLS_Exception){
  ServerRSAParams ret;  
  int offset = 0;
  int len = 0;
  int str_len = stream.lengthof();
  
  if(str_len < offset + 2) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  len = oct2int(substr(stream, offset, 2));
  offset += 2;
  
  if(str_len < offset + len) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  ret.rsa__modulus() = substr(stream, offset, len);
  offset += len;

  if(str_len < offset + 2) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}  
  len = oct2int(substr(stream, offset, 2));
  offset += 2;

  if(str_len < offset + len) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}  
  ret.rsa__exponent() = substr(stream, offset, len);
  
	return ret;	
}

/////////////////////////////////////
//// Server DH Params EncDec
/////////////////////////////////////

void enc__TLS__ServerDHParams(const TLS__Types::ServerDHParams& sdhp, TTCN_Buffer& buf) {
  buf.put_os(int2oct(sdhp.dh__p().lengthof(), 2));
  buf.put_os(sdhp.dh__p());
  buf.put_os(int2oct(sdhp.dh__g().lengthof(), 2));
  buf.put_os(sdhp.dh__g());
  buf.put_os(int2oct(sdhp.dh__Ys().lengthof(), 2));
  buf.put_os(sdhp.dh__Ys());
}

ServerDHParams dec__TLS__ServerDHParams(const OCTETSTRING& stream) throw(TLS_Exception){
  ServerDHParams ret;  
  int offset = 0;
  int len;
  int str_len = stream.lengthof();

  if(str_len < offset + 2) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}  
  len = oct2int(substr(stream, offset, 2));
  offset += 2;

  if(str_len < offset + len) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}  
  ret.dh__p() = substr(stream, offset, len);
  offset += len;

  if(str_len < offset + 2) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}  
  len = oct2int(substr(stream, offset, 2));
  offset += 2;

  if(str_len < offset + len) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}  
  ret.dh__g() = substr(stream, offset, len);
  offset += len;

  if(str_len < offset + 2) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}  
  len = oct2int(substr(stream, offset, 2));
  offset += 2;

  if(str_len < offset + len) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}  
  ret.dh__Ys() = substr(stream, offset, len);
  
	return ret;	
}

/////////////////////////////////////
//// RSA Signature EncDec
/////////////////////////////////////

void enc__TLS__RSASignature(const TLS__Types::RSASignature& rsasign, TTCN_Buffer& buf) {
  buf.put_os(rsasign.md5__hash());
  buf.put_os(rsasign.sha__hash());
}

RSASignature dec__TLS__RSASignature(const OCTETSTRING& stream) throw(TLS_Exception){
  RSASignature ret;
  int str_len = stream.lengthof();

  if(str_len < 36) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
	
  ret.md5__hash() = substr(stream, 0, 16);
  ret.sha__hash() = substr(stream, 16, 20);

	return ret;
}

/////////////////////////////////////
//// DSA Signature EncDec
/////////////////////////////////////

void enc__TLS__DSASignature(const TLS__Types::DSASignature& dsasign, TTCN_Buffer& buf) {
  buf.put_os(dsasign.sha__hash());
}

DSASignature dec__TLS__DSASignature(const OCTETSTRING& stream) throw(TLS_Exception){
  DSASignature ret;
  int str_len = stream.lengthof();

  if(str_len < 20) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  ret.sha__hash() = substr(stream, 0, 20);

	return ret;
}

/////////////////////////////////////
//// Anonym Signature EncDec
/////////////////////////////////////

void enc__TLS__AnonymSignature(const TLS__Types::AnonymSignature& anonsign, TTCN_Buffer& buf) {
  buf.put_os(OCTETSTRING(0, (const unsigned char*)""));
}

AnonymSignature dec__TLS__AnonymSignature(const OCTETSTRING& stream) {
  AnonymSignature ret = AnonymSignature(NULL_VALUE);

	return ret;
}

/////////////////////////////////////
//// Signature EncDec
/////////////////////////////////////

void enc__TLS__Signature(const TLS__Types::Signature& sign, TTCN_Buffer& buf) {
  switch(sign.get_selection()){
    case Signature::ALT_anonym : enc__TLS__AnonymSignature(sign.anonym(), buf); break;
    case Signature::ALT_rsa : enc__TLS__RSASignature(sign.rsa(), buf); break;
    case Signature::ALT_dsa : enc__TLS__DSASignature(sign.dsa(), buf); break;
    default : buf.put_os(sign.sign()); break;
  }
}

Signature dec__TLS__Signature(const OCTETSTRING& stream) throw(TLS_Exception){
  Signature ret;
  switch(stream.lengthof()){
    case 0 : ret.anonym() = dec__TLS__AnonymSignature(stream); break;
    case 36 : ret.rsa() = dec__TLS__RSASignature(stream); break;
    case 20 : ret.dsa() = dec__TLS__DSASignature(stream); break;
    default : ret.sign() = stream; break;
  }

	return ret;
}

/////////////////////////////////////
//// Server Params EncDec
/////////////////////////////////////

void enc__TLS__ServerParams(const TLS__Types::ServerParams& sp, TTCN_Buffer& buf) {
  switch(sp.get_selection()){
    case ServerParams::ALT_dh__params : enc__TLS__ServerDHParams(sp.dh__params(), buf); break;
    case ServerParams::ALT_rsa__params : enc__TLS__ServerRSAParams(sp.rsa__params(), buf); break;
    default :
    TTCN_Logger::begin_event(TTCN_WARNING);
    TTCN_Logger::log_event("Wrong field was selected from ServerParams");
    TTCN_Logger::end_event();

  }
}

ServerParams dec__TLS__ServerParams(const OCTETSTRING& stream) throw(TLS_Exception){
  ServerParams ret;
  int len;
  int str_len = stream.lengthof();
  
  if(str_len < 2) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  len = oct2int(substr(stream, 0, 2));
  len += oct2int(substr(stream, len + 2, len + 4));

  ret.dh__params() = dec__TLS__ServerDHParams(stream);
  if((len + 4) == str_len){
    ret.rsa__params() = dec__TLS__ServerRSAParams(stream);
  } else {
    ret.dh__params() = dec__TLS__ServerDHParams(stream);
  }
	return ret;
}

/////////////////////////////////////
//// Server Key Exchange EncDec
/////////////////////////////////////

void enc__TLS__ServerKeyExchange(const TLS__Types::ServerKeyExchange& ske, TTCN_Buffer& buf) {
  enc__TLS__ServerParams(ske.params(), buf);
  enc__TLS__Signature(ske.signed__params(), buf);
}

ServerKeyExchange dec__TLS__ServerKeyExchange(const OCTETSTRING& stream, const TLS__Types::KeyExchangeAlgorithm& kea) throw(TLS_Exception){
  ServerKeyExchange ret;  
  int len = 0;
  int offset = 0;
  int str_len = stream.lengthof();
  OCTETSTRING p1;
  OCTETSTRING p2;
  OCTETSTRING p3;
  
  switch(kea){
    case KeyExchangeAlgorithm::diffie__hellman : 
      if(str_len < offset + 2) {
      	TLS_Exception e;
	      e.what = (const char*)"Invalid length";
	      e.file = (const char*)__FILE__;
	      e.line = __LINE__-4;
	      e.func = __func__;
	      throw e;
	    }
      len = oct2int(substr(stream, offset, 2));
      offset += 2;
      
      if(str_len < offset + len) {
      	TLS_Exception e;
	      e.what = (const char*)"Invalid length";
	      e.file = (const char*)__FILE__;
	      e.line = __LINE__-4;
	      e.func = __func__;
	      throw e;
	    }
      p1 = substr(stream, offset, len);
      offset += len;
  
      if(str_len < offset + 2) {
      	TLS_Exception e;
	      e.what = (const char*)"Invalid length";
	      e.file = (const char*)__FILE__;
	      e.line = __LINE__-4;
	      e.func = __func__;
	      throw e;
	    }
      len = oct2int(substr(stream, offset, 2));
      offset += 2;
      
      if(str_len < offset + len) {
      	TLS_Exception e;
	      e.what = (const char*)"Invalid length";
	      e.file = (const char*)__FILE__;
	      e.line = __LINE__-4;
	      e.func = __func__;
	      throw e;
	    }
      p2 = substr(stream, offset, len);
      offset += len;
      
      if(str_len < offset + 2) {
      	TLS_Exception e;
	      e.what = (const char*)"Invalid length";
	      e.file = (const char*)__FILE__;
	      e.line = __LINE__-4;
	      e.func = __func__;
	      throw e;
	    }
      len = oct2int(substr(stream, offset, 2));
      offset += 2;
      
      if(str_len < offset + len) {
      	TLS_Exception e;
	      e.what = (const char*)"Invalid length";
	      e.file = (const char*)__FILE__;
	      e.line = __LINE__-4;
	      e.func = __func__;
	      throw e;
	    }
      p3 = substr(stream, offset, len);
      offset += len;
      
      ret.params().dh__params().dh__p() = p1;
      ret.params().dh__params().dh__g() = p2;
      ret.params().dh__params().dh__Ys() = p3;
      
      break;
      
    case KeyExchangeAlgorithm::rsa :
      if(str_len < offset + 2) {
      	TLS_Exception e;
	      e.what = (const char*)"Invalid length";
	      e.file = (const char*)__FILE__;
	      e.line = __LINE__-4;
	      e.func = __func__;
	      throw e;
	    }
      len = oct2int(substr(stream, offset, 2));
      offset += 2;
      
      if(str_len < offset + len) {
      	TLS_Exception e;
	      e.what = (const char*)"Invalid length";
	      e.file = (const char*)__FILE__;
	      e.line = __LINE__-4;
	      e.func = __func__;
	      throw e;
	    }
      p1 = substr(stream, offset, len);
      offset += len;
  
      if(str_len < offset + 2) {
      	TLS_Exception e;
	      e.what = (const char*)"Invalid length";
	      e.file = (const char*)__FILE__;
	      e.line = __LINE__-4;
	      e.func = __func__;
	      throw e;
	    }
      len = oct2int(substr(stream, offset, 2));
      offset += 2;
      
      if(str_len < offset + len) {
      	TLS_Exception e;
	      e.what = (const char*)"Invalid length";
	      e.file = (const char*)__FILE__;
	      e.line = __LINE__-4;
	      e.func = __func__;
	      throw e;
	    }
      p2 = substr(stream, offset, len);
      offset += len;
      
      ret.params().rsa__params().rsa__modulus() = p1;
      ret.params().rsa__params().rsa__exponent() = p2;
      
      break;
      
    default : break;
  }
  
  ret.signed__params() = dec__TLS__Signature(substr(stream, offset, str_len - offset));
	return ret;	
}

/////////////////////////////////////
//// Signature Algorithm EncDec
/////////////////////////////////////

void enc__TLS__SignatureAlgorithm(const TLS__Types::SignatureAlgorithm& sa, TTCN_Buffer& buf) {
  buf.put_os(int2oct(sa, 1));
}

SignatureAlgorithm dec__TLS__SignatureAlgorithm(const OCTETSTRING& stream) throw(TLS_Exception){
  if(!SignatureAlgorithm::is_valid_enum(oct2int(stream))) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid SignatureAlgorithm";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  SignatureAlgorithm ret = (SignatureAlgorithm) oct2int(stream);  
  
	return ret;	
}

/////////////////////////////////////
//// Client Certificate Type EncDec
/////////////////////////////////////

void enc__TLS__ClientCertificateType(const TLS__Types::ClientCertificateType& cct, TTCN_Buffer& buf) {
  buf.put_os(int2oct(cct, 1));
}

ClientCertificateType dec__TLS__ClientCertificateType(const OCTETSTRING& stream) throw(TLS_Exception){
  if(!ClientCertificateType::is_valid_enum(oct2int(stream))) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid ClientCertificateType";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  ClientCertificateType ret = (ClientCertificateType) oct2int(stream);
  
	return ret;	
}

/////////////////////////////////////
//// Client Certificate Type List EncDec
/////////////////////////////////////

void enc__TLS__ClientCertificateTypeList(const TLS__Types::ClientCertificateTypeList& cctl, TTCN_Buffer& buf) {
  int size = cctl.size_of();
  
  buf.put_os(int2oct(size, 1));
  for(int i = 0; i < size; i++){
    enc__TLS__ClientCertificateType(cctl[i], buf);
  }
}

ClientCertificateTypeList dec__TLS__ClientCertificateTypeList(const OCTETSTRING& stream, const INTEGER& size) throw(TLS_Exception){
  ClientCertificateTypeList ret;  
  if(stream.lengthof() < size) {
  	TLS_Exception e;
	  e.what = (const char*)"Invalid ClientCertificateTypeList";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  for(int i = 0; i < size; i++){
    ret[i] = dec__TLS__ClientCertificateType(substr(stream, i, 1));
  }
  
	return ret;	
}

/////////////////////////////////////
//// Distinguished Name EncDec
/////////////////////////////////////

void enc__TLS__DistinguishedName(const TLS__Types::DistinguishedName& dn, TTCN_Buffer& buf) {
	  buf.put_os(int2oct(dn.lengthof(), 2));
	  buf.put_os(dn);
}

DistinguishedName dec__TLS__DistinguishedName(const OCTETSTRING& stream) throw(TLS_Exception){
  DistinguishedName ret;
  int str_len = stream.lengthof();
  
  if(str_len < 2) {
   	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  int len = oct2int(substr(stream, 0, 2));
  if(len != 0) {
    if(str_len < len + 2) {
     	TLS_Exception e;
	    e.what = (const char*)"Invalid length";
	    e.file = (const char*)__FILE__;
	    e.line = __LINE__-4;
	    e.func = __func__;
	    throw e;
	  }
	  ret = substr(stream, 2, len);
  }
  
	return ret;	
}

/////////////////////////////////////
//// Certificate Request EncDec
/////////////////////////////////////

void enc__TLS__CertificateRequest(const TLS__Types::CertificateRequest& cr, TTCN_Buffer& buf) {
  enc__TLS__ClientCertificateTypeList(cr.certificate__types(), buf);
  buf.put_os(int2oct(cr.certificate__authorities()().lengthof()+2, 2));
  if(cr.certificate__authorities().ispresent()){
	  enc__TLS__DistinguishedName(cr.certificate__authorities(), buf);
  } else {
	  buf.put_os(OCTETSTRING(2, (const unsigned char*)"0000"));
  }
}

CertificateRequest dec__TLS__CertificateRequest(const OCTETSTRING& stream) throw(TLS_Exception){
  CertificateRequest ret;  
  int offset = 0;
  int str_len = stream.lengthof();
  
  if(str_len < offset + 1) {
   	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  int len = oct2int(substr(stream, 0, 1));
  offset += 1;

  if(str_len < offset + len) {
   	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  ret.certificate__types() = dec__TLS__ClientCertificateTypeList(substr(stream, offset, len), len);
  offset += len;

  if(str_len < offset + 2) {
   	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}  
  len = oct2int(substr(stream, offset, 2));
  offset += 2;

  if(str_len < offset + len) {
   	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  ret.certificate__authorities() = dec__TLS__DistinguishedName(substr(stream, offset, len));

  if(!ret.certificate__authorities().is_bound()){
	  ret.certificate__authorities() = OMIT_VALUE;
  }
    
	return ret;	
}

/////////////////////////////////////
//// Server Hello Done EncDec
/////////////////////////////////////

void enc__TLS__ServerHelloDone(const ServerHelloDone& shd, TTCN_Buffer& buf) {
  buf.put_os(OCTETSTRING(0, (const unsigned char*)""));
}

ServerHelloDone dec__TLS__ServerHelloDone(const OCTETSTRING& stream) {
  return ServerHelloDone(NULL_VALUE);
}

/////////////////////////////////////
//// Certificate Verify EncDec
/////////////////////////////////////

void enc__TLS__CertificateVerify(const TLS__Types::CertificateVerify& cv, TTCN_Buffer& buf) {
  enc__TLS__Signature(cv.signature__(), buf);
}

CertificateVerify dec__TLS__CertificateVerify(const OCTETSTRING& stream) {
	CertificateVerify ret;
  
  ret.signature__() = dec__TLS__Signature(stream);
  
  return ret;
}

/////////////////////////////////////
//// Public Value Encoding EncDec
/////////////////////////////////////

void enc__TLS__PublicValueEncoding(const TLS__Types::PublicValueEncoding& pve, TTCN_Buffer& buf) {
  buf.put_os(int2oct(pve, 1));
}

PublicValueEncoding dec__TLS__PublicValueEncoding(const OCTETSTRING& stream) throw(TLS_Exception){
  if(!PublicValueEncoding::is_valid_enum(oct2int(stream))) {
   	TLS_Exception e;
	  e.what = (const char*)"Invalid PublicValueEncoding";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
	PublicValueEncoding ret = (PublicValueEncoding) oct2int(stream);
  
	return ret;	
}

/////////////////////////////////////
//// Premaster Secret EncDec
/////////////////////////////////////

void enc__TLS__PreMasterSecret(const TLS__Types::PreMasterSecret& ps, TTCN_Buffer& buf) {
  enc__TLS__ProtocolVersion(ps.client__version(), buf);
  buf.put_os(ps.random());  
}

PreMasterSecret dec__TLS__PreMasterSecret(const OCTETSTRING& stream) throw(TLS_Exception){
  PreMasterSecret ret;  
  int str_len = stream.lengthof();

  if(str_len < 2) {
   	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}  
  ret.client__version() = dec__TLS__ProtocolVersion(substr(stream, 0, 2));

  if(str_len < 48) {
   	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	} 
  ret.random() = substr(stream, 2, 46);
    
	return ret;	
}

/////////////////////////////////////
//// Encrypted PreMaster Secret EncDec
/////////////////////////////////////

void enc__TLS__EncryptedPreMasterSecret(const TLS__Types::EncryptedPreMasterSecret epms, TTCN_Buffer& buf) {
  enc__TLS__PreMasterSecret(epms.pre__master__secret(), buf);
}

EncryptedPreMasterSecret dec__TLS__EncryptedPreMasterSecret(const OCTETSTRING& stream) {
  EncryptedPreMasterSecret ret;
  
  ret.pre__master__secret() = dec__TLS__PreMasterSecret(stream);
  
  return ret;
}

/////////////////////////////////////
//// Client Diffie Hellman Public Implicit EncDec
/////////////////////////////////////

void enc__TLS__ClientDiffieHellmanPublicImplicit(const TLS__Types::ClientDiffieHellmanPublicImplicit cdhpi, TTCN_Buffer& buf) {
  buf.put_os(OCTETSTRING(0, (const unsigned char*)""));
}

ClientDiffieHellmanPublicImplicit dec__TLS__ClientDiffieHellmanPublicImplicit(const OCTETSTRING& stream) {
  return ClientDiffieHellmanPublicImplicit(NULL_VALUE);
}

/////////////////////////////////////
//// Client Diffie Hellman Public Explicit EncDec
/////////////////////////////////////

void enc__TLS__ClientDiffieHellmanPublicExplicit(const TLS__Types::ClientDiffieHellmanPublicExplicit cdhpe, TTCN_Buffer& buf) {
  buf.put_os(int2oct(cdhpe.DH__Yc().lengthof(), 2));
  buf.put_os(cdhpe.DH__Yc());
}

ClientDiffieHellmanPublicExplicit dec__TLS__ClientDiffieHellmanPublicExplicit(const OCTETSTRING& stream) throw(TLS_Exception){
  ClientDiffieHellmanPublicExplicit ret;
  int len;
  int str_len = stream.lengthof();
  
  if(str_len < 2) {
   	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  len = oct2int(substr(stream, 0, 2));
  
  if(str_len < len + 2) {
   	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  ret.DH__Yc() = substr(stream, 2, len);
    
  return ret;
}

/////////////////////////////////////
//// Client Diffie Hellman Public Values EncDec
/////////////////////////////////////

void enc__TLS__ClientDiffieHellmanPublicValues(const TLS__Types::ClientDiffieHellmanPublicValues cdhpv, const TLS__Types::PublicValueEncoding pve, TTCN_Buffer& buf) {
   switch(pve) {
    case PublicValueEncoding::implicit : enc__TLS__ClientDiffieHellmanPublicImplicit(cdhpv.implicit(), buf); break;
    case PublicValueEncoding::explicit__ : enc__TLS__ClientDiffieHellmanPublicExplicit(cdhpv.explicit__(), buf); break;
    default :
      TTCN_Logger::begin_event(TTCN_WARNING);
      TTCN_Logger::log_event("Wrong field was selected from ClientDiffieHellmanPublicValues");
      TTCN_Logger::end_event();
    }
}

ClientDiffieHellmanPublicValues dec__TLS__ClientDiffieHellmanPublicValues(const OCTETSTRING& stream, const TLS__Types::PublicValueEncoding pve) {
  ClientDiffieHellmanPublicValues ret;
   
   switch(pve) {
    case PublicValueEncoding::implicit : ret.implicit() = dec__TLS__ClientDiffieHellmanPublicImplicit(stream); break;
    case PublicValueEncoding::explicit__ : ret.explicit__() = dec__TLS__ClientDiffieHellmanPublicExplicit(stream); break;
    default :
      TTCN_Logger::begin_event(TTCN_WARNING);
      TTCN_Logger::log_event("Wrong field was selected from ClientDiffieHellmanPublicValues");
      TTCN_Logger::end_event();
    }
    
  return ret;
}

/////////////////////////////////////
//// Client Diffie Hellman Public EncDec
/////////////////////////////////////

void enc__TLS__ClientDiffieHellmanPublic(const TLS__Types::ClientDiffieHellmanPublic cdhp, TTCN_Buffer& buf) {
  PublicValueEncoding pve;
  
  if(cdhp.dh__public().get_selection() == ClientDiffieHellmanPublicValues::ALT_implicit){
    pve = PublicValueEncoding::implicit;
  } else {
    pve = PublicValueEncoding::explicit__;
  }   

 enc__TLS__ClientDiffieHellmanPublicValues(cdhp.dh__public(), pve, buf);
}

ClientDiffieHellmanPublic dec__TLS__ClientDiffieHellmanPublic(const OCTETSTRING& stream) {
  ClientDiffieHellmanPublic ret;
  PublicValueEncoding pve;
  
  if(stream.lengthof() == 0){
    pve = PublicValueEncoding::implicit;
  } else {
    pve = PublicValueEncoding::explicit__;
  }
  
  ret.dh__public() = dec__TLS__ClientDiffieHellmanPublicValues(stream, pve);
    
  return ret;
}

/////////////////////////////////////
//// Client Key Exchange Keys EncDec
/////////////////////////////////////

void enc__TLS__ClientKeyExchangeKeys(const TLS__Types::ClientKeyExchangeKeys ckek, const TLS__Types::KeyExchangeAlgorithm& kea, TTCN_Buffer& buf) {
  switch(kea){
    case KeyExchangeAlgorithm::rsa : enc__TLS__EncryptedPreMasterSecret(ckek.rsa(), buf); break;
    case KeyExchangeAlgorithm::diffie__hellman : enc__TLS__ClientDiffieHellmanPublic(ckek.diffie__hellman(), buf); break;
    default :
    TTCN_Logger::begin_event(TTCN_WARNING);
    TTCN_Logger::log_event("Wrong field was selected from ClientKeyExchangeKeys");
    TTCN_Logger::end_event();
  }
}

ClientKeyExchangeKeys dec__TLS__ClientKeyExchangeKeys(const OCTETSTRING& stream, const TLS__Types::KeyExchangeAlgorithm& kea) {
  ClientKeyExchangeKeys ret;
  
  switch(kea){
    case KeyExchangeAlgorithm::rsa : ret.rsa() = dec__TLS__EncryptedPreMasterSecret(stream); break;
    case KeyExchangeAlgorithm::diffie__hellman : ret.diffie__hellman() = dec__TLS__ClientDiffieHellmanPublic(stream); break;
    default :
    TTCN_Logger::begin_event(TTCN_WARNING);
    TTCN_Logger::log_event("Wrong field was selected from ClientKeyExchangeKeys");
    TTCN_Logger::end_event();
  };
    
  return ret;
}

/////////////////////////////////////
//// Client Key Exchange EncDec
/////////////////////////////////////

void enc__TLS__ClientKeyExchange(const TLS__Types::ClientKeyExchange& cke, TTCN_Buffer& buf) {
  KeyExchangeAlgorithm kea;
  
  if(cke.exchange__keys().get_selection() == ClientKeyExchangeKeys::ALT_rsa) {
    kea = KeyExchangeAlgorithm::rsa;
  } else {
    kea = KeyExchangeAlgorithm::diffie__hellman;
  }
  
  enc__TLS__ClientKeyExchangeKeys(cke.exchange__keys(), kea, buf);
}

ClientKeyExchange dec__TLS__ClientKeyExchange(const OCTETSTRING& stream) {
  ClientKeyExchange ret;
  KeyExchangeAlgorithm kea;
  
  if(stream.lengthof() == 48) {
    kea = KeyExchangeAlgorithm::rsa;
  } else {
    kea = KeyExchangeAlgorithm::diffie__hellman;
  }
  
  ret.exchange__keys() = dec__TLS__ClientKeyExchangeKeys(stream, kea);
    
  return ret;
}

/////////////////////////////////////
//// Finished EncDec
/////////////////////////////////////

void enc__TLS__Finished(const TLS__Types::Finished& fin, TTCN_Buffer& buf) {
  buf.put_os(fin.verify__data());
}

Finished dec__TLS__Finished(const OCTETSTRING& stream) {
  Finished ret;
  
  ret.verify__data() = stream;
    
  return ret;
}

/////////////////////////////////////
//// Handshake Body EncDec
/////////////////////////////////////

void enc__TLS__HandshakeBody(const TLS__Types::HandshakeBody& body, const TLS__Types::HandshakeType& type, TTCN_Buffer& buf) {
  switch(type){
    case HandshakeType::hello__request : enc__TLS__HelloRequest(body.hello__request(), buf); break;
    case HandshakeType::client__hello : enc__TLS__ClientHello(body.client__hello(), buf); break;
    case HandshakeType::server__hello : enc__TLS__ServerHello(body.server__hello(), buf); break;
    case HandshakeType::certificate : enc__TLS__Certificate(body.certificate(), buf); break;
    case HandshakeType::server__key__exchange : enc__TLS__ServerKeyExchange(body.server__key__exchange(), buf); break;
    case HandshakeType::certificate__request : enc__TLS__CertificateRequest(body.certificate__request(), buf); break;
    case HandshakeType::server__hello__done : enc__TLS__ServerHelloDone(body.server__hello__done(), buf); break;
    case HandshakeType::certificate__verify : enc__TLS__CertificateVerify(body.certificate__verify(), buf); break;
    case HandshakeType::client__key__exchange : enc__TLS__ClientKeyExchange(body.client__key__exchange(), buf); break;
    case HandshakeType::finished : enc__TLS__Finished(body.finished(), buf); break;
    default :
      TTCN_Logger::begin_event(TTCN_WARNING);
      TTCN_Logger::log_event("Wrong field was selected from HandshakeBody");
      TTCN_Logger::end_event();
  }
}

HandshakeBody dec__TLS__HandshakeBody(const OCTETSTRING& stream, const TLS__Types::HandshakeType& type, const TLS__Types::KeyExchangeAlgorithm& kea) {
  HandshakeBody ret;
  switch(type){
    case HandshakeType::hello__request : ret.hello__request() = dec__TLS__HelloRequest(stream); break;
    case HandshakeType::client__hello : ret.client__hello() = dec__TLS__ClientHello(stream); break;
    case HandshakeType::server__hello : ret.server__hello() = dec__TLS__ServerHello(stream); break;
    case HandshakeType::certificate : ret.certificate() = dec__TLS__Certificate(stream); break;
    case HandshakeType::server__key__exchange : ret.server__key__exchange() = dec__TLS__ServerKeyExchange(stream, kea); break;
    case HandshakeType::certificate__request : ret.certificate__request() = dec__TLS__CertificateRequest(stream); break;
    case HandshakeType::server__hello__done : ret.server__hello__done() = dec__TLS__ServerHelloDone(stream); break;
    case HandshakeType::certificate__verify : ret.certificate__verify() = dec__TLS__CertificateVerify(stream); break;
    case HandshakeType::client__key__exchange : ret.client__key__exchange() = dec__TLS__ClientKeyExchange(stream); break;
    case HandshakeType::finished : ret.finished() = dec__TLS__Finished(stream); break;
    default :
      TTCN_Logger::begin_event(TTCN_WARNING);
      TTCN_Logger::log_event("Wrong field was selected from HandshakeBody");
      TTCN_Logger::end_event();
  }

  return ret;
}

/////////////////////////////////////
//// Handshake  Enc
/////////////////////////////////////

void enc__TLS__Handshake(const TLS__Types::Handshake& hs, TTCN_Buffer& buf) {
  if(hs.msg__type().ispresent())
	  enc__TLS__HandshakeType(hs.msg__type(), buf);
  if(hs.length__().ispresent())
	  buf.put_os(int2oct(hs.length__(), 3));
  if(hs.msg__type().ispresent())
	  enc__TLS__HandshakeBody(hs.body(), hs.msg__type(), buf);
  else
	  buf.put_os(hs.body().encrypted());
}

/////////////////////////////////////
//// Multiple Handshake  EncDec
/////////////////////////////////////

void enc__TLS__MultipleHandshake(const TLS__Types::MultipleHandshake& hs, TTCN_Buffer& buf) {
  for(int i = 0; i < hs.size_of(); i++){
    enc__TLS__Handshake(hs[i], buf);
  }
}

MultipleHandshake dec__TLS__MultipleHandshake(const OCTETSTRING& stream, const TLS__Types::KeyExchangeAlgorithm& kea) throw(TLS_Exception){
  MultipleHandshake ret;
  int offset = 0;
  int i = 0;
  int str_len = stream.lengthof();

  do {
	  if(str_len < offset + 1) {
	   	TLS_Exception e;
		  e.what = (const char*)"Invalid length";
		  e.file = (const char*)__FILE__;
		  e.line = __LINE__-4;
		  e.func = __func__;
		  throw e;
		}
	  int res = dec__TLS__HandshakeType(substr(stream, offset, 1), ret[i].msg__type()());
	  if(res != 1){
		  ret[i].body().encrypted() = substr(stream, offset, str_len - offset);
		  ret[i].msg__type() = OMIT_VALUE;
		  ret[i].length__() = OMIT_VALUE;
		  return ret;
	  }
	  offset += 1;

	  if(str_len < offset + 3) {
	   	TLS_Exception e;
		  e.what = (const char*)"Invalid length";
		  e.file = (const char*)__FILE__;
		  e.line = __LINE__-4;
		  e.func = __func__;
		  throw e;
		}
	  ret[i].length__() = oct2int(substr(stream, offset, 3));
	  offset += 3;
	  try {
		ret[i].body() = dec__TLS__HandshakeBody(substr(stream, offset, ret[i].length__()()), ret[i].msg__type()(), kea);
	  } catch (TLS_Exception e) {
		  ret[i].body().encrypted() = substr(stream, offset, str_len - offset);
		  ret[i].msg__type() = OMIT_VALUE;
		  ret[i].length__() = OMIT_VALUE;
		  return ret;
	  }
		offset += ret[i].length__()();
		i++;
  } while(offset < str_len);

	return ret;
}

/////////////////////////////////////
//// Content EncDec
/////////////////////////////////////

OCTETSTRING enc__TLS__Content(const TLS__Types::Content& cont, const TLS__Types::ContentType& ctype, TTCN_Buffer& buf){
  OCTETSTRING ret;
	switch(ctype) {
    case ContentType::change__cipher__spec : enc__TLS__ChangeCipherSpec(cont.change__cipher__spec(), buf); break;
    case ContentType::alert :  enc__TLS__Alert(cont.alert(), buf); break;
    case ContentType::handshake : enc__TLS__MultipleHandshake(cont.multiple__handshake(), buf); break;
    case ContentType::application__data : buf.put_os(cont.application__data()); break;
    default :
      TTCN_Logger::begin_event(TTCN_WARNING);
      TTCN_Logger::log_event("Wrong field was selected from Content");
      TTCN_Logger::end_event();
  }
	buf.get_string(ret);

	return ret;

}

Content dec__TLS__Content(const OCTETSTRING& stream, const TLS__Types::ContentType& ctype, const KeyExchangeAlgorithm& kea){
  Content ret;
  
  switch(ctype) {
  case ContentType::change__cipher__spec : ret.change__cipher__spec() = dec__TLS__ChangeCipherSpec(stream); break;
  case ContentType::alert : ret.alert() = dec__TLS__Alert(stream); break;
  case ContentType::handshake : ret.multiple__handshake() = dec__TLS__MultipleHandshake(stream, kea); break;
  case ContentType::application__data : ret.application__data() = stream; break;
  default :
    TTCN_Logger::begin_event(TTCN_WARNING);
    TTCN_Logger::log_event("Wrong field was selected from Content");
    TTCN_Logger::end_event();
  }

  return ret;

}

/////////////////////////////////////
//// TLS Plaintext EncDec
/////////////////////////////////////

void enc__TLS__TLSPlaintext(const TLS__Types::TLSPlaintext& text, TTCN_Buffer& buf) {
  enc__TLS__ContentType(text.type__(), buf);
  enc__TLS__ProtocolVersion(text.version(), buf);
  buf.put_os(int2oct(text.length__(), 2));
  enc__TLS__Content(text.fragment(), text.type__(), buf);

}

TLSPlaintext dec__TLS__TLSPlaintext(const OCTETSTRING& stream, const TLS__Types::KeyExchangeAlgorithm& kea) {
  TLSPlaintext ret;
  int str_len = stream.lengthof();
  int offset = 0;

  if(str_len < offset + 1) {
   	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  ret.type__() = dec__TLS__ContentType( substr(stream, offset, 1));

	offset += 1;

  if(str_len < offset + 2) {
   	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  ret.version() = dec__TLS__ProtocolVersion( substr(stream, offset, 2));
	offset += 2;

  if(str_len < offset + 2) {
   	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
	ret.length__() = oct2int(substr( stream, offset, 2));
	offset += 2;

	if(str_len < offset) {
	  TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
	ret.fragment() = dec__TLS__Content(substr(stream, offset, str_len - offset), ret.type__(), kea);
  return ret;
}

/////////////////////////////////////
//// TLS Plaintexts EncDec
/////////////////////////////////////

OCTETSTRING enc__TLS__TLSPlaintexts(const TLS__Types::TLSPlaintexts& texts) {
  TTCN_Buffer buf;
  OCTETSTRING ret;
  int size = texts.size_of();
  
  for(int i = 0; i < size; i++) {
    enc__TLS__TLSPlaintext(texts[i], buf);
  }

  buf.get_string(ret);
  
  return ret;
}

INTEGER dec__TLS__TLSPlaintexts(const OCTETSTRING& stream, TLS__Types::TLSPlaintexts& ret, const TLS__Types::KeyExchangeAlgorithm& kea=TLS__Types::KeyExchangeAlgorithm::null__) {
  int str_len = stream.lengthof();
  int offset = 0;
  int len;
  int i = 0;
  do {
    try {
      if(str_len < offset + 5) {
       	TLS_Exception e;
	      e.what = (const char*)"Invalid length";
	      e.file = (const char*)__FILE__;
	      e.line = __LINE__-4;
	      e.func = __func__;
	      throw e;
	    }
      len = oct2int(substr(stream, offset + 3, 2));      

      if(str_len < offset + len + 5) {
       	TLS_Exception e;
	      e.what = (const char*)"Invalid length";
	      e.file = (const char*)__FILE__;
	      e.line = __LINE__-4;
	      e.func = __func__;
	      throw e;
	    }
      ret[i] = dec__TLS__TLSPlaintext(substr(stream, offset, len + 5), kea);
     } catch (TLS_Exception e) {
    	TTCN_Logger::begin_event(TTCN_USER);
    	TTCN_Logger::log_event("***Error has occured: %s. In file: %s in function: %s at line: %d", e.what, e.file, e.func, e.line);
    	TTCN_Logger::end_event();
      return 0;
    }
    
    i++;
    offset += len + 5;
  } while(offset != str_len);
  
  return 1;
}

/////////////////////////////////////
//// TLS Compressed EncDec
/////////////////////////////////////

OCTETSTRING enc__TLS__TLSCompressed(const TLS__Types::TLSCompressed& text) {
  TTCN_Buffer buf;
  OCTETSTRING ret;

  enc__TLS__ContentType(text.type__(), buf);
  enc__TLS__ProtocolVersion(text.version(), buf);
  buf.put_os(int2oct(text.length__(), 2));
  enc__TLS__Content(text.fragment(), text.type__(), buf);

  buf.get_string(ret);

  return ret;
}

INTEGER dec__TLS__TLSCompressed(const OCTETSTRING& stream,  TLS__Types::TLSCompressed& ret, const TLS__Types::KeyExchangeAlgorithm& kea=TLS__Types::KeyExchangeAlgorithm::null__) {
  int stream_len = stream.lengthof();
  int offset = 0;
  
  if(stream_len > 5) {
    try{
      ret.type__() = dec__TLS__ContentType(substr(stream, offset, 1));
      offset += 1;

      ret.version() = dec__TLS__ProtocolVersion(substr(stream, offset, 2));
      offset += 2;

      ret.length__() = oct2int(substr(stream, offset, 2));
      offset += 2;

      if(stream_len - offset == ret.length__()) {
        ret.fragment() = dec__TLS__Content(substr( stream, offset, stream_len - offset), ret.type__(), kea);
        return 1;
      }
    } catch (TLS_Exception e) {
    	TTCN_Logger::begin_event(TTCN_WARNING);
    	TTCN_Logger::log_event("***Error has occured: %s. In file: %s in function: %s at line: %d", e.what, e.file, e.func, e.line);
    	TTCN_Logger::end_event();
      return 0;
    } 
  }
  return 0;
}

/////////////////////////////////////
//// Generic Stream Cipher EncDec
/////////////////////////////////////

void enc__TLS__GenericStreamCipher(const TLS__Types::GenericStreamCipher& gsc, const TLS__Types::TLSCompressed& cmpd, const TLS__Types::SecurityParameters& sp, TTCN_Buffer& buf) {
  buf.put_os(padd_os_to_len(enc__TLS__Content(gsc.content(), cmpd.type__(), buf), cmpd.length__()));
  buf.put_os(padd_os_to_len(gsc.mac(), sp.hash__size()));
}

GenericStreamCipher dec__TLS__GenericStreamCipher(const OCTETSTRING& stream, const TLS__Types::TLSCompressed& cmpd, const TLS__Types::SecurityParameters& sp, const KeyExchangeAlgorithm& kea) throw(TLS_Exception){
  GenericStreamCipher ret;
  int str_len = stream.lengthof();
  
  if(str_len < cmpd.length__()) {
   	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  ret.content() = dec__TLS__Content(substr(stream, 0, cmpd.length__()), cmpd.type__(), kea);
  
  if(str_len < cmpd.length__() + sp.hash__size()) {
   	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  ret.mac() = substr(stream, cmpd.length__(), sp.hash__size());

  return ret;
}

/////////////////////////////////////
//// Generic Block Cipher EncDec
/////////////////////////////////////

void enc__TLS__GenericBlockCipher(const TLS__Types::GenericBlockCipher& gbc, const TLS__Types::TLSCompressed& cmpd, const TLS__Types::SecurityParameters& sp, TTCN_Buffer& buf) {
  buf.put_os(gbc.iv());
  buf.put_os(padd_os_to_len(enc__TLS__Content(gbc.content(), cmpd.type__(), buf), cmpd.length__()));
  buf.put_os(padd_os_to_len(gbc.mac(), sp.hash__size()));
  buf.put_os(int2oct(gbc.padding(), 1));
  buf.put_os(int2oct(gbc.padding__length(), 1));
}

GenericBlockCipher dec__TLS__GenericBlockCipher(const OCTETSTRING& stream, const TLS__Types::TLSCompressed& cmpd, const TLS__Types::SecurityParameters& sp, const KeyExchangeAlgorithm& kea) throw(TLS_Exception){
  GenericBlockCipher ret;
  int str_len = stream.lengthof();

  if(str_len < 2+cmpd.length__()+sp.hash__size()) {
   	TLS_Exception e;
	  e.what = (const char*)"Invalid length";
	  e.file = (const char*)__FILE__;
	  e.line = __LINE__-4;
	  e.func = __func__;
	  throw e;
	}
  ret.padding__length() = oct2int(substr(stream, str_len-1, 1)); 
  ret.padding() = oct2int(substr(stream, str_len-2, 1));
  ret.mac() = substr(stream, str_len-2-sp.hash__size(), sp.hash__size());
  ret.content() = dec__TLS__Content(substr(stream, str_len-2-sp.hash__size()-cmpd.length__(), cmpd.length__()), cmpd.type__(), kea);
  ret.iv() = substr(stream, 0, str_len-2-cmpd.length__()-sp.hash__size());


  return ret;
}

/////////////////////////////////////
//// Cipher Spec Type EncDec
/////////////////////////////////////

OCTETSTRING enc__TLS__CipherSpecType(const TLS__Types::CipherSpecType& cst, const TLS__Types::TLSCompressed& cmpd, const TLS__Types::SecurityParameters& sp, TTCN_Buffer& buf) {
	OCTETSTRING ret;
  switch(cst.get_selection()){
    case CipherSpecType::ALT_stream : enc__TLS__GenericStreamCipher(cst.stream(), cmpd, sp, buf); break;
    case CipherSpecType::ALT_block : enc__TLS__GenericBlockCipher(cst.block(), cmpd, sp, buf); break;
    default :
      TTCN_Logger::begin_event(TTCN_WARNING);
      TTCN_Logger::log_event("Wrong field was selected from CipherSpecType");
      TTCN_Logger::end_event();
  }

  buf.get_string(ret);

  return ret;
}

CipherSpecType dec__TLS__CipherSpecType(const OCTETSTRING& stream, const TLS__Types::TLSCompressed& cmpd, const TLS__Types::SecurityParameters& sp, const TLS__Types::KeyExchangeAlgorithm& kea) {
  CipherSpecType ret;
  if(stream.lengthof() == cmpd.length__() + sp.hash__size())
    ret.stream() = dec__TLS__GenericStreamCipher(stream, cmpd, sp, kea);
  else
    ret.block() = dec__TLS__GenericBlockCipher(stream, cmpd, sp, kea);
    
  return ret; 
}

/////////////////////////////////////
//// TLS Ciphertext EncDec
/////////////////////////////////////

OCTETSTRING enc__TLS__TLSCiphertext(const TLS__Types::TLSCiphertext& text, const TLS__Types::TLSCompressed& cmpd, const TLS__Types::SecurityParameters& sp) {
  TTCN_Buffer buf;
  OCTETSTRING ret;

  enc__TLS__ContentType(text.type__(), buf);
  enc__TLS__ProtocolVersion(text.version(), buf);
  buf.put_os(int2oct(text.length__(), 2));
  buf.put_os(padd_os_to_len(enc__TLS__CipherSpecType(text.fragment(), cmpd, sp, buf), text.length__()));

  buf.get_string(ret);

  return ret;
}

INTEGER dec__TLS__TLSCiphertext(const OCTETSTRING& stream, const TLS__Types::TLSCompressed& cmpd, const TLS__Types::SecurityParameters& sp, const TLS__Types::KeyExchangeAlgorithm& kea, TLS__Types::TLSCiphertext& ret) {
  int stream_len = stream.lengthof();
  
  if(stream_len > 5){
    try {
      ret.type__() = dec__TLS__ContentType(substr(stream, 0, 1));
      ret.version() = dec__TLS__ProtocolVersion(substr(stream, 1, 2));
      ret.length__() = oct2int(substr(stream, 3, 2));
      if(ret.length__() == stream_len - 5){
        ret.fragment() = dec__TLS__CipherSpecType(substr(stream, 5, stream_len - 5), cmpd, sp, kea);
        return 1;
      }
    } catch (TLS_Exception e) {
    	TTCN_Logger::begin_event(TTCN_WARNING);
    	TTCN_Logger::log_event("***Error has occured: %s. In file: %s in function: %s at line: %d", e.what, e.file, e.func, e.line);
    	TTCN_Logger::end_event();
    	return 0;
    }
  }
  
  return 0;
}

}//namespace
