--- /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;
+ }