Update contrib.
1 // Copyright (c) 2007-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 the License "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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // Implements the IpSec Test Cases
20 #include <caf/streaming/keystreamdecoder.h>
21 #include <caf/streaming/protectedstreamdesc.h>
22 #include <caf/streaming/keystreamsink.h>
23 #include <caf/streaming/keyassociation.h>
25 //Networking and IpSec includes
26 #include <networking/pfkeyv2.h>
27 #include <networking/ipsecerr.h>
28 #include <pfkey_send.h>
35 _LIT(KDefaultServerAddr,"192.168.174.5");
36 _LIT(KClientLocalAddr,"192.168.0.3");
37 _LIT(KDefaultListenAddr, "0.0.0.0");
38 const TInt KClientPort = 3002;
39 const TInt KServerPort = 3003;
40 const TUint KTestSpiBase = 667;
41 _LIT8(KTestData, "test\n");
42 _LIT8(KDefaultEncryptionKey, "1234567890123456");
43 _LIT8(KDefaultAuthenticationKey, "12345678901234567890");
45 using namespace StreamAccess;
47 //--------------------------CScafIpSec--------------------
49 CScafIpSec::CScafIpSec(CScafServer& aParent): CScafStep(aParent)
51 SetTestStepName(KScafIpSec);
54 TVerdict CScafIpSec::doTestStepPreambleL()
57 INFO_PRINTF2(_L("HEAP CELLS: %d"), User::CountAllocCells());
59 ReadTestConfigurationL();
61 // Create a session to esock server
62 User::LeaveIfError(iSocketServ.Connect());
63 // Create a connection
64 User::LeaveIfError(iConnection.Open(iSocketServ, KAfInet));
65 TRequestStatus status;
66 User::LeaveIfError(iConnection.Start());
68 User::LeaveIfError(iClientSocket.Open(iSocketServ, KAfInet, KSockDatagram, KProtocolInetUdp, iConnection));
69 // By default, we listen on the same port as then we use for the SA - can be different on a negative test
70 TInt listenPort(KClientPort);
71 GetIntFromConfig(ConfigSection(), _L("ListenPort"), listenPort);
73 // Create and bind the client socket
75 User::LeaveIfError(listenAddr.Input(KDefaultListenAddr));
76 listenAddr.SetPort(listenPort);
77 User::LeaveIfError(iClientSocket.Bind(listenAddr));
79 TPtrC serverAddrFromConfig;
80 if (GetStringFromConfig(ConfigSection(), _L("ServerAddress"), serverAddrFromConfig))
81 {// If the IP address of the server is specified explicitly in the configuration file, use it as the server address.
82 // This specification is made when the server is a remote host.
83 INFO_PRINTF2(_L("Assign server address from the configuration: %S"), &serverAddrFromConfig);
84 User::LeaveIfError(iServerAddr.Input(serverAddrFromConfig));
87 {// If the server IP address is not specified, try to find out the own IP address of the device
88 // by looking up its ethernet interface. It means that the client and server are running on the same device.
89 TBool srvAddrFound = EFalse;
90 TSoInetInterfaceInfo networkInfo;
91 TPckg<TSoInetInterfaceInfo> opt(networkInfo);
92 User::LeaveIfError(iClientSocket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl));
97 res = iClientSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, opt);
98 if(!opt().iAddress.IsUnspecified())
100 opt().iAddress.Output(ip);
101 INFO_PRINTF3(_L("Interface Name:%S Interface Address:%S"),&(opt().iName), &ip);
102 // Skip loopback interfaces and get the address of first extrenal interface
103 if(opt().iName.Find(_L("loop")) == KErrNotFound)
105 INFO_PRINTF2(_L("Assign server address as %S"), &ip);
106 iServerAddr = opt().iAddress;
107 srvAddrFound = ETrue;
111 }while (res == KErrNone);
112 // If the device doesn't have got an ethernet interface or its address has not been obtained, try to use a default one.
115 INFO_PRINTF2(_L("Couldn't find a proper interface. Assign server address as %S"), &KDefaultServerAddr);
116 User::LeaveIfError(iServerAddr.Input(KDefaultServerAddr));
119 iServerAddr.SetPort(KServerPort);
121 // Connect the UDP socket - this is needed for the sub-connection interface
122 iClientSocket.Connect(iServerAddr, status);
123 User::WaitForRequest(status);
124 User::LeaveIfError(status.Int());
126 // The client address is not equal to the listening address, since the PF_KEY association set
127 // by key stream sink needs to have a well defined dest. address and not INADDR_ANY used on the listening socket
128 // The section below should be removed if and when we switch to sub-connection interface
129 User::LeaveIfError(iClientAddr.Input(KClientLocalAddr));
130 iClientAddr.SetPort(KClientPort);
132 iAssociationsNumber = 1;
133 GetIntFromConfig(ConfigSection(), _L("AssociationsNumber"), iAssociationsNumber);
135 iAuthenticationUsed = ETrue;
136 GetBoolFromConfig(ConfigSection(), _L("UseAuthentication"), iAuthenticationUsed);
138 TPtrC encryptionKeyFromConfig;
139 if (GetStringFromConfig(ConfigSection(), _L("EncryptionKey"), encryptionKeyFromConfig))
141 iEncryptionKey = HBufC8::NewL(encryptionKeyFromConfig.Length());
142 iEncryptionKey->Des().Copy(encryptionKeyFromConfig);
145 iEncryptionKey = KDefaultEncryptionKey().AllocL();
147 iEncryptionAlgorithm = EAES_128_CBC;
148 GetIntFromConfig(ConfigSection(), _L("EncryptionAlgorithm"), iEncryptionAlgorithm);
150 if (iAuthenticationUsed)
152 TPtrC authenticationKeyFromConfig;
153 if (GetStringFromConfig(ConfigSection(), _L("AuthenticationKey"), authenticationKeyFromConfig))
155 iAuthenticationKey = HBufC8::NewL(authenticationKeyFromConfig.Length());
156 iAuthenticationKey->Des().Copy(authenticationKeyFromConfig);
159 iAuthenticationKey = KDefaultAuthenticationKey().AllocL();
160 iAuthenticationAlgorithm = EHMAC_SHA1;
161 GetIntFromConfig(ConfigSection(), _L("AuthenticationAlgorithm"), iAuthenticationAlgorithm);
164 iAuthenticationAlgorithm = ENoAuthentication;
166 return TestStepResult();
169 void ReceiveAndCompareBufL(RSocket &aSocket, const TDesC8 &aCompareTo)
171 HBufC8 *testBuf = HBufC8::NewLC(aCompareTo.Length());
172 TRequestStatus status;
173 TPtr8 testBufPtr(testBuf->Des());
174 aSocket.Recv(testBufPtr, 0, status);
175 User::WaitForRequest(status);
176 User::LeaveIfError(status.Int());
178 if (testBufPtr.Compare(aCompareTo) != 0)
179 User::Leave(KErrGeneral);
181 CleanupStack::PopAndDestroy(testBuf);
184 TUint32 ConvertToNetworkOrder(TUint32 aNum)
186 const TInt KMaxTUint32CStringLen = 11;
187 TUint8 temp[ KMaxTUint32CStringLen ];
188 LittleEndian::Put32( temp, aNum );
189 return BigEndian::Get32( temp );
192 // Check whether a particular SA is present in SADB - used for testing the IPsec key stream decoder.
193 // Two modes supported: positive and negative - in the negative one the SA should not be present
194 // Some of the code is copy/pasted from IPSec key stream production code, since it cannot be exposed in the
196 static void ValidateSadbL(TInt32 aSpi, TInetAddr &aSourceAddr, TInetAddr &aDestAddr, TBool aPositiveTesting)
198 RSocketServ socketServ;
199 User::LeaveIfError(socketServ.Connect());
200 CleanupClosePushL(socketServ);
202 User::LeaveIfError(rsadb.Open(socketServ));
203 CleanupClosePushL(rsadb);
204 // We use the same sequence number as the SPI - since we use different SPI in our tests
205 // this provides uniqueness required of sequence id-s
206 TPfkeySendMsg sendMessage(SADB_GET, SADB_SATYPE_ESP, aSpi, RProcess().Id());
207 TUint32 bigEndianSpi(ConvertToNetworkOrder(aSpi));
208 sendMessage.Add( Int2Type<SADB_EXT_SA>(), bigEndianSpi, 0, 0);
209 sendMessage.Add( Int2Type<SADB_EXT_ADDRESS_SRC>(), aSourceAddr, 0, 0 );
210 sendMessage.Add( Int2Type<SADB_EXT_ADDRESS_DST>(), aDestAddr, 0, 0 );
212 TRequestStatus status;
213 rsadb.FinalizeAndSend(sendMessage, status);
214 User::WaitForRequest(status);
215 User::LeaveIfError(status.Int());
217 // Since SADB sends replies to _all_ sockets, we must take care to filter out replies which
218 // do not correspond to our request. A similar logic is done in IPSec key stream decoder, but it is private there
219 // and cannot be reused
222 TPfkeyRecvMsg receivedReply;
223 rsadb.ReadRequest(receivedReply, status);
224 User::WaitForRequest(status);
225 User::LeaveIfError(status.Int());
227 sadb_msg &msgHeader = receivedReply.MsgHdr();
229 if (msgHeader.sadb_msg_pid != RProcess().Id())
231 if (msgHeader.sadb_msg_seq != aSpi)
234 // If the message types does not match, then the problem is internal in IPSec - it should not answer with a different message type
235 if (msgHeader.sadb_msg_type != SADB_GET)
236 User::Leave(KErrArgument);
237 if (msgHeader.sadb_msg_errno ^ aPositiveTesting == 0)
239 // Mimic the logic in IPSec error handling (see the Update function in key_msg.cpp)
240 TUint16 reservedField = (TUint16)msgHeader.sadb_msg_reserved << 8;
241 TUint16 errnoField = msgHeader.sadb_msg_errno;
242 User::Leave(-(reservedField + errnoField));
246 CleanupStack::PopAndDestroy(2, &socketServ);
249 void CScafIpSec::CallValidateSadbL(TInt32 aSpi, TInetAddr &aSourceAddr, TInetAddr &aDestAddr, TBool aPositiveTesting)
251 ValidateSadbL(aSpi, aSourceAddr, aDestAddr, aPositiveTesting);
254 void CScafIpSec::InitializeAlgorithmsL(CKeyStreamSink *aKeyStreamSink)
256 aKeyStreamSink->SetEncryptionAlgorithmL((TEncryptionAlgorithm)iEncryptionAlgorithm);
257 aKeyStreamSink->SetAuthenticationAlgorithmL((TAuthenticationAlgorithm)iAuthenticationAlgorithm);
260 CKeyStreamSink *CScafIpSec::CreateDefaultKeyStreamSinkLC()
262 // when RSubConnection interface starts working use the below code
264 RSubConnection subconn;
265 User::LeaveIfError(subconn.Open(ss, RSubConnection::ECreateNew, conn));
266 CleanupClosePushL(subconn);
268 subconn.Add(clientSocket, status);
269 User::WaitForRequest(status);
270 User::LeaveIfError(status.Int());
272 CProtectedStreamDesc *protectedStreamDesc = CIPSecProtectedStreamDesc::NewLC(subconn);
275 CProtectedStreamDesc *protectedStreamDesc = CIpSecProtectedStreamDesc::NewLC(iServerAddr, iClientAddr);
276 CKeyStreamSink *keyStreamSink = protectedStreamDesc->CreateKeyStreamSinkLC();
277 InitializeAlgorithmsL(keyStreamSink);
279 CleanupStack::Pop(keyStreamSink);
280 CleanupStack::PopAndDestroy(protectedStreamDesc);
281 CleanupStack::PushL(keyStreamSink);
282 return keyStreamSink;
285 void CScafIpSec::SendKeyAssociationToKeySinkL(TInt aSpi, CKeyStreamSink *aKeyStreamSink)
287 INFO_PRINTF2(_L("Sending key association with SPI %d"), aSpi);
288 CKeyAssociation *ipSecKeyAssociation = CIpSecKeyAssociation::NewL(aSpi, iEncryptionKey,
290 CleanupStack::PushL(ipSecKeyAssociation); // Not using NewLC directly, so that NewL and NewLC will both be covered in tests
292 aKeyStreamSink->ProcessNewKeyAssociationL(*ipSecKeyAssociation);
294 //aKeyStreamSink->ProcessNewKeyAssociationL(*ipSecKeyAssociation);
295 INFO_PRINTF2(_L("Sent key association with SPI %d"), aSpi);
296 CleanupStack::PopAndDestroy(ipSecKeyAssociation);
299 void CScafIpSec::AddAndValidateAssociationsL(CKeyStreamSink *aKeyStreamSink, TInt aSpiBase)
301 for (TInt i = 0; i < iAssociationsNumber; ++i)
303 SendKeyAssociationToKeySinkL(aSpiBase + i, aKeyStreamSink);
304 INFO_PRINTF2(_L("Validating key association with SPI %d"), aSpiBase + i);
305 ValidateSadbL(aSpiBase + i, iServerAddr, iClientAddr, ETrue);
306 INFO_PRINTF2(_L("Validated key association with SPI %d"), aSpiBase + i);
310 void CScafIpSec::ValidateNoAssociationsL(TInt aSpiBase)
312 // Check that after key stream decoder was removed, all the SA-s had been deleted
313 for (TInt i = 0; i < iAssociationsNumber; ++i)
314 ValidateSadbL(aSpiBase + i, iServerAddr, iClientAddr, EFalse);
315 INFO_PRINTF3(_L("Validated that no associations exist from SPI %d to SPI %d"), aSpiBase, aSpiBase + iAssociationsNumber - 1);
318 TVerdict CScafIpSec::doTestL()
320 CKeyStreamSink *keyStreamSink = CreateDefaultKeyStreamSinkLC();
322 TBool integrationTest(ETrue);
323 GetBoolFromConfig(ConfigSection(), _L("IntegrationTest"), integrationTest);
325 for (TInt i = 0; i < iAssociationsNumber; ++i)
327 SendKeyAssociationToKeySinkL(KTestSpiBase + i, keyStreamSink);
328 // Receive the packet and compare the data - disabled on automatic tests
331 ReceiveAndCompareBufL(iClientSocket, KTestData());
334 CleanupStack::PopAndDestroy(keyStreamSink);
335 return TestStepResult();
338 TVerdict CScafIpSec::doTestStepPostambleL()
340 delete iEncryptionKey;
341 delete iAuthenticationKey;
342 iClientSocket.Close();
346 iDecoderConfigurationArray.ResetAndDestroy();
348 INFO_PRINTF2(_L("HEAP CELLS: %d"), User::CountAllocCells());
351 return TestStepResult();
354 //-------------------------CScafIpSecDecoderIntegration---------------------------
356 CScafIpSecDecoderIntegration::CScafIpSecDecoderIntegration(CScafServer& aParent): CScafIpSec(aParent)
358 SetTestStepName(KScafIpSecDecoderIntegration);
361 TVerdict CScafIpSecDecoderIntegration::doTestL()
363 TBool integrationTest(ETrue);
364 GetBoolFromConfig(ConfigSection(), _L("IntegrationTest"), integrationTest);
366 CTestKeyStreamDecoderBase *keyStreamDecoder = NULL;
367 CSdpMediaField *sdp = NULL;
368 CSdpDocument* sdpDoc = NULL;
372 if(iDecoderConfigurationArray[0]->iPrivateFolderPath.Length())
374 privatePath.Set(iDecoderConfigurationArray[0]->iPrivateFolderPath);
378 privatePath.Set(KStaPrivateFolder());
381 //Create an SDP document object and set the created key stream field object
382 sdpDoc = CreateSdpDocumentLC();
384 //Create an SDP object with an attribute requiring the service protected RO
385 sdp = CreateSdpLC(0);
386 AddMediaFieldL(*sdpDoc, sdp);
387 CleanupStack::Pop(sdp);
389 INFO_PRINTF1(_L("Decoder integration test - created SDP"));
390 CKeyStreamSink *keyStreamSink = CreateDefaultKeyStreamSinkLC();
392 //Create a test agent key stream decoder
393 if(iDecoderConfigurationArray[0]->iSingleProcessAgent)
395 // Single Process Stream Agent
396 keyStreamDecoder = CTestSingleProcessKeyStreamDecoder::NewL(*keyStreamSink, *sdp, *sdpDoc);
400 // Client/Server Stream Agent
401 keyStreamDecoder = CTestAgentKeyStreamDecoder::NewL(*keyStreamSink, *sdp, *sdpDoc);
404 INFO_PRINTF1(_L("Decoder integration test - created key stream decoder"));
405 CleanupStack::PushL(keyStreamDecoder);
407 for (TInt i = 0; i < iAssociationsNumber; ++i)
409 INFO_PRINTF2(_L("Decoder integration test - before sending association %d"), i + 1);
410 keyStreamDecoder->SendIpSecAssociationL(KTestSpiBase + i, iEncryptionKey, iAuthenticationKey);
412 ReceiveAndCompareBufL(iClientSocket, KTestData());
414 ValidateSadbL(KTestSpiBase + i, iServerAddr, iClientAddr, ETrue);
415 INFO_PRINTF2(_L("Decoder integration test - after receiving and comparing buffer for association %d"), i + 1);
417 CleanupStack::PopAndDestroy(2, keyStreamSink);
418 CleanupStack::PopAndDestroy(); // sdpDoc
419 return TestStepResult();
422 //-------------------------CScafIpSecSadbVerification---------------------------
424 CScafIpSecSadbVerification::CScafIpSecSadbVerification(CScafServer& aParent): CScafIpSec(aParent)
426 SetTestStepName(KScafIpSecSadbVerification);
429 TVerdict CScafIpSecSadbVerification::doTestL()
431 CKeyStreamSink *keyStreamSink = CreateDefaultKeyStreamSinkLC();
432 AddAndValidateAssociationsL(keyStreamSink, KTestSpiBase);
433 CleanupStack::PopAndDestroy(keyStreamSink);
435 ValidateNoAssociationsL(KTestSpiBase);
436 return TestStepResult();
439 //-------------------------CScafIpSecSadbVerificationConcurrency---------------------------
441 CScafIpSecSadbVerificationConcurrency::CScafIpSecSadbVerificationConcurrency(CScafServer& aParent): CScafIpSec(aParent)
443 SetTestStepName(KScafIpSecSadbVerificationConcurrency);
446 template <class T> void ResetAndDestroyPointerArray(TAny *pointerArray)
448 reinterpret_cast<RPointerArray<T> *>(pointerArray)->ResetAndDestroy();
451 struct CThreadFuncParam : public CBase
453 CThreadFuncParam(TInt aBaseSpi, TInt aAssociationsNumber)
454 : iBaseSpi(aBaseSpi), iAssociationsNumber(aAssociationsNumber) {}
457 TInt iAssociationsNumber;
460 void TestThreadFuncL(CThreadFuncParam *aThreadParam)
462 // Since this function runs in another thread, we cannot use member stack variables
463 // of the CScafIpSecSadbVerificationConcurrency class - some of the functionality has to be duplicated here
464 TInetAddr clientAddr, serverAddr;
465 User::LeaveIfError(clientAddr.Input(KClientLocalAddr));
466 clientAddr.SetPort(KClientPort);
467 User::LeaveIfError(serverAddr.Input(KDefaultServerAddr));
468 serverAddr.SetPort(KServerPort);
469 RSocketServ socketServ;
470 User::LeaveIfError(socketServ.Connect());
471 CleanupClosePushL(socketServ);
473 User::LeaveIfError(rsadb.Open(socketServ));
474 CleanupClosePushL(rsadb);
476 HBufC8 *encryptionKey = KDefaultEncryptionKey().AllocLC();
477 HBufC8 *authenticationKey = KDefaultAuthenticationKey().AllocLC();
479 CProtectedStreamDesc *protectedStreamDesc = CIpSecProtectedStreamDesc::NewLC(serverAddr, clientAddr);
480 CKeyStreamSink *keyStreamSink = protectedStreamDesc->CreateKeyStreamSinkLC();
482 keyStreamSink->SetEncryptionAlgorithmL(EAES_128_CBC);
483 keyStreamSink->SetAuthenticationAlgorithmL(EHMAC_SHA1);
485 for (TInt i = 0; i < aThreadParam->iAssociationsNumber; ++i)
487 TInt spi = aThreadParam->iBaseSpi + i;
488 CKeyAssociation *ipSecKeyAssociation = CIpSecKeyAssociation::NewLC(spi, encryptionKey,
491 keyStreamSink->ProcessNewKeyAssociationL(*ipSecKeyAssociation);
493 CleanupStack::PopAndDestroy(ipSecKeyAssociation);
494 ValidateSadbL(spi, serverAddr, clientAddr, ETrue);
497 CleanupStack::PopAndDestroy(keyStreamSink);
499 for (TInt i = 0; i < aThreadParam->iAssociationsNumber; ++i)
500 ValidateSadbL(aThreadParam->iBaseSpi + i, serverAddr, clientAddr, EFalse);
502 CleanupStack::PopAndDestroy(5, &socketServ); // socketServ, rsadb, protectedStreamDesc, copiedEncryptionKey, copiedAuthenticationKey
505 TInt TestThreadFunc(TAny *aThreadParam)
507 CThreadFuncParam *param = reinterpret_cast<CThreadFuncParam *>(aThreadParam);
508 CTrapCleanup* cleanup=CTrapCleanup::New();
509 TRAPD(err, TestThreadFuncL(param));
514 void ThreadCleanup(TAny *aThread)
516 ((RThread *)aThread)->Terminate(0);
517 ((RThread *)aThread)->Close();
520 void CleanupThreadArray(TAny *aThreadArray)
522 RArray<RThread> *threadArrayPtr = reinterpret_cast<RArray<RThread> *>(aThreadArray);
523 TInt threadsNum = threadArrayPtr->Count();
524 for (TInt i = 0; i < threadsNum; ++i)
526 ThreadCleanup(&(*threadArrayPtr)[i]);
528 threadArrayPtr->Close();
531 TVerdict CScafIpSecSadbVerificationConcurrency::doTestL()
533 const TInt KDefaultThreadsNumber = 10;
534 TInt threadsNumber(KDefaultThreadsNumber);
535 GetIntFromConfig(ConfigSection(), _L("ThreadsNumber"), threadsNumber);
537 RArray<RThread> spawnedThreads;
538 CleanupStack::PushL(TCleanupItem(CleanupThreadArray, &spawnedThreads));
539 RPointerArray<CThreadFuncParam> threadParams;
540 CleanupStack::PushL(TCleanupItem(ResetAndDestroyPointerArray<CKeyStreamSink>, &threadParams));
543 for (; i < threadsNumber; ++i)
545 const TInt KHeapSize = 0x600;
547 TInt spiBase = KTestSpiBase + iAssociationsNumber * i;
549 CThreadFuncParam *threadParam = new (ELeave) CThreadFuncParam(spiBase, iAssociationsNumber);
550 CleanupStack::PushL(threadParam);
551 threadParams.AppendL(threadParam);
552 CleanupStack::Pop(threadParam);
555 threadName.Format(_L("CAF IPSec Thread %d"), i);
556 User::LeaveIfError(thread.Create(threadName, TestThreadFunc, KDefaultStackSize, KHeapSize, KHeapSize, threadParam));
557 CleanupStack::PushL(TCleanupItem(ThreadCleanup, &thread));
558 spawnedThreads.AppendL(thread);
559 // The thread itself is owned by the array
560 CleanupStack::Pop(&thread);
563 for (i = 0; i < threadsNumber; ++i)
564 spawnedThreads[i].Resume();
566 for (i = 0; i < threadsNumber; ++i)
568 TRequestStatus status;
569 // Wait for all threads to finish
570 spawnedThreads[i].Logon(status);
571 User::WaitForRequest(status);
572 if (status.Int() != KErrNone)
574 ERR_PRINTF3(_L("In IpSec concurrency tests, thread %d has returned with status %d"), i, status.Int());
575 SetTestStepResult(EFail);
578 INFO_PRINTF2(_L("IPSec concurrency test - thread %d finished successfully"), i);
581 CleanupStack::PopAndDestroy(2); // threadParams, spawnedThreads - cleanup item
582 return TestStepResult();
585 //-------------------------CScafIpSecNegative---------------------------
587 CScafIpSecNegative::CScafIpSecNegative(CScafServer& aParent): CScafIpSec(aParent)
589 SetTestStepName(KScafIpSecNegative);
592 TVerdict CScafIpSecNegative::doTestL()
594 TInt encryptionKeyLength(iEncryptionKey->Length());
595 ASSERT(encryptionKeyLength);
596 // Save encryption and authentication key to temp. variable
597 HBufC8 *malformedEncryptionKey = HBufC8::NewLC(encryptionKeyLength);
598 TPtr8 malformedEncryptionKeyPtr(malformedEncryptionKey->Des());
599 malformedEncryptionKeyPtr.Copy(iEncryptionKey->Des());
601 TInt authenticationKeyLength(iAuthenticationKey->Length());
602 ASSERT(authenticationKeyLength);
603 HBufC8 *malformedAuthenticationKey = HBufC8::NewLC(authenticationKeyLength);
604 TPtr8 malformedAuthenticationKeyPtr(malformedAuthenticationKey->Des());
605 malformedAuthenticationKeyPtr.Copy(iAuthenticationKey->Des());
606 // Delete the last characters from keys - this makes them invalid
607 malformedEncryptionKeyPtr.SetLength(encryptionKeyLength - 1);
608 malformedAuthenticationKeyPtr.SetLength(authenticationKeyLength - 1);
610 CKeyStreamSink *keyStreamSink = CreateDefaultKeyStreamSinkLC();
611 // Send new assoc. - should fail
612 CKeyAssociation *malformedKeyAssociation = CIpSecKeyAssociation::NewLC(KTestSpiBase, malformedEncryptionKey,
613 malformedAuthenticationKey);
614 TRAPD(err, keyStreamSink->ProcessNewKeyAssociationL(*malformedKeyAssociation));
615 if (err != EIpsec_BadCipherKey)
617 if (err != KErrNoMemory)
619 ERR_PRINTF2(_L("In IpSec negative tests, an incorrect error was returned when setting invalid keys. The error is %d"), err);
622 SetTestStepResult(EFail);
626 INFO_PRINTF1(_L("IPSec negative test - received correct error on malformed association"));
627 // Here, we should have had a test which verifies that IPSec key stream sink rejects non-IPSec associations
628 // Due to lack of dynamic_cast support, it is omitted.
630 // Send twice a new assoc. - should fail. KTestSpiBase + 1 is used
631 // since IPSec implementation adds the malformed assoc. from step A to DB despite returning an error
632 SendKeyAssociationToKeySinkL(KTestSpiBase + 1, keyStreamSink);
633 INFO_PRINTF1(_L("IPSec negative test - sent correct association"));
634 TRAP(err, SendKeyAssociationToKeySinkL(KTestSpiBase + 1, keyStreamSink));
635 if (err != KErrAlreadyExists)
637 if (err != KErrNoMemory)
639 ERR_PRINTF2(_L("In IpSec negative tests, an incorrect error was returned when setting duplicate SA. The error is %d"), err);
642 SetTestStepResult(EFail);
646 INFO_PRINTF1(_L("IPSec negative test - received correct error on duplicate association"));
647 CleanupStack::PopAndDestroy(4, malformedEncryptionKey); // malformedEncryptionKey, malformedAuthenticationKey, keyStreamSink, malformedKeyAssociation
648 return TestStepResult();
651 //-------------------------CScafIpSecMultipleSinks---------------------------
653 CScafIpSecMultipleSinks::CScafIpSecMultipleSinks(CScafServer& aParent): CScafIpSec(aParent)
655 SetTestStepName(KScafIpSecMultipleSinks);
658 TInt KDefaultNumberOfSinks = 10;
660 TVerdict CScafIpSecMultipleSinks::doTestL()
662 // Read from configuration the number of sinks
663 TInt sinksNumber(KDefaultNumberOfSinks);
664 GetIntFromConfig(ConfigSection(), _L("SinksNumber"), sinksNumber);
665 // Instantiate decoders using the same protected stream desc.
666 CProtectedStreamDesc *protectedStreamDesc = CIpSecProtectedStreamDesc::NewLC(iServerAddr, iClientAddr);
667 RPointerArray<CKeyStreamSink> sinkArray;
668 CleanupStack::PushL(TCleanupItem(ResetAndDestroyPointerArray<CKeyStreamSink>, &sinkArray));
670 for (; i < sinksNumber; ++i)
672 CKeyStreamSink *sink = protectedStreamDesc->CreateKeyStreamSinkLC();
673 User::LeaveIfError(sinkArray.Append(sink));
674 InitializeAlgorithmsL(sink);
675 CleanupStack::Pop(sink);
676 INFO_PRINTF2(_L("IPSec multiple sinks test - instantiated decoder %d"), i);
678 // Loop over decoders and number of associations, submit associations and validate them
679 for (i = 0; i < iAssociationsNumber; ++i)
680 for (TInt j = 0; j < sinksNumber; ++j)
682 TInt spi = KTestSpiBase + j * iAssociationsNumber + i;
683 SendKeyAssociationToKeySinkL(spi, sinkArray[j]);
684 ValidateSadbL(spi, iServerAddr, iClientAddr, ETrue);
688 CleanupStack::PopAndDestroy(&sinkArray);
689 // Validate that there are no associations
690 for (; i < sinksNumber; ++i)
692 ValidateNoAssociationsL(KTestSpiBase + i * iAssociationsNumber);
694 CleanupStack::PopAndDestroy(protectedStreamDesc);
695 return TestStepResult();
698 //-------------------------CScafIpSecAlgorithmChange---------------------------
700 CScafIpSecAlgorithmChange::CScafIpSecAlgorithmChange(CScafServer& aParent): CScafIpSec(aParent)
702 SetTestStepName(KScafIpSecAlgorithmChange);
705 TVerdict CScafIpSecAlgorithmChange::doTestL()
707 CKeyStreamSink *keyStreamSink = CreateDefaultKeyStreamSinkLC();
708 SendKeyAssociationToKeySinkL(KTestSpiBase, keyStreamSink);
709 TRAPD(err, keyStreamSink->SetEncryptionAlgorithmL(ENoEncryption));
710 if (err != KErrNotSupported)
712 ERR_PRINTF2(_L("In IpSec algorithm change, an incorrect error was returned when setting NULL encryption. The error is %d"), err);
713 SetTestStepResult(EFail);
715 INFO_PRINTF1(_L("IPSec algorithms change test - received correct error after modifying encryption algorithm"));
716 TRAP(err, keyStreamSink->SetAuthenticationAlgorithmL(ENoAuthentication));
717 if (err != KErrNotSupported)
719 ERR_PRINTF2(_L("In IpSec algorithm change, an incorrect error was returned when setting NULL authentication. The error is %d"), err);
720 SetTestStepResult(EFail);
722 INFO_PRINTF1(_L("IPSec algorithms change test - received correct error after modifying authentication algorithm"));
723 CleanupStack::PopAndDestroy(keyStreamSink);
724 return TestStepResult();
728 //-------------------------CScafIpSecSARemoval---------------------------
730 CScafIpSecSARemoval::CScafIpSecSARemoval(CScafServer& aParent): CScafIpSec(aParent)
732 SetTestStepName(KScafIpSecSARemoval);
735 const TUint KDefaultMaxSpiNumber = 3; // The constant is copied from IPSec's sink production code - it is not exposed in its interface
737 TVerdict CScafIpSecSARemoval::doTestL()
739 CKeyStreamSink *keyStreamSink = CreateDefaultKeyStreamSinkLC();
740 if (iAssociationsNumber <= KDefaultMaxSpiNumber)
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);
743 User::Leave(KErrArgument);
746 for (; i < iAssociationsNumber; ++i)
748 SendKeyAssociationToKeySinkL(KTestSpiBase + i, keyStreamSink);
750 INFO_PRINTF2(_L("IPSec SA removal test - sent %d associations successfully"), iAssociationsNumber);
751 for (i = 0; i < iAssociationsNumber - KDefaultMaxSpiNumber; ++i)
753 ValidateSadbL(KTestSpiBase + i, iServerAddr, iClientAddr, EFalse);
755 INFO_PRINTF3(_L("IPSec SA removal test - verified that associations %d to %d do not exist"), KTestSpiBase, KTestSpiBase + iAssociationsNumber - KDefaultMaxSpiNumber - 1);
756 for (i = iAssociationsNumber - KDefaultMaxSpiNumber; i < iAssociationsNumber; ++i)
758 ValidateSadbL(KTestSpiBase + i, iServerAddr, iClientAddr, ETrue);
760 INFO_PRINTF3(_L("IPSec SA removal test - verified that associations %d to %d exist"), KTestSpiBase + iAssociationsNumber - KDefaultMaxSpiNumber, KTestSpiBase + iAssociationsNumber - 1);
762 CleanupStack::PopAndDestroy(keyStreamSink);
763 return TestStepResult();