os/security/crypto/weakcryptospi/source/spi/cryptospisetup/cryptopluginsloader.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/crypto/weakcryptospi/source/spi/cryptospisetup/cryptopluginsloader.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,448 @@
1.4 +/*
1.5 +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of the License "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +* crypto plugins loader implementation
1.19 +* crypto spi state implementation
1.20 +*
1.21 +*/
1.22 +
1.23 +
1.24 +/**
1.25 + @file
1.26 +*/
1.27 +#include "cryptopluginsloader.h"
1.28 +#include <f32file.h>
1.29 +#include <cryptospi/cryptospidef.h>
1.30 +#include "cryptospiproperty.h"
1.31 +#include <e32property.h>
1.32 +
1.33 +using namespace CryptoSpi;
1.34 +
1.35 +_LIT(KPluginDir, "z:\\sys\\bin\\");
1.36 +
1.37 +HBufC *GetConfigFileNameL();
1.38 +
1.39 +//
1.40 +// Implementation of TCharacteristicsDll
1.41 +//
1.42 +TCharacteristicsDll::TCharacteristicsDll(const TAny* aCharacteristics, TInt aIndex)
1.43 +:iCharacteristics(aCharacteristics), iDllIndex(aIndex)
1.44 + {
1.45 + }
1.46 +
1.47 +void TCharacteristicsDll::ExternalizeL(RWriteStream& aStream)
1.48 + {
1.49 + const TCommonCharacteristics* common=reinterpret_cast<const TCommonCharacteristics*>(iCharacteristics);
1.50 + switch (common->iInterfaceUID)
1.51 + {
1.52 + case KHashInterface:
1.53 + case KAsyncHashInterface:
1.54 + {
1.55 + const THashCharacteristics* characteristics=reinterpret_cast<const THashCharacteristics*>(iCharacteristics);
1.56 + characteristics->ExternalizeL(aStream);
1.57 + }
1.58 + break;
1.59 + case KRandomInterface:
1.60 + case KAsyncRandomInterface:
1.61 + {
1.62 + const TRandomCharacteristics* characteristics=reinterpret_cast<const TRandomCharacteristics*>(iCharacteristics);
1.63 + characteristics->ExternalizeL(aStream);
1.64 + }
1.65 + break;
1.66 +
1.67 + case KSymmetricCipherInterface:
1.68 + case KAsyncSymmetricCipherInterface:
1.69 + {
1.70 + const TSymmetricCipherCharacteristics* characteristics=reinterpret_cast<const TSymmetricCipherCharacteristics*>(iCharacteristics);
1.71 + characteristics->ExternalizeL(aStream);
1.72 + }
1.73 + break;
1.74 +
1.75 + case KAsymmetricCipherInterface:
1.76 + case KAsyncAsymmetricCipherInterface:
1.77 + {
1.78 + const TAsymmetricCipherCharacteristics* characteristics=reinterpret_cast<const TAsymmetricCipherCharacteristics*>(iCharacteristics);
1.79 + characteristics->ExternalizeL(aStream);
1.80 + }
1.81 + break;
1.82 +
1.83 + case KSignerInterface:
1.84 + case KVerifierInterface:
1.85 + case KAsyncSignerInterface:
1.86 + case KAsyncVerifierInterface:
1.87 + {
1.88 + const TAsymmetricSignatureCharacteristics* characteristics=reinterpret_cast<const TAsymmetricSignatureCharacteristics*>(iCharacteristics);
1.89 + characteristics->ExternalizeL(aStream);
1.90 + }
1.91 + break;
1.92 +
1.93 + case KKeyAgreementInterface:
1.94 + case KAsyncKeyAgreementInterface:
1.95 + {
1.96 + const TKeyAgreementCharacteristics* characteristics=reinterpret_cast<const TKeyAgreementCharacteristics*>(iCharacteristics);
1.97 + characteristics->ExternalizeL(aStream);
1.98 + }
1.99 + break;
1.100 +
1.101 + case KKeypairGeneratorInterface:
1.102 + case KAsyncKeypairGeneratorInterface:
1.103 + {
1.104 + const TAsymmetricKeypairGeneratorCharacteristics* characteristics=reinterpret_cast<const TAsymmetricKeypairGeneratorCharacteristics*>(iCharacteristics);
1.105 + characteristics->ExternalizeL(aStream);
1.106 + }
1.107 + break;
1.108 +#ifdef SYMBIAN_SDP_IPSEC_VOIP_SUPPORT
1.109 + case KMacInterface:
1.110 + case KAsyncMacInterface:
1.111 + {
1.112 + const TMacCharacteristics* characteristics=reinterpret_cast<const TMacCharacteristics*>(iCharacteristics);
1.113 + characteristics->ExternalizeL(aStream);
1.114 + }
1.115 + break;
1.116 +#endif
1.117 + default:
1.118 + User::Leave(KErrNotSupported);
1.119 + }
1.120 +
1.121 + aStream.WriteInt8L(iDllIndex);
1.122 + }
1.123 +
1.124 +//
1.125 +// Implementation of CCharacteristicDllIndexList
1.126 +//
1.127 +CCharacteristicDllIndexList* CCharacteristicDllIndexList::NewL()
1.128 + {
1.129 + CCharacteristicDllIndexList* self=new(ELeave) CCharacteristicDllIndexList();
1.130 + return self;
1.131 + }
1.132 +
1.133 +CCharacteristicDllIndexList* CCharacteristicDllIndexList::NewLC()
1.134 + {
1.135 + CCharacteristicDllIndexList* self=new(ELeave) CCharacteristicDllIndexList();
1.136 + CleanupStack::PushL(self);
1.137 + return self;
1.138 + }
1.139 +
1.140 +CCharacteristicDllIndexList::CCharacteristicDllIndexList()
1.141 + {
1.142 + }
1.143 +
1.144 +CCharacteristicDllIndexList::~CCharacteristicDllIndexList()
1.145 + {
1.146 + iCharacteristicList.Close();
1.147 + }
1.148 +
1.149 +void CCharacteristicDllIndexList::ExternalizeL(RWriteStream& aStream)
1.150 + {
1.151 + TInt count=iCharacteristicList.Count();
1.152 + aStream.WriteInt16L(count);
1.153 + for (TInt i=0;i<count;i++)
1.154 + {
1.155 + iCharacteristicList[i].ExternalizeL(aStream);
1.156 + }
1.157 + }
1.158 +
1.159 +//
1.160 +// Implementation of CCryptoPluginsLoader
1.161 +//
1.162 +CCryptoPluginsLoader* CCryptoPluginsLoader::NewL()
1.163 + {
1.164 + CCryptoPluginsLoader* self=NewLC();
1.165 + CleanupStack::Pop(self);
1.166 + return self;
1.167 + }
1.168 +
1.169 +CCryptoPluginsLoader* CCryptoPluginsLoader::NewLC()
1.170 + {
1.171 + CCryptoPluginsLoader* self=new(ELeave)CCryptoPluginsLoader();
1.172 + CleanupStack::PushL(self);
1.173 + self->ConstructL();
1.174 + return self;
1.175 + }
1.176 +
1.177 +CCryptoPluginsLoader::CCryptoPluginsLoader()
1.178 + {
1.179 + }
1.180 +
1.181 +CCryptoPluginsLoader::~CCryptoPluginsLoader()
1.182 + {
1.183 + //Destroy the characteristic map
1.184 + THashMapIter<TInt32, CCharacteristicDllIndexList*> it(iInterfaceCharacteristicsMap);
1.185 + it.NextValue();
1.186 + while (it.CurrentValue())
1.187 + {
1.188 + delete *it.CurrentValue();
1.189 + it.NextValue();
1.190 + }
1.191 + iInterfaceCharacteristicsMap.Close();
1.192 +
1.193 + //Unload the plugin DLLs and release the array
1.194 + TInt dllCount=iPluginDllList.Count();
1.195 + for (TInt i=0;i<dllCount;i++)
1.196 + {
1.197 + iPluginDllList[i].Close();
1.198 + }
1.199 + iPluginDllList.Close();
1.200 + iPluginNames.Close();
1.201 + }
1.202 +
1.203 +void CCryptoPluginsLoader::ConstructL()
1.204 + {
1.205 + LoadPluginsL();
1.206 + }
1.207 +
1.208 +void CCryptoPluginsLoader::LoadPluginsL()
1.209 + {
1.210 + HBufC *configFileBuf = GetConfigFileNameL();
1.211 + CleanupStack::PushL(configFileBuf);
1.212 + TPtr configFile(configFileBuf->Des());
1.213 +
1.214 + RFs fs;
1.215 + User::LeaveIfError(fs.Connect());
1.216 + CleanupClosePushL(fs);
1.217 +
1.218 + RFile file;
1.219 + User::LeaveIfError(file.Open(fs, configFile, KEntryAttNormal));
1.220 + CleanupClosePushL(file);
1.221 +
1.222 + TFileText ft;
1.223 + ft.Set(file);
1.224 + TFileName line;
1.225 +
1.226 + User::LeaveIfError(ft.Read(line));
1.227 +
1.228 + //Load all the plugins
1.229 + do
1.230 + {
1.231 + TFileName filename;
1.232 + filename.Append(KPluginDir);
1.233 + filename.Append(line);
1.234 +
1.235 + //Load...
1.236 + RLibrary plugin;
1.237 + TInt err=plugin.Load(filename);
1.238 + if (err==KErrNone)
1.239 + {
1.240 + CleanupClosePushL(plugin);
1.241 + iPluginDllList.AppendL(plugin);
1.242 + CleanupStack::Pop(&plugin);
1.243 + iPluginNames.AppendL(line);
1.244 + }
1.245 + }
1.246 + while(ft.Read(line) == KErrNone);
1.247 +
1.248 +
1.249 + CleanupStack::PopAndDestroy(&file);
1.250 + CleanupStack::PopAndDestroy(&fs);
1.251 + CleanupStack::PopAndDestroy(configFileBuf);
1.252 +
1.253 + BuildPluginCharacteristicsL();
1.254 + }
1.255 +
1.256 +void CCryptoPluginsLoader::BuildPluginCharacteristicsL()
1.257 + {
1.258 + TInt dllCount=iPluginDllList.Count();
1.259 + TInt interfaceCount=sizeof(KInterfacesUids)/sizeof(KInterfacesUids[0]);
1.260 + for (TInt i=0;i<dllCount;i++)
1.261 + {
1.262 +
1.263 + //find the enumeration function pointer
1.264 + EnumerateCharacteristicsFunc enumerateFunc=(EnumerateCharacteristicsFunc)iPluginDllList[i].Lookup(EEnumerateCharacteristicsOrdinal);
1.265 + if (enumerateFunc)
1.266 + {
1.267 + for (TInt j=0;j<interfaceCount;j++)
1.268 + {
1.269 + BuildInterfaceCharacteristicsL(KInterfacesUids[j], enumerateFunc, i);
1.270 + }
1.271 + }
1.272 + }
1.273 + }
1.274 +
1.275 +void CCryptoPluginsLoader::BuildInterfaceCharacteristicsL(TUid aInterfaceUid,
1.276 + EnumerateCharacteristicsFunc aEntryFunc,
1.277 + TInt aDllIndex)
1.278 + {
1.279 + //Get the corresponding characteristics from the plug-in module
1.280 + TInt numPlugins=0;
1.281 + const TCharacteristics** p = aEntryFunc(aInterfaceUid, numPlugins);
1.282 +
1.283 + //characteristics are available
1.284 + if (p)
1.285 + {
1.286 + //look for it first
1.287 + CCharacteristicDllIndexList** charsListPtr=iInterfaceCharacteristicsMap.Find(aInterfaceUid.iUid);
1.288 + CCharacteristicDllIndexList* charsList=NULL;
1.289 + //create new one if it is not in the map
1.290 + if (!charsListPtr)
1.291 + {
1.292 + charsList=CCharacteristicDllIndexList::NewLC();
1.293 + iInterfaceCharacteristicsMap.InsertL(aInterfaceUid.iUid, charsList);
1.294 + CleanupStack::Pop(charsList);
1.295 + }
1.296 + else
1.297 + {
1.298 + //Use the existing one.
1.299 + charsList=*charsListPtr;
1.300 + }
1.301 +
1.302 + for (TInt i=0; i<numPlugins; ++i)
1.303 + {
1.304 + // The pointer should never be null, but try to prevent
1.305 + // rogue plug-ins from breaking the framework.
1.306 + ASSERT(p);
1.307 + if (p)
1.308 + {
1.309 + TCharacteristicsDll temp(*p, aDllIndex);
1.310 + charsList->iCharacteristicList.AppendL(temp);
1.311 + }
1.312 + p++;
1.313 + }
1.314 + }
1.315 + }
1.316 +
1.317 +void CCryptoPluginsLoader::CreatePluginConfigPropertyL()
1.318 + {
1.319 + RProcess thisProcess;
1.320 + // sanity check that feature property category in common header equals SID of this process
1.321 + ASSERT(KCryptoSpiPropertyCat == thisProcess.SecureId());
1.322 + TSecurityPolicy readPolicy(TSecurityPolicy::EAlwaysPass);
1.323 + TSecurityPolicy writePolicy(thisProcess.SecureId());
1.324 +
1.325 + TInt count=iPluginNames.Count();
1.326 + TInt publishResult=KErrNone;
1.327 + for (TInt i=0;i<count;i++)
1.328 + {
1.329 + publishResult = RProperty::Define(KPluginsConfigurationKey+i, RProperty::EByteArray, readPolicy, writePolicy);
1.330 + if ((publishResult == KErrNone) || (publishResult == KErrAlreadyExists))
1.331 + {
1.332 + TSizeStream ss;
1.333 + RWriteStream ws(&ss);
1.334 + ws<<iPluginNames[i];
1.335 +
1.336 + HBufC8* buf = HBufC8::NewLC(ss.Size());
1.337 + TPtr8 bufPtr(buf->Des());
1.338 + RDesWriteStream dws(bufPtr);
1.339 + dws<<iPluginNames[i];
1.340 + dws.CommitL();
1.341 + publishResult = RProperty::Set(KCryptoSpiPropertyCat, KPluginsConfigurationKey+i, bufPtr);
1.342 + CleanupStack::PopAndDestroy(buf);
1.343 + }
1.344 + else
1.345 + {
1.346 + User::Leave(publishResult);
1.347 + }
1.348 + }
1.349 + publishResult = RProperty::Define(KPluginsConfigurationKeyCount, RProperty::EInt, readPolicy, writePolicy);
1.350 + if ((publishResult == KErrNone) || (publishResult == KErrAlreadyExists))
1.351 + {
1.352 + publishResult = RProperty::Set(KCryptoSpiPropertyCat, KPluginsConfigurationKeyCount, count);
1.353 + }
1.354 + else
1.355 + {
1.356 + User::Leave(publishResult);
1.357 + }
1.358 + }
1.359 +
1.360 +void CCryptoPluginsLoader::CreateInterfacePropertyL(TInt32 aInterface)
1.361 + {
1.362 + TSizeStream ss;
1.363 + RWriteStream ws(&ss);
1.364 + ws.WriteInt32L(0);
1.365 + DoCreateInterfacePropertyL(ws, aInterface);
1.366 +
1.367 + HBufC8* buf = HBufC8::NewLC(ss.Size());
1.368 + TPtr8 bufPtr(buf->Des());
1.369 + RDesWriteStream dws(bufPtr);
1.370 + dws.WriteInt32L(ss.Size());
1.371 + DoCreateInterfacePropertyL(dws, aInterface);
1.372 + dws.CommitL();
1.373 + User::LeaveIfError(RProperty::Set(KCryptoSpiPropertyCat, aInterface, bufPtr));
1.374 + CleanupStack::PopAndDestroy(buf);
1.375 + }
1.376 +
1.377 +void CCryptoPluginsLoader::DoCreateInterfacePropertyL(RWriteStream& aStream, TInt32 aInterface)
1.378 + {
1.379 + RProcess thisProcess;
1.380 + // sanity check that feature property category in common header equals SID of this process
1.381 + ASSERT(KCryptoSpiPropertyCat == thisProcess.SecureId());
1.382 + TSecurityPolicy readPolicy(TSecurityPolicy::EAlwaysPass);
1.383 + TSecurityPolicy writePolicy(thisProcess.SecureId());
1.384 +
1.385 + TInt publishResult = RProperty::Define(aInterface, RProperty::ELargeByteArray, readPolicy, writePolicy);
1.386 + if ((publishResult == KErrNone) || (publishResult == KErrAlreadyExists))
1.387 + {
1.388 + CCharacteristicDllIndexList** charsListPtr=iInterfaceCharacteristicsMap.Find(aInterface);
1.389 + if (charsListPtr)
1.390 + {
1.391 + (*charsListPtr)->ExternalizeL(aStream);
1.392 + }
1.393 + }
1.394 + else
1.395 + {
1.396 + User::Leave(publishResult);
1.397 + }
1.398 + }
1.399 +
1.400 +//
1.401 +// Implementation of TSizeStream
1.402 +//
1.403 +void TSizeStream::DoWriteL(const TAny* /* aPtr */, TInt aLength)
1.404 + {
1.405 + iSize += aLength;
1.406 + }
1.407 +
1.408 +_LIT(KPluginConfigFile, "z:\\resource\\cryptospi\\plug-ins.txt");
1.409 +HBufC *GetConfigFileNameL()
1.410 + {
1.411 + // Check the command line. It should be empty or a single decimal digit
1.412 + TInt argsLen = User::CommandLineLength();
1.413 +
1.414 + if(argsLen == 0)
1.415 + {
1.416 + // No arguments so return the default config file name
1.417 + return KPluginConfigFile().AllocL();
1.418 + }
1.419 +
1.420 + // We only support a single digit argument
1.421 + if(argsLen != 1)
1.422 + {
1.423 + User::Leave(KErrArgument);
1.424 + }
1.425 +
1.426 +
1.427 + // Read the single char command line
1.428 + TBuf<1> argsBuf;
1.429 + User::CommandLine(argsBuf);
1.430 +
1.431 + // Check if it is a digit
1.432 + TChar ch(argsBuf[0]);
1.433 + if(!ch.IsDigit())
1.434 + {
1.435 + User::Leave(KErrArgument);
1.436 + }
1.437 +
1.438 + // Create buffer for config file name, inc space to append the digit
1.439 + HBufC *configFileBuf = HBufC::NewL(KPluginConfigFile().Length()+1);
1.440 + TPtr configFile(configFileBuf->Des());
1.441 +
1.442 + // Initialise it to the default file name
1.443 + configFile = KPluginConfigFile;
1.444 +
1.445 + // Append the digit to the config file name
1.446 + configFile.Append(ch);
1.447 +
1.448 + return configFileBuf;
1.449 + }
1.450 +
1.451 +// End of file