networksecurity/tlsprovider/Test/tlstest2/handshakestep.cpp
changeset 0 af10295192d8
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file handshakestep.cpp
       
    18  @internalTechnology
       
    19 */
       
    20 #include "handshakestep.h"
       
    21 
       
    22 #include <tlsprovinterface.h>
       
    23 
       
    24 
       
    25 _LIT(KWebAddress,"WebAddress");
       
    26 _LIT(KWebPage,"WebPage");
       
    27 _LIT(KPortNum,"PortNum");
       
    28 _LIT(KExpectedFinalCipher, "ExpectedFinalCipherSuit");
       
    29 _LIT(KExpectedSetCipherError, "ExpectedSetCipherError");
       
    30 _LIT(KExpectedHandshakeError, "ExpectedHandshakeError");
       
    31 _LIT8(KSimpleGet, "GET /");
       
    32 _LIT8(KGetTail, " HTTP/1.0\r\n\r\n");
       
    33 _LIT8(KExpectedPageContent, "Hello world");
       
    34 _LIT8(KPSK_IDENTITY, "Client_identity");
       
    35 _LIT8(KPSK_KEY, "0123456789"); 
       
    36 _LIT(KNumServerNames, "NumServerNames");
       
    37 _LIT(KServerNameBase, "ServerName");
       
    38 
       
    39 
       
    40 
       
    41 // CertRequest tester active.
       
    42 CHandShakeTesterActive::CHandShakeTesterActive( CTestExecuteLogger& aLogger ) : 
       
    43    CActive( EPriorityStandard ),
       
    44    iLogger( aLogger )
       
    45 	{
       
    46 	CActiveScheduler::Add( this );
       
    47 	}
       
    48 	
       
    49 CHandShakeTesterActive::~CHandShakeTesterActive()
       
    50 	{
       
    51    
       
    52 	}
       
    53 
       
    54 /** This is the core of the test, it handshakes a TLS test server, if succesfull it
       
    55     requests a web page from the TLS server, if the page was received succesfully it
       
    56     checks its content. Finally it checks the cipher suite used is what was expected. 
       
    57 	@param None
       
    58 	@return TVeredic EPass if all test sequence was completed an succesful.
       
    59 	*/
       
    60 TVerdict CHandShakeTesterActive::DoSecureConnectionTestL(CHandShakeStep* master)
       
    61 	{
       
    62 	TInt error_Returned;
       
    63 	
       
    64 	iStepPointer = master;
       
    65 	// Negociates secure connection.
       
    66 	error_Returned = HandShakeL();
       
    67 	if (error_Returned != iStepPointer->iExpectedHandshakeError)
       
    68 		{
       
    69 		ERR_PRINTF3(_L("Handshake failed, Expected error: %D Received Error: %D"), iStepPointer->iExpectedHandshakeError, error_Returned);
       
    70 		return EFail;
       
    71 		} 
       
    72 	else if( error_Returned != KErrNone) 
       
    73 		{
       
    74 		// An error was received but it was expected, communication can not continue as handshake failed.
       
    75 		ERR_PRINTF2(_L("Test abbreviated as expected handshake error %D was received."), error_Returned);
       
    76 		return EPass;  // Terminates test.	
       
    77 		}
       
    78 		
       
    79 	// request a web page to server.
       
    80 	if (MakePageRequest() != KErrNone)
       
    81 		{
       
    82 		ERR_PRINTF1(_L("Page request failed"));
       
    83 		return EFail;
       
    84 		} 
       
    85 
       
    86 	// Invokes appropiate methods to receive web page.
       
    87 	GetPageReceivedL();
       
    88 		
       
    89 	//	Verify that the page received has the expected content.
       
    90  	if (VerifyPageReceived() != KErrNone)
       
    91 		{
       
    92 		ERR_PRINTF1(_L("Page received not what expected"));
       
    93 		return EFail;
       
    94 		}   
       
    95 		
       
    96 	// debug, outputs page received to file.
       
    97 	// OutputPageToFileL(iStepPointer->iRcvPage); // debug 	
       
    98 		
       
    99 	// 	Check that the cipher suite negociated on handshake is the one
       
   100 	//  expected by the tester.
       
   101 	if (VerifyFinalCipherUsed() != KErrNone)
       
   102 		{
       
   103 		ERR_PRINTF1(_L("The final cipher Suite used not what expected"));
       
   104 		return EFail;
       
   105 		}   
       
   106 	return EPass; 
       
   107 	}
       
   108 
       
   109 void CHandShakeStep::GetPskL(const HBufC8 */*aPskIdentityHint*/, HBufC8 *&aPskIdentity, HBufC8 *&aPskKey)
       
   110 	{   
       
   111     
       
   112 	aPskIdentity = KPSK_IDENTITY().AllocL();
       
   113 	aPskKey = KPSK_KEY().AllocL();
       
   114 
       
   115 	return;
       
   116 	}
       
   117 
       
   118 /** Establishes secure connection to TLS test server by using 
       
   119     CSecureSocket::StartClientHandshake method.
       
   120 	@param None
       
   121 	@return TInt ,return error code returned by status of StartClientHandshake method.
       
   122 	*/
       
   123 TInt CHandShakeTesterActive::HandShakeL()
       
   124 	{
       
   125 	_LIT(KTLS1,"TLS1.0");
       
   126 	iStepPointer->iTlsSocket = CSecureSocket::NewL( iStepPointer->iSocket, KTLS1 );
       
   127 
       
   128 	// Clears any previous options
       
   129 	iStepPointer->iTlsSocket->FlushSessionCache();
       
   130 
       
   131 	// Sets Call back if needed.
       
   132 	iStepPointer->SetPskL();
       
   133 	
       
   134 	// Sets Null cipher if needed.
       
   135 	iStepPointer->SetNullCipherL();
       
   136 
       
   137 	// No client authentication or dialogs for this test.
       
   138 	iStepPointer->iTlsSocket->SetClientCertMode(EClientCertModeIgnore);
       
   139 	iStepPointer->iTlsSocket->SetDialogMode(EDialogModeUnattended);
       
   140 	
       
   141 	// Sets Server Name
       
   142 	if(iStepPointer->iUseServerNames)
       
   143 		{
       
   144 		TPckgC<CDesC8Array *> serverNamePkg(iStepPointer->iServerNamesArray);
       
   145 		User::LeaveIfError(iStepPointer->iTlsSocket->SetOpt(KSoServerNameIndication, KSolInetSSL, serverNamePkg));	
       
   146 		}
       
   147 
       
   148 	// Alternatively dialog mode attended could be used for manual tests.
       
   149 	// 	iStepPointer->iTlsSocket->SetClientCertMode(EClientCertModeOptional); // debug
       
   150 	// 	iStepPointer->iTlsSocket->SetDialogMode(EDialogModeAttended); // debug
       
   151 
       
   152 	// Set cipher suits to be presented in client hello message for handshake.
       
   153 	TInt setCipherSuitesError;
       
   154 	setCipherSuitesError = iStepPointer->iTlsSocket->SetAvailableCipherSuites( *(iStepPointer->iBufCipherSuitesFromIni));   
       
   155 
       
   156 	if ( setCipherSuitesError != iStepPointer->iExpectedSetSuitesError)
       
   157 		{
       
   158 		ERR_PRINTF3(_L("The SetAvailableCipherSuites method returned error: %d but error expected was: %d"), setCipherSuitesError , iStepPointer->iExpectedSetSuitesError);
       
   159 		User::Leave(KErrGeneral);	
       
   160 		}
       
   161 	// start the handshake 
       
   162 	iStepPointer->iTlsSocket->StartClientHandshake( iStatus);  
       
   163 	iState = ESecureConnected; 
       
   164 	SetActive();
       
   165 	CActiveScheduler::Start(); 
       
   166 
       
   167 	return iStatus.Int();  
       
   168 	}	
       
   169 
       
   170 /** Requests web page to TLS test server. 
       
   171 	@param None
       
   172 	@return TInt ,return error code returned by status of CSecureSocket::Send method.
       
   173 	*/
       
   174 TInt  CHandShakeTesterActive::MakePageRequest()
       
   175 	{
       
   176 	// Create a GET request
       
   177 	iStepPointer->iSndBuffer += KSimpleGet;
       
   178 	iStepPointer->iSndBuffer += iStepPointer->iConnectSettings.iPage;
       
   179 	iStepPointer->iSndBuffer += KGetTail;
       
   180 
       
   181 	// Send the request
       
   182 	iStepPointer->iTlsSocket->Send( iStepPointer->iSndBuffer, iStatus, iStepPointer->iBytesSent );
       
   183 	iState = EGetRequestSent;
       
   184 	SetActive();
       
   185 	CActiveScheduler::Start();
       
   186 	return iStatus.Int();  
       
   187 	}
       
   188 
       
   189 /** Receives web page previously requested to TLS test server. 
       
   190 	@param None
       
   191 	@return TInt ,return error code returned by status of CSecureSocket::Recv method.
       
   192 	*/
       
   193 void CHandShakeTesterActive::GetPageReceivedL()
       
   194 	{
       
   195 	// check for unexpected error.
       
   196 	if(iStatus != KErrEof && iStatus != KErrNone)
       
   197 		{
       
   198 		ERR_PRINTF2(_L("Unexpected error received on get page requested: %d"), iStatus.Int());
       
   199 		User::Leave(iStatus.Int());		
       
   200 		}
       
   201 	
       
   202 	// First receive invoked (status equals to KErrNone)
       
   203 	if(iStatus == KErrNone) 
       
   204 		{
       
   205 		iStepPointer->iRcvBuffer.SetLength( 0 );
       
   206 		iStepPointer->iTlsSocket->Recv( iStepPointer->iRcvBuffer, iStatus );
       
   207 		iState = EGetPageReceived;
       
   208 		SetActive();
       
   209 		CActiveScheduler::Start();
       
   210 		INFO_PRINTF1(_L("New packet received (for page request)"));
       
   211 		// Append received packet to page received so far. 
       
   212 		iStepPointer->iRcvPage.Append(iStepPointer->iRcvBuffer);	
       
   213 		}
       
   214 	
       
   215 	// KErrEof or buffer with length zero  received.
       
   216 	if(iStatus == KErrEof || iStepPointer->iRcvBuffer.Length() == 0)
       
   217 		{
       
   218 		// Tells the state machine to stop requesting for more packets.
       
   219 		iState = EIdle;
       
   220 		return;
       
   221 		}
       
   222 
       
   223 	}
       
   224 
       
   225 /** Compares the received page content against expected content.
       
   226     At present the expected content is hardcoded in constant KExpectedPageContent,
       
   227     if more sofisticated web pages checkings are needed test code may need to be modified to
       
   228     read expected content from binary file.  
       
   229 	@param None
       
   230 	@return KErrNone if webpage is what is expected , otherwise returns KErrGeneral.
       
   231 	*/	
       
   232 TInt CHandShakeTesterActive::VerifyPageReceived()
       
   233 	{
       
   234 	if( iStepPointer->iRcvPage == KExpectedPageContent)
       
   235 		{
       
   236 		return KErrNone;
       
   237 		}
       
   238 	else
       
   239 		{
       
   240 		return KErrGeneral;
       
   241 		}
       
   242 	}
       
   243 
       
   244 /** Checks that the cipher suit agreed in the TLS handshake is what the tester
       
   245 	was expecting.
       
   246    	@param None
       
   247 	@return KErrNone if final cipher suite is what is expected , otherwise returns KErrGeneral.
       
   248 	*/
       
   249 TInt CHandShakeTesterActive::VerifyFinalCipherUsed()
       
   250 	{
       
   251 	TBuf8<2>	finalCipherBuffer; 
       
   252 	TInt    	finalCipher=0;
       
   253 	iStepPointer->iTlsSocket->CurrentCipherSuite(finalCipherBuffer);
       
   254 	// Converts two bytes buffer in single integer.
       
   255 	finalCipher += finalCipherBuffer[1];
       
   256 	finalCipher += (finalCipherBuffer[0] << 8);
       
   257 
       
   258 	if( iStepPointer->iExpectedFinalCipher == finalCipher)
       
   259 		{
       
   260 		return KErrNone;
       
   261 		}
       
   262 	else   
       
   263 		{
       
   264 		ERR_PRINTF3(_L("Used cipher: %d. Expected cipher: %d"), finalCipher, iStepPointer->iExpectedFinalCipher );
       
   265 		return KErrGeneral;
       
   266 		}
       
   267 	}
       
   268 	
       
   269 void CHandShakeTesterActive::OutputPageToFileL(const TDesC8& aPageReceived)
       
   270 	{
       
   271 	RFs	fs;
       
   272 	User::LeaveIfError (fs.Connect());
       
   273 	TDriveUnit sysDrive (RFs::GetSystemDrive());
       
   274 	TBuf<128> rName (sysDrive.Name());;
       
   275 	rName.Append(_L("\\tlstest2\\myresults\\"));
       
   276 			
       
   277 	TInt err = fs.MkDir(rName);
       
   278 	if (err != KErrNone && err != KErrAlreadyExists)
       
   279 		{
       
   280 		// This line will panic if directory does not exist.
       
   281 		User::Leave(err);	
       
   282 		}
       
   283 				
       
   284 	RFile file;
       
   285 	CleanupClosePushL(file);
       
   286 	
       
   287 	_LIT(KExtension, ".html");
       
   288 	rName.Append(iStepPointer->ConfigSection());
       
   289 	rName.Append(KExtension);
       
   290 	rName.LowerCase();
       
   291 	User::LeaveIfError(file.Replace(fs, rName, EFileWrite | EFileStream));
       
   292 	User::LeaveIfError(file.Write(aPageReceived));
       
   293 	CleanupStack::PopAndDestroy(&file);
       
   294 	fs.Close ();
       
   295 	}
       
   296 
       
   297 TInt CHandShakeTesterActive::RunError(TInt aError)
       
   298 	{
       
   299 	iRunError = aError;
       
   300 	CActiveScheduler::Stop();
       
   301 	return KErrNone;
       
   302 	}
       
   303 
       
   304 
       
   305 
       
   306 /** RunL method used for all asyncronous requests made by test code.
       
   307    	*/
       
   308 void CHandShakeTesterActive::RunL()
       
   309 	{
       
   310 		iRunError =KErrNone;
       
   311 	
       
   312 		User::LeaveIfError(iStatus.Int());
       
   313 	
       
   314 		switch(iState)
       
   315 			{
       
   316 			case EIdle:
       
   317 				CActiveScheduler::Stop();
       
   318 				break;
       
   319 			
       
   320 			case ESecureConnected:
       
   321 				INFO_PRINTF1(_L(" secure connection made "));
       
   322 				iState = EIdle;
       
   323 				CActiveScheduler::Stop();
       
   324 				break;
       
   325 			case EGetRequestSent:
       
   326 				INFO_PRINTF1(_L(" Page requested "));
       
   327 				iState = EIdle;
       
   328 				CActiveScheduler::Stop();
       
   329 				break; 
       
   330 			case EGetPageReceived:
       
   331 				// Keeps getting packages until KErrEof is received.  
       
   332 				GetPageReceivedL();
       
   333 				// This line will be reach only after all packages received.
       
   334 				CActiveScheduler::Stop();
       
   335 				break; 
       
   336 			default:
       
   337 				{
       
   338 				INFO_PRINTF1(_L("HandShakeTesterActive: State corrupted."));
       
   339 				User::Leave(KErrCorrupt);
       
   340 				}
       
   341 			} 
       
   342 	return; 
       
   343 	}
       
   344 
       
   345 CHandShakeStep::CHandShakeStep()
       
   346 	{
       
   347 	SetTestStepName(KHandShakeTestStep);
       
   348 	}
       
   349 
       
   350 CHandShakeStep::~CHandShakeStep()
       
   351 	{
       
   352 	delete iBufCipherSuitesFromIni;
       
   353 	iSndBuffer.Close();
       
   354 	iRcvBuffer.Close();	
       
   355 	iRcvPage.Close();
       
   356 	if (iActiveObjTest)
       
   357 		{
       
   358 		delete iActiveObjTest;
       
   359 		}
       
   360 	}
       
   361 
       
   362 /** Test preamble reads all ini values needed for test, these are:
       
   363  	NumCipherSuites: (int) The number of cipher suit to be included in client hello message.
       
   364    	CipherSuiteX: (hex) individual cipher suite to be included in client hello message.
       
   365 	WebAddress: (string) address of the test server could be decimal doted or human readable.
       
   366 	WebPage: (string) Test page to be requested to test server.
       
   367 	PortNum: (int) listening port used by test server.
       
   368 	ExpectedFinalCipherSuit: (hex) The cipher suite that is expected to be adopted on hnadshake.
       
   369 	UsePsk: (Bool) Use to indicate if optional PSK cipher suites are to be included in list 
       
   370 	of cipher suites send client hello message. 	
       
   371 	*/
       
   372 TVerdict CHandShakeStep::doTestStepPreambleL()
       
   373 	{
       
   374 	// Reads cipher suites to be sent in client hello message.
       
   375 	iBufCipherSuitesFromIni = ReadCipherSuitesL();
       
   376 
       
   377 	// Reads web address, this value is mandatory.
       
   378 	TPtrC   webAddress;
       
   379 	if(GetStringFromConfig(ConfigSection(), KWebAddress, webAddress))
       
   380 		{
       
   381 		iConnectSettings.iAddress = webAddress;
       
   382 		}
       
   383 	else
       
   384 		{
       
   385 		ERR_PRINTF1(_L("Failed to read web address value from INI file."));
       
   386 		User::Leave(KErrNotFound);
       
   387 		}
       
   388 
       
   389 	// Reads page web to be requested, this value is mandatory
       
   390 	TPtrC   page;
       
   391 	if(GetStringFromConfig(ConfigSection(), KWebPage, page))
       
   392 		{
       
   393 		iConnectSettings.iPage.Copy(page) ;
       
   394 		}
       
   395 	else
       
   396 		{
       
   397 		ERR_PRINTF1(_L("Failed to read page value from INI file."));
       
   398 		User::Leave(KErrNotFound);
       
   399 		}
       
   400 
       
   401 	// Reads port, this value is mandatory
       
   402 	TInt   portNum;
       
   403 	if(GetIntFromConfig(ConfigSection(), KPortNum, portNum))
       
   404 		{
       
   405 		iConnectSettings.iPortNum = portNum;
       
   406 		}
       
   407 	else
       
   408 		{
       
   409 		ERR_PRINTF1(_L("Failed to read Port Number from INI file"));
       
   410 		User::Leave(KErrNotFound);
       
   411 		}
       
   412 
       
   413 	// Reads expected final cipher suits, mandatory value
       
   414 	TInt cipher;	
       
   415 	if(GetHexFromConfig(ConfigSection(), KExpectedFinalCipher, cipher))
       
   416 		{
       
   417 		iExpectedFinalCipher = cipher;
       
   418 		}
       
   419 	else
       
   420 		{
       
   421 		ERR_PRINTF1(_L("Failed to read Expect final cipher value from INI file."));
       
   422 		User::Leave(KErrNotFound);
       
   423 		}
       
   424 		
       
   425 	// Reads expected set cipher suites error, optional value
       
   426 	TInt expectedSetSuitesError;	
       
   427 	if(GetIntFromConfig(ConfigSection(), KExpectedSetCipherError, expectedSetSuitesError))
       
   428 		{
       
   429 		iExpectedSetSuitesError = expectedSetSuitesError;
       
   430 		}
       
   431 	else
       
   432 		{
       
   433 		iExpectedSetSuitesError = KErrNone; 
       
   434 		}
       
   435 		
       
   436 	// Reads expected handshake  error, optional value
       
   437 	TInt expectedHandshakeError;	
       
   438 	if(GetIntFromConfig(ConfigSection(), KExpectedHandshakeError, expectedHandshakeError))
       
   439 		{
       
   440 		iExpectedHandshakeError = expectedHandshakeError;
       
   441 		}
       
   442 	else
       
   443 		{
       
   444 		iExpectedHandshakeError = KErrNone; 
       
   445 		}
       
   446 		
       
   447 
       
   448 	// Initialises send and receive buffers
       
   449 	iSndBuffer.CreateL(KSendBufferSize);
       
   450 	iRcvBuffer.CreateL(KReceiveBufferSize);
       
   451 	iRcvPage.CreateL(KReceiveBufferSize * 8); // Assumes 8 packages will be enough
       
   452 		
       
   453 	// Reads PSK options (optional)
       
   454 	TBool option;	
       
   455 	if(GetBoolFromConfig(ConfigSection(), KUsePsk, option))
       
   456 		{
       
   457 		iUsePsk = option;
       
   458 		}
       
   459 	else
       
   460 		{
       
   461 		iUsePsk = EFalse;
       
   462 		} 
       
   463 		
       
   464 	// Reads Null cipher options (optional)
       
   465  	TBool nullCipher;	
       
   466 	if(GetBoolFromConfig(ConfigSection(), KUseNullCipher, nullCipher))
       
   467 		{
       
   468 		iUseNullCipher = nullCipher;
       
   469 		}
       
   470 	else
       
   471 		{
       
   472 		iUseNullCipher = EFalse;
       
   473 		}  
       
   474 	
       
   475 	// Read server names from INI file.	
       
   476 	iServerNamesArray = ReadServerNamesL();
       
   477 		
       
   478 	return EPass;
       
   479 	}
       
   480 
       
   481 TVerdict CHandShakeStep::doTestStepL()
       
   482 	{
       
   483 	doTestL();
       
   484 	return TestStepResult();
       
   485 	}
       
   486 
       
   487 
       
   488 TVerdict CHandShakeStep::doTestL()
       
   489 	{
       
   490 	TVerdict testResult;
       
   491     SetTestStepResult(EFail); 
       
   492 
       
   493 	// Instantiates scheduler
       
   494  	iSched=new(ELeave) CActiveScheduler; 
       
   495     CleanupStack::PushL(iSched);  
       
   496 	CActiveScheduler::Install(iSched);
       
   497 	
       
   498 	// Initialises and connects the RSocket
       
   499 	ConnectL();
       
   500     
       
   501 	// Creates active tester object which will deal will CSecureSocket instance 
       
   502 	iActiveObjTest = new (ELeave) CHandShakeTesterActive(Logger());
       
   503 	CleanupStack::PushL(iActiveObjTest);
       
   504 	
       
   505 	// Creates secure socket and start client handshake.
       
   506  	testResult = iActiveObjTest->DoSecureConnectionTestL(this);
       
   507 	
       
   508 	// Deletes and closes all production code been tested.
       
   509  	CloseConnection();
       
   510 
       
   511 	CleanupStack::PopAndDestroy(iActiveObjTest);
       
   512 	iActiveObjTest = NULL;
       
   513 	CleanupStack::PopAndDestroy(iSched);
       
   514 	iSched=NULL;
       
   515     
       
   516     SetTestStepResult(testResult);
       
   517 	return TestStepResult();
       
   518 	}
       
   519 
       
   520 
       
   521 void  CHandShakeStep::SetPskL()
       
   522 	{
       
   523 
       
   524 	if(iUsePsk)
       
   525 		{
       
   526 		TPckgBuf<MSoPskKeyHandler *> pskConfigPkg;
       
   527 		pskConfigPkg() = this;
       
   528 		User::LeaveIfError(iTlsSocket->SetOpt(KSoPskConfig, KSolInetSSL, pskConfigPkg));
       
   529 		}
       
   530 
       
   531 	}	
       
   532 	
       
   533 void  CHandShakeStep::SetNullCipherL()
       
   534 	{
       
   535 	
       
   536 		if(iUseNullCipher)
       
   537  		{
       
   538  		User::LeaveIfError(iTlsSocket->SetOpt(KSoEnableNullCiphers, KSolInetSSL, ETrue));
       
   539  		}
       
   540 	
       
   541 	}
       
   542 
       
   543 
       
   544 void CHandShakeStep::CloseConnection()
       
   545 	{
       
   546 
       
   547 	// Clean up
       
   548 	iSocket.CancelAll();
       
   549 	if(iTlsSocket)
       
   550 		{
       
   551 		iTlsSocket->CancelAll();
       
   552 		iTlsSocket->Close();
       
   553 		delete iTlsSocket;
       
   554 		iTlsSocket =0;
       
   555 		}
       
   556 
       
   557 	iSocket.Close();
       
   558 
       
   559 	}
       
   560 
       
   561 	
       
   562 void CHandShakeStep::ConnectL()
       
   563 	{
       
   564 
       
   565 	TRequestStatus rs;
       
   566 	RHostResolver hostResolver;
       
   567 	
       
   568 	// Connect the socket server
       
   569 	User::LeaveIfError( iSocketServ.Connect());	
       
   570 	
       
   571 //	User::LeaveIfError( iSocketServ.Connect());	// debug
       
   572 
       
   573 	// Interpret server address
       
   574 	if (iInetAddr.Input(iConnectSettings.iAddress) != KErrNone)
       
   575 		// Success if already in dotted-decimal format
       
   576 		{
       
   577 		// Connect to a host resolver (for DNS resolution) - happens sychronously
       
   578 		TInt retVal = hostResolver.Open( iSocketServ, KAfInet, KProtocolInetTcp);
       
   579 		
       
   580 		if(retVal != KErrNone)
       
   581 			{
       
   582 			ERR_PRINTF2(_L("Failed to open host resolver, Error:%d"),retVal);
       
   583 			User::Leave(KErrGeneral);
       
   584 			} 	 
       
   585 
       
   586 		CleanupClosePushL(hostResolver);
       
   587 
       
   588 		// Try to resolve symbolic name
       
   589 		TNameEntry nameEntry;
       
   590 
       
   591 		retVal = hostResolver.GetByName( iConnectSettings.iAddress, nameEntry );
       
   592 		if(retVal != KErrNone)
       
   593 			{
       
   594 			ERR_PRINTF2(_L("Failed to get name from host resolver, Error:%d"),retVal);
       
   595 			User::Leave(KErrGeneral);
       
   596 			} 
       
   597 
       
   598 		TSockAddr sockAddr = nameEntry().iAddr;
       
   599 		iInetAddr = iInetAddr.Cast( sockAddr );
       
   600 		
       
   601 		CleanupStack::PopAndDestroy(&hostResolver); 
       
   602 		}
       
   603 	// Store other connection parameters
       
   604 	iInetAddr.SetPort( iConnectSettings.iPortNum );
       
   605 
       
   606 	// Open a TCP socket
       
   607 	User::LeaveIfError( iSocket.Open( iSocketServ, KAfInet, KSockStream, KProtocolInetTcp ) );	
       
   608 
       
   609 	// Connect to the server, asynchronously
       
   610 	iSocket.Connect( iInetAddr, rs );
       
   611 
       
   612 	User::WaitForRequest( rs );
       
   613 	// Print status	
       
   614 	if(rs.Int() != KErrNone)
       
   615 		{
       
   616 		INFO_PRINTF4(_L("Connection failed to %S port:%d Error: %d"), &iConnectSettings.iAddress, iConnectSettings.iPortNum, rs.Int() );
       
   617 		User::Leave(KErrCouldNotConnect);
       
   618 		}
       
   619 	else
       
   620 		{
       
   621 		INFO_PRINTF3(_L("Connected to %S port:%d"), &iConnectSettings.iAddress, iConnectSettings.iPortNum );
       
   622 		}
       
   623 	}
       
   624 	
       
   625 /** Read list of cipher to be included in client hello message.
       
   626 @param None
       
   627 @return HBufC8 list of cipher suites
       
   628 */
       
   629 
       
   630 HBufC8* CHandShakeStep::ReadCipherSuitesL()
       
   631 	{
       
   632 	
       
   633 	TInt numCipherSuites;
       
   634 	TName  fCipherSuite;
       
   635 	TInt   iniCipherSuite;  
       
   636 	HBufC8* allSuites = NULL;
       
   637 		
       
   638 	if(GetIntFromConfig(ConfigSection(),KNumCipherSuites,numCipherSuites))
       
   639 		{
       
   640 		// Each cipher suite uses 2 bytes
       
   641 		allSuites = HBufC8::NewMaxL( numCipherSuites * 2);
       
   642 		TPtr8 ptr = allSuites->Des(); 
       
   643 	
       
   644 		for(TInt index = 1;index <= numCipherSuites ; ++index)
       
   645 			{
       
   646 			fCipherSuite.Format(_L("%S%d"), &KCipherSuiteBase, index);
       
   647 			if(GetHexFromConfig(ConfigSection(), fCipherSuite,iniCipherSuite))
       
   648 				{
       
   649 				// Two bytes for each cipher suite
       
   650 				ptr[(index - 1) * 2] =	( ( iniCipherSuite & 0xFF00) >> 8);
       
   651 				ptr[( (index - 1) * 2 ) + 1] =	iniCipherSuite & 0xFF;
       
   652 				}
       
   653 			}
       
   654 		}
       
   655 	
       
   656 	return allSuites;
       
   657 	}  
       
   658 
       
   659 /** Read list of server to be included in client hello message form INI file.
       
   660 @param None
       
   661 @return CDesC8ArrayFlat list of server names
       
   662 */
       
   663 
       
   664 
       
   665 CDesC8ArrayFlat * CHandShakeStep::ReadServerNamesL()
       
   666 	{
       
   667  
       
   668 	TInt numServerNames;
       
   669 	TName  fServerName;
       
   670 	TPtrC  serverName;  
       
   671 	CDesC8ArrayFlat* allServerNames = NULL;   
       
   672 	
       
   673 	if(GetIntFromConfig(ConfigSection(),KNumServerNames,numServerNames))
       
   674 		{
       
   675 		
       
   676 		if( numServerNames >0)
       
   677 			{
       
   678 			iUseServerNames = ETrue;
       
   679 			
       
   680 			allServerNames = new(ELeave) CDesC8ArrayFlat(1);
       
   681 			CleanupStack::PushL(allServerNames);
       
   682 			
       
   683 			// Reads each server name and appends it to array.
       
   684 			for(TInt index = 1;index <= numServerNames ; ++index)
       
   685 				{
       
   686 				fServerName.Format(_L("%S%d"), &KServerNameBase, index);
       
   687 				if(GetStringFromConfig(ConfigSection(), fServerName, serverName))
       
   688 					{
       
   689 					HBufC8 *serverName8bited = HBufC8::NewMaxLC(serverName.Length());
       
   690 					serverName8bited->Des().Copy(serverName);
       
   691 		 			allServerNames->AppendL(serverName8bited->Des());
       
   692 		 			CleanupStack::PopAndDestroy(serverName8bited);
       
   693 					}
       
   694 				else
       
   695 					{
       
   696 					INFO_PRINTF2(_L("Could not found ServerName %d from INI file"), index );
       
   697 					User::Leave(KErrGeneral);	
       
   698 					}
       
   699 				}
       
   700 			CleanupStack::Pop(allServerNames);		
       
   701 			}
       
   702 	
       
   703 		}
       
   704 	else
       
   705 		{
       
   706 		iUseServerNames = EFalse; 	
       
   707 		}
       
   708 	 
       
   709 	return allServerNames;
       
   710 	}  
       
   711 	
       
   712 	
       
   713