networksecurity/tls/protocol/tlshandshakeitem.h
changeset 0 af10295192d8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/networksecurity/tls/protocol/tlshandshakeitem.h	Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,958 @@
+/**
+* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* SSL3.0 and TLS1.0 Handshake message items header file.
+* This file contains definitions for SSL3.0 and TLS1.0 handshake items 
+* (i.e., handshake protocol types, headers, message structures, etc).
+* 
+*
+*/
+
+
+
+/**
+ @file TlsHandshakeItem.h
+*/
+
+#include "tlsrecorditem.h"
+
+#ifndef _TLSHANDSHAKEITEM_H_
+#define _TLSHANDSHAKEITEM_H_
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <tlstypedef_internal.h>
+#endif
+
+
+// Handshake protocol types, as defined in RFC2246, section A.4
+enum ETlsHandshakeMessage 
+{
+	ETlsHelloRequestMsg = 0,						/** Hello Request message */
+	ETlsClientHelloMsg = 1,							/** Client Hello message */
+	ETlsServerHelloMsg = 2,							/** Server Hello message */
+	ETlsCertificateMsg = 11,						/** Certificate message */
+	ETlsServerCertificateMsg = ETlsCertificateMsg,	/** Certificate message (server)	*/
+	ETlsServerKeyExchMsg = 12,						/** Server Key exchange message */
+	ETlsCertificateReqMsg = 13,						/** Certificate Request message */
+	ETlsServerHelloDoneMsg = 14,					/** Server Hello Done message */
+	ETlsClientCertificateMsg = ETlsCertificateMsg,	/** Certificate message (client) */
+	ETlsCertificateVerifyMsg = 15,					/** Certificate verify message */
+	ETlsClientKeyExchMsg = 16,						/** Client Key exchange message */
+	ETlsFinishedMsg = 20,							/** Finished message */
+	ETlsMsgNotDefined = 200							/** Undefined/unknown message */
+};
+
+// Constants for a Handshake header object
+const TInt KTlsHandshakeHeaderSize = 4;		///< Size of Handshake protocol header, 4 bytes
+const TInt KTlsHandshakeTypeOffset = 0;		///< Offset of Handshake type within the header
+const TInt KTlsHandshakeLengthOffset = 1;	///< Offset of Handshake length within the header
+const TInt KTlsHandshakeBodyLength = 3; 	///< Size of Handshake body length, 3 bytes
+const TInt KTlsMaxHandshakeBodySize = 0x80000; 	///< Max Size of Handshake body
+
+// Constants for Hello message (Client and Server) items
+const TInt KTlsProtocolBodyLength = 2;		///< Number of bytes for the Protocol version's body item
+const TInt KTlsSessionIdLength = 1;			///< Number of bytes for the Session Id's length item
+const TInt KTlsCipherSuiteLength = 2;		///< Number of bytes for the CipherSuite's length item
+const TInt KTlsCompressionLength = 1;		///< Number of bytes for the Compression's length item
+const TInt KTlsCompressionBodyLength = 1;	///< Number of bytes for the Compression's body item, 
+											///< currently 1 as only NULL compression is supported
+const TInt KTlsCipherSuiteBodyLength = 2;	///< Number of bytes for the selected cipher suite body item
+
+// Other message constants
+const TInt KTlsCertChainLength = 3;			///< Number of bytes for the Certificate chain length
+const TInt KTlsVerifyDataLength = 12;		///< Number of bytes for the VerifyData item (Finished message)
+const TInt KTlsSigLength = 2;				///< Number of bytes for a signature length
+const TInt KTlsMd5Length = 16;				///< Number of bytes for MD5 hash
+const TInt KTlsShaLength = 20;				///< Number of bytes for SHA hash
+const TInt KTlsRsaModLength = 2;			///< Number of bytes for the RSA modulus's length item
+const TInt KTlsRsaKeyExchLength = 2;			///< RSA key exchange length
+const TInt KTlsRsaModBodyLength = 2;		///< Initial number of bytes for the RSA modulus's body item (initially == to  KTlsRsaModLength)
+const TInt KTlsRsaExpLength = 2;			///< Number of bytes for the RSA exponent's length item
+const TInt KTlsRsaExpBodyLength = 2;		///< Initial number of bytes for the RSA exponent's body item (initially == to  KTlsRsaExpLength)
+const TInt KTlsDhpLength = 2;				///< Number of bytes for the DH prime modulus' length item
+const TInt KTlsDhpBodyLength = 2;			///< Number of bytes for the DH prime modulus' body item
+const TInt KTlsDhgLength = 2;				///< Number of bytes for the DH generator length item
+const TInt KTlsDhgBodyLength = 2;			///< Number of bytes for the DH generator body item
+const TInt KTlsDhYsLength = 2;				///< Number of bytes for the DH public value length item
+const TInt KTlsDhYsBodyLength = 2;			///< Number of bytes for the DH public value body item
+const TInt KTlsCertTypesLength = 1;			///< Number of bytes for the Certificate types length item
+const TInt KTlsCertTypesBodyLength = 1;		///< Number of bytes for the Certificate types body item
+const TInt KTlsCALength = 2;				///< Number of bytes for the Certificate Authorities length item
+const TInt KTlsDhYcLength = 2;				///< Number of bytes for the DHE Yc length item
+const TInt KTlsDhYcBodyLength = 2;			///< Number of bytes for the DHE Yc item (length item + DH Yc value), default is KTlsDhYcLength.
+const TInt KTlsPskLength = 2;				///< Number of bytes for the PSK other_secret and psk length fields
+const TInt KTlsExtensionLength = 2;			///< Number of bytes for the Extension length fields
+const TInt KTlsExtensionTypeLength = 2;			///< Number of bytes for the Extension type field
+const TInt KTlsExtensionNameTypeLength = 1;	///< Number of bytes for the Extension name type length fields
+
+class CHandshakeHeader : public CItem< TConstant >
+/** 
+ * Represents a Handshake message header
+ */ 
+{
+public:
+   CHandshakeHeader( CItemBase* aNext ) :
+      CItem< TConstant >( aNext, KTlsHandshakeHeaderSize),
+      iRecord( NULL )
+   {
+      iRecord.iFirst = this;
+   }
+
+   void ComposeHeader( ETlsHandshakeMessage aHandshakeMessage, TInt aLength );
+	
+public:
+   TRecord iRecord;
+};
+
+// Class initialisation for these message items strongly relies on the fact that 
+// non-virtual base clases are initialised in the order in which they appear in 
+// the class declaration. Also, member objects are initialised in the order in 
+// which they are declared in the class.
+
+
+class CClientHelloMsg : public CHandshakeHeader
+/**
+ * Represents the data items that make up a Client Hello message. 
+ *
+ * Its constructor sets up the default values for a Hello message object, e.g.,
+ * the size of the Handshake header (4), the number of bytes to use for the protocol 
+ * version (2), the number of bytes used to represent the length of session id's length
+ * item (1), etc. The values of these items will subsequently be set when the body of 
+ * the item has been retrieved.
+ *
+ * @note A Session Id is represented by 2 items, the 1st is 1 byte which will contain 
+ * the actual length of the session id, the 2nd is the session id itself which is of 
+ * variable length (32 bytes or less).
+ */
+{
+public:
+   CClientHelloMsg(CItemBase *aClientHelloExtension = NULL) :
+      CHandshakeHeader( &iVersion ),
+      iVersion( &iRandom, KTlsProtocolBodyLength ),
+      iRandom( &iSessionId ),
+      iSessionId( KTlsSessionIdLength, &iCipherSuite ),
+      iCipherSuite( KTlsCipherSuiteLength, &iCompression ),
+      iCompression( KTlsCompressionLength, aClientHelloExtension, KTlsCompressionBodyLength )
+   {
+   }
+
+public:
+   CConstItem iVersion;			///< SSL or TLS protocol version, 2 bytes
+   CRandomItem iRandom;			///< 32 byte Random value
+   CVariableItem iSessionId;	///< Session Id (variable size, 32 bytes or less)
+   CVariableItem iCipherSuite;	///< Proposed cipher suites (variable size)
+   CVariableItem iCompression;	///< Proposed compression methods (variable size)
+};
+
+/**
+ The class represents a header of an CCompoundList. 
+ 
+ An item list is a variable part of a message. It's created as the data is being parsed
+ @see CCompoundList
+ @internalComponent
+ **/
+NONSHARABLE_CLASS(CCompoundListHeader) : public CConstItem
+{
+public:
+	CCompoundListHeader( CItemBase* aNext, TInt aLength) :
+      CConstItem( aNext, aLength )
+	{
+   	}
+};
+
+/**
+ Represents an item list consisting of CItemBase items and 
+ having a CCompoundListHeader header.
+ @see CCompoundListHeader
+ @see CListItemHeader
+ @internalComponent
+ **/
+NONSHARABLE_CLASS(CCompoundList) : public CCompoundListHeader
+{
+public:
+   CCompoundList( CItemBase* aNext, TInt aLength );
+   virtual ~CCompoundList();
+
+   virtual void Dump( const TDesC& aTag, const TDesC& aFile );
+   void AddNodeL( CItemBase* aNode );
+   virtual void InitialiseL( TPtr8& aBuf8 );  //buffer must be initialised beforehand
+   virtual TInt CalcTotalInitialiseLength() const;
+
+   virtual void ParseL( TPtr8& aDes8 );
+
+   CItemBase* Node(TInt aIndex) const;
+
+   void DropNodes();
+
+private:
+   //TRecord iRecord; // list containing all fields of all nodes
+   RArray<TRecord> iRecords;
+};
+
+inline CCompoundList::CCompoundList( CItemBase* aNext, TInt aLength) :
+   CCompoundListHeader( aNext, aLength )
+{
+}
+
+inline CItemBase* CCompoundList::Node(TInt aIndex) const
+   {
+   	  if((aIndex < 0) || (aIndex >= iRecords.Count()))
+   	  	{
+   	  	return 0;
+   	  	}
+      return iRecords[aIndex].First();
+   }
+
+inline void CCompoundList::DropNodes()
+{
+	iRecords.Reset();
+}
+
+#ifdef _DEBUG
+inline void CCompoundList::Dump( const TDesC& aTag, const TDesC& aFile )
+/** 
+ * Dumps the variable item list's header and item list.
+
+ * The items must be parsed or initialised
+ *
+ * @param aTag A log file tag
+ * @param aFile A log file
+ */
+{
+   CCompoundListHeader::Dump( aTag, aFile );
+   TInt nodeCount = iRecords.Count();
+   for(TInt i=0; i<nodeCount; ++i)
+		{
+		iRecords[i].Dump( aTag, aFile );
+		}
+}
+#else
+inline void CCompoundList::Dump( const TDesC& /*aTag*/, const TDesC& /*aFile*/ )
+{
+}
+#endif
+
+/**
+Base class for TLS extensions.
+
+ All extensions start with a 2 byte type field followed by a length field, but this class only represents the type field.
+
+ @internalComponent
+ **/
+NONSHARABLE_CLASS(CExtensionNode) : public CConstItem
+{
+public:
+ 	enum TTlsExtensionType
+	{
+		KExtServerName = 0,
+		KExtMaxFraqmentLength = 1,
+		KExtClientCertificateUrl = 2,
+		KExtTrustedCaKeys = 3,
+		KExtTruncatedHmac = 4,
+		KExtStatusRequest = 5
+	};
+	virtual TInt ExtensionLength();
+protected:
+   CExtensionNode(CItemBase* aNext);
+   virtual ~CExtensionNode();
+};
+
+
+/**
+ Represents one item of the extension list.
+ The body of the extension is contained in a class derived from this class and is wrapped by our iOpaqueData member.
+  @internalComponent
+ **/
+NONSHARABLE_CLASS(CKnownExtensionNode) : public CExtensionNode
+{
+protected:
+   CKnownExtensionNode();
+   void ConstructOpaqueDataWrapperL(CItemBase* aNext);
+   ~CKnownExtensionNode();
+private:
+	CCompoundList iOpaqueData;
+};
+
+
+/**
+ Represents a generic extension
+ **/
+NONSHARABLE_CLASS(CGenericExtension) : public CExtensionNode
+{
+public:
+	static CGenericExtension* NewLC(TInt aInitialLength);
+	virtual TInt ExtensionLength();
+
+private:
+   CGenericExtension( TInt aInitialLength );
+   ~CGenericExtension();
+public:
+  	CVariableItem iOpaqueData; // The opaque extension data
+};
+
+
+NONSHARABLE_CLASS(CGenericExtensionList) : public CCompoundList
+{
+public:
+   CGenericExtensionList( CItemBase* aNext);
+
+   virtual void ParseL( TPtr8& aDes8 );
+
+   CGenericExtension* Node(TInt aIndex) const;
+};
+
+
+NONSHARABLE_CLASS(CClientServerNameEntry) : public CConstItem
+{
+public:
+ 	enum TTlsExtensionServerNameType
+	{
+		KExtServerNameTypeDns = 0
+ 	};
+
+	static CClientServerNameEntry* NewLC(TInt aInitialLength);
+private:
+   CClientServerNameEntry( TInt aInitialLength );
+public:
+  	CVariableItem iName; // Server name
+};
+
+
+NONSHARABLE_CLASS(CClientServerNameExtension) : public CKnownExtensionNode
+/**
+ Represents a client server name identification extension
+ **/
+{
+public:
+	static CClientServerNameExtension* NewLC();
+	void AddServerNameEntryL(CClientServerNameEntry *aServerNameEntry);
+	CClientServerNameEntry* Node(TInt aIndex);
+private:
+   CClientServerNameExtension();
+public:
+  	CCompoundList iServerNames;
+};
+
+
+NONSHARABLE_CLASS(CClientHelloWithExtensionsMsg) : public CClientHelloMsg
+	/**
+	Represents a Client Hello message which includes one or more Extensions.
+	*/
+{
+public:
+	CClientHelloWithExtensionsMsg(CItemBase *aNext = NULL) :
+		CClientHelloMsg(&iClientHelloExtensionList),
+		iClientHelloExtensionList(aNext, KTlsExtensionLength)
+  {
+  }
+	inline void AddExtensionL(CExtensionNode *aExtension);
+	inline CExtensionNode* Node(TInt aIndex);
+	
+	CCompoundList iClientHelloExtensionList;
+};
+
+inline void CClientHelloWithExtensionsMsg::AddExtensionL(CExtensionNode *aExtension)
+{
+	iClientHelloExtensionList.AddNodeL(aExtension);
+}
+
+inline CExtensionNode* CClientHelloWithExtensionsMsg::Node(TInt aIndex)
+{
+	return static_cast<CExtensionNode*>(iClientHelloExtensionList.Node(aIndex));
+}
+
+
+class CServerHelloMsg : public CHandshakeHeader
+/**
+ * Represents the data items that make up a Server Hello message. 
+ *
+ * Its constructor sets up the default values for a Hello message object, e.g.,
+ * the size of the Handshake header (4), the number of bytes to use for the protocol 
+ * version (2), the number of bytes used to represent the length of session id's length
+ * item (1), etc. The values of these items will subsequently be set when the body of 
+ * the item has been retrieved.
+ * Note that for a Server Hello message, a single cipher suite (2 bytes) and a single 
+ * compression value (1 byte) is returned. These items do not have length items 
+ * (compared to the Client Hello message). 
+ */
+{
+public:
+   CServerHelloMsg(CItemBase *aNext = 0) :
+      CHandshakeHeader( &iVersion ),
+      iVersion( &iRandom, KTlsProtocolBodyLength ),
+      iRandom( &iSessionId ),
+      iSessionId( KTlsSessionIdLength, &iCipherSuite ),
+      iCipherSuite( &iCompression, KTlsCipherSuiteBodyLength ),
+      iCompression( aNext, KTlsCompressionBodyLength )
+   {
+   }
+
+public:
+   CConstItem iVersion;			///< Selected protocol version, 2 bytes
+   CRandomItem iRandom;			///< 32 byte Server random value
+   CVariableItem iSessionId;	///< Session Id (variable size, 32 bytes or less)
+   CConstItem iCipherSuite;		///< Selected cipher suites, 2 bytes
+   CConstItem iCompression;		///< Selected compression methods, 1 byte
+};
+
+class CServerHelloMsgWithOptionalExtensions : public CServerHelloMsg
+{
+public:
+	CServerHelloMsgWithOptionalExtensions()
+		: CServerHelloMsg(&iExtensions),
+		  iExtensions(NULL)
+		{
+		}
+	CGenericExtensionList iExtensions;
+};
+
+class CCertificateMsg : public CHandshakeHeader
+/**
+ * Represents the Certificate (Client or Server) message items.
+ *
+ * The body of the Certificate message contains a chain of public key 
+ * certificates with the first 3 bytes of this message indicating the
+ * length of this chain.
+ */ 
+{
+public:
+   CCertificateMsg() :
+      CHandshakeHeader( &iCertificateList ),
+      iCertificateList( 0, KTlsCertChainLength )
+   {
+   }
+   void ComposeHeader( TInt aLength ) { CHandshakeHeader::ComposeHeader( ETlsCertificateMsg, aLength );}
+
+public:
+   CListItem iCertificateList;	///< List of certificates (Certificate chain)
+};
+
+
+class CFinishedMsg : public CHandshakeHeader
+/**
+ * Represents the contents/body of a SSL3.0 and/or a TLS1.0 Protocol 
+ * Finished message. This message indicates that the negotiation is complete and 
+ * that the negotiated cipher suite is in effect. As such, it is the first message  
+ * protected by the negotiated algorithms, keys and secrets.
+ *
+ * The message body consists of 12 bytes of data calculated using a Pseudo Random
+ * Function (PRF) for TLS1.0 and a concatenation of two hash results using MD5 and 
+ * SHA hash algorithms for SSL3.0.
+ */
+{
+public:
+   CFinishedMsg(TInt aMsgLength) :
+      CHandshakeHeader( &iFinishedData ),
+      iFinishedData( 0, aMsgLength )
+   {
+   }
+   void ComposeHeader( TInt aLength ) { CHandshakeHeader::ComposeHeader( ETlsFinishedMsg, aLength );}
+
+public:
+   CConstItem iFinishedData;		///< 12 bytes (TLS1.0) or 36 bytes (SSL3.0)
+};
+
+
+class CRsaParams
+/**
+ * Represents a Server's RSA key exchange parameters. 
+ * It consists of the RSA modulus and public exponent.
+ */
+{
+public:
+   CRsaParams( CItemBase* aNext = NULL ) :
+      iRsaModulus( KTlsRsaModLength, &iRsaExponent, KTlsRsaModBodyLength ),
+      iRsaExponent( KTlsRsaExpLength, aNext, KTlsRsaExpBodyLength )
+   {
+   }
+
+public:
+   CVariableItem iRsaModulus;	///< The modulus of the server's temporary RSA key.
+   CVariableItem iRsaExponent;	///< The public exponent of the server's temporary RSA key.
+
+};
+
+class CDhParams
+/**
+ * Represents a Server's Ephemeral DH key exchange parameters.
+ * It consists of the prime modulus, generator and DH public value.
+ */
+{
+public:
+   CDhParams( CItemBase* aNext = NULL ) :
+      iDh_p( KTlsDhpLength, &iDh_g, KTlsDhpBodyLength ),
+      iDh_g( KTlsDhgLength, &iDh_Ys, KTlsDhgBodyLength ),
+      iDh_Ys( KTlsDhYsLength, aNext, KTlsDhYsBodyLength )
+   {
+   }
+
+public:
+   CVariableItem iDh_p;		///< The prime modulus used for the Diffie-Hellman operation.
+   CVariableItem iDh_g;		///< The generator used for the Diffie-Hellman operation.
+   CVariableItem iDh_Ys;	///< The server's Diffie-Hellman public value (g^X mod p).
+
+};
+
+class CPskServerParams
+/**
+ * Represents a Server's PreShared Key (PSK) key exchange parameters.
+ * It consists of the just the psk_identity_hint.
+ */
+{
+public:
+   CPskServerParams( CItemBase* aNext = NULL ) :
+      iPskIdentityHint( KTlsPskLength, aNext )
+   {
+   }
+
+public:
+   CVariableItem iPskIdentityHint;		///< The "psk identity hint" field from the server
+};
+
+class CRsaSignature
+/**
+ * Represents a RSA signature. This is a hash (MD5 + SHA) of the 
+ * Server's key with the signature appropriate to that hash applied (RSA).
+ * Note that 1 signature covers both hashes.
+ */
+{
+public:
+   CRsaSignature() :
+      iMd5Sha( KTlsSigLength, 0, KTlsMd5Length + KTlsShaLength )
+   {
+   }
+
+public:
+   CVariableItem iMd5Sha;		///< 36 bytes
+};
+
+class CDsaSignature
+/**
+ * Represents a DSA signature. This is a SHA hash of the Server's key
+ * exchange params with the signature appropriate to that hash applied (DSA).
+ */
+{
+public:
+   CDsaSignature() :
+      iSha( KTlsSigLength, 0, KTlsShaLength )
+   {
+   }
+
+public:
+   CVariableItem iSha;		///< 20 bytes
+};
+
+// Server-side messages. 
+// Note that the Hello Request message (CHelloRequestMsg) is an empty message.
+class CMessageDigest;
+class CTlsCryptoAttributes;
+class CServerKeyExchMsg : public CHandshakeHeader
+/**
+ * Server Key Exchange message - abstract
+ */
+{
+public:
+   CServerKeyExchMsg( CItemBase* aNext ) :
+      CHandshakeHeader( aNext )
+   {
+   }
+
+public:
+   virtual void CopyParamsL( CTlsCryptoAttributes *aAttrs ) = 0;
+   virtual void ComputeDigestL( const TDesC8& aClientRandom, const TDesC8& aServerRandom, TDes8& aDigest ) = 0;
+   virtual TPtr8 Signature() = 0;
+
+protected:
+   void ComputeDSADigestL( const TDesC8& aClientRandom, const TDesC8& aServerRandom, TPtrC8& aDigestParams, TDes8& aDigest ) const;
+   void ComputeRSADigestL( const TDesC8& aClientRandom, const TDesC8& aServerRandom, TPtrC8& aDigestParams, TDes8& aDigest ) const;
+   void ComputeDigest( CMessageDigest* pDigest, const TDesC8& aClientRandom, const TDesC8& aServerRandom, TPtrC8& aDigestParams, TDes8& aDigest ) const;
+};
+
+class CRsaAnonServerKeyExchMsg : public CServerKeyExchMsg
+/**
+ * Server Key Exchange message with RSA params and no signature (anonymous).
+ */
+{
+public:
+   CRsaAnonServerKeyExchMsg() :
+      CServerKeyExchMsg( &iRsaParams.iRsaModulus )
+   {
+   }
+
+   virtual void CopyParamsL( CTlsCryptoAttributes *aAttrs );
+public:
+   CRsaParams iRsaParams;
+
+protected:
+   TUint8* GetDigestParamsPtr() const;
+   TInt GetDigestParamsLength() const;
+};
+
+class CRsaDsaServerKeyExchMsg : public CRsaAnonServerKeyExchMsg
+/**
+ * Server Key Exchange message with RSA params and a DSA signature.
+ */
+{
+public:
+   CRsaDsaServerKeyExchMsg()
+   {
+      iRsaParams.iRsaExponent.iNext = &iDsaSignature.iSha;
+   }
+   
+   virtual TPtr8 Signature();
+   virtual void ComputeDigestL( const TDesC8& aClientRandom, const TDesC8& aServerRandom, TDes8& aDigest );
+public:
+   CDsaSignature iDsaSignature;
+};
+
+class CRsaRsaServerKeyExchMsg : public CRsaAnonServerKeyExchMsg
+/**
+ * Server Key Exchange message with RSA params and a RSA signature.
+ */
+{
+public:
+   CRsaRsaServerKeyExchMsg()
+   {
+      iRsaParams.iRsaExponent.iNext = &iRsaSignature.iMd5Sha;
+   }
+
+   virtual TPtr8 Signature();
+   virtual void ComputeDigestL( const TDesC8& aClientRandom, const TDesC8& aServerRandom, TDes8& aDigest );
+
+public:
+   CRsaSignature iRsaSignature;
+};
+
+class CDhAnonServerKeyExchMsg : public CServerKeyExchMsg
+/**
+ * Server Key Exchange message with DH params and no signature (anonymous).
+ */
+{
+public:
+   CDhAnonServerKeyExchMsg() :
+      CServerKeyExchMsg( &iDhParams.iDh_p )
+   {
+   }
+   virtual void CopyParamsL( CTlsCryptoAttributes *aAttrs );
+
+public:
+   CDhParams iDhParams;
+
+protected:
+   TUint8* GetDigestParamsPtr() const;
+   TInt GetDigestParamsLength() const;
+};
+
+class CDhDsaServerKeyExchMsg : public CDhAnonServerKeyExchMsg
+/**
+ * Server Key Exchange message with DH params and a DSA signature.
+ */
+{
+public:
+   CDhDsaServerKeyExchMsg()
+   {
+      iDhParams.iDh_Ys.iNext = &iDsaSignature.iSha;
+   }
+   
+   virtual TPtr8 Signature();
+   virtual void ComputeDigestL( const TDesC8& aClientRandom, const TDesC8& aServerRandom, TDes8& aDigest );
+   
+public:
+   CDsaSignature iDsaSignature;
+};
+
+class CDhRsaServerKeyExchMsg : public CDhAnonServerKeyExchMsg
+/**
+ * Server Key Exchange message with DH params and a RSA signature.
+ */
+{
+public:
+   CDhRsaServerKeyExchMsg()
+   {
+      iDhParams.iDh_Ys.iNext = &iRsaSignature.iMd5Sha;
+   }
+
+   virtual TPtr8 Signature();
+   virtual void ComputeDigestL( const TDesC8& aClientRandom, const TDesC8& aServerRandom, TDes8& aDigest );
+
+public:
+   CRsaSignature iRsaSignature;
+};
+
+class CPskServerKeyExchMsg : public CServerKeyExchMsg
+/**
+ * PSK Server Key Exchange message
+ */
+{
+public:
+   CPskServerKeyExchMsg()
+      : CServerKeyExchMsg( &iPskServerParams.iPskIdentityHint)
+   {
+   }
+
+   virtual void CopyParamsL( CTlsCryptoAttributes *aAttrs );
+   virtual TPtr8 Signature();
+   virtual void ComputeDigestL( const TDesC8& aClientRandom, const TDesC8& aServerRandom, TDes8& aDigest );
+
+public:
+   CPskServerParams iPskServerParams;
+};
+
+class CCertificateReqMsg : public CHandshakeHeader
+/**
+ * Represents a Certificate Request message sent by a Server.
+ * This message asks a Client to send its certificate (to authenticate itself)
+ * and to sign information using the private key for that Certificate. It also
+ * tells a client which Certificates are acceptable to the Server.
+ *
+ * Note that SSL3.0 defines 3 Certificate types more than TLS1.0 (rsa_ephemeral_dh,
+ * dss_ephemeral_dh, fortezza_kea(20)). Fortezza is not supported in this implementation.
+ */
+
+{
+public:
+   CCertificateReqMsg() :
+      CHandshakeHeader( &iClientCertificateTypes ),
+      iClientCertificateTypes( KTlsCertTypesLength, &iDistinguishedNames, KTlsCertTypesBodyLength ),
+      iDistinguishedNames( 0, KTlsCALength )
+   {
+   }
+
+public:
+   CVariableItem iClientCertificateTypes;	///< List of the requested Certificates types.
+   CListItem iDistinguishedNames;			///< List of acceptable CAs.
+};
+
+class CServerHelloDoneMsg : public CHandshakeHeader
+/**
+ * Server Hello Done message. This message concludes the Server's part of a 
+ * handshake negotiation. Apart from the handshake type, its message body is empty
+ * (i.e., it does not carry any information).
+ */
+{
+public:
+   CServerHelloDoneMsg() :
+      CHandshakeHeader( 0 )
+   {
+   }
+};
+
+// Client side messages
+// Client side messages
+class CClientKeyExchMsg : public CHandshakeHeader
+{
+public:
+   CClientKeyExchMsg( CItemBase* iNext ) :
+      CHandshakeHeader( iNext )
+   {
+   }
+
+   void ComposeHeader( TInt aLength ) { CHandshakeHeader::ComposeHeader( ETlsClientKeyExchMsg, aLength );}
+   virtual void SetKeyExchnage( TDesC8& aDes8 ) = 0;
+};
+
+class CRsaClientKeyExchMsg31 : public CClientKeyExchMsg
+/**
+ * Represents a RSA Client Key Exchange message for TLS1.0. This message enables a 
+ * Client to provide the Server with the key materials necessary for securing the
+ * communication.
+ * 
+ * For RSA, the message body consists of the Encrypted Premaster secret (2 bytes
+ * for the Protocol version and 46 securely generated random bytes) encrypted with the
+ * server's public key. Encryption of the premaster secret increases its size from 48 bytes.
+ */
+{
+public:
+   CRsaClientKeyExchMsg31( TInt aEncryptedDataLength ) :
+      CClientKeyExchMsg( &iEncryptedPreMasterSecret ),
+	  iEncryptedPreMasterSecret( KTlsRsaKeyExchLength, NULL, aEncryptedDataLength)
+   {
+   }
+   virtual void SetKeyExchnage( TDesC8& aDes8 ) {iEncryptedPreMasterSecret.SetBody( aDes8 );}
+
+public:
+   CVariableItem iEncryptedPreMasterSecret;
+};
+
+class CRsaClientKeyExchMsg30 : public CClientKeyExchMsg
+/**
+ * Represents a RSA Client Key Exchange message for SSL3.0. This message enables a 
+ * Client to provide the Server with the key materials necessary for securing the
+ * communication.
+ * 
+ * For RSA, the message body consists of the Encrypted Premaster secret (2 bytes
+ * for the Protocol version and 46 securely generated random bytes) encrypted with the
+ * server's public key. Encryption of the premaster secret increases its size from 48 bytes.
+ */
+{
+public:
+   CRsaClientKeyExchMsg30( TInt aEncryptedDataLength ) :
+      CClientKeyExchMsg( &iEncryptedPreMasterSecret ),
+	  iEncryptedPreMasterSecret( NULL, aEncryptedDataLength)
+   {
+   }
+   virtual void SetKeyExchnage( TDesC8& aDes8 ) {iEncryptedPreMasterSecret.SetBody( aDes8 );}
+
+public:
+   CConstItem iEncryptedPreMasterSecret;
+};
+
+class CDhExplicitClientKeyExchMsg : public CClientKeyExchMsg
+/**
+ * Represents an Explicit DH Client Key Exchange message (Ephemeral DH). 
+ * This message enables a Client to provide the Server with the key materials 
+ * necessary for securing the communication.
+ * 
+ * The message body contains the Client's DH public (Yc) value which is sent explicitly
+ * in this message.
+ */
+{
+public:
+   CDhExplicitClientKeyExchMsg( TInt aEncryptedDataLength ) :
+      CClientKeyExchMsg( &iDh_Yc ),
+      iDh_Yc( KTlsDhYcLength, 0, aEncryptedDataLength )
+   {
+   }
+   virtual void SetKeyExchnage( TDesC8& aDes8 ) {iDh_Yc.SetBody( aDes8 );}
+
+public:
+   CVariableItem iDh_Yc;
+};
+
+class CDhImplicitClientKeyExchMsg : public CClientKeyExchMsg
+/**
+ * Represents an Implicit DH Client Key Exchange message.
+ * This message enables a Client to provide the Server with the key materials 
+ * necessary for securing the communication.
+ * 
+ * The Client's public (Yc) value is implicit (contained in the Client certificate)
+ * and does not need to be sent again. As such, the message body is empty, although
+ * the message will be sent.
+ */
+{
+public:
+   CDhImplicitClientKeyExchMsg() :
+      CClientKeyExchMsg( NULL )
+   {
+   }
+   virtual void SetKeyExchnage( TDesC8& /*aDes8*/ ) {}
+};
+
+class CPskClientKeyExchMsg : public CClientKeyExchMsg
+/**
+ * Represents a PSK Client Key Exchange message. 
+ * This message enables a Client to provide the Server with the key materials 
+ * necessary for securing the communication.
+ * 
+ * The message body contains the PSK identity.
+ */
+{
+public:
+   CPskClientKeyExchMsg( TInt aDataLength ) :
+      CClientKeyExchMsg( &iPskIdentity ),
+      iPskIdentity( KTlsPskLength, 0, aDataLength )
+   {
+   }
+   virtual void SetKeyExchnage( TDesC8& aDes8 ) {iPskIdentity.SetBody( aDes8 );}
+
+public:
+   CVariableItem iPskIdentity;
+};
+
+class CCertificateVerifyMsg : public CHandshakeHeader
+/**
+ * Represents a Certificate verify message base
+ * 
+ */
+{
+public:
+   CCertificateVerifyMsg( CItemBase* aNext ) :
+      CHandshakeHeader( aNext )
+   {
+   }
+   void ComposeHeader( TInt aLength ) { CHandshakeHeader::ComposeHeader( ETlsCertificateVerifyMsg, aLength );}
+   virtual void SetSignature( TDesC8& aSign ) = 0;
+   virtual void SetSignatureLength( TDesC8& aSign ) = 0;
+};
+
+class CDsaCertificateVerifyMsg : public CCertificateVerifyMsg
+/**
+ * Represents a Certificate verify message. This message provides explicit
+ * verification of a DSA certificate.
+ * For SSL3.0 and TLS1.0, a SHA hash is created and signed. However, the input
+ * into the hash differs for both protocols.
+ * 
+ * The message body consists of a DSA signature. 
+ */
+{
+public:
+   CDsaCertificateVerifyMsg() :
+      CCertificateVerifyMsg( &iDsaSignature.iSha )
+   {
+   }
+
+   virtual void SetSignature( TDesC8& aSign );
+   virtual void SetSignatureLength( TDesC8& aSign );
+
+public:
+   CDsaSignature iDsaSignature;
+};
+
+class CRsaCertificateVerifyMsg : public CCertificateVerifyMsg
+/**
+ * Represents a Certificate verify message. This message provides explicit
+ * verification of a RSA certificate. 
+ * For SSL3.0 and TLS1.0, two hashes (MD5 and SHA) are combined and signed.
+ * However, the input into the hash differs for both protocols.
+ * 
+ * The message body consists of a RSA signature. 
+ */
+{
+public:
+   CRsaCertificateVerifyMsg() :
+      CCertificateVerifyMsg( &iRsaSignature.iMd5Sha )
+   {
+   }
+   void ComposeHeader( TInt aLength ) { CHandshakeHeader::ComposeHeader( ETlsCertificateVerifyMsg, aLength );}
+   
+   virtual void SetSignature( TDesC8& aSign );
+   virtual void SetSignatureLength( TDesC8& aSign );
+
+public:   
+   CRsaSignature iRsaSignature;
+};
+
+// Inline functions
+inline TUint8* CRsaAnonServerKeyExchMsg::GetDigestParamsPtr() const
+{
+   return iRsaParams.iRsaModulus.Ptr();
+}
+
+inline TInt CRsaAnonServerKeyExchMsg::GetDigestParamsLength() const
+{
+   return iRsaParams.iRsaModulus.GetItemLength() + iRsaParams.iRsaExponent.GetItemLength();
+}
+
+inline TUint8* CDhAnonServerKeyExchMsg::GetDigestParamsPtr() const
+{
+   return iDhParams.iDh_p.Ptr();
+}
+
+inline TInt CDhAnonServerKeyExchMsg::GetDigestParamsLength() const
+{
+   return iDhParams.iDh_p.GetItemLength() + iDhParams.iDh_g.GetItemLength() + 
+          iDhParams.iDh_Ys.GetItemLength();
+}
+
+#endif