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