networksecurity/tlsprovider/Test/tlstest2/tlsstepbase.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 tlsstepbase.cpp
       
    18  @internalTechnology
       
    19 */
       
    20 #include "tlsstepbase.h"
       
    21 
       
    22 #include <f32file.h>
       
    23 #include <tlsprovinterface.h>
       
    24 #include <asymmetric.h>
       
    25 #include <asymmetrickeys.h>
       
    26 #include <symmetric.h>
       
    27 #include <asnpkcs.h>
       
    28 #include "tlsgenericactive.h"
       
    29 #include "psuedorandom.h"
       
    30 #include "dhparamreader.h"
       
    31 #include "testpadding.h"
       
    32 
       
    33 CTlsStepBase::~CTlsStepBase()
       
    34 	{
       
    35 	delete iActive;
       
    36 	delete iProvider;
       
    37 	delete iSched;
       
    38 	iSuites.Close();
       
    39 //	iGenerator.Close();
       
    40 //	iPrime.Close();
       
    41 	delete iKeyPair;
       
    42 	delete iClientMacSecret;
       
    43 	delete iServerMacSecret;
       
    44 	delete iClientWriteSecret;
       
    45 	delete iServerWriteSecret;
       
    46 	delete iClientInitVector;
       
    47 	delete iServerInitVector;
       
    48 	
       
    49 	}
       
    50 	
       
    51 void CTlsStepBase::ConstructL()
       
    52 	{
       
    53 	iSched=new(ELeave) CActiveScheduler;
       
    54 	CActiveScheduler::Install(iSched);
       
    55 	
       
    56 	iProvider = CTLSProvider::ConnectL();
       
    57 	iActive = new (ELeave) CGenericActive;
       
    58 	}
       
    59 
       
    60 // Test methods
       
    61 
       
    62 TInt CTlsStepBase::GetCipherSuitesL()
       
    63 	{
       
    64 	iSuites.Reset();
       
    65 	iProvider->CipherSuitesL(iSuites, iActive->iStatus);
       
    66 	iActive->Start();
       
    67 	return iActive->iStatus.Int();
       
    68 	}
       
    69 
       
    70 TInt CTlsStepBase::GetCipherSuitesWithCancelL()
       
    71 	{
       
    72 	iSuites.Reset();
       
    73 	iProvider->CipherSuitesL(iSuites, iActive->iStatus);
       
    74 	iProvider->CancelRequest();
       
    75 	iActive->Start();
       
    76 	return iActive->iStatus.Int();
       
    77 	}
       
    78 
       
    79 
       
    80 TInt CTlsStepBase::GetCipherSuitesL(CTLSProvider* & aTLSProviderInstance, RArray<TTLSCipherSuite> & aCipherSuites)
       
    81 	{
       
    82 	aTLSProviderInstance->CipherSuitesL(aCipherSuites, iActive->iStatus);
       
    83 	iActive->Start();
       
    84 	return iActive->iStatus.Int();
       
    85 	}
       
    86 
       
    87 TInt CTlsStepBase::VerifyServerCertificateL(CX509Certificate*& aCertOut)
       
    88 	{
       
    89 	HBufC8* cert = ServerCertificateL();
       
    90 	iProvider->VerifyServerCertificate(*cert, aCertOut, iActive->iStatus);
       
    91 	iActive->Start();
       
    92 	delete cert;
       
    93 	return iActive->iStatus.Int();
       
    94 	}
       
    95 
       
    96 TInt CTlsStepBase::VerifyServerCertificateL(CTLSProvider* & aTLSProviderInstance, CX509Certificate*& aCertOut)
       
    97 	{
       
    98 	HBufC8* cert = ServerCertificateL();
       
    99 	aTLSProviderInstance->VerifyServerCertificate(*cert, aCertOut, iActive->iStatus);
       
   100 	iActive->Start();
       
   101 	delete cert;
       
   102 	return iActive->iStatus.Int();
       
   103 	}
       
   104 	
       
   105 TInt CTlsStepBase::VerifyServerCertificateWithCancelL(CX509Certificate*& aCertOut)
       
   106 	{
       
   107 	HBufC8* cert = ServerCertificateL();
       
   108 	iProvider->VerifyServerCertificate(*cert, aCertOut, iActive->iStatus);
       
   109 	iProvider->CancelRequest();
       
   110 	iActive->Start();
       
   111 	delete cert;
       
   112 	return iActive->iStatus.Int();
       
   113 	}
       
   114 
       
   115 TInt CTlsStepBase::RetrieveServerCert(CX509Certificate*& aCertOut)
       
   116 	{
       
   117 	iSession->ServerCertificate(aCertOut,iActive->iStatus);		
       
   118 	iActive->Start();
       
   119 	return iActive->iStatus.Int();
       
   120 	}
       
   121 
       
   122 TInt CTlsStepBase::CreateSessionL()
       
   123 	{
       
   124 	iProvider->CreateL(iSession, iActive->iStatus);
       
   125 	iActive->Start();
       
   126 	return iActive->iStatus.Int();
       
   127 	}
       
   128 
       
   129 TInt CTlsStepBase::CreateSessionWithCancelL()
       
   130 	{
       
   131 	iProvider->CreateL(iSession, iActive->iStatus);
       
   132 	iProvider->CancelRequest();
       
   133 	iActive->Start();
       
   134 	return iActive->iStatus.Int();
       
   135 	}
       
   136 
       
   137 TInt CTlsStepBase::CreateSessionL(CTLSProvider* & aTLSProviderInstance, CTLSSession* aCTLSSession)
       
   138 	{
       
   139 	aTLSProviderInstance->CreateL(aCTLSSession, iActive->iStatus);
       
   140 	iActive->Start();
       
   141 	return iActive->iStatus.Int();
       
   142 	}
       
   143 
       
   144 
       
   145 TInt CTlsStepBase ::VerifyGetSessionL(TTLSServerAddr& aServerName,TInt& aSessionIdLength)
       
   146 	{
       
   147 	TTLSSessionId sessionId;
       
   148 	iProvider->GetSessionL(
       
   149 		aServerName,
       
   150 		sessionId,
       
   151 		iActive->iStatus );
       
   152 	iActive->Start();
       
   153 	aSessionIdLength = sessionId.Length();
       
   154 	return iActive->iStatus.Int();
       
   155 	}
       
   156 
       
   157 TInt CTlsStepBase ::VerifyGetSessionL(CTLSProvider* & aTLSProviderInstance , TTLSServerAddr& aServerName, TInt& aSessionIdLength)
       
   158 	{
       
   159 	TTLSSessionId sessionId;
       
   160 	aTLSProviderInstance->GetSessionL(
       
   161 		aServerName,
       
   162 		sessionId,
       
   163 		iActive->iStatus );
       
   164 	iActive->Start();
       
   165 	aSessionIdLength = sessionId.Length();
       
   166 	return iActive->iStatus.Int();
       
   167 	}
       
   168 
       
   169 
       
   170 TInt CTlsStepBase ::CreateSessionAddedL(TInt aHiByte,TInt aLoByte)
       
   171 	{
       
   172 	
       
   173 	CTlsCryptoAttributes* TlsCryptoAttributes =  iProvider->Attributes();
       
   174 	TlsCryptoAttributes->iNegotiatedProtocol = KTLS1_0;
       
   175 	TlsCryptoAttributes->iCurrentCipherSuite.iHiByte = aHiByte;
       
   176 	TlsCryptoAttributes->iCurrentCipherSuite.iLoByte = aLoByte;
       
   177 	iProvider->CreateL(iSession, iActive->iStatus);
       
   178 	iActive->Start();
       
   179 	return iActive->iStatus.Int();
       
   180 	}
       
   181 	
       
   182 TInt CTlsStepBase::ClearSessionCacheL(TTLSSessionNameAndID &aSessionNameAndId)
       
   183 	{
       
   184 	iProvider->ClearSessionCacheL( 
       
   185 			aSessionNameAndId, 
       
   186 			iActive->iStatus);
       
   187 	iActive->Start();
       
   188 	return iActive->iStatus.Int();
       
   189 	}
       
   190 
       
   191 TInt CTlsStepBase::ClearSessionCacheWithCancelL(TTLSSessionNameAndID &aSessionNameAndId)
       
   192 	{
       
   193 	iProvider->ClearSessionCacheL( 
       
   194 			aSessionNameAndId, 
       
   195 			iActive->iStatus);
       
   196 	iProvider->CancelRequest();
       
   197 	iActive->Start();
       
   198 	return iActive->iStatus.Int();
       
   199 	}
       
   200 
       
   201 TInt CTlsStepBase::ClearSessionCacheL(CTLSProvider* & aTLSProviderInstance ,TTLSSessionNameAndID &aSessionNameAndId)
       
   202 	{
       
   203 	aTLSProviderInstance->ClearSessionCacheL( 
       
   204 			aSessionNameAndId, 
       
   205 			iActive->iStatus);
       
   206 	iActive->Start();
       
   207 	return iActive->iStatus.Int();
       
   208 	}
       
   209 
       
   210 void CTlsStepBase::SessionCancelReq()
       
   211 	{
       
   212 	iSession->CancelRequest();
       
   213 	}
       
   214 
       
   215 void CTlsStepBase::ProviderCancelReq()
       
   216 	{
       
   217 	iProvider->CancelRequest();
       
   218 	}
       
   219 
       
   220 TInt CTlsStepBase::ClientKeyExchange(HBufC8*& aMessageOut)
       
   221 	{
       
   222 	iSession->ClientKeyExchange(aMessageOut, iActive->iStatus);
       
   223 	iActive->Start();
       
   224 	return iActive->iStatus.Int();
       
   225 	}
       
   226 
       
   227 TInt CTlsStepBase::ClientKeyExchange(CTLSSession* &aCTLSSession, HBufC8*& aMessageOut)
       
   228 	{
       
   229 	aCTLSSession->ClientKeyExchange(aMessageOut, iActive->iStatus);
       
   230 	iActive->Start();
       
   231 	return iActive->iStatus.Int();
       
   232 	}
       
   233 
       
   234 
       
   235 TInt CTlsStepBase::ClientKeyExchangeWithCancel(HBufC8*& aMessageOut)
       
   236 	{
       
   237 	iSession->ClientKeyExchange(aMessageOut, iActive->iStatus);
       
   238 	iSession->CancelRequest();
       
   239 	iActive->Start();
       
   240 	return iActive->iStatus.Int();
       
   241 	}
       
   242 
       
   243 
       
   244 TInt CTlsStepBase::GenerateClientFinishedL(CMessageDigest* aShaDigest, CMessageDigest* aMd5Digest, HBufC8*& aMessageOut)
       
   245 	{
       
   246 	iSession->ClientFinishedMsgL(aMd5Digest, aShaDigest, aMessageOut, iActive->iStatus);
       
   247 	iActive->Start();
       
   248 	return iActive->iStatus.Int();
       
   249 	}
       
   250 	
       
   251 TInt CTlsStepBase::VerifyServerFinishedL(CMessageDigest* aShaDigest, CMessageDigest* aMd5Digest, const TDesC8& aMessage)
       
   252 	{
       
   253 	iSession->VerifyServerFinishedMsgL(aMd5Digest, aShaDigest, aMessage, iActive->iStatus);
       
   254 	iActive->Start();
       
   255 	return iActive->iStatus.Int();
       
   256 	}
       
   257 
       
   258 TInt CTlsStepBase::CipherSuiteIndex(const TTLSCipherSuite& aSuite)
       
   259 	{
       
   260 	for (TInt i = 0 ; i < CipherSuites().Count() ; ++i)
       
   261 		{
       
   262 		if (CipherSuites()[i] == aSuite)
       
   263 			{
       
   264 			return i;
       
   265 			};
       
   266 		}
       
   267 	return KErrNotFound;
       
   268 	}
       
   269 
       
   270 HBufC8* CTlsStepBase::DerivePreMasterSecretL(const TDesC8& aClientKeyExMessage)
       
   271 	{
       
   272 	return DerivePreMasterSecretL(iProvider, aClientKeyExMessage);
       
   273 	}
       
   274 
       
   275 HBufC8* CTlsStepBase::DerivePreMasterSecretL(CTLSProvider* & aTLSProviderInstance, const TDesC8& aClientKeyExMessage)
       
   276 	{
       
   277 	// Look up the cipher suite we used for this test
       
   278 	CTlsCryptoAttributes* atts = aTLSProviderInstance->Attributes();
       
   279 	
       
   280 	TInt index = CipherSuiteIndex(atts->iCurrentCipherSuite);
       
   281 	if (index < 0)
       
   282 		{
       
   283 		INFO_PRINTF3(_L("Failed! Could not find cipher 0x%02x.0x%02x, did the ECOM plugin load okay?"),
       
   284 			  atts->iCurrentCipherSuite.iHiByte, atts->iCurrentCipherSuite.iLoByte);
       
   285 		User::Leave(index);
       
   286 		}
       
   287 
       
   288 	HBufC8* ret = NULL;
       
   289 
       
   290 	// currently, we only support three key exhange algorithms, so that is what we test here
       
   291 	switch (CipherSuites()[index].CipherDetails()->iKeyExAlg)
       
   292 		{
       
   293 	case ERsa:
       
   294 		// decrypt the key exhange message with the "server" private key, and
       
   295 		// verify the version and that the premaster key is the right size...
       
   296 		{
       
   297 		CDecPKCS8Data* keyData = ServerPrivateKeyL();
       
   298 		CleanupStack::PushL(keyData);
       
   299 		
       
   300 		// we don't own this pointer...
       
   301 		CPKCS8KeyPairRSA* key = static_cast<CPKCS8KeyPairRSA*>(keyData->KeyPairData());
       
   302 		
       
   303 		CRSAPKCS1v15Decryptor* decryptor = CRSAPKCS1v15Decryptor::NewLC(key->PrivateKey());
       
   304 		
       
   305 		ret = HBufC8::NewLC(decryptor->MaxOutputLength());
       
   306 		TPtr8 ptr = ret->Des();
       
   307 		decryptor->DecryptL(aClientKeyExMessage, ptr);
       
   308 
       
   309 		CleanupStack::Pop(ret);
       
   310 		CleanupStack::PopAndDestroy(2, keyData); // decryptor
       
   311 		}
       
   312 		break;
       
   313 		
       
   314 	case EDHE:
       
   315 		{
       
   316 		RInteger clientX = RInteger::NewL(aClientKeyExMessage);
       
   317 		CleanupClosePushL(clientX);
       
   318 		
       
   319 		RInteger prime = RInteger::NewL(iPrime);
       
   320 		CleanupClosePushL(prime);
       
   321 		
       
   322 		RInteger gen = RInteger::NewL(iGenerator);
       
   323 		CleanupClosePushL(gen);
       
   324 		
       
   325 		CDHPublicKey* clientKey = CDHPublicKey::NewL(prime, gen, clientX);
       
   326 		CleanupStack::Pop(3, &clientX); // prime, gen, adopted by clientKey
       
   327 		CleanupStack::PushL(clientKey);
       
   328 		
       
   329 		CDH* dh = CDH::NewLC(KeyPair()->PrivateKey());
       
   330 		// this cast is evil, but hey! it's test code. And I'm not gonna revise the interface.
       
   331 		ret = const_cast<HBufC8*>(dh->AgreeL(*clientKey));
       
   332 		
       
   333 		CleanupStack::PopAndDestroy(2, clientKey); // dh
       
   334 		}
       
   335 		break;
       
   336 		
       
   337 	case EPsk:
       
   338 		{
       
   339 		// For PSK cipher suites the premaster secret is formed as follows: 
       
   340 		// if the PSK is N octets long, concatenate a uint16 with the value N, 
       
   341 		// N zero octets, a second uint16 with the value N, and the PSK itself.
       
   342 		// REF: RFC4279
       
   343 		
       
   344 		ret = HBufC8::NewLC(iPskKey->Length()*2 + 4 );
       
   345 		ret->Des().FillZ(iPskKey->Length()*2 + 4);
       
   346  		TPtr8 ptr = ret->Des();
       
   347 		
       
   348 		// Populates first two field bytes values. 
       
   349 		
       
   350 		ptr[0] = (iPskKey->Length() & 0xFF00 ) >> 8;
       
   351 		ptr[1] = iPskKey->Length() & 0xFF; 
       
   352 		
       
   353 		// Populates second two field bytes values. 
       
   354 		ptr[iPskKey->Length() + 2] = ptr[0];
       
   355 		ptr[iPskKey->Length() + 3] = ptr[1];
       
   356 		
       
   357 		// Populates the actual key value.
       
   358 		ptr.Replace(iPskKey->Length() + 4, iPskKey->Length(), iPskKey->Des() );
       
   359 		
       
   360 		CleanupStack::Pop(ret);
       
   361 		
       
   362 		}
       
   363 		break;
       
   364 
       
   365 	default:
       
   366 		User::Leave(KErrUnknown);
       
   367 		break;
       
   368 		}
       
   369 	
       
   370 	return ret;
       
   371 	}
       
   372 
       
   373 HBufC8* CTlsStepBase::ComputeMasterSecretL(const TDesC8& aPremasterSecret)
       
   374 	{
       
   375 	return CTlsStepBase::ComputeMasterSecretL(iProvider, aPremasterSecret);
       
   376 	}
       
   377 	
       
   378 HBufC8* CTlsStepBase::ComputeMasterSecretL(CTLSProvider* & aTLSProviderInstance, const TDesC8& aPremasterSecret)
       
   379 	{
       
   380 	if (aTLSProviderInstance->Attributes()->iNegotiatedProtocol == KSSL3_0)
       
   381 		{
       
   382 		return ComputeSslMasterSecretL(aPremasterSecret);
       
   383 		}
       
   384 	else if (aTLSProviderInstance->Attributes()->iNegotiatedProtocol == KTLS1_0)
       
   385 		{
       
   386 		return ComputeTlsMasterSecretL(aPremasterSecret);
       
   387 		}
       
   388 	else
       
   389 		{
       
   390 		// currently unknown protocol!
       
   391 		User::Leave(KErrUnknown);
       
   392 		return NULL; // keep the compiler happy..
       
   393 		}
       
   394 	}
       
   395 
       
   396 HBufC8* CTlsStepBase::ComputeMacL(const TDesC8& aData, TInt64 aSequenceNumber, TRecordProtocol& aType, TBool aIsServerMac)
       
   397 	{
       
   398 	if (Provider()->Attributes()->iNegotiatedProtocol == KSSL3_0)
       
   399 		{
       
   400 		return ComputeSslMacL(aData, aSequenceNumber, aType, aIsServerMac);
       
   401 		}
       
   402 	else if (Provider()->Attributes()->iNegotiatedProtocol == KTLS1_0)
       
   403 		{
       
   404 		return ComputeTlsMacL(aData, aSequenceNumber, aType, aIsServerMac);
       
   405 		}
       
   406 	else
       
   407 		{
       
   408 		// currently unknown protocol!
       
   409 		User::Leave(KErrUnknown);
       
   410 		return NULL; // keep the compiler happy..
       
   411 		}
       
   412 	}
       
   413 	
       
   414 HBufC8* CTlsStepBase::ComputeFinishedMessageL(CMessageDigest* aShaDigest, CMessageDigest* aMd5Digest,
       
   415 	const TDesC8& aMasterSecret, TBool aClientFinished)
       
   416 	{
       
   417 	if (Provider()->Attributes()->iNegotiatedProtocol == KSSL3_0)
       
   418 		{
       
   419 		return ComputeSslFinishedL(aShaDigest, aMd5Digest, aMasterSecret, aClientFinished);
       
   420 		}
       
   421 	else if (Provider()->Attributes()->iNegotiatedProtocol == KTLS1_0)
       
   422 		{
       
   423 		return ComputeTlsFinishedL(aShaDigest, aMd5Digest, aMasterSecret, aClientFinished);
       
   424 		}
       
   425 	else
       
   426 		{
       
   427 		// currently unknown protocol!
       
   428 		User::Leave(KErrUnknown);
       
   429 		return NULL; // keep the compiler happy..
       
   430 		}
       
   431 	}
       
   432 	
       
   433 HBufC8* CTlsStepBase::EncryptRecordL(const TDesC8& aData, TInt64 aSequenceNumber, TRecordProtocol& aType, TBool aIsServerCrypt)
       
   434 	{
       
   435 	// Compute the mac for this record...
       
   436 	HBufC8* mac = ComputeMacL(aData, aSequenceNumber, aType, aIsServerCrypt);
       
   437 	CleanupStack::PushL(mac);
       
   438 	
       
   439 	// now, create an encryptor for this operation....
       
   440 	CTlsCryptoAttributes* atts = Provider()->Attributes();
       
   441 	
       
   442 	TInt index = CipherSuiteIndex(atts->iCurrentCipherSuite);
       
   443 	User::LeaveIfError(index);
       
   444 	
       
   445 	TTLSCipherSuite suite = CipherSuites()[index];
       
   446 	CSymmetricCipher* encryptor = NULL;
       
   447 	HBufC8* key = aIsServerCrypt ? ServerWriteSecret() : ClientWriteSecret();
       
   448 	
       
   449 	if (suite.CipherDetails()->iCipherType == EStream)
       
   450 		{
       
   451 		
       
   452 		switch (suite.CipherDetails()->iBulkCiphAlg)
       
   453 			{
       
   454 		case ERc4:
       
   455 			encryptor = CARC4::NewL(*key, 0);
       
   456 			break;
       
   457 		case ENullSymCiph:
       
   458 			encryptor = CNullCipher::NewL();
       
   459 			break;	
       
   460 		default:
       
   461 			User::Leave(KErrUnknown); // unknown cipher!
       
   462 			break;
       
   463 			}
       
   464 		}
       
   465 	else
       
   466 		{
       
   467 		
       
   468 		CBlockTransformation* transform = NULL;
       
   469 		switch (suite.CipherDetails()->iBulkCiphAlg)
       
   470 			{
       
   471 		case EDes:
       
   472 		case EDes40:
       
   473 			transform = CDESEncryptor::NewLC(*key, EFalse);
       
   474 			break;
       
   475 			
       
   476 		case E3Des:
       
   477 			transform = C3DESEncryptor::NewLC(*key);
       
   478 			break;
       
   479 			
       
   480 		case EAes:
       
   481 			transform = CAESEncryptor::NewLC(*key);
       
   482 			break;
       
   483 			
       
   484 		default:
       
   485 			User::Leave(KErrUnknown); // unknown cipher!
       
   486 			break;
       
   487 			}
       
   488 			
       
   489 		HBufC8* iv = aIsServerCrypt ? ServerInitVector() : ClientInitVector();
       
   490 		CleanupStack::Pop(transform); // ownership transfered to cbc
       
   491 		CModeCBCEncryptor* cbc = CModeCBCEncryptor::NewLC(transform, *iv);
       
   492 		
       
   493 		CPaddingSSLv3* padding = CPaddingSSLv3::NewLC(cbc->BlockSize());
       
   494 		// Use next line instead later. Currently broken. Will be required for TLS 1.2
       
   495 		// CTlsTestPadding* padding = CTlsTestPadding::NewLC(cbc->BlockSize(), 0);
       
   496 		
       
   497 		encryptor = CBufferedEncryptor::NewL(cbc, padding);
       
   498 		CleanupStack::Pop(2, cbc); // padding - ownership transfered to encryptor
       
   499 		}
       
   500 	
       
   501 	CleanupStack::PushL(encryptor);
       
   502 	
       
   503 	// encrypt the data, and the mac... padding will be added as appropriate.
       
   504 	TInt outputMaxLen = encryptor->MaxFinalOutputLength(mac->Length() + aData.Length());
       
   505 	HBufC8* ret = HBufC8::NewLC(outputMaxLen);
       
   506 	TPtr8 des = ret->Des();
       
   507 	
       
   508 	encryptor->Process(aData, des);
       
   509 	encryptor->ProcessFinalL(*mac, des);
       
   510 	
       
   511 	CleanupStack::Pop(ret);
       
   512 	CleanupStack::PopAndDestroy(2, mac); // encryptor
       
   513 	return ret;
       
   514 	}
       
   515 
       
   516 // INI Read methods
       
   517 
       
   518 HBufC8* CTlsStepBase::ServerRandomL()
       
   519 	{
       
   520 	return ReadRandomL(KServerRandomFile);
       
   521 	}
       
   522 	
       
   523 HBufC8* CTlsStepBase::ClientRandomL()
       
   524 	{
       
   525 	return ReadRandomL(KClientRandomFile);
       
   526 	}
       
   527 	
       
   528 TTLSCipherSuite CTlsStepBase::CipherSuiteL()
       
   529 	{
       
   530 	TTLSCipherSuite ret;
       
   531 	
       
   532 	TInt highByte(0);
       
   533 	if (!GetIntFromConfig(ConfigSection(), KCipherHighByte, highByte))
       
   534 		{
       
   535 		User::Leave(KErrNotFound);
       
   536 		}
       
   537 	
       
   538 	TInt lowByte(0);
       
   539 	if (!GetIntFromConfig(ConfigSection(), KCipherLowByte, lowByte))
       
   540 		{
       
   541 		User::Leave(KErrNotFound);
       
   542 		}
       
   543 		
       
   544 	ret.iHiByte = highByte;
       
   545 	ret.iLoByte = lowByte;
       
   546 		
       
   547 	return ret;
       
   548 	}
       
   549 	
       
   550 TTLSProtocolVersion CTlsStepBase::ProtocolVersionL()
       
   551 	{
       
   552 	TTLSProtocolVersion ret;
       
   553 	
       
   554 	TInt majorVersion(0);
       
   555 	if (!GetIntFromConfig(ConfigSection(), KProtocolMajorVersion, majorVersion))
       
   556 		{
       
   557 		User::Leave(KErrNotFound);
       
   558 		}
       
   559 		
       
   560 	TInt minorVersion(0);
       
   561 	if (!GetIntFromConfig(ConfigSection(), KProtocolMinorVersion, minorVersion))
       
   562 		{
       
   563 		User::Leave(KErrNotFound);
       
   564 		}
       
   565 		
       
   566 	ret.iMajor = majorVersion;
       
   567 	ret.iMinor = minorVersion;
       
   568 	
       
   569 	return ret;	
       
   570 	}
       
   571 	
       
   572 TTLSSessionId CTlsStepBase::SessionId()
       
   573 	{
       
   574 	// Create a unique session ID, by filling with zeros, then setting the top
       
   575 	// 8 bytes with the current time.
       
   576 	TTLSSessionId ret;
       
   577 	ret.SetMax();
       
   578 	ret.Fill(0);
       
   579 	
       
   580 	TTime now;
       
   581 	now.UniversalTime();
       
   582 	
       
   583 	TInt64 time = now.Int64();
       
   584 	TInt byteNum(0);
       
   585 	while (time)
       
   586 		{
       
   587 		ret[byteNum++] = time & 0xFF;
       
   588 		time >>= 8;
       
   589 		}
       
   590 	
       
   591 	return ret;
       
   592 	}
       
   593 	
       
   594 HBufC8* CTlsStepBase::ServerCertificateL()
       
   595 	{
       
   596 	TPtrC serverCertName;
       
   597 	if (!GetStringFromConfig(ConfigSection(), KServerCert, serverCertName))
       
   598 		{
       
   599 		User::Leave(KErrNotFound);
       
   600 		}
       
   601 	
       
   602 	RFs fs;
       
   603 	User::LeaveIfError(fs.Connect());
       
   604 	CleanupClosePushL(fs);
       
   605 	
       
   606 	RFile certFile;
       
   607 	User::LeaveIfError(certFile.Open(fs, serverCertName, EFileRead));
       
   608 	CleanupClosePushL(certFile);
       
   609 	
       
   610 	TInt size(0);
       
   611 	User::LeaveIfError(certFile.Size(size));
       
   612 	HBufC8* certData = HBufC8::NewLC(size);
       
   613 	TPtr8 ptr = certData->Des();
       
   614 	
       
   615 	User::LeaveIfError(certFile.Read(ptr, size));
       
   616 	
       
   617 	CleanupStack::Pop(certData);
       
   618 	CleanupStack::PopAndDestroy(2, &fs); // certFile
       
   619 	return certData;
       
   620 	}
       
   621 	
       
   622 void CTlsStepBase::ReadDHParamsL()
       
   623 	{
       
   624 	TPtrC dhParamName;
       
   625 	if (!GetStringFromConfig(ConfigSection(), KDhParamFile, dhParamName))
       
   626 		{
       
   627 		User::Leave(KErrNotFound);
       
   628 		}
       
   629 
       
   630 	CDHParamReader::DecodeDERL(dhParamName, iPrime, iGenerator);
       
   631 	iKeyPair = CDHKeyPair::NewL(iPrime, iGenerator);
       
   632 	}
       
   633 	
       
   634 	
       
   635 TPtrC CTlsStepBase::DomainNameL()
       
   636 	{
       
   637 	TPtrC name;
       
   638 	if (!GetStringFromConfig(ConfigSection(), KDomainName, name))
       
   639 		{
       
   640 		User::Leave(KErrNotFound);
       
   641 		}
       
   642 	return name;
       
   643 	}
       
   644 	
       
   645 CDecPKCS8Data* CTlsStepBase::ServerPrivateKeyL()
       
   646 	{
       
   647 	TPtrC serverKeyName;
       
   648 	if (!GetStringFromConfig(ConfigSection(), KServerKey, serverKeyName))
       
   649 		{
       
   650 		User::Leave(KErrNotFound);
       
   651 		}
       
   652 	
       
   653 	RFs fs;
       
   654 	User::LeaveIfError(fs.Connect());
       
   655 	CleanupClosePushL(fs);
       
   656 	
       
   657 	RFile keyFile;
       
   658 	User::LeaveIfError(keyFile.Open(fs, serverKeyName, EFileRead));
       
   659 	CleanupClosePushL(keyFile);
       
   660 	
       
   661 	TInt size(0);
       
   662 	User::LeaveIfError(keyFile.Size(size));
       
   663 	HBufC8* keyData = HBufC8::NewLC(size);
       
   664 	TPtr8 ptr = keyData->Des();
       
   665 	
       
   666 	User::LeaveIfError(keyFile.Read(ptr, size));
       
   667 	
       
   668 	CDecPKCS8Data* ret = TASN1DecPKCS8::DecodeDERL(*keyData);
       
   669 
       
   670 	CleanupStack::PopAndDestroy(3, &fs); // keyFile, keyData
       
   671 	return ret;
       
   672 	}
       
   673 	
       
   674 HBufC8* CTlsStepBase::ReadRandomL(const TDesC& aTag)
       
   675 	{
       
   676 	TPtrC randomFile;
       
   677 	if (!GetStringFromConfig(ConfigSection(), aTag, randomFile))
       
   678 		{
       
   679 		User::Leave(KErrNotFound);
       
   680 		}
       
   681 	
       
   682 	RFs fs;
       
   683 	User::LeaveIfError(fs.Connect());
       
   684 	CleanupClosePushL(fs);
       
   685 	
       
   686 	RFile file;
       
   687 	User::LeaveIfError(file.Open(fs, randomFile, EFileRead));
       
   688 	CleanupClosePushL(file);
       
   689 	
       
   690 	TInt fileSize;
       
   691 	User::LeaveIfError(file.Size(fileSize));
       
   692 	
       
   693 	HBufC8* random = HBufC8::NewLC(fileSize);
       
   694 	TPtr8 randomDes = random->Des();
       
   695 	User::LeaveIfError(file.Read(randomDes));
       
   696 	
       
   697 	CleanupStack::Pop(random);
       
   698 	CleanupStack::PopAndDestroy(2, &fs); // file
       
   699 	return random;
       
   700 	}
       
   701 	
       
   702 HBufC8* CTlsStepBase::ComputeTlsMasterSecretL(const TDesC8& aPremasterSecret)
       
   703 	{
       
   704 	HBufC8* random = HBufC8::NewLC(KTLSServerClientRandomLen * 2);
       
   705 	
       
   706 	TTLSMasterSecretInput params = iProvider->Attributes()->iMasterSecretInput;
       
   707 	random->Des().Append(params.iClientRandom);
       
   708 	random->Des().Append(params.iServerRandom);
       
   709 	
       
   710 	_LIT8(KMasterSecretLabel, "master secret");
       
   711 	HBufC8* ret = CTls10PsuedoRandom::PseudoRandomL(aPremasterSecret, KMasterSecretLabel, 
       
   712 		*random, KTLSMasterSecretLen);
       
   713 	CleanupStack::PushL(ret);
       
   714 	
       
   715 	ComputeTlsCipherKeysL(*ret, *random);
       
   716 	
       
   717 	CleanupStack::Pop(ret);
       
   718 	CleanupStack::PopAndDestroy(random);
       
   719 	return ret;
       
   720 	}
       
   721 	
       
   722 HBufC8* CTlsStepBase::ComputeSslMasterSecretL(const TDesC8& aPremasterSecret)
       
   723 	{
       
   724 	HBufC8* random = HBufC8::NewLC(KTLSServerClientRandomLen * 2);
       
   725 	
       
   726 	TTLSMasterSecretInput params = iProvider->Attributes()->iMasterSecretInput;
       
   727 	random->Des().Append(params.iClientRandom);
       
   728 	random->Des().Append(params.iServerRandom);
       
   729 	
       
   730 	HBufC8* ret = CSsl30PsuedoRandom::PseudoRandomL(aPremasterSecret, *random, KTLSMasterSecretLen);
       
   731 	CleanupStack::PushL(ret);
       
   732 	
       
   733 	ComputeSslCipherKeysL(*ret, *random);
       
   734 	
       
   735 	CleanupStack::Pop(ret);
       
   736 	CleanupStack::PopAndDestroy(random);
       
   737 	return ret;
       
   738 	}
       
   739 	
       
   740 void CTlsStepBase::ComputeTlsCipherKeysL(const TDesC8& aMasterSecret, const TDesC8& aRandom)
       
   741 	{
       
   742 	// Look up the cipher suite we used for this test
       
   743 	CTlsCryptoAttributes* atts = Provider()->Attributes();
       
   744 	
       
   745 	TInt index = CipherSuiteIndex(atts->iCurrentCipherSuite);
       
   746 	User::LeaveIfError(index);
       
   747 	
       
   748 	TTLSCipherSuite suite = CipherSuites()[index];
       
   749 	
       
   750 	// Key material is:
       
   751 	// - 2 mac secrets of size hash_size
       
   752 	// - 2 bulk cipher secrets of size keymaterial_size
       
   753 	// - 2 initialisation vectors of size iv_size
       
   754 	
       
   755 	TInt hashSize = suite.CipherDetails()->iHashSize;
       
   756 	TInt keySize = suite.CipherDetails()->iKeyMaterial;
       
   757 	TInt ivSize = suite.CipherDetails()->iIVSize;
       
   758 	
       
   759 	TInt keyMaterialSize = (2*hashSize) + (2*keySize) + (2*ivSize);
       
   760 	
       
   761 	// This calculation uses the random data in the opposite order to the master secret
       
   762 	
       
   763 	HBufC8* random = HBufC8::NewLC(KTLSServerClientRandomLen * 2);
       
   764 	TTLSMasterSecretInput params = atts->iMasterSecretInput;
       
   765 	random->Des().Append(params.iServerRandom);
       
   766 	random->Des().Append(params.iClientRandom);
       
   767 	
       
   768 	_LIT8(KKeyExpansionLabel, "key expansion");
       
   769 	HBufC8* keyMaterial = CTls10PsuedoRandom::PseudoRandomL(aMasterSecret, KKeyExpansionLabel,
       
   770 	    *random, keyMaterialSize);		
       
   771 	CleanupStack::PushL(keyMaterial);
       
   772 		
       
   773 	iClientMacSecret = keyMaterial->Left(hashSize).AllocL();
       
   774 	iServerMacSecret = keyMaterial->Mid(hashSize, hashSize).AllocL();
       
   775 		
       
   776 	// if the cipher is exportable, we need to do further PRF calculations to get the keys
       
   777 	if (suite.CipherDetails()->iIsExportable)
       
   778 		{
       
   779 		TInt expandedKeySize = 	suite.CipherDetails()->iExpKeySize;
       
   780 		
       
   781 		_LIT8(KClientWriteLabel, "client write key");
       
   782 		iClientWriteSecret = CTls10PsuedoRandom::PseudoRandomL(keyMaterial->Mid(2*hashSize, keySize), 
       
   783 		    KClientWriteLabel, aRandom, expandedKeySize);
       
   784 			
       
   785 		_LIT8(KServerWriteLabel, "server write key");
       
   786 		iServerWriteSecret = CTls10PsuedoRandom::PseudoRandomL(keyMaterial->Mid((2*hashSize)+keySize, keySize),
       
   787 		    KServerWriteLabel, aRandom, expandedKeySize);
       
   788 			
       
   789 		_LIT8(KIVBlockLabel, "IV block");
       
   790 		HBufC8* ivMaterial = CTls10PsuedoRandom::PseudoRandomL(KNullDesC8, KIVBlockLabel, aRandom, 2*ivSize);
       
   791 		CleanupStack::PushL(ivMaterial);
       
   792 		
       
   793 		iClientInitVector = ivMaterial->Left(ivSize).AllocL();
       
   794 		iServerInitVector = ivMaterial->Right(ivSize).AllocL();
       
   795 		
       
   796 		CleanupStack::PopAndDestroy(ivMaterial);
       
   797 		}
       
   798 	else
       
   799 		{
       
   800 		// just devide the key material up in to its respective blocks
       
   801 		iClientWriteSecret = keyMaterial->Mid(2*hashSize, keySize).AllocL();
       
   802 		iServerWriteSecret = keyMaterial->Mid((2*hashSize)+keySize, keySize).AllocL();
       
   803 		iClientInitVector = keyMaterial->Mid((2*hashSize)+(2*keySize), ivSize).AllocL();
       
   804 		iServerInitVector = keyMaterial->Right(ivSize).AllocL();
       
   805 		}
       
   806 	
       
   807 	CleanupStack::PopAndDestroy(2, random); // keyMaterial
       
   808 	}
       
   809 	
       
   810 void CTlsStepBase::ComputeSslCipherKeysL(const TDesC8& aMasterSecret, const TDesC8& aRandom)
       
   811 	{
       
   812 	// Look up the cipher suite we used for this test
       
   813 	CTlsCryptoAttributes* atts = Provider()->Attributes();
       
   814 	
       
   815 	TInt index = CipherSuiteIndex(atts->iCurrentCipherSuite);
       
   816 	User::LeaveIfError(index);
       
   817 	
       
   818 	TTLSCipherSuite suite = CipherSuites()[index];
       
   819 	
       
   820 	// Key material is:
       
   821 	// - 2 mac secrets of size hash_size
       
   822 	// - 2 bulk cipher secrets of size keymaterial_size
       
   823 	// - 2 initialisation vectors of size iv_size
       
   824 	
       
   825 	TInt hashSize = suite.CipherDetails()->iHashSize;
       
   826 	TInt keySize = suite.CipherDetails()->iKeyMaterial;
       
   827 	TInt ivSize = suite.CipherDetails()->iIVSize;
       
   828 	
       
   829 	TInt keyMaterialSize = (2*hashSize) + (2*keySize) + (2*ivSize);
       
   830 	
       
   831 	// This calculation uses the random data in the opposite order to the master secret
       
   832 	
       
   833 	HBufC8* random = HBufC8::NewLC(KTLSServerClientRandomLen * 2);
       
   834 	TTLSMasterSecretInput params = atts->iMasterSecretInput;
       
   835 	random->Des().Append(params.iServerRandom);
       
   836 	random->Des().Append(params.iClientRandom);
       
   837 	
       
   838 	HBufC8* keyMaterial = CSsl30PsuedoRandom::PseudoRandomL(aMasterSecret, *random, keyMaterialSize);		
       
   839 	CleanupStack::PushL(keyMaterial);
       
   840 	
       
   841 	iClientMacSecret = keyMaterial->Left(hashSize).AllocL();
       
   842 	iServerMacSecret = keyMaterial->Mid(hashSize, hashSize).AllocL();
       
   843 	
       
   844 	// if the cipher is exportable, we need to do further MD5 calculations to get the keys
       
   845 	if (suite.CipherDetails()->iIsExportable)
       
   846 		{
       
   847 		TInt expandedKeySize = 	suite.CipherDetails()->iExpKeySize;
       
   848 
       
   849 		CMessageDigest* md5dig = CMessageDigestFactory::NewDigestLC(CMessageDigest::EMD5);
       
   850 			
       
   851 		md5dig->Update(keyMaterial->Mid((2*hashSize), keySize));
       
   852 		iClientWriteSecret = md5dig->Hash(aRandom).Left(expandedKeySize).AllocL();
       
   853 		md5dig->Reset();
       
   854 			
       
   855 		md5dig->Update(keyMaterial->Mid((2*hashSize)+keySize, keySize));
       
   856 		iServerWriteSecret = md5dig->Hash(*random).Left(expandedKeySize).AllocL();
       
   857 		md5dig->Reset();
       
   858 		
       
   859 		iClientInitVector = md5dig->Hash(aRandom).Left(ivSize).AllocL();
       
   860 		md5dig->Reset();
       
   861 		
       
   862 		iServerInitVector = md5dig->Hash(*random).Left(ivSize).AllocL();
       
   863 		
       
   864 		CleanupStack::PopAndDestroy(md5dig);
       
   865 		}
       
   866 	else
       
   867 		{
       
   868 		// just devide the key material up in to its respective blocks
       
   869 		iClientWriteSecret = keyMaterial->Mid(2*hashSize, keySize).AllocL();
       
   870 		iServerWriteSecret = keyMaterial->Mid((2*hashSize)+keySize, keySize).AllocL();
       
   871 		iClientInitVector = keyMaterial->Mid((2*hashSize)+(2*keySize), ivSize).AllocL();
       
   872 		iServerInitVector = keyMaterial->Right(ivSize).AllocL();
       
   873 		}
       
   874 	
       
   875 	CleanupStack::PopAndDestroy(2, random); // keyMaterial
       
   876 	}
       
   877 	
       
   878 HBufC8* CTlsStepBase::ComputeTlsMacL(const TDesC8& aData, TInt64 aSequenceNumber, TRecordProtocol& aType, TBool aIsServerMac)
       
   879 	{
       
   880 	HBufC8* macSecret = aIsServerMac ? ServerMacSecret() : ClientMacSecret();
       
   881 		
       
   882 	// look up the cipher suite
       
   883 	CTlsCryptoAttributes* atts = Provider()->Attributes();
       
   884 	
       
   885 	TInt index = CipherSuiteIndex(atts->iCurrentCipherSuite);
       
   886 	User::LeaveIfError(index);
       
   887 	
       
   888 	TTLSCipherSuite suite = CipherSuites()[index];
       
   889 	
       
   890 	// use the hash algorithm associated with it for the mac. 
       
   891 	CMessageDigest::THashId hashId = CMessageDigest::ESHA1;
       
   892 	switch (suite.CipherDetails()->iMacAlg)
       
   893 		{
       
   894 	case EMd5:
       
   895 		hashId = CMessageDigest::EMD5;
       
   896 		break;
       
   897 	case ESha:
       
   898 		hashId = CMessageDigest::ESHA1;
       
   899 		break;
       
   900 	default:
       
   901 		User::Leave(KErrUnknown); // unknown mac algorithm
       
   902 		break;
       
   903 		}
       
   904 	
       
   905 	CMessageDigest* digest = CMessageDigestFactory::NewHMACLC(hashId, *macSecret);
       
   906 	
       
   907 	// construct the mac header, which consists of:
       
   908 	// - The 8 byte sequence number
       
   909 	// - The one byte record type
       
   910 	// - The two byte version
       
   911 	// - The two byte record length
       
   912 	// = 13 bytes
       
   913 	
       
   914 	TBuf8<13> macHeader;
       
   915 	macHeader.SetLength(13);
       
   916 	
       
   917 	TUint len = aData.Length();
       
   918 	TInt64 seq = aSequenceNumber;
       
   919 	for (TInt i = 7; i >= 0; --i)
       
   920 		{
       
   921 		macHeader[i] = seq;
       
   922 		seq >>= 8;
       
   923 		}
       
   924 		
       
   925 	macHeader[8] = aType;
       
   926 	macHeader[9] = atts->iNegotiatedProtocol.iMajor;
       
   927 	macHeader[10] = atts->iNegotiatedProtocol.iMinor;
       
   928 	macHeader[11] = (len >> 8);
       
   929 	macHeader[12] = len;
       
   930 	
       
   931 	// now, hash the header and the data to get the final mac
       
   932 	digest->Update(macHeader);
       
   933 	HBufC8* ret = digest->Hash(aData).AllocL();
       
   934 	
       
   935 	CleanupStack::PopAndDestroy(digest);
       
   936 	return ret;
       
   937 	}
       
   938 
       
   939 
       
   940 HBufC8* CTlsStepBase::ComputeSslMacL(const TDesC8& aData, TInt64 aSequenceNumber, TRecordProtocol& aType, TBool aIsServerMac)
       
   941 	{
       
   942 	HBufC8* macSecret = aIsServerMac ? ServerMacSecret() : ClientMacSecret();
       
   943 		
       
   944 	// look up the cipher suite
       
   945 	CTlsCryptoAttributes* atts = Provider()->Attributes();
       
   946 	
       
   947 	TInt index = CipherSuiteIndex(atts->iCurrentCipherSuite);
       
   948 	User::LeaveIfError(index);
       
   949 	
       
   950 	TTLSCipherSuite suite = CipherSuites()[index];
       
   951 	
       
   952 	// use the hash algorithm associated with it for the mac. 
       
   953 	CMessageDigest::THashId hashId = CMessageDigest::ESHA1;
       
   954 	TInt paddingLen = 0;
       
   955 	switch (suite.CipherDetails()->iMacAlg)
       
   956 		{
       
   957 	case EMd5:
       
   958 		hashId = CMessageDigest::EMD5;
       
   959 		paddingLen = 48;
       
   960 		break;
       
   961 	case ESha:
       
   962 		hashId = CMessageDigest::ESHA1;
       
   963 		paddingLen = 40;
       
   964 		break;
       
   965 	default:
       
   966 		User::Leave(KErrUnknown); // unknown mac algorithm
       
   967 		break;
       
   968 		}
       
   969 	
       
   970 	CMessageDigest* digest = CMessageDigestFactory::NewDigestLC(hashId);
       
   971 	
       
   972 	// construct the mac header, which consists of:
       
   973 	// - The 8 byte sequence number
       
   974 	// - The one byte record type
       
   975 	// - The two byte record length
       
   976 	// = 11 bytes
       
   977 	
       
   978 	TBuf8<11> macHeader;
       
   979 	macHeader.SetLength(11);
       
   980 	
       
   981 	TUint len = aData.Length();
       
   982 	TInt64 seq = aSequenceNumber;
       
   983 	for (TInt i = 7; i >= 0; --i)
       
   984 		{
       
   985 		macHeader[i] = seq;
       
   986 		seq >>= 8;
       
   987 		}
       
   988 		
       
   989 	macHeader[8] = aType;
       
   990 	macHeader[9] = (len >> 8);
       
   991 	macHeader[10] = len;
       
   992 	
       
   993 	// construct the padding.
       
   994 	HBufC8* padding = HBufC8::NewLC(paddingLen);
       
   995 	TPtr8 paddingBuf = padding->Des();	
       
   996 	paddingBuf.SetLength(paddingLen);
       
   997 	
       
   998 	// fill padding buffer for padding 1
       
   999 	paddingBuf.Fill(0x36);
       
  1000 	
       
  1001 	// compute the inner hash
       
  1002 	digest->Update(*macSecret);
       
  1003 	digest->Update(*padding);
       
  1004 	digest->Update(macHeader);
       
  1005 	digest->Update(aData);
       
  1006 	HBufC8* inner = digest->Final().AllocL();
       
  1007 	
       
  1008 	digest->Reset();
       
  1009 	// fill padding buffer for padding 2
       
  1010 	paddingBuf.Fill(0x5c);
       
  1011 	
       
  1012 	// compute the outer hash
       
  1013 	digest->Update(*macSecret);
       
  1014 	digest->Update(*padding);
       
  1015 	digest->Update(*inner);
       
  1016 	delete inner;
       
  1017 	
       
  1018 	HBufC8* ret = digest->Final().AllocL();
       
  1019 	CleanupStack::PopAndDestroy(2, digest); // padding
       
  1020 	return ret;
       
  1021 	}
       
  1022 
       
  1023 HBufC8* CTlsStepBase::ComputeTlsFinishedL(CMessageDigest* aShaDigest, CMessageDigest* aMd5Digest,
       
  1024 	const TDesC8& aMasterSecret, TBool aClientFinished)
       
  1025 	{
       
  1026 	CMessageDigest* ourSha = aShaDigest->CopyL();
       
  1027 	CleanupStack::PushL(ourSha);
       
  1028 	
       
  1029 	CMessageDigest* ourMd = aMd5Digest->CopyL();
       
  1030 	CleanupStack::PushL(ourMd);
       
  1031 	
       
  1032 	TInt len = ourSha->HashSize() + ourMd->HashSize();
       
  1033 	HBufC8* hashBuf = HBufC8::NewLC(len);
       
  1034 	
       
  1035 	hashBuf->Des().Append(ourMd->Final());
       
  1036 	hashBuf->Des().Append(ourSha->Final());
       
  1037 	
       
  1038 	_LIT8(KClientLabel, "client finished");
       
  1039 	_LIT8(KServerLabel, "server finished");
       
  1040 	
       
  1041 	TPtrC8 label;
       
  1042 	if (aClientFinished)
       
  1043 		{
       
  1044 		label.Set(KClientLabel);
       
  1045 		}
       
  1046 	else
       
  1047 		{
       
  1048 		label.Set(KServerLabel);
       
  1049 		}
       
  1050 	
       
  1051 	HBufC8* ret = CTls10PsuedoRandom::PseudoRandomL(aMasterSecret, label, *hashBuf, 12);
       
  1052 	CleanupStack::PopAndDestroy(3, ourSha);
       
  1053 	return ret;
       
  1054 	}
       
  1055 	
       
  1056 HBufC8* CTlsStepBase::ComputeSslFinishedL(CMessageDigest* aShaDigest, CMessageDigest* aMd5Digest,
       
  1057 	const TDesC8& aMasterSecret, TBool aClientFinished)
       
  1058 	{
       
  1059 	CMessageDigest* ourSha = aShaDigest->CopyL();
       
  1060 	CleanupStack::PushL(ourSha);
       
  1061 	
       
  1062 	CMessageDigest* ourMd = aMd5Digest->CopyL();
       
  1063 	CleanupStack::PushL(ourMd);
       
  1064 	
       
  1065 	_LIT8(KClientLabel, "CLNT");
       
  1066 	_LIT8(KServerLabel, "SRVR");
       
  1067 	
       
  1068 	TPtrC8 label;
       
  1069 	if (aClientFinished)
       
  1070 		{
       
  1071 		label.Set(KClientLabel);
       
  1072 		}
       
  1073 	else
       
  1074 		{
       
  1075 		label.Set(KServerLabel);
       
  1076 		}
       
  1077 
       
  1078 	// hash the label and master secret
       
  1079 	ourSha->Update(label);
       
  1080 	ourMd->Update(label);
       
  1081 	
       
  1082 	ourSha->Update(aMasterSecret);
       
  1083 	ourMd->Update(aMasterSecret);
       
  1084 
       
  1085 	// add the padding
       
  1086 	HBufC8* shaPadding = HBufC8::NewLC(40);
       
  1087 	TPtr8 shaPaddingBuf = shaPadding->Des();
       
  1088 	shaPaddingBuf.SetLength(40);
       
  1089 	
       
  1090 	HBufC8* mdPadding = HBufC8::NewLC(48);
       
  1091 	TPtr8 mdPaddingBuf = mdPadding->Des();
       
  1092 	mdPaddingBuf.SetLength(48);
       
  1093 	
       
  1094 	shaPaddingBuf.Fill(0x36);
       
  1095 	mdPaddingBuf.Fill(0x36);
       
  1096 	
       
  1097 	ourSha->Update(shaPaddingBuf);
       
  1098 	ourMd->Update(mdPaddingBuf);
       
  1099 	
       
  1100 	// finalise the inner hashes
       
  1101 	HBufC8* innerSha = ourSha->Final().AllocLC();
       
  1102 	HBufC8* innerMd = ourMd->Final().AllocLC();
       
  1103 	
       
  1104 	// reset for the outer hashes
       
  1105 	ourSha->Reset();
       
  1106 	ourMd->Reset();
       
  1107 	
       
  1108 	// hash master secret and padding for outer hashes
       
  1109 	ourSha->Update(aMasterSecret);
       
  1110 	ourMd->Update(aMasterSecret);
       
  1111 	
       
  1112 	shaPaddingBuf.Fill(0x5c);
       
  1113 	mdPaddingBuf.Fill(0x5c);
       
  1114 	
       
  1115 	ourSha->Update(shaPaddingBuf);
       
  1116 	ourMd->Update(mdPaddingBuf);
       
  1117 	
       
  1118 	// and finally, the inner hash.
       
  1119 	ourSha->Update(*innerSha);
       
  1120 	ourMd->Update(*innerMd);
       
  1121 	
       
  1122 	// create the final buffer
       
  1123 	HBufC8* ret = HBufC8::NewL(ourSha->HashSize() + ourMd->HashSize());
       
  1124 	ret->Des().Append(ourMd->Final());
       
  1125 	ret->Des().Append(ourSha->Final());
       
  1126 
       
  1127 	CleanupStack::PopAndDestroy(6, ourSha); // ourMd, shaPadding, mdPadding, innerSha, innerMd
       
  1128 	return ret;		
       
  1129 	}
       
  1130 	
       
  1131 TInt CTlsStepBase::ClientCertificate(CX509Certificate* aCert)
       
  1132 	{
       
  1133 	iSession->ClientCertificate(aCert,iActive->iStatus);
       
  1134 	iActive->Start();
       
  1135 	return iActive->iStatus.Int();
       
  1136 	}
       
  1137 
       
  1138 TInt CTlsStepBase::ClientCertificate(HBufC8*& aCertBuf)
       
  1139 	{
       
  1140 	iActive->iStatus = KRequestPending;
       
  1141 	iSession->ClientCertificate(aCertBuf, iActive->iStatus);
       
  1142 	iActive->Start();
       
  1143 	return iActive->iStatus.Int();
       
  1144 	}
       
  1145 
       
  1146 TInt CTlsStepBase::ClientCertificate(RPointerArray<HBufC8>* aClientCertArray)
       
  1147 	{
       
  1148 	iActive->iStatus = KRequestPending;
       
  1149 	iSession->ClientCertificate(aClientCertArray, iActive->iStatus);
       
  1150 	iActive->Start();
       
  1151 	return iActive->iStatus.Int();
       
  1152 	}
       
  1153 
       
  1154 TInt CTlsStepBase::CertificateVerifySignatureL(
       
  1155 		CMessageDigest* iMd5DigestInput,
       
  1156 		CMessageDigest* iShaDigestInput,
       
  1157 		HBufC8*& aOutput)
       
  1158 	{
       
  1159 	iActive->iStatus = KRequestPending;
       
  1160 	iSession->CertificateVerifySignatureL(
       
  1161 		iMd5DigestInput, 
       
  1162 		iShaDigestInput,
       
  1163 		aOutput,
       
  1164 		iActive->iStatus);
       
  1165 	iActive->Start();
       
  1166 	return iActive->iStatus.Int();
       
  1167 	}
       
  1168 	
       
  1169 TBool CTlsStepBase::ReadPskToBeUsedL() 
       
  1170 	{
       
  1171 	
       
  1172 	TBool theReturn = ETrue;
       
  1173 	
       
  1174 	
       
  1175  	TBool usePsk;
       
  1176 	if(GetBoolFromConfig(ConfigSection(), KUsePsk, usePsk))
       
  1177 		{
       
  1178 	 	iUsePsk = usePsk;
       
  1179 	 	}
       
  1180 	else
       
  1181 		{
       
  1182 		iUsePsk = EFalse;
       
  1183 		theReturn = EFalse;
       
  1184 		}
       
  1185 	
       
  1186  	// Reads key 1 value	
       
  1187  	if (iUsePsk)
       
  1188 		{	
       
  1189 			TPtrC8  pskKey;
       
  1190 			if(GetKeyFromConfigL(ConfigSection(),KPskKey ,pskKey ) )
       
  1191 				{
       
  1192 				iPskKey = pskKey.AllocL();
       
  1193 				}
       
  1194 				else
       
  1195 				{
       
  1196 				ERR_PRINTF1(_L("Couldn't read PSK key") );
       
  1197 				User::Leave(KErrGeneral);
       
  1198 				}
       
  1199 		}  
       
  1200 		
       
  1201  	// Reads PSK identity	
       
  1202  	if (iUsePsk)
       
  1203 		{	
       
  1204 			TPtrC   pskIdentity;
       
  1205 			if(GetStringFromConfig(ConfigSection(), KPskIdentity, pskIdentity) )
       
  1206 				{
       
  1207 				iPskIdentity = HBufC8::New(pskIdentity.Length());
       
  1208 				iPskIdentity->Des().Copy(pskIdentity);
       
  1209 				}
       
  1210 			else
       
  1211 				{
       
  1212 				ERR_PRINTF1(_L("Couldn't read PSK identity") );
       
  1213 				User::Leave(KErrGeneral);
       
  1214 				}
       
  1215 		}  
       
  1216 		  
       
  1217 	return theReturn;
       
  1218 	}
       
  1219 	
       
  1220 void CTlsStepBase::ReadUseNullCipher() 
       
  1221 	{
       
  1222 	 	TBool useNullCipher;
       
  1223 	if(GetBoolFromConfig(ConfigSection(), KUseNullCipher, useNullCipher))
       
  1224 		{
       
  1225 	 	iUseNullCipher = useNullCipher;
       
  1226 	 	}
       
  1227 	else
       
  1228 		{
       
  1229 		iUseNullCipher = EFalse;
       
  1230 		}
       
  1231 	}
       
  1232 	
       
  1233 TInt CTlsStepBase::ReadGetSessionDelayL() 
       
  1234 	{
       
  1235 	TInt sessionDelay;
       
  1236 	
       
  1237 	if(GetIntFromConfig(ConfigSection(), KSessionDelay, sessionDelay))
       
  1238 		{
       
  1239 	 	return sessionDelay;
       
  1240 	 	}
       
  1241 	else
       
  1242 		{
       
  1243 		ERR_PRINTF1(_L("Couldn't read session delay INI value") );
       
  1244 		User::Leave(KErrNotFound);
       
  1245 		}
       
  1246 	 // Keeps compiler happy, will not hit.
       
  1247 	return 0;
       
  1248 	}
       
  1249 
       
  1250 	HBufC8* CTlsStepBase::StringToHexLC(const TDes8 &aString)
       
  1251 	/**
       
  1252 	 * Function to convert the contents of a TDes8 into a Binary format
       
  1253 	 *
       
  1254 	 * @param  - cosnt TDes8 aString: String to convert into Hexadecimal
       
  1255 	 * @return - HBufC8*: Converted Binary string representation
       
  1256 	 **/
       
  1257 	{
       
  1258  	HBufC8* parsedString = HBufC8::NewLC(aString.Length()/2);
       
  1259 
       
  1260     TBuf8<1> binChar;
       
  1261 	_LIT8(KFormatBinary,"%c"); 
       
  1262 	
       
  1263  	TPtr8 ptr(parsedString->Des());
       
  1264 	
       
  1265   	for(TInt i = 0; i<aString.Length()/2 ; i++)
       
  1266     	{
       
  1267     	TPtrC8 tempPtr(aString.Mid(i*2,2));
       
  1268     	TLex8 lex(tempPtr);
       
  1269     	TUint val=0;
       
  1270     	lex.Val(val, EHex);
       
  1271     	binChar.Format(KFormatBinary,val);
       
  1272     	 ptr.Append(binChar);
       
  1273              	
       
  1274        	}   
       
  1275       	
       
  1276         
       
  1277 	return parsedString;
       
  1278 	}
       
  1279 
       
  1280 	
       
  1281 	
       
  1282 	
       
  1283     TBool CTlsStepBase::GetKeyFromConfigL(const TDesC& aSectName, const TDesC& aIniValueName, TPtrC8 & aResult)
       
  1284 	{
       
  1285 	
       
  1286 	
       
  1287 	TBool theReturn(ETrue);
       
  1288 	// The buffer with key read form ini file as a string converted to a buffer of hex.
       
  1289 
       
  1290 	TPtrC iniString; 
       
  1291 	if(GetStringFromConfig(aSectName, aIniValueName, iniString))
       
  1292 		{
       
  1293 		
       
  1294 					
       
  1295 		TInt stringLength(iniString.Length());
       
  1296 		// Assumes that keys must be formed by Hex pairs (full bytes)
       
  1297 		// example:  ABC1  is acceptable.  ABC   is not acceptable
       
  1298 		if( stringLength % 2 > 0)
       
  1299 			{
       
  1300 			// not pairs.
       
  1301 			theReturn = EFalse;
       
  1302 			}
       
  1303 		// Pairs
       
  1304 		else
       
  1305 			{
       
  1306 		 		
       
  1307 			HBufC8* keyBuf = HBufC8::New(iniString.Length());
       
  1308 			TPtr8 ptrKey = keyBuf->Des();
       
  1309 			ptrKey.Copy(iniString);
       
  1310 			
       
  1311 		  	HBufC8* key = StringToHexLC(keyBuf->Des());
       
  1312 			delete keyBuf;
       
  1313 	 		aResult.Set(key->Des());
       
  1314 	 		CleanupStack::PopAndDestroy(key);
       
  1315  			
       
  1316 			}
       
  1317 				
       
  1318 		}
       
  1319 
       
  1320  	return theReturn;		
       
  1321 	}
       
  1322  
       
  1323 TInt CTlsStepBase::SessionServerCertificate(CX509Certificate*& aCertOut) 
       
  1324 	{
       
  1325 	iActive->iStatus = KRequestPending;
       
  1326 	iSession->ServerCertificate(aCertOut, iActive->iStatus );
       
  1327 	iActive->Start();
       
  1328 	return iActive->iStatus.Int();
       
  1329 		
       
  1330 	}
       
  1331 
       
  1332 TInt CTlsStepBase::SessionServerCertificateWithCancel(CX509Certificate*& aCertOut) 
       
  1333 	{
       
  1334 	iActive->iStatus = KRequestPending;
       
  1335 	iSession->ServerCertificate(aCertOut, iActive->iStatus );
       
  1336 	iSession->CancelRequest();
       
  1337  	iActive->Start();
       
  1338 	return iActive->iStatus.Int();
       
  1339 	}
       
  1340 
       
  1341 void CTlsStepBase::StandardAttrInit( CTlsCryptoAttributes* tlsCryptoAttributes)
       
  1342 	{
       
  1343 	tlsCryptoAttributes->iClientAuthenticate = EFalse;
       
  1344 	tlsCryptoAttributes->iDialogNonAttendedMode = ETrue;
       
  1345 	
       
  1346 	tlsCryptoAttributes->iSessionNameAndID.iServerName.iAddress.Copy( KNServer1 );
       
  1347 	tlsCryptoAttributes->iSessionNameAndID.iServerName.iPort = 10;
       
  1348 	tlsCryptoAttributes->iSessionNameAndID.iSessionId.Append( KSessionId1 );
       
  1349 		
       
  1350 	tlsCryptoAttributes->iCompressionMethod = ENullCompression;
       
  1351 	tlsCryptoAttributes->iCurrentCipherSuite.iHiByte = 0;
       
  1352 	tlsCryptoAttributes->iCurrentCipherSuite.iLoByte = 3;
       
  1353 			
       
  1354 	tlsCryptoAttributes->iNegotiatedProtocol.iMajor = 3;
       
  1355 	tlsCryptoAttributes->iNegotiatedProtocol.iMinor = 1; 
       
  1356 	
       
  1357 	tlsCryptoAttributes->iProposedProtocol.iMajor = 3;
       
  1358 	tlsCryptoAttributes->iProposedProtocol.iMinor = 1; 
       
  1359 		
       
  1360 	tlsCryptoAttributes->iPublicKeyParams->iKeyType = ERsa;
       
  1361 	tlsCryptoAttributes->iClientAuthenticate = EFalse; 
       
  1362 	tlsCryptoAttributes->iDialogNonAttendedMode = ETrue;
       
  1363 	}
       
  1364 
       
  1365 void CTlsStepBase::DeleteSecureDialogFilesL()
       
  1366 	{
       
  1367 	RFs fs;
       
  1368 	User::LeaveIfError(fs.Connect());
       
  1369 	CleanupClosePushL(fs);
       
  1370 	
       
  1371 	CFileMan* fileMan = CFileMan::NewL(fs);
       
  1372 	CleanupStack::PushL(fileMan);
       
  1373 	
       
  1374 	TDriveUnit sysDrive (RFs::GetSystemDrive());
       
  1375 	TDriveName sysDriveName (sysDrive.Name());
       
  1376 	
       
  1377 	TBuf<128> fileName (sysDriveName);
       
  1378 	fileName.Append(KInputFile);
       
  1379 	TInt err = fileMan->Delete(fileName);
       
  1380 	if ( err != KErrNotFound && err != KErrNone )
       
  1381 		{
       
  1382 		User::LeaveIfError(err);
       
  1383 		}
       
  1384 		
       
  1385 	fileName.Copy(sysDriveName);
       
  1386 	fileName.Append(KOutputFile);	
       
  1387 	err = fileMan->Delete(fileName);
       
  1388 	if (err != KErrNotFound && err != KErrNone )
       
  1389 		{
       
  1390 		User::LeaveIfError(err);
       
  1391 		}
       
  1392 	CleanupStack::PopAndDestroy(2, &fs);// and fileMan
       
  1393 	}
       
  1394 
       
  1395 void CTlsStepBase::SetDialogRecordL(RFileWriteStream& aStream, TSecurityDialogOperation aOp, const TDesC& aLabelSpec,
       
  1396 											 const TDesC& aResponse1, const TDesC& aResponse2)
       
  1397 	{
       
  1398 	MStreamBuf* streamBuf = aStream.Sink();
       
  1399 	streamBuf->SeekL(MStreamBuf::EWrite, EStreamEnd);
       
  1400 	aStream.WriteInt32L(aOp);
       
  1401 	aStream.WriteInt32L(aLabelSpec.Length());
       
  1402 	aStream.WriteL(aLabelSpec);
       
  1403 	aStream.WriteInt32L(aResponse1.Length());
       
  1404 	aStream.WriteL(aResponse1);
       
  1405 	aStream.WriteInt32L(aResponse2.Length());
       
  1406 	aStream.WriteL(aResponse2);
       
  1407 	}
       
  1408 
       
  1409 
       
  1410