R3A --> R4A
diff --git a/TLS_CNL113806.tpd b/TLS_CNL113806.tpd
index a15c3d1..eebcac8 100644
--- a/TLS_CNL113806.tpd
+++ b/TLS_CNL113806.tpd
@@ -1,4 +1,19 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2017 Ericsson
+
+  All rights reserved. This program and the accompanying materials
+  are made available under the terms of the Eclipse Public License v1.0
+  which accompanies this distribution, and is available at
+  http://www.eclipse.org/legal/epl-v10.html
+
+
+   File:               TLS_CNL113806.tpd
+   Description:        tpd project file
+   Rev:                R4A
+   Prodnr:             CNL 113 806
+
+ -->
 <TITAN_Project_File_Information version="1.0">
   <ProjectName>TLS_CNL113806</ProjectName>
   <ReferencedProjects>
@@ -30,4 +45,4 @@
       </ProjectProperties>
     </Configuration>
   </Configurations>
-</TITAN_Project_File_Information>
\ No newline at end of file
+</TITAN_Project_File_Information>
diff --git a/doc/TLS_CNL113806_1551.doc b/doc/TLS_CNL113806_1551.doc
index f6f4dee..5eb446f 100644
--- a/doc/TLS_CNL113806_1551.doc
+++ b/doc/TLS_CNL113806_1551.doc
Binary files differ
diff --git a/doc/TLS_CNL113806_PRI.doc b/doc/TLS_CNL113806_PRI.doc
new file mode 100644
index 0000000..6a54c9c
--- /dev/null
+++ b/doc/TLS_CNL113806_PRI.doc
Binary files differ
diff --git a/src/TLS_CNL113806.grp b/src/TLS_CNL113806.grp
index 0f20762..a5e2811 100644
--- a/src/TLS_CNL113806.grp
+++ b/src/TLS_CNL113806.grp
@@ -1,18 +1,18 @@
 <!--
 ///////////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2000-2016 Ericsson Telecom AB
+// Copyright (c) 2014 Ericsson Telecom AB
 //
 // All rights reserved. This program and the accompanying materials
 // are made available under the terms of the Eclipse Public License v1.0
 // which accompanies this distribution, and is available at
-// http://www.eclipse.org/legal/epl-v10.html
+// http://www.eclipse.org/legal/epl-v10.html/
+//                                                                           
 ///////////////////////////////////////////////////////////////////////////////
-
 //
 //  File:               TLS_CNL113806.grp
 //  Description:        TLS Protocol Module group file
-//  Rev:                R2B
+//  Rev:                R4A
 //  Prodnr:             CNL 113 806
 //  Updated:            2014-06-27
 //  Contact:            http://ttcn.ericsson.se
diff --git a/src/TLS_Constants.ttcn b/src/TLS_Constants.ttcn
index 7f62019..198ee71 100644
--- a/src/TLS_Constants.ttcn
+++ b/src/TLS_Constants.ttcn
@@ -1,16 +1,17 @@
 ///////////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2000-2016 Ericsson Telecom AB
+// Copyright (c) 2014 Ericsson Telecom AB
 //
 // All rights reserved. This program and the accompanying materials
 // are made available under the terms of the Eclipse Public License v1.0
 // which accompanies this distribution, and is available at
 // http://www.eclipse.org/legal/epl-v10.html
+//                                                                           
 ///////////////////////////////////////////////////////////////////////////////
 //
 //  File:               TLS_Constants.ttcn
 //  Description:        TLS Constants
-//  Rev:                R2B
+//  Rev:                R4A
 //  Prodnr:             CNL 113 806
 //  Updated:            2014-06-13
 //  Contact:            http://ttcn.ericsson.se
diff --git a/src/TLS_EncDec.cc b/src/TLS_EncDec.cc
index 309ea81..f03556e 100644
--- a/src/TLS_EncDec.cc
+++ b/src/TLS_EncDec.cc
@@ -1,16 +1,17 @@
 ///////////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2000-2016 Ericsson Telecom AB
+// Copyright (c) 2014 Ericsson Telecom AB
 //
 // All rights reserved. This program and the accompanying materials
 // are made available under the terms of the Eclipse Public License v1.0
 // which accompanies this distribution, and is available at
 // http://www.eclipse.org/legal/epl-v10.html
+//                                                                           
 ///////////////////////////////////////////////////////////////////////////////
 //
 //  File:           TLS_EncDec.cc
 //  Description:    Encode/decode functions for TLS messages
-//  Rev:            R2B
+//  Rev:            R4A
 //  Prodnr:         CNL 113 806
 //  Updated:        2014-06-20
 //  Contact:        http://ttcn.ericsson.se
@@ -21,6 +22,7 @@
 #include <stdio.h>
 #include <iostream>
 #include <exception>
+#include <stdint.h>
 
 namespace TLS__Types{
 
@@ -31,6 +33,50 @@
 	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;
@@ -43,6 +89,112 @@
   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
 /////////////////////////////////////
@@ -57,7 +209,7 @@
 
   ret.major__() = oct2int(substr(stream, 0, 1));
   ret.minor__() = oct2int(substr(stream, 1, 1));
-
+  
   return ret;
 }
 
@@ -78,7 +230,7 @@
 	  e.func = __func__;
     throw e;
   }
-
+  
   return (ContentType) oct2int(stream);
 }
 
@@ -236,8 +388,8 @@
    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; 
+ }   
 
   return 1;
 }
@@ -258,8 +410,8 @@
 		e.line = __LINE__-4;
 		e.func = __func__;
 	  throw e;
-	}
-	return (ChangeCipherSpecEnum) oct2int(stream);;
+	}  
+	return (ChangeCipherSpecEnum) oct2int(stream);;	
 }
 
 /////////////////////////////////////
@@ -273,8 +425,8 @@
 ChangeCipherSpec dec__TLS__ChangeCipherSpec(const OCTETSTRING& stream){
   ChangeCipherSpec ret;
   ret.type__() = dec__TLS__ChangeCipherSpecEnum(stream);
-
-	return ret;
+  
+	return ret;	
 }
 
 /////////////////////////////////////
@@ -293,8 +445,8 @@
 		e.line = __LINE__-4;
 		e.func = __func__;
 	  throw e;
-	}
-	return (AlertLevel) oct2int(stream);
+	}    
+	return (AlertLevel) oct2int(stream);	
 }
 
 /////////////////////////////////////
@@ -313,8 +465,8 @@
 		e.line = __LINE__-4;
 		e.func = __func__;
 	  throw e;
-	}
-
+	} 
+  
 	return (AlertDescription) oct2int(stream);
 }
 
@@ -329,11 +481,11 @@
 
 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;
+  
+	return ret;	
 }
 
 /////////////////////////////////////
@@ -362,7 +514,7 @@
 
 HelloRequest dec__TLS__HelloRequest(const OCTETSTRING& stream) {
   HelloRequest ret = HelloRequest(NULL_VALUE);
-
+ 
   return ret;
 }
 
@@ -378,11 +530,11 @@
 
 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;
+  
+	return ret;	
 }
 
 /////////////////////////////////////
@@ -396,7 +548,7 @@
 
 SessionID dec__TLS__SessionID(const OCTETSTRING& stream) {
   SessionID ret = (SessionID) stream;
-
+  	
 	return ret;
 }
 
@@ -410,8 +562,8 @@
 }
 
 CipherSuite dec__TLS__CipherSuite(const OCTETSTRING& stream) throw(TLS_Exception){
-	CipherSuite ret;
-
+	CipherSuite ret;	
+	
 	if(stream.lengthof() < 2) {
   	TLS_Exception e;
 	  e.what = (const char*)"Invalid length";
@@ -420,10 +572,10 @@
 		e.func = __func__;
 	  throw e;
 	}
-
+	
 	ret.field1() =  substr(stream, 0, 1);
 	ret.field2() =  substr(stream, 1, 1);
-
+	
 	return ret;
 }
 
@@ -433,7 +585,7 @@
 
 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);
@@ -454,7 +606,7 @@
   for(int i = 0; i < size; i++){
 	  ret[i] = dec__TLS__CipherSuite(substr(stream, (i*2), 2));
 	}
-
+	
 	return ret;
 }
 
@@ -464,7 +616,7 @@
 
 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);
@@ -473,7 +625,7 @@
 
 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";
@@ -482,11 +634,11 @@
 		e.func = __func__;
 	  throw e;
 	}
-
+	
   for(int i = 0; i < len; i++){
 	  ret[i] = dec__TLS__CompressionMethod(substr(stream, i, 1));
 	}
-
+	
 	return ret;
 }
 
@@ -501,10 +653,10 @@
     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__()());
 	}
@@ -548,7 +700,7 @@
 	}
   len = oct2int(substr(stream, offset, 1));
   offset += 1;
-
+  
   if(len != 0) {
     if(str_len < offset + len) {
     	TLS_Exception e;
@@ -562,7 +714,7 @@
     offset += len;
   } else {
     ret.session__id() = OMIT_VALUE;
-  }
+  }  
 
   if(str_len < offset + 2) {
   	TLS_Exception e;
@@ -596,7 +748,7 @@
 	}
   len = oct2int(substr(stream,offset, 1));
   offset += 1;
-
+  
   if(str_len < offset + len) {
   	TLS_Exception e;
 	  e.what = (const char*)"Invalid length";
@@ -607,7 +759,7 @@
 	}
   ret.compression__methods() = dec__TLS__CompressionMethodList(substr(stream, offset, len), len);
   offset += len;
-
+  
   if(str_len == offset){
 	  ret.extension__() = OMIT_VALUE;
 	} else {
@@ -669,10 +821,10 @@
 	  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;
@@ -686,7 +838,7 @@
     offset += len;
   } else {
     ret.session__id() = OMIT_VALUE;
-  }
+  }  
 
   if(str_len < offset + 2) {
   	TLS_Exception e;
@@ -695,7 +847,7 @@
 	  e.line = __LINE__-4;
 	  e.func = __func__;
 	  throw e;
-	}
+	}  
   ret.cipher__suite() = dec__TLS__CipherSuite(substr(stream, offset, 2));
   offset += 2;
 
@@ -718,7 +870,7 @@
 
 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]);
@@ -753,7 +905,7 @@
     offset += len;
     i++;
  } while(offset + 3 <= stream_len);
-
+	
 	return ret;
 }
 
@@ -764,11 +916,11 @@
 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);
 }
@@ -777,7 +929,7 @@
 	Certificate ret;
   int len;
   int str_len = stream.lengthof();
-
+  
   if(str_len < 3) {
   	TLS_Exception e;
 	  e.what = (const char*)"Invalid length";
@@ -787,7 +939,7 @@
 	  throw e;
 	}
   len = oct2int(substr(stream, 0, 3));
-
+  
   if(str_len < len + 3) {
   	TLS_Exception e;
 	  e.what = (const char*)"Invalid length";
@@ -797,7 +949,7 @@
 	  throw e;
 	}
   ret.certificate__list() = dec__TLS__CertificateList(substr(stream, 3, len), len);
-
+	
 	return ret;
 }
 
@@ -817,10 +969,10 @@
 		e.line = __LINE__-4;
 		e.func = __func__;
 	  throw e;
-	}
-  KeyExchangeAlgorithm ret = (KeyExchangeAlgorithm) oct2int(stream);
-
-	return ret;
+	} 
+  KeyExchangeAlgorithm ret = (KeyExchangeAlgorithm) oct2int(stream);  
+  
+	return ret;	
 }
 
 /////////////////////////////////////
@@ -835,11 +987,11 @@
 }
 
 ServerRSAParams dec__TLS__ServerRSAParams(const OCTETSTRING& stream) throw(TLS_Exception){
-  ServerRSAParams ret;
+  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";
@@ -850,7 +1002,7 @@
 	}
   len = oct2int(substr(stream, offset, 2));
   offset += 2;
-
+  
   if(str_len < offset + len) {
   	TLS_Exception e;
 	  e.what = (const char*)"Invalid length";
@@ -869,7 +1021,7 @@
 	  e.line = __LINE__-4;
 	  e.func = __func__;
 	  throw e;
-	}
+	}  
   len = oct2int(substr(stream, offset, 2));
   offset += 2;
 
@@ -880,10 +1032,10 @@
 	  e.line = __LINE__-4;
 	  e.func = __func__;
 	  throw e;
-	}
+	}  
   ret.rsa__exponent() = substr(stream, offset, len);
-
-	return ret;
+  
+	return ret;	
 }
 
 /////////////////////////////////////
@@ -900,7 +1052,7 @@
 }
 
 ServerDHParams dec__TLS__ServerDHParams(const OCTETSTRING& stream) throw(TLS_Exception){
-  ServerDHParams ret;
+  ServerDHParams ret;  
   int offset = 0;
   int len;
   int str_len = stream.lengthof();
@@ -912,7 +1064,7 @@
 	  e.line = __LINE__-4;
 	  e.func = __func__;
 	  throw e;
-	}
+	}  
   len = oct2int(substr(stream, offset, 2));
   offset += 2;
 
@@ -923,7 +1075,7 @@
 	  e.line = __LINE__-4;
 	  e.func = __func__;
 	  throw e;
-	}
+	}  
   ret.dh__p() = substr(stream, offset, len);
   offset += len;
 
@@ -934,7 +1086,7 @@
 	  e.line = __LINE__-4;
 	  e.func = __func__;
 	  throw e;
-	}
+	}  
   len = oct2int(substr(stream, offset, 2));
   offset += 2;
 
@@ -945,7 +1097,7 @@
 	  e.line = __LINE__-4;
 	  e.func = __func__;
 	  throw e;
-	}
+	}  
   ret.dh__g() = substr(stream, offset, len);
   offset += len;
 
@@ -956,7 +1108,7 @@
 	  e.line = __LINE__-4;
 	  e.func = __func__;
 	  throw e;
-	}
+	}  
   len = oct2int(substr(stream, offset, 2));
   offset += 2;
 
@@ -967,10 +1119,10 @@
 	  e.line = __LINE__-4;
 	  e.func = __func__;
 	  throw e;
-	}
+	}  
   ret.dh__Ys() = substr(stream, offset, len);
-
-	return ret;
+  
+	return ret;	
 }
 
 /////////////////////////////////////
@@ -994,7 +1146,7 @@
 	  e.func = __func__;
 	  throw e;
 	}
-
+	
   ret.md5__hash() = substr(stream, 0, 16);
   ret.sha__hash() = substr(stream, 16, 20);
 
@@ -1049,7 +1201,7 @@
     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 : ;
+    default : buf.put_os(sign.sign()); break;
   }
 }
 
@@ -1059,7 +1211,7 @@
     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 : ;
+    default : ret.sign() = stream; break;
   }
 
 	return ret;
@@ -1085,7 +1237,7 @@
   ServerParams ret;
   int len;
   int str_len = stream.lengthof();
-
+  
   if(str_len < 2) {
   	TLS_Exception e;
 	  e.what = (const char*)"Invalid length";
@@ -1116,16 +1268,16 @@
 }
 
 ServerKeyExchange dec__TLS__ServerKeyExchange(const OCTETSTRING& stream, const TLS__Types::KeyExchangeAlgorithm& kea) throw(TLS_Exception){
-  ServerKeyExchange ret;
+  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 :
+    case KeyExchangeAlgorithm::diffie__hellman : 
       if(str_len < offset + 2) {
       	TLS_Exception e;
 	      e.what = (const char*)"Invalid length";
@@ -1136,7 +1288,7 @@
 	    }
       len = oct2int(substr(stream, offset, 2));
       offset += 2;
-
+      
       if(str_len < offset + len) {
       	TLS_Exception e;
 	      e.what = (const char*)"Invalid length";
@@ -1147,7 +1299,7 @@
 	    }
       p1 = substr(stream, offset, len);
       offset += len;
-
+  
       if(str_len < offset + 2) {
       	TLS_Exception e;
 	      e.what = (const char*)"Invalid length";
@@ -1158,7 +1310,7 @@
 	    }
       len = oct2int(substr(stream, offset, 2));
       offset += 2;
-
+      
       if(str_len < offset + len) {
       	TLS_Exception e;
 	      e.what = (const char*)"Invalid length";
@@ -1169,7 +1321,7 @@
 	    }
       p2 = substr(stream, offset, len);
       offset += len;
-
+      
       if(str_len < offset + 2) {
       	TLS_Exception e;
 	      e.what = (const char*)"Invalid length";
@@ -1180,7 +1332,7 @@
 	    }
       len = oct2int(substr(stream, offset, 2));
       offset += 2;
-
+      
       if(str_len < offset + len) {
       	TLS_Exception e;
 	      e.what = (const char*)"Invalid length";
@@ -1191,13 +1343,13 @@
 	    }
       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;
@@ -1209,7 +1361,7 @@
 	    }
       len = oct2int(substr(stream, offset, 2));
       offset += 2;
-
+      
       if(str_len < offset + len) {
       	TLS_Exception e;
 	      e.what = (const char*)"Invalid length";
@@ -1220,7 +1372,7 @@
 	    }
       p1 = substr(stream, offset, len);
       offset += len;
-
+  
       if(str_len < offset + 2) {
       	TLS_Exception e;
 	      e.what = (const char*)"Invalid length";
@@ -1231,7 +1383,7 @@
 	    }
       len = oct2int(substr(stream, offset, 2));
       offset += 2;
-
+      
       if(str_len < offset + len) {
       	TLS_Exception e;
 	      e.what = (const char*)"Invalid length";
@@ -1242,17 +1394,17 @@
 	    }
       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;
+	return ret;	
 }
 
 /////////////////////////////////////
@@ -1272,9 +1424,9 @@
 	  e.func = __func__;
 	  throw e;
 	}
-  SignatureAlgorithm ret = (SignatureAlgorithm) oct2int(stream);
-
-	return ret;
+  SignatureAlgorithm ret = (SignatureAlgorithm) oct2int(stream);  
+  
+	return ret;	
 }
 
 /////////////////////////////////////
@@ -1287,17 +1439,16 @@
 
 ClientCertificateType dec__TLS__ClientCertificateType(const OCTETSTRING& stream) throw(TLS_Exception){
   if(!ClientCertificateType::is_valid_enum(oct2int(stream))) {
-    return ClientCertificateType::UNKNOWN_VALUE;
-//   	TLS_Exception e;
-// 	  e.what = (const char*)"Invalid ClientCertificateType";
-// 	  e.file = (const char*)__FILE__;
-// 	  e.line = __LINE__-4;
-// 	  e.func = __func__;
-// 	  throw e;
+  	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;
+  
+	return ret;	
 }
 
 /////////////////////////////////////
@@ -1306,7 +1457,7 @@
 
 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);
@@ -1314,7 +1465,7 @@
 }
 
 ClientCertificateTypeList dec__TLS__ClientCertificateTypeList(const OCTETSTRING& stream, const INTEGER& size) throw(TLS_Exception){
-  ClientCertificateTypeList ret;
+  ClientCertificateTypeList ret;  
   if(stream.lengthof() < size) {
   	TLS_Exception e;
 	  e.what = (const char*)"Invalid ClientCertificateTypeList";
@@ -1326,8 +1477,8 @@
   for(int i = 0; i < size; i++){
     ret[i] = dec__TLS__ClientCertificateType(substr(stream, i, 1));
   }
-
-	return ret;
+  
+	return ret;	
 }
 
 /////////////////////////////////////
@@ -1342,7 +1493,7 @@
 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";
@@ -1362,11 +1513,9 @@
 	    throw e;
 	  }
 	  ret = substr(stream, 2, len);
-  } else {
-    ret = OCTETSTRING(0,NULL);
   }
-
-	return ret;
+  
+	return ret;	
 }
 
 /////////////////////////////////////
@@ -1384,10 +1533,10 @@
 }
 
 CertificateRequest dec__TLS__CertificateRequest(const OCTETSTRING& stream) throw(TLS_Exception){
-  CertificateRequest ret;
+  CertificateRequest ret;  
   int offset = 0;
   int str_len = stream.lengthof();
-
+  
   if(str_len < offset + 1) {
    	TLS_Exception e;
 	  e.what = (const char*)"Invalid length";
@@ -1417,7 +1566,7 @@
 	  e.line = __LINE__-4;
 	  e.func = __func__;
 	  throw e;
-	}
+	}  
   len = oct2int(substr(stream, offset, 2));
   offset += 2;
 
@@ -1429,17 +1578,13 @@
 	  e.func = __func__;
 	  throw e;
 	}
-  if (len == 0) {
-    ret.certificate__authorities() = OMIT_VALUE;
-  } else {
-    ret.certificate__authorities() = dec__TLS__DistinguishedName(substr(stream, offset, len));
-  }
+  ret.certificate__authorities() = dec__TLS__DistinguishedName(substr(stream, offset, len));
 
   if(!ret.certificate__authorities().is_bound()){
 	  ret.certificate__authorities() = OMIT_VALUE;
   }
-
-	return ret;
+    
+	return ret;	
 }
 
 /////////////////////////////////////
@@ -1459,16 +1604,14 @@
 /////////////////////////////////////
 
 void enc__TLS__CertificateVerify(const TLS__Types::CertificateVerify& cv, TTCN_Buffer& buf) {
-  /*enc__TLS__Signature(cv.signature__(), buf);*/
-	buf.put_os(cv.signature__());
+  enc__TLS__Signature(cv.signature__(), buf);
 }
 
 CertificateVerify dec__TLS__CertificateVerify(const OCTETSTRING& stream) {
 	CertificateVerify ret;
-
-  //ret.signature__() = dec__TLS__Signature(stream);
-  ret.signature__() = stream;
-
+  
+  ret.signature__() = dec__TLS__Signature(stream);
+  
   return ret;
 }
 
@@ -1490,8 +1633,8 @@
 	  throw e;
 	}
 	PublicValueEncoding ret = (PublicValueEncoding) oct2int(stream);
-
-	return ret;
+  
+	return ret;	
 }
 
 /////////////////////////////////////
@@ -1500,11 +1643,11 @@
 
 void enc__TLS__PreMasterSecret(const TLS__Types::PreMasterSecret& ps, TTCN_Buffer& buf) {
   enc__TLS__ProtocolVersion(ps.client__version(), buf);
-  buf.put_os(ps.random());
+  buf.put_os(ps.random());  
 }
 
 PreMasterSecret dec__TLS__PreMasterSecret(const OCTETSTRING& stream) throw(TLS_Exception){
-  PreMasterSecret ret;
+  PreMasterSecret ret;  
   int str_len = stream.lengthof();
 
   if(str_len < 2) {
@@ -1514,7 +1657,7 @@
 	  e.line = __LINE__-4;
 	  e.func = __func__;
 	  throw e;
-	}
+	}  
   ret.client__version() = dec__TLS__ProtocolVersion(substr(stream, 0, 2));
 
   if(str_len < 48) {
@@ -1524,10 +1667,10 @@
 	  e.line = __LINE__-4;
 	  e.func = __func__;
 	  throw e;
-	}
+	} 
   ret.random() = substr(stream, 2, 46);
-
-	return ret;
+    
+	return ret;	
 }
 
 /////////////////////////////////////
@@ -1540,9 +1683,9 @@
 
 EncryptedPreMasterSecret dec__TLS__EncryptedPreMasterSecret(const OCTETSTRING& stream) {
   EncryptedPreMasterSecret ret;
-
+  
   ret.pre__master__secret() = dec__TLS__PreMasterSecret(stream);
-
+  
   return ret;
 }
 
@@ -1571,7 +1714,7 @@
   ClientDiffieHellmanPublicExplicit ret;
   int len;
   int str_len = stream.lengthof();
-
+  
   if(str_len < 2) {
    	TLS_Exception e;
 	  e.what = (const char*)"Invalid length";
@@ -1581,7 +1724,7 @@
 	  throw e;
 	}
   len = oct2int(substr(stream, 0, 2));
-
+  
   if(str_len < len + 2) {
    	TLS_Exception e;
 	  e.what = (const char*)"Invalid length";
@@ -1591,7 +1734,7 @@
 	  throw e;
 	}
   ret.DH__Yc() = substr(stream, 2, len);
-
+    
   return ret;
 }
 
@@ -1612,7 +1755,7 @@
 
 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;
@@ -1621,7 +1764,7 @@
       TTCN_Logger::log_event("Wrong field was selected from ClientDiffieHellmanPublicValues");
       TTCN_Logger::end_event();
     }
-
+    
   return ret;
 }
 
@@ -1631,12 +1774,12 @@
 
 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);
 }
@@ -1644,15 +1787,15 @@
 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;
 }
 
@@ -1673,7 +1816,7 @@
 
 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;
@@ -1682,7 +1825,7 @@
     TTCN_Logger::log_event("Wrong field was selected from ClientKeyExchangeKeys");
     TTCN_Logger::end_event();
   };
-
+    
   return ret;
 }
 
@@ -1691,32 +1834,29 @@
 /////////////////////////////////////
 
 void enc__TLS__ClientKeyExchange(const TLS__Types::ClientKeyExchange& cke, TTCN_Buffer& buf) {
-  /*KeyExchangeAlgorithm kea;
-
+  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);*/
-	buf.put_os(cke.exchange__keys());
+  
+  enc__TLS__ClientKeyExchangeKeys(cke.exchange__keys(), kea, buf);
 }
 
 ClientKeyExchange dec__TLS__ClientKeyExchange(const OCTETSTRING& stream) {
   ClientKeyExchange ret;
-  /*KeyExchangeAlgorithm kea;
-
+  KeyExchangeAlgorithm kea;
+  
   if(stream.lengthof() == 48) {
     kea = KeyExchangeAlgorithm::rsa;
   } else {
     kea = KeyExchangeAlgorithm::diffie__hellman;
   }
-
-  ret.exchange__keys() = dec__TLS__ClientKeyExchangeKeys(stream, kea);*/
-
-	ret.exchange__keys() = stream;
-
+  
+  ret.exchange__keys() = dec__TLS__ClientKeyExchangeKeys(stream, kea);
+    
   return ret;
 }
 
@@ -1730,9 +1870,9 @@
 
 Finished dec__TLS__Finished(const OCTETSTRING& stream) {
   Finished ret;
-
+  
   ret.verify__data() = stream;
-
+    
   return ret;
 }
 
@@ -1786,15 +1926,14 @@
 /////////////////////////////////////
 
 void enc__TLS__Handshake(const TLS__Types::Handshake& hs, TTCN_Buffer& buf) {
-	TTCN_Buffer temp_buf;
-  if(hs.msg__type().ispresent()) {
+  if(hs.msg__type().ispresent())
 	  enc__TLS__HandshakeType(hs.msg__type(), buf);
-	  enc__TLS__HandshakeBody(hs.body(), hs.msg__type(), temp_buf);
-	  buf.put_os(int2oct(temp_buf.get_len(), 3));
-	  buf.put_buf(temp_buf);
-  } else {
+  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());
-  }
 }
 
 /////////////////////////////////////
@@ -1880,7 +2019,7 @@
 
 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;
@@ -1901,12 +2040,11 @@
 /////////////////////////////////////
 
 void enc__TLS__TLSPlaintext(const TLS__Types::TLSPlaintext& text, TTCN_Buffer& buf) {
-	TTCN_Buffer temp_buf;
   enc__TLS__ContentType(text.type__(), buf);
   enc__TLS__ProtocolVersion(text.version(), buf);
-  enc__TLS__Content(text.fragment(), text.type__(), temp_buf);
-  buf.put_os(int2oct(temp_buf.get_len(), 2));
-  buf.put_buf(temp_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) {
@@ -1968,13 +2106,13 @@
   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;
 }
 
@@ -1993,7 +2131,7 @@
 	      e.func = __func__;
 	      throw e;
 	    }
-      len = oct2int(substr(stream, offset + 3, 2));
+      len = oct2int(substr(stream, offset + 3, 2));      
 
       if(str_len < offset + len + 5) {
        	TLS_Exception e;
@@ -2010,11 +2148,11 @@
     	TTCN_Logger::end_event();
       return 0;
     }
-
+    
     i++;
     offset += len + 5;
   } while(offset != str_len);
-
+  
   return 1;
 }
 
@@ -2024,14 +2162,12 @@
 
 OCTETSTRING enc__TLS__TLSCompressed(const TLS__Types::TLSCompressed& text) {
   TTCN_Buffer buf;
-  TTCN_Buffer temp_buf;
   OCTETSTRING ret;
 
   enc__TLS__ContentType(text.type__(), buf);
   enc__TLS__ProtocolVersion(text.version(), buf);
-  enc__TLS__Content(text.fragment(), text.type__(), temp_buf);
-  buf.put_os(int2oct(temp_buf.get_len(), 2));
-  buf.put_buf(temp_buf);
+  buf.put_os(int2oct(text.length__(), 2));
+  enc__TLS__Content(text.fragment(), text.type__(), buf);
 
   buf.get_string(ret);
 
@@ -2041,7 +2177,7 @@
 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));
@@ -2062,7 +2198,7 @@
     	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;
 }
@@ -2079,7 +2215,7 @@
 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";
@@ -2089,7 +2225,7 @@
 	  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";
@@ -2127,7 +2263,7 @@
 	  e.func = __func__;
 	  throw e;
 	}
-  ret.padding__length() = oct2int(substr(stream, str_len-1, 1));
+  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);
@@ -2163,8 +2299,8 @@
     ret.stream() = dec__TLS__GenericStreamCipher(stream, cmpd, sp, kea);
   else
     ret.block() = dec__TLS__GenericBlockCipher(stream, cmpd, sp, kea);
-
-  return ret;
+    
+  return ret; 
 }
 
 /////////////////////////////////////
@@ -2173,14 +2309,12 @@
 
 OCTETSTRING enc__TLS__TLSCiphertext(const TLS__Types::TLSCiphertext& text, const TLS__Types::TLSCompressed& cmpd, const TLS__Types::SecurityParameters& sp) {
   TTCN_Buffer buf;
-  TTCN_Buffer temp_buf;
   OCTETSTRING ret;
 
   enc__TLS__ContentType(text.type__(), buf);
   enc__TLS__ProtocolVersion(text.version(), buf);
-  enc__TLS__CipherSpecType(text.fragment(), cmpd, sp, temp_buf);
-  buf.put_os(int2oct(temp_buf.get_len(), 2));
-  buf.put_buf(temp_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);
 
@@ -2189,7 +2323,7 @@
 
 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));
@@ -2206,7 +2340,7 @@
     	return 0;
     }
   }
-
+  
   return 0;
 }
 
diff --git a/src/TLS_Types.ttcn b/src/TLS_Types.ttcn
index d85c15b..f7f20ac 100644
--- a/src/TLS_Types.ttcn
+++ b/src/TLS_Types.ttcn
@@ -1,16 +1,17 @@
 ///////////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2000-2016 Ericsson Telecom AB
+// Copyright (c) 2014 Ericsson Telecom AB
 //
 // All rights reserved. This program and the accompanying materials
 // are made available under the terms of the Eclipse Public License v1.0
 // which accompanies this distribution, and is available at
 // http://www.eclipse.org/legal/epl-v10.html
+//                                                                           
 ///////////////////////////////////////////////////////////////////////////////
 //
 //  File:               TLS_Types.ttcn
 //  Description:        TLS Types
-//  Rev:                R2B
+//  Rev:                R4A
 //  Prodnr:             CNL 113 806
 //  Updated:            2014-06-13
 //  Contact:            http://ttcn.ericsson.se
@@ -32,7 +33,10 @@
     
     external function enc_TLS_TLSCiphertext( in TLSCiphertext pl_text, in TLSCompressed pl_cmpd, in SecurityParameters pl_sp) return octetstring;    
     external function dec_TLS_TLSCiphertext( in octetstring pl_stream, in TLSCompressed pl_cmpd, in SecurityParameters pl_sp, in KeyExchangeAlgorithm pl_kea, out TLSCiphertext pl_decoded) return integer;
-    
+
+    external function enc_TLS_Extensions( in TLS_Extensions pl_ext ) return octetstring;
+    external function dec_TLS_Extensions( in octetstring pl_stream, out TLS_Extensions pl_ext ) return integer;
+
     import from General_Types all;   
     
     type octetstring OCT1_16 length(1..16);
@@ -256,12 +260,40 @@
       Random                random,
       SessionID             session_id      optional,
       CipherSuite           cipher_suite,
-      CompressionMethod     compression_method
+      CompressionMethod     compression_method,
+      octetstring                extension_  optional
     }
     
     /*---------------------------------------------------------------------*/
     /*-----------End of the type definitions of Hello messages-------------*/
     /*---------------------------------------------------------------------*/
+
+
+    /*---------------------------------------------------------------------*/
+    /*---------Begining of the type definitions of Extensions    ----------*/
+    /*---------------------------------------------------------------------*/
+
+    type union ServerName {   //RFC6066
+      charstring   hostname
+    }
+    
+    type record of ServerName ServerNameList;
+    
+    type record of octetstring ProtocolNameList; //RFC7301
+    
+    type union TLS_Extension {
+      ProtocolNameList    protocol_name_list,
+      ServerNameList      server_name_list,
+      octetstring         future_extensions
+    }
+    
+    type record of TLS_Extension TLS_Extensions
+
+    /*---------------------------------------------------------------------*/
+    /*-----------End of the type definitions of Extensions    -------------*/
+    /*---------------------------------------------------------------------*/
+
+
     
     /*---------------------------------------------------------------------*/
     /*-------Begining of the type definitions of SA and Key Exchange-------*/
@@ -324,7 +356,8 @@
     type union Signature {
       AnonymSignature       anonym,
       RSASignature          rsa,
-      DSASignature          dsa
+      DSASignature          dsa,
+      octetstring           sign
     }
     
     type enumerated ClientCertificateType{
@@ -334,8 +367,7 @@
       dss_fixed_dh                  (4),
       rsa_ephemeral_dh_RESERVED     (5),
       dss_ephemeral_dh_RESERVED     (6),
-      fortezza_dms_RESERVED         (20),
-      ecdsa_sign                    (64)
+      fortezza_dms_RESERVED         (20)
     }
     
     type OCT1_16 DistinguishedName;
@@ -362,7 +394,7 @@
     }
     
     type record ClientKeyExchange {
-      octetstring     exchange_keys
+      ClientKeyExchangeKeys     exchange_keys
     }
     
     type enumerated PublicValueEncoding {
@@ -395,7 +427,7 @@
     }
     
     type record CertificateVerify {
-      octetstring         signature_
+      Signature         signature_
     }
     
     /*---------------------------------------------------------------------*/