diff -r 675a964f4eb5 -r 35751d3474b7 cryptoservices/certificateandkeymgmt/swicertstore/CSWICertStoreImpl.cpp --- a/cryptoservices/certificateandkeymgmt/swicertstore/CSWICertStoreImpl.cpp Tue Jul 21 01:04:32 2009 +0100 +++ b/cryptoservices/certificateandkeymgmt/swicertstore/CSWICertStoreImpl.cpp Thu Sep 10 14:01:51 2009 +0300 @@ -1,515 +1,520 @@ -/* -* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* -*/ - - -#include "CSWICertStoreImpl.h" -#include "CSWICertStoreEntryList.h" -#include "CSWICertStoreEntry.h" -#include "CSWICertStoreTokenType.h" -#include "CSWICertStoreToken.h" -#include "unifiedcertstore.h" -#include "log.h" -#include "certstorepatchdata.h" -#include -#include -#include - -_LIT(KSWICertStoreZFilename,"z:\\resource\\swicertstore.dat"); -_LIT(KSWIWritableCertStorePath,"!:\\resource\\swicertstore\\dat\\"); -_LIT(KSWIROMCertStoreFilenamePattern,"z:\\resource\\swicertstore*.dat"); - -///////////////////////////////////////////////////////////////////////////////////////// -//CFSCertStoreServer -///////////////////////////////////////////////////////////////////////////////////////// - -CSWICertStoreImpl* CSWICertStoreImpl::NewL(MCTToken& aToken, RFs& aFs) - { - CSWICertStoreImpl* self = new (ELeave) CSWICertStoreImpl(aToken, aFs); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(self); - return self; - } - -CSWICertStoreImpl::CSWICertStoreImpl(MCTToken& aToken, RFs& aFs) : - CActive(EPriorityStandard), iToken(aToken), iFs(aFs) - { - CActiveScheduler::Add(this); - } - -void CSWICertStoreImpl::ConstructL() - { - TInt err = iSwicertstoreProperty.Attach(KUnifiedCertStorePropertyCat, - EUnifiedCertStoreFlag, EOwnerThread); - - User::LeaveIfError(err); - - iPatchableConst = KAggregateCertStore; - - #ifdef __WINS__ - // For the emulator allow the constant to be patched via epoc.ini - UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalIntProperty, - (TAny*)"KAggregateCertStore", &iPatchableConst); // read emulator property (if present) - #endif - - - // if patchable constant is enabled - if(iPatchableConst) - { - // Setup composite ROM Certstore - SetupCompositeROMCertStoreL(); - } - else - { - // Setup the ROM CertStore - SetupROMCertStoreL(); - } - - // Setup the Writable CertStore - // Bear in mind we need to trap NewL(), OpenLC() etc. - // Any error occurs, it should still setup the z:\ certstore - TRAP_IGNORE(SetupWritableCertStoreL()); - - // aggregate ROM composite certstore and writable certstore if patchable constant is enabled - if(iPatchableConst) - { - if(iCEntryList) - { - // ETrue to indicate that we are passing 'iZEntryList'. - // This action will remove duplicate entries from 'iZEntryList'. - MergeCertificateEntryListsL(*iZEntryList, ETrue); - } - } - // Subscribe to the Property - iSwicertstoreProperty.Subscribe(iStatus); - SetActive(); - } - -void CSWICertStoreImpl::DoCancel() - { - // Cancel outstanding request - iSwicertstoreProperty.Cancel(); - } - -void CSWICertStoreImpl::RunL() - { - // Resubscribe before processing new value to prevent missing updates - iSwicertstoreProperty.Subscribe(iStatus); - SetActive(); - - // Bear in mind we need to trap NewL(), OpenLC() etc. - TRAP_IGNORE(SetupWritableCertStoreL()); - } - -void CSWICertStoreImpl::SetupWritableCertStoreL() - { - TInt err = KErrNone; - - delete iCEntryList; - iCEntryList = NULL; - - // The attached file will be freed as well. - delete iCStore; - iCStore = NULL; - - do - { - // Open the store if it is there - RFile file; - CDir* entryList = NULL; - - TPath writableSwiCertStorePath(KSWIWritableCertStorePath); - TChar systemDriveChar = SecTcbUtil::GetSystemDriveChar(SecTcbUtil::GetSystemDrive()); - writableSwiCertStorePath[0] = systemDriveChar; - - if (KErrNone == iFs.GetDir (writableSwiCertStorePath, KEntryAttNormal, - ESortByName|EDirsFirst, entryList)) - { - if (entryList) - { - CleanupStack::PushL(entryList); - - TFileName certstoreFile; - TInt count = entryList->Count(); - - if (count > 0) - { - // Get the highest version certstore file - const TEntry& entry = (*entryList)[count - 1]; - - certstoreFile.Append(writableSwiCertStorePath); - certstoreFile.Append(entry.iName); - - CleanupStack::PopAndDestroy(1, entryList); - } - else - { - CleanupStack::PopAndDestroy(1, entryList); - - // No certstore in this directory - // Currently there should not have any directory in this path - return; - } - - err = file.Open(iFs, certstoreFile, EFileShareReadersOnly); - - if (err != KErrNone && err != KErrNotFound) - { - // Log the error to the system file. - DEBUG_PRINTF2(_L8("Error Opening SWI writable certstore: %S."), &certstoreFile); - return; - } - - if (err == KErrNone) - { - // File exist - CleanupClosePushL(file); - - TRAP_IGNORE(iCStore = CPermanentFileStore::FromL(file)); - - if (iCStore) - { - CleanupStack::Pop(&file); // now owned by store - - // Read id of cert list stream - TStreamId streamId; - RStoreReadStream stream; - stream.OpenLC(*iCStore, iCStore->Root()); - stream >> streamId; - CleanupStack::PopAndDestroy(&stream); - - // Read the certificate list - RStoreReadStream entryStream; - entryStream.OpenLC(*iCStore, streamId); - iCEntryList = CSWICertStoreEntryList::NewL(entryStream, iToken, iCertIndex); - - CleanupStack::PopAndDestroy(&entryStream); - - // Record the writable certstore index - // The index will then be used to set the tokenId in the - // in handle, so to make the handle unique. - iCertIndex += iCEntryList->Count(); - } - else - { - // The file format might not comply to the CPermanentFileStore format - CleanupStack::PopAndDestroy(&file); - - // Log the error to the system file. - DEBUG_PRINTF2(_L8("Error Opening SWI writable certstore: %S."), &certstoreFile); - - return; - } - } - } - } - }while (err == KErrNotFound); // There is a very slight chance that the file has been deleted - } - -void CSWICertStoreImpl::MergeCertificateEntryListsL(const CSWICertStoreEntryList& aSourceList, TBool aIsZEntryList) - { - ASSERT(iPatchableConst); - // if patchable constant is enabled - - TInt sourceCount = aSourceList.Count(); - for(TInt i = 0; i < sourceCount; i++) - { - if(!aIsZEntryList) - { - if (!iZEntryList->LabelExists(aSourceList.GetByIndex(i).CertInfo().Label())) - { - // Aggregation: Append this entry in the ROM composite list - const CSWICertStoreEntry& entry = aSourceList.GetByIndex(i); - CSWICertStoreEntry* newEntry = CSWICertStoreEntry::NewL(entry.CertInfo(), - entry.CertificateApps(), - entry.Trusted(), - entry.DataStreamId(), - entry.CertMetaInfo(), - entry.StoreIndex()); - CleanupStack::PushL(newEntry); - iZEntryList->AppendL(newEntry); - // iZEntryList has taken ownership - CleanupStack::Pop(newEntry); - } - // Eclipsing: Higher order store certificates with same labels take precedence over lower order store certificates. - // therefore the later are not included in the composite certificate entry list. - // N.B iCertIndex will not give total count of certificates because of Eclipsing mechanism. - // Higher order store certificates are ones which are aggregated prior to other certificates. - } - else - { - // remove duplicate label entries from the 'iZEntryList' - if (iCEntryList->LabelExists(aSourceList.GetByIndex(i).CertInfo().Label())) - { - // Remove entries from iZEntryList having same labels as in iCEntryList. - iZEntryList->Remove(i); - } - } - } - } - -void CSWICertStoreImpl::SetupCompositeROMCertStoreL() - { - ASSERT(iPatchableConst); - - // Collect the file present in ROM certstore private directory. - //The files in this list will be in descending order by name. - CDir* filenameList = NULL; - - User::LeaveIfError(iFs.GetDir(KSWIROMCertStoreFilenamePattern, KEntryAttNormal, ESortByName|EDescending, filenameList)); - CleanupStack::PushL(filenameList); - TInt count = filenameList->Count(); - TStreamId streamId; - - // make full path to the certstore files residing on ROM drive - // N.B filenameList will contain filenames in descending order. - RFile file; - RStoreReadStream stream; - - // create an empty list, this will be the composite certificate entry list - iZEntryList = CSWICertStoreEntryList::NewL(); - // the 'corruptCount' is used for proper correctly referencing valid certstores - TInt corruptCount=0; - for(TInt i = 0; i < count; i++) - { - RBuf romFile; - romFile.CreateL(KMaxFileName); - CleanupClosePushL(romFile); - romFile.Append(_L("z:\\resource\\")); - romFile.Append(((*filenameList)[i]).iName); - User::LeaveIfError(file.Open(iFs,romFile,EFileShareReadersOnly)); - CleanupClosePushL(file); - // open and append the store in array of stores - CPermanentFileStore* store = NULL; - // if there is any corrupt certstore present then we will simply ignore its - // aggregation and proceed with aggregating remaining stores. - // ownership is transfered to 'iZArrayOfStores' - TRAPD(err, store = CPermanentFileStore::FromL(file)); - if(err != KErrNone) - { - corruptCount++; - //cleanup file and romFile. - CleanupStack::PopAndDestroy(2, &romFile); - continue; - } - iZArrayOfStores.AppendL(store); - TInt index = i - corruptCount; - // open the root stream containing the streamId of info stream. - stream.OpenLC(*(iZArrayOfStores)[index],(iZArrayOfStores[index])->Root()); - stream >> streamId; - CleanupStack::PopAndDestroy(&stream); - - // re-open the info stream containing the certificates entry list. - stream.OpenLC(*(iZArrayOfStores)[index],streamId); - - // store index for these entries will be 'index'. - // iCertIndex will be 0 for the first certificate entry list passed. - CSWICertStoreEntryList* temp_list = CSWICertStoreEntryList::NewL(stream, iToken,iCertIndex,index); - // increment to have unique certificate Ids allocation. - iCertIndex += temp_list->Count(); - CleanupStack::PushL(temp_list); - MergeCertificateEntryListsL(*temp_list); - //temp_list, stream, file and romFile. - CleanupStack::PopAndDestroy(4, &romFile); - } - CleanupStack::PopAndDestroy(filenameList); - } - -void CSWICertStoreImpl::SetupROMCertStoreL() - { - // Open the store - RFile file; - User::LeaveIfError(file.Open(iFs, KSWICertStoreZFilename, EFileShareReadersOnly)); - CleanupClosePushL(file); - iZStore = CPermanentFileStore::FromL(file); - CleanupStack::Pop(&file); // now owned by store - - // Read id of cert list stream - TStreamId streamId; - RStoreReadStream stream; - stream.OpenLC(*iZStore, iZStore->Root()); - stream >> streamId; - CleanupStack::PopAndDestroy(&stream); - - // Read the certificate list - RStoreReadStream entryStream; - entryStream.OpenLC(*iZStore, streamId); - iZEntryList = CSWICertStoreEntryList::NewL(entryStream, iToken); - CleanupStack::PopAndDestroy(&entryStream); - - // set the valid indexes of writable certstore - iCertIndex = iZEntryList->Count(); - } - -CSWICertStoreImpl::~CSWICertStoreImpl() - { - Cancel(); - iSwicertstoreProperty.Close(); - delete iCEntryList; - delete iZEntryList; - delete iCStore; - delete iZStore; - iZArrayOfStores.ResetAndDestroy(); - } - -void CSWICertStoreImpl::ListL(RMPointerArray& aCerts, - const CCertAttributeFilter& aFilter) - { - if (iCEntryList) - { - FilterCertificateListL(aCerts, aFilter, *iCEntryList); - } - FilterCertificateListL(aCerts, aFilter, *iZEntryList); - } - -CCTCertInfo* CSWICertStoreImpl::GetCertL(const TCTTokenObjectHandle& aHandle) - { - TBool isCEntryHandle = EFalse; - const CSWICertStoreEntry* entry = GetCSWICertStoreEntryL(aHandle, isCEntryHandle); - return CCTCertInfo::NewL(entry->CertInfo()); - } - -void CSWICertStoreImpl::ApplicationsL(const TCTTokenObjectHandle& aHandle, RArray& aApplications) - { - TBool isCEntryHandle = EFalse; - const CSWICertStoreEntry* entry = GetCSWICertStoreEntryL(aHandle, isCEntryHandle); - - const RArray& apps = entry->CertificateApps(); - TInt count = apps.Count(); - - for (TInt i = 0 ; i < count ; ++i) - { - User::LeaveIfError(aApplications.Append(apps[i])); - } - } - -TBool CSWICertStoreImpl::IsApplicableL(const TCTTokenObjectHandle& aHandle, TUid aApplication) - { - TBool isCEntryHandle = EFalse; - const CSWICertStoreEntry* entry = GetCSWICertStoreEntryL(aHandle, isCEntryHandle); - return entry->IsApplicable(aApplication); - } - -TBool CSWICertStoreImpl::TrustedL(const TCTTokenObjectHandle& aHandle) - { - TBool isCEntryHandle = EFalse; - const CSWICertStoreEntry* entry = GetCSWICertStoreEntryL(aHandle, isCEntryHandle); - return entry->Trusted(); - } - -void CSWICertStoreImpl::RetrieveL(const TCTTokenObjectHandle& aHandle, TDes8& aEncodedCert) - { - TBool isCEntryHandle = EFalse; - const CSWICertStoreEntry* entry = GetCSWICertStoreEntryL(aHandle, isCEntryHandle); - RStoreReadStream stream; - - if (iCEntryList && isCEntryHandle) - { - stream.OpenLC(*iCStore, entry->DataStreamId()); - } - else - { - // if patchable constant is enabled - if (iPatchableConst) - { - stream.OpenLC(*(iZArrayOfStores[entry->StoreIndex()]), entry->DataStreamId()); - } - else - { - stream.OpenLC(*iZStore, entry->DataStreamId()); - } - } - - TInt size = entry->CertInfo().Size(); - - if (aEncodedCert.MaxLength() < size) - { - User::Leave(KErrOverflow); - } - - stream.ReadL(aEncodedCert, size); - CleanupStack::PopAndDestroy(&stream); - } - -const TCertMetaInfo& CSWICertStoreImpl::CertMetaInfoL(const TCTTokenObjectHandle& aHandle) const - { - TBool isCEntryHandle = EFalse; - const CSWICertStoreEntry* entry = GetCSWICertStoreEntryL(aHandle, isCEntryHandle); - return entry->CertMetaInfo(); - } - -const CSWICertStoreEntry* CSWICertStoreImpl::GetCSWICertStoreEntryL(const TCTTokenObjectHandle& aHandle, TBool& aCEntryHandle) const - { - if (iCEntryList) - { - const CSWICertStoreEntry* entry = NULL; - - TRAPD (retCode, entry = &(iCEntryList->GetByHandleL(aHandle))); - - if (entry && (retCode == KErrNone)) - { - aCEntryHandle = ETrue; - return entry; - } - } - return &iZEntryList->GetByHandleL(aHandle); - } - -void CSWICertStoreImpl::AddIfMatchesFilterL(RMPointerArray& aCerts, const CCertAttributeFilter& aFilter, const CSWICertStoreEntry& aEntry) - { - const CCTCertInfo& certInfo = aEntry.CertInfo(); - TBool accept = ETrue; - - if (aFilter.iUidIsSet) - { - accept = aEntry.IsApplicable(aFilter.iUid); - } - if (aFilter.iFormatIsSet && accept) - { - accept = (aFilter.iFormat == certInfo.CertificateFormat()); - } - if (aFilter.iOwnerTypeIsSet && accept) - { - accept = (aFilter.iOwnerType == certInfo.CertificateOwnerType()); - } - if (aFilter.iSubjectKeyIdIsSet && accept) - { - accept = (aFilter.iSubjectKeyId == certInfo.SubjectKeyId()); - } - if (aFilter.iLabelIsSet && accept) - { - accept = (aFilter.iLabel == certInfo.Label()); - } - - if (accept) - { - CCTCertInfo* newCertInfo = CCTCertInfo::NewLC(certInfo); - User::LeaveIfError(aCerts.Append(newCertInfo)); - CleanupStack::Pop(newCertInfo); - } - } - -void CSWICertStoreImpl::FilterCertificateListL(RMPointerArray& aCerts, - const CCertAttributeFilter& aFilter, const CSWICertStoreEntryList& aEntryList) - { - TInt count = aEntryList.Count(); - for (TInt index = 0; index < count; index++) - { - const CSWICertStoreEntry& entry = aEntryList.GetByIndex(index); - AddIfMatchesFilterL(aCerts, aFilter, entry); - } - } +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include "CSWICertStoreImpl.h" +#include "CSWICertStoreEntryList.h" +#include "CSWICertStoreEntry.h" +#include "CSWICertStoreTokenType.h" +#include "CSWICertStoreToken.h" +#include "unifiedcertstore.h" +#include "log.h" + +#include +#include +#include +#include + +_LIT(KSWICertStoreZFilename,"z:\\resource\\swicertstore.dat"); +_LIT(KSWIWritableCertStorePath,"!:\\resource\\swicertstore\\dat\\"); +_LIT(KSWIROMCertStoreFilenamePattern,"z:\\resource\\swicertstore*.dat"); + +///////////////////////////////////////////////////////////////////////////////////////// +//CFSCertStoreServer +///////////////////////////////////////////////////////////////////////////////////////// + +CSWICertStoreImpl* CSWICertStoreImpl::NewL(MCTToken& aToken, RFs& aFs) + { + CSWICertStoreImpl* self = new (ELeave) CSWICertStoreImpl(aToken, aFs); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +CSWICertStoreImpl::CSWICertStoreImpl(MCTToken& aToken, RFs& aFs) : + CActive(EPriorityStandard), iToken(aToken), iFs(aFs) + { + CActiveScheduler::Add(this); + } + +void CSWICertStoreImpl::ConstructL() + { + TInt err = iSwicertstoreProperty.Attach(KUnifiedCertStorePropertyCat, + EUnifiedCertStoreFlag, EOwnerThread); + + User::LeaveIfError(err); + + iPatchableConst = KAggregateCertStore; + + #ifdef __WINS__ + // For the emulator allow the constant to be patched via epoc.ini + UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalIntProperty, + (TAny*)"KAggregateCertStore", &iPatchableConst); // read emulator property (if present) + #endif + + + // if patchable constant is enabled + if(iPatchableConst) + { + // Setup composite ROM Certstore + SetupCompositeROMCertStoreL(); + } + else + { + // Setup the ROM CertStore + SetupROMCertStoreL(); + } + + // Setup the Writable CertStore + // Bear in mind we need to trap NewL(), OpenLC() etc. + // Any error occurs, it should still setup the z:\ certstore + TRAP_IGNORE(SetupWritableCertStoreL()); + + // aggregate ROM composite certstore and writable certstore if patchable constant is enabled + if(iPatchableConst) + { + if(iCEntryList) + { + // ETrue to indicate that we are passing 'iZEntryList'. + // This action will remove duplicate entries from 'iZEntryList'. + MergeCertificateEntryListsL(*iZEntryList, ETrue); + } + } + // Subscribe to the Property + iSwicertstoreProperty.Subscribe(iStatus); + SetActive(); + } + +void CSWICertStoreImpl::DoCancel() + { + // Cancel outstanding request + iSwicertstoreProperty.Cancel(); + } + +void CSWICertStoreImpl::RunL() + { + // Resubscribe before processing new value to prevent missing updates + iSwicertstoreProperty.Subscribe(iStatus); + SetActive(); + + // Bear in mind we need to trap NewL(), OpenLC() etc. + TRAP_IGNORE(SetupWritableCertStoreL()); + } + +void CSWICertStoreImpl::SetupWritableCertStoreL() + { + TInt err = KErrNone; + + delete iCEntryList; + iCEntryList = NULL; + + // The attached file will be freed as well. + delete iCStore; + iCStore = NULL; + + do + { + // Open the store if it is there + RFile file; + CDir* entryList = NULL; + + TPath writableSwiCertStorePath(KSWIWritableCertStorePath); + + TChar systemDriveChar = RFs::GetSystemDriveChar(); + + writableSwiCertStorePath[0] = systemDriveChar; + + if (KErrNone == iFs.GetDir (writableSwiCertStorePath, KEntryAttNormal, + ESortByName|EDirsFirst, entryList)) + { + if (entryList) + { + CleanupStack::PushL(entryList); + + TFileName certstoreFile; + TInt count = entryList->Count(); + + if (count > 0) + { + // Get the highest version certstore file + const TEntry& entry = (*entryList)[count - 1]; + + certstoreFile.Append(writableSwiCertStorePath); + certstoreFile.Append(entry.iName); + + CleanupStack::PopAndDestroy(1, entryList); + } + else + { + CleanupStack::PopAndDestroy(1, entryList); + + // No certstore in this directory + // Currently there should not have any directory in this path + return; + } + + err = file.Open(iFs, certstoreFile, EFileShareReadersOnly); + + if (err != KErrNone && err != KErrNotFound) + { + // Log the error to the system file. + DEBUG_PRINTF2(_L8("Error Opening SWI writable certstore: %S."), &certstoreFile); + return; + } + + if (err == KErrNone) + { + // File exist + CleanupClosePushL(file); + + TRAP_IGNORE(iCStore = CPermanentFileStore::FromL(file)); + + if (iCStore) + { + CleanupStack::Pop(&file); // now owned by store + + // Read id of cert list stream + TStreamId streamId; + RStoreReadStream stream; + stream.OpenLC(*iCStore, iCStore->Root()); + stream >> streamId; + CleanupStack::PopAndDestroy(&stream); + + // Read the certificate list + RStoreReadStream entryStream; + entryStream.OpenLC(*iCStore, streamId); + iCEntryList = CSWICertStoreEntryList::NewL(entryStream, iToken, iCertIndex); + + CleanupStack::PopAndDestroy(&entryStream); + + // Record the writable certstore index + // The index will then be used to set the tokenId in the + // in handle, so to make the handle unique. + iCertIndex += iCEntryList->Count(); + } + else + { + // The file format might not comply to the CPermanentFileStore format + CleanupStack::PopAndDestroy(&file); + + // Log the error to the system file. + DEBUG_PRINTF2(_L8("Error Opening SWI writable certstore: %S."), &certstoreFile); + + return; + } + } + } + } + }while (err == KErrNotFound); // There is a very slight chance that the file has been deleted + } + +void CSWICertStoreImpl::MergeCertificateEntryListsL(const CSWICertStoreEntryList& aSourceList, TBool aIsZEntryList) + { + ASSERT(iPatchableConst); + // if patchable constant is enabled + + TInt sourceCount = aSourceList.Count(); + for(TInt i = 0; i < sourceCount; i++) + { + if(!aIsZEntryList) + { + if (!iZEntryList->LabelExists(aSourceList.GetByIndex(i).CertInfo().Label())) + { + // Aggregation: Append this entry in the ROM composite list + const CSWICertStoreEntry& entry = aSourceList.GetByIndex(i); + CSWICertStoreEntry* newEntry = CSWICertStoreEntry::NewL(entry.CertInfo(), + entry.CertificateApps(), + entry.Trusted(), + entry.DataStreamId(), + entry.CertMetaInfo(), + entry.StoreIndex()); + CleanupStack::PushL(newEntry); + iZEntryList->AppendL(newEntry); + // iZEntryList has taken ownership + CleanupStack::Pop(newEntry); + } + // Eclipsing: Higher order store certificates with same labels take precedence over lower order store certificates. + // therefore the later are not included in the composite certificate entry list. + // N.B iCertIndex will not give total count of certificates because of Eclipsing mechanism. + // Higher order store certificates are ones which are aggregated prior to other certificates. + } + else + { + // remove duplicate label entries from the 'iZEntryList' + if (iCEntryList->LabelExists(aSourceList.GetByIndex(i).CertInfo().Label())) + { + // Remove entries from iZEntryList having same labels as in iCEntryList. + iZEntryList->Remove(i); + } + } + } + } + +void CSWICertStoreImpl::SetupCompositeROMCertStoreL() + { + ASSERT(iPatchableConst); + + // Collect the file present in ROM certstore private directory. + //The files in this list will be in descending order by name. + CDir* filenameList = NULL; + + User::LeaveIfError(iFs.GetDir(KSWIROMCertStoreFilenamePattern, KEntryAttNormal, ESortByName|EDescending, filenameList)); + CleanupStack::PushL(filenameList); + TInt count = filenameList->Count(); + TStreamId streamId; + + // make full path to the certstore files residing on ROM drive + // N.B filenameList will contain filenames in descending order. + RFile file; + RStoreReadStream stream; + + // create an empty list, this will be the composite certificate entry list + iZEntryList = CSWICertStoreEntryList::NewL(); + // the 'corruptCount' is used for proper correctly referencing valid certstores + TInt corruptCount=0; + for(TInt i = 0; i < count; i++) + { + RBuf romFile; + romFile.CreateL(KMaxFileName); + CleanupClosePushL(romFile); + romFile.Append(_L("z:\\resource\\")); + romFile.Append(((*filenameList)[i]).iName); + User::LeaveIfError(file.Open(iFs,romFile,EFileShareReadersOnly)); + CleanupClosePushL(file); + // open and append the store in array of stores + CPermanentFileStore* store = NULL; + // if there is any corrupt certstore present then we will simply ignore its + // aggregation and proceed with aggregating remaining stores. + // ownership is transfered to 'iZArrayOfStores' + TRAPD(err, store = CPermanentFileStore::FromL(file)); + if(err != KErrNone) + { + corruptCount++; + //cleanup file and romFile. + CleanupStack::PopAndDestroy(2, &romFile); + continue; + } + iZArrayOfStores.AppendL(store); + TInt index = i - corruptCount; + // open the root stream containing the streamId of info stream. + stream.OpenLC(*(iZArrayOfStores)[index],(iZArrayOfStores[index])->Root()); + stream >> streamId; + CleanupStack::PopAndDestroy(&stream); + + // re-open the info stream containing the certificates entry list. + stream.OpenLC(*(iZArrayOfStores)[index],streamId); + + // store index for these entries will be 'index'. + // iCertIndex will be 0 for the first certificate entry list passed. + CSWICertStoreEntryList* temp_list = CSWICertStoreEntryList::NewL(stream, iToken,iCertIndex,index); + // increment to have unique certificate Ids allocation. + iCertIndex += temp_list->Count(); + CleanupStack::PushL(temp_list); + MergeCertificateEntryListsL(*temp_list); + //temp_list, stream, file and romFile. + CleanupStack::PopAndDestroy(4, &romFile); + } + CleanupStack::PopAndDestroy(filenameList); + } + +void CSWICertStoreImpl::SetupROMCertStoreL() + { + // Open the store + RFile file; + User::LeaveIfError(file.Open(iFs, KSWICertStoreZFilename, EFileShareReadersOnly)); + CleanupClosePushL(file); + iZStore = CPermanentFileStore::FromL(file); + CleanupStack::Pop(&file); // now owned by store + + // Read id of cert list stream + TStreamId streamId; + RStoreReadStream stream; + stream.OpenLC(*iZStore, iZStore->Root()); + stream >> streamId; + CleanupStack::PopAndDestroy(&stream); + + // Read the certificate list + RStoreReadStream entryStream; + entryStream.OpenLC(*iZStore, streamId); + iZEntryList = CSWICertStoreEntryList::NewL(entryStream, iToken); + CleanupStack::PopAndDestroy(&entryStream); + + // set the valid indexes of writable certstore + iCertIndex = iZEntryList->Count(); + } + +CSWICertStoreImpl::~CSWICertStoreImpl() + { + Cancel(); + iSwicertstoreProperty.Close(); + delete iCEntryList; + delete iZEntryList; + delete iCStore; + delete iZStore; + iZArrayOfStores.ResetAndDestroy(); + } + +void CSWICertStoreImpl::ListL(RMPointerArray& aCerts, + const CCertAttributeFilter& aFilter) + { + if (iCEntryList) + { + FilterCertificateListL(aCerts, aFilter, *iCEntryList); + } + FilterCertificateListL(aCerts, aFilter, *iZEntryList); + } + +CCTCertInfo* CSWICertStoreImpl::GetCertL(const TCTTokenObjectHandle& aHandle) + { + TBool isCEntryHandle = EFalse; + const CSWICertStoreEntry* entry = GetCSWICertStoreEntryL(aHandle, isCEntryHandle); + return CCTCertInfo::NewL(entry->CertInfo()); + } + +void CSWICertStoreImpl::ApplicationsL(const TCTTokenObjectHandle& aHandle, RArray& aApplications) + { + TBool isCEntryHandle = EFalse; + const CSWICertStoreEntry* entry = GetCSWICertStoreEntryL(aHandle, isCEntryHandle); + + const RArray& apps = entry->CertificateApps(); + TInt count = apps.Count(); + + for (TInt i = 0 ; i < count ; ++i) + { + User::LeaveIfError(aApplications.Append(apps[i])); + } + } + +TBool CSWICertStoreImpl::IsApplicableL(const TCTTokenObjectHandle& aHandle, TUid aApplication) + { + TBool isCEntryHandle = EFalse; + const CSWICertStoreEntry* entry = GetCSWICertStoreEntryL(aHandle, isCEntryHandle); + return entry->IsApplicable(aApplication); + } + +TBool CSWICertStoreImpl::TrustedL(const TCTTokenObjectHandle& aHandle) + { + TBool isCEntryHandle = EFalse; + const CSWICertStoreEntry* entry = GetCSWICertStoreEntryL(aHandle, isCEntryHandle); + return entry->Trusted(); + } + +void CSWICertStoreImpl::RetrieveL(const TCTTokenObjectHandle& aHandle, TDes8& aEncodedCert) + { + TBool isCEntryHandle = EFalse; + const CSWICertStoreEntry* entry = GetCSWICertStoreEntryL(aHandle, isCEntryHandle); + RStoreReadStream stream; + + if (iCEntryList && isCEntryHandle) + { + stream.OpenLC(*iCStore, entry->DataStreamId()); + } + else + { + // if patchable constant is enabled + if (iPatchableConst) + { + stream.OpenLC(*(iZArrayOfStores[entry->StoreIndex()]), entry->DataStreamId()); + } + else + { + stream.OpenLC(*iZStore, entry->DataStreamId()); + } + } + + TInt size = entry->CertInfo().Size(); + + if (aEncodedCert.MaxLength() < size) + { + User::Leave(KErrOverflow); + } + + stream.ReadL(aEncodedCert, size); + CleanupStack::PopAndDestroy(&stream); + } + +const TCertMetaInfo& CSWICertStoreImpl::CertMetaInfoL(const TCTTokenObjectHandle& aHandle) const + { + TBool isCEntryHandle = EFalse; + const CSWICertStoreEntry* entry = GetCSWICertStoreEntryL(aHandle, isCEntryHandle); + return entry->CertMetaInfo(); + } + +const CSWICertStoreEntry* CSWICertStoreImpl::GetCSWICertStoreEntryL(const TCTTokenObjectHandle& aHandle, TBool& aCEntryHandle) const + { + if (iCEntryList) + { + const CSWICertStoreEntry* entry = NULL; + + TRAPD (retCode, entry = &(iCEntryList->GetByHandleL(aHandle))); + + if (entry && (retCode == KErrNone)) + { + aCEntryHandle = ETrue; + return entry; + } + } + return &iZEntryList->GetByHandleL(aHandle); + } + +void CSWICertStoreImpl::AddIfMatchesFilterL(RMPointerArray& aCerts, const CCertAttributeFilter& aFilter, const CSWICertStoreEntry& aEntry) + { + const CCTCertInfo& certInfo = aEntry.CertInfo(); + TBool accept = ETrue; + + if (aFilter.iUidIsSet) + { + accept = aEntry.IsApplicable(aFilter.iUid); + } + if (aFilter.iFormatIsSet && accept) + { + accept = (aFilter.iFormat == certInfo.CertificateFormat()); + } + if (aFilter.iOwnerTypeIsSet && accept) + { + accept = (aFilter.iOwnerType == certInfo.CertificateOwnerType()); + } + if (aFilter.iSubjectKeyIdIsSet && accept) + { + accept = (aFilter.iSubjectKeyId == certInfo.SubjectKeyId()); + } + if (aFilter.iLabelIsSet && accept) + { + accept = (aFilter.iLabel == certInfo.Label()); + } + + if (accept) + { + CCTCertInfo* newCertInfo = CCTCertInfo::NewLC(certInfo); + User::LeaveIfError(aCerts.Append(newCertInfo)); + CleanupStack::Pop(newCertInfo); + } + } + +void CSWICertStoreImpl::FilterCertificateListL(RMPointerArray& aCerts, + const CCertAttributeFilter& aFilter, const CSWICertStoreEntryList& aEntryList) + { + TInt count = aEntryList.Count(); + for (TInt index = 0; index < count; index++) + { + const CSWICertStoreEntry& entry = aEntryList.GetByIndex(index); + AddIfMatchesFilterL(aCerts, aFilter, entry); + } + } + +