os/security/contentmgmt/cafstreamingsupport/test/tscaf/source/tipsec.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// Implements the IpSec Test Cases
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include "tipsec.h"
sl@0
    19
sl@0
    20
#include <caf/streaming/keystreamdecoder.h>
sl@0
    21
#include <caf/streaming/protectedstreamdesc.h>
sl@0
    22
#include <caf/streaming/keystreamsink.h>
sl@0
    23
#include <caf/streaming/keyassociation.h>
sl@0
    24
sl@0
    25
//Networking and IpSec includes
sl@0
    26
#include <networking/pfkeyv2.h>
sl@0
    27
#include <networking/ipsecerr.h>
sl@0
    28
#include <pfkey_send.h>
sl@0
    29
#include <es_sock.h> 
sl@0
    30
#include <es_enum.h>
sl@0
    31
sl@0
    32
#include <e32base.h>
sl@0
    33
#include <c32comm.h>
sl@0
    34
sl@0
    35
_LIT(KDefaultServerAddr,"192.168.174.5");
sl@0
    36
_LIT(KClientLocalAddr,"192.168.0.3");
sl@0
    37
_LIT(KDefaultListenAddr, "0.0.0.0");
sl@0
    38
const TInt KClientPort = 3002;
sl@0
    39
const TInt KServerPort = 3003;
sl@0
    40
const TUint KTestSpiBase = 667;
sl@0
    41
_LIT8(KTestData, "test\n");
sl@0
    42
_LIT8(KDefaultEncryptionKey, "1234567890123456");
sl@0
    43
_LIT8(KDefaultAuthenticationKey, "12345678901234567890");
sl@0
    44
sl@0
    45
using namespace StreamAccess;
sl@0
    46
sl@0
    47
//--------------------------CScafIpSec--------------------
sl@0
    48
sl@0
    49
CScafIpSec::CScafIpSec(CScafServer& aParent): CScafStep(aParent)
sl@0
    50
	{
sl@0
    51
	SetTestStepName(KScafIpSec);
sl@0
    52
	}
sl@0
    53
sl@0
    54
TVerdict CScafIpSec::doTestStepPreambleL()
sl@0
    55
	{
sl@0
    56
	__UHEAP_MARK;
sl@0
    57
	INFO_PRINTF2(_L("HEAP CELLS: %d"), User::CountAllocCells());
sl@0
    58
	
sl@0
    59
	ReadTestConfigurationL();
sl@0
    60
	
sl@0
    61
	// Create a session to esock server
sl@0
    62
	User::LeaveIfError(iSocketServ.Connect());	
sl@0
    63
	// Create a connection
sl@0
    64
	User::LeaveIfError(iConnection.Open(iSocketServ, KAfInet));
sl@0
    65
	TRequestStatus status;			
sl@0
    66
	User::LeaveIfError(iConnection.Start());
sl@0
    67
	
sl@0
    68
	User::LeaveIfError(iClientSocket.Open(iSocketServ, KAfInet, KSockDatagram, KProtocolInetUdp, iConnection));
sl@0
    69
	// By default, we listen on the same port as then we use for the SA - can be different on a negative test
sl@0
    70
	TInt listenPort(KClientPort); 
sl@0
    71
	GetIntFromConfig(ConfigSection(), _L("ListenPort"), listenPort);	
sl@0
    72
	
sl@0
    73
	// Create and bind the client socket
sl@0
    74
	TInetAddr listenAddr;
sl@0
    75
	User::LeaveIfError(listenAddr.Input(KDefaultListenAddr));
sl@0
    76
	listenAddr.SetPort(listenPort);
sl@0
    77
	User::LeaveIfError(iClientSocket.Bind(listenAddr));
sl@0
    78
	
sl@0
    79
	TPtrC serverAddrFromConfig;
sl@0
    80
	if (GetStringFromConfig(ConfigSection(), _L("ServerAddress"), serverAddrFromConfig))
sl@0
    81
		{// If the IP address of the server is specified explicitly in the configuration file, use it as the server address.
sl@0
    82
		 // This specification is made when the server is a remote host.
sl@0
    83
		INFO_PRINTF2(_L("Assign server address from the configuration: %S"), &serverAddrFromConfig);
sl@0
    84
		User::LeaveIfError(iServerAddr.Input(serverAddrFromConfig));
sl@0
    85
		}
sl@0
    86
	else
sl@0
    87
		{// If the server IP address is not specified, try to find out the own IP address of the device
sl@0
    88
		 // by looking up its ethernet interface. It means that the client and server are running on the same device.
sl@0
    89
		TBool srvAddrFound = EFalse;
sl@0
    90
		TSoInetInterfaceInfo networkInfo;
sl@0
    91
		TPckg<TSoInetInterfaceInfo> opt(networkInfo);
sl@0
    92
		User::LeaveIfError(iClientSocket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl));
sl@0
    93
		TInt res = KErrNone;
sl@0
    94
		TName ip;
sl@0
    95
		do 
sl@0
    96
			{
sl@0
    97
			res = iClientSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, opt);
sl@0
    98
			if(!opt().iAddress.IsUnspecified())
sl@0
    99
				{
sl@0
   100
				opt().iAddress.Output(ip);
sl@0
   101
				INFO_PRINTF3(_L("Interface Name:%S Interface Address:%S"),&(opt().iName), &ip);
sl@0
   102
				// Skip loopback interfaces and get the address of first extrenal interface
sl@0
   103
				if(opt().iName.Find(_L("loop"))  == KErrNotFound)
sl@0
   104
					{
sl@0
   105
					INFO_PRINTF2(_L("Assign server address as %S"), &ip);
sl@0
   106
					iServerAddr = opt().iAddress;
sl@0
   107
					srvAddrFound = ETrue;
sl@0
   108
					break;
sl@0
   109
					}
sl@0
   110
				}
sl@0
   111
			}while (res == KErrNone);
sl@0
   112
			// If the device doesn't have got an ethernet interface or its address has not been obtained, try to use a default one.
sl@0
   113
			if(!srvAddrFound)
sl@0
   114
				{
sl@0
   115
				INFO_PRINTF2(_L("Couldn't find a proper interface. Assign server address as %S"), &KDefaultServerAddr);
sl@0
   116
				User::LeaveIfError(iServerAddr.Input(KDefaultServerAddr));
sl@0
   117
				}
sl@0
   118
		}
sl@0
   119
	iServerAddr.SetPort(KServerPort);
sl@0
   120
sl@0
   121
	// Connect the UDP socket - this is needed for the sub-connection interface
sl@0
   122
	iClientSocket.Connect(iServerAddr, status);
sl@0
   123
	User::WaitForRequest(status);
sl@0
   124
	User::LeaveIfError(status.Int());		
sl@0
   125
	
sl@0
   126
	// The client address is not equal to the listening address, since the PF_KEY association set
sl@0
   127
	// by key stream sink needs to have a well defined dest. address and not INADDR_ANY used on the listening socket	
sl@0
   128
	// The section below should be removed if and when we switch to sub-connection interface		
sl@0
   129
	User::LeaveIfError(iClientAddr.Input(KClientLocalAddr));
sl@0
   130
	iClientAddr.SetPort(KClientPort);
sl@0
   131
	
sl@0
   132
	iAssociationsNumber = 1;
sl@0
   133
	GetIntFromConfig(ConfigSection(), _L("AssociationsNumber"), iAssociationsNumber);
sl@0
   134
sl@0
   135
	iAuthenticationUsed = ETrue;
sl@0
   136
	GetBoolFromConfig(ConfigSection(), _L("UseAuthentication"), iAuthenticationUsed);	
sl@0
   137
		
sl@0
   138
	TPtrC encryptionKeyFromConfig;
sl@0
   139
	if (GetStringFromConfig(ConfigSection(), _L("EncryptionKey"), encryptionKeyFromConfig))
sl@0
   140
		{
sl@0
   141
		iEncryptionKey = HBufC8::NewL(encryptionKeyFromConfig.Length());
sl@0
   142
		iEncryptionKey->Des().Copy(encryptionKeyFromConfig);
sl@0
   143
		}
sl@0
   144
	else
sl@0
   145
		iEncryptionKey = KDefaultEncryptionKey().AllocL();
sl@0
   146
	
sl@0
   147
	iEncryptionAlgorithm = EAES_128_CBC;
sl@0
   148
	GetIntFromConfig(ConfigSection(), _L("EncryptionAlgorithm"), iEncryptionAlgorithm);
sl@0
   149
	
sl@0
   150
	if (iAuthenticationUsed)
sl@0
   151
		{
sl@0
   152
		TPtrC authenticationKeyFromConfig;
sl@0
   153
		if (GetStringFromConfig(ConfigSection(), _L("AuthenticationKey"), authenticationKeyFromConfig))
sl@0
   154
			{
sl@0
   155
			iAuthenticationKey = HBufC8::NewL(authenticationKeyFromConfig.Length());
sl@0
   156
			iAuthenticationKey->Des().Copy(authenticationKeyFromConfig);			
sl@0
   157
			}
sl@0
   158
		else
sl@0
   159
			iAuthenticationKey = KDefaultAuthenticationKey().AllocL();
sl@0
   160
		iAuthenticationAlgorithm = EHMAC_SHA1;
sl@0
   161
		GetIntFromConfig(ConfigSection(), _L("AuthenticationAlgorithm"), iAuthenticationAlgorithm);
sl@0
   162
		}
sl@0
   163
	else
sl@0
   164
		iAuthenticationAlgorithm = ENoAuthentication;
sl@0
   165
	
sl@0
   166
	return TestStepResult();
sl@0
   167
	}
sl@0
   168
		
sl@0
   169
void ReceiveAndCompareBufL(RSocket &aSocket, const TDesC8 &aCompareTo)
sl@0
   170
	{
sl@0
   171
	HBufC8 *testBuf = HBufC8::NewLC(aCompareTo.Length());
sl@0
   172
	TRequestStatus status;	
sl@0
   173
	TPtr8 testBufPtr(testBuf->Des());
sl@0
   174
	aSocket.Recv(testBufPtr, 0, status);
sl@0
   175
	User::WaitForRequest(status);
sl@0
   176
	User::LeaveIfError(status.Int());
sl@0
   177
		
sl@0
   178
	if (testBufPtr.Compare(aCompareTo) != 0)
sl@0
   179
		User::Leave(KErrGeneral);
sl@0
   180
	
sl@0
   181
	CleanupStack::PopAndDestroy(testBuf);
sl@0
   182
	}	
sl@0
   183
sl@0
   184
TUint32 ConvertToNetworkOrder(TUint32 aNum)
sl@0
   185
    {
sl@0
   186
    const TInt KMaxTUint32CStringLen = 11;
sl@0
   187
    TUint8 temp[ KMaxTUint32CStringLen ];   
sl@0
   188
    LittleEndian::Put32( temp, aNum );
sl@0
   189
    return BigEndian::Get32( temp );
sl@0
   190
    }
sl@0
   191
   
sl@0
   192
// Check whether a particular SA is present in SADB - used for testing the IPsec key stream decoder.
sl@0
   193
// Two modes supported: positive and negative - in the negative one the SA should not be present
sl@0
   194
// Some of the code is copy/pasted from IPSec key stream production code, since it cannot be exposed in the
sl@0
   195
// interfaces there
sl@0
   196
static void ValidateSadbL(TInt32 aSpi, TInetAddr &aSourceAddr, TInetAddr &aDestAddr, TBool aPositiveTesting)
sl@0
   197
	{	
sl@0
   198
	RSocketServ socketServ;
sl@0
   199
	User::LeaveIfError(socketServ.Connect());
sl@0
   200
	CleanupClosePushL(socketServ);
sl@0
   201
	RSADB rsadb;
sl@0
   202
	User::LeaveIfError(rsadb.Open(socketServ));
sl@0
   203
	CleanupClosePushL(rsadb);
sl@0
   204
	// We use the same sequence number as the SPI - since we use different SPI in our tests
sl@0
   205
	// this provides uniqueness required of sequence id-s 
sl@0
   206
	TPfkeySendMsg sendMessage(SADB_GET, SADB_SATYPE_ESP, aSpi, RProcess().Id());
sl@0
   207
	TUint32 bigEndianSpi(ConvertToNetworkOrder(aSpi));
sl@0
   208
	sendMessage.Add( Int2Type<SADB_EXT_SA>(), bigEndianSpi, 0, 0); 
sl@0
   209
	sendMessage.Add( Int2Type<SADB_EXT_ADDRESS_SRC>(), aSourceAddr, 0, 0 );
sl@0
   210
	sendMessage.Add( Int2Type<SADB_EXT_ADDRESS_DST>(), aDestAddr, 0, 0 );
sl@0
   211
	
sl@0
   212
	TRequestStatus status;
sl@0
   213
	rsadb.FinalizeAndSend(sendMessage, status);
sl@0
   214
	User::WaitForRequest(status);
sl@0
   215
	User::LeaveIfError(status.Int());
sl@0
   216
sl@0
   217
	// Since SADB sends replies to _all_ sockets, we must take care to filter out replies which
sl@0
   218
	// do not correspond to our request. A similar logic is done in IPSec key stream decoder, but it is private there
sl@0
   219
	// and cannot be reused
sl@0
   220
	while (1)
sl@0
   221
		{
sl@0
   222
		TPfkeyRecvMsg receivedReply;
sl@0
   223
		rsadb.ReadRequest(receivedReply, status);
sl@0
   224
		User::WaitForRequest(status);
sl@0
   225
		User::LeaveIfError(status.Int());		
sl@0
   226
		
sl@0
   227
		sadb_msg &msgHeader = receivedReply.MsgHdr();
sl@0
   228
	
sl@0
   229
		if (msgHeader.sadb_msg_pid != RProcess().Id())
sl@0
   230
			continue;
sl@0
   231
		if (msgHeader.sadb_msg_seq != aSpi)
sl@0
   232
			continue;		
sl@0
   233
		
sl@0
   234
		// If the message types does not match, then the problem is internal in IPSec - it should not answer with a different message type	
sl@0
   235
		if (msgHeader.sadb_msg_type != SADB_GET)
sl@0
   236
			User::Leave(KErrArgument); 
sl@0
   237
		if (msgHeader.sadb_msg_errno ^ aPositiveTesting == 0)
sl@0
   238
			{
sl@0
   239
			// Mimic the logic in IPSec error handling (see the Update function in key_msg.cpp)		
sl@0
   240
			TUint16 reservedField = (TUint16)msgHeader.sadb_msg_reserved << 8;
sl@0
   241
			TUint16 errnoField = msgHeader.sadb_msg_errno;
sl@0
   242
			User::Leave(-(reservedField + errnoField));
sl@0
   243
			}
sl@0
   244
		break;		
sl@0
   245
		}							
sl@0
   246
	CleanupStack::PopAndDestroy(2, &socketServ);
sl@0
   247
	}
sl@0
   248
sl@0
   249
void CScafIpSec::CallValidateSadbL(TInt32 aSpi, TInetAddr &aSourceAddr, TInetAddr &aDestAddr, TBool aPositiveTesting)
sl@0
   250
	{
sl@0
   251
	ValidateSadbL(aSpi, aSourceAddr, aDestAddr, aPositiveTesting);
sl@0
   252
	}
sl@0
   253
sl@0
   254
void CScafIpSec::InitializeAlgorithmsL(CKeyStreamSink *aKeyStreamSink)
sl@0
   255
	{
sl@0
   256
	aKeyStreamSink->SetEncryptionAlgorithmL((TEncryptionAlgorithm)iEncryptionAlgorithm);
sl@0
   257
	aKeyStreamSink->SetAuthenticationAlgorithmL((TAuthenticationAlgorithm)iAuthenticationAlgorithm);		
sl@0
   258
	}
sl@0
   259
sl@0
   260
CKeyStreamSink *CScafIpSec::CreateDefaultKeyStreamSinkLC()
sl@0
   261
	{
sl@0
   262
	// when RSubConnection interface starts working use the below code
sl@0
   263
	/*
sl@0
   264
	RSubConnection subconn;
sl@0
   265
	User::LeaveIfError(subconn.Open(ss, RSubConnection::ECreateNew, conn));
sl@0
   266
	CleanupClosePushL(subconn);
sl@0
   267
	
sl@0
   268
	subconn.Add(clientSocket, status);
sl@0
   269
	User::WaitForRequest(status);	
sl@0
   270
	User::LeaveIfError(status.Int());
sl@0
   271
	
sl@0
   272
	CProtectedStreamDesc *protectedStreamDesc = CIPSecProtectedStreamDesc::NewLC(subconn);
sl@0
   273
	*/			
sl@0
   274
	
sl@0
   275
	CProtectedStreamDesc *protectedStreamDesc = CIpSecProtectedStreamDesc::NewLC(iServerAddr, iClientAddr);
sl@0
   276
	CKeyStreamSink *keyStreamSink = protectedStreamDesc->CreateKeyStreamSinkLC();	
sl@0
   277
	InitializeAlgorithmsL(keyStreamSink);
sl@0
   278
	
sl@0
   279
	CleanupStack::Pop(keyStreamSink);
sl@0
   280
	CleanupStack::PopAndDestroy(protectedStreamDesc);
sl@0
   281
	CleanupStack::PushL(keyStreamSink);
sl@0
   282
	return keyStreamSink;
sl@0
   283
	}
sl@0
   284
	
sl@0
   285
void CScafIpSec::SendKeyAssociationToKeySinkL(TInt aSpi, CKeyStreamSink *aKeyStreamSink)
sl@0
   286
	{
sl@0
   287
	INFO_PRINTF2(_L("Sending key association with SPI %d"), aSpi);
sl@0
   288
	CKeyAssociation *ipSecKeyAssociation = CIpSecKeyAssociation::NewL(aSpi, iEncryptionKey, 
sl@0
   289
							iAuthenticationKey);
sl@0
   290
	CleanupStack::PushL(ipSecKeyAssociation); // Not using NewLC directly, so that NewL and NewLC will both be covered in tests
sl@0
   291
	
sl@0
   292
	aKeyStreamSink->ProcessNewKeyAssociationL(*ipSecKeyAssociation);	
sl@0
   293
		
sl@0
   294
	//aKeyStreamSink->ProcessNewKeyAssociationL(*ipSecKeyAssociation);	
sl@0
   295
	INFO_PRINTF2(_L("Sent key association with SPI %d"), aSpi);
sl@0
   296
	CleanupStack::PopAndDestroy(ipSecKeyAssociation);	
sl@0
   297
	}
sl@0
   298
	
sl@0
   299
void CScafIpSec::AddAndValidateAssociationsL(CKeyStreamSink *aKeyStreamSink, TInt aSpiBase)
sl@0
   300
	{
sl@0
   301
	for (TInt i = 0; i < iAssociationsNumber; ++i)
sl@0
   302
		{
sl@0
   303
		SendKeyAssociationToKeySinkL(aSpiBase + i, aKeyStreamSink);
sl@0
   304
		INFO_PRINTF2(_L("Validating key association with SPI %d"), aSpiBase + i);
sl@0
   305
		ValidateSadbL(aSpiBase + i, iServerAddr, iClientAddr, ETrue);
sl@0
   306
		INFO_PRINTF2(_L("Validated key association with SPI %d"), aSpiBase + i);
sl@0
   307
		}	
sl@0
   308
	}
sl@0
   309
	
sl@0
   310
void CScafIpSec::ValidateNoAssociationsL(TInt aSpiBase)
sl@0
   311
	{
sl@0
   312
	// Check that after key stream decoder was removed, all the SA-s had been deleted	
sl@0
   313
	for (TInt i = 0; i < iAssociationsNumber; ++i)
sl@0
   314
		ValidateSadbL(aSpiBase + i, iServerAddr, iClientAddr, EFalse);
sl@0
   315
	INFO_PRINTF3(_L("Validated that no associations exist from SPI %d to SPI %d"), aSpiBase, aSpiBase + iAssociationsNumber - 1);	
sl@0
   316
	}
sl@0
   317
sl@0
   318
TVerdict CScafIpSec::doTestL()
sl@0
   319
	{
sl@0
   320
	CKeyStreamSink *keyStreamSink = CreateDefaultKeyStreamSinkLC();
sl@0
   321
	
sl@0
   322
	TBool integrationTest(ETrue);
sl@0
   323
	GetBoolFromConfig(ConfigSection(), _L("IntegrationTest"), integrationTest);	
sl@0
   324
			
sl@0
   325
	for (TInt i = 0; i < iAssociationsNumber; ++i)
sl@0
   326
		{
sl@0
   327
		SendKeyAssociationToKeySinkL(KTestSpiBase + i, keyStreamSink);
sl@0
   328
		// Receive the packet and compare the data - disabled on automatic tests
sl@0
   329
		if (integrationTest)
sl@0
   330
			{
sl@0
   331
			ReceiveAndCompareBufL(iClientSocket, KTestData());					
sl@0
   332
			}
sl@0
   333
		}		
sl@0
   334
	CleanupStack::PopAndDestroy(keyStreamSink);
sl@0
   335
	return TestStepResult();	
sl@0
   336
	}
sl@0
   337
sl@0
   338
TVerdict CScafIpSec::doTestStepPostambleL()
sl@0
   339
	{
sl@0
   340
	delete iEncryptionKey;
sl@0
   341
	delete iAuthenticationKey;
sl@0
   342
	iClientSocket.Close();	
sl@0
   343
	iConnection.Close();	
sl@0
   344
	iSocketServ.Close();
sl@0
   345
	
sl@0
   346
	iDecoderConfigurationArray.ResetAndDestroy();
sl@0
   347
	
sl@0
   348
	INFO_PRINTF2(_L("HEAP CELLS: %d"), User::CountAllocCells());
sl@0
   349
	__UHEAP_MARKEND;
sl@0
   350
	
sl@0
   351
	return TestStepResult();
sl@0
   352
	}
sl@0
   353
sl@0
   354
//-------------------------CScafIpSecDecoderIntegration---------------------------
sl@0
   355
sl@0
   356
CScafIpSecDecoderIntegration::CScafIpSecDecoderIntegration(CScafServer& aParent): CScafIpSec(aParent)
sl@0
   357
	{
sl@0
   358
	SetTestStepName(KScafIpSecDecoderIntegration);
sl@0
   359
	}
sl@0
   360
sl@0
   361
TVerdict CScafIpSecDecoderIntegration::doTestL()
sl@0
   362
	{	
sl@0
   363
	TBool integrationTest(ETrue);
sl@0
   364
	GetBoolFromConfig(ConfigSection(), _L("IntegrationTest"), integrationTest);
sl@0
   365
	
sl@0
   366
	CTestKeyStreamDecoderBase *keyStreamDecoder = NULL;
sl@0
   367
	CSdpMediaField *sdp = NULL;
sl@0
   368
	CSdpDocument* sdpDoc = NULL;
sl@0
   369
	
sl@0
   370
	TPtrC privatePath;
sl@0
   371
	
sl@0
   372
	if(iDecoderConfigurationArray[0]->iPrivateFolderPath.Length())
sl@0
   373
		{
sl@0
   374
		privatePath.Set(iDecoderConfigurationArray[0]->iPrivateFolderPath);
sl@0
   375
		}
sl@0
   376
	else
sl@0
   377
		{
sl@0
   378
		privatePath.Set(KStaPrivateFolder());
sl@0
   379
		}
sl@0
   380
	
sl@0
   381
	//Create an SDP document object and set the created key stream field object
sl@0
   382
	sdpDoc = CreateSdpDocumentLC();
sl@0
   383
	
sl@0
   384
	//Create an SDP object with an attribute requiring the service protected RO
sl@0
   385
	sdp = CreateSdpLC(0);
sl@0
   386
	AddMediaFieldL(*sdpDoc, sdp);
sl@0
   387
	CleanupStack::Pop(sdp);
sl@0
   388
	
sl@0
   389
	INFO_PRINTF1(_L("Decoder integration test - created SDP"));	
sl@0
   390
	CKeyStreamSink *keyStreamSink = CreateDefaultKeyStreamSinkLC();
sl@0
   391
	
sl@0
   392
	//Create a test agent key stream decoder
sl@0
   393
	if(iDecoderConfigurationArray[0]->iSingleProcessAgent)
sl@0
   394
		{
sl@0
   395
		// Single Process Stream Agent
sl@0
   396
		keyStreamDecoder = CTestSingleProcessKeyStreamDecoder::NewL(*keyStreamSink, *sdp, *sdpDoc);
sl@0
   397
		}
sl@0
   398
	else
sl@0
   399
		{
sl@0
   400
		// Client/Server Stream Agent
sl@0
   401
		keyStreamDecoder = CTestAgentKeyStreamDecoder::NewL(*keyStreamSink, *sdp, *sdpDoc);
sl@0
   402
		}
sl@0
   403
	
sl@0
   404
	INFO_PRINTF1(_L("Decoder integration test - created key stream decoder"));	
sl@0
   405
	CleanupStack::PushL(keyStreamDecoder);
sl@0
   406
	
sl@0
   407
	for (TInt i = 0; i < iAssociationsNumber; ++i)
sl@0
   408
		{
sl@0
   409
		INFO_PRINTF2(_L("Decoder integration test - before sending association %d"), i + 1);	
sl@0
   410
		keyStreamDecoder->SendIpSecAssociationL(KTestSpiBase + i, iEncryptionKey, iAuthenticationKey);
sl@0
   411
		if (integrationTest)
sl@0
   412
			ReceiveAndCompareBufL(iClientSocket, KTestData());					
sl@0
   413
		else
sl@0
   414
			ValidateSadbL(KTestSpiBase + i, iServerAddr, iClientAddr, ETrue);
sl@0
   415
		INFO_PRINTF2(_L("Decoder integration test - after receiving and comparing buffer for association %d"), i + 1);	
sl@0
   416
		}
sl@0
   417
	CleanupStack::PopAndDestroy(2, keyStreamSink);
sl@0
   418
	CleanupStack::PopAndDestroy(); // sdpDoc
sl@0
   419
	return TestStepResult();
sl@0
   420
	}
sl@0
   421
sl@0
   422
//-------------------------CScafIpSecSadbVerification---------------------------
sl@0
   423
	
sl@0
   424
CScafIpSecSadbVerification::CScafIpSecSadbVerification(CScafServer& aParent): CScafIpSec(aParent)
sl@0
   425
	{
sl@0
   426
	SetTestStepName(KScafIpSecSadbVerification);
sl@0
   427
	}
sl@0
   428
sl@0
   429
TVerdict CScafIpSecSadbVerification::doTestL()
sl@0
   430
	{
sl@0
   431
	CKeyStreamSink *keyStreamSink = CreateDefaultKeyStreamSinkLC();	
sl@0
   432
	AddAndValidateAssociationsL(keyStreamSink, KTestSpiBase);
sl@0
   433
	CleanupStack::PopAndDestroy(keyStreamSink);
sl@0
   434
	
sl@0
   435
	ValidateNoAssociationsL(KTestSpiBase);	
sl@0
   436
	return TestStepResult();		
sl@0
   437
	}
sl@0
   438
		
sl@0
   439
//-------------------------CScafIpSecSadbVerificationConcurrency---------------------------
sl@0
   440
	
sl@0
   441
CScafIpSecSadbVerificationConcurrency::CScafIpSecSadbVerificationConcurrency(CScafServer& aParent): CScafIpSec(aParent)
sl@0
   442
	{
sl@0
   443
	SetTestStepName(KScafIpSecSadbVerificationConcurrency);	
sl@0
   444
	}
sl@0
   445
sl@0
   446
template <class T> void ResetAndDestroyPointerArray(TAny *pointerArray)
sl@0
   447
	{
sl@0
   448
	reinterpret_cast<RPointerArray<T> *>(pointerArray)->ResetAndDestroy();
sl@0
   449
	}
sl@0
   450
sl@0
   451
struct CThreadFuncParam : public CBase
sl@0
   452
	{
sl@0
   453
	CThreadFuncParam(TInt aBaseSpi, TInt aAssociationsNumber) 
sl@0
   454
		: iBaseSpi(aBaseSpi), iAssociationsNumber(aAssociationsNumber) {}
sl@0
   455
		  
sl@0
   456
	TInt iBaseSpi;
sl@0
   457
	TInt iAssociationsNumber;
sl@0
   458
	};
sl@0
   459
sl@0
   460
void TestThreadFuncL(CThreadFuncParam *aThreadParam)
sl@0
   461
	{
sl@0
   462
	// Since this function runs in another thread, we cannot use member stack variables
sl@0
   463
	// of the CScafIpSecSadbVerificationConcurrency class - some of the functionality has to be duplicated here
sl@0
   464
	TInetAddr clientAddr, serverAddr;
sl@0
   465
	User::LeaveIfError(clientAddr.Input(KClientLocalAddr));
sl@0
   466
	clientAddr.SetPort(KClientPort);
sl@0
   467
	User::LeaveIfError(serverAddr.Input(KDefaultServerAddr));
sl@0
   468
	serverAddr.SetPort(KServerPort);
sl@0
   469
	RSocketServ socketServ;
sl@0
   470
	User::LeaveIfError(socketServ.Connect());
sl@0
   471
	CleanupClosePushL(socketServ);
sl@0
   472
	RSADB rsadb;
sl@0
   473
	User::LeaveIfError(rsadb.Open(socketServ));
sl@0
   474
	CleanupClosePushL(rsadb);	
sl@0
   475
sl@0
   476
	HBufC8 *encryptionKey = KDefaultEncryptionKey().AllocLC();	
sl@0
   477
	HBufC8 *authenticationKey = KDefaultAuthenticationKey().AllocLC();	
sl@0
   478
sl@0
   479
	CProtectedStreamDesc *protectedStreamDesc = CIpSecProtectedStreamDesc::NewLC(serverAddr, clientAddr);
sl@0
   480
	CKeyStreamSink *keyStreamSink = protectedStreamDesc->CreateKeyStreamSinkLC();	
sl@0
   481
sl@0
   482
	keyStreamSink->SetEncryptionAlgorithmL(EAES_128_CBC);
sl@0
   483
	keyStreamSink->SetAuthenticationAlgorithmL(EHMAC_SHA1);	
sl@0
   484
		
sl@0
   485
	for (TInt i = 0; i < aThreadParam->iAssociationsNumber; ++i)
sl@0
   486
		{
sl@0
   487
		TInt spi = aThreadParam->iBaseSpi + i;
sl@0
   488
		CKeyAssociation *ipSecKeyAssociation = CIpSecKeyAssociation::NewLC(spi, encryptionKey, 
sl@0
   489
																		   authenticationKey);
sl@0
   490
								   
sl@0
   491
		keyStreamSink->ProcessNewKeyAssociationL(*ipSecKeyAssociation);	
sl@0
   492
				
sl@0
   493
		CleanupStack::PopAndDestroy(ipSecKeyAssociation);			
sl@0
   494
		ValidateSadbL(spi, serverAddr, clientAddr, ETrue);
sl@0
   495
		}
sl@0
   496
	
sl@0
   497
	CleanupStack::PopAndDestroy(keyStreamSink);
sl@0
   498
	
sl@0
   499
	for (TInt i = 0; i < aThreadParam->iAssociationsNumber; ++i)
sl@0
   500
		ValidateSadbL(aThreadParam->iBaseSpi + i, serverAddr, clientAddr, EFalse);
sl@0
   501
		
sl@0
   502
	CleanupStack::PopAndDestroy(5, &socketServ); // socketServ, rsadb, protectedStreamDesc, copiedEncryptionKey, copiedAuthenticationKey
sl@0
   503
	}
sl@0
   504
sl@0
   505
TInt TestThreadFunc(TAny *aThreadParam)
sl@0
   506
	{
sl@0
   507
	CThreadFuncParam *param = reinterpret_cast<CThreadFuncParam *>(aThreadParam);
sl@0
   508
	CTrapCleanup* cleanup=CTrapCleanup::New(); 
sl@0
   509
	TRAPD(err, TestThreadFuncL(param));
sl@0
   510
	delete cleanup;
sl@0
   511
	return err;
sl@0
   512
	}
sl@0
   513
sl@0
   514
void ThreadCleanup(TAny *aThread)
sl@0
   515
	{	
sl@0
   516
	((RThread *)aThread)->Terminate(0);
sl@0
   517
	((RThread *)aThread)->Close();
sl@0
   518
	}
sl@0
   519
sl@0
   520
void CleanupThreadArray(TAny *aThreadArray)
sl@0
   521
	{
sl@0
   522
	RArray<RThread> *threadArrayPtr = reinterpret_cast<RArray<RThread> *>(aThreadArray);
sl@0
   523
	TInt threadsNum = threadArrayPtr->Count();
sl@0
   524
	for (TInt i = 0; i < threadsNum; ++i)
sl@0
   525
		{
sl@0
   526
		ThreadCleanup(&(*threadArrayPtr)[i]);
sl@0
   527
		}
sl@0
   528
	threadArrayPtr->Close();
sl@0
   529
	}
sl@0
   530
		
sl@0
   531
TVerdict CScafIpSecSadbVerificationConcurrency::doTestL()
sl@0
   532
	{
sl@0
   533
	const TInt KDefaultThreadsNumber = 10;
sl@0
   534
	TInt threadsNumber(KDefaultThreadsNumber);
sl@0
   535
	GetIntFromConfig(ConfigSection(), _L("ThreadsNumber"), threadsNumber);	
sl@0
   536
	
sl@0
   537
	RArray<RThread> spawnedThreads;
sl@0
   538
	CleanupStack::PushL(TCleanupItem(CleanupThreadArray, &spawnedThreads));	
sl@0
   539
	RPointerArray<CThreadFuncParam> threadParams;
sl@0
   540
	CleanupStack::PushL(TCleanupItem(ResetAndDestroyPointerArray<CKeyStreamSink>, &threadParams));
sl@0
   541
	
sl@0
   542
	TInt i = 0;
sl@0
   543
	for (; i < threadsNumber; ++i)
sl@0
   544
		{
sl@0
   545
		const TInt KHeapSize = 0x600;
sl@0
   546
		RThread thread;
sl@0
   547
		TInt spiBase = KTestSpiBase + iAssociationsNumber * i;
sl@0
   548
				
sl@0
   549
		CThreadFuncParam *threadParam = new (ELeave) CThreadFuncParam(spiBase, iAssociationsNumber);
sl@0
   550
		CleanupStack::PushL(threadParam);
sl@0
   551
		threadParams.AppendL(threadParam);
sl@0
   552
		CleanupStack::Pop(threadParam);
sl@0
   553
		
sl@0
   554
		TBuf<25> threadName;
sl@0
   555
		threadName.Format(_L("CAF IPSec Thread %d"), i);
sl@0
   556
		User::LeaveIfError(thread.Create(threadName, TestThreadFunc, KDefaultStackSize, KHeapSize, KHeapSize, threadParam));
sl@0
   557
		CleanupStack::PushL(TCleanupItem(ThreadCleanup, &thread));		
sl@0
   558
		spawnedThreads.AppendL(thread);
sl@0
   559
		// The thread itself is owned by the array		
sl@0
   560
		CleanupStack::Pop(&thread); 		
sl@0
   561
		}
sl@0
   562
		
sl@0
   563
	for (i = 0; i < threadsNumber; ++i)
sl@0
   564
		spawnedThreads[i].Resume();
sl@0
   565
		
sl@0
   566
	for (i = 0; i < threadsNumber; ++i)
sl@0
   567
		{
sl@0
   568
		TRequestStatus status;	
sl@0
   569
		// Wait for all threads to finish	
sl@0
   570
		spawnedThreads[i].Logon(status);
sl@0
   571
		User::WaitForRequest(status);
sl@0
   572
		if (status.Int() != KErrNone)
sl@0
   573
			{
sl@0
   574
			ERR_PRINTF3(_L("In IpSec concurrency tests, thread %d has returned with status %d"), i, status.Int());
sl@0
   575
			SetTestStepResult(EFail);
sl@0
   576
			}
sl@0
   577
		else
sl@0
   578
			INFO_PRINTF2(_L("IPSec concurrency test - thread %d finished successfully"), i);
sl@0
   579
		}
sl@0
   580
		
sl@0
   581
	CleanupStack::PopAndDestroy(2); // threadParams, spawnedThreads - cleanup item
sl@0
   582
	return TestStepResult();
sl@0
   583
	}
sl@0
   584
sl@0
   585
//-------------------------CScafIpSecNegative---------------------------
sl@0
   586
sl@0
   587
CScafIpSecNegative::CScafIpSecNegative(CScafServer& aParent): CScafIpSec(aParent)
sl@0
   588
	{
sl@0
   589
	SetTestStepName(KScafIpSecNegative);	
sl@0
   590
	}
sl@0
   591
sl@0
   592
TVerdict CScafIpSecNegative::doTestL()
sl@0
   593
	{	
sl@0
   594
	TInt encryptionKeyLength(iEncryptionKey->Length());
sl@0
   595
	ASSERT(encryptionKeyLength);
sl@0
   596
	// Save encryption and authentication key to temp. variable
sl@0
   597
	HBufC8 *malformedEncryptionKey = HBufC8::NewLC(encryptionKeyLength);
sl@0
   598
	TPtr8 malformedEncryptionKeyPtr(malformedEncryptionKey->Des());
sl@0
   599
	malformedEncryptionKeyPtr.Copy(iEncryptionKey->Des());
sl@0
   600
	
sl@0
   601
	TInt authenticationKeyLength(iAuthenticationKey->Length());
sl@0
   602
	ASSERT(authenticationKeyLength);
sl@0
   603
	HBufC8 *malformedAuthenticationKey = HBufC8::NewLC(authenticationKeyLength);
sl@0
   604
	TPtr8 malformedAuthenticationKeyPtr(malformedAuthenticationKey->Des());	
sl@0
   605
	malformedAuthenticationKeyPtr.Copy(iAuthenticationKey->Des());
sl@0
   606
	// Delete the last characters from keys - this makes them invalid	
sl@0
   607
	malformedEncryptionKeyPtr.SetLength(encryptionKeyLength - 1);	
sl@0
   608
	malformedAuthenticationKeyPtr.SetLength(authenticationKeyLength - 1);	
sl@0
   609
	
sl@0
   610
	CKeyStreamSink *keyStreamSink = CreateDefaultKeyStreamSinkLC();
sl@0
   611
	// Send new assoc. - should fail	
sl@0
   612
	CKeyAssociation *malformedKeyAssociation = CIpSecKeyAssociation::NewLC(KTestSpiBase, malformedEncryptionKey, 
sl@0
   613
							malformedAuthenticationKey);	
sl@0
   614
	TRAPD(err, keyStreamSink->ProcessNewKeyAssociationL(*malformedKeyAssociation));							
sl@0
   615
	if (err != EIpsec_BadCipherKey)
sl@0
   616
		{
sl@0
   617
		if (err != KErrNoMemory)
sl@0
   618
			{
sl@0
   619
			ERR_PRINTF2(_L("In IpSec negative tests, an incorrect error was returned when setting invalid keys. The error is %d"), err);
sl@0
   620
			}			
sl@0
   621
		if (err == KErrNone)
sl@0
   622
			SetTestStepResult(EFail);
sl@0
   623
		else
sl@0
   624
			User::Leave(err);
sl@0
   625
		}			
sl@0
   626
	INFO_PRINTF1(_L("IPSec negative test - received correct error on malformed association"));				
sl@0
   627
	// Here, we should have had a test which verifies that IPSec key stream sink rejects non-IPSec associations
sl@0
   628
	// Due to lack of dynamic_cast support, it is omitted.
sl@0
   629
		
sl@0
   630
	// Send twice a new assoc. - should fail. KTestSpiBase + 1 is used 
sl@0
   631
	// since IPSec implementation adds the malformed assoc. from step A to DB despite returning an error
sl@0
   632
	SendKeyAssociationToKeySinkL(KTestSpiBase + 1, keyStreamSink);
sl@0
   633
	INFO_PRINTF1(_L("IPSec negative test - sent correct association"));			
sl@0
   634
	TRAP(err, SendKeyAssociationToKeySinkL(KTestSpiBase + 1, keyStreamSink));
sl@0
   635
	if (err != KErrAlreadyExists)
sl@0
   636
		{
sl@0
   637
		if (err != KErrNoMemory)
sl@0
   638
			{
sl@0
   639
			ERR_PRINTF2(_L("In IpSec negative tests, an incorrect error was returned when setting duplicate SA. The error is %d"), err);
sl@0
   640
			}			
sl@0
   641
		if (err == KErrNone)
sl@0
   642
			SetTestStepResult(EFail);
sl@0
   643
		else
sl@0
   644
			User::Leave(err);
sl@0
   645
		}	
sl@0
   646
	INFO_PRINTF1(_L("IPSec negative test - received correct error on duplicate association"));			
sl@0
   647
	CleanupStack::PopAndDestroy(4, malformedEncryptionKey); // malformedEncryptionKey, malformedAuthenticationKey, keyStreamSink, malformedKeyAssociation
sl@0
   648
	return TestStepResult();
sl@0
   649
	}
sl@0
   650
	
sl@0
   651
//-------------------------CScafIpSecMultipleSinks---------------------------
sl@0
   652
sl@0
   653
CScafIpSecMultipleSinks::CScafIpSecMultipleSinks(CScafServer& aParent): CScafIpSec(aParent)
sl@0
   654
	{
sl@0
   655
	SetTestStepName(KScafIpSecMultipleSinks);	
sl@0
   656
	}
sl@0
   657
sl@0
   658
TInt KDefaultNumberOfSinks = 10;
sl@0
   659
sl@0
   660
TVerdict CScafIpSecMultipleSinks::doTestL()
sl@0
   661
	{
sl@0
   662
	// Read from configuration the number of sinks
sl@0
   663
	TInt sinksNumber(KDefaultNumberOfSinks);
sl@0
   664
	GetIntFromConfig(ConfigSection(), _L("SinksNumber"), sinksNumber);
sl@0
   665
	// Instantiate decoders using the same protected stream desc.
sl@0
   666
	CProtectedStreamDesc *protectedStreamDesc = CIpSecProtectedStreamDesc::NewLC(iServerAddr, iClientAddr);
sl@0
   667
	RPointerArray<CKeyStreamSink> sinkArray;
sl@0
   668
	CleanupStack::PushL(TCleanupItem(ResetAndDestroyPointerArray<CKeyStreamSink>, &sinkArray));
sl@0
   669
	TInt i = 0;
sl@0
   670
	for (; i < sinksNumber; ++i)
sl@0
   671
		{
sl@0
   672
		CKeyStreamSink *sink = protectedStreamDesc->CreateKeyStreamSinkLC();
sl@0
   673
		User::LeaveIfError(sinkArray.Append(sink));
sl@0
   674
		InitializeAlgorithmsL(sink);
sl@0
   675
		CleanupStack::Pop(sink);
sl@0
   676
		INFO_PRINTF2(_L("IPSec multiple sinks test - instantiated decoder %d"), i);
sl@0
   677
		}
sl@0
   678
	// Loop over decoders and number of associations, submit associations and validate them
sl@0
   679
	for (i = 0; i < iAssociationsNumber; ++i)
sl@0
   680
		for (TInt j = 0; j < sinksNumber; ++j)
sl@0
   681
			{
sl@0
   682
			TInt spi = KTestSpiBase + j * iAssociationsNumber + i;
sl@0
   683
			SendKeyAssociationToKeySinkL(spi, sinkArray[j]);
sl@0
   684
			ValidateSadbL(spi, iServerAddr, iClientAddr, ETrue);
sl@0
   685
			}
sl@0
   686
		
sl@0
   687
	// Delete decoders
sl@0
   688
	CleanupStack::PopAndDestroy(&sinkArray);
sl@0
   689
	// Validate that there are no associations
sl@0
   690
	for (; i < sinksNumber; ++i)
sl@0
   691
		{
sl@0
   692
		ValidateNoAssociationsL(KTestSpiBase + i * iAssociationsNumber);
sl@0
   693
		}	
sl@0
   694
	CleanupStack::PopAndDestroy(protectedStreamDesc);
sl@0
   695
	return TestStepResult();
sl@0
   696
	}
sl@0
   697
	
sl@0
   698
//-------------------------CScafIpSecAlgorithmChange---------------------------
sl@0
   699
sl@0
   700
CScafIpSecAlgorithmChange::CScafIpSecAlgorithmChange(CScafServer& aParent): CScafIpSec(aParent)
sl@0
   701
	{
sl@0
   702
	SetTestStepName(KScafIpSecAlgorithmChange);	
sl@0
   703
	}
sl@0
   704
sl@0
   705
TVerdict CScafIpSecAlgorithmChange::doTestL()
sl@0
   706
	{
sl@0
   707
	CKeyStreamSink *keyStreamSink = CreateDefaultKeyStreamSinkLC();
sl@0
   708
	SendKeyAssociationToKeySinkL(KTestSpiBase, keyStreamSink);
sl@0
   709
	TRAPD(err, keyStreamSink->SetEncryptionAlgorithmL(ENoEncryption));
sl@0
   710
	if (err != KErrNotSupported)
sl@0
   711
		{
sl@0
   712
		ERR_PRINTF2(_L("In IpSec algorithm change, an incorrect error was returned when setting NULL encryption. The error is %d"), err);
sl@0
   713
		SetTestStepResult(EFail);	
sl@0
   714
		}
sl@0
   715
	INFO_PRINTF1(_L("IPSec algorithms change test - received correct error after modifying encryption algorithm"));
sl@0
   716
	TRAP(err, keyStreamSink->SetAuthenticationAlgorithmL(ENoAuthentication));	
sl@0
   717
	if (err != KErrNotSupported)
sl@0
   718
		{
sl@0
   719
		ERR_PRINTF2(_L("In IpSec algorithm change, an incorrect error was returned when setting NULL authentication. The error is %d"), err);
sl@0
   720
		SetTestStepResult(EFail);	
sl@0
   721
		}	
sl@0
   722
	INFO_PRINTF1(_L("IPSec algorithms change test - received correct error after modifying authentication algorithm"));		
sl@0
   723
	CleanupStack::PopAndDestroy(keyStreamSink);
sl@0
   724
	return TestStepResult();
sl@0
   725
	}
sl@0
   726
sl@0
   727
sl@0
   728
//-------------------------CScafIpSecSARemoval---------------------------
sl@0
   729
sl@0
   730
CScafIpSecSARemoval::CScafIpSecSARemoval(CScafServer& aParent): CScafIpSec(aParent)
sl@0
   731
	{
sl@0
   732
	SetTestStepName(KScafIpSecSARemoval);	
sl@0
   733
	}
sl@0
   734
sl@0
   735
const TUint KDefaultMaxSpiNumber = 3;  // The constant is copied from IPSec's sink production code - it is not exposed in its interface
sl@0
   736
sl@0
   737
TVerdict CScafIpSecSARemoval::doTestL()
sl@0
   738
	{
sl@0
   739
	CKeyStreamSink *keyStreamSink = CreateDefaultKeyStreamSinkLC();	
sl@0
   740
	if (iAssociationsNumber <= KDefaultMaxSpiNumber)
sl@0
   741
		{
sl@0
   742
		ERR_PRINTF3(_L("Incorrect number of associations specified in SA removal test - should be at least %d, and it is %d"), KDefaultMaxSpiNumber + 1, iAssociationsNumber);
sl@0
   743
		User::Leave(KErrArgument);
sl@0
   744
		}
sl@0
   745
	TInt i = 0;
sl@0
   746
	for (; i < iAssociationsNumber; ++i)
sl@0
   747
		{
sl@0
   748
		SendKeyAssociationToKeySinkL(KTestSpiBase + i, keyStreamSink);	
sl@0
   749
		}
sl@0
   750
	INFO_PRINTF2(_L("IPSec SA removal test - sent %d associations successfully"), iAssociationsNumber);
sl@0
   751
	for (i = 0; i < iAssociationsNumber - KDefaultMaxSpiNumber; ++i)
sl@0
   752
		{
sl@0
   753
		ValidateSadbL(KTestSpiBase + i, iServerAddr, iClientAddr, EFalse);		
sl@0
   754
		}
sl@0
   755
	INFO_PRINTF3(_L("IPSec SA removal test - verified that associations %d to %d do not exist"), KTestSpiBase, KTestSpiBase + iAssociationsNumber - KDefaultMaxSpiNumber - 1);
sl@0
   756
	for (i = iAssociationsNumber - KDefaultMaxSpiNumber; i < iAssociationsNumber; ++i)
sl@0
   757
		{
sl@0
   758
		ValidateSadbL(KTestSpiBase + i, iServerAddr, iClientAddr, ETrue);		
sl@0
   759
		}
sl@0
   760
	INFO_PRINTF3(_L("IPSec SA removal test - verified that associations %d to %d exist"), KTestSpiBase + iAssociationsNumber - KDefaultMaxSpiNumber, KTestSpiBase + iAssociationsNumber - 1);
sl@0
   761
sl@0
   762
	CleanupStack::PopAndDestroy(keyStreamSink);
sl@0
   763
	return TestStepResult();
sl@0
   764
	}