os/security/crypto/weakcryptospi/source/spi/cryptospisetup/cryptopluginsloader.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) 2007-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
* crypto plugins loader implementation
sl@0
    16
* crypto spi state implementation
sl@0
    17
*
sl@0
    18
*/
sl@0
    19
sl@0
    20
sl@0
    21
/**
sl@0
    22
 @file
sl@0
    23
*/
sl@0
    24
#include "cryptopluginsloader.h"
sl@0
    25
#include <f32file.h>
sl@0
    26
#include <cryptospi/cryptospidef.h>
sl@0
    27
#include "cryptospiproperty.h"
sl@0
    28
#include <e32property.h>
sl@0
    29
sl@0
    30
using namespace CryptoSpi;
sl@0
    31
sl@0
    32
_LIT(KPluginDir, "z:\\sys\\bin\\");
sl@0
    33
sl@0
    34
HBufC *GetConfigFileNameL();
sl@0
    35
sl@0
    36
//
sl@0
    37
// Implementation of TCharacteristicsDll
sl@0
    38
//
sl@0
    39
TCharacteristicsDll::TCharacteristicsDll(const TAny* aCharacteristics, TInt aIndex)
sl@0
    40
:iCharacteristics(aCharacteristics), iDllIndex(aIndex)
sl@0
    41
	{
sl@0
    42
	}
sl@0
    43
sl@0
    44
void TCharacteristicsDll::ExternalizeL(RWriteStream& aStream)
sl@0
    45
	{
sl@0
    46
	const TCommonCharacteristics* common=reinterpret_cast<const TCommonCharacteristics*>(iCharacteristics);
sl@0
    47
	switch (common->iInterfaceUID)
sl@0
    48
		{
sl@0
    49
	case KHashInterface:
sl@0
    50
	case KAsyncHashInterface:
sl@0
    51
		{
sl@0
    52
		const THashCharacteristics* characteristics=reinterpret_cast<const THashCharacteristics*>(iCharacteristics);
sl@0
    53
		characteristics->ExternalizeL(aStream);
sl@0
    54
		}
sl@0
    55
		break;
sl@0
    56
	case KRandomInterface:
sl@0
    57
	case KAsyncRandomInterface:
sl@0
    58
		{
sl@0
    59
		const TRandomCharacteristics* characteristics=reinterpret_cast<const TRandomCharacteristics*>(iCharacteristics);
sl@0
    60
		characteristics->ExternalizeL(aStream);		
sl@0
    61
		}
sl@0
    62
		break;
sl@0
    63
sl@0
    64
	case KSymmetricCipherInterface:
sl@0
    65
	case KAsyncSymmetricCipherInterface:
sl@0
    66
		{
sl@0
    67
		const TSymmetricCipherCharacteristics* characteristics=reinterpret_cast<const TSymmetricCipherCharacteristics*>(iCharacteristics);
sl@0
    68
		characteristics->ExternalizeL(aStream);		
sl@0
    69
		}
sl@0
    70
		break;
sl@0
    71
sl@0
    72
	case KAsymmetricCipherInterface:
sl@0
    73
	case KAsyncAsymmetricCipherInterface:
sl@0
    74
		{
sl@0
    75
		const TAsymmetricCipherCharacteristics* characteristics=reinterpret_cast<const TAsymmetricCipherCharacteristics*>(iCharacteristics);
sl@0
    76
		characteristics->ExternalizeL(aStream);		
sl@0
    77
		}
sl@0
    78
		break;
sl@0
    79
sl@0
    80
	case KSignerInterface:
sl@0
    81
	case KVerifierInterface:
sl@0
    82
	case KAsyncSignerInterface:
sl@0
    83
	case KAsyncVerifierInterface:
sl@0
    84
		{
sl@0
    85
		const TAsymmetricSignatureCharacteristics* characteristics=reinterpret_cast<const TAsymmetricSignatureCharacteristics*>(iCharacteristics);
sl@0
    86
		characteristics->ExternalizeL(aStream);		
sl@0
    87
		}
sl@0
    88
		break;
sl@0
    89
	
sl@0
    90
	case KKeyAgreementInterface:
sl@0
    91
	case KAsyncKeyAgreementInterface:
sl@0
    92
		{
sl@0
    93
		const TKeyAgreementCharacteristics* characteristics=reinterpret_cast<const TKeyAgreementCharacteristics*>(iCharacteristics);
sl@0
    94
		characteristics->ExternalizeL(aStream);
sl@0
    95
		}
sl@0
    96
		break;
sl@0
    97
sl@0
    98
	case KKeypairGeneratorInterface:
sl@0
    99
	case KAsyncKeypairGeneratorInterface:
sl@0
   100
		{
sl@0
   101
		const TAsymmetricKeypairGeneratorCharacteristics* characteristics=reinterpret_cast<const TAsymmetricKeypairGeneratorCharacteristics*>(iCharacteristics);
sl@0
   102
		characteristics->ExternalizeL(aStream);
sl@0
   103
		}
sl@0
   104
		break;
sl@0
   105
#ifdef SYMBIAN_SDP_IPSEC_VOIP_SUPPORT			
sl@0
   106
	case KMacInterface:
sl@0
   107
	case KAsyncMacInterface:
sl@0
   108
		{
sl@0
   109
		const TMacCharacteristics* characteristics=reinterpret_cast<const TMacCharacteristics*>(iCharacteristics);
sl@0
   110
		characteristics->ExternalizeL(aStream);
sl@0
   111
		}
sl@0
   112
		break;
sl@0
   113
#endif		
sl@0
   114
	default:
sl@0
   115
		User::Leave(KErrNotSupported); 
sl@0
   116
		}
sl@0
   117
		
sl@0
   118
	aStream.WriteInt8L(iDllIndex);
sl@0
   119
	}
sl@0
   120
sl@0
   121
//
sl@0
   122
// Implementation of CCharacteristicDllIndexList
sl@0
   123
//
sl@0
   124
CCharacteristicDllIndexList* CCharacteristicDllIndexList::NewL()
sl@0
   125
	{
sl@0
   126
	CCharacteristicDllIndexList* self=new(ELeave) CCharacteristicDllIndexList();
sl@0
   127
	return self;
sl@0
   128
	}
sl@0
   129
sl@0
   130
CCharacteristicDllIndexList* CCharacteristicDllIndexList::NewLC()
sl@0
   131
	{
sl@0
   132
	CCharacteristicDllIndexList* self=new(ELeave) CCharacteristicDllIndexList();
sl@0
   133
	CleanupStack::PushL(self);
sl@0
   134
	return self;		
sl@0
   135
	}
sl@0
   136
sl@0
   137
CCharacteristicDllIndexList::CCharacteristicDllIndexList()
sl@0
   138
	{
sl@0
   139
	}
sl@0
   140
sl@0
   141
CCharacteristicDllIndexList::~CCharacteristicDllIndexList()
sl@0
   142
	{
sl@0
   143
	iCharacteristicList.Close();	
sl@0
   144
	}
sl@0
   145
sl@0
   146
void CCharacteristicDllIndexList::ExternalizeL(RWriteStream& aStream)
sl@0
   147
	{
sl@0
   148
	TInt count=iCharacteristicList.Count();
sl@0
   149
	aStream.WriteInt16L(count);
sl@0
   150
	for (TInt i=0;i<count;i++)
sl@0
   151
		{
sl@0
   152
		iCharacteristicList[i].ExternalizeL(aStream);
sl@0
   153
		}
sl@0
   154
	}
sl@0
   155
sl@0
   156
//
sl@0
   157
// Implementation of CCryptoPluginsLoader
sl@0
   158
//
sl@0
   159
CCryptoPluginsLoader* CCryptoPluginsLoader::NewL()
sl@0
   160
	{
sl@0
   161
	CCryptoPluginsLoader* self=NewLC();
sl@0
   162
	CleanupStack::Pop(self);
sl@0
   163
	return self;
sl@0
   164
	}
sl@0
   165
sl@0
   166
CCryptoPluginsLoader* CCryptoPluginsLoader::NewLC()
sl@0
   167
	{
sl@0
   168
	CCryptoPluginsLoader* self=new(ELeave)CCryptoPluginsLoader();
sl@0
   169
	CleanupStack::PushL(self);
sl@0
   170
	self->ConstructL();
sl@0
   171
	return self;
sl@0
   172
	}
sl@0
   173
	
sl@0
   174
CCryptoPluginsLoader::CCryptoPluginsLoader()
sl@0
   175
	{
sl@0
   176
	}
sl@0
   177
sl@0
   178
CCryptoPluginsLoader::~CCryptoPluginsLoader()
sl@0
   179
	{
sl@0
   180
	//Destroy the characteristic map
sl@0
   181
	THashMapIter<TInt32, CCharacteristicDllIndexList*> it(iInterfaceCharacteristicsMap);
sl@0
   182
	it.NextValue();
sl@0
   183
	while (it.CurrentValue())
sl@0
   184
		{
sl@0
   185
		delete *it.CurrentValue();
sl@0
   186
		it.NextValue();
sl@0
   187
		}
sl@0
   188
	iInterfaceCharacteristicsMap.Close();
sl@0
   189
sl@0
   190
	//Unload the plugin DLLs and release the array
sl@0
   191
	TInt dllCount=iPluginDllList.Count();
sl@0
   192
	for (TInt i=0;i<dllCount;i++)
sl@0
   193
		{
sl@0
   194
		iPluginDllList[i].Close();	
sl@0
   195
		}
sl@0
   196
	iPluginDllList.Close();
sl@0
   197
	iPluginNames.Close();
sl@0
   198
	}
sl@0
   199
sl@0
   200
void CCryptoPluginsLoader::ConstructL()
sl@0
   201
	{
sl@0
   202
	LoadPluginsL();
sl@0
   203
	}
sl@0
   204
sl@0
   205
void CCryptoPluginsLoader::LoadPluginsL()
sl@0
   206
	{
sl@0
   207
	HBufC *configFileBuf = GetConfigFileNameL();
sl@0
   208
	CleanupStack::PushL(configFileBuf);
sl@0
   209
	TPtr configFile(configFileBuf->Des());
sl@0
   210
sl@0
   211
	RFs fs;
sl@0
   212
	User::LeaveIfError(fs.Connect());
sl@0
   213
	CleanupClosePushL(fs);
sl@0
   214
sl@0
   215
	RFile file;
sl@0
   216
	User::LeaveIfError(file.Open(fs, configFile, KEntryAttNormal));
sl@0
   217
	CleanupClosePushL(file);
sl@0
   218
sl@0
   219
	TFileText ft;
sl@0
   220
	ft.Set(file);
sl@0
   221
	TFileName line;
sl@0
   222
	
sl@0
   223
	User::LeaveIfError(ft.Read(line));
sl@0
   224
		
sl@0
   225
	//Load all the plugins
sl@0
   226
	do
sl@0
   227
		{	
sl@0
   228
		TFileName filename;
sl@0
   229
		filename.Append(KPluginDir);
sl@0
   230
		filename.Append(line);
sl@0
   231
sl@0
   232
		//Load...
sl@0
   233
		RLibrary plugin;
sl@0
   234
		TInt err=plugin.Load(filename);
sl@0
   235
		if (err==KErrNone)
sl@0
   236
			{
sl@0
   237
			CleanupClosePushL(plugin);
sl@0
   238
			iPluginDllList.AppendL(plugin);
sl@0
   239
			CleanupStack::Pop(&plugin);
sl@0
   240
			iPluginNames.AppendL(line);
sl@0
   241
			}
sl@0
   242
		}
sl@0
   243
	while(ft.Read(line) == KErrNone);
sl@0
   244
		
sl@0
   245
		
sl@0
   246
	CleanupStack::PopAndDestroy(&file);
sl@0
   247
	CleanupStack::PopAndDestroy(&fs);
sl@0
   248
	CleanupStack::PopAndDestroy(configFileBuf);
sl@0
   249
	
sl@0
   250
	BuildPluginCharacteristicsL();		
sl@0
   251
	}
sl@0
   252
sl@0
   253
void CCryptoPluginsLoader::BuildPluginCharacteristicsL()
sl@0
   254
	{
sl@0
   255
	TInt dllCount=iPluginDllList.Count();
sl@0
   256
	TInt interfaceCount=sizeof(KInterfacesUids)/sizeof(KInterfacesUids[0]);
sl@0
   257
	for (TInt i=0;i<dllCount;i++)
sl@0
   258
		{
sl@0
   259
		
sl@0
   260
		//find the enumeration function pointer
sl@0
   261
		EnumerateCharacteristicsFunc enumerateFunc=(EnumerateCharacteristicsFunc)iPluginDllList[i].Lookup(EEnumerateCharacteristicsOrdinal);
sl@0
   262
		if (enumerateFunc)
sl@0
   263
			{
sl@0
   264
			for (TInt j=0;j<interfaceCount;j++)
sl@0
   265
				{
sl@0
   266
				BuildInterfaceCharacteristicsL(KInterfacesUids[j], enumerateFunc, i);
sl@0
   267
				}
sl@0
   268
			}
sl@0
   269
		}
sl@0
   270
	}	
sl@0
   271
sl@0
   272
void CCryptoPluginsLoader::BuildInterfaceCharacteristicsL(TUid aInterfaceUid, 
sl@0
   273
													EnumerateCharacteristicsFunc aEntryFunc,
sl@0
   274
													TInt aDllIndex)
sl@0
   275
	{
sl@0
   276
	//Get the corresponding characteristics from the plug-in module
sl@0
   277
	TInt numPlugins=0;
sl@0
   278
	const TCharacteristics** p = aEntryFunc(aInterfaceUid, numPlugins);
sl@0
   279
	
sl@0
   280
	//characteristics are available
sl@0
   281
	if (p)
sl@0
   282
		{
sl@0
   283
		//look for it first
sl@0
   284
		CCharacteristicDllIndexList** charsListPtr=iInterfaceCharacteristicsMap.Find(aInterfaceUid.iUid);
sl@0
   285
		CCharacteristicDllIndexList* charsList=NULL;
sl@0
   286
		//create new one if it is not in the map
sl@0
   287
		if (!charsListPtr)
sl@0
   288
			{
sl@0
   289
			charsList=CCharacteristicDllIndexList::NewLC();
sl@0
   290
			iInterfaceCharacteristicsMap.InsertL(aInterfaceUid.iUid, charsList);
sl@0
   291
			CleanupStack::Pop(charsList);
sl@0
   292
			}
sl@0
   293
		else
sl@0
   294
			{
sl@0
   295
			//Use the existing one.
sl@0
   296
			charsList=*charsListPtr;
sl@0
   297
			}
sl@0
   298
		
sl@0
   299
		for (TInt i=0; i<numPlugins; ++i)
sl@0
   300
			{
sl@0
   301
			// The pointer should never be null, but try to prevent
sl@0
   302
			// rogue plug-ins from breaking the framework.
sl@0
   303
			ASSERT(p);
sl@0
   304
			if (p)
sl@0
   305
				{
sl@0
   306
				TCharacteristicsDll temp(*p, aDllIndex);
sl@0
   307
				charsList->iCharacteristicList.AppendL(temp);
sl@0
   308
				}
sl@0
   309
			p++;							
sl@0
   310
			}
sl@0
   311
		}
sl@0
   312
	}	
sl@0
   313
sl@0
   314
void CCryptoPluginsLoader::CreatePluginConfigPropertyL()
sl@0
   315
	{
sl@0
   316
	RProcess thisProcess;
sl@0
   317
	// sanity check that feature property category in common header equals SID of this process
sl@0
   318
	ASSERT(KCryptoSpiPropertyCat == thisProcess.SecureId());
sl@0
   319
	TSecurityPolicy readPolicy(TSecurityPolicy::EAlwaysPass);
sl@0
   320
	TSecurityPolicy writePolicy(thisProcess.SecureId());
sl@0
   321
	
sl@0
   322
	TInt count=iPluginNames.Count();
sl@0
   323
	TInt publishResult=KErrNone;
sl@0
   324
	for (TInt i=0;i<count;i++)
sl@0
   325
		{
sl@0
   326
		publishResult = RProperty::Define(KPluginsConfigurationKey+i, RProperty::EByteArray, readPolicy, writePolicy);
sl@0
   327
		if ((publishResult == KErrNone) || (publishResult == KErrAlreadyExists))
sl@0
   328
			{
sl@0
   329
			TSizeStream ss;
sl@0
   330
			RWriteStream ws(&ss);
sl@0
   331
			ws<<iPluginNames[i];
sl@0
   332
	
sl@0
   333
			HBufC8* buf = HBufC8::NewLC(ss.Size());
sl@0
   334
			TPtr8 bufPtr(buf->Des());
sl@0
   335
			RDesWriteStream dws(bufPtr);
sl@0
   336
			dws<<iPluginNames[i];
sl@0
   337
			dws.CommitL();
sl@0
   338
			publishResult = RProperty::Set(KCryptoSpiPropertyCat, KPluginsConfigurationKey+i, bufPtr);
sl@0
   339
			CleanupStack::PopAndDestroy(buf);
sl@0
   340
			}
sl@0
   341
		else
sl@0
   342
			{
sl@0
   343
			User::Leave(publishResult);
sl@0
   344
			}
sl@0
   345
		}
sl@0
   346
	publishResult = RProperty::Define(KPluginsConfigurationKeyCount, RProperty::EInt, readPolicy, writePolicy);	
sl@0
   347
	if ((publishResult == KErrNone) || (publishResult == KErrAlreadyExists))
sl@0
   348
		{
sl@0
   349
		publishResult = RProperty::Set(KCryptoSpiPropertyCat, KPluginsConfigurationKeyCount, count);
sl@0
   350
		}
sl@0
   351
	else
sl@0
   352
		{
sl@0
   353
		User::Leave(publishResult);
sl@0
   354
		}
sl@0
   355
	}
sl@0
   356
sl@0
   357
void CCryptoPluginsLoader::CreateInterfacePropertyL(TInt32 aInterface)
sl@0
   358
	{
sl@0
   359
	TSizeStream ss;
sl@0
   360
	RWriteStream ws(&ss);
sl@0
   361
	ws.WriteInt32L(0);
sl@0
   362
	DoCreateInterfacePropertyL(ws, aInterface);
sl@0
   363
	
sl@0
   364
	HBufC8* buf = HBufC8::NewLC(ss.Size());
sl@0
   365
	TPtr8 bufPtr(buf->Des());
sl@0
   366
	RDesWriteStream dws(bufPtr);
sl@0
   367
	dws.WriteInt32L(ss.Size());
sl@0
   368
	DoCreateInterfacePropertyL(dws, aInterface);
sl@0
   369
	dws.CommitL();
sl@0
   370
	User::LeaveIfError(RProperty::Set(KCryptoSpiPropertyCat, aInterface, bufPtr));
sl@0
   371
	CleanupStack::PopAndDestroy(buf);	
sl@0
   372
	}
sl@0
   373
	
sl@0
   374
void CCryptoPluginsLoader::DoCreateInterfacePropertyL(RWriteStream& aStream, TInt32 aInterface)
sl@0
   375
	{
sl@0
   376
	RProcess thisProcess;
sl@0
   377
	// sanity check that feature property category in common header equals SID of this process
sl@0
   378
	ASSERT(KCryptoSpiPropertyCat == thisProcess.SecureId());
sl@0
   379
	TSecurityPolicy readPolicy(TSecurityPolicy::EAlwaysPass);
sl@0
   380
	TSecurityPolicy writePolicy(thisProcess.SecureId());
sl@0
   381
	
sl@0
   382
	TInt publishResult = RProperty::Define(aInterface, RProperty::ELargeByteArray, readPolicy, writePolicy);
sl@0
   383
	if ((publishResult == KErrNone) || (publishResult == KErrAlreadyExists))
sl@0
   384
		{
sl@0
   385
		CCharacteristicDllIndexList** charsListPtr=iInterfaceCharacteristicsMap.Find(aInterface);
sl@0
   386
		if (charsListPtr)
sl@0
   387
			{
sl@0
   388
			(*charsListPtr)->ExternalizeL(aStream);
sl@0
   389
			}
sl@0
   390
		}
sl@0
   391
	else
sl@0
   392
		{
sl@0
   393
		User::Leave(publishResult);
sl@0
   394
		}		
sl@0
   395
	}
sl@0
   396
	
sl@0
   397
//
sl@0
   398
// Implementation of TSizeStream
sl@0
   399
//
sl@0
   400
void TSizeStream::DoWriteL(const TAny* /* aPtr */, TInt aLength)
sl@0
   401
	{
sl@0
   402
	iSize += aLength;
sl@0
   403
	}
sl@0
   404
sl@0
   405
_LIT(KPluginConfigFile, "z:\\resource\\cryptospi\\plug-ins.txt");
sl@0
   406
HBufC *GetConfigFileNameL()
sl@0
   407
	{
sl@0
   408
	// Check the command line. It should be empty or a single decimal digit
sl@0
   409
	TInt argsLen = User::CommandLineLength();
sl@0
   410
sl@0
   411
	if(argsLen == 0)
sl@0
   412
		{
sl@0
   413
		// No arguments so return the default config file name
sl@0
   414
		return KPluginConfigFile().AllocL();
sl@0
   415
		}
sl@0
   416
sl@0
   417
	// We only support a single digit argument
sl@0
   418
	if(argsLen != 1)
sl@0
   419
		{
sl@0
   420
		User::Leave(KErrArgument);
sl@0
   421
		}
sl@0
   422
	
sl@0
   423
sl@0
   424
	// Read the single char command line
sl@0
   425
	TBuf<1> argsBuf;
sl@0
   426
	User::CommandLine(argsBuf);
sl@0
   427
		
sl@0
   428
	// Check if it is a digit
sl@0
   429
	TChar ch(argsBuf[0]);
sl@0
   430
	if(!ch.IsDigit())
sl@0
   431
		{
sl@0
   432
		User::Leave(KErrArgument);
sl@0
   433
		}
sl@0
   434
sl@0
   435
	// Create buffer for config file name, inc space to append the digit
sl@0
   436
	HBufC *configFileBuf = HBufC::NewL(KPluginConfigFile().Length()+1);
sl@0
   437
	TPtr configFile(configFileBuf->Des());
sl@0
   438
		
sl@0
   439
	// Initialise it to the default file name
sl@0
   440
	configFile = KPluginConfigFile;
sl@0
   441
		
sl@0
   442
	// Append the digit to the config file name
sl@0
   443
	configFile.Append(ch);
sl@0
   444
	
sl@0
   445
	return configFileBuf;
sl@0
   446
	}
sl@0
   447
sl@0
   448
// End of file