networksecurity/tls/ts_tls/T_TLS_test.cpp
changeset 0 af10295192d8
child 53 7e41d162e158
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/networksecurity/tls/ts_tls/T_TLS_test.cpp	Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,955 @@
+// 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:
+//
+ 
+#include "T_TLS_test.h"
+#include <e32svr.h>
+#include <ssl.h>
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <ssl_internal.h>
+#endif
+
+
+
+const TInt KHexDumpWidth = 16;
+const TInt KEAPKeyLength = 128+64;
+
+
+TInt CTLSTest::RunError( TInt aError )
+	{
+
+	iTestStep->Log( _L("RunL err %d"), aError );
+
+	if ( iTlsSocket )
+		{
+		iTlsSocket->Close();
+
+		delete iTlsSocket;
+		iTlsSocket = 0;
+
+		
+		}
+
+	iInUse = EFalse;
+
+	return KErrNone;
+	}
+
+CTLSTest* CTLSTest::NewL()
+	{
+	CTLSTest* self = new(ELeave) CTLSTest;
+	CleanupStack::PushL( self );
+	self->ConstructL();
+	CleanupStack::Pop();		
+	return self;
+	}
+
+// Constructor should also call the parent constructor to set the priority
+// of the active object.
+CTLSTest::CTLSTest() : CActive(0)
+	{
+	}
+
+CTLSTest::~CTLSTest()
+	{
+	// Cancel any outstanding request
+	Cancel();	
+
+	delete iTlsSocket;
+	delete iTlsSocket2;
+	delete iGenericSocket;
+
+	iTimer.Close();
+
+	// Close the resources in the reverse order
+	iHostResolver.Close();
+	iSocket.Close();
+	iSocketServ.Close();
+
+//	__UHEAP_MARK; 
+//	__UHEAP_MARKEND;
+	}
+
+void CTLSTest::ConstructL()
+	{
+
+	// Connect the socket server
+	User::LeaveIfError( iSocketServ.Connect() );
+	
+	// Create a local timer
+	User::LeaveIfError( iTimer.CreateLocal() );
+
+	// Connect to a host resolver
+	User::LeaveIfError( iHostResolver.Open( iSocketServ, KAfInet, KProtocolInetTcp ) );
+
+	iRunState = ESocketConnected;
+	iInUse = EFalse;
+
+	CActiveScheduler::Add( this );
+	}
+
+void CTLSTest::RunL()
+	{
+	THTTPMessage *iMyHTTP;
+	TInt err = KErrNone;
+#ifdef __WINS__
+	TText margin = 0;
+	TText header = 0;
+	TSockXfrLength aLen;
+#endif
+
+	switch ( iRunState )
+		{
+	case ESocketConnected:
+		{
+		iTestStep->Log( _L("STATE: ENotSecureConnected Status: %d"), iStatus.Int() );
+
+		// As the receive buffer is static, set it's length to 0 here,
+		// so if there is an error somewhere, the previous buffer's contents 
+		// wont be dumped to the log file again.
+		iRcvBuffer.SetLength( 0 );
+		iBytesRead = 0;
+		iTotalBytesRead = 0;
+		iFirstRunFlag = ETrue;
+
+		if ( iStatus != KErrNone )
+			{
+			iTestStep->Log( KStateErrConnected, iStatus.Int() );
+			iRunState = EConnectionClosed;
+			iTestPassed = EFalse;
+			iTimer.After( iStatus, 1000000 );
+			SetActive();			 
+			break;
+			}
+
+		//=========================================================
+		// Construct the Tls socket
+		if ( !iTlsSocket )
+			{
+			TInt lcode = KErrNone;
+			if(iUseGenericSocket)
+				{
+				iTestStep->Log( _L("Creating SecureSocket using Generic Socket") );
+				TRAP(lcode, iTlsSocket = CSecureSocket::NewL( *iGenericSocket, iProtocol ) );
+				}
+			else
+				{
+				iTestStep->Log( _L("Creating SecureSocket using RSocket") );
+				TRAP(lcode, iTlsSocket = CSecureSocket::NewL( iSocket, iProtocol ) );
+				}
+			if ( lcode )
+				{ 
+				iTestStep->Log( _L("Error creating secure socket: %d"), lcode );
+				iRunState = EConnectionClosed;
+				iTestPassed = EFalse;
+				iTimer.After( iStatus, 1000000 );
+				SetActive();			 
+				break;
+				}
+			}
+
+		//=========================================================
+
+		if( iEAPKeyDerivation )
+			{
+			if(KeyDerivationTests(EFalse) != KErrNone)
+				{
+				iRunState = EConnectionClosed;
+				iTestPassed = EFalse;
+				iTimer.After( iStatus, 1000000 );
+				SetActive();			 
+				break;
+				}
+			}
+
+
+		//======================================================================================
+		// Set any options before the handshake starts
+		if ( !iTlsSocket2 )
+			{
+			iTestStep->Log( _L("Flush session cache") );
+			iTlsSocket->FlushSessionCache();
+			}
+
+		//=========================================================
+		// Set the cipher suite list
+		if ( iCipherSuites.Length() > 1 )
+			{
+
+			// Create the buffer with the cipher suites
+			TBuf8<KCipherBufSize>	cipherBuf;
+//			TBuf8<KCipherBufSize>	iCipherSuites;
+			TBuf8<3>	tempBuf;
+			TInt	i;
+			TInt	value;
+			TInt	ret = KErrNone;
+			TInt	cCount = 0;			// used as an array index into the cipherBuf descriptor
+			TLex8	myLex;
+
+
+			// The cipher buffer will actually be the same length as the aCipherSuite passed in
+			// because it's in binary format with leading 0's.
+			cipherBuf.SetLength( iCipherSuites.Length() );
+
+			iTestStep->Log( _L("Cipher suites") );
+
+			for ( i=0; i<iCipherSuites.Length(); i+=2 )
+				{
+				// iCipherSuites contains a list of decimal values for each cipher suite that
+				// the client should offer to use. They are in a string format, so each decimal 
+				// value takes 2 bytes.
+				//
+				// Copy the 2 bytes of one value into a buffer so that it can be converted into
+				// a real decimal value;
+				tempBuf.SetLength( 2 );
+				tempBuf[0] = iCipherSuites[i];
+				tempBuf[1] = iCipherSuites[i+1];
+
+				myLex.Assign( tempBuf );
+				ret = myLex.Val( value );
+				if ( ret!=KErrNone )
+					{
+					break; // from for loop
+					}
+				iTestStep->Log( _L(":%X"), value );
+
+				if ( value == 99 )
+					{
+					cipherBuf[ cCount++ ] = 0xFF;
+					cipherBuf[ cCount++ ] = 0xFF;
+					}
+				else
+					{
+					// The actual cipher suite list that must be passed in the socket options
+					// is in a binary format of 0x0,0xCipherValue,0x0,CipherValue etc				
+					cipherBuf[ cCount++ ] = 0;
+					cipherBuf[ cCount++ ] = (unsigned char)value;
+					}
+
+				} // end of for loop
+
+			if ( cipherBuf.Length() )
+				{
+#ifdef __WINS__
+				iTestStep->Log( _L("Setting avilable cipher suites") );
+				HexDump( &header, &margin, &cipherBuf[0], cipherBuf.Length() );
+#endif
+
+				ret = iTlsSocket->SetOpt(KSoEnableNullCiphers, KSolInetSSL, ETrue);
+				
+				if ( ret != KErrNone )
+					{
+					TPtrC errorText = iTestStep->EpocErrorToText(ret);
+					iTestStep->Log( _L("Couldnt set NULL cipher suite option :%S  (%d)"),&errorText, ret );
+					iTestPassed = EFalse;
+					}
+
+				ret = iTlsSocket->SetAvailableCipherSuites( cipherBuf );
+
+				if ( ret != KErrNone )
+					{
+					TPtrC errorText = iTestStep->EpocErrorToText(ret);
+					iTestStep->Log( _L("Couldnt set available cipher suites error:%S  (%d)"),&errorText, ret );
+					iTestPassed = EFalse;
+					}
+				}
+
+			iTestStep->Log( _L("") );
+			} // end of if iciphersuites .length
+
+		// end of setting the cipher suite list
+		//=========================================================
+
+
+		TBuf<8> prot;
+		err = iTlsSocket->Protocol( prot );
+    	
+		//*****************************************************
+		if ( !err )
+			{
+			iTestStep->Log( _L("Protocol set for use:") );
+			iTestStep->Log( prot );
+			}
+
+		err = iTlsSocket->SetProtocol( prot );
+		if ( err )
+			{
+			iTestStep->Log( _L("Failed to set Protocol for use: (%d)"),err );
+			}
+
+		// Set the domain name we're connecting to...
+		iStatus = iTlsSocket->SetOpt(KSoSSLDomainName,KSolInetSSL, iDNSName);
+		if ( iStatus != KErrNone )
+			{
+			iTestStep->Log( KStateErrReceivePage, iStatus.Int() );
+			iTestStep->Log( KStateErrReceivePage, iStatus.Int() );
+			iRunState = EConnectionClosed;
+			iTestPassed = EFalse;
+			iTlsSocket->Close();				 
+			iTimer.After( iStatus, 1000000 );
+			}
+			// end of setting options
+			//======================================================================================
+		else
+			{
+			//=========================================================
+			// start the handshake 
+			iTlsSocket->StartClientHandshake( iStatus );
+			//=========================================================
+			iRunState = ESecureConnected;
+			}
+
+		SetActive();
+		break;
+		}
+
+	case ESecureConnected:
+	case ESecureRenegotiated:
+		{
+		iTestStep->Log( _L("STATE: ESecureConnected/ESecureRenegotiated Status: %d"), iStatus.Int() );
+
+		// The secure connection has now been made.
+		// Send a get request for the page.
+
+		// Send the get request
+
+
+
+
+		if ( iStatus != KErrNone )
+			{
+			TPtrC errorText = iTestStep->EpocErrorToText(iStatus.Int());
+			iTestStep->Log( _L("ESecureConnected:%S %d"),&errorText, iStatus.Int() );
+			iTestStep->Log( KStateErrReceivePage, iStatus.Int() );
+			iTestStep->Log( KStateErrReceivePage, iStatus.Int() );
+			iRunState = EConnectionClosed;
+			iTestPassed = EFalse;
+			iTlsSocket->Close();				 
+			iTimer.After( iStatus, 1000000 );
+			SetActive();
+			break;
+			}
+		else
+			{
+			iTestStep->Log( _L("ESecureConnected:KErrNone %d"),iStatus.Int() );
+			}
+
+		TDes8* pSendDes;
+		if ( !iTlsSocket2 )
+			{
+			pSendDes = &iRcvBuffer;
+			iRcvBuffer.SetLength( iRcvBuffer.MaxLength() );
+			iTestStep->Log( _L("Sending %d bytes"), iRcvBuffer.Length() );
+			}
+		else
+			{
+			pSendDes = &iSndBuffer;
+			// Can a simple "GET /page.htm" request be used? 
+			if ( iSimpleGet )
+				{
+				iSndBuffer.Copy( _L("GET ") );
+				iSndBuffer.Append( iPage );
+				iSndBuffer.Append( _L("") );
+				iTestStep->Log( _L("Using simple get") );
+				}
+			else
+				{
+				// build and send a HTTP GET request to retrieve a page
+				iMyHTTP = new THTTPMessage;
+				iMyHTTP->Method(_L8("GET"));
+				iMyHTTP->URI( iPage );
+				iMyHTTP->AddHeaderField(_L8("Connection"),_L8("close"));
+				iMyHTTP->AddHeaderField(_L8("User-Agent"),_L8("SSL_TEST"));
+				iMyHTTP->AddHeaderField(_L8("Accept-Encoding"));
+				iMyHTTP->AddHeaderField(_L8("Accept"),_L8("*/*"));
+				iMyHTTP->GetHeader(iSndBuffer);
+				delete iMyHTTP;
+				}
+
+			iTestStep->Log( KLogSendingRequest );
+#ifdef __WINS__
+			HexDump( &header, &margin, &iSndBuffer[0], iSndBuffer.Length() );
+#endif
+			}
+
+		iRunState = iRunState == ESecureRenegotiated ? EGetRequestSentReneg : EGetRequestSent;
+
+		//=========================================================
+		// send the request
+		iTlsSocket->Send( *pSendDes, iStatus, iBytesSent );
+		//=========================================================	
+
+		if( iEAPKeyDerivation )
+			{
+			if(KeyDerivationTests(ETrue) != KErrNone)
+				{
+				iRunState = EConnectionClosed;
+				iTestPassed = EFalse;
+				iTimer.After( iStatus, 1000000 );
+				SetActive();			 
+				break;
+				}
+			}
+		
+		SetActive();
+		break;
+		}
+
+	case EGetRequestSent:
+	case EGetRequestSentReneg:
+		{
+
+		// The get request has been sent, can now try and receive the data
+
+		iTestStep->Log( _L("STATE: EGetRequestSent/EGetRequestSentReneg Status: %d"), iStatus.Int() );
+
+		if ( iStatus != KErrNone )
+			{
+			iTestStep->Log( _L("EGetRequestSent: %d"), iStatus.Int() );
+			iRunState = EConnectionClosed;
+			iTestPassed = EFalse;
+			iTlsSocket->Close();
+			iTimer.After( iStatus, 1000000 );
+			SetActive();			 
+			break;
+			}
+
+		// Before that, check which cipher suite has been negotiated.
+		TBuf8<4> buf; 
+		// no need to set descriptor length as in case with the old getopt, 
+		// CurrentCipherSuite will do that
+		err = iTlsSocket->CurrentCipherSuite( buf );
+		if ( err )
+			{
+			iTestStep->Log( _L("CurrentCipherSuite: %d"), err );
+			}
+		else
+			{
+#ifdef __WINS__
+			iTestStep->Log( _L("Cipher suite in use:") );
+			HexDump( &header, &margin, &buf[0], buf.Length() );
+#endif
+			}
+
+		// Get the servers certificate
+		const CX509Certificate *servCert = iTlsSocket->ServerCert();
+
+		if ( servCert )
+			{
+			GetCertInfo( *servCert );
+			}
+		else
+			{
+			iTestStep->Log( _L("No server certificate is available") );
+			}
+
+		// Get the protocol version string
+		TBuf<32> protocol;
+
+		err = iTlsSocket->Protocol( protocol );
+
+		if ( !err )
+			{
+			iTestStep->Log( _L("Protocol used in connection:") );
+			iTestStep->Log( protocol );
+			}
+
+		// New tests added as part of GT167 Zephyr.
+		// These tests are not meant to be in a logical order. They simply exercise the 
+		// Secure socket API. Logical ordering of the tests should happen in further
+		// development of the TLS test code and all supported APIS should be called/tested.
+
+		// Get the Client certificate
+		const CX509Certificate *clientCert = iTlsSocket->ClientCert();
+
+		if ( clientCert )
+			{
+			GetCertInfo( *clientCert );
+			}
+		else
+			{
+			iTestStep->Log( _L("No client certificate is available") );
+			}
+
+		// Get the Client cert mode. This API is NOT supported in client mode.
+		TClientCertMode certMode = iTlsSocket->ClientCertMode();
+		if ( certMode )
+			{
+			iTestStep->Log( _L("ClientCertMode() is not supported, Default value is: %d"), EClientCertModeIgnore );
+			iTestStep->Log( _L("Current mode setting is: %d"), certMode );			
+			}
+
+		iTestStep->Log( _L("Set Client Cert mode to: %d"), EClientCertModeOptional );
+		err = iTlsSocket->SetClientCertMode(EClientCertModeOptional);
+		if (err != KErrNotSupported)
+			{
+			iTestStep->Log( _L("SetClientCertMode Failed: %d"), err );
+			}
+
+		// Get the Dialog mode.
+		TDialogMode dialogMode = iTlsSocket->DialogMode();
+		iTestStep->Log( _L("Dialog mode setting is: %d"), dialogMode );			
+
+		// GetOpt() API: Current cipher suite option
+		TUint optionName = KSoCurrentCipherSuite;
+		TUint optionLevel = KSolInetSSL;
+		TBuf8<30> option;  // Note that the size of 30 is arbitrary.
+
+		TInt retValue = iTlsSocket->GetOpt(optionName, optionLevel, option);
+
+		// GetOpt() API: Available cipher cipher suites option
+		option.FillZ();		// reset the descriptor before reuse
+		option.Zero();	
+		optionName = KSoAvailableCipherSuites;
+		retValue = iTlsSocket->GetOpt(optionName, optionLevel, option);
+
+		// GetOpt() API: Dialog mode option
+		option.FillZ();		// reset the descriptor before reuse
+		option.Zero();	
+		optionName = KSoDialogMode;
+		retValue = iTlsSocket->GetOpt(optionName, optionLevel, option);
+
+		// GetOpt() API: Server certificate option
+		option.FillZ();		// reset the descriptor before reuse
+		option.Zero();	
+		optionName = KSoSSLServerCert;
+		//		retValue = iTlsSocket->GetOpt(optionName, optionLevel, option);
+
+		// SetOpt() API: Dialog mode option
+		option.FillZ();		// reset the descriptor before reuse
+		option.Zero();	
+		optionName = KSoDialogMode;
+		//		retValue = iTlsSocket->SetOpt(optionName, optionLevel, option);
+		// End of the addition of new tests for GT167 Zephyr
+
+		iRunState = iRunState == EGetRequestSent ? EDataReceived : EDataReceivedReneg;
+		if ( iTlsSocket2 )
+			{
+			iRcvBuffer.Zero();
+			iTlsSocket->Recv( iRcvBuffer, iStatus );
+			SetActive();
+			break;
+			}
+		iRcvBuffer.Zero();
+
+		if( iEAPKeyDerivation )
+			{
+			if(KeyDerivationTests(ETrue) != KErrNone)
+				{
+				iRunState = EConnectionClosed;
+				iTestPassed = EFalse;
+				iTlsSocket->Close();
+				iTimer.After( iStatus, 1000000 );
+				SetActive();			 
+				break;
+				}
+			}
+
+		// Fall through
+		}
+
+	case EDataReceived:
+	case EDataReceivedReneg:
+		{
+		iTestStep->Log( _L("STATE: EDataReceived/EDataReceivedReneg Status: %d"), iStatus.Int() );
+		iTestStep->Log( _L("EDataReceived length:%d"), iRcvBuffer.Length() );		
+
+		// Any error other than KErrEof means the test is a failure
+		if ( iStatus!=KErrNone && iStatus!=KErrEof)
+			{
+			// Close the socket neatly
+			iRunState = EConnectionClosed;
+			iTlsSocket->Close();
+			iTimer.After( iStatus, 1000000 );
+			SetActive();
+			break;	
+			}
+
+		// Log the received buffer
+		if ( iRcvBuffer.Length() )
+			{
+			iTestStep->Log( KLogBytesRead, iRcvBuffer.Length() );
+#ifdef __WINS__
+			HexDump( &header, &margin, &iRcvBuffer[0], iRcvBuffer.Length() );
+#endif
+			iTotalBytesRead += iRcvBuffer.Length();
+			if ( iStatus==KErrEof  )
+				{
+				iRunState = EConnectionClosed;
+				iTlsSocket->Close();
+				iTimer.After( iStatus, 1000000 );
+
+				if( iEAPKeyDerivation )
+					{
+					if(KeyDerivationTests(EFalse) != KErrNone)
+						{
+						iTestPassed = EFalse;
+						}
+					}
+				}				
+			else
+				{
+				//read again
+				iRcvBuffer.SetLength( 0 );
+				iTlsSocket->Recv( iRcvBuffer, iStatus );
+				}
+
+			SetActive(); 
+			break;
+			}
+		else
+			{
+			if ( iRunState == EDataReceived )
+				{
+				iRunState = ESecureRenegotiated;
+				iTestStep->Log( _L("******* Trying renegotiate *******") );
+				iTlsSocket->FlushSessionCache();
+				iTlsSocket->RenegotiateHandshake( iStatus );
+
+				if( iEAPKeyDerivation )
+					{
+					if(KeyDerivationTests(ETrue) != KErrNone)
+						{
+						iRunState = EConnectionClosed;
+						iTestPassed = EFalse;
+						iTlsSocket->Close();
+						iTimer.After( iStatus, 1000000 );
+						SetActive();			 
+						break;
+						}
+					}
+
+				SetActive(); 
+				break;
+				}
+			else
+				{
+				iRunState = EConnectionClosed;
+				}
+			}
+
+		// Fall through
+		}
+
+	case EConnectionClosed:
+		{
+		iTestStep->Log( _L("STATE: EConnectionClose Status: %d"), iStatus.Int() );
+
+		if ( iStatus != KErrNone )
+			{
+			iTestStep->Log( KStateErrFinished, iStatus.Int() );
+			iTestStep->Log( KStateErrFinished, iStatus.Int() );
+			iTestPassed = EFalse;
+			}
+
+		if ( iTotalBytesRead )
+			{
+			iTestStep->Log( KLogBytesRead, iTotalBytesRead );
+			}
+
+		if ( iTestPassed )
+			{
+			iTestStep->iTestStepResult = EPass;
+			iTestStep->Log( KLogTestPassed );
+			}
+		else
+			{
+			iTestStep->iTestStepResult = EFail;
+			iTestStep->Log( KLogTestFailed );
+			}
+
+		if ( iTlsSocket2 ) //to test abreviatted handshake
+			{
+			iInUse = EFalse;
+			iTlsSocket->Close();
+			delete iTlsSocket;
+			iTlsSocket =0;
+			delete iTlsSocket2;
+			iTlsSocket2 =0;
+			}
+		else if ( iTlsSocket )
+			{//keep the first instance live not to destroy the session cache
+			iTlsSocket2 = iTlsSocket;
+			iTlsSocket = NULL;
+			iTestStep->Log(_L("Connecting to %s:%d"), iAddress.PtrZ(), iPortNum );
+			iTlsSocket2->Close();
+			User::LeaveIfError( iSocket.Open( iSocketServ, KAfInet, KSockStream, KProtocolInetTcp ) );	
+			iSocket.Connect( iInetAddr, iStatus );
+			SetActive();
+			iRunState = ESocketConnected;
+			}
+		else
+			{
+			iInUse = EFalse;
+			}
+
+		// can wait here for an unload of the ssl.dll to make sure that a session is not
+		// reconnected next time. The option to set the unload timeout via a SetOpt
+		// may not currently work, so this is a sure way to stop a reconnection.
+		if ( iTestEndDelay )
+			{
+			iTestStep->Log( _L("Waiting for %d seconds"), iTestEndDelay );
+			User::After( 1000000 * iTestEndDelay );
+			}
+
+		break;
+		}
+
+	case EDummyConnection:
+		iTestStep->Log( _L("STATE: EDummyConnection Status: %d"), iStatus.Int() );
+		iInUse = EFalse;
+		break;
+
+		// end switch
+		}
+	}
+
+void CTLSTest::DoCancel()
+	{	
+	// Cancel the connect
+	iSocket.CancelConnect();
+	}
+
+void CTLSTest::ConnectL( const TDesC &aAddress, 
+				const TInt aPortNum, 
+				const TDesC &aPage, 
+				const TDesC8 &aCipherSuite, 
+				const TInt aCipher, 
+				const TInt aSimpleGet, 
+				const TInt aTestEndDelay, 
+				const TDesC8& aDNSName ,
+				const TDesC& aProtocol, 
+				TBool aUseGenericSocket, 
+				TBool aEAPKeyDerivation )
+	{
+#if 0
+	iRunState = EDummyConnection;
+	TRequestStatus* p=&iStatus;
+	User::RequestComplete( p, KErrNone );
+   SetActive();
+   return;
+#endif
+
+	TInt err;
+	TNameEntry nameEntry;
+	TNameRecord nameRecord;
+	TSockAddr sockAddr;
+
+	iInUse = ETrue;
+
+	err = iInetAddr.Input( aAddress );
+	if ( err != KErrNone )
+		{
+		err = iHostResolver.GetByName( aAddress, nameEntry );
+		if ( err == KErrNone )
+			{
+			nameRecord = nameEntry();
+			sockAddr = nameRecord.iAddr;
+			iInetAddr = iInetAddr.Cast( sockAddr );
+			}
+		}
+
+	iInetAddr.SetPort( aPortNum );
+	iAddress = aAddress;
+	iDNSName = aDNSName;
+	iPortNum = aPortNum;
+	iCipherSuites.Copy( aCipherSuite );
+	iProtocol.Copy( aProtocol );
+	iCipher = aCipher;
+	iPage.Copy( aPage );
+	iSimpleGet = aSimpleGet;
+	iTestEndDelay = aTestEndDelay;
+	iUseGenericSocket = aUseGenericSocket;
+	iEAPKeyDerivation = aEAPKeyDerivation;
+
+	// Print info to the log
+	iTestStep->Log( _L("*****Connecting to*****") );
+	iTestStep->Log( _L("%s:%d "), iAddress.PtrZ(), iPortNum ); 
+
+
+	// Open the socket
+	User::LeaveIfError( iSocket.Open( iSocketServ, KAfInet, KSockStream, KProtocolInetTcp ) );	
+	
+	if(iUseGenericSocket)
+		{
+		iGenericSocket = new(ELeave)CGenericSecureSocket<RSocket>(iSocket);
+		}
+
+	iTestPassed = ETrue;
+	iCiphersMatch = EFalse;
+
+	iRunState = ESocketConnected;
+	
+	// Open the socket
+	User::LeaveIfError( iInetAddr.Input( iAddress ));
+	iInetAddr.SetPort( iPortNum );
+
+	iTestStep->Log(_L("Connecting to %s:%d"), iAddress.PtrZ(), iPortNum );
+	iSocket.Connect( iInetAddr, iStatus );	
+
+	SetActive();
+	}
+
+void CTLSTest::SetConsole( CTestStepTls * aTestStep )
+	{
+	iTestStep = aTestStep;
+	}
+
+TBool CTLSTest::InUse()
+	{
+	return iInUse;
+	}
+
+TBool CTLSTest::TestingSite( const TDesC &aAddress, const TInt aPortNum )
+	{
+		TInt match = iAddress.Compare( aAddress );
+
+		if ( ( aPortNum == iPortNum ) && ( match == 0 ) && ( iInUse ) )
+			return ETrue ;
+		else 
+			return EFalse;
+	}
+
+void CTLSTest::HexDump(const TText* aHeader, const TText* aMargin, const TUint8* aPtr, TInt aLen)
+	{
+
+	TBuf<0x100> buf;
+	buf.SetLength(0);
+	TInt i = 0;
+	const TText* p = aHeader;
+	while (aLen>0)
+		{
+		TInt n = aLen>KHexDumpWidth ? KHexDumpWidth : aLen;
+		buf.AppendFormat(_L("%s%04x : "), p, i);
+		TInt j;
+		for (j=0; j<n; j++)
+			buf.AppendFormat(_L("%02x "), aPtr[i+j]);
+		while (j++<KHexDumpWidth)
+			buf.AppendFormat(_L("   "));
+		buf.AppendFormat(_L(" "));
+		for (j=0; j<n; j++)
+			{
+			TUint8 byteAsChar;
+			byteAsChar = aPtr[i+j]<32 || aPtr[i+j]>126 ? '.' : aPtr[i+j];
+			if ((byteAsChar == '%') || (byteAsChar == '<'))
+				byteAsChar = '.';
+			buf.AppendFormat(_L("%c"), byteAsChar );
+			}
+		iTestStep->Log(buf);
+		buf.SetLength(0);
+		aLen -= n;
+		i += n;
+		p = aMargin;
+		}
+	}
+
+
+
+TInt CTLSTest::GetCertInfo(const CX509Certificate& aSource)
+	{
+	TText margin = 0;
+	TText header = 0;
+
+	iTestStep->Log( _L("------Certificate Info------") );
+
+	iTestStep->Log( _L("FingerPrint") );
+	HexDump( &header, &margin, aSource.Fingerprint().Ptr(), aSource.Fingerprint().Length() );
+
+	iTestStep->Log( _L("SerialNumber") );
+	HexDump( &header, &margin, aSource.SerialNumber().Ptr(), aSource.SerialNumber().Length() );
+							   
+	const CSubjectPublicKeyInfo& publicKeyInfo = aSource.PublicKey();
+	iTestStep->Log( _L("PublicKeyInfo") );
+	HexDump( &header, &margin, publicKeyInfo.KeyData().Ptr(), publicKeyInfo.KeyData().Length() );
+
+	iTestStep->Log( _L("----------------------------") );
+
+	return KErrNone;
+	}
+
+
+TInt CTLSTest::KeyDerivationTests(TBool aSocketOpen)
+	{
+	if( aSocketOpen )
+		{
+		// Input should be no longer than 100 bytes
+		iTestStep->Log( _L("Attempt to get EAP Keys with too large an input descriptor") );
+		TBuf8<KEAPKeyLength> tooBig;
+		tooBig.Fill('X',101);
+		TInt err = iTlsSocket->GetOpt(KSoKeyingMaterial, KSolInetSSL, tooBig);
+		if(err != KErrArgument)
+			{
+			iTestStep->Log( _L("FAILED: Did not return KErrArgument.  Error: %d"), err );
+			if(err == KErrNone)
+				{
+				err = KErrGeneral;
+				}
+			return err;
+			}
+		iTestStep->Log( _L("Passed") );
+
+		// Descriptor should be of size to fit 128+64 bytes
+		iTestStep->Log( _L("Attempt to get EAP Keys with too small an input descriptor") );
+		TBuf8<KEAPKeyLength-5> tooSmall;
+		err = iTlsSocket->GetOpt(KSoKeyingMaterial, KSolInetSSL, tooSmall);
+		if(err != KErrArgument)
+			{
+			iTestStep->Log( _L("FAILED: Did not return KErrArgument.  Error: %d"), err );
+			if(err == KErrNone)
+				{
+				err = KErrGeneral;
+				}
+			return err;
+			}
+		iTestStep->Log( _L("Passed") );
+
+		// Should be able to generate key
+		iTestStep->Log( _L("Attempt to get EAP Keys with a valid input descriptor") );
+		TBuf8<KEAPKeyLength+5> retVal;
+		err = iTlsSocket->GetOpt(KSoKeyingMaterial, KSolInetSSL, retVal);
+		if(err != KErrNone)
+			{
+			iTestStep->Log( _L("FAILED: Call failed with error: %d"), err );
+			if(err == KErrNone)
+				{
+				err = KErrGeneral;
+				}
+			return err;
+			}
+		if(retVal.Length() != KEAPKeyLength)
+			{
+			iTestStep->Log( _L("FAILED: Call OK but Key returned is the wrong size.  Expected=%d Actual=%d"), 128+64, retVal.Length() );
+			err = KErrGeneral;
+			return err;
+			}
+		iTestStep->Log( _L("Passed") );
+		}
+	else
+		{
+		// Can only generate keys whilst have an open socket that has completed the SSL handshake
+		iTestStep->Log( _L("Attempt to get EAP Keys before handshake/after socket closed") );
+		TBuf8<KEAPKeyLength> retVal;
+		TInt err = iTlsSocket->GetOpt(KSoKeyingMaterial, KSolInetSSL, retVal);
+		if(err != KErrNotReady)
+			{
+			iTestStep->Log( _L("FAILED: Did not return KErrNotReady.  Error: %d"), err );
+			if(err == KErrNone) err = KErrGeneral;
+			return err;
+			}
+		iTestStep->Log( _L("Passed") );
+		}
+
+	return KErrNone;
+	}