sl@0: /*
sl@0: * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: * All rights reserved.
sl@0: * This component and the accompanying materials are made available
sl@0: * under the terms of the License "Eclipse Public License v1.0"
sl@0: * which accompanies this distribution, and is available
sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: *
sl@0: * Initial Contributors:
sl@0: * Nokia Corporation - initial contribution.
sl@0: *
sl@0: * Contributors:
sl@0: *
sl@0: * Description: 
sl@0: * This class implements the reference Crypto Token Hardware Abstraction 
sl@0: * Interface (HAI). It is just intended to show how operations using 
sl@0: * device keys can be performed using crypto token framework. In the 
sl@0: * real world scenario, this HAI should be replaced by device drivers 
sl@0: * by the licensees. In such a case, all the operations performed by 
sl@0: * the replacing class would be performed in Kernel Space.
sl@0: *
sl@0: */
sl@0: 
sl@0: 
sl@0: #include "tcryptotokenhai.h"
sl@0: #include "tkeydetails.h"
sl@0: #include "cryptosignatureapi.h"
sl@0: #include "keys.h"
sl@0: 
sl@0: #include <cryptospi/cryptoparams.h>
sl@0: #include <cryptospi/cryptospidef.h>
sl@0: 
sl@0: EXPORT_C CCryptoTokenHai* CCryptoTokenHai::NewLC(MCTToken* aToken)
sl@0: 	{
sl@0: 	CCryptoTokenHai* instance = new(ELeave) CCryptoTokenHai(*aToken);
sl@0: 	CleanupStack::PushL(instance);
sl@0: 	instance->ConstructL();
sl@0: 	return instance;
sl@0: 	}
sl@0: 
sl@0: EXPORT_C CCryptoTokenHai* CCryptoTokenHai::NewL(MCTToken* aToken)
sl@0: 	{
sl@0: 	CCryptoTokenHai* instance = CCryptoTokenHai::NewLC(aToken);
sl@0: 	CleanupStack::Pop(instance);
sl@0: 	return instance;
sl@0: 	}
sl@0: 
sl@0: void CCryptoTokenHai::ConstructL()
sl@0: 	{
sl@0: 	User::LeaveIfError(iFs.Connect());
sl@0: 	OpenStoreL();
sl@0: 	}
sl@0: 
sl@0: CCryptoTokenHai::CCryptoTokenHai(MCTToken& aToken)
sl@0: 	:iToken(aToken)
sl@0: 	{}
sl@0: 
sl@0: EXPORT_C CCryptoTokenHai::~CCryptoTokenHai()
sl@0: 	{
sl@0: 	if(iFileStore)
sl@0:         {
sl@0:         CompactStore();
sl@0:         delete iFileStore;
sl@0:         }
sl@0: 	
sl@0: 	iFs.Close();
sl@0: 	iKeys.ResetAndDestroy();
sl@0:     iKeys.Close();
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  * Performs the decryption operation.
sl@0:  * 
sl@0:  * This API gets called when the decryption is supposed to be done in  
sl@0:  * the hardware.
sl@0:  * 
sl@0:  * @param aHandle The key handle
sl@0:  * @param aCiphertext The cipher text. This is not being used presently 
sl@0:  * due to decryption logic used in this function.
sl@0:  * @param aPlainText Output param. The decrypted plain text. Ownership 
sl@0:  * of the pointer lies with the caller.
sl@0:  * 
sl@0:  * @leave This function can leave with following error codes:-
sl@0:  * - KErrNotFound - If the key corresponding to given handle is not 
sl@0:  * found.
sl@0:  * - Any other error code returned by AllocL().
sl@0:  *
sl@0:  * @note This function does not actually implement ECC decryption. It 
sl@0:  * just intends to show that the key is with this class and it can 
sl@0:  * do actual ECC decryption here. This function just returns the 
sl@0:  * private key as decrypted text. The caller can verify the decryption 
sl@0:  * by ensuring that test case has same public and private keys and then 
sl@0:  * comparing the decrypted text with public key. 
sl@0:  */
sl@0: EXPORT_C void CCryptoTokenHai::DecryptL(	TInt aHandle,	
sl@0: 											const TDesC8& /* aCiphertext */,
sl@0: 											HBufC8*& aPlainText )
sl@0: 	{
sl@0:     TInt keyIndex = KeyPresent(aHandle);
sl@0:     if(keyIndex == KErrNotFound)
sl@0:         {
sl@0:         User::Leave(KErrNotFound);
sl@0:         }
sl@0:     
sl@0:     ExportPrivateKeyL(aHandle, aPlainText);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  * Performs the signing operation.
sl@0:  * 
sl@0:  * This API gets called when the signing is supposed to be done inside 
sl@0:  * the hardware.
sl@0:  * 
sl@0:  * @param aHandle The key handle
sl@0:  * @param aPlaintext The text which has to be signed. This is not being 
sl@0:  * used due to signing logic used in this function.
sl@0:  * @param aSignature Output param. The signature in HBufC8 format.  
sl@0:  * Ownership of the pointer lies with the caller. This should be 
sl@0:  * converted to CCryptoParams by the crypto token reference plugin. 
sl@0:  * 
sl@0:  * @leave This function can leave with following error codes:-
sl@0:  * - KErrNotFound - If the key corresponding to given handle is not 
sl@0:  * found.
sl@0:  * - Any other error code returned by AllocL().
sl@0:  * 
sl@0:  * @note This function does not actually implement ECC signing. It 
sl@0:  * just intends to show that the key is with this class and it can 
sl@0:  * do actual ECC signing here. Currently this function just returns 
sl@0:  * the private key as output signature. The caller can verify the 
sl@0:  * signature by ensuring that test case has same public and private 
sl@0:  * keys and then comparing the signature with public key.
sl@0:  */
sl@0: EXPORT_C void CCryptoTokenHai::SignL( 	TInt aHandle,
sl@0: 										const TDesC8& /* aPlaintext */,
sl@0: 										HBufC8*& aSignature )
sl@0: 	{
sl@0: 	TInt keyIndex = KeyPresent(aHandle);
sl@0: 	if(keyIndex == KErrNotFound)
sl@0: 	    {
sl@0: 	    User::Leave(KErrNotFound);
sl@0: 	    }
sl@0: 	
sl@0: 	ExportPrivateKeyL(aHandle, aSignature);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  * Returns the index of the key whose handle is given.
sl@0:  * 
sl@0:  * @param aHandle Handle of the key. This is used to search the key.
sl@0:  * 
sl@0:  * @return index of the key if search is successful, KErrNotFound 
sl@0:  * otherwise.
sl@0:  */
sl@0: EXPORT_C TInt CCryptoTokenHai::KeyPresent( TInt aHandle )
sl@0: 	{
sl@0: 	int keysCount = iKeys.Count();
sl@0: 	for(TInt i=0; i < keysCount; ++i)
sl@0: 		{
sl@0: 		if(iKeys[i]->Handle() == aHandle)
sl@0: 			{
sl@0: 			return i;
sl@0: 			}
sl@0: 		}
sl@0: 	return KErrNotFound;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  * Extracts the private key.
sl@0:  * 
sl@0:  * @param aHandle Handle of the private key to be extracted.
sl@0:  * @param aKey Output Parameter. Stores the private key on success. 
sl@0:  * Ownership of pointer is with the caller.
sl@0:  * 
sl@0:  * @leave Following leave codes possible:-
sl@0:  * - Any leave code returned by AllocL().
sl@0:  * - KErrNotFound - If key corresponding to the given handle is not 
sl@0:  * found.
sl@0:  * 
sl@0:  * @note In the actual implementation, licensees should ensure that 
sl@0:  * this function can be called only in Kernel space. In the reference 
sl@0:  * implementation, this function gets called only by CCryptoSpiHai, 
sl@0:  * which is assumed to operate in kernel space. This would ensure that 
sl@0:  * the private key always stays inside the hardware.
sl@0:  */
sl@0: EXPORT_C void CCryptoTokenHai::ExportPrivateKeyL( TInt aHandle, HBufC8*& aKey )
sl@0: 	{
sl@0: 	int keysCount = iKeys.Count();
sl@0: 	for(int i = 0; i < keysCount; ++i)
sl@0: 		{
sl@0: 		if(iKeys[i]->Handle() == aHandle)
sl@0: 			{
sl@0: 			aKey = iKeys[i]->PrivateKey()->AllocL();
sl@0: 			return;
sl@0: 			}
sl@0: 		}
sl@0: 	User::Leave(KErrNotFound);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  * Extracts the public key.
sl@0:  * 
sl@0:  * @param aHandle Handle of the public key to be extracted.
sl@0:  * @param aKey Output Parameter. Stores the public key on success.
sl@0:  * Ownership of pointer is with the caller.
sl@0:  * 
sl@0:  * @leave Following leave codes possible:-
sl@0:  * - Any leave code returned by AllocL().
sl@0:  * - KErrNotFound - If key corresponding to the given handle is not 
sl@0:  * found.
sl@0:  */
sl@0: EXPORT_C void CCryptoTokenHai::ExportPublicKeyL( TInt aHandle, HBufC8*& aKey )
sl@0:     {
sl@0:     int keysCount = iKeys.Count();
sl@0:     for(int i = 0; i < keysCount; ++i)
sl@0:         {
sl@0:         if(iKeys[i]->Handle() == aHandle)
sl@0:             {
sl@0:             aKey = iKeys[i]->PublicKey()->AllocL();
sl@0:             return;
sl@0:             }
sl@0:         }
sl@0:     User::Leave(KErrNotFound);
sl@0:     }
sl@0: 
sl@0: /**
sl@0:  * Stores the key with given details.
sl@0:  * 
sl@0:  * @param aLabel Label of the key.
sl@0:  * @param aPrivateKey Private component of the key.
sl@0:  * @param aPublicKey Public component of the key.
sl@0:  * 
sl@0:  * @leave Following leave codes possible:-
sl@0:  * - KErrAlreadyExists If there is already a key with the inputted
sl@0:  * label.
sl@0:  * - Any other leave code returned by NewL() or AppendL().
sl@0:  *  
sl@0:  * @note In the present reference implementation this function is not 
sl@0:  * being used, since device keys are pre-provisioned by the licensees. 
sl@0:  * Hence licensees may decide not to implement this function in their 
sl@0:  * real implementation. 
sl@0:  */
sl@0: EXPORT_C void CCryptoTokenHai::ImportKeyL(const TDesC& aLabel, 
sl@0:         const TDesC8& aPrivateKey, const TDesC8& aPublicKey)
sl@0: 	{
sl@0: 	int keysCount = iKeys.Count();
sl@0: 	for(int i = 0; i < keysCount; ++i)
sl@0: 		{
sl@0: 		if(iKeys[i]->Label() == aLabel)
sl@0: 			{
sl@0: 			User::Leave(KErrAlreadyExists);
sl@0: 			}
sl@0: 		}
sl@0: 	CKeyDetails* keyDetails = CKeyDetails::NewL(keysCount+1,aLabel,aPrivateKey,aPublicKey);
sl@0: 	iKeys.AppendL(keyDetails);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  * Populates the string containing full RAM path of file containing 
sl@0:  * keys.
sl@0:  */
sl@0: void CCryptoTokenHai::MakePrivateFilenameL(RFs& aFs, const TDesC& aLeafName, TDes& aNameOut)
sl@0:     {
sl@0:     aNameOut.SetLength(0);  
sl@0:     aNameOut.Append(RFs::GetSystemDriveChar());
sl@0: 
sl@0:     aNameOut.Append(':');
sl@0: 
sl@0:     // Get private path
sl@0:     TBuf<20> privatePath;
sl@0:     User::LeaveIfError(aFs.PrivatePath(privatePath));
sl@0:     aNameOut.Append(privatePath);
sl@0:     
sl@0:     aNameOut.Append(aLeafName);
sl@0:     }
sl@0: 
sl@0: /**
sl@0:  * Creates the corresponding directory, if it does not exist.
sl@0:  */
sl@0: void CCryptoTokenHai::EnsurePathL(RFs& aFs, const TDesC& aFile)
sl@0:     {
sl@0:     TInt err = aFs.MkDirAll(aFile);
sl@0:     if (err != KErrNone && err != KErrAlreadyExists)
sl@0:         {
sl@0:         User::Leave(err);
sl@0:         }
sl@0:     }
sl@0: 
sl@0: /**
sl@0:  * Populates the string containing full ROM path of the keys file.
sl@0:  */
sl@0: void CCryptoTokenHai::MakePrivateROMFilenameL(RFs& aFs, const TDesC& aLeafName, TDes& aNameOut)
sl@0:     {
sl@0:     _LIT(KFileStoreROMDrive, "Z:");
sl@0:     
sl@0:     aNameOut.Copy(KFileStoreROMDrive);
sl@0: 
sl@0:     // Get private path
sl@0:     TBuf<20> privatePath;
sl@0:     User::LeaveIfError(aFs.PrivatePath(privatePath)); 
sl@0:     aNameOut.Append(privatePath);
sl@0:     aNameOut.Append(aLeafName);
sl@0:     }
sl@0: 
sl@0: /**
sl@0:  * Copies the contents of source file to destination file.
sl@0:  * 
sl@0:  * This is typically used to copy the keys file from ROM to RAM.
sl@0:  */
sl@0: void CCryptoTokenHai::CopyL(RFs& aFs, const TDesC& aSouce, const TDesC& aDest)
sl@0:     {
sl@0:     RFileReadStream in;
sl@0:     User::LeaveIfError(in.Open(aFs, aSouce, EFileRead | EFileShareReadersOnly));
sl@0:     CleanupClosePushL(in);
sl@0: 
sl@0:     RFileWriteStream out;
sl@0:     User::LeaveIfError(out.Replace(aFs, aDest, EFileWrite | EFileShareExclusive));
sl@0:     CleanupClosePushL(out);
sl@0: 
sl@0:     in.ReadL(out);  
sl@0:     CleanupStack::PopAndDestroy(2, &in);
sl@0:     }
sl@0: 
sl@0: /**
sl@0:  * Keys corresponding to this store are present in hwkeys.dat. 
sl@0:  * In the production code written by licensees, this would be the path 
sl@0:  * where device keys are stored.
sl@0:  */
sl@0: _LIT(KKeyStoreFilename,"hwkeys.dat");
sl@0: 
sl@0: /**
sl@0:  * Opens a store containing hardware keys.
sl@0:  * 
sl@0:  * This function uses the following logic to open the store:-
sl@0:  * -# Try to open the store from the private directory.
sl@0:  * -# If this fails copy the file from ROM to RAM.
sl@0:  * -# If both fail, create your own keys store from scratch.
sl@0:  */
sl@0: void CCryptoTokenHai::OpenStoreL()
sl@0: 	{
sl@0: 	TFileName fullPath;
sl@0: 	MakePrivateFilenameL(iFs, KKeyStoreFilename, fullPath);
sl@0: 
sl@0: 	EnsurePathL(iFs, fullPath);
sl@0: 	TRAPD(result, OpenStoreInFileL(fullPath));
sl@0: 
sl@0: 	if (result == KErrInUse  ) 
sl@0: 		{		
sl@0: 		// Cannot access the file now. Abort rather than wiping the keystore.
sl@0: 		User::Leave(result); 
sl@0: 		}
sl@0: 	
sl@0: 	if (result != KErrNone )
sl@0: 		{		
sl@0: 		/*
sl@0: 		 * Not yet opened a valid store, either no file to be found, or 
sl@0: 		 * no valid store in it. Copy the original one stored in the 
sl@0: 		 * ROM.
sl@0: 		 */
sl@0: 		TRAPD(result2, CopyStoreFromROML(fullPath, result));
sl@0: 				
sl@0: 		if (KErrNone != result2)
sl@0: 			{
sl@0: 			/*
sl@0: 			 * We tried to copy the keystore from ROM. For some reason this
sl@0: 			 * failed and we still cannot open the file. Create a new one from
sl@0: 			 * scratch.
sl@0: 			 */ 
sl@0: 			CreateStoreInFileL(fullPath);
sl@0: 			}
sl@0: 		}
sl@0: 
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  * Copies the key store file from ROM to RAM.
sl@0:  */
sl@0: void CCryptoTokenHai::CopyStoreFromROML(const TDesC& fullPath, TInt result)
sl@0:     {
sl@0:     if (result != KErrNotFound)
sl@0:         {
sl@0:         // Wipe the keystore if we can't open it (it's corrupt anyway)
sl@0:         User::LeaveIfError(iFs.Delete(fullPath));
sl@0:         }
sl@0: 
sl@0:     TFileName romPath;
sl@0:     MakePrivateROMFilenameL(iFs, KKeyStoreFilename, romPath);
sl@0: 
sl@0:     // Copy data from rom and open it   
sl@0:     CopyL(iFs, romPath, fullPath);
sl@0:     OpenStoreInFileL(fullPath);
sl@0:     }
sl@0: 
sl@0: /**
sl@0:  * Opens a store from the given file.
sl@0:  */
sl@0: void CCryptoTokenHai::OpenStoreInFileL(const TDesC& aFile)
sl@0: 	{
sl@0: 	RFile file;
sl@0: 	User::LeaveIfError(file.Open(iFs, aFile, EFileRead | EFileWrite | EFileShareAny));
sl@0: 	CleanupClosePushL(file);
sl@0:     delete iFileStore;
sl@0:     iFileStore = NULL;
sl@0: 
sl@0: 	iFileStore = CPermanentFileStore::FromL(file);
sl@0:     // iFileStore takes ownership of file now
sl@0: 	CleanupStack::Pop(&file);
sl@0: 	
sl@0:     // Get the salt, root and manager TStreamIds
sl@0:     iRootStreamId = iFileStore->Root();
sl@0:     if (iRootStreamId == KNullStreamId)
sl@0:         {
sl@0:         User::Leave(KErrCorrupt);
sl@0:         }
sl@0:     RStoreReadStream rootStream;
sl@0:     rootStream.OpenLC(*iFileStore, iRootStreamId);
sl@0:     ReadKeysFromStoreL();
sl@0:     CleanupStack::PopAndDestroy(&rootStream);
sl@0:     }
sl@0: 
sl@0: /**
sl@0:  * Creates a keys store in RAM from scratch.
sl@0:  * 
sl@0:  * @note This function should never get called as hwkeys.dat should be 
sl@0:  * always present in ROM. If this function somehow gets called, it 
sl@0:  * will create a hwkeys.dat file from scratch. However, this file would 
sl@0:  * not contain any keys and tests would not pass.
sl@0:  */
sl@0: void CCryptoTokenHai::CreateStoreInFileL(const TDesC& aFile)
sl@0: 	{
sl@0: 	TInt r = iFs.MkDirAll(aFile);
sl@0: 	if ( (r!=KErrNone) && (r!=KErrAlreadyExists) )
sl@0: 		User::Leave(r);
sl@0: 
sl@0:     delete iFileStore;
sl@0:     iFileStore = NULL;
sl@0: 	iFileStore = CPermanentFileStore::ReplaceL(iFs, aFile, EFileRead | EFileWrite | EFileShareExclusive);
sl@0: 	iFileStore->SetTypeL(KPermanentFileStoreLayoutUid);
sl@0: 
sl@0: 	TCleanupItem cleanupStore(RevertStore, iFileStore);
sl@0: 	CleanupStack::PushL(cleanupStore);
sl@0: 	
sl@0: 	// Create root stream - just contains id of info stream
sl@0: 	RStoreWriteStream rootStream;
sl@0: 	iRootStreamId = rootStream.CreateLC(*iFileStore);
sl@0: 	iFileStore->SetRootL(iRootStreamId);
sl@0: 	WriteKeysToStoreL(rootStream);
sl@0: 	iFileStore->CommitL();
sl@0: 	CleanupStack::PopAndDestroy(&rootStream);
sl@0: 	CleanupStack::Pop(); // cleanupStore
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  * Copies the keys stored in the instance to inputted write stream.
sl@0:  * 
sl@0:  * This invokes the CKeyDetails::ExternalizeL() function.
sl@0:  */
sl@0: void CCryptoTokenHai::WriteKeysToStoreL(RStoreWriteStream& aRootStream)
sl@0: 	{
sl@0: 	TInt keyCount = iKeys.Count();
sl@0: 	aRootStream.WriteInt32L(keyCount);
sl@0: 
sl@0: 	for (TInt index = 0; index < keyCount; index++)
sl@0: 		{
sl@0: 		aRootStream << *iKeys[index];
sl@0: 		}
sl@0: 	aRootStream.CommitL();
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  * Copies the keys present in the read store to instance of class.
sl@0:  * 
sl@0:  * This eventually invokes the CKeyDetails::InternalizeL() function.
sl@0:  */
sl@0: void CCryptoTokenHai::ReadKeysFromStoreL()
sl@0: 	{
sl@0: 	RStoreReadStream rootStream;
sl@0: 	
sl@0: 	rootStream.OpenLC(*iFileStore, iRootStreamId);
sl@0: 	TInt keyCount = rootStream.ReadInt32L();
sl@0: 
sl@0: 	for (TInt index = 0; index < keyCount; index++)
sl@0: 		{
sl@0: 		CKeyDetails* keyDetails = CKeyDetails::NewL(rootStream);
sl@0: 		iKeys.Append(keyDetails);
sl@0: 		}
sl@0: 	CleanupStack::PopAndDestroy(&rootStream);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  * This is a cleanup item that reverts the store.
sl@0:  */
sl@0: void CCryptoTokenHai::RevertStore(TAny* aStore)
sl@0: 	{
sl@0: 	CPermanentFileStore* store = reinterpret_cast<CPermanentFileStore*>(aStore);
sl@0: 	TRAP_IGNORE(store->RevertL());
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  * Compacts the store.
sl@0:  */
sl@0: void CCryptoTokenHai::CompactStore()
sl@0:     {
sl@0:     ASSERT(iFileStore);
sl@0:     TRAP_IGNORE(iFileStore->ReclaimL(); iFileStore->CompactL());
sl@0:     }
sl@0: 
sl@0: /**
sl@0:  * Populates the list of keys based on the input filter.
sl@0:  * 
sl@0:  * @param aFilter Set of conditions to be used to decide which keys 
sl@0:  * should be listed
sl@0:  * @param aKeys Output param. Contains the array of keys which fulfil 
sl@0:  * criteria mentioned in filter. Caller should take responsibility of 
sl@0:  * this array.
sl@0:  * 
sl@0:  * @leave Any of the system wide error codes.
sl@0:  * 
sl@0:  * @note Though Crypto Token HAI internally operates in CKeyDetails, 
sl@0:  * this function returns CCTKeyInfo array.
sl@0:  */
sl@0: EXPORT_C void CCryptoTokenHai::ListL(const TCTKeyAttributeFilter&  aFilter , 
sl@0:                 RPointerArray<CCTKeyInfo>& aKeys) const
sl@0:     {
sl@0:     TInt count = iKeys.Count();
sl@0:     for(TInt index = 0 ;index < count; ++ index)
sl@0:     	{
sl@0:     	const CKeyDetails* keyDetails = iKeys[index];
sl@0:     	
sl@0:     	if(KeyMatchesFilterL(*keyDetails,aFilter))
sl@0:     		{
sl@0: 			MCTAuthenticationObject* authObject = NULL;
sl@0: 			HBufC8* attribute = keyDetails->PKCS8AttributeSet().AllocLC();
sl@0: 			HBufC* label = keyDetails->Label().AllocLC();
sl@0: 			
sl@0: 			CCTKeyInfo* keyInfo = CCTKeyInfo::NewL(
sl@0: 					keyDetails->ID(),keyDetails->Usage(),keyDetails->Size(),
sl@0: 					authObject,label,iToken,keyDetails->Handle(),keyDetails->UsePolicy(),
sl@0: 					keyDetails->ManagementPolicy(),keyDetails->Algorithm(),keyDetails->AccessType(),
sl@0: 					keyDetails->Native(),keyDetails->StartDate(),keyDetails->EndDate(),attribute);
sl@0: 			
sl@0: 			CleanupStack::Pop(2, attribute); // label
sl@0: 			CleanupReleasePushL(*keyInfo);
sl@0: 						
sl@0: 			User::LeaveIfError(aKeys.Append(keyInfo));
sl@0: 			CleanupStack::Pop(keyInfo); 
sl@0: 			
sl@0: 			}
sl@0:     	}
sl@0:     	
sl@0:     }
sl@0: 
sl@0: /**
sl@0:  * Takes in a filter and key details and decides if key fulfils the 
sl@0:  * filter criteria.
sl@0:  * 
sl@0:  * @param aInfo The Key Details
sl@0:  * @param aFilter Filter specifying the conditions to be satisfied for 
sl@0:  * listing the keys.
sl@0:  * 
sl@0:  * @retval ETrue if key satisfies the conditions specified in filter
sl@0:  * @retval EFalse otherwise.
sl@0:  * 
sl@0:  * @leave KErrArgument If there is an issue in policy filter.
sl@0:  */
sl@0: TBool CCryptoTokenHai::KeyMatchesFilterL(const CKeyDetails& aInfo,
sl@0: 										   const TCTKeyAttributeFilter& aFilter) const
sl@0: 	{
sl@0: 		
sl@0: 	if (aFilter.iKeyId.Length() && aFilter.iKeyId != aInfo.ID())
sl@0: 		{
sl@0: 		return EFalse;
sl@0: 		}
sl@0: 
sl@0: 	if (aFilter.iUsage != EPKCS15UsageAll)
sl@0: 		{
sl@0: 		if ((aInfo.Usage() & aFilter.iUsage) == 0)
sl@0: 			return EFalse;
sl@0: 		}
sl@0: 
sl@0: 	if (aFilter.iKeyAlgorithm != CCTKeyInfo::EInvalidAlgorithm && 
sl@0: 		aFilter.iKeyAlgorithm != aInfo.Algorithm())
sl@0: 		{
sl@0: 		return EFalse;
sl@0: 		}
sl@0: 	
sl@0: 	switch (aFilter.iPolicyFilter)
sl@0: 		{
sl@0: 		case TCTKeyAttributeFilter::EAllKeys:
sl@0: 			// All keys pass
sl@0: 			break;
sl@0: 			   
sl@0: 		case TCTKeyAttributeFilter::EUsableKeys:
sl@0: 			if (!aInfo.UsePolicy().CheckPolicy(RThread()))
sl@0: 				{
sl@0: 				return EFalse;
sl@0: 				}
sl@0: 			break;
sl@0: 		case TCTKeyAttributeFilter::EManageableKeys:
sl@0: 			// As this key store implementation is a hardware simulation,
sl@0: 			// the support for managing through software interface has been diabled.
sl@0: 			return EFalse;
sl@0: 
sl@0: 		case TCTKeyAttributeFilter::EUsableOrManageableKeys:
sl@0: 			if (!aInfo.UsePolicy().CheckPolicy(RThread()) &&
sl@0: 				!aInfo.ManagementPolicy().CheckPolicy(RThread()))
sl@0: 				{
sl@0: 				return EFalse;
sl@0: 				}
sl@0: 			break;
sl@0: 						
sl@0: 		default:
sl@0: 			User::Leave(KErrArgument);
sl@0: 		}
sl@0: 
sl@0: 	return ETrue;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: