crypto/weakcryptospi/source/spi/cryptospisetup/cryptopluginsloader.cpp
changeset 8 35751d3474b7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crypto/weakcryptospi/source/spi/cryptospisetup/cryptopluginsloader.cpp	Thu Sep 10 14:01:51 2009 +0300
@@ -0,0 +1,448 @@
+/*
+* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+* crypto plugins loader implementation
+* crypto spi state implementation
+*
+*/
+
+
+/**
+ @file
+*/
+#include "cryptopluginsloader.h"
+#include <f32file.h>
+#include <cryptospi/cryptospidef.h>
+#include "cryptospiproperty.h"
+#include <e32property.h>
+
+using namespace CryptoSpi;
+
+_LIT(KPluginDir, "z:\\sys\\bin\\");
+
+HBufC *GetConfigFileNameL();
+
+//
+// Implementation of TCharacteristicsDll
+//
+TCharacteristicsDll::TCharacteristicsDll(const TAny* aCharacteristics, TInt aIndex)
+:iCharacteristics(aCharacteristics), iDllIndex(aIndex)
+	{
+	}
+
+void TCharacteristicsDll::ExternalizeL(RWriteStream& aStream)
+	{
+	const TCommonCharacteristics* common=reinterpret_cast<const TCommonCharacteristics*>(iCharacteristics);
+	switch (common->iInterfaceUID)
+		{
+	case KHashInterface:
+	case KAsyncHashInterface:
+		{
+		const THashCharacteristics* characteristics=reinterpret_cast<const THashCharacteristics*>(iCharacteristics);
+		characteristics->ExternalizeL(aStream);
+		}
+		break;
+	case KRandomInterface:
+	case KAsyncRandomInterface:
+		{
+		const TRandomCharacteristics* characteristics=reinterpret_cast<const TRandomCharacteristics*>(iCharacteristics);
+		characteristics->ExternalizeL(aStream);		
+		}
+		break;
+
+	case KSymmetricCipherInterface:
+	case KAsyncSymmetricCipherInterface:
+		{
+		const TSymmetricCipherCharacteristics* characteristics=reinterpret_cast<const TSymmetricCipherCharacteristics*>(iCharacteristics);
+		characteristics->ExternalizeL(aStream);		
+		}
+		break;
+
+	case KAsymmetricCipherInterface:
+	case KAsyncAsymmetricCipherInterface:
+		{
+		const TAsymmetricCipherCharacteristics* characteristics=reinterpret_cast<const TAsymmetricCipherCharacteristics*>(iCharacteristics);
+		characteristics->ExternalizeL(aStream);		
+		}
+		break;
+
+	case KSignerInterface:
+	case KVerifierInterface:
+	case KAsyncSignerInterface:
+	case KAsyncVerifierInterface:
+		{
+		const TAsymmetricSignatureCharacteristics* characteristics=reinterpret_cast<const TAsymmetricSignatureCharacteristics*>(iCharacteristics);
+		characteristics->ExternalizeL(aStream);		
+		}
+		break;
+	
+	case KKeyAgreementInterface:
+	case KAsyncKeyAgreementInterface:
+		{
+		const TKeyAgreementCharacteristics* characteristics=reinterpret_cast<const TKeyAgreementCharacteristics*>(iCharacteristics);
+		characteristics->ExternalizeL(aStream);
+		}
+		break;
+
+	case KKeypairGeneratorInterface:
+	case KAsyncKeypairGeneratorInterface:
+		{
+		const TAsymmetricKeypairGeneratorCharacteristics* characteristics=reinterpret_cast<const TAsymmetricKeypairGeneratorCharacteristics*>(iCharacteristics);
+		characteristics->ExternalizeL(aStream);
+		}
+		break;
+#ifdef SYMBIAN_SDP_IPSEC_VOIP_SUPPORT			
+	case KMacInterface:
+	case KAsyncMacInterface:
+		{
+		const TMacCharacteristics* characteristics=reinterpret_cast<const TMacCharacteristics*>(iCharacteristics);
+		characteristics->ExternalizeL(aStream);
+		}
+		break;
+#endif		
+	default:
+		User::Leave(KErrNotSupported); 
+		}
+		
+	aStream.WriteInt8L(iDllIndex);
+	}
+
+//
+// Implementation of CCharacteristicDllIndexList
+//
+CCharacteristicDllIndexList* CCharacteristicDllIndexList::NewL()
+	{
+	CCharacteristicDllIndexList* self=new(ELeave) CCharacteristicDllIndexList();
+	return self;
+	}
+
+CCharacteristicDllIndexList* CCharacteristicDllIndexList::NewLC()
+	{
+	CCharacteristicDllIndexList* self=new(ELeave) CCharacteristicDllIndexList();
+	CleanupStack::PushL(self);
+	return self;		
+	}
+
+CCharacteristicDllIndexList::CCharacteristicDllIndexList()
+	{
+	}
+
+CCharacteristicDllIndexList::~CCharacteristicDllIndexList()
+	{
+	iCharacteristicList.Close();	
+	}
+
+void CCharacteristicDllIndexList::ExternalizeL(RWriteStream& aStream)
+	{
+	TInt count=iCharacteristicList.Count();
+	aStream.WriteInt16L(count);
+	for (TInt i=0;i<count;i++)
+		{
+		iCharacteristicList[i].ExternalizeL(aStream);
+		}
+	}
+
+//
+// Implementation of CCryptoPluginsLoader
+//
+CCryptoPluginsLoader* CCryptoPluginsLoader::NewL()
+	{
+	CCryptoPluginsLoader* self=NewLC();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CCryptoPluginsLoader* CCryptoPluginsLoader::NewLC()
+	{
+	CCryptoPluginsLoader* self=new(ELeave)CCryptoPluginsLoader();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+	
+CCryptoPluginsLoader::CCryptoPluginsLoader()
+	{
+	}
+
+CCryptoPluginsLoader::~CCryptoPluginsLoader()
+	{
+	//Destroy the characteristic map
+	THashMapIter<TInt32, CCharacteristicDllIndexList*> it(iInterfaceCharacteristicsMap);
+	it.NextValue();
+	while (it.CurrentValue())
+		{
+		delete *it.CurrentValue();
+		it.NextValue();
+		}
+	iInterfaceCharacteristicsMap.Close();
+
+	//Unload the plugin DLLs and release the array
+	TInt dllCount=iPluginDllList.Count();
+	for (TInt i=0;i<dllCount;i++)
+		{
+		iPluginDllList[i].Close();	
+		}
+	iPluginDllList.Close();
+	iPluginNames.Close();
+	}
+
+void CCryptoPluginsLoader::ConstructL()
+	{
+	LoadPluginsL();
+	}
+
+void CCryptoPluginsLoader::LoadPluginsL()
+	{
+	HBufC *configFileBuf = GetConfigFileNameL();
+	CleanupStack::PushL(configFileBuf);
+	TPtr configFile(configFileBuf->Des());
+
+	RFs fs;
+	User::LeaveIfError(fs.Connect());
+	CleanupClosePushL(fs);
+
+	RFile file;
+	User::LeaveIfError(file.Open(fs, configFile, KEntryAttNormal));
+	CleanupClosePushL(file);
+
+	TFileText ft;
+	ft.Set(file);
+	TFileName line;
+	
+	User::LeaveIfError(ft.Read(line));
+		
+	//Load all the plugins
+	do
+		{	
+		TFileName filename;
+		filename.Append(KPluginDir);
+		filename.Append(line);
+
+		//Load...
+		RLibrary plugin;
+		TInt err=plugin.Load(filename);
+		if (err==KErrNone)
+			{
+			CleanupClosePushL(plugin);
+			iPluginDllList.AppendL(plugin);
+			CleanupStack::Pop(&plugin);
+			iPluginNames.AppendL(line);
+			}
+		}
+	while(ft.Read(line) == KErrNone);
+		
+		
+	CleanupStack::PopAndDestroy(&file);
+	CleanupStack::PopAndDestroy(&fs);
+	CleanupStack::PopAndDestroy(configFileBuf);
+	
+	BuildPluginCharacteristicsL();		
+	}
+
+void CCryptoPluginsLoader::BuildPluginCharacteristicsL()
+	{
+	TInt dllCount=iPluginDllList.Count();
+	TInt interfaceCount=sizeof(KInterfacesUids)/sizeof(KInterfacesUids[0]);
+	for (TInt i=0;i<dllCount;i++)
+		{
+		
+		//find the enumeration function pointer
+		EnumerateCharacteristicsFunc enumerateFunc=(EnumerateCharacteristicsFunc)iPluginDllList[i].Lookup(EEnumerateCharacteristicsOrdinal);
+		if (enumerateFunc)
+			{
+			for (TInt j=0;j<interfaceCount;j++)
+				{
+				BuildInterfaceCharacteristicsL(KInterfacesUids[j], enumerateFunc, i);
+				}
+			}
+		}
+	}	
+
+void CCryptoPluginsLoader::BuildInterfaceCharacteristicsL(TUid aInterfaceUid, 
+													EnumerateCharacteristicsFunc aEntryFunc,
+													TInt aDllIndex)
+	{
+	//Get the corresponding characteristics from the plug-in module
+	TInt numPlugins=0;
+	const TCharacteristics** p = aEntryFunc(aInterfaceUid, numPlugins);
+	
+	//characteristics are available
+	if (p)
+		{
+		//look for it first
+		CCharacteristicDllIndexList** charsListPtr=iInterfaceCharacteristicsMap.Find(aInterfaceUid.iUid);
+		CCharacteristicDllIndexList* charsList=NULL;
+		//create new one if it is not in the map
+		if (!charsListPtr)
+			{
+			charsList=CCharacteristicDllIndexList::NewLC();
+			iInterfaceCharacteristicsMap.InsertL(aInterfaceUid.iUid, charsList);
+			CleanupStack::Pop(charsList);
+			}
+		else
+			{
+			//Use the existing one.
+			charsList=*charsListPtr;
+			}
+		
+		for (TInt i=0; i<numPlugins; ++i)
+			{
+			// The pointer should never be null, but try to prevent
+			// rogue plug-ins from breaking the framework.
+			ASSERT(p);
+			if (p)
+				{
+				TCharacteristicsDll temp(*p, aDllIndex);
+				charsList->iCharacteristicList.AppendL(temp);
+				}
+			p++;							
+			}
+		}
+	}	
+
+void CCryptoPluginsLoader::CreatePluginConfigPropertyL()
+	{
+	RProcess thisProcess;
+	// sanity check that feature property category in common header equals SID of this process
+	ASSERT(KCryptoSpiPropertyCat == thisProcess.SecureId());
+	TSecurityPolicy readPolicy(TSecurityPolicy::EAlwaysPass);
+	TSecurityPolicy writePolicy(thisProcess.SecureId());
+	
+	TInt count=iPluginNames.Count();
+	TInt publishResult=KErrNone;
+	for (TInt i=0;i<count;i++)
+		{
+		publishResult = RProperty::Define(KPluginsConfigurationKey+i, RProperty::EByteArray, readPolicy, writePolicy);
+		if ((publishResult == KErrNone) || (publishResult == KErrAlreadyExists))
+			{
+			TSizeStream ss;
+			RWriteStream ws(&ss);
+			ws<<iPluginNames[i];
+	
+			HBufC8* buf = HBufC8::NewLC(ss.Size());
+			TPtr8 bufPtr(buf->Des());
+			RDesWriteStream dws(bufPtr);
+			dws<<iPluginNames[i];
+			dws.CommitL();
+			publishResult = RProperty::Set(KCryptoSpiPropertyCat, KPluginsConfigurationKey+i, bufPtr);
+			CleanupStack::PopAndDestroy(buf);
+			}
+		else
+			{
+			User::Leave(publishResult);
+			}
+		}
+	publishResult = RProperty::Define(KPluginsConfigurationKeyCount, RProperty::EInt, readPolicy, writePolicy);	
+	if ((publishResult == KErrNone) || (publishResult == KErrAlreadyExists))
+		{
+		publishResult = RProperty::Set(KCryptoSpiPropertyCat, KPluginsConfigurationKeyCount, count);
+		}
+	else
+		{
+		User::Leave(publishResult);
+		}
+	}
+
+void CCryptoPluginsLoader::CreateInterfacePropertyL(TInt32 aInterface)
+	{
+	TSizeStream ss;
+	RWriteStream ws(&ss);
+	ws.WriteInt32L(0);
+	DoCreateInterfacePropertyL(ws, aInterface);
+	
+	HBufC8* buf = HBufC8::NewLC(ss.Size());
+	TPtr8 bufPtr(buf->Des());
+	RDesWriteStream dws(bufPtr);
+	dws.WriteInt32L(ss.Size());
+	DoCreateInterfacePropertyL(dws, aInterface);
+	dws.CommitL();
+	User::LeaveIfError(RProperty::Set(KCryptoSpiPropertyCat, aInterface, bufPtr));
+	CleanupStack::PopAndDestroy(buf);	
+	}
+	
+void CCryptoPluginsLoader::DoCreateInterfacePropertyL(RWriteStream& aStream, TInt32 aInterface)
+	{
+	RProcess thisProcess;
+	// sanity check that feature property category in common header equals SID of this process
+	ASSERT(KCryptoSpiPropertyCat == thisProcess.SecureId());
+	TSecurityPolicy readPolicy(TSecurityPolicy::EAlwaysPass);
+	TSecurityPolicy writePolicy(thisProcess.SecureId());
+	
+	TInt publishResult = RProperty::Define(aInterface, RProperty::ELargeByteArray, readPolicy, writePolicy);
+	if ((publishResult == KErrNone) || (publishResult == KErrAlreadyExists))
+		{
+		CCharacteristicDllIndexList** charsListPtr=iInterfaceCharacteristicsMap.Find(aInterface);
+		if (charsListPtr)
+			{
+			(*charsListPtr)->ExternalizeL(aStream);
+			}
+		}
+	else
+		{
+		User::Leave(publishResult);
+		}		
+	}
+	
+//
+// Implementation of TSizeStream
+//
+void TSizeStream::DoWriteL(const TAny* /* aPtr */, TInt aLength)
+	{
+	iSize += aLength;
+	}
+
+_LIT(KPluginConfigFile, "z:\\resource\\cryptospi\\plug-ins.txt");
+HBufC *GetConfigFileNameL()
+	{
+	// Check the command line. It should be empty or a single decimal digit
+	TInt argsLen = User::CommandLineLength();
+
+	if(argsLen == 0)
+		{
+		// No arguments so return the default config file name
+		return KPluginConfigFile().AllocL();
+		}
+
+	// We only support a single digit argument
+	if(argsLen != 1)
+		{
+		User::Leave(KErrArgument);
+		}
+	
+
+	// Read the single char command line
+	TBuf<1> argsBuf;
+	User::CommandLine(argsBuf);
+		
+	// Check if it is a digit
+	TChar ch(argsBuf[0]);
+	if(!ch.IsDigit())
+		{
+		User::Leave(KErrArgument);
+		}
+
+	// Create buffer for config file name, inc space to append the digit
+	HBufC *configFileBuf = HBufC::NewL(KPluginConfigFile().Length()+1);
+	TPtr configFile(configFileBuf->Des());
+		
+	// Initialise it to the default file name
+	configFile = KPluginConfigFile;
+		
+	// Append the digit to the config file name
+	configFile.Append(ch);
+	
+	return configFileBuf;
+	}
+
+// End of file