os/security/cryptoservices/filebasedcertificateandkeystores/source/keystore/Server/CKeyDataManager.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/cryptoservices/filebasedcertificateandkeystores/source/keystore/Server/CKeyDataManager.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,860 @@
1.4 +/*
1.5 +* Copyright (c) 2004-2010 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of the License "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +*
1.19 +*/
1.20 +
1.21 +
1.22 +#include "CKeyDataManager.h"
1.23 +#include "fsdatatypes.h"
1.24 +#include "fstokencliserv.h"
1.25 +#include "fstokenutil.h"
1.26 +#include "keystorepassphrase.h"
1.27 +
1.28 +_LIT(KKeyStoreFilename,"keys.dat");
1.29 +
1.30 +#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.31 +#include <e32property.h>
1.32 +#include <authserver/aspubsubdefs.h>
1.33 +#else
1.34 +const TInt KDefaultPassphraseTimeout = 30;
1.35 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.36 +
1.37 +// *********************************************************************
1.38 +// Key store data manager - maintains array of objects representing keys
1.39 +// *********************************************************************
1.40 +
1.41 +/*static*/ CFileKeyDataManager* CFileKeyDataManager::NewL()
1.42 + {
1.43 + CFileKeyDataManager* self = new (ELeave) CFileKeyDataManager();
1.44 + CleanupStack::PushL(self);
1.45 + self->ConstructL();
1.46 + CleanupStack::Pop(self);
1.47 + return self;
1.48 + }
1.49 +
1.50 +CFileKeyDataManager::~CFileKeyDataManager()
1.51 + {
1.52 + if (iFileStore)
1.53 + {
1.54 + CompactStore();
1.55 + delete iFileStore;
1.56 + }
1.57 +
1.58 + iFile.Close(); // May already have been closed by store
1.59 + iFs.Close();
1.60 +
1.61 + iKeys.ResetAndDestroy();
1.62 + iKeys.Close();
1.63 + #ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.64 + iIdentityId.Close();
1.65 + #endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.66 + }
1.67 +
1.68 +CFileKeyDataManager::CFileKeyDataManager() :
1.69 + iRootStreamId(KNullStreamId),
1.70 + iInfoStreamId(KNullStreamId)
1.71 +#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.72 + ,iPassStreamId(KNullStreamId),
1.73 + iTimeoutStreamId(KNullStreamId)
1.74 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.75 + {
1.76 + }
1.77 +
1.78 +void CFileKeyDataManager::ConstructL()
1.79 + {
1.80 +
1.81 + User::LeaveIfError(iFs.Connect());
1.82 + OpenStoreL();
1.83 +
1.84 + RStoreReadStream lookupStream;
1.85 + lookupStream.OpenLC(*iFileStore, iInfoStreamId);
1.86 +
1.87 + #ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.88 + User::LeaveIfError(iIdentityId.Attach( AuthServer::KAuthServerSecureId,
1.89 + AuthServer::KUidAuthServerAuthChangeEvent));
1.90 + #else
1.91 + iPassStreamId = (TStreamId) lookupStream.ReadUint32L();
1.92 + iTimeoutStreamId = (TStreamId) lookupStream.ReadUint32L();
1.93 + #endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.94 +
1.95 + TInt count = lookupStream.ReadInt32L();
1.96 + for (TInt index = 0; index < count; index++)
1.97 + {
1.98 + CFileKeyData* keyData = CFileKeyData::NewL(lookupStream);
1.99 + CleanupStack::PushL(keyData);
1.100 +
1.101 + if (keyData->Handle() > iKeyIdentifier)
1.102 + iKeyIdentifier = keyData->Handle();
1.103 +
1.104 + iKeys.AppendL(keyData);
1.105 + CleanupStack::Pop(keyData);
1.106 + }
1.107 +
1.108 + CleanupStack::PopAndDestroy(&lookupStream);
1.109 +
1.110 +#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.111 + ReadPassphraseTimeoutL();
1.112 +#endif //SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.113 +
1.114 + }
1.115 +
1.116 +CPassphraseManager* CFileKeyDataManager::CreatePassphraseManagerLC()
1.117 + {
1.118 + CPassphraseManager* result = CPassphraseManager::NewL(*iFileStore);
1.119 + CleanupStack::PushL(result);
1.120 + return result;
1.121 + }
1.122 +
1.123 +void CFileKeyDataManager::OpenStoreL()
1.124 + {
1.125 + // Tries to locate a key store file on the default drive and then from ROM
1.126 + // If it cannot find one, tries to create a file with permanent file store
1.127 + // inside it In all cases, should initialise iFileStore unless it cannot
1.128 + // create the file/store/streams
1.129 +
1.130 + __ASSERT_DEBUG(!iFileStore, PanicServer(EPanicStoreInitialised));
1.131 +
1.132 + TFileName fullPath;
1.133 + FileUtils::MakePrivateFilenameL(iFs, KKeyStoreFilename, fullPath);
1.134 +
1.135 + FileUtils::EnsurePathL(iFs, fullPath);
1.136 + TRAPD(result, OpenStoreInFileL(fullPath));
1.137 +
1.138 + if (result == KErrInUse)
1.139 + {
1.140 + // Cannot access the file now. Abort server startup rather than wiping the keystore.
1.141 + User::Leave(result);
1.142 + }
1.143 +
1.144 + if (result != KErrNone)
1.145 + {
1.146 + // Not yet opened a valid store, either no file to be found, or no valid
1.147 + // store in it. Copy the original one stored in the ROM.
1.148 + delete iFileStore;
1.149 + iFileStore = NULL;
1.150 +
1.151 + TFileName romPath;
1.152 + FileUtils::MakePrivateROMFilenameL(iFs, KKeyStoreFilename, romPath);
1.153 +
1.154 + if (result != KErrNotFound)
1.155 + {
1.156 + // Wipe the keystore if we can't open it (it's corrupt anyway)
1.157 + User::LeaveIfError(iFs.Delete(fullPath));
1.158 + }
1.159 +
1.160 + // Copy data from rom and open it
1.161 + TRAPD(err,
1.162 + FileUtils::CopyL(iFs, romPath, fullPath);
1.163 + OpenStoreInFileL(fullPath)
1.164 + );
1.165 +
1.166 + if (KErrNone != err)
1.167 + {
1.168 + // We tried to copy the keystore from ROM. For some reason this
1.169 + // failed and we still cannot open the file. Create a new one from
1.170 + // scratch.
1.171 + CreateStoreInFileL(fullPath);
1.172 + }
1.173 + }
1.174 +
1.175 + __ASSERT_DEBUG(iFileStore, PanicServer(EPanicStoreInitialised));
1.176 + __ASSERT_DEBUG((KNullStreamId!=iRootStreamId), PanicServer(EPanicRootStreamNotReady));
1.177 + __ASSERT_DEBUG((KNullStreamId!=iInfoStreamId), PanicServer(EPanicManagerStreamNotReady));
1.178 + }
1.179 +
1.180 +void CFileKeyDataManager::CreateStoreInFileL(const TDesC& aFile)
1.181 + {
1.182 + TInt r = iFs.MkDirAll(aFile);
1.183 + if ( (r!=KErrNone) && (r!=KErrAlreadyExists) )
1.184 + User::Leave(r);
1.185 +
1.186 + iFileStore = CPermanentFileStore::ReplaceL(iFs, aFile, EFileRead | EFileWrite | EFileShareExclusive);
1.187 + iFileStore->SetTypeL(KPermanentFileStoreLayoutUid);
1.188 +
1.189 + TCleanupItem cleanupStore(RevertStore, iFileStore);
1.190 + CleanupStack::PushL(cleanupStore);
1.191 +
1.192 +#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.193 + // Create timeout stream with default timeout
1.194 + RStoreWriteStream timeoutStream;
1.195 + iTimeoutStreamId = timeoutStream.CreateLC(*iFileStore);
1.196 + timeoutStream.WriteUint32L(KDefaultPassphraseTimeout);
1.197 + timeoutStream.CommitL();
1.198 + CleanupStack::PopAndDestroy(&timeoutStream);
1.199 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.200 +
1.201 + // Create info stream - Currently no passphrase created, and no keys
1.202 + RStoreWriteStream infoStream;
1.203 + iInfoStreamId = infoStream.CreateLC(*iFileStore);
1.204 +
1.205 +#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.206 + infoStream.WriteUint32L(KNullStreamId.Value());
1.207 + infoStream.WriteUint32L(iTimeoutStreamId.Value());
1.208 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.209 +
1.210 + infoStream.WriteUint32L(0); // Write key count of zero
1.211 + infoStream.CommitL();
1.212 + CleanupStack::PopAndDestroy(&infoStream);
1.213 +
1.214 + // Create root stream - just contains id of info stream
1.215 + RStoreWriteStream rootStream;
1.216 + iRootStreamId = rootStream.CreateLC(*iFileStore);
1.217 + iFileStore->SetRootL(iRootStreamId);
1.218 +
1.219 + rootStream.WriteUint32L(iInfoStreamId.Value());
1.220 + rootStream.CommitL();
1.221 + CleanupStack::PopAndDestroy(&rootStream);
1.222 +
1.223 + WriteKeysToStoreL();
1.224 +
1.225 + iFileStore->CommitL();
1.226 + CleanupStack::Pop(); // cleanupStore
1.227 + }
1.228 +
1.229 +void CFileKeyDataManager::OpenStoreInFileL(const TDesC& aFile)
1.230 + {
1.231 + // Make sure the file isn't write protected
1.232 + User::LeaveIfError(iFs.SetAtt(aFile, 0, KEntryAttReadOnly));
1.233 +
1.234 + User::LeaveIfError(iFile.Open(iFs, aFile, EFileRead | EFileWrite | EFileShareExclusive));
1.235 +
1.236 + iFileStore = CPermanentFileStore::FromL(iFile);
1.237 +
1.238 + // Get the salt, root and manager TStreamIds
1.239 + iRootStreamId = iFileStore->Root();
1.240 + if (iRootStreamId == KNullStreamId)
1.241 + {
1.242 + User::Leave(KErrCorrupt);
1.243 + }
1.244 +
1.245 + RStoreReadStream rootStream;
1.246 + rootStream.OpenLC(*iFileStore, iRootStreamId);
1.247 + iInfoStreamId = (TStreamId)(rootStream.ReadUint32L());
1.248 + CleanupStack::PopAndDestroy(&rootStream);
1.249 + }
1.250 +
1.251 +// Methods dealing with atomic updates to key data file ////////////////////////
1.252 +
1.253 +// This is a cleanup item that reverts the store
1.254 +void CFileKeyDataManager::RevertStore(TAny* aStore)
1.255 +{
1.256 + CPermanentFileStore* store = reinterpret_cast<CPermanentFileStore*>(aStore);
1.257 + TRAP_IGNORE(store->RevertL());
1.258 + // We're ignoring the leave code from this becuase there's no way we can
1.259 + // handle this sensibly. This shouldn't be a problem in practice - this
1.260 + // will leave if for example the file store is on removable which is
1.261 + // unexpectedly remove, and this is never the case for us.
1.262 +}
1.263 +
1.264 +// Rewrites the info stream (ie the array of key data info) to the store
1.265 +void CFileKeyDataManager::WriteKeysToStoreL()
1.266 + {
1.267 + RStoreWriteStream lookupStream;
1.268 + lookupStream.ReplaceLC(*iFileStore, iInfoStreamId);
1.269 +
1.270 + #ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.271 + lookupStream.WriteUint32L(iPassStreamId.Value());
1.272 + lookupStream.WriteUint32L(iTimeoutStreamId.Value());
1.273 + #endif //SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.274 +
1.275 + TInt keyCount = iKeys.Count();
1.276 + lookupStream.WriteInt32L(keyCount);
1.277 +
1.278 + for (TInt index = 0; index < keyCount; index++)
1.279 + {
1.280 + const CFileKeyData* key = iKeys[index];
1.281 + key->ExternalizeL(lookupStream);
1.282 + }
1.283 +
1.284 + lookupStream.CommitL();
1.285 + CleanupStack::PopAndDestroy(&lookupStream);
1.286 + }
1.287 +
1.288 +/**
1.289 + * Add a key to the store. Assumes that the key data streams (info, public key
1.290 + * and private key) have already been written.
1.291 + */
1.292 +void CFileKeyDataManager::AddL(const CFileKeyData* aKeyData)
1.293 + {
1.294 + ASSERT(aKeyData);
1.295 +#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.296 + ASSERT(aKeyData->PassphraseStreamId() != KNullStreamId);
1.297 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.298 +
1.299 + // Add the key to to the array, rewrite the infostream and
1.300 + // ONLY THEN commit the store
1.301 + User::LeaveIfError(iKeys.Append(aKeyData));
1.302 +
1.303 +#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.304 + TStreamId oldDefaultPassphraseId;
1.305 +
1.306 + // Set the default passphrase id if this is the first key
1.307 + oldDefaultPassphraseId = iPassStreamId;
1.308 + if (iKeys.Count() == 1)
1.309 + {
1.310 + iPassStreamId = aKeyData->PassphraseStreamId();
1.311 + }
1.312 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.313 +
1.314 + TRAPD(err,UpdateStoreL());
1.315 +
1.316 + if (err != KErrNone)
1.317 + {
1.318 + iKeys.Remove(iKeys.Count() - 1);
1.319 + #ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.320 + iPassStreamId = oldDefaultPassphraseId;
1.321 + #endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.322 + User::Leave(err);
1.323 + }
1.324 + }
1.325 +
1.326 +void CFileKeyDataManager::UpdateStoreL()
1.327 + {
1.328 + WriteKeysToStoreL();
1.329 +
1.330 + // Release ownership of key data and reset default passphrase id if store
1.331 + // can't be written
1.332 + TCleanupItem cleanupStore(RevertStore, iFileStore);
1.333 + CleanupStack::PushL(cleanupStore);
1.334 +
1.335 + iFileStore->CommitL();
1.336 +
1.337 + CleanupStack::Pop(); // cleanupStore
1.338 + }
1.339 +
1.340 +/**
1.341 + * "Transaction safe" key removal - only removes the key in memory and file if
1.342 + * all operations are successful.
1.343 + */
1.344 +void CFileKeyDataManager::RemoveL(TInt aObjectId)
1.345 + {
1.346 + TInt index;
1.347 + const CFileKeyData* key = NULL;
1.348 + for (index = 0 ; index < iKeys.Count() ; ++index)
1.349 + {
1.350 + if (iKeys[index]->Handle() == aObjectId)
1.351 + {
1.352 + key = iKeys[index];
1.353 + break;
1.354 + }
1.355 + }
1.356 +
1.357 + if (!key)
1.358 + {
1.359 + User::Leave(KErrNotFound);
1.360 + }
1.361 +
1.362 + TCleanupItem cleanupStore(RevertStore, iFileStore);
1.363 + CleanupStack::PushL(cleanupStore);
1.364 +
1.365 + iFileStore->DeleteL(key->PrivateDataStreamId());
1.366 + iFileStore->DeleteL(key->PublicDataStreamId());
1.367 + iFileStore->DeleteL(key->InfoDataStreamId());
1.368 +
1.369 +#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.370 + // Remove the passphrase if it's the last key
1.371 + TStreamId oldPassphraseId = iPassStreamId;
1.372 + if (Count() == 1)
1.373 + {
1.374 + iFileStore->DeleteL(iPassStreamId);
1.375 + iPassStreamId = KNullStreamId;
1.376 + }
1.377 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.378 +
1.379 + // Remove the key
1.380 + iKeys.Remove(index);
1.381 +
1.382 + TRAPD(res, WriteKeysToStoreL());
1.383 +
1.384 + if (res != KErrNone)
1.385 + {
1.386 +#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.387 + iPassStreamId = oldPassphraseId;
1.388 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.389 + User::LeaveIfError(iKeys.Append(key)); // Put it back, shouldn't leave
1.390 + User::Leave(res);
1.391 + }
1.392 + else
1.393 + {
1.394 + delete key; // Cannot leave from the point it's removed to here, so no cleanup stack!
1.395 + }
1.396 + iFileStore->CommitL();
1.397 +
1.398 + CleanupStack::Pop(); // cleanupStore
1.399 + CompactStore();
1.400 +}
1.401 +
1.402 +#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.403 +TBool CFileKeyDataManager::IsKeyAlreadyInStore(const TDesC& aKeyLabel, AuthServer::TIdentityId aIdentity) const
1.404 + {// Check each key in the store to determine if aKeyLabel already exists
1.405 + TInt keyCount = iKeys.Count();
1.406 + TBool isInStore = EFalse;
1.407 + for (TInt index = 0; index < keyCount; ++index)
1.408 + {
1.409 + const TDesC& keyLabel = iKeys[index]->Label();
1.410 + if (keyLabel.Compare(aKeyLabel)==0 && (iKeys[index]->Identity() == aIdentity))
1.411 + {
1.412 + isInStore = ETrue;
1.413 + break;
1.414 + }
1.415 + }
1.416 + return (isInStore);
1.417 + }
1.418 +
1.419 +#else
1.420 +TBool CFileKeyDataManager::IsKeyAlreadyInStore(const TDesC& aKeyLabel) const
1.421 +{// Check each key in the store to determine if aKeyLabel already exists
1.422 + TInt keyCount = iKeys.Count();
1.423 + TBool isInStore = EFalse;
1.424 + for (TInt index = 0; index < keyCount; index++)
1.425 + {
1.426 + const TDesC& keyLabel = iKeys[index]->Label();
1.427 + if (keyLabel.Compare(aKeyLabel)==0)
1.428 + {
1.429 + isInStore = ETrue;
1.430 + break;
1.431 + }
1.432 + }
1.433 +
1.434 + return (isInStore);
1.435 +}
1.436 +
1.437 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.438 +
1.439 +TInt CFileKeyDataManager::Count() const
1.440 + {
1.441 + return iKeys.Count();
1.442 + }
1.443 +
1.444 +const CFileKeyData* CFileKeyDataManager::operator[](TInt aIndex) const
1.445 + {
1.446 + return iKeys[aIndex];
1.447 + }
1.448 +
1.449 +const CFileKeyData* CFileKeyDataManager::Lookup(TInt aObjectId) const
1.450 + {
1.451 + TInt count = Count();
1.452 + for (TInt i = 0; i < count; ++i)
1.453 + {
1.454 + if ((*this)[i]->Handle() == aObjectId)
1.455 + {
1.456 + return (*this)[i];
1.457 + }
1.458 + }
1.459 + return NULL;
1.460 + }
1.461 +
1.462 +// *********************************************************************
1.463 +// Management of file and store therein
1.464 +// *********************************************************************
1.465 +
1.466 +#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.467 +
1.468 +const CFileKeyData* CFileKeyDataManager::CreateKeyDataLC(const TDesC& aLabel, AuthServer::TIdentityId aIdentityId)
1.469 + {
1.470 + TInt objectId = ++iKeyIdentifier;
1.471 + TStreamId infoData = CreateWriteStreamL();
1.472 + TStreamId publicKeyData = CreateWriteStreamL();
1.473 + TStreamId privateKeyData = CreateWriteStreamL();
1.474 + return CFileKeyData::NewLC(objectId, aLabel, infoData, publicKeyData, privateKeyData, aIdentityId);
1.475 + }
1.476 +
1.477 +#else
1.478 +const CFileKeyData* CFileKeyDataManager::CreateKeyDataLC(const TDesC& aLabel, TStreamId aPassStreamId)
1.479 + {
1.480 + ASSERT(aPassStreamId != KNullStreamId);
1.481 + TInt objectId = ++iKeyIdentifier;
1.482 + TStreamId infoData = CreateWriteStreamL();
1.483 + TStreamId publicKeyData = CreateWriteStreamL();
1.484 + TStreamId privateKeyData = CreateWriteStreamL();
1.485 + return CFileKeyData::NewLC(objectId, aLabel, infoData, aPassStreamId, publicKeyData, privateKeyData);
1.486 + }
1.487 +
1.488 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.489 +
1.490 +// Creates a new write stream in the store (which it then closes)
1.491 +// Returns the TStreamId associated with it
1.492 +TStreamId CFileKeyDataManager::CreateWriteStreamL()
1.493 + {
1.494 + __ASSERT_DEBUG(iFileStore, PanicServer(EPanicStoreInitialised));
1.495 + if (!iFileStore)
1.496 + User::Leave(KErrNotReady);
1.497 +
1.498 + RStoreWriteStream newStream;
1.499 + TStreamId result = newStream.CreateLC(*iFileStore);
1.500 + if (KNullStreamId == result)
1.501 + User::Leave(KErrBadHandle);
1.502 +
1.503 + newStream.CommitL();
1.504 + CleanupStack::PopAndDestroy(&newStream);
1.505 +
1.506 + return result;
1.507 + }
1.508 +
1.509 +CKeyInfo* CFileKeyDataManager::ReadKeyInfoLC(const CFileKeyData& aKeyData) const
1.510 + {
1.511 + __ASSERT_ALWAYS(iFileStore, PanicServer(EPanicStoreInitialised));
1.512 + RStoreReadStream stream;
1.513 + stream.OpenLC(*iFileStore, aKeyData.InfoDataStreamId());
1.514 + CKeyInfo* info = CKeyInfo::NewL(stream);
1.515 +
1.516 +#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.517 + ReadAuthDetailsL(stream, *info);
1.518 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.519 + CleanupStack::PopAndDestroy(&stream);
1.520 + info->CleanupPushL();
1.521 + if (info->Handle() != aKeyData.Handle())
1.522 + {
1.523 + User::Leave(KErrCorrupt); // is this appropriate?
1.524 + }
1.525 + return info;
1.526 + }
1.527 +
1.528 +void CFileKeyDataManager::WriteKeyInfoL(const CFileKeyData& aKeyData, const CKeyInfo& aKeyInfo)
1.529 + {
1.530 + RStoreWriteStream infoStream;
1.531 + OpenInfoDataStreamLC(aKeyData, infoStream);
1.532 + infoStream << aKeyInfo;
1.533 +#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.534 + WriteAuthDetailsL(infoStream, aKeyInfo);
1.535 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.536 + infoStream.CommitL();
1.537 + CleanupStack::PopAndDestroy(&infoStream);
1.538 + }
1.539 +
1.540 +#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.541 +void CFileKeyDataManager::WriteAuthDetailsL( RStoreWriteStream& aInfoStream, const CKeyInfo& aKeyInfo )
1.542 + {
1.543 + aInfoStream.WriteInt32L(aKeyInfo.Identity());
1.544 + aInfoStream << aKeyInfo.AuthExpression();
1.545 + aInfoStream.WriteInt32L(aKeyInfo.Freshness());
1.546 + }
1.547 +
1.548 +void CFileKeyDataManager::ReadAuthDetailsL( RStoreReadStream& aInfoStream, CKeyInfo& aKeyInfo ) const
1.549 + {
1.550 + aKeyInfo.SetIdentity(aInfoStream.ReadInt32L());
1.551 + HBufC* expression = HBufC::NewLC(aInfoStream, KMaxTInt);
1.552 + aKeyInfo.SetAuthExpressionL(*expression);
1.553 + aKeyInfo.SetFreshness(aInfoStream.ReadInt32L());
1.554 + CleanupStack::PopAndDestroy(expression);
1.555 + }
1.556 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.557 +
1.558 +void CFileKeyDataManager::SafeWriteKeyInfoL(const CFileKeyData& aKeyData, const CKeyInfo& aKeyInfo)
1.559 + {
1.560 + TCleanupItem cleanupStore(RevertStore, iFileStore);
1.561 + CleanupStack::PushL(cleanupStore);
1.562 +
1.563 + WriteKeyInfoL(aKeyData, aKeyInfo);
1.564 + iFileStore->CommitL();
1.565 +
1.566 + CleanupStack::Pop(); // cleanupStore
1.567 + }
1.568 +
1.569 +void CFileKeyDataManager::OpenInfoDataStreamLC(const CFileKeyData& aKeyData, RStoreWriteStream& aStream)
1.570 + {
1.571 + __ASSERT_ALWAYS(iFileStore, PanicServer(EPanicStoreInitialised));
1.572 + aStream.ReplaceLC(*iFileStore, aKeyData.InfoDataStreamId());
1.573 + }
1.574 +
1.575 +void CFileKeyDataManager::OpenPublicDataStreamLC(const CFileKeyData& aKeyData, RStoreWriteStream& aStream)
1.576 + {
1.577 + __ASSERT_ALWAYS(iFileStore, PanicServer(EPanicStoreInitialised));
1.578 + aStream.ReplaceLC(*iFileStore, aKeyData.PublicDataStreamId());
1.579 + }
1.580 +
1.581 +void CFileKeyDataManager::OpenPublicDataStreamLC(const CFileKeyData& aKeyData, RStoreReadStream& aStream) const
1.582 + {
1.583 + __ASSERT_ALWAYS(iFileStore, PanicServer(EPanicStoreInitialised));
1.584 + aStream.OpenLC(*iFileStore, aKeyData.PublicDataStreamId());
1.585 + }
1.586 +
1.587 +#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.588 +
1.589 +void CFileKeyDataManager::OpenPrivateDataStreamLC(const CFileKeyData& aKeyData, RStoreWriteStream& aStream)
1.590 + {
1.591 + __ASSERT_DEBUG(iFileStore, PanicServer(EPanicStoreInitialised));
1.592 + aStream.ReplaceLC(*iFileStore, aKeyData.PrivateDataStreamId());
1.593 + }
1.594 +
1.595 +void CFileKeyDataManager::OpenPrivateDataStreamLC(const CFileKeyData& aKeyData, RStoreReadStream& aStream) const
1.596 + {
1.597 + __ASSERT_DEBUG(iFileStore, PanicServer(EPanicStoreInitialised));
1.598 + aStream.OpenLC(*iFileStore, aKeyData.PrivateDataStreamId());
1.599 + }
1.600 +
1.601 +#else
1.602 +
1.603 +void CFileKeyDataManager::OpenPrivateDataStreamLC(const CFileKeyData& aKeyData, CPassphrase& aPassphrase,
1.604 + RStoreReadStream& aStream)
1.605 + {
1.606 + __ASSERT_DEBUG(iFileStore, PanicServer(EPanicStoreInitialised));
1.607 + aStream.OpenLC(aPassphrase.Store(), aKeyData.PrivateDataStreamId());
1.608 + }
1.609 +
1.610 +void CFileKeyDataManager::OpenPrivateDataStreamLC(const CFileKeyData& aKeyData, CPassphrase& aPassphrase,
1.611 + RStoreWriteStream& aStream)
1.612 + {
1.613 + __ASSERT_DEBUG(iFileStore, PanicServer(EPanicStoreInitialised));
1.614 + aStream.ReplaceLC(aPassphrase.Store(), aKeyData.PrivateDataStreamId());
1.615 + }
1.616 +
1.617 +
1.618 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.619 +
1.620 +#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.621 +TInt CFileKeyDataManager::GetPassphraseTimeout() const
1.622 + {
1.623 + return iTimeout;
1.624 + }
1.625 +
1.626 +void CFileKeyDataManager::SetPassphraseTimeoutL(TInt aTimeout)
1.627 + {
1.628 + TInt oldTimeout = iTimeout;
1.629 +
1.630 + iTimeout = aTimeout;
1.631 + TRAPD(err, WritePassphraseTimeoutL(); iFileStore->CommitL());
1.632 +
1.633 + if (err != KErrNone)
1.634 + {
1.635 + iTimeout = oldTimeout;
1.636 + iFileStore->RevertL(); // shouldn't leave
1.637 + User::Leave(err);
1.638 + }
1.639 + }
1.640 +
1.641 +void CFileKeyDataManager::ReadPassphraseTimeoutL()
1.642 + {
1.643 + ASSERT(iTimeout == 0); // Only called from ConstructL()
1.644 +
1.645 + RStoreReadStream stream;
1.646 + stream.OpenLC(*iFileStore, iTimeoutStreamId);
1.647 + iTimeout = stream.ReadInt32L();
1.648 + CleanupStack::PopAndDestroy(&stream);
1.649 + }
1.650 +
1.651 +void CFileKeyDataManager::WritePassphraseTimeoutL()
1.652 + {
1.653 + RStoreWriteStream stream;
1.654 + stream.ReplaceLC(*iFileStore, iTimeoutStreamId);
1.655 + stream.WriteUint32L(iTimeout);
1.656 + stream.CommitL();
1.657 + CleanupStack::PopAndDestroy(&stream);
1.658 + }
1.659 +
1.660 +TStreamId CFileKeyDataManager::DefaultPassphraseId() const
1.661 + {
1.662 + ASSERT((iPassStreamId == KNullStreamId) == (Count() == 0));
1.663 + return iPassStreamId;
1.664 + }
1.665 +
1.666 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.667 +
1.668 +/**
1.669 + * Attempt to compact the store - it doesn't matter if these calls leave, it
1.670 + * will only mean that the store takes up more space than necessary.
1.671 + */
1.672 +void CFileKeyDataManager::CompactStore()
1.673 + {
1.674 + ASSERT(iFileStore);
1.675 + TRAP_IGNORE(iFileStore->ReclaimL(); iFileStore->CompactL());
1.676 + }
1.677 +
1.678 +#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.679 +TUint32 CFileKeyDataManager::CachedIdentity()
1.680 + {
1.681 + TInt value = 0;
1.682 + iIdentityId.Get(value);
1.683 + return value;
1.684 + }
1.685 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.686 +
1.687 +// CFileKeyData ////////////////////////////////////////////////////////////////
1.688 +
1.689 +#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.690 +CFileKeyData* CFileKeyData::NewLC( TInt aObjectId, const TDesC& aLabel, TStreamId aInfoData,
1.691 + TStreamId aPublicData, TStreamId aPrivateData,
1.692 + AuthServer::TIdentityId aIdentityId)
1.693 + {
1.694 + CFileKeyData* self = new (ELeave) CFileKeyData(aObjectId, aInfoData, aPublicData, aPrivateData, aIdentityId);
1.695 + CleanupStack::PushL(self);
1.696 + self->ConstructL(aLabel);
1.697 + return self;
1.698 + }
1.699 +#else
1.700 +CFileKeyData* CFileKeyData::NewLC(TInt aObjectId, const TDesC& aLabel, TStreamId aInfoData,
1.701 + TStreamId aPassphraseId, TStreamId aPublicData, TStreamId aPrivateData)
1.702 + {
1.703 + CFileKeyData* self = new (ELeave) CFileKeyData(aObjectId, aInfoData, aPassphraseId, aPublicData, aPrivateData);
1.704 + CleanupStack::PushL(self);
1.705 + self->ConstructL(aLabel);
1.706 + return self;
1.707 + }
1.708 +
1.709 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.710 +
1.711 +CFileKeyData* CFileKeyData::NewL(RStoreReadStream& aReadStream)
1.712 + {
1.713 + CFileKeyData* self = new (ELeave) CFileKeyData();
1.714 + CleanupStack::PushL(self);
1.715 + self->InternalizeL(aReadStream);
1.716 + CleanupStack::Pop(self);
1.717 + return (self);
1.718 + }
1.719 +
1.720 +CFileKeyData::~CFileKeyData()
1.721 + {
1.722 + delete iLabel;
1.723 + }
1.724 +
1.725 +#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.726 +CFileKeyData::CFileKeyData(TInt aObjectId, TStreamId aInfoData,
1.727 + TStreamId aPublicData, TStreamId aPrivateData,
1.728 + AuthServer::TIdentityId aIdentityId) :
1.729 + iObjectId(aObjectId), iInfoData(aInfoData),
1.730 + iPublicKeyData(aPublicData), iPrivateKeyData(aPrivateData),
1.731 + iIdentityId(aIdentityId)
1.732 + {
1.733 + ASSERT(iObjectId);
1.734 + ASSERT(iInfoData != KNullStreamId);
1.735 + ASSERT(iPublicKeyData != KNullStreamId);
1.736 + ASSERT(iPrivateKeyData != KNullStreamId);
1.737 + ASSERT(iIdentityId);
1.738 + }
1.739 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.740 +#ifdef KEYTOOL
1.741 +CFileKeyData::CFileKeyData(TInt aObjectId, TStreamId aInfoData,
1.742 + TStreamId aPublicData, TStreamId aPrivateData,
1.743 + AuthServer::TIdentityId aIdentityId) :
1.744 + iObjectId(aObjectId), iInfoData(aInfoData),
1.745 + iPublicKeyData(aPublicData), iPrivateKeyData(aPrivateData),
1.746 + iIdentityId(aIdentityId)
1.747 + {
1.748 + ASSERT(iObjectId);
1.749 + ASSERT(iInfoData != KNullStreamId);
1.750 + ASSERT(iPublicKeyData != KNullStreamId);
1.751 + ASSERT(iPrivateKeyData != KNullStreamId);
1.752 + ASSERT(iIdentityId);
1.753 + }
1.754 +#endif // KEYTOOL
1.755 +
1.756 +CFileKeyData::CFileKeyData(TInt aObjectId, TStreamId aInfoData, TStreamId aPassphraseId,
1.757 + TStreamId aPublicData, TStreamId aPrivateData) :
1.758 + iObjectId(aObjectId), iInfoData(aInfoData), iPassphraseId(aPassphraseId),
1.759 + iPublicKeyData(aPublicData), iPrivateKeyData(aPrivateData)
1.760 + {
1.761 + ASSERT(iObjectId);
1.762 + ASSERT(iInfoData != KNullStreamId);
1.763 + ASSERT(iPassphraseId != KNullStreamId);
1.764 + ASSERT(iPublicKeyData != KNullStreamId);
1.765 + ASSERT(iPrivateKeyData != KNullStreamId);
1.766 + }
1.767 +
1.768 +CFileKeyData::CFileKeyData()
1.769 + {
1.770 + }
1.771 +
1.772 +void CFileKeyData::ConstructL(const TDesC& aLabel)
1.773 + {
1.774 + TInt labelLen = aLabel.Length();
1.775 + iLabel = HBufC::NewMaxL(labelLen);
1.776 + TPtr theLabel(iLabel->Des());
1.777 + theLabel.FillZ();
1.778 + theLabel.Copy(aLabel);
1.779 + }
1.780 +
1.781 +void CFileKeyData::InternalizeL(RReadStream& aReadStream)
1.782 +{
1.783 + iObjectId = aReadStream.ReadInt32L();
1.784 + iInfoData.InternalizeL(aReadStream);
1.785 +#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.786 + iPassphraseId.InternalizeL(aReadStream);
1.787 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.788 + iPublicKeyData.InternalizeL(aReadStream);
1.789 + iPrivateKeyData.InternalizeL(aReadStream);
1.790 +
1.791 + TInt labelLen = aReadStream.ReadInt32L();
1.792 + iLabel = HBufC::NewMaxL(labelLen);
1.793 + TPtr theLabel((TUint16*)iLabel->Ptr(), labelLen, labelLen);
1.794 + theLabel.FillZ(labelLen);
1.795 + aReadStream.ReadL(theLabel);
1.796 +#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.797 + iIdentityId = aReadStream.ReadInt32L();
1.798 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.799 +}
1.800 +
1.801 +void CFileKeyData::ExternalizeL(RWriteStream& aWriteStream) const
1.802 +{
1.803 + aWriteStream.WriteInt32L(iObjectId);
1.804 + iInfoData.ExternalizeL(aWriteStream);
1.805 +#ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.806 + iPassphraseId.ExternalizeL(aWriteStream);
1.807 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.808 + iPublicKeyData.ExternalizeL(aWriteStream);
1.809 + iPrivateKeyData.ExternalizeL(aWriteStream);
1.810 +
1.811 + TInt labelLen = iLabel->Length();
1.812 + aWriteStream.WriteInt32L(labelLen);
1.813 + TPtr theLabel(iLabel->Des());
1.814 + theLabel.SetLength(labelLen);
1.815 + aWriteStream.WriteL(theLabel);
1.816 +#ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.817 + aWriteStream.WriteInt32L(iIdentityId);
1.818 +#endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
1.819 +
1.820 +}
1.821 +
1.822 +#ifdef KEYTOOL
1.823 +
1.824 +CFileKeyData* CFileKeyData::CreateOldKeyL(RStoreReadStream& aReadStream)
1.825 + {
1.826 + CFileKeyData* self = new (ELeave) CFileKeyData();
1.827 + CleanupStack::PushL(self);
1.828 + self->InternalizeOldKeyL(aReadStream);
1.829 + CleanupStack::Pop(self);
1.830 + return (self);
1.831 + }
1.832 +
1.833 +void CFileKeyData::InternalizeOldKeyL(RReadStream& aReadStream)
1.834 + {
1.835 + iObjectId = aReadStream.ReadInt32L();
1.836 + iInfoData.InternalizeL(aReadStream);
1.837 + iPassphraseId.InternalizeL(aReadStream);
1.838 + iPublicKeyData.InternalizeL(aReadStream);
1.839 + iPrivateKeyData.InternalizeL(aReadStream);
1.840 +
1.841 + TInt labelLen = aReadStream.ReadInt32L();
1.842 + iLabel = HBufC::NewMaxL(labelLen);
1.843 + TPtr theLabel((TUint16*)iLabel->Ptr(), labelLen, labelLen);
1.844 + theLabel.FillZ(labelLen);
1.845 + aReadStream.ReadL(theLabel);
1.846 + }
1.847 +
1.848 +void CFileKeyData::ExternalizeWithAuthL(RWriteStream& aWriteStream)
1.849 +{
1.850 + aWriteStream.WriteInt32L(iObjectId);
1.851 + iInfoData.ExternalizeL(aWriteStream);
1.852 + iPublicKeyData.ExternalizeL(aWriteStream);
1.853 + iPrivateKeyData.ExternalizeL(aWriteStream);
1.854 +
1.855 + TInt labelLen = iLabel->Length();
1.856 + aWriteStream.WriteInt32L(labelLen);
1.857 + TPtr theLabel(iLabel->Des());
1.858 + theLabel.SetLength(labelLen);
1.859 + aWriteStream.WriteL(theLabel);
1.860 + aWriteStream.WriteInt32L(iIdentityId);
1.861 +}
1.862 +
1.863 +#endif // KEYTOOL