--- /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