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