blob: 02ec176c2e290a619093d2405ba070e6abb12535 [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2019 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