networksecurity/tlsprovider/Test/tlstest2/newtlsstepbase.cpp
changeset 0 af10295192d8
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file newtlsstepbase.cpp
       
    18  @internalTechnology
       
    19 */
       
    20 #include "newtlsstepbase.h"
       
    21 #include "psuedorandom.h"
       
    22 #include <tlsprovinterface.h>
       
    23 
       
    24 CNewTlsStepBase::~CNewTlsStepBase()
       
    25 	{
       
    26 	// values populated at preamble
       
    27  	delete iActive;
       
    28 	delete iSched;
       
    29 	delete iServerRandom;
       
    30 	delete iClientRandom;
       
    31 	delete iPskKey;
       
    32 	delete iPskIdentity;
       
    33 	
       
    34 	// values populated at test time. need to add appropiate destruction for OOM testing
       
    35 	delete iClientMacSecret;
       
    36 	delete iServerMacSecret;
       
    37 
       
    38 	delete iClientWriteSecret;
       
    39 	delete iServerWriteSecret;
       
    40 
       
    41 	delete iClientInitVector;
       
    42 	delete iServerInitVector;
       
    43 	}
       
    44 	
       
    45 TVerdict CNewTlsStepBase::doTestStepPreambleL()
       
    46 	{
       
    47  	ConstructL();
       
    48 	
       
    49 	GetBoolFromConfig(ConfigSection(), _L("OOMCondition"),iOOMCondition);
       
    50 	GetBoolFromConfig(ConfigSection(), _L("OOMAllowNonMemoryErrors"),iOOMAllowNonMemoryErrors);
       
    51 		
       
    52 	// Reads PSK values if included in INI file.
       
    53 	ReadPskToBeUsedL();
       
    54 	
       
    55 	if(!UsePsk())
       
    56 		{
       
    57 		// Read Diffie Hellman parameters only if not intending to use PSKs.
       
    58 	    TRAPD(err,ReadDHParamsL());
       
    59 	    if(err == KErrNone)
       
    60 		    {
       
    61 		    iUseDHParams = ETrue; 	
       
    62 		    }
       
    63 		 else
       
    64 			{
       
    65 		    iUseDHParams = EFalse; 	
       
    66 		    }
       
    67 		// read server certificate form INI file.
       
    68 		iServerCertificate = ServerCertificateL();
       
    69 		
       
    70 		// Reads server private key from INI file.
       
    71 		iServerPrivateKey = ServerPrivateKeyL();
       
    72 		}
       
    73 	
       
    74 	// Reads if NULL ciphers suites are to be allowed from INI file.
       
    75 	ReadUseNullCipher();
       
    76 	
       
    77 	// Reads server random from INI file.
       
    78 	iServerRandom = ServerRandomL();
       
    79 	
       
    80 	// Reads client random from INI file.
       
    81 	iClientRandom = ClientRandomL();
       
    82 	
       
    83 	// Reads cipher Suites from INI file.
       
    84 	iCipherSuite = CipherSuiteL();
       
    85 	
       
    86 	// Reads protocol version from INI file.
       
    87 	iProtocolVersion = ProtocolVersionL(); 
       
    88 	
       
    89 	// Gets session ID from INI file.
       
    90 	iSessionId = SessionId();
       
    91 	
       
    92 	// Gets domain name.
       
    93 	iDomainName.Set(DomainNameL());
       
    94 	
       
    95 	// key material.
       
    96 	iClientMacSecret = NULL;
       
    97 	iServerMacSecret = NULL;
       
    98     iClientWriteSecret = NULL;
       
    99     iServerWriteSecret = NULL;
       
   100     iClientInitVector = NULL;
       
   101     iServerInitVector = NULL;
       
   102 	
       
   103 	return EPass;
       
   104 	}
       
   105 	
       
   106 TVerdict CNewTlsStepBase::doTestStepL()
       
   107 	{
       
   108  	if (!iOOMCondition)
       
   109 		{
       
   110 		 doTestL(); 
       
   111 		}
       
   112 	else
       
   113 		{
       
   114  		return doOOMTestL();
       
   115 	    }	
       
   116    	return TestStepResult();
       
   117 	}
       
   118 
       
   119 TVerdict CNewTlsStepBase::doOOMTestL()
       
   120 	{
       
   121 	TVerdict verdict = EFail;
       
   122 	TInt countAfter = 0;
       
   123 	TInt countBefore = 0;
       
   124 	for (TInt oomCount = 0; ; oomCount++)
       
   125 		{
       
   126 		INFO_PRINTF2(_L("==== Number of memory allocations %d ===="), oomCount);
       
   127 
       
   128 		verdict = EFail;
       
   129 		__UHEAP_RESET;
       
   130 		__UHEAP_SETFAIL(RHeap::EDeterministic, oomCount);
       
   131 		countBefore = User::CountAllocCells();
       
   132 
       
   133 //		__UHEAP_MARK; // debug.
       
   134 
       
   135 		TRAPD(error, doTestL());// ----> This is the actual test that runs under OOM conditions.
       
   136 
       
   137 		countAfter = User::CountAllocCells();
       
   138 
       
   139 		if(countBefore != countAfter)
       
   140 			{
       
   141 			INFO_PRINTF3(_L("Heap alloc count: %d final vs %d initial"), countAfter,countBefore);
       
   142 			}  
       
   143 
       
   144 //		__UHEAP_MARKEND; // debug	
       
   145 		__UHEAP_RESET;
       
   146 
       
   147 		if(error == KErrNone)  // First posibility: Test sequence was able to run to completion
       
   148 			{
       
   149 			verdict = EPass;
       
   150 			INFO_PRINTF1(_L("OOM Test sequence completed"));
       
   151 
       
   152 			if(countBefore != countAfter)
       
   153 				{
       
   154 				// Memory has to balance.
       
   155 				verdict = EFail;
       
   156 				INFO_PRINTF1(_L("Memory did not balance. Test outcome : Fail"));
       
   157 				break;
       
   158 				}  
       
   159 			break;
       
   160 			} 
       
   161 		// Second possibility: Test sequence was NOT completed and error other than KErrNoMemory was returned. 
       
   162 		else if (error != KErrNoMemory)  
       
   163 			{
       
   164 			if(iOOMAllowNonMemoryErrors == EFalse)
       
   165 				{
       
   166 				INFO_PRINTF1(_L("Test outcome : Fail"));
       
   167 				INFO_PRINTF2(_L("Non KErrNoMemory returned : %d"), error);
       
   168 				verdict = EFail;
       
   169 				break;	
       
   170 				}
       
   171 
       
   172 			if(countBefore != countAfter)
       
   173 				{
       
   174 				// For any error returned memory has to balance.
       
   175 				verdict = EFail;
       
   176 				INFO_PRINTF1(_L("Memory did not balance. Test outcome : Fail"));
       
   177 				break;
       
   178 				}  
       
   179 			}
       
   180 		// Third possibility: Test sequence was NOT completed and error KErrNoMemory was returned. 
       
   181 		else   
       
   182 			{
       
   183 			if (countBefore != countAfter)
       
   184 				{
       
   185 				verdict = EFail;
       
   186 				INFO_PRINTF2(_L("OOM Status %d"),error);
       
   187 				INFO_PRINTF2(_L("MEMORY DID NOT BALANCE!!. OOM Failed at %d"), oomCount);
       
   188 				break;  
       
   189 				}   
       
   190 			}  
       
   191 		INFO_PRINTF2(_L("OOM Failed Point status %d"), error);
       
   192 		}  // End of for loop.
       
   193 	SetTestStepResult(verdict);
       
   194 	return verdict;	
       
   195 	}
       
   196 	
       
   197 void CNewTlsStepBase::doTestL()
       
   198 	{
       
   199 	ASSERT(EFail);	
       
   200 	}
       
   201 	
       
   202 void CNewTlsStepBase::ConstructL()
       
   203 	{
       
   204 	iSched = new(ELeave) CActiveScheduler;
       
   205 	CActiveScheduler::Install(iSched);
       
   206 	iActive = new (ELeave) CGenericActive;
       
   207 	}
       
   208 	
       
   209 TInt CNewTlsStepBase::LeanVerifyServerCertificate(CX509Certificate*& aCertOut, HBufC8* aCertIn)
       
   210 	{
       
   211   	iProvider->VerifyServerCertificate(aCertIn->Des(), aCertOut, iActive->iStatus);
       
   212  	iActive->Start();
       
   213  	return iActive->iStatus.Int();   
       
   214 	}
       
   215 	
       
   216 
       
   217 TInt CNewTlsStepBase::LeanCreateSession()
       
   218 	{
       
   219 
       
   220 	TRAPD(error,iProvider->CreateL(iSession, iActive->iStatus));
       
   221 	if(error)
       
   222 		{
       
   223 		return error;	
       
   224 		}
       
   225 	iActive->Start();
       
   226 	return iActive->iStatus.Int();
       
   227 	}
       
   228 	
       
   229 TInt CNewTlsStepBase::LeanClientKeyExchange(HBufC8*& aMessageOut)
       
   230 	{
       
   231 	iSession->ClientKeyExchange(aMessageOut, iActive->iStatus);
       
   232 	iActive->Start();
       
   233 	return iActive->iStatus.Int();
       
   234 	}
       
   235 	
       
   236 HBufC8* CNewTlsStepBase::LeanDerivePreMasterSecretL(const TDesC8& aClientKeyExMessage,CDecPKCS8Data* aServerKeyData )
       
   237 	{
       
   238 	// Look up the cipher suite we used for this test
       
   239 	CTlsCryptoAttributes* atts = iProvider->Attributes();
       
   240 	
       
   241 	TInt index = LeanCipherSuiteIndex(atts->iCurrentCipherSuite);
       
   242 	if (index < 0)
       
   243 		{
       
   244 		INFO_PRINTF3(_L("Failed! Could not find cipher 0x%02x.0x%02x, did the ECOM plugin load okay?"),
       
   245 			  atts->iCurrentCipherSuite.iHiByte, atts->iCurrentCipherSuite.iLoByte);
       
   246 		User::Leave(KErrNotFound);
       
   247 		}
       
   248 
       
   249 	HBufC8* ret = NULL;
       
   250 
       
   251 	// currently, we only support three key exhange algorithms, so that is what we test here
       
   252 	switch (iSuites[index].CipherDetails()->iKeyExAlg)
       
   253 		{
       
   254 	case ERsa:
       
   255 		// decrypt the key exhange message with the "server" private key, and
       
   256 		// verify the version and that the premaster key is the right size...
       
   257 		{
       
   258 		CDecPKCS8Data* keyData = aServerKeyData;
       
   259 		CleanupStack::PushL(keyData);
       
   260 		
       
   261 		// we don't own this pointer...
       
   262 		CPKCS8KeyPairRSA* key = static_cast<CPKCS8KeyPairRSA*>(keyData->KeyPairData());
       
   263 		
       
   264 		CRSAPKCS1v15Decryptor* decryptor = CRSAPKCS1v15Decryptor::NewLC(key->PrivateKey());
       
   265 		
       
   266 		ret = HBufC8::NewLC(decryptor->MaxOutputLength());
       
   267 		TPtr8 ptr = ret->Des();
       
   268 		decryptor->DecryptL(aClientKeyExMessage, ptr);
       
   269 
       
   270 		CleanupStack::Pop(ret);
       
   271 		CleanupStack::PopAndDestroy(2, keyData); // decryptor
       
   272 		}
       
   273 		break;
       
   274 		
       
   275 	case EDHE:
       
   276 		{
       
   277 		RInteger clientX = RInteger::NewL(aClientKeyExMessage);
       
   278 		CleanupClosePushL(clientX);
       
   279 		
       
   280 		RInteger prime = RInteger::NewL(Prime());
       
   281 		CleanupClosePushL(prime);
       
   282 		
       
   283 		RInteger gen = RInteger::NewL(Generator());
       
   284 		CleanupClosePushL(gen);
       
   285 		
       
   286 		CDHPublicKey* clientKey = CDHPublicKey::NewL(prime, gen, clientX);
       
   287 		CleanupStack::Pop(3, &clientX); // prime, gen, adopted by clientKey
       
   288 		CleanupStack::PushL(clientKey);
       
   289 		
       
   290 		CDH* dh = CDH::NewLC(KeyPair()->PrivateKey());
       
   291 		ret = const_cast<HBufC8*>(dh->AgreeL(*clientKey));
       
   292 		
       
   293 		CleanupStack::PopAndDestroy(2, clientKey); // dh
       
   294 		}
       
   295 		break;
       
   296 		
       
   297 	case EPsk:
       
   298 		{
       
   299 		// For PSK cipher suites the premaster secret is formed as follows: 
       
   300 		// if the PSK is N octets long, concatenate a uint16 with the value N, 
       
   301 		// N zero octets, a second uint16 with the value N, and the PSK itself.
       
   302 		// REF: RFC4279
       
   303 		
       
   304 		ret = HBufC8::NewLC(PskKey()->Length()*2 + 4 );
       
   305 		ret->Des().FillZ(PskKey()->Length()*2 + 4);
       
   306  		TPtr8 ptr = ret->Des();
       
   307 		
       
   308 		// Populates first two field bytes values. 
       
   309 		ptr[0] = (PskKey()->Length() & 0xFF00 ) >> 8;
       
   310 		ptr[1] = PskKey()->Length() & 0xFF; 
       
   311 		
       
   312 		// Populates second two field bytes values. 
       
   313 		ptr[PskKey()->Length() + 2] = ptr[0];
       
   314 		ptr[PskKey()->Length() + 3] = ptr[1];
       
   315 		
       
   316 		// Populates the actual key value.
       
   317 		ptr.Replace(PskKey()->Length() + 4, PskKey()->Length(), PskKey()->Des() );
       
   318 		
       
   319 		CleanupStack::Pop(ret);
       
   320 		
       
   321 		}
       
   322 		break;
       
   323 
       
   324 	default:
       
   325 		User::Leave(KErrUnknown);
       
   326 		break;
       
   327 		}
       
   328 		
       
   329 	return ret;
       
   330 	}
       
   331 
       
   332 
       
   333 TInt CNewTlsStepBase::LeanCipherSuiteIndex(const TTLSCipherSuite& aSuite)
       
   334 	{
       
   335 	for (TInt i = 0 ; i < iSuites.Count() ; ++i)
       
   336 		{
       
   337 		if (iSuites[i] == aSuite)
       
   338 			{
       
   339 			return i;
       
   340 			};
       
   341 		}
       
   342 	return KErrNotFound;
       
   343 	}
       
   344 	
       
   345 
       
   346 HBufC8* CNewTlsStepBase::LeanComputeMasterSecretL(const TDesC8& aPremasterSecret)
       
   347 	{
       
   348 	if (iProvider->Attributes()->iNegotiatedProtocol == KSSL3_0)
       
   349 		{
       
   350 		return LeanComputeSslMasterSecretL(aPremasterSecret);
       
   351 		}
       
   352 	else if (iProvider->Attributes()->iNegotiatedProtocol == KTLS1_0)
       
   353 		{
       
   354 		return LeanComputeTlsMasterSecretL(aPremasterSecret);
       
   355 		}
       
   356 	else
       
   357 		{
       
   358 		// currently unknown protocol!
       
   359 		User::Leave(KErrUnknown);
       
   360 		return NULL; // keep the compiler happy..
       
   361 		}
       
   362 	}
       
   363 	
       
   364 HBufC8* CNewTlsStepBase::LeanComputeTlsMasterSecretL(const TDesC8& aPremasterSecret)
       
   365 	{
       
   366 	HBufC8* random = HBufC8::NewLC(KTLSServerClientRandomLen * 2);
       
   367 	
       
   368 	TTLSMasterSecretInput params = iProvider->Attributes()->iMasterSecretInput;
       
   369 	random->Des().Append(params.iClientRandom);
       
   370 	random->Des().Append(params.iServerRandom);
       
   371 	
       
   372 	_LIT8(KMasterSecretLabel, "master secret");
       
   373 	HBufC8* ret = CTls10PsuedoRandom::PseudoRandomL(aPremasterSecret, KMasterSecretLabel, 
       
   374 		*random, KTLSMasterSecretLen);
       
   375 	CleanupStack::PushL(ret);
       
   376 	
       
   377 	LeanComputeTlsCipherKeysL(*ret, *random);
       
   378 	
       
   379 	CleanupStack::Pop(ret);
       
   380 	CleanupStack::PopAndDestroy(random);
       
   381 	return ret;
       
   382 	}
       
   383 	
       
   384 HBufC8* CNewTlsStepBase::LeanComputeSslMasterSecretL(const TDesC8& aPremasterSecret)
       
   385 	{
       
   386 	HBufC8* random = HBufC8::NewLC(KTLSServerClientRandomLen * 2);
       
   387 	
       
   388 	TTLSMasterSecretInput params = iProvider->Attributes()->iMasterSecretInput;
       
   389 	random->Des().Append(params.iClientRandom);
       
   390 	random->Des().Append(params.iServerRandom);
       
   391 	
       
   392 	HBufC8* ret = CSsl30PsuedoRandom::PseudoRandomL(aPremasterSecret, *random, KTLSMasterSecretLen);
       
   393 	CleanupStack::PushL(ret);
       
   394 	
       
   395 	LeanComputeSslCipherKeysL(*ret, *random);
       
   396 	
       
   397 	CleanupStack::Pop(ret);
       
   398 	CleanupStack::PopAndDestroy(random);
       
   399 	return ret;
       
   400 	}
       
   401 	
       
   402 void CNewTlsStepBase::LeanComputeTlsCipherKeysL(const TDesC8& aMasterSecret, const TDesC8& aRandom)
       
   403 	{
       
   404 	// Look up the cipher suite we used for this test
       
   405 	CTlsCryptoAttributes* atts = iProvider->Attributes();
       
   406 	
       
   407 	TInt index = LeanCipherSuiteIndex(atts->iCurrentCipherSuite);
       
   408 	User::LeaveIfError(index);
       
   409 	
       
   410 	TTLSCipherSuite suite = iSuites[index];
       
   411 	
       
   412 	// Key material is:
       
   413 	// - 2 mac secrets of size hash_size
       
   414 	// - 2 bulk cipher secrets of size keymaterial_size
       
   415 	// - 2 initialisation vectors of size iv_size
       
   416 	
       
   417 	TInt hashSize = suite.CipherDetails()->iHashSize;
       
   418 	TInt keySize = suite.CipherDetails()->iKeyMaterial;
       
   419 	TInt ivSize = suite.CipherDetails()->iIVSize;
       
   420 	
       
   421 	TInt keyMaterialSize = (2*hashSize) + (2*keySize) + (2*ivSize);
       
   422 	
       
   423 	// This calculation uses the random data in the opposite order to the master secret
       
   424 	
       
   425 	HBufC8* random = HBufC8::NewLC(KTLSServerClientRandomLen * 2);
       
   426 	TTLSMasterSecretInput params = atts->iMasterSecretInput;
       
   427 	random->Des().Append(params.iServerRandom);
       
   428 	random->Des().Append(params.iClientRandom);
       
   429 	
       
   430 	_LIT8(KKeyExpansionLabel, "key expansion");
       
   431 	HBufC8* keyMaterial = CTls10PsuedoRandom::PseudoRandomL(aMasterSecret, KKeyExpansionLabel,
       
   432 	    *random, keyMaterialSize);		
       
   433 	CleanupStack::PushL(keyMaterial);
       
   434 		
       
   435 	iClientMacSecret = keyMaterial->Left(hashSize).AllocL();
       
   436 	iServerMacSecret = keyMaterial->Mid(hashSize, hashSize).AllocL();
       
   437 		
       
   438 	// if the cipher is exportable, we need to do further PRF calculations to get the keys
       
   439 	if (suite.CipherDetails()->iIsExportable)
       
   440 		{
       
   441 		TInt expandedKeySize = 	suite.CipherDetails()->iExpKeySize;
       
   442 		
       
   443 		_LIT8(KClientWriteLabel, "client write key");
       
   444 		iClientWriteSecret = CTls10PsuedoRandom::PseudoRandomL(keyMaterial->Mid(2*hashSize, keySize), 
       
   445 		    KClientWriteLabel, aRandom, expandedKeySize);
       
   446 			
       
   447 		_LIT8(KServerWriteLabel, "server write key");
       
   448 		iServerWriteSecret = CTls10PsuedoRandom::PseudoRandomL(keyMaterial->Mid((2*hashSize)+keySize, keySize),
       
   449 		    KServerWriteLabel, aRandom, expandedKeySize);
       
   450 			
       
   451 		_LIT8(KIVBlockLabel, "IV block");
       
   452 		HBufC8* ivMaterial = CTls10PsuedoRandom::PseudoRandomL(KNullDesC8, KIVBlockLabel, aRandom, 2*ivSize);
       
   453 		CleanupStack::PushL(ivMaterial);
       
   454 		
       
   455 		iClientInitVector = ivMaterial->Left(ivSize).AllocL();
       
   456 		iServerInitVector = ivMaterial->Right(ivSize).AllocL();
       
   457 		
       
   458 		CleanupStack::PopAndDestroy(ivMaterial);
       
   459 		}
       
   460 	else
       
   461 		{
       
   462 		// just devide the key material up in to its respective blocks
       
   463 		iClientWriteSecret = keyMaterial->Mid(2*hashSize, keySize).AllocL();
       
   464 		iServerWriteSecret = keyMaterial->Mid((2*hashSize)+keySize, keySize).AllocL();
       
   465 		iClientInitVector = keyMaterial->Mid((2*hashSize)+(2*keySize), ivSize).AllocL();
       
   466 		iServerInitVector = keyMaterial->Right(ivSize).AllocL();
       
   467 		}
       
   468 	
       
   469 	CleanupStack::PopAndDestroy(2, random); // keyMaterial
       
   470 	}
       
   471 	
       
   472 	
       
   473 void CNewTlsStepBase::LeanComputeSslCipherKeysL(const TDesC8& aMasterSecret, const TDesC8& aRandom)
       
   474 	{
       
   475 	// Look up the cipher suite we used for this test
       
   476 	CTlsCryptoAttributes* atts = iProvider->Attributes();
       
   477 	
       
   478 	TInt index = LeanCipherSuiteIndex(atts->iCurrentCipherSuite);
       
   479 	User::LeaveIfError(index);
       
   480 	
       
   481 	TTLSCipherSuite suite = iSuites[index];
       
   482 	
       
   483 	// Key material is:
       
   484 	// - 2 mac secrets of size hash_size
       
   485 	// - 2 bulk cipher secrets of size keymaterial_size
       
   486 	// - 2 initialisation vectors of size iv_size
       
   487 	
       
   488 	TInt hashSize = suite.CipherDetails()->iHashSize;
       
   489 	TInt keySize = suite.CipherDetails()->iKeyMaterial;
       
   490 	TInt ivSize = suite.CipherDetails()->iIVSize;
       
   491 	
       
   492 	TInt keyMaterialSize = (2*hashSize) + (2*keySize) + (2*ivSize);
       
   493 	
       
   494 	// This calculation uses the random data in the opposite order to the master secret
       
   495 	
       
   496 	HBufC8* random = HBufC8::NewLC(KTLSServerClientRandomLen * 2);
       
   497 	TTLSMasterSecretInput params = atts->iMasterSecretInput;
       
   498 	random->Des().Append(params.iServerRandom);
       
   499 	random->Des().Append(params.iClientRandom);
       
   500 	
       
   501 	HBufC8* keyMaterial = CSsl30PsuedoRandom::PseudoRandomL(aMasterSecret, *random, keyMaterialSize);		
       
   502 	CleanupStack::PushL(keyMaterial);
       
   503 	
       
   504 	iClientMacSecret = keyMaterial->Left(hashSize).AllocL();
       
   505 	iServerMacSecret = keyMaterial->Mid(hashSize, hashSize).AllocL();
       
   506 	
       
   507 	// if the cipher is exportable, we need to do further MD5 calculations to get the keys
       
   508 	if (suite.CipherDetails()->iIsExportable)
       
   509 		{
       
   510 		TInt expandedKeySize = 	suite.CipherDetails()->iExpKeySize;
       
   511 
       
   512 		CMessageDigest* md5dig = CMessageDigestFactory::NewDigestLC(CMessageDigest::EMD5);
       
   513 			
       
   514 		md5dig->Update(keyMaterial->Mid((2*hashSize), keySize));
       
   515 		iClientWriteSecret = md5dig->Hash(aRandom).Left(expandedKeySize).AllocL();
       
   516 		md5dig->Reset();
       
   517 			
       
   518 		md5dig->Update(keyMaterial->Mid((2*hashSize)+keySize, keySize));
       
   519 		iServerWriteSecret = md5dig->Hash(*random).Left(expandedKeySize).AllocL();
       
   520 		md5dig->Reset();
       
   521 		
       
   522 		iClientInitVector = md5dig->Hash(aRandom).Left(ivSize).AllocL();
       
   523 		md5dig->Reset();
       
   524 		
       
   525 		iServerInitVector = md5dig->Hash(*random).Left(ivSize).AllocL();
       
   526 		
       
   527 		CleanupStack::PopAndDestroy(md5dig);
       
   528 		}
       
   529 	else
       
   530 		{
       
   531 		// just devide the key material up in to its respective blocks
       
   532 		iClientWriteSecret = keyMaterial->Mid(2*hashSize, keySize).AllocL();
       
   533 		iServerWriteSecret = keyMaterial->Mid((2*hashSize)+keySize, keySize).AllocL();
       
   534 		iClientInitVector = keyMaterial->Mid((2*hashSize)+(2*keySize), ivSize).AllocL();
       
   535 		iServerInitVector = keyMaterial->Right(ivSize).AllocL();
       
   536 		}
       
   537 	
       
   538 	CleanupStack::PopAndDestroy(2, random); // keyMaterial
       
   539 	}
       
   540 
       
   541 
       
   542 TInt CNewTlsStepBase::LeanGetCipherSuitesL()
       
   543 	{
       
   544 	iSuites.Reset();
       
   545 	iProvider->CipherSuitesL(iSuites, iActive->iStatus);
       
   546 	iActive->Start();
       
   547 	return iActive->iStatus.Int();
       
   548 	}
       
   549 
       
   550 
       
   551