diff -r 000000000000 -r af10295192d8 networksecurity/tls/ts_tls/T_TLS_test.cpp --- /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 +#include + +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +#include +#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 cipherBuf; +// TBuf8 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; iLog( _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(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; j126 ? '.' : 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 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 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 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 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; + }