cryptoservices/filebasedcertificateandkeystores/test/tcryptotokenhai/tcryptotokenhai.cpp
changeset 15 da2ae96f639b
child 19 cd501b96611d
equal deleted inserted replaced
10:afc583cfa176 15:da2ae96f639b
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 * This class implements the reference Crypto Token Hardware Abstraction 
       
    16 * Interface (HAI). It is just intended to show how operations using 
       
    17 * device keys can be performed using crypto token framework. In the 
       
    18 * real world scenario, this HAI should be replaced by device drivers 
       
    19 * by the licensees. In such a case, all the operations performed by 
       
    20 * the replacing class would be performed in Kernel Space.
       
    21 *
       
    22 */
       
    23 
       
    24 
       
    25 #include "tcryptotokenhai.h"
       
    26 #include "tkeydetails.h"
       
    27 #include "cryptosignatureapi.h"
       
    28 #include "keys.h"
       
    29 
       
    30 #include <cryptospi/cryptoparams.h>
       
    31 #include <cryptospi/cryptospidef.h>
       
    32 
       
    33 EXPORT_C CCryptoTokenHai* CCryptoTokenHai::NewLC(MCTToken* aToken)
       
    34 	{
       
    35 	CCryptoTokenHai* instance = new(ELeave) CCryptoTokenHai(*aToken);
       
    36 	CleanupStack::PushL(instance);
       
    37 	instance->ConstructL();
       
    38 	return instance;
       
    39 	}
       
    40 
       
    41 EXPORT_C CCryptoTokenHai* CCryptoTokenHai::NewL(MCTToken* aToken)
       
    42 	{
       
    43 	CCryptoTokenHai* instance = CCryptoTokenHai::NewLC(aToken);
       
    44 	CleanupStack::Pop(instance);
       
    45 	return instance;
       
    46 	}
       
    47 
       
    48 void CCryptoTokenHai::ConstructL()
       
    49 	{
       
    50 	User::LeaveIfError(iFs.Connect());
       
    51 	OpenStoreL();
       
    52 	}
       
    53 
       
    54 CCryptoTokenHai::CCryptoTokenHai(MCTToken& aToken)
       
    55 	:iToken(aToken)
       
    56 	{}
       
    57 
       
    58 EXPORT_C CCryptoTokenHai::~CCryptoTokenHai()
       
    59 	{
       
    60 	if(iFileStore)
       
    61         {
       
    62         CompactStore();
       
    63         delete iFileStore;
       
    64         }
       
    65 	
       
    66 	iFs.Close();
       
    67 	iKeys.ResetAndDestroy();
       
    68     iKeys.Close();
       
    69 	}
       
    70 
       
    71 /**
       
    72  * Performs the decryption operation.
       
    73  * 
       
    74  * This API gets called when the decryption is supposed to be done in  
       
    75  * the hardware.
       
    76  * 
       
    77  * @param aHandle The key handle
       
    78  * @param aCiphertext The cipher text. This is not being used presently 
       
    79  * due to decryption logic used in this function.
       
    80  * @param aPlainText Output param. The decrypted plain text. Ownership 
       
    81  * of the pointer lies with the caller.
       
    82  * 
       
    83  * @leave This function can leave with following error codes:-
       
    84  * - KErrNotFound - If the key corresponding to given handle is not 
       
    85  * found.
       
    86  * - Any other error code returned by AllocL().
       
    87  *
       
    88  * @note This function does not actually implement ECC decryption. It 
       
    89  * just intends to show that the key is with this class and it can 
       
    90  * do actual ECC decryption here. This function just returns the 
       
    91  * private key as decrypted text. The caller can verify the decryption 
       
    92  * by ensuring that test case has same public and private keys and then 
       
    93  * comparing the decrypted text with public key. 
       
    94  */
       
    95 EXPORT_C void CCryptoTokenHai::DecryptL(	TInt aHandle,	
       
    96 											const TDesC8& /* aCiphertext */,
       
    97 											HBufC8*& aPlainText )
       
    98 	{
       
    99     TInt keyIndex = KeyPresent(aHandle);
       
   100     if(keyIndex == KErrNotFound)
       
   101         {
       
   102         User::Leave(KErrNotFound);
       
   103         }
       
   104     
       
   105     ExportPrivateKeyL(aHandle, aPlainText);
       
   106 	}
       
   107 
       
   108 /**
       
   109  * Performs the signing operation.
       
   110  * 
       
   111  * This API gets called when the signing is supposed to be done inside 
       
   112  * the hardware.
       
   113  * 
       
   114  * @param aHandle The key handle
       
   115  * @param aPlaintext The text which has to be signed. This is not being 
       
   116  * used due to signing logic used in this function.
       
   117  * @param aSignature Output param. The signature in HBufC8 format.  
       
   118  * Ownership of the pointer lies with the caller. This should be 
       
   119  * converted to CCryptoParams by the crypto token reference plugin. 
       
   120  * 
       
   121  * @leave This function can leave with following error codes:-
       
   122  * - KErrNotFound - If the key corresponding to given handle is not 
       
   123  * found.
       
   124  * - Any other error code returned by AllocL().
       
   125  * 
       
   126  * @note This function does not actually implement ECC signing. It 
       
   127  * just intends to show that the key is with this class and it can 
       
   128  * do actual ECC signing here. Currently this function just returns 
       
   129  * the private key as output signature. The caller can verify the 
       
   130  * signature by ensuring that test case has same public and private 
       
   131  * keys and then comparing the signature with public key.
       
   132  */
       
   133 EXPORT_C void CCryptoTokenHai::SignL( 	TInt aHandle,
       
   134 										const TDesC8& /* aPlaintext */,
       
   135 										HBufC8*& aSignature )
       
   136 	{
       
   137 	TInt keyIndex = KeyPresent(aHandle);
       
   138 	if(keyIndex == KErrNotFound)
       
   139 	    {
       
   140 	    User::Leave(KErrNotFound);
       
   141 	    }
       
   142 	
       
   143 	ExportPrivateKeyL(aHandle, aSignature);
       
   144 	}
       
   145 
       
   146 /**
       
   147  * Returns the index of the key whose handle is given.
       
   148  * 
       
   149  * @param aHandle Handle of the key. This is used to search the key.
       
   150  * 
       
   151  * @return index of the key if search is successful, KErrNotFound 
       
   152  * otherwise.
       
   153  */
       
   154 EXPORT_C TInt CCryptoTokenHai::KeyPresent( TInt aHandle )
       
   155 	{
       
   156 	int keysCount = iKeys.Count();
       
   157 	for(TInt i=0; i < keysCount; ++i)
       
   158 		{
       
   159 		if(iKeys[i]->Handle() == aHandle)
       
   160 			{
       
   161 			return i;
       
   162 			}
       
   163 		}
       
   164 	return KErrNotFound;
       
   165 	}
       
   166 
       
   167 /**
       
   168  * Extracts the private key.
       
   169  * 
       
   170  * @param aHandle Handle of the private key to be extracted.
       
   171  * @param aKey Output Parameter. Stores the private key on success. 
       
   172  * Ownership of pointer is with the caller.
       
   173  * 
       
   174  * @leave Following leave codes possible:-
       
   175  * - Any leave code returned by AllocL().
       
   176  * - KErrNotFound - If key corresponding to the given handle is not 
       
   177  * found.
       
   178  * 
       
   179  * @note In the actual implementation, licensees should ensure that 
       
   180  * this function can be called only in Kernel space. In the reference 
       
   181  * implementation, this function gets called only by CCryptoSpiHai, 
       
   182  * which is assumed to operate in kernel space. This would ensure that 
       
   183  * the private key always stays inside the hardware.
       
   184  */
       
   185 EXPORT_C void CCryptoTokenHai::ExportPrivateKeyL( TInt aHandle, HBufC8*& aKey )
       
   186 	{
       
   187 	int keysCount = iKeys.Count();
       
   188 	for(int i = 0; i < keysCount; ++i)
       
   189 		{
       
   190 		if(iKeys[i]->Handle() == aHandle)
       
   191 			{
       
   192 			aKey = iKeys[i]->PrivateKey()->AllocL();
       
   193 			return;
       
   194 			}
       
   195 		}
       
   196 	User::Leave(KErrNotFound);
       
   197 	}
       
   198 
       
   199 /**
       
   200  * Extracts the public key.
       
   201  * 
       
   202  * @param aHandle Handle of the public key to be extracted.
       
   203  * @param aKey Output Parameter. Stores the public key on success.
       
   204  * Ownership of pointer is with the caller.
       
   205  * 
       
   206  * @leave Following leave codes possible:-
       
   207  * - Any leave code returned by AllocL().
       
   208  * - KErrNotFound - If key corresponding to the given handle is not 
       
   209  * found.
       
   210  */
       
   211 EXPORT_C void CCryptoTokenHai::ExportPublicKeyL( TInt aHandle, HBufC8*& aKey )
       
   212     {
       
   213     int keysCount = iKeys.Count();
       
   214     for(int i = 0; i < keysCount; ++i)
       
   215         {
       
   216         if(iKeys[i]->Handle() == aHandle)
       
   217             {
       
   218             aKey = iKeys[i]->PublicKey()->AllocL();
       
   219             return;
       
   220             }
       
   221         }
       
   222     User::Leave(KErrNotFound);
       
   223     }
       
   224 
       
   225 /**
       
   226  * Stores the key with given details.
       
   227  * 
       
   228  * @param aLabel Label of the key.
       
   229  * @param aPrivateKey Private component of the key.
       
   230  * @param aPublicKey Public component of the key.
       
   231  * 
       
   232  * @leave Following leave codes possible:-
       
   233  * - KErrAlreadyExists If there is already a key with the inputted
       
   234  * label.
       
   235  * - Any other leave code returned by NewL() or AppendL().
       
   236  *  
       
   237  * @note In the present reference implementation this function is not 
       
   238  * being used, since device keys are pre-provisioned by the licensees. 
       
   239  * Hence licensees may decide not to implement this function in their 
       
   240  * real implementation. 
       
   241  */
       
   242 EXPORT_C void CCryptoTokenHai::ImportKeyL(const TDesC& aLabel, 
       
   243         const TDesC8& aPrivateKey, const TDesC8& aPublicKey)
       
   244 	{
       
   245 	int keysCount = iKeys.Count();
       
   246 	for(int i = 0; i < keysCount; ++i)
       
   247 		{
       
   248 		if(iKeys[i]->Label() == aLabel)
       
   249 			{
       
   250 			User::Leave(KErrAlreadyExists);
       
   251 			}
       
   252 		}
       
   253 	CKeyDetails* keyDetails = CKeyDetails::NewL(keysCount+1,aLabel,aPrivateKey,aPublicKey);
       
   254 	iKeys.AppendL(keyDetails);
       
   255 	}
       
   256 
       
   257 /**
       
   258  * Populates the string containing full RAM path of file containing 
       
   259  * keys.
       
   260  */
       
   261 void CCryptoTokenHai::MakePrivateFilenameL(RFs& aFs, const TDesC& aLeafName, TDes& aNameOut)
       
   262     {
       
   263     aNameOut.SetLength(0);  
       
   264     aNameOut.Append(RFs::GetSystemDriveChar());
       
   265 
       
   266     aNameOut.Append(':');
       
   267 
       
   268     // Get private path
       
   269     TBuf<20> privatePath;
       
   270     User::LeaveIfError(aFs.PrivatePath(privatePath));
       
   271     aNameOut.Append(privatePath);
       
   272     
       
   273     aNameOut.Append(aLeafName);
       
   274     }
       
   275 
       
   276 /**
       
   277  * Creates the corresponding directory, if it does not exist.
       
   278  */
       
   279 void CCryptoTokenHai::EnsurePathL(RFs& aFs, const TDesC& aFile)
       
   280     {
       
   281     TInt err = aFs.MkDirAll(aFile);
       
   282     if (err != KErrNone && err != KErrAlreadyExists)
       
   283         {
       
   284         User::Leave(err);
       
   285         }
       
   286     }
       
   287 
       
   288 /**
       
   289  * Populates the string containing full ROM path of the keys file.
       
   290  */
       
   291 void CCryptoTokenHai::MakePrivateROMFilenameL(RFs& aFs, const TDesC& aLeafName, TDes& aNameOut)
       
   292     {
       
   293     _LIT(KFileStoreROMDrive, "Z:");
       
   294     
       
   295     aNameOut.Copy(KFileStoreROMDrive);
       
   296 
       
   297     // Get private path
       
   298     TBuf<20> privatePath;
       
   299     User::LeaveIfError(aFs.PrivatePath(privatePath)); 
       
   300     aNameOut.Append(privatePath);
       
   301     aNameOut.Append(aLeafName);
       
   302     }
       
   303 
       
   304 /**
       
   305  * Copies the contents of source file to destination file.
       
   306  * 
       
   307  * This is typically used to copy the keys file from ROM to RAM.
       
   308  */
       
   309 void CCryptoTokenHai::CopyL(RFs& aFs, const TDesC& aSouce, const TDesC& aDest)
       
   310     {
       
   311     RFileReadStream in;
       
   312     User::LeaveIfError(in.Open(aFs, aSouce, EFileRead | EFileShareReadersOnly));
       
   313     CleanupClosePushL(in);
       
   314 
       
   315     RFileWriteStream out;
       
   316     User::LeaveIfError(out.Replace(aFs, aDest, EFileWrite | EFileShareExclusive));
       
   317     CleanupClosePushL(out);
       
   318 
       
   319     in.ReadL(out);  
       
   320     CleanupStack::PopAndDestroy(2, &in);
       
   321     }
       
   322 
       
   323 /**
       
   324  * Keys corresponding to this store are present in hwkeys.dat. 
       
   325  * In the production code written by licensees, this would be the path 
       
   326  * where device keys are stored.
       
   327  */
       
   328 _LIT(KKeyStoreFilename,"hwkeys.dat");
       
   329 
       
   330 /**
       
   331  * Opens a store containing hardware keys.
       
   332  * 
       
   333  * This function uses the following logic to open the store:-
       
   334  * -# Try to open the store from the private directory.
       
   335  * -# If this fails copy the file from ROM to RAM.
       
   336  * -# If both fail, create your own keys store from scratch.
       
   337  */
       
   338 void CCryptoTokenHai::OpenStoreL()
       
   339 	{
       
   340 	TFileName fullPath;
       
   341 	MakePrivateFilenameL(iFs, KKeyStoreFilename, fullPath);
       
   342 
       
   343 	EnsurePathL(iFs, fullPath);
       
   344 	TRAPD(result, OpenStoreInFileL(fullPath));
       
   345 
       
   346 	if (result == KErrInUse  ) 
       
   347 		{		
       
   348 		// Cannot access the file now. Abort rather than wiping the keystore.
       
   349 		User::Leave(result); 
       
   350 		}
       
   351 	
       
   352 	if (result != KErrNone )
       
   353 		{		
       
   354 		/*
       
   355 		 * Not yet opened a valid store, either no file to be found, or 
       
   356 		 * no valid store in it. Copy the original one stored in the 
       
   357 		 * ROM.
       
   358 		 */
       
   359 		TRAPD(result2, CopyStoreFromROML(fullPath, result));
       
   360 				
       
   361 		if (KErrNone != result2)
       
   362 			{
       
   363 			/*
       
   364 			 * We tried to copy the keystore from ROM. For some reason this
       
   365 			 * failed and we still cannot open the file. Create a new one from
       
   366 			 * scratch.
       
   367 			 */ 
       
   368 			CreateStoreInFileL(fullPath);
       
   369 			}
       
   370 		}
       
   371 
       
   372 	}
       
   373 
       
   374 /**
       
   375  * Copies the key store file from ROM to RAM.
       
   376  */
       
   377 void CCryptoTokenHai::CopyStoreFromROML(const TDesC& fullPath, TInt result)
       
   378     {
       
   379     if (result != KErrNotFound)
       
   380         {
       
   381         // Wipe the keystore if we can't open it (it's corrupt anyway)
       
   382         User::LeaveIfError(iFs.Delete(fullPath));
       
   383         }
       
   384 
       
   385     TFileName romPath;
       
   386     MakePrivateROMFilenameL(iFs, KKeyStoreFilename, romPath);
       
   387 
       
   388     // Copy data from rom and open it   
       
   389     CopyL(iFs, romPath, fullPath);
       
   390     OpenStoreInFileL(fullPath);
       
   391     }
       
   392 
       
   393 /**
       
   394  * Opens a store from the given file.
       
   395  */
       
   396 void CCryptoTokenHai::OpenStoreInFileL(const TDesC& aFile)
       
   397 	{
       
   398 	RFile file;
       
   399 	User::LeaveIfError(file.Open(iFs, aFile, EFileRead | EFileWrite | EFileShareAny));
       
   400 	CleanupClosePushL(file);
       
   401     delete iFileStore;
       
   402     iFileStore = NULL;
       
   403 
       
   404 	iFileStore = CPermanentFileStore::FromL(file);
       
   405     // iFileStore takes ownership of file now
       
   406 	CleanupStack::Pop(&file);
       
   407 	
       
   408     // Get the salt, root and manager TStreamIds
       
   409     iRootStreamId = iFileStore->Root();
       
   410     if (iRootStreamId == KNullStreamId)
       
   411         {
       
   412         User::Leave(KErrCorrupt);
       
   413         }
       
   414     RStoreReadStream rootStream;
       
   415     rootStream.OpenLC(*iFileStore, iRootStreamId);
       
   416     ReadKeysFromStoreL();
       
   417     CleanupStack::PopAndDestroy(&rootStream);
       
   418     }
       
   419 
       
   420 /**
       
   421  * Creates a keys store in RAM from scratch.
       
   422  * 
       
   423  * @note This function should never get called as hwkeys.dat should be 
       
   424  * always present in ROM. If this function somehow gets called, it 
       
   425  * will create a hwkeys.dat file from scratch. However, this file would 
       
   426  * not contain any keys and tests would not pass.
       
   427  */
       
   428 void CCryptoTokenHai::CreateStoreInFileL(const TDesC& aFile)
       
   429 	{
       
   430 	TInt r = iFs.MkDirAll(aFile);
       
   431 	if ( (r!=KErrNone) && (r!=KErrAlreadyExists) )
       
   432 		User::Leave(r);
       
   433 
       
   434     delete iFileStore;
       
   435     iFileStore = NULL;
       
   436 	iFileStore = CPermanentFileStore::ReplaceL(iFs, aFile, EFileRead | EFileWrite | EFileShareExclusive);
       
   437 	iFileStore->SetTypeL(KPermanentFileStoreLayoutUid);
       
   438 
       
   439 	TCleanupItem cleanupStore(RevertStore, iFileStore);
       
   440 	CleanupStack::PushL(cleanupStore);
       
   441 	
       
   442 	// Create root stream - just contains id of info stream
       
   443 	RStoreWriteStream rootStream;
       
   444 	iRootStreamId = rootStream.CreateLC(*iFileStore);
       
   445 	iFileStore->SetRootL(iRootStreamId);
       
   446 	WriteKeysToStoreL(rootStream);
       
   447 	iFileStore->CommitL();
       
   448 	CleanupStack::PopAndDestroy(&rootStream);
       
   449 	CleanupStack::Pop(); // cleanupStore
       
   450 	}
       
   451 
       
   452 /**
       
   453  * Copies the keys stored in the instance to inputted write stream.
       
   454  * 
       
   455  * This invokes the CKeyDetails::ExternalizeL() function.
       
   456  */
       
   457 void CCryptoTokenHai::WriteKeysToStoreL(RStoreWriteStream& aRootStream)
       
   458 	{
       
   459 	TInt keyCount = iKeys.Count();
       
   460 	aRootStream.WriteInt32L(keyCount);
       
   461 
       
   462 	for (TInt index = 0; index < keyCount; index++)
       
   463 		{
       
   464 		aRootStream << *iKeys[index];
       
   465 		}
       
   466 	aRootStream.CommitL();
       
   467 	}
       
   468 
       
   469 /**
       
   470  * Copies the keys present in the read store to instance of class.
       
   471  * 
       
   472  * This eventually invokes the CKeyDetails::InternalizeL() function.
       
   473  */
       
   474 void CCryptoTokenHai::ReadKeysFromStoreL()
       
   475 	{
       
   476 	RStoreReadStream rootStream;
       
   477 	
       
   478 	rootStream.OpenLC(*iFileStore, iRootStreamId);
       
   479 	TInt keyCount = rootStream.ReadInt32L();
       
   480 
       
   481 	for (TInt index = 0; index < keyCount; index++)
       
   482 		{
       
   483 		CKeyDetails* keyDetails = CKeyDetails::NewL(rootStream);
       
   484 		iKeys.Append(keyDetails);
       
   485 		}
       
   486 	CleanupStack::PopAndDestroy(&rootStream);
       
   487 	}
       
   488 
       
   489 /**
       
   490  * This is a cleanup item that reverts the store.
       
   491  */
       
   492 void CCryptoTokenHai::RevertStore(TAny* aStore)
       
   493 	{
       
   494 	CPermanentFileStore* store = reinterpret_cast<CPermanentFileStore*>(aStore);
       
   495 	TRAP_IGNORE(store->RevertL());
       
   496 	}
       
   497 
       
   498 /**
       
   499  * Compacts the store.
       
   500  */
       
   501 void CCryptoTokenHai::CompactStore()
       
   502     {
       
   503     ASSERT(iFileStore);
       
   504     TRAP_IGNORE(iFileStore->ReclaimL(); iFileStore->CompactL());
       
   505     }
       
   506 
       
   507 /**
       
   508  * Populates the list of keys based on the input filter.
       
   509  * 
       
   510  * @param aFilter Set of conditions to be used to decide which keys 
       
   511  * should be listed
       
   512  * @param aKeys Output param. Contains the array of keys which fulfil 
       
   513  * criteria mentioned in filter. Caller should take responsibility of 
       
   514  * this array.
       
   515  * 
       
   516  * @leave Any of the system wide error codes.
       
   517  * 
       
   518  * @note Though Crypto Token HAI internally operates in CKeyDetails, 
       
   519  * this function returns CCTKeyInfo array.
       
   520  */
       
   521 EXPORT_C void CCryptoTokenHai::ListL(const TCTKeyAttributeFilter&  aFilter , 
       
   522                 RPointerArray<CCTKeyInfo>& aKeys) const
       
   523     {
       
   524     TInt count = iKeys.Count();
       
   525     for(TInt index = 0 ;index < count; ++ index)
       
   526     	{
       
   527     	const CKeyDetails* keyDetails = iKeys[index];
       
   528     	
       
   529     	if(KeyMatchesFilterL(*keyDetails,aFilter))
       
   530     		{
       
   531 			MCTAuthenticationObject* authObject = NULL;
       
   532 			HBufC8* attribute = keyDetails->PKCS8AttributeSet().AllocLC();
       
   533 			HBufC* label = keyDetails->Label().AllocLC();
       
   534 			
       
   535 			CCTKeyInfo* keyInfo = CCTKeyInfo::NewL(
       
   536 					keyDetails->ID(),keyDetails->Usage(),keyDetails->Size(),
       
   537 					authObject,label,iToken,keyDetails->Handle(),keyDetails->UsePolicy(),
       
   538 					keyDetails->ManagementPolicy(),keyDetails->Algorithm(),keyDetails->AccessType(),
       
   539 					keyDetails->Native(),keyDetails->StartDate(),keyDetails->EndDate(),attribute);
       
   540 			
       
   541 			CleanupStack::Pop(2, attribute); // label
       
   542 			CleanupReleasePushL(*keyInfo);
       
   543 						
       
   544 			User::LeaveIfError(aKeys.Append(keyInfo));
       
   545 			CleanupStack::Pop(keyInfo); 
       
   546 			
       
   547 			}
       
   548     	}
       
   549     	
       
   550     }
       
   551 
       
   552 /**
       
   553  * Takes in a filter and key details and decides if key fulfils the 
       
   554  * filter criteria.
       
   555  * 
       
   556  * @param aInfo The Key Details
       
   557  * @param aFilter Filter specifying the conditions to be satisfied for 
       
   558  * listing the keys.
       
   559  * 
       
   560  * @retval ETrue if key satisfies the conditions specified in filter
       
   561  * @retval EFalse otherwise.
       
   562  * 
       
   563  * @leave KErrArgument If there is an issue in policy filter.
       
   564  */
       
   565 TBool CCryptoTokenHai::KeyMatchesFilterL(const CKeyDetails& aInfo,
       
   566 										   const TCTKeyAttributeFilter& aFilter) const
       
   567 	{
       
   568 		
       
   569 	if (aFilter.iKeyId.Length() && aFilter.iKeyId != aInfo.ID())
       
   570 		{
       
   571 		return EFalse;
       
   572 		}
       
   573 
       
   574 	if (aFilter.iUsage != EPKCS15UsageAll)
       
   575 		{
       
   576 		if ((aInfo.Usage() & aFilter.iUsage) == 0)
       
   577 			return EFalse;
       
   578 		}
       
   579 
       
   580 	if (aFilter.iKeyAlgorithm != CCTKeyInfo::EInvalidAlgorithm && 
       
   581 		aFilter.iKeyAlgorithm != aInfo.Algorithm())
       
   582 		{
       
   583 		return EFalse;
       
   584 		}
       
   585 	
       
   586 	switch (aFilter.iPolicyFilter)
       
   587 		{
       
   588 		case TCTKeyAttributeFilter::EAllKeys:
       
   589 			// All keys pass
       
   590 			break;
       
   591 			   
       
   592 		case TCTKeyAttributeFilter::EUsableKeys:
       
   593 			if (!aInfo.UsePolicy().CheckPolicy(RThread()))
       
   594 				{
       
   595 				return EFalse;
       
   596 				}
       
   597 			break;
       
   598 			
       
   599 		case TCTKeyAttributeFilter::EManageableKeys:
       
   600 			if (!aInfo.ManagementPolicy().CheckPolicy(RThread()))
       
   601 				{
       
   602 				return EFalse;
       
   603 				}
       
   604 			break;
       
   605 
       
   606 		case TCTKeyAttributeFilter::EUsableOrManageableKeys:
       
   607 			if (!aInfo.UsePolicy().CheckPolicy(RThread()) &&
       
   608 				!aInfo.ManagementPolicy().CheckPolicy(RThread()))
       
   609 				{
       
   610 				return EFalse;
       
   611 				}
       
   612 			break;
       
   613 						
       
   614 		default:
       
   615 			User::Leave(KErrArgument);
       
   616 		}
       
   617 
       
   618 	return ETrue;
       
   619 	}
       
   620 
       
   621 
       
   622