networksecurity/tls/ts_tls/T_TLS_test.cpp
changeset 0 af10295192d8
child 20 7e41d162e158
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2003-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 #include "T_TLS_test.h"
       
    17 #include <e32svr.h>
       
    18 #include <ssl.h>
       
    19 
       
    20 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    21 #include <ssl_internal.h>
       
    22 #endif
       
    23 
       
    24 
       
    25 
       
    26 const TInt KHexDumpWidth = 16;
       
    27 const TInt KEAPKeyLength = 128+64;
       
    28 
       
    29 
       
    30 TInt CTLSTest::RunError( TInt aError )
       
    31 	{
       
    32 
       
    33 	iTestStep->Log( _L("RunL err %d"), aError );
       
    34 
       
    35 	if ( iTlsSocket )
       
    36 		{
       
    37 		iTlsSocket->Close();
       
    38 
       
    39 		delete iTlsSocket;
       
    40 		iTlsSocket = 0;
       
    41 
       
    42 		
       
    43 		}
       
    44 
       
    45 	iInUse = EFalse;
       
    46 
       
    47 	return KErrNone;
       
    48 	}
       
    49 
       
    50 CTLSTest* CTLSTest::NewL()
       
    51 	{
       
    52 	CTLSTest* self = new(ELeave) CTLSTest;
       
    53 	CleanupStack::PushL( self );
       
    54 	self->ConstructL();
       
    55 	CleanupStack::Pop();		
       
    56 	return self;
       
    57 	}
       
    58 
       
    59 // Constructor should also call the parent constructor to set the priority
       
    60 // of the active object.
       
    61 CTLSTest::CTLSTest() : CActive(0)
       
    62 	{
       
    63 	}
       
    64 
       
    65 CTLSTest::~CTLSTest()
       
    66 	{
       
    67 	// Cancel any outstanding request
       
    68 	Cancel();	
       
    69 
       
    70 	delete iTlsSocket;
       
    71 	delete iTlsSocket2;
       
    72 	delete iGenericSocket;
       
    73 
       
    74 	iTimer.Close();
       
    75 
       
    76 	// Close the resources in the reverse order
       
    77 	iHostResolver.Close();
       
    78 	iSocket.Close();
       
    79 	iSocketServ.Close();
       
    80 
       
    81 //	__UHEAP_MARK; 
       
    82 //	__UHEAP_MARKEND;
       
    83 	}
       
    84 
       
    85 void CTLSTest::ConstructL()
       
    86 	{
       
    87 
       
    88 	// Connect the socket server
       
    89 	User::LeaveIfError( iSocketServ.Connect() );
       
    90 	
       
    91 	// Create a local timer
       
    92 	User::LeaveIfError( iTimer.CreateLocal() );
       
    93 
       
    94 	// Connect to a host resolver
       
    95 	User::LeaveIfError( iHostResolver.Open( iSocketServ, KAfInet, KProtocolInetTcp ) );
       
    96 
       
    97 	iRunState = ESocketConnected;
       
    98 	iInUse = EFalse;
       
    99 
       
   100 	CActiveScheduler::Add( this );
       
   101 	}
       
   102 
       
   103 void CTLSTest::RunL()
       
   104 	{
       
   105 	THTTPMessage *iMyHTTP;
       
   106 	TInt err = KErrNone;
       
   107 #ifdef __WINS__
       
   108 	TText margin = 0;
       
   109 	TText header = 0;
       
   110 	TSockXfrLength aLen;
       
   111 #endif
       
   112 
       
   113 	switch ( iRunState )
       
   114 		{
       
   115 	case ESocketConnected:
       
   116 		{
       
   117 		iTestStep->Log( _L("STATE: ENotSecureConnected Status: %d"), iStatus.Int() );
       
   118 
       
   119 		// As the receive buffer is static, set it's length to 0 here,
       
   120 		// so if there is an error somewhere, the previous buffer's contents 
       
   121 		// wont be dumped to the log file again.
       
   122 		iRcvBuffer.SetLength( 0 );
       
   123 		iBytesRead = 0;
       
   124 		iTotalBytesRead = 0;
       
   125 		iFirstRunFlag = ETrue;
       
   126 
       
   127 		if ( iStatus != KErrNone )
       
   128 			{
       
   129 			iTestStep->Log( KStateErrConnected, iStatus.Int() );
       
   130 			iRunState = EConnectionClosed;
       
   131 			iTestPassed = EFalse;
       
   132 			iTimer.After( iStatus, 1000000 );
       
   133 			SetActive();			 
       
   134 			break;
       
   135 			}
       
   136 
       
   137 		//=========================================================
       
   138 		// Construct the Tls socket
       
   139 		if ( !iTlsSocket )
       
   140 			{
       
   141 			TInt lcode = KErrNone;
       
   142 			if(iUseGenericSocket)
       
   143 				{
       
   144 				iTestStep->Log( _L("Creating SecureSocket using Generic Socket") );
       
   145 				TRAP(lcode, iTlsSocket = CSecureSocket::NewL( *iGenericSocket, iProtocol ) );
       
   146 				}
       
   147 			else
       
   148 				{
       
   149 				iTestStep->Log( _L("Creating SecureSocket using RSocket") );
       
   150 				TRAP(lcode, iTlsSocket = CSecureSocket::NewL( iSocket, iProtocol ) );
       
   151 				}
       
   152 			if ( lcode )
       
   153 				{ 
       
   154 				iTestStep->Log( _L("Error creating secure socket: %d"), lcode );
       
   155 				iRunState = EConnectionClosed;
       
   156 				iTestPassed = EFalse;
       
   157 				iTimer.After( iStatus, 1000000 );
       
   158 				SetActive();			 
       
   159 				break;
       
   160 				}
       
   161 			}
       
   162 
       
   163 		//=========================================================
       
   164 
       
   165 		if( iEAPKeyDerivation )
       
   166 			{
       
   167 			if(KeyDerivationTests(EFalse) != KErrNone)
       
   168 				{
       
   169 				iRunState = EConnectionClosed;
       
   170 				iTestPassed = EFalse;
       
   171 				iTimer.After( iStatus, 1000000 );
       
   172 				SetActive();			 
       
   173 				break;
       
   174 				}
       
   175 			}
       
   176 
       
   177 
       
   178 		//======================================================================================
       
   179 		// Set any options before the handshake starts
       
   180 		if ( !iTlsSocket2 )
       
   181 			{
       
   182 			iTestStep->Log( _L("Flush session cache") );
       
   183 			iTlsSocket->FlushSessionCache();
       
   184 			}
       
   185 
       
   186 		//=========================================================
       
   187 		// Set the cipher suite list
       
   188 		if ( iCipherSuites.Length() > 1 )
       
   189 			{
       
   190 
       
   191 			// Create the buffer with the cipher suites
       
   192 			TBuf8<KCipherBufSize>	cipherBuf;
       
   193 //			TBuf8<KCipherBufSize>	iCipherSuites;
       
   194 			TBuf8<3>	tempBuf;
       
   195 			TInt	i;
       
   196 			TInt	value;
       
   197 			TInt	ret = KErrNone;
       
   198 			TInt	cCount = 0;			// used as an array index into the cipherBuf descriptor
       
   199 			TLex8	myLex;
       
   200 
       
   201 
       
   202 			// The cipher buffer will actually be the same length as the aCipherSuite passed in
       
   203 			// because it's in binary format with leading 0's.
       
   204 			cipherBuf.SetLength( iCipherSuites.Length() );
       
   205 
       
   206 			iTestStep->Log( _L("Cipher suites") );
       
   207 
       
   208 			for ( i=0; i<iCipherSuites.Length(); i+=2 )
       
   209 				{
       
   210 				// iCipherSuites contains a list of decimal values for each cipher suite that
       
   211 				// the client should offer to use. They are in a string format, so each decimal 
       
   212 				// value takes 2 bytes.
       
   213 				//
       
   214 				// Copy the 2 bytes of one value into a buffer so that it can be converted into
       
   215 				// a real decimal value;
       
   216 				tempBuf.SetLength( 2 );
       
   217 				tempBuf[0] = iCipherSuites[i];
       
   218 				tempBuf[1] = iCipherSuites[i+1];
       
   219 
       
   220 				myLex.Assign( tempBuf );
       
   221 				ret = myLex.Val( value );
       
   222 				if ( ret!=KErrNone )
       
   223 					{
       
   224 					break; // from for loop
       
   225 					}
       
   226 				iTestStep->Log( _L(":%X"), value );
       
   227 
       
   228 				if ( value == 99 )
       
   229 					{
       
   230 					cipherBuf[ cCount++ ] = 0xFF;
       
   231 					cipherBuf[ cCount++ ] = 0xFF;
       
   232 					}
       
   233 				else
       
   234 					{
       
   235 					// The actual cipher suite list that must be passed in the socket options
       
   236 					// is in a binary format of 0x0,0xCipherValue,0x0,CipherValue etc				
       
   237 					cipherBuf[ cCount++ ] = 0;
       
   238 					cipherBuf[ cCount++ ] = (unsigned char)value;
       
   239 					}
       
   240 
       
   241 				} // end of for loop
       
   242 
       
   243 			if ( cipherBuf.Length() )
       
   244 				{
       
   245 #ifdef __WINS__
       
   246 				iTestStep->Log( _L("Setting avilable cipher suites") );
       
   247 				HexDump( &header, &margin, &cipherBuf[0], cipherBuf.Length() );
       
   248 #endif
       
   249 
       
   250 				ret = iTlsSocket->SetOpt(KSoEnableNullCiphers, KSolInetSSL, ETrue);
       
   251 				
       
   252 				if ( ret != KErrNone )
       
   253 					{
       
   254 					TPtrC errorText = iTestStep->EpocErrorToText(ret);
       
   255 					iTestStep->Log( _L("Couldnt set NULL cipher suite option :%S  (%d)"),&errorText, ret );
       
   256 					iTestPassed = EFalse;
       
   257 					}
       
   258 
       
   259 				ret = iTlsSocket->SetAvailableCipherSuites( cipherBuf );
       
   260 
       
   261 				if ( ret != KErrNone )
       
   262 					{
       
   263 					TPtrC errorText = iTestStep->EpocErrorToText(ret);
       
   264 					iTestStep->Log( _L("Couldnt set available cipher suites error:%S  (%d)"),&errorText, ret );
       
   265 					iTestPassed = EFalse;
       
   266 					}
       
   267 				}
       
   268 
       
   269 			iTestStep->Log( _L("") );
       
   270 			} // end of if iciphersuites .length
       
   271 
       
   272 		// end of setting the cipher suite list
       
   273 		//=========================================================
       
   274 
       
   275 
       
   276 		TBuf<8> prot;
       
   277 		err = iTlsSocket->Protocol( prot );
       
   278     	
       
   279 		//*****************************************************
       
   280 		if ( !err )
       
   281 			{
       
   282 			iTestStep->Log( _L("Protocol set for use:") );
       
   283 			iTestStep->Log( prot );
       
   284 			}
       
   285 
       
   286 		err = iTlsSocket->SetProtocol( prot );
       
   287 		if ( err )
       
   288 			{
       
   289 			iTestStep->Log( _L("Failed to set Protocol for use: (%d)"),err );
       
   290 			}
       
   291 
       
   292 		// Set the domain name we're connecting to...
       
   293 		iStatus = iTlsSocket->SetOpt(KSoSSLDomainName,KSolInetSSL, iDNSName);
       
   294 		if ( iStatus != KErrNone )
       
   295 			{
       
   296 			iTestStep->Log( KStateErrReceivePage, iStatus.Int() );
       
   297 			iTestStep->Log( KStateErrReceivePage, iStatus.Int() );
       
   298 			iRunState = EConnectionClosed;
       
   299 			iTestPassed = EFalse;
       
   300 			iTlsSocket->Close();				 
       
   301 			iTimer.After( iStatus, 1000000 );
       
   302 			}
       
   303 			// end of setting options
       
   304 			//======================================================================================
       
   305 		else
       
   306 			{
       
   307 			//=========================================================
       
   308 			// start the handshake 
       
   309 			iTlsSocket->StartClientHandshake( iStatus );
       
   310 			//=========================================================
       
   311 			iRunState = ESecureConnected;
       
   312 			}
       
   313 
       
   314 		SetActive();
       
   315 		break;
       
   316 		}
       
   317 
       
   318 	case ESecureConnected:
       
   319 	case ESecureRenegotiated:
       
   320 		{
       
   321 		iTestStep->Log( _L("STATE: ESecureConnected/ESecureRenegotiated Status: %d"), iStatus.Int() );
       
   322 
       
   323 		// The secure connection has now been made.
       
   324 		// Send a get request for the page.
       
   325 
       
   326 		// Send the get request
       
   327 
       
   328 
       
   329 
       
   330 
       
   331 		if ( iStatus != KErrNone )
       
   332 			{
       
   333 			TPtrC errorText = iTestStep->EpocErrorToText(iStatus.Int());
       
   334 			iTestStep->Log( _L("ESecureConnected:%S %d"),&errorText, iStatus.Int() );
       
   335 			iTestStep->Log( KStateErrReceivePage, iStatus.Int() );
       
   336 			iTestStep->Log( KStateErrReceivePage, iStatus.Int() );
       
   337 			iRunState = EConnectionClosed;
       
   338 			iTestPassed = EFalse;
       
   339 			iTlsSocket->Close();				 
       
   340 			iTimer.After( iStatus, 1000000 );
       
   341 			SetActive();
       
   342 			break;
       
   343 			}
       
   344 		else
       
   345 			{
       
   346 			iTestStep->Log( _L("ESecureConnected:KErrNone %d"),iStatus.Int() );
       
   347 			}
       
   348 
       
   349 		TDes8* pSendDes;
       
   350 		if ( !iTlsSocket2 )
       
   351 			{
       
   352 			pSendDes = &iRcvBuffer;
       
   353 			iRcvBuffer.SetLength( iRcvBuffer.MaxLength() );
       
   354 			iTestStep->Log( _L("Sending %d bytes"), iRcvBuffer.Length() );
       
   355 			}
       
   356 		else
       
   357 			{
       
   358 			pSendDes = &iSndBuffer;
       
   359 			// Can a simple "GET /page.htm" request be used? 
       
   360 			if ( iSimpleGet )
       
   361 				{
       
   362 				iSndBuffer.Copy( _L("GET ") );
       
   363 				iSndBuffer.Append( iPage );
       
   364 				iSndBuffer.Append( _L("") );
       
   365 				iTestStep->Log( _L("Using simple get") );
       
   366 				}
       
   367 			else
       
   368 				{
       
   369 				// build and send a HTTP GET request to retrieve a page
       
   370 				iMyHTTP = new THTTPMessage;
       
   371 				iMyHTTP->Method(_L8("GET"));
       
   372 				iMyHTTP->URI( iPage );
       
   373 				iMyHTTP->AddHeaderField(_L8("Connection"),_L8("close"));
       
   374 				iMyHTTP->AddHeaderField(_L8("User-Agent"),_L8("SSL_TEST"));
       
   375 				iMyHTTP->AddHeaderField(_L8("Accept-Encoding"));
       
   376 				iMyHTTP->AddHeaderField(_L8("Accept"),_L8("*/*"));
       
   377 				iMyHTTP->GetHeader(iSndBuffer);
       
   378 				delete iMyHTTP;
       
   379 				}
       
   380 
       
   381 			iTestStep->Log( KLogSendingRequest );
       
   382 #ifdef __WINS__
       
   383 			HexDump( &header, &margin, &iSndBuffer[0], iSndBuffer.Length() );
       
   384 #endif
       
   385 			}
       
   386 
       
   387 		iRunState = iRunState == ESecureRenegotiated ? EGetRequestSentReneg : EGetRequestSent;
       
   388 
       
   389 		//=========================================================
       
   390 		// send the request
       
   391 		iTlsSocket->Send( *pSendDes, iStatus, iBytesSent );
       
   392 		//=========================================================	
       
   393 
       
   394 		if( iEAPKeyDerivation )
       
   395 			{
       
   396 			if(KeyDerivationTests(ETrue) != KErrNone)
       
   397 				{
       
   398 				iRunState = EConnectionClosed;
       
   399 				iTestPassed = EFalse;
       
   400 				iTimer.After( iStatus, 1000000 );
       
   401 				SetActive();			 
       
   402 				break;
       
   403 				}
       
   404 			}
       
   405 		
       
   406 		SetActive();
       
   407 		break;
       
   408 		}
       
   409 
       
   410 	case EGetRequestSent:
       
   411 	case EGetRequestSentReneg:
       
   412 		{
       
   413 
       
   414 		// The get request has been sent, can now try and receive the data
       
   415 
       
   416 		iTestStep->Log( _L("STATE: EGetRequestSent/EGetRequestSentReneg Status: %d"), iStatus.Int() );
       
   417 
       
   418 		if ( iStatus != KErrNone )
       
   419 			{
       
   420 			iTestStep->Log( _L("EGetRequestSent: %d"), iStatus.Int() );
       
   421 			iRunState = EConnectionClosed;
       
   422 			iTestPassed = EFalse;
       
   423 			iTlsSocket->Close();
       
   424 			iTimer.After( iStatus, 1000000 );
       
   425 			SetActive();			 
       
   426 			break;
       
   427 			}
       
   428 
       
   429 		// Before that, check which cipher suite has been negotiated.
       
   430 		TBuf8<4> buf; 
       
   431 		// no need to set descriptor length as in case with the old getopt, 
       
   432 		// CurrentCipherSuite will do that
       
   433 		err = iTlsSocket->CurrentCipherSuite( buf );
       
   434 		if ( err )
       
   435 			{
       
   436 			iTestStep->Log( _L("CurrentCipherSuite: %d"), err );
       
   437 			}
       
   438 		else
       
   439 			{
       
   440 #ifdef __WINS__
       
   441 			iTestStep->Log( _L("Cipher suite in use:") );
       
   442 			HexDump( &header, &margin, &buf[0], buf.Length() );
       
   443 #endif
       
   444 			}
       
   445 
       
   446 		// Get the servers certificate
       
   447 		const CX509Certificate *servCert = iTlsSocket->ServerCert();
       
   448 
       
   449 		if ( servCert )
       
   450 			{
       
   451 			GetCertInfo( *servCert );
       
   452 			}
       
   453 		else
       
   454 			{
       
   455 			iTestStep->Log( _L("No server certificate is available") );
       
   456 			}
       
   457 
       
   458 		// Get the protocol version string
       
   459 		TBuf<32> protocol;
       
   460 
       
   461 		err = iTlsSocket->Protocol( protocol );
       
   462 
       
   463 		if ( !err )
       
   464 			{
       
   465 			iTestStep->Log( _L("Protocol used in connection:") );
       
   466 			iTestStep->Log( protocol );
       
   467 			}
       
   468 
       
   469 		// New tests added as part of GT167 Zephyr.
       
   470 		// These tests are not meant to be in a logical order. They simply exercise the 
       
   471 		// Secure socket API. Logical ordering of the tests should happen in further
       
   472 		// development of the TLS test code and all supported APIS should be called/tested.
       
   473 
       
   474 		// Get the Client certificate
       
   475 		const CX509Certificate *clientCert = iTlsSocket->ClientCert();
       
   476 
       
   477 		if ( clientCert )
       
   478 			{
       
   479 			GetCertInfo( *clientCert );
       
   480 			}
       
   481 		else
       
   482 			{
       
   483 			iTestStep->Log( _L("No client certificate is available") );
       
   484 			}
       
   485 
       
   486 		// Get the Client cert mode. This API is NOT supported in client mode.
       
   487 		TClientCertMode certMode = iTlsSocket->ClientCertMode();
       
   488 		if ( certMode )
       
   489 			{
       
   490 			iTestStep->Log( _L("ClientCertMode() is not supported, Default value is: %d"), EClientCertModeIgnore );
       
   491 			iTestStep->Log( _L("Current mode setting is: %d"), certMode );			
       
   492 			}
       
   493 
       
   494 		iTestStep->Log( _L("Set Client Cert mode to: %d"), EClientCertModeOptional );
       
   495 		err = iTlsSocket->SetClientCertMode(EClientCertModeOptional);
       
   496 		if (err != KErrNotSupported)
       
   497 			{
       
   498 			iTestStep->Log( _L("SetClientCertMode Failed: %d"), err );
       
   499 			}
       
   500 
       
   501 		// Get the Dialog mode.
       
   502 		TDialogMode dialogMode = iTlsSocket->DialogMode();
       
   503 		iTestStep->Log( _L("Dialog mode setting is: %d"), dialogMode );			
       
   504 
       
   505 		// GetOpt() API: Current cipher suite option
       
   506 		TUint optionName = KSoCurrentCipherSuite;
       
   507 		TUint optionLevel = KSolInetSSL;
       
   508 		TBuf8<30> option;  // Note that the size of 30 is arbitrary.
       
   509 
       
   510 		TInt retValue = iTlsSocket->GetOpt(optionName, optionLevel, option);
       
   511 
       
   512 		// GetOpt() API: Available cipher cipher suites option
       
   513 		option.FillZ();		// reset the descriptor before reuse
       
   514 		option.Zero();	
       
   515 		optionName = KSoAvailableCipherSuites;
       
   516 		retValue = iTlsSocket->GetOpt(optionName, optionLevel, option);
       
   517 
       
   518 		// GetOpt() API: Dialog mode option
       
   519 		option.FillZ();		// reset the descriptor before reuse
       
   520 		option.Zero();	
       
   521 		optionName = KSoDialogMode;
       
   522 		retValue = iTlsSocket->GetOpt(optionName, optionLevel, option);
       
   523 
       
   524 		// GetOpt() API: Server certificate option
       
   525 		option.FillZ();		// reset the descriptor before reuse
       
   526 		option.Zero();	
       
   527 		optionName = KSoSSLServerCert;
       
   528 		//		retValue = iTlsSocket->GetOpt(optionName, optionLevel, option);
       
   529 
       
   530 		// SetOpt() API: Dialog mode option
       
   531 		option.FillZ();		// reset the descriptor before reuse
       
   532 		option.Zero();	
       
   533 		optionName = KSoDialogMode;
       
   534 		//		retValue = iTlsSocket->SetOpt(optionName, optionLevel, option);
       
   535 		// End of the addition of new tests for GT167 Zephyr
       
   536 
       
   537 		iRunState = iRunState == EGetRequestSent ? EDataReceived : EDataReceivedReneg;
       
   538 		if ( iTlsSocket2 )
       
   539 			{
       
   540 			iRcvBuffer.Zero();
       
   541 			iTlsSocket->Recv( iRcvBuffer, iStatus );
       
   542 			SetActive();
       
   543 			break;
       
   544 			}
       
   545 		iRcvBuffer.Zero();
       
   546 
       
   547 		if( iEAPKeyDerivation )
       
   548 			{
       
   549 			if(KeyDerivationTests(ETrue) != KErrNone)
       
   550 				{
       
   551 				iRunState = EConnectionClosed;
       
   552 				iTestPassed = EFalse;
       
   553 				iTlsSocket->Close();
       
   554 				iTimer.After( iStatus, 1000000 );
       
   555 				SetActive();			 
       
   556 				break;
       
   557 				}
       
   558 			}
       
   559 
       
   560 		// Fall through
       
   561 		}
       
   562 
       
   563 	case EDataReceived:
       
   564 	case EDataReceivedReneg:
       
   565 		{
       
   566 		iTestStep->Log( _L("STATE: EDataReceived/EDataReceivedReneg Status: %d"), iStatus.Int() );
       
   567 		iTestStep->Log( _L("EDataReceived length:%d"), iRcvBuffer.Length() );		
       
   568 
       
   569 		// Any error other than KErrEof means the test is a failure
       
   570 		if ( iStatus!=KErrNone && iStatus!=KErrEof)
       
   571 			{
       
   572 			// Close the socket neatly
       
   573 			iRunState = EConnectionClosed;
       
   574 			iTlsSocket->Close();
       
   575 			iTimer.After( iStatus, 1000000 );
       
   576 			SetActive();
       
   577 			break;	
       
   578 			}
       
   579 
       
   580 		// Log the received buffer
       
   581 		if ( iRcvBuffer.Length() )
       
   582 			{
       
   583 			iTestStep->Log( KLogBytesRead, iRcvBuffer.Length() );
       
   584 #ifdef __WINS__
       
   585 			HexDump( &header, &margin, &iRcvBuffer[0], iRcvBuffer.Length() );
       
   586 #endif
       
   587 			iTotalBytesRead += iRcvBuffer.Length();
       
   588 			if ( iStatus==KErrEof  )
       
   589 				{
       
   590 				iRunState = EConnectionClosed;
       
   591 				iTlsSocket->Close();
       
   592 				iTimer.After( iStatus, 1000000 );
       
   593 
       
   594 				if( iEAPKeyDerivation )
       
   595 					{
       
   596 					if(KeyDerivationTests(EFalse) != KErrNone)
       
   597 						{
       
   598 						iTestPassed = EFalse;
       
   599 						}
       
   600 					}
       
   601 				}				
       
   602 			else
       
   603 				{
       
   604 				//read again
       
   605 				iRcvBuffer.SetLength( 0 );
       
   606 				iTlsSocket->Recv( iRcvBuffer, iStatus );
       
   607 				}
       
   608 
       
   609 			SetActive(); 
       
   610 			break;
       
   611 			}
       
   612 		else
       
   613 			{
       
   614 			if ( iRunState == EDataReceived )
       
   615 				{
       
   616 				iRunState = ESecureRenegotiated;
       
   617 				iTestStep->Log( _L("******* Trying renegotiate *******") );
       
   618 				iTlsSocket->FlushSessionCache();
       
   619 				iTlsSocket->RenegotiateHandshake( iStatus );
       
   620 
       
   621 				if( iEAPKeyDerivation )
       
   622 					{
       
   623 					if(KeyDerivationTests(ETrue) != KErrNone)
       
   624 						{
       
   625 						iRunState = EConnectionClosed;
       
   626 						iTestPassed = EFalse;
       
   627 						iTlsSocket->Close();
       
   628 						iTimer.After( iStatus, 1000000 );
       
   629 						SetActive();			 
       
   630 						break;
       
   631 						}
       
   632 					}
       
   633 
       
   634 				SetActive(); 
       
   635 				break;
       
   636 				}
       
   637 			else
       
   638 				{
       
   639 				iRunState = EConnectionClosed;
       
   640 				}
       
   641 			}
       
   642 
       
   643 		// Fall through
       
   644 		}
       
   645 
       
   646 	case EConnectionClosed:
       
   647 		{
       
   648 		iTestStep->Log( _L("STATE: EConnectionClose Status: %d"), iStatus.Int() );
       
   649 
       
   650 		if ( iStatus != KErrNone )
       
   651 			{
       
   652 			iTestStep->Log( KStateErrFinished, iStatus.Int() );
       
   653 			iTestStep->Log( KStateErrFinished, iStatus.Int() );
       
   654 			iTestPassed = EFalse;
       
   655 			}
       
   656 
       
   657 		if ( iTotalBytesRead )
       
   658 			{
       
   659 			iTestStep->Log( KLogBytesRead, iTotalBytesRead );
       
   660 			}
       
   661 
       
   662 		if ( iTestPassed )
       
   663 			{
       
   664 			iTestStep->iTestStepResult = EPass;
       
   665 			iTestStep->Log( KLogTestPassed );
       
   666 			}
       
   667 		else
       
   668 			{
       
   669 			iTestStep->iTestStepResult = EFail;
       
   670 			iTestStep->Log( KLogTestFailed );
       
   671 			}
       
   672 
       
   673 		if ( iTlsSocket2 ) //to test abreviatted handshake
       
   674 			{
       
   675 			iInUse = EFalse;
       
   676 			iTlsSocket->Close();
       
   677 			delete iTlsSocket;
       
   678 			iTlsSocket =0;
       
   679 			delete iTlsSocket2;
       
   680 			iTlsSocket2 =0;
       
   681 			}
       
   682 		else if ( iTlsSocket )
       
   683 			{//keep the first instance live not to destroy the session cache
       
   684 			iTlsSocket2 = iTlsSocket;
       
   685 			iTlsSocket = NULL;
       
   686 			iTestStep->Log(_L("Connecting to %s:%d"), iAddress.PtrZ(), iPortNum );
       
   687 			iTlsSocket2->Close();
       
   688 			User::LeaveIfError( iSocket.Open( iSocketServ, KAfInet, KSockStream, KProtocolInetTcp ) );	
       
   689 			iSocket.Connect( iInetAddr, iStatus );
       
   690 			SetActive();
       
   691 			iRunState = ESocketConnected;
       
   692 			}
       
   693 		else
       
   694 			{
       
   695 			iInUse = EFalse;
       
   696 			}
       
   697 
       
   698 		// can wait here for an unload of the ssl.dll to make sure that a session is not
       
   699 		// reconnected next time. The option to set the unload timeout via a SetOpt
       
   700 		// may not currently work, so this is a sure way to stop a reconnection.
       
   701 		if ( iTestEndDelay )
       
   702 			{
       
   703 			iTestStep->Log( _L("Waiting for %d seconds"), iTestEndDelay );
       
   704 			User::After( 1000000 * iTestEndDelay );
       
   705 			}
       
   706 
       
   707 		break;
       
   708 		}
       
   709 
       
   710 	case EDummyConnection:
       
   711 		iTestStep->Log( _L("STATE: EDummyConnection Status: %d"), iStatus.Int() );
       
   712 		iInUse = EFalse;
       
   713 		break;
       
   714 
       
   715 		// end switch
       
   716 		}
       
   717 	}
       
   718 
       
   719 void CTLSTest::DoCancel()
       
   720 	{	
       
   721 	// Cancel the connect
       
   722 	iSocket.CancelConnect();
       
   723 	}
       
   724 
       
   725 void CTLSTest::ConnectL( const TDesC &aAddress, 
       
   726 				const TInt aPortNum, 
       
   727 				const TDesC &aPage, 
       
   728 				const TDesC8 &aCipherSuite, 
       
   729 				const TInt aCipher, 
       
   730 				const TInt aSimpleGet, 
       
   731 				const TInt aTestEndDelay, 
       
   732 				const TDesC8& aDNSName ,
       
   733 				const TDesC& aProtocol, 
       
   734 				TBool aUseGenericSocket, 
       
   735 				TBool aEAPKeyDerivation )
       
   736 	{
       
   737 #if 0
       
   738 	iRunState = EDummyConnection;
       
   739 	TRequestStatus* p=&iStatus;
       
   740 	User::RequestComplete( p, KErrNone );
       
   741    SetActive();
       
   742    return;
       
   743 #endif
       
   744 
       
   745 	TInt err;
       
   746 	TNameEntry nameEntry;
       
   747 	TNameRecord nameRecord;
       
   748 	TSockAddr sockAddr;
       
   749 
       
   750 	iInUse = ETrue;
       
   751 
       
   752 	err = iInetAddr.Input( aAddress );
       
   753 	if ( err != KErrNone )
       
   754 		{
       
   755 		err = iHostResolver.GetByName( aAddress, nameEntry );
       
   756 		if ( err == KErrNone )
       
   757 			{
       
   758 			nameRecord = nameEntry();
       
   759 			sockAddr = nameRecord.iAddr;
       
   760 			iInetAddr = iInetAddr.Cast( sockAddr );
       
   761 			}
       
   762 		}
       
   763 
       
   764 	iInetAddr.SetPort( aPortNum );
       
   765 	iAddress = aAddress;
       
   766 	iDNSName = aDNSName;
       
   767 	iPortNum = aPortNum;
       
   768 	iCipherSuites.Copy( aCipherSuite );
       
   769 	iProtocol.Copy( aProtocol );
       
   770 	iCipher = aCipher;
       
   771 	iPage.Copy( aPage );
       
   772 	iSimpleGet = aSimpleGet;
       
   773 	iTestEndDelay = aTestEndDelay;
       
   774 	iUseGenericSocket = aUseGenericSocket;
       
   775 	iEAPKeyDerivation = aEAPKeyDerivation;
       
   776 
       
   777 	// Print info to the log
       
   778 	iTestStep->Log( _L("*****Connecting to*****") );
       
   779 	iTestStep->Log( _L("%s:%d "), iAddress.PtrZ(), iPortNum ); 
       
   780 
       
   781 
       
   782 	// Open the socket
       
   783 	User::LeaveIfError( iSocket.Open( iSocketServ, KAfInet, KSockStream, KProtocolInetTcp ) );	
       
   784 	
       
   785 	if(iUseGenericSocket)
       
   786 		{
       
   787 		iGenericSocket = new(ELeave)CGenericSecureSocket<RSocket>(iSocket);
       
   788 		}
       
   789 
       
   790 	iTestPassed = ETrue;
       
   791 	iCiphersMatch = EFalse;
       
   792 
       
   793 	iRunState = ESocketConnected;
       
   794 	
       
   795 	// Open the socket
       
   796 	User::LeaveIfError( iInetAddr.Input( iAddress ));
       
   797 	iInetAddr.SetPort( iPortNum );
       
   798 
       
   799 	iTestStep->Log(_L("Connecting to %s:%d"), iAddress.PtrZ(), iPortNum );
       
   800 	iSocket.Connect( iInetAddr, iStatus );	
       
   801 
       
   802 	SetActive();
       
   803 	}
       
   804 
       
   805 void CTLSTest::SetConsole( CTestStepTls * aTestStep )
       
   806 	{
       
   807 	iTestStep = aTestStep;
       
   808 	}
       
   809 
       
   810 TBool CTLSTest::InUse()
       
   811 	{
       
   812 	return iInUse;
       
   813 	}
       
   814 
       
   815 TBool CTLSTest::TestingSite( const TDesC &aAddress, const TInt aPortNum )
       
   816 	{
       
   817 		TInt match = iAddress.Compare( aAddress );
       
   818 
       
   819 		if ( ( aPortNum == iPortNum ) && ( match == 0 ) && ( iInUse ) )
       
   820 			return ETrue ;
       
   821 		else 
       
   822 			return EFalse;
       
   823 	}
       
   824 
       
   825 void CTLSTest::HexDump(const TText* aHeader, const TText* aMargin, const TUint8* aPtr, TInt aLen)
       
   826 	{
       
   827 
       
   828 	TBuf<0x100> buf;
       
   829 	buf.SetLength(0);
       
   830 	TInt i = 0;
       
   831 	const TText* p = aHeader;
       
   832 	while (aLen>0)
       
   833 		{
       
   834 		TInt n = aLen>KHexDumpWidth ? KHexDumpWidth : aLen;
       
   835 		buf.AppendFormat(_L("%s%04x : "), p, i);
       
   836 		TInt j;
       
   837 		for (j=0; j<n; j++)
       
   838 			buf.AppendFormat(_L("%02x "), aPtr[i+j]);
       
   839 		while (j++<KHexDumpWidth)
       
   840 			buf.AppendFormat(_L("   "));
       
   841 		buf.AppendFormat(_L(" "));
       
   842 		for (j=0; j<n; j++)
       
   843 			{
       
   844 			TUint8 byteAsChar;
       
   845 			byteAsChar = aPtr[i+j]<32 || aPtr[i+j]>126 ? '.' : aPtr[i+j];
       
   846 			if ((byteAsChar == '%') || (byteAsChar == '<'))
       
   847 				byteAsChar = '.';
       
   848 			buf.AppendFormat(_L("%c"), byteAsChar );
       
   849 			}
       
   850 		iTestStep->Log(buf);
       
   851 		buf.SetLength(0);
       
   852 		aLen -= n;
       
   853 		i += n;
       
   854 		p = aMargin;
       
   855 		}
       
   856 	}
       
   857 
       
   858 
       
   859 
       
   860 TInt CTLSTest::GetCertInfo(const CX509Certificate& aSource)
       
   861 	{
       
   862 	TText margin = 0;
       
   863 	TText header = 0;
       
   864 
       
   865 	iTestStep->Log( _L("------Certificate Info------") );
       
   866 
       
   867 	iTestStep->Log( _L("FingerPrint") );
       
   868 	HexDump( &header, &margin, aSource.Fingerprint().Ptr(), aSource.Fingerprint().Length() );
       
   869 
       
   870 	iTestStep->Log( _L("SerialNumber") );
       
   871 	HexDump( &header, &margin, aSource.SerialNumber().Ptr(), aSource.SerialNumber().Length() );
       
   872 							   
       
   873 	const CSubjectPublicKeyInfo& publicKeyInfo = aSource.PublicKey();
       
   874 	iTestStep->Log( _L("PublicKeyInfo") );
       
   875 	HexDump( &header, &margin, publicKeyInfo.KeyData().Ptr(), publicKeyInfo.KeyData().Length() );
       
   876 
       
   877 	iTestStep->Log( _L("----------------------------") );
       
   878 
       
   879 	return KErrNone;
       
   880 	}
       
   881 
       
   882 
       
   883 TInt CTLSTest::KeyDerivationTests(TBool aSocketOpen)
       
   884 	{
       
   885 	if( aSocketOpen )
       
   886 		{
       
   887 		// Input should be no longer than 100 bytes
       
   888 		iTestStep->Log( _L("Attempt to get EAP Keys with too large an input descriptor") );
       
   889 		TBuf8<KEAPKeyLength> tooBig;
       
   890 		tooBig.Fill('X',101);
       
   891 		TInt err = iTlsSocket->GetOpt(KSoKeyingMaterial, KSolInetSSL, tooBig);
       
   892 		if(err != KErrArgument)
       
   893 			{
       
   894 			iTestStep->Log( _L("FAILED: Did not return KErrArgument.  Error: %d"), err );
       
   895 			if(err == KErrNone)
       
   896 				{
       
   897 				err = KErrGeneral;
       
   898 				}
       
   899 			return err;
       
   900 			}
       
   901 		iTestStep->Log( _L("Passed") );
       
   902 
       
   903 		// Descriptor should be of size to fit 128+64 bytes
       
   904 		iTestStep->Log( _L("Attempt to get EAP Keys with too small an input descriptor") );
       
   905 		TBuf8<KEAPKeyLength-5> tooSmall;
       
   906 		err = iTlsSocket->GetOpt(KSoKeyingMaterial, KSolInetSSL, tooSmall);
       
   907 		if(err != KErrArgument)
       
   908 			{
       
   909 			iTestStep->Log( _L("FAILED: Did not return KErrArgument.  Error: %d"), err );
       
   910 			if(err == KErrNone)
       
   911 				{
       
   912 				err = KErrGeneral;
       
   913 				}
       
   914 			return err;
       
   915 			}
       
   916 		iTestStep->Log( _L("Passed") );
       
   917 
       
   918 		// Should be able to generate key
       
   919 		iTestStep->Log( _L("Attempt to get EAP Keys with a valid input descriptor") );
       
   920 		TBuf8<KEAPKeyLength+5> retVal;
       
   921 		err = iTlsSocket->GetOpt(KSoKeyingMaterial, KSolInetSSL, retVal);
       
   922 		if(err != KErrNone)
       
   923 			{
       
   924 			iTestStep->Log( _L("FAILED: Call failed with error: %d"), err );
       
   925 			if(err == KErrNone)
       
   926 				{
       
   927 				err = KErrGeneral;
       
   928 				}
       
   929 			return err;
       
   930 			}
       
   931 		if(retVal.Length() != KEAPKeyLength)
       
   932 			{
       
   933 			iTestStep->Log( _L("FAILED: Call OK but Key returned is the wrong size.  Expected=%d Actual=%d"), 128+64, retVal.Length() );
       
   934 			err = KErrGeneral;
       
   935 			return err;
       
   936 			}
       
   937 		iTestStep->Log( _L("Passed") );
       
   938 		}
       
   939 	else
       
   940 		{
       
   941 		// Can only generate keys whilst have an open socket that has completed the SSL handshake
       
   942 		iTestStep->Log( _L("Attempt to get EAP Keys before handshake/after socket closed") );
       
   943 		TBuf8<KEAPKeyLength> retVal;
       
   944 		TInt err = iTlsSocket->GetOpt(KSoKeyingMaterial, KSolInetSSL, retVal);
       
   945 		if(err != KErrNotReady)
       
   946 			{
       
   947 			iTestStep->Log( _L("FAILED: Did not return KErrNotReady.  Error: %d"), err );
       
   948 			if(err == KErrNone) err = KErrGeneral;
       
   949 			return err;
       
   950 			}
       
   951 		iTestStep->Log( _L("Passed") );
       
   952 		}
       
   953 
       
   954 	return KErrNone;
       
   955 	}