os/security/cryptoservices/filebasedcertificateandkeystores/source/keystore/Server/CKeyDataManager.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2004-2010 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of the License "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description: 
sl@0
    15
*
sl@0
    16
*/
sl@0
    17
sl@0
    18
sl@0
    19
#include "CKeyDataManager.h"
sl@0
    20
#include "fsdatatypes.h"
sl@0
    21
#include "fstokencliserv.h"
sl@0
    22
#include "fstokenutil.h"
sl@0
    23
#include "keystorepassphrase.h"
sl@0
    24
sl@0
    25
_LIT(KKeyStoreFilename,"keys.dat");
sl@0
    26
sl@0
    27
#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
    28
#include <e32property.h>
sl@0
    29
#include <authserver/aspubsubdefs.h>
sl@0
    30
#else
sl@0
    31
const TInt KDefaultPassphraseTimeout = 30;
sl@0
    32
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
    33
sl@0
    34
//	*********************************************************************
sl@0
    35
//	Key store data manager - maintains array of objects representing keys
sl@0
    36
//	*********************************************************************
sl@0
    37
sl@0
    38
/*static*/ CFileKeyDataManager* CFileKeyDataManager::NewL()
sl@0
    39
	{
sl@0
    40
	CFileKeyDataManager* self = new (ELeave) CFileKeyDataManager();
sl@0
    41
	CleanupStack::PushL(self);
sl@0
    42
	self->ConstructL();
sl@0
    43
	CleanupStack::Pop(self);
sl@0
    44
	return self;
sl@0
    45
	}
sl@0
    46
sl@0
    47
CFileKeyDataManager::~CFileKeyDataManager()
sl@0
    48
	{
sl@0
    49
	if (iFileStore)
sl@0
    50
		{
sl@0
    51
		CompactStore();
sl@0
    52
		delete iFileStore;
sl@0
    53
		}
sl@0
    54
sl@0
    55
	iFile.Close(); // May already have been closed by store
sl@0
    56
	iFs.Close();
sl@0
    57
		
sl@0
    58
	iKeys.ResetAndDestroy();
sl@0
    59
	iKeys.Close();
sl@0
    60
	#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
    61
	iIdentityId.Close();
sl@0
    62
	#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
    63
	}
sl@0
    64
sl@0
    65
CFileKeyDataManager::CFileKeyDataManager() :
sl@0
    66
	iRootStreamId(KNullStreamId),
sl@0
    67
	iInfoStreamId(KNullStreamId)
sl@0
    68
#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
    69
	,iPassStreamId(KNullStreamId),
sl@0
    70
	iTimeoutStreamId(KNullStreamId)
sl@0
    71
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
    72
	{
sl@0
    73
	}
sl@0
    74
sl@0
    75
void CFileKeyDataManager::ConstructL()
sl@0
    76
	{
sl@0
    77
	
sl@0
    78
	User::LeaveIfError(iFs.Connect());
sl@0
    79
	OpenStoreL();
sl@0
    80
sl@0
    81
	RStoreReadStream lookupStream;
sl@0
    82
	lookupStream.OpenLC(*iFileStore, iInfoStreamId);
sl@0
    83
sl@0
    84
	#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
    85
	User::LeaveIfError(iIdentityId.Attach(	AuthServer::KAuthServerSecureId,
sl@0
    86
											AuthServer::KUidAuthServerAuthChangeEvent));
sl@0
    87
	#else
sl@0
    88
	iPassStreamId = (TStreamId) lookupStream.ReadUint32L();
sl@0
    89
	iTimeoutStreamId = (TStreamId) lookupStream.ReadUint32L();
sl@0
    90
	#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
    91
sl@0
    92
	TInt count = lookupStream.ReadInt32L();
sl@0
    93
	for (TInt index = 0; index < count; index++)
sl@0
    94
		{
sl@0
    95
		CFileKeyData* keyData = CFileKeyData::NewL(lookupStream);
sl@0
    96
		CleanupStack::PushL(keyData);
sl@0
    97
sl@0
    98
		if (keyData->Handle() > iKeyIdentifier)
sl@0
    99
			iKeyIdentifier = keyData->Handle();
sl@0
   100
sl@0
   101
		iKeys.AppendL(keyData);
sl@0
   102
		CleanupStack::Pop(keyData);
sl@0
   103
		}
sl@0
   104
	
sl@0
   105
	CleanupStack::PopAndDestroy(&lookupStream);
sl@0
   106
sl@0
   107
#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   108
	ReadPassphraseTimeoutL();
sl@0
   109
#endif //SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   110
	
sl@0
   111
	}
sl@0
   112
sl@0
   113
CPassphraseManager* CFileKeyDataManager::CreatePassphraseManagerLC()
sl@0
   114
	{
sl@0
   115
	CPassphraseManager* result = CPassphraseManager::NewL(*iFileStore);
sl@0
   116
	CleanupStack::PushL(result);
sl@0
   117
	return result;
sl@0
   118
	}
sl@0
   119
sl@0
   120
void CFileKeyDataManager::OpenStoreL()
sl@0
   121
	{
sl@0
   122
	//	Tries to locate a key store file on the default drive and then from ROM
sl@0
   123
	//	If it cannot find one, tries to create a file with permanent file store
sl@0
   124
	//	inside it In all cases, should initialise iFileStore unless it cannot
sl@0
   125
	//	create the file/store/streams
sl@0
   126
	
sl@0
   127
	__ASSERT_DEBUG(!iFileStore, PanicServer(EPanicStoreInitialised));
sl@0
   128
sl@0
   129
	TFileName fullPath;
sl@0
   130
	FileUtils::MakePrivateFilenameL(iFs, KKeyStoreFilename, fullPath);
sl@0
   131
sl@0
   132
	FileUtils::EnsurePathL(iFs, fullPath);
sl@0
   133
	TRAPD(result, OpenStoreInFileL(fullPath));
sl@0
   134
sl@0
   135
	if (result == KErrInUse) 
sl@0
   136
		{		
sl@0
   137
		// Cannot access the file now. Abort server startup rather than wiping the keystore.
sl@0
   138
		User::Leave(result); 
sl@0
   139
		}
sl@0
   140
sl@0
   141
	if (result != KErrNone)
sl@0
   142
		{		
sl@0
   143
		// Not yet opened a valid store, either no file to be found, or no valid
sl@0
   144
		// store in it. Copy the original one stored in the ROM.
sl@0
   145
		delete iFileStore;
sl@0
   146
		iFileStore = NULL;
sl@0
   147
		
sl@0
   148
		TFileName romPath;
sl@0
   149
		FileUtils::MakePrivateROMFilenameL(iFs, KKeyStoreFilename, romPath);
sl@0
   150
sl@0
   151
		if (result != KErrNotFound)
sl@0
   152
			{
sl@0
   153
			// Wipe the keystore if we can't open it (it's corrupt anyway)
sl@0
   154
			User::LeaveIfError(iFs.Delete(fullPath));
sl@0
   155
			}
sl@0
   156
sl@0
   157
		// Copy data from rom and open it	
sl@0
   158
		TRAPD(err,
sl@0
   159
			  FileUtils::CopyL(iFs, romPath, fullPath);
sl@0
   160
			  OpenStoreInFileL(fullPath)
sl@0
   161
			);
sl@0
   162
		
sl@0
   163
		if (KErrNone != err)
sl@0
   164
			{
sl@0
   165
			// We tried to copy the keystore from ROM. For some reason this
sl@0
   166
			// failed and we still cannot open the file. Create a new one from
sl@0
   167
			// scratch.
sl@0
   168
			CreateStoreInFileL(fullPath);
sl@0
   169
			}
sl@0
   170
		}
sl@0
   171
sl@0
   172
	__ASSERT_DEBUG(iFileStore, PanicServer(EPanicStoreInitialised));
sl@0
   173
	__ASSERT_DEBUG((KNullStreamId!=iRootStreamId), PanicServer(EPanicRootStreamNotReady));
sl@0
   174
	__ASSERT_DEBUG((KNullStreamId!=iInfoStreamId), PanicServer(EPanicManagerStreamNotReady));
sl@0
   175
	}
sl@0
   176
sl@0
   177
void CFileKeyDataManager::CreateStoreInFileL(const TDesC& aFile)
sl@0
   178
	{
sl@0
   179
	TInt r = iFs.MkDirAll(aFile);
sl@0
   180
	if ( (r!=KErrNone) && (r!=KErrAlreadyExists) )
sl@0
   181
		User::Leave(r);
sl@0
   182
sl@0
   183
	iFileStore = CPermanentFileStore::ReplaceL(iFs, aFile, EFileRead | EFileWrite | EFileShareExclusive);
sl@0
   184
	iFileStore->SetTypeL(KPermanentFileStoreLayoutUid);
sl@0
   185
sl@0
   186
	TCleanupItem cleanupStore(RevertStore, iFileStore);
sl@0
   187
	CleanupStack::PushL(cleanupStore);
sl@0
   188
	
sl@0
   189
#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   190
	// Create timeout stream with default timeout
sl@0
   191
	RStoreWriteStream timeoutStream;
sl@0
   192
	iTimeoutStreamId = timeoutStream.CreateLC(*iFileStore);
sl@0
   193
	timeoutStream.WriteUint32L(KDefaultPassphraseTimeout);
sl@0
   194
	timeoutStream.CommitL();
sl@0
   195
	CleanupStack::PopAndDestroy(&timeoutStream);
sl@0
   196
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   197
	
sl@0
   198
	// Create info stream - Currently no passphrase created, and no keys
sl@0
   199
	RStoreWriteStream infoStream;
sl@0
   200
	iInfoStreamId = infoStream.CreateLC(*iFileStore);
sl@0
   201
	
sl@0
   202
#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   203
	infoStream.WriteUint32L(KNullStreamId.Value());
sl@0
   204
	infoStream.WriteUint32L(iTimeoutStreamId.Value());
sl@0
   205
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   206
	
sl@0
   207
	infoStream.WriteUint32L(0); // Write key count of zero
sl@0
   208
	infoStream.CommitL();
sl@0
   209
	CleanupStack::PopAndDestroy(&infoStream);
sl@0
   210
sl@0
   211
	// Create root stream - just contains id of info stream
sl@0
   212
	RStoreWriteStream rootStream;
sl@0
   213
	iRootStreamId = rootStream.CreateLC(*iFileStore);
sl@0
   214
	iFileStore->SetRootL(iRootStreamId);
sl@0
   215
sl@0
   216
	rootStream.WriteUint32L(iInfoStreamId.Value());		
sl@0
   217
	rootStream.CommitL();
sl@0
   218
	CleanupStack::PopAndDestroy(&rootStream);
sl@0
   219
sl@0
   220
	WriteKeysToStoreL();
sl@0
   221
	
sl@0
   222
	iFileStore->CommitL();
sl@0
   223
	CleanupStack::Pop(); // cleanupStore
sl@0
   224
	}
sl@0
   225
sl@0
   226
void CFileKeyDataManager::OpenStoreInFileL(const TDesC& aFile)
sl@0
   227
	{
sl@0
   228
	// Make sure the file isn't write protected
sl@0
   229
	User::LeaveIfError(iFs.SetAtt(aFile, 0, KEntryAttReadOnly));
sl@0
   230
	
sl@0
   231
	User::LeaveIfError(iFile.Open(iFs, aFile, EFileRead | EFileWrite | EFileShareExclusive));
sl@0
   232
	
sl@0
   233
	iFileStore = CPermanentFileStore::FromL(iFile);		
sl@0
   234
sl@0
   235
	// Get the salt, root and manager TStreamIds
sl@0
   236
	iRootStreamId = iFileStore->Root();
sl@0
   237
	if (iRootStreamId == KNullStreamId)
sl@0
   238
		{
sl@0
   239
		User::Leave(KErrCorrupt);
sl@0
   240
		}
sl@0
   241
	
sl@0
   242
	RStoreReadStream rootStream;
sl@0
   243
	rootStream.OpenLC(*iFileStore, iRootStreamId);
sl@0
   244
	iInfoStreamId = (TStreamId)(rootStream.ReadUint32L());
sl@0
   245
	CleanupStack::PopAndDestroy(&rootStream);
sl@0
   246
	}
sl@0
   247
sl@0
   248
// Methods dealing with atomic updates to key data file ////////////////////////
sl@0
   249
sl@0
   250
// This is a cleanup item that reverts the store
sl@0
   251
void CFileKeyDataManager::RevertStore(TAny* aStore)
sl@0
   252
{
sl@0
   253
	CPermanentFileStore* store = reinterpret_cast<CPermanentFileStore*>(aStore);
sl@0
   254
	TRAP_IGNORE(store->RevertL());
sl@0
   255
	// We're ignoring the leave code from this becuase there's no way we can
sl@0
   256
	// handle this sensibly.  This shouldn't be a problem in practice - this
sl@0
   257
	// will leave if for example the file store is on removable which is
sl@0
   258
	// unexpectedly remove, and this is never the case for us.
sl@0
   259
}
sl@0
   260
sl@0
   261
// Rewrites the info stream (ie the array of key data info) to the store
sl@0
   262
void CFileKeyDataManager::WriteKeysToStoreL()
sl@0
   263
	{
sl@0
   264
	RStoreWriteStream lookupStream;
sl@0
   265
	lookupStream.ReplaceLC(*iFileStore, iInfoStreamId);
sl@0
   266
sl@0
   267
	#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   268
		lookupStream.WriteUint32L(iPassStreamId.Value());
sl@0
   269
		lookupStream.WriteUint32L(iTimeoutStreamId.Value());
sl@0
   270
	#endif //SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   271
	
sl@0
   272
	TInt keyCount = iKeys.Count();
sl@0
   273
	lookupStream.WriteInt32L(keyCount);
sl@0
   274
sl@0
   275
	for (TInt index = 0; index < keyCount; index++)
sl@0
   276
		{
sl@0
   277
		const CFileKeyData* key = iKeys[index];
sl@0
   278
		key->ExternalizeL(lookupStream);
sl@0
   279
		}
sl@0
   280
sl@0
   281
	lookupStream.CommitL();
sl@0
   282
	CleanupStack::PopAndDestroy(&lookupStream);
sl@0
   283
	}
sl@0
   284
sl@0
   285
/**
sl@0
   286
 * Add a key to the store.  Assumes that the key data streams (info, public key
sl@0
   287
 * and private key) have already been written.
sl@0
   288
 */
sl@0
   289
void CFileKeyDataManager::AddL(const CFileKeyData* aKeyData)
sl@0
   290
	{
sl@0
   291
	ASSERT(aKeyData);
sl@0
   292
#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   293
		ASSERT(aKeyData->PassphraseStreamId() != KNullStreamId);
sl@0
   294
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   295
sl@0
   296
	// Add the key to to the array, rewrite the infostream and 
sl@0
   297
	// ONLY THEN commit the store
sl@0
   298
	User::LeaveIfError(iKeys.Append(aKeyData));
sl@0
   299
sl@0
   300
#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   301
	TStreamId oldDefaultPassphraseId;
sl@0
   302
sl@0
   303
	// Set the default passphrase id if this is the first key
sl@0
   304
	oldDefaultPassphraseId = iPassStreamId;
sl@0
   305
	if (iKeys.Count() == 1)
sl@0
   306
		{
sl@0
   307
		iPassStreamId = aKeyData->PassphraseStreamId();
sl@0
   308
		}
sl@0
   309
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   310
	
sl@0
   311
	TRAPD(err,UpdateStoreL());
sl@0
   312
	
sl@0
   313
	if (err != KErrNone)
sl@0
   314
		{
sl@0
   315
		iKeys.Remove(iKeys.Count() - 1);
sl@0
   316
		#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   317
			iPassStreamId = oldDefaultPassphraseId;
sl@0
   318
		#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   319
		User::Leave(err);
sl@0
   320
		}
sl@0
   321
	}
sl@0
   322
sl@0
   323
void CFileKeyDataManager::UpdateStoreL()
sl@0
   324
	{
sl@0
   325
	WriteKeysToStoreL();
sl@0
   326
sl@0
   327
	// Release ownership of key data and reset default passphrase id if store
sl@0
   328
	// can't be written
sl@0
   329
	TCleanupItem cleanupStore(RevertStore, iFileStore);
sl@0
   330
	CleanupStack::PushL(cleanupStore);
sl@0
   331
sl@0
   332
	iFileStore->CommitL();
sl@0
   333
	
sl@0
   334
	CleanupStack::Pop(); // cleanupStore
sl@0
   335
	}
sl@0
   336
sl@0
   337
/**
sl@0
   338
 * "Transaction safe" key removal - only removes the key in memory and file if
sl@0
   339
 * all operations are successful.
sl@0
   340
 */
sl@0
   341
void CFileKeyDataManager::RemoveL(TInt aObjectId)
sl@0
   342
	{
sl@0
   343
	TInt index;
sl@0
   344
	const CFileKeyData* key = NULL;
sl@0
   345
	for (index = 0 ; index < iKeys.Count() ; ++index)
sl@0
   346
		{
sl@0
   347
		if (iKeys[index]->Handle() == aObjectId)
sl@0
   348
			{
sl@0
   349
			key = iKeys[index];
sl@0
   350
			break;
sl@0
   351
			}
sl@0
   352
		}
sl@0
   353
	
sl@0
   354
	if (!key)
sl@0
   355
		{
sl@0
   356
		User::Leave(KErrNotFound);
sl@0
   357
		}
sl@0
   358
sl@0
   359
	TCleanupItem cleanupStore(RevertStore, iFileStore);
sl@0
   360
	CleanupStack::PushL(cleanupStore);	
sl@0
   361
sl@0
   362
	iFileStore->DeleteL(key->PrivateDataStreamId());
sl@0
   363
	iFileStore->DeleteL(key->PublicDataStreamId());
sl@0
   364
	iFileStore->DeleteL(key->InfoDataStreamId());
sl@0
   365
sl@0
   366
#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   367
	// Remove the passphrase if it's the last key
sl@0
   368
	TStreamId oldPassphraseId = iPassStreamId;
sl@0
   369
	if (Count() == 1)
sl@0
   370
		{
sl@0
   371
		iFileStore->DeleteL(iPassStreamId);
sl@0
   372
		iPassStreamId = KNullStreamId;
sl@0
   373
		}
sl@0
   374
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   375
	
sl@0
   376
	// Remove the key
sl@0
   377
	iKeys.Remove(index);
sl@0
   378
	
sl@0
   379
	TRAPD(res, WriteKeysToStoreL());
sl@0
   380
sl@0
   381
	if (res != KErrNone)
sl@0
   382
		{
sl@0
   383
#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER		
sl@0
   384
		iPassStreamId = oldPassphraseId;
sl@0
   385
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   386
		User::LeaveIfError(iKeys.Append(key)); // Put it back, shouldn't leave
sl@0
   387
		User::Leave(res);
sl@0
   388
		}
sl@0
   389
	else 
sl@0
   390
		{
sl@0
   391
		delete key;   // Cannot leave from the point it's removed to here, so no cleanup stack!
sl@0
   392
		}		
sl@0
   393
	iFileStore->CommitL();
sl@0
   394
sl@0
   395
	CleanupStack::Pop(); // cleanupStore
sl@0
   396
	CompactStore();
sl@0
   397
}
sl@0
   398
sl@0
   399
#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   400
TBool CFileKeyDataManager::IsKeyAlreadyInStore(const TDesC& aKeyLabel, AuthServer::TIdentityId aIdentity) const
sl@0
   401
	{//	Check each key in the store to determine if aKeyLabel already exists
sl@0
   402
	TInt keyCount = iKeys.Count();
sl@0
   403
	TBool isInStore = EFalse;
sl@0
   404
	for (TInt index = 0; index < keyCount; ++index)
sl@0
   405
		{
sl@0
   406
		const TDesC& keyLabel = iKeys[index]->Label();
sl@0
   407
		if (keyLabel.Compare(aKeyLabel)==0 && (iKeys[index]->Identity() == aIdentity))
sl@0
   408
			{
sl@0
   409
			isInStore = ETrue;
sl@0
   410
			break;
sl@0
   411
			}
sl@0
   412
		}
sl@0
   413
	return (isInStore);
sl@0
   414
	}
sl@0
   415
sl@0
   416
#else
sl@0
   417
TBool CFileKeyDataManager::IsKeyAlreadyInStore(const TDesC& aKeyLabel) const
sl@0
   418
{//	Check each key in the store to determine if aKeyLabel already exists
sl@0
   419
	TInt keyCount = iKeys.Count();
sl@0
   420
	TBool isInStore = EFalse;
sl@0
   421
	for (TInt index = 0; index < keyCount; index++)
sl@0
   422
	{
sl@0
   423
		const TDesC& keyLabel = iKeys[index]->Label();
sl@0
   424
		if (keyLabel.Compare(aKeyLabel)==0)
sl@0
   425
		{
sl@0
   426
			isInStore = ETrue;
sl@0
   427
			break;
sl@0
   428
		}
sl@0
   429
	}
sl@0
   430
sl@0
   431
	return (isInStore);
sl@0
   432
}
sl@0
   433
sl@0
   434
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   435
sl@0
   436
TInt CFileKeyDataManager::Count() const
sl@0
   437
	{
sl@0
   438
	return iKeys.Count();
sl@0
   439
	}	
sl@0
   440
sl@0
   441
const CFileKeyData* CFileKeyDataManager::operator[](TInt aIndex) const
sl@0
   442
	{
sl@0
   443
	return iKeys[aIndex];
sl@0
   444
	}
sl@0
   445
sl@0
   446
const CFileKeyData* CFileKeyDataManager::Lookup(TInt aObjectId) const
sl@0
   447
	{
sl@0
   448
	TInt count = Count();
sl@0
   449
	for (TInt i = 0; i < count; ++i)
sl@0
   450
		{
sl@0
   451
		if ((*this)[i]->Handle() == aObjectId)
sl@0
   452
			{
sl@0
   453
			return (*this)[i];
sl@0
   454
			}
sl@0
   455
		}
sl@0
   456
	return NULL;
sl@0
   457
	}
sl@0
   458
sl@0
   459
//	*********************************************************************
sl@0
   460
//	Management of file and store therein
sl@0
   461
//	*********************************************************************
sl@0
   462
sl@0
   463
#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   464
sl@0
   465
const CFileKeyData* CFileKeyDataManager::CreateKeyDataLC(const TDesC& aLabel, AuthServer::TIdentityId aIdentityId)
sl@0
   466
	{
sl@0
   467
	TInt objectId = ++iKeyIdentifier;
sl@0
   468
	TStreamId infoData = CreateWriteStreamL();
sl@0
   469
	TStreamId publicKeyData = CreateWriteStreamL();
sl@0
   470
	TStreamId privateKeyData = CreateWriteStreamL();
sl@0
   471
	return CFileKeyData::NewLC(objectId, aLabel, infoData, publicKeyData, privateKeyData, aIdentityId);
sl@0
   472
	}
sl@0
   473
sl@0
   474
#else
sl@0
   475
const CFileKeyData* CFileKeyDataManager::CreateKeyDataLC(const TDesC& aLabel, TStreamId aPassStreamId)
sl@0
   476
	{
sl@0
   477
	ASSERT(aPassStreamId != KNullStreamId);
sl@0
   478
	TInt objectId = ++iKeyIdentifier;
sl@0
   479
	TStreamId infoData = CreateWriteStreamL();
sl@0
   480
	TStreamId publicKeyData = CreateWriteStreamL();
sl@0
   481
	TStreamId privateKeyData = CreateWriteStreamL();
sl@0
   482
	return CFileKeyData::NewLC(objectId, aLabel, infoData, aPassStreamId, publicKeyData, privateKeyData);
sl@0
   483
	}
sl@0
   484
sl@0
   485
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   486
sl@0
   487
//	Creates a new write stream in the store (which it then closes)
sl@0
   488
//	Returns the TStreamId associated with it
sl@0
   489
TStreamId CFileKeyDataManager::CreateWriteStreamL()
sl@0
   490
	{
sl@0
   491
	__ASSERT_DEBUG(iFileStore, PanicServer(EPanicStoreInitialised));
sl@0
   492
	if (!iFileStore)
sl@0
   493
		User::Leave(KErrNotReady);
sl@0
   494
sl@0
   495
	RStoreWriteStream newStream;
sl@0
   496
	TStreamId result = newStream.CreateLC(*iFileStore);
sl@0
   497
	if (KNullStreamId == result)
sl@0
   498
		User::Leave(KErrBadHandle);
sl@0
   499
sl@0
   500
	newStream.CommitL();
sl@0
   501
	CleanupStack::PopAndDestroy(&newStream);
sl@0
   502
sl@0
   503
	return result;
sl@0
   504
	}
sl@0
   505
sl@0
   506
CKeyInfo* CFileKeyDataManager::ReadKeyInfoLC(const CFileKeyData& aKeyData) const
sl@0
   507
	{
sl@0
   508
	__ASSERT_ALWAYS(iFileStore, PanicServer(EPanicStoreInitialised));
sl@0
   509
	RStoreReadStream stream;
sl@0
   510
	stream.OpenLC(*iFileStore, aKeyData.InfoDataStreamId());
sl@0
   511
	CKeyInfo* info = CKeyInfo::NewL(stream);
sl@0
   512
	
sl@0
   513
#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   514
	ReadAuthDetailsL(stream, *info);
sl@0
   515
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   516
	CleanupStack::PopAndDestroy(&stream);
sl@0
   517
	info->CleanupPushL();
sl@0
   518
	if (info->Handle() != aKeyData.Handle())
sl@0
   519
		{
sl@0
   520
		User::Leave(KErrCorrupt); // is this appropriate?
sl@0
   521
		}
sl@0
   522
	return info;
sl@0
   523
	}
sl@0
   524
sl@0
   525
void CFileKeyDataManager::WriteKeyInfoL(const CFileKeyData& aKeyData, const CKeyInfo& aKeyInfo)
sl@0
   526
	{
sl@0
   527
	RStoreWriteStream infoStream;
sl@0
   528
	OpenInfoDataStreamLC(aKeyData, infoStream);
sl@0
   529
	infoStream << aKeyInfo;
sl@0
   530
#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   531
	WriteAuthDetailsL(infoStream, aKeyInfo);
sl@0
   532
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   533
	infoStream.CommitL();
sl@0
   534
	CleanupStack::PopAndDestroy(&infoStream);
sl@0
   535
	}
sl@0
   536
sl@0
   537
#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   538
void CFileKeyDataManager::WriteAuthDetailsL( RStoreWriteStream& aInfoStream, const CKeyInfo& aKeyInfo )
sl@0
   539
	{
sl@0
   540
	aInfoStream.WriteInt32L(aKeyInfo.Identity());
sl@0
   541
	aInfoStream << aKeyInfo.AuthExpression();
sl@0
   542
  	aInfoStream.WriteInt32L(aKeyInfo.Freshness());
sl@0
   543
	}
sl@0
   544
sl@0
   545
void CFileKeyDataManager::ReadAuthDetailsL( RStoreReadStream& aInfoStream, CKeyInfo& aKeyInfo ) const
sl@0
   546
	{
sl@0
   547
	aKeyInfo.SetIdentity(aInfoStream.ReadInt32L());
sl@0
   548
	HBufC* expression = HBufC::NewLC(aInfoStream, KMaxTInt);
sl@0
   549
	aKeyInfo.SetAuthExpressionL(*expression);
sl@0
   550
	aKeyInfo.SetFreshness(aInfoStream.ReadInt32L());
sl@0
   551
	CleanupStack::PopAndDestroy(expression);
sl@0
   552
	}
sl@0
   553
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   554
sl@0
   555
void CFileKeyDataManager::SafeWriteKeyInfoL(const CFileKeyData& aKeyData, const CKeyInfo& aKeyInfo)
sl@0
   556
	{
sl@0
   557
	TCleanupItem cleanupStore(RevertStore, iFileStore);
sl@0
   558
	CleanupStack::PushL(cleanupStore);	
sl@0
   559
sl@0
   560
	WriteKeyInfoL(aKeyData, aKeyInfo);
sl@0
   561
	iFileStore->CommitL();
sl@0
   562
	
sl@0
   563
	CleanupStack::Pop(); // cleanupStore	
sl@0
   564
	}
sl@0
   565
sl@0
   566
void CFileKeyDataManager::OpenInfoDataStreamLC(const CFileKeyData& aKeyData, RStoreWriteStream& aStream)
sl@0
   567
	{
sl@0
   568
	__ASSERT_ALWAYS(iFileStore, PanicServer(EPanicStoreInitialised));
sl@0
   569
	aStream.ReplaceLC(*iFileStore, aKeyData.InfoDataStreamId());
sl@0
   570
	}
sl@0
   571
sl@0
   572
void CFileKeyDataManager::OpenPublicDataStreamLC(const CFileKeyData& aKeyData, RStoreWriteStream& aStream)
sl@0
   573
	{
sl@0
   574
	__ASSERT_ALWAYS(iFileStore, PanicServer(EPanicStoreInitialised));
sl@0
   575
	aStream.ReplaceLC(*iFileStore, aKeyData.PublicDataStreamId());
sl@0
   576
	}
sl@0
   577
sl@0
   578
void CFileKeyDataManager::OpenPublicDataStreamLC(const CFileKeyData& aKeyData, RStoreReadStream& aStream) const
sl@0
   579
	{
sl@0
   580
	__ASSERT_ALWAYS(iFileStore, PanicServer(EPanicStoreInitialised));
sl@0
   581
	aStream.OpenLC(*iFileStore, aKeyData.PublicDataStreamId());
sl@0
   582
	}
sl@0
   583
sl@0
   584
#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   585
sl@0
   586
void CFileKeyDataManager::OpenPrivateDataStreamLC(const CFileKeyData& aKeyData, RStoreWriteStream& aStream) 
sl@0
   587
	{
sl@0
   588
	__ASSERT_DEBUG(iFileStore, PanicServer(EPanicStoreInitialised));
sl@0
   589
	aStream.ReplaceLC(*iFileStore, aKeyData.PrivateDataStreamId());
sl@0
   590
	}
sl@0
   591
sl@0
   592
void CFileKeyDataManager::OpenPrivateDataStreamLC(const CFileKeyData& aKeyData, RStoreReadStream& aStream) const
sl@0
   593
	{
sl@0
   594
	__ASSERT_DEBUG(iFileStore, PanicServer(EPanicStoreInitialised));
sl@0
   595
	aStream.OpenLC(*iFileStore, aKeyData.PrivateDataStreamId());
sl@0
   596
	}
sl@0
   597
sl@0
   598
#else
sl@0
   599
sl@0
   600
void CFileKeyDataManager::OpenPrivateDataStreamLC(const CFileKeyData& aKeyData, CPassphrase& aPassphrase,
sl@0
   601
												  RStoreReadStream& aStream) 
sl@0
   602
	{
sl@0
   603
	__ASSERT_DEBUG(iFileStore, PanicServer(EPanicStoreInitialised));
sl@0
   604
	aStream.OpenLC(aPassphrase.Store(), aKeyData.PrivateDataStreamId());
sl@0
   605
	}
sl@0
   606
sl@0
   607
void CFileKeyDataManager::OpenPrivateDataStreamLC(const CFileKeyData& aKeyData, CPassphrase& aPassphrase,
sl@0
   608
												  RStoreWriteStream& aStream)
sl@0
   609
	{
sl@0
   610
	__ASSERT_DEBUG(iFileStore, PanicServer(EPanicStoreInitialised));
sl@0
   611
	aStream.ReplaceLC(aPassphrase.Store(), aKeyData.PrivateDataStreamId());
sl@0
   612
	}
sl@0
   613
sl@0
   614
sl@0
   615
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   616
sl@0
   617
#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   618
TInt CFileKeyDataManager::GetPassphraseTimeout() const
sl@0
   619
	{
sl@0
   620
	return iTimeout;
sl@0
   621
	}
sl@0
   622
sl@0
   623
void CFileKeyDataManager::SetPassphraseTimeoutL(TInt aTimeout)
sl@0
   624
	{
sl@0
   625
	TInt oldTimeout = iTimeout;
sl@0
   626
sl@0
   627
	iTimeout = aTimeout;
sl@0
   628
	TRAPD(err, WritePassphraseTimeoutL(); iFileStore->CommitL());
sl@0
   629
sl@0
   630
	if (err != KErrNone)
sl@0
   631
		{
sl@0
   632
		iTimeout = oldTimeout;
sl@0
   633
		iFileStore->RevertL(); // shouldn't leave
sl@0
   634
		User::Leave(err);
sl@0
   635
		}
sl@0
   636
	}
sl@0
   637
sl@0
   638
void CFileKeyDataManager::ReadPassphraseTimeoutL()
sl@0
   639
	{
sl@0
   640
	ASSERT(iTimeout == 0); // Only called from ConstructL()
sl@0
   641
	
sl@0
   642
	RStoreReadStream stream;
sl@0
   643
	stream.OpenLC(*iFileStore, iTimeoutStreamId);
sl@0
   644
	iTimeout = stream.ReadInt32L();
sl@0
   645
	CleanupStack::PopAndDestroy(&stream);
sl@0
   646
	}
sl@0
   647
sl@0
   648
void CFileKeyDataManager::WritePassphraseTimeoutL()
sl@0
   649
	{
sl@0
   650
	RStoreWriteStream stream;
sl@0
   651
	stream.ReplaceLC(*iFileStore, iTimeoutStreamId);
sl@0
   652
	stream.WriteUint32L(iTimeout);	
sl@0
   653
	stream.CommitL();
sl@0
   654
	CleanupStack::PopAndDestroy(&stream);
sl@0
   655
	}
sl@0
   656
sl@0
   657
TStreamId CFileKeyDataManager::DefaultPassphraseId() const
sl@0
   658
	{
sl@0
   659
	ASSERT((iPassStreamId == KNullStreamId) == (Count() == 0));
sl@0
   660
	return iPassStreamId;
sl@0
   661
	}
sl@0
   662
sl@0
   663
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   664
sl@0
   665
/**
sl@0
   666
 * Attempt to compact the store - it doesn't matter if these calls leave, it
sl@0
   667
 * will only mean that the store takes up more space than necessary.
sl@0
   668
 */
sl@0
   669
void CFileKeyDataManager::CompactStore()
sl@0
   670
	{
sl@0
   671
	ASSERT(iFileStore);
sl@0
   672
	TRAP_IGNORE(iFileStore->ReclaimL(); iFileStore->CompactL());
sl@0
   673
	}
sl@0
   674
sl@0
   675
#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   676
TUint32 CFileKeyDataManager::CachedIdentity()
sl@0
   677
	{
sl@0
   678
	TInt value = 0;
sl@0
   679
	iIdentityId.Get(value);
sl@0
   680
	return value;
sl@0
   681
	}
sl@0
   682
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   683
sl@0
   684
// CFileKeyData ////////////////////////////////////////////////////////////////
sl@0
   685
sl@0
   686
#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   687
CFileKeyData* CFileKeyData::NewLC(	TInt aObjectId, const TDesC& aLabel, TStreamId aInfoData,
sl@0
   688
								  TStreamId aPublicData, TStreamId aPrivateData,
sl@0
   689
								  AuthServer::TIdentityId aIdentityId)
sl@0
   690
	{
sl@0
   691
	CFileKeyData* self = new (ELeave) CFileKeyData(aObjectId, aInfoData, aPublicData, aPrivateData, aIdentityId);
sl@0
   692
	CleanupStack::PushL(self);
sl@0
   693
	self->ConstructL(aLabel);
sl@0
   694
	return self;
sl@0
   695
	}
sl@0
   696
#else
sl@0
   697
CFileKeyData* CFileKeyData::NewLC(TInt aObjectId, const TDesC& aLabel, TStreamId aInfoData,
sl@0
   698
								  TStreamId aPassphraseId, TStreamId aPublicData, TStreamId aPrivateData)
sl@0
   699
	{
sl@0
   700
	CFileKeyData* self = new (ELeave) CFileKeyData(aObjectId, aInfoData, aPassphraseId, aPublicData, aPrivateData);
sl@0
   701
	CleanupStack::PushL(self);
sl@0
   702
	self->ConstructL(aLabel);
sl@0
   703
	return self;
sl@0
   704
	}
sl@0
   705
sl@0
   706
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   707
sl@0
   708
CFileKeyData* CFileKeyData::NewL(RStoreReadStream& aReadStream)
sl@0
   709
	{
sl@0
   710
	CFileKeyData* self = new (ELeave) CFileKeyData();
sl@0
   711
	CleanupStack::PushL(self);
sl@0
   712
	self->InternalizeL(aReadStream);
sl@0
   713
	CleanupStack::Pop(self);
sl@0
   714
	return (self);
sl@0
   715
	}
sl@0
   716
sl@0
   717
CFileKeyData::~CFileKeyData()
sl@0
   718
	{
sl@0
   719
	delete iLabel;
sl@0
   720
	}
sl@0
   721
sl@0
   722
#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   723
CFileKeyData::CFileKeyData(TInt aObjectId, TStreamId aInfoData,  
sl@0
   724
						   TStreamId aPublicData, TStreamId aPrivateData,
sl@0
   725
						   AuthServer::TIdentityId aIdentityId) :
sl@0
   726
	iObjectId(aObjectId), iInfoData(aInfoData), 
sl@0
   727
	iPublicKeyData(aPublicData), iPrivateKeyData(aPrivateData),
sl@0
   728
	iIdentityId(aIdentityId)
sl@0
   729
	{
sl@0
   730
	ASSERT(iObjectId);
sl@0
   731
	ASSERT(iInfoData != KNullStreamId);
sl@0
   732
	ASSERT(iPublicKeyData != KNullStreamId);
sl@0
   733
	ASSERT(iPrivateKeyData != KNullStreamId);
sl@0
   734
	ASSERT(iIdentityId);
sl@0
   735
	}
sl@0
   736
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   737
#ifdef KEYTOOL
sl@0
   738
CFileKeyData::CFileKeyData(TInt aObjectId, TStreamId aInfoData,  
sl@0
   739
						   TStreamId aPublicData, TStreamId aPrivateData,
sl@0
   740
						   AuthServer::TIdentityId aIdentityId) :
sl@0
   741
	iObjectId(aObjectId), iInfoData(aInfoData), 
sl@0
   742
	iPublicKeyData(aPublicData), iPrivateKeyData(aPrivateData),
sl@0
   743
	iIdentityId(aIdentityId)
sl@0
   744
	{
sl@0
   745
	ASSERT(iObjectId);
sl@0
   746
	ASSERT(iInfoData != KNullStreamId);
sl@0
   747
	ASSERT(iPublicKeyData != KNullStreamId);
sl@0
   748
	ASSERT(iPrivateKeyData != KNullStreamId);
sl@0
   749
	ASSERT(iIdentityId);
sl@0
   750
	}
sl@0
   751
#endif // KEYTOOL
sl@0
   752
sl@0
   753
CFileKeyData::CFileKeyData(TInt aObjectId, TStreamId aInfoData, TStreamId aPassphraseId, 
sl@0
   754
						   TStreamId aPublicData, TStreamId aPrivateData) :
sl@0
   755
	iObjectId(aObjectId), iInfoData(aInfoData), iPassphraseId(aPassphraseId),
sl@0
   756
	iPublicKeyData(aPublicData), iPrivateKeyData(aPrivateData)
sl@0
   757
	{
sl@0
   758
	ASSERT(iObjectId);
sl@0
   759
	ASSERT(iInfoData != KNullStreamId);
sl@0
   760
	ASSERT(iPassphraseId != KNullStreamId);
sl@0
   761
	ASSERT(iPublicKeyData != KNullStreamId);
sl@0
   762
	ASSERT(iPrivateKeyData != KNullStreamId);
sl@0
   763
	}
sl@0
   764
sl@0
   765
CFileKeyData::CFileKeyData()
sl@0
   766
	{
sl@0
   767
	}
sl@0
   768
sl@0
   769
void CFileKeyData::ConstructL(const TDesC& aLabel)
sl@0
   770
	{
sl@0
   771
	TInt labelLen = aLabel.Length();
sl@0
   772
	iLabel = HBufC::NewMaxL(labelLen);
sl@0
   773
	TPtr theLabel(iLabel->Des());
sl@0
   774
	theLabel.FillZ();
sl@0
   775
	theLabel.Copy(aLabel);
sl@0
   776
	}
sl@0
   777
sl@0
   778
void CFileKeyData::InternalizeL(RReadStream& aReadStream)
sl@0
   779
{
sl@0
   780
	iObjectId = aReadStream.ReadInt32L();
sl@0
   781
	iInfoData.InternalizeL(aReadStream);
sl@0
   782
#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   783
	iPassphraseId.InternalizeL(aReadStream);
sl@0
   784
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   785
	iPublicKeyData.InternalizeL(aReadStream);
sl@0
   786
	iPrivateKeyData.InternalizeL(aReadStream);
sl@0
   787
	
sl@0
   788
	TInt labelLen = aReadStream.ReadInt32L();
sl@0
   789
	iLabel = HBufC::NewMaxL(labelLen);
sl@0
   790
	TPtr theLabel((TUint16*)iLabel->Ptr(), labelLen, labelLen);
sl@0
   791
	theLabel.FillZ(labelLen);
sl@0
   792
	aReadStream.ReadL(theLabel);
sl@0
   793
#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   794
	iIdentityId = aReadStream.ReadInt32L();
sl@0
   795
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   796
}
sl@0
   797
sl@0
   798
void CFileKeyData::ExternalizeL(RWriteStream& aWriteStream) const
sl@0
   799
{
sl@0
   800
	aWriteStream.WriteInt32L(iObjectId);
sl@0
   801
	iInfoData.ExternalizeL(aWriteStream);
sl@0
   802
#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   803
	iPassphraseId.ExternalizeL(aWriteStream);
sl@0
   804
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   805
	iPublicKeyData.ExternalizeL(aWriteStream);
sl@0
   806
	iPrivateKeyData.ExternalizeL(aWriteStream);
sl@0
   807
sl@0
   808
	TInt labelLen = iLabel->Length();
sl@0
   809
	aWriteStream.WriteInt32L(labelLen);
sl@0
   810
	TPtr theLabel(iLabel->Des());
sl@0
   811
	theLabel.SetLength(labelLen);
sl@0
   812
	aWriteStream.WriteL(theLabel);
sl@0
   813
#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   814
	aWriteStream.WriteInt32L(iIdentityId);
sl@0
   815
#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
sl@0
   816
sl@0
   817
}
sl@0
   818
sl@0
   819
#ifdef KEYTOOL
sl@0
   820
sl@0
   821
CFileKeyData* CFileKeyData::CreateOldKeyL(RStoreReadStream& aReadStream)
sl@0
   822
	{
sl@0
   823
	CFileKeyData* self = new (ELeave) CFileKeyData();
sl@0
   824
	CleanupStack::PushL(self);
sl@0
   825
	self->InternalizeOldKeyL(aReadStream);
sl@0
   826
	CleanupStack::Pop(self);
sl@0
   827
	return (self);
sl@0
   828
	}
sl@0
   829
sl@0
   830
void CFileKeyData::InternalizeOldKeyL(RReadStream& aReadStream)
sl@0
   831
	{
sl@0
   832
	iObjectId = aReadStream.ReadInt32L();
sl@0
   833
	iInfoData.InternalizeL(aReadStream);
sl@0
   834
	iPassphraseId.InternalizeL(aReadStream);
sl@0
   835
	iPublicKeyData.InternalizeL(aReadStream);
sl@0
   836
	iPrivateKeyData.InternalizeL(aReadStream);
sl@0
   837
	
sl@0
   838
	TInt labelLen = aReadStream.ReadInt32L();
sl@0
   839
	iLabel = HBufC::NewMaxL(labelLen);
sl@0
   840
	TPtr theLabel((TUint16*)iLabel->Ptr(), labelLen, labelLen);
sl@0
   841
	theLabel.FillZ(labelLen);
sl@0
   842
	aReadStream.ReadL(theLabel);
sl@0
   843
	}
sl@0
   844
sl@0
   845
void CFileKeyData::ExternalizeWithAuthL(RWriteStream& aWriteStream) 
sl@0
   846
{
sl@0
   847
	aWriteStream.WriteInt32L(iObjectId);
sl@0
   848
	iInfoData.ExternalizeL(aWriteStream);
sl@0
   849
	iPublicKeyData.ExternalizeL(aWriteStream);
sl@0
   850
	iPrivateKeyData.ExternalizeL(aWriteStream);
sl@0
   851
sl@0
   852
	TInt labelLen = iLabel->Length();
sl@0
   853
	aWriteStream.WriteInt32L(labelLen);
sl@0
   854
	TPtr theLabel(iLabel->Des());
sl@0
   855
	theLabel.SetLength(labelLen);
sl@0
   856
	aWriteStream.WriteL(theLabel);
sl@0
   857
	aWriteStream.WriteInt32L(iIdentityId);
sl@0
   858
}
sl@0
   859
sl@0
   860
#endif // KEYTOOL