--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/installationservices/swidevicetools/source/swicertstoretool/CSWICertStoreTool.cpp Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,523 @@
+/*
+* Copyright (c) 2006-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:
+*
+*/
+
+
+#include "CSWICertStoreTool.h"
+#include <testconfigfileparser.h>
+#include <cctcertinfo.h>
+#include <x509cert.h>
+#include <utf.h>
+
+_LIT(KSWICertStoreToolName, "SWICertStoreTool");
+_LIT8(KNewLine, "\r\n");
+
+_LIT8(KDefaultsSection, "Defaults");
+
+_LIT8(KLogErrorTemplate, "*** %S: Error: %d");
+_LIT8(KLogOKTemplate, " %S: OK");
+_LIT8(KLogParameterTemplate, " %S = %S");
+
+_LIT8(KLogStartMessage, "SWICertStoreTool");
+_LIT8(KLogEndMessage, "Done.");
+_LIT8(KLogSectionName, "Processing: %S");
+_LIT8(KLogIllegalCertLabel, "*** Section name is not a legal cert label - must be between 0 and 64 characters long");
+_LIT8(KLogDuplicateCertLabel, "*** Duplicate cert label");
+_LIT8(KLogNoFileSpecifiedError, "*** No certificate file spcified (use 'file = <cert filename>'");
+_LIT8(KLogIllegalMandatoryValue, "*** Illegal value for mandatory flag (must be 0 or 1)");
+_LIT8(KLogIllegalSystemUpgradeValue, "*** Illegal value for system upgrade flag (must be 0 or 1)");
+_LIT8(KLogIllegalCapabilityValue, "*** Unrecognised capability name: %S");
+_LIT8(KLogIllegalApplicationValue, "*** Unrecognised application (must be 'SWInstall' or 'SWInstallOCSP')");
+_LIT8(KLogNoApplications, "*** No applications specified (must one or more of 'SWInstall' and 'SWInstallOCSP')");
+
+_LIT8(KActionOpenInputFile, "Opening input file");
+_LIT8(KActionOpenOutputFile, "Opening output file");
+_LIT8(KActionParseSection, "Parsing section");
+_LIT8(KActionLoadCertData, "Loading certficate file");
+_LIT8(KActionParseX509Cert, "Parsing X509 certificate");
+_LIT8(KActionWriteCertData, "Writing cert data to store");
+_LIT8(KActionWriteInfoStream, "Writing info stream to store");
+_LIT8(KActionWriteRootStream, "Writing root stream to store");
+
+_LIT8(KItemFile, "file");
+_LIT8(KItemMandatory, "mandatory");
+_LIT8(KItemSystemUpgrade, "systemupgrade");
+_LIT8(KItemCapability, "capability");
+_LIT8(KItemApplication, "application");
+
+_LIT8(KParamInputFile, "input file");
+_LIT8(KParamOutputFile, "outut file");
+_LIT8(KParamLabel, "label");
+
+_LIT8(KApplicationSWInstall, "SWInstall");
+_LIT8(KApplicationSWInstallOCSP, "SWInstallOCSP");
+
+_LIT8(KString0, "0");
+_LIT8(KString1, "1");
+_LIT8(KFalse, "false");
+_LIT8(KTrue, "true");
+
+const TBool KTrueValue = 1;
+const TBool KFalseValue = 0;
+
+const TUid KApplicationSWInstallUid = { 0x100042ab };
+const TUid KApplicationSWInstallOCSPUid = { 0x1000a8b6 };
+
+const TInt KMaxLineLength = 200;
+
+// Capability names
+_LIT8(KCapabilityTCB, "TCB");
+_LIT8(KCapabilityCommDD, "CommDD");
+_LIT8(KCapabilityPowerMgmt, "PowerMgmt");
+_LIT8(KCapabilityMultimediaDD, "MultimediaDD");
+_LIT8(KCapabilityReadDeviceData, "ReadDeviceData");
+_LIT8(KCapabilityWriteDeviceData, "WriteDeviceData");
+_LIT8(KCapabilityDRM, "DRM");
+_LIT8(KCapabilityTrustedUI, "TrustedUI");
+_LIT8(KCapabilityProtServ, "ProtServ");
+_LIT8(KCapabilityDiskAdmin, "DiskAdmin");
+_LIT8(KCapabilityNetworkControl, "NetworkControl");
+_LIT8(KCapabilityAllFiles, "AllFiles");
+_LIT8(KCapabilitySwEvent, "SwEvent");
+_LIT8(KCapabilityNetworkServices, "NetworkServices");
+_LIT8(KCapabilityLocalServices, "LocalServices");
+_LIT8(KCapabilityReadUserData, "ReadUserData");
+_LIT8(KCapabilityWriteUserData, "WriteUserData");
+_LIT8(KCapabilityLocation, "Location");
+_LIT8(KCapabilitySurroundingsDD, "SurroundingsDD");
+_LIT8(KCapabilityUserEnvironment, "UserEnvironment");
+
+#define TRAP_AND_LOG(NAME, ACTION) \
+ { \
+ TRAPD(err, ACTION); \
+ TrapAndLogL(NAME, err); \
+ }
+
+ CSWICertStoreTool* CSWICertStoreTool::NewLC(const TDesC& aInputFile,
+ const TDesC& aOutputFile,
+ const TDesC& aLogFile)
+ {
+ CSWICertStoreTool* self = new (ELeave) CSWICertStoreTool(aInputFile, aOutputFile);
+ CleanupStack::PushL(self);
+ self->ConstructL(aLogFile);
+ return self;
+ }
+
+CSWICertStoreTool::CSWICertStoreTool(const TDesC& aInputFile, const TDesC& aOutputFile) :
+ iInputFile(aInputFile), iOutputFile(aOutputFile)
+ {
+ }
+
+void CSWICertStoreTool::ConstructL(const TDesC& aLogFile)
+ {
+ User::LeaveIfError(iFs.Connect());
+ User::LeaveIfError(iLogFile.Replace(iFs, aLogFile, EFileWrite | EFileShareExclusive));
+ }
+
+CSWICertStoreTool::~CSWICertStoreTool()
+ {
+ iLogFile.Close();
+ iFs.Close();
+ }
+
+void CSWICertStoreTool::LogL(TRefByValue<const TDesC8> aFmt, ...)
+ {
+ TBuf8<KMaxLineLength> buf;
+ VA_LIST args;
+ VA_START(args, aFmt);
+ buf.AppendFormatList(aFmt, args);
+ VA_END(args);
+
+ User::LeaveIfError(iLogFile.Write(buf));
+ User::LeaveIfError(iLogFile.Write(KNewLine));
+ User::LeaveIfError(iLogFile.Flush());
+ }
+
+void CSWICertStoreTool::TrapAndLogL(const TDesC8& aName, TInt err)
+ {
+ if (err != KErrNone)
+ {
+ LogL(KLogErrorTemplate, &aName, err);
+ User::Leave(err);
+ }
+ else
+ {
+ LogL(KLogOKTemplate, &aName);
+ }
+ }
+
+void CSWICertStoreTool::LogArgL(const TDesC8& aName, const TDesC& aValue)
+ {
+ TBuf8<KMaxLineLength> buf;
+ buf.Copy(aValue);
+ LogL(KLogParameterTemplate, &aName, &buf);
+ }
+
+void CSWICertStoreTool::LogParameterL(const TDesC8& aName, const TDesC8& aValue)
+ {
+ LogL(KLogParameterTemplate, &aName, &aValue);
+ }
+
+void CSWICertStoreTool::RunToolL()
+ {
+ TRAPD(err, DoRunToolL());
+
+ iCerts.ResetAndDestroy();
+ iCerts.Close();
+ delete iStore;
+ delete iScript;
+
+ if (err != KErrNone)
+ {
+ iFs.Delete(iOutputFile); // ignore errors
+ User::Leave(err);
+ }
+ }
+
+void CSWICertStoreTool::DoRunToolL()
+ {
+ LogL(KLogStartMessage);
+
+ LogArgL(KParamInputFile, iInputFile);
+ TRAP_AND_LOG(KActionOpenInputFile, OpenInputFileL(iInputFile));
+
+ LogArgL(KParamOutputFile, iOutputFile);
+ TRAP_AND_LOG(KActionOpenOutputFile, OpenStoreL(iOutputFile));
+
+ const RPointerArray<CTestConfigSection>& sections = iScript->Sections();
+
+ for (TInt i = 0 ; i < sections.Count() ; ++i)
+ {
+ const CTestConfigSection& section = *sections[i];
+ const TDesC8& name = section.SectionName();
+
+ // Skip 'Defaults' section
+ if (name == KDefaultsSection)
+ {
+ continue;
+ }
+
+ if (name.Length() == 0 || name.Length() > KMaxCertLabelLength)
+ {
+ LogL(KLogIllegalCertLabel, &name);
+ User::Leave(KErrArgument);
+ }
+
+ LogL(KLogSectionName, &name);
+ TRAP_AND_LOG(KActionParseSection, ParseScriptSectionL(section));
+ }
+
+ TStreamId infoStreamId = KNullStreamId;
+ TRAP_AND_LOG(KActionWriteInfoStream, infoStreamId = WriteInfoStreamL());
+ TRAP_AND_LOG(KActionWriteRootStream, WriteRootStreamL(infoStreamId));
+
+ LogL(KLogEndMessage);
+ }
+
+void CSWICertStoreTool::ParseScriptSectionL(const CTestConfigSection& aSection)
+ {
+ // Get cert label
+ const TDesC8& sectionName = aSection.SectionName();
+ TCertLabel label;
+ label.Copy(sectionName);
+ LogParameterL(KParamLabel, aSection.SectionName());
+ CheckCertLabelL(label);
+
+ // Parse file
+ const CTestConfigItem* item = aSection.Item(KItemFile);
+ if (item == NULL)
+ {
+ LogL(KLogNoFileSpecifiedError);
+ User::Leave(KErrNotFound);
+ }
+ const TDesC8& certFile = item->Value();
+ LogParameterL(KItemFile, certFile);
+
+ // Load certificate data
+ HBufC8* certData = NULL;
+ TRAP_AND_LOG(KActionLoadCertData, certData = LoadCertDataL(certFile));
+ CleanupStack::PushL(certData);
+
+ // Parse the certificate
+ CX509Certificate* cert = NULL;
+ TRAP_AND_LOG(KActionParseX509Cert, cert = CX509Certificate::NewL(*certData));
+ CleanupStack::PushL(cert);
+
+ // Write cert to store
+ TStreamId dataStreamId = KNullStreamId;
+ TRAP_AND_LOG(KActionWriteCertData, dataStreamId = WriteCertDataL(*certData));
+
+ // parse additional meta data for the certificate
+ TCertMetaInfo certMetaInfo;
+ // Parse mandatory flag
+ certMetaInfo.iIsMandatory = 0;
+ const CTestConfigItem* mandatory = aSection.Item(KItemMandatory);
+ if (mandatory != NULL)
+ {
+ const TDesC8& mandatoryValue = mandatory->Value();
+ if (mandatoryValue.CompareF(KTrue) == KErrNone || mandatoryValue.CompareF(KString1) == KErrNone)
+ {
+ certMetaInfo.iIsMandatory = KTrueValue;
+ }
+ else if (mandatoryValue.CompareF(KFalse) == KErrNone || mandatoryValue.CompareF(KString0) == KErrNone)
+ {
+ certMetaInfo.iIsMandatory = KFalseValue;
+ }
+ else
+ {
+ LogL(KLogIllegalMandatoryValue, &mandatoryValue);
+ User::Leave(KErrArgument);
+ }
+ }
+ LogParameterL(KItemMandatory, certMetaInfo.iIsMandatory ? KString1 : KString0);
+
+ // Parse system upgrade flag
+ certMetaInfo.iIsSystemUpgrade = 0;
+ const CTestConfigItem* sysUpgrade = aSection.Item(KItemSystemUpgrade);
+ if (sysUpgrade != NULL)
+ {
+ const TDesC8& sysUpgradeValue = sysUpgrade->Value();
+ if (sysUpgradeValue.CompareF(KTrue) == KErrNone || sysUpgradeValue.CompareF(KString1) == KErrNone)
+ {
+ certMetaInfo.iIsSystemUpgrade = KTrueValue;
+ }
+ else if (sysUpgradeValue.CompareF(KFalse) == KErrNone || sysUpgradeValue.CompareF(KString0) == KErrNone)
+ {
+ certMetaInfo.iIsSystemUpgrade = KFalseValue;
+ }
+ else
+ {
+ LogL(KLogIllegalSystemUpgradeValue, &sysUpgradeValue);
+ User::Leave(KErrArgument);
+ }
+ }
+ LogParameterL(KItemSystemUpgrade, certMetaInfo.iIsSystemUpgrade ? KString1 : KString0);
+
+
+ // Parse capabilities
+ certMetaInfo.iCapabilities = ParseCapabilitiesL(aSection);
+
+ // Parse applications
+ RArray<TUid> applications;
+ CleanupClosePushL(applications);
+ ParseApplicationsL(aSection, applications);
+
+ CSWICertStoreToolCert* certInfo = CSWICertStoreToolCert::NewLC(certData->Length(),
+ label,
+ iCertificateId++,
+ cert->KeyIdentifierL(),
+ applications,
+ dataStreamId,
+ certMetaInfo);
+ User::LeaveIfError(iCerts.Append(certInfo));
+ CleanupStack::Pop(certInfo);
+ CleanupStack::PopAndDestroy(3, certData); // applications, cert, certData
+ }
+
+void CSWICertStoreTool::CheckCertLabelL(const TDesC& aLabel)
+ {
+ for (TInt i = 0 ; i < iCerts.Count() ; ++i)
+ {
+ if (iCerts[i]->Label().CompareF(aLabel) == 0)
+ {
+ LogL(KLogDuplicateCertLabel);
+ User::Leave(KErrArgument);
+ }
+ }
+ }
+
+HBufC8* CSWICertStoreTool::LoadCertDataL(const TDesC8& aPath)
+ {
+ HBufC* aBuf = HBufC::NewLC(aPath.Length());
+ TPtr path(aBuf->Des());
+ CnvUtfConverter::ConvertToUnicodeFromUtf8(path,aPath);
+
+ RFile file;
+ User::LeaveIfError(file.Open(iFs, path, EFileRead | EFileShareExclusive));
+ CleanupClosePushL(file);
+
+ TInt size;
+ User::LeaveIfError(file.Size(size));
+
+ HBufC8* buf = HBufC8::NewLC(size);
+ TPtr8 ptr = buf->Des();
+ User::LeaveIfError(file.Read(ptr, size));
+
+ CleanupStack::Pop(buf);
+ CleanupStack::PopAndDestroy(&file);
+ CleanupStack::PopAndDestroy(aBuf);
+ return buf;
+ }
+
+TStreamId CSWICertStoreTool::WriteCertDataL(const TDesC8& aData)
+ {
+ RStoreWriteStream stream;
+ TStreamId streamId = stream.CreateLC(*iStore);
+ stream.WriteL(aData);
+ stream.CommitL();
+ CleanupStack::PopAndDestroy(&stream);
+ return streamId;
+ }
+
+TCapabilitySet CSWICertStoreTool::ParseCapabilitiesL(const CTestConfigSection& aSection)
+ {
+ TCapabilitySet capabilities;
+ capabilities.SetEmpty();
+ for (TInt index = 0 ; ; ++index)
+ {
+ const CTestConfigItem* item = aSection.Item(KItemCapability, index);
+ if (item == NULL)
+ {
+ break;
+ }
+ const TDesC8& capName = item->Value();
+ TCapability capability = ECapability_None;
+ TRAPD(err, capability = ParseCapabilityNameL(capName));
+ if (err != KErrNone)
+ {
+ LogL(KLogIllegalCapabilityValue, &item->Value());
+ User::Leave(KErrArgument);
+ }
+ capabilities.AddCapability(capability);
+ LogParameterL(KItemCapability, capName);
+ }
+
+ return capabilities;
+ }
+
+void CSWICertStoreTool::ParseApplicationsL(const CTestConfigSection& aSection, RArray<TUid>& aApplications)
+ {
+ for (TInt index = 0 ; ; ++index)
+ {
+ const CTestConfigItem* item = aSection.Item(KItemApplication, index);
+ if (item == NULL)
+ {
+ break;
+ }
+ const TDesC8& appName = item->Value();
+ TUid application;
+ TRAPD(err, application = ParseApplicationNameL(appName));
+ if (err != KErrNone)
+ {
+ LogL(KLogIllegalApplicationValue, &item->Value());
+ User::Leave(KErrArgument);
+ }
+ User::LeaveIfError(aApplications.Append(application));
+ LogParameterL(KItemApplication, appName);
+ }
+
+ if (aApplications.Count() == 0)
+ {
+ LogL(KLogNoApplications);
+ User::Leave(KErrArgument);
+ }
+ }
+
+void CSWICertStoreTool::OpenInputFileL(const TDesC& aInputFile)
+ {
+ iScript = CTestConfig::NewLC(iFs, KSWICertStoreToolName, aInputFile);
+ CleanupStack::Pop(iScript);
+ }
+
+void CSWICertStoreTool::OpenStoreL(const TDesC& aOutputFile)
+ {
+ iStore = CPermanentFileStore::ReplaceL(iFs, aOutputFile, EFileRead | EFileWrite | EFileShareExclusive);
+ iStore->SetTypeL(KPermanentFileStoreLayoutUid);
+ }
+
+TStreamId CSWICertStoreTool::WriteInfoStreamL()
+ {
+ // Create info stream
+ RStoreWriteStream infoStream;
+ TStreamId streamId = infoStream.CreateLC(*iStore);
+
+ infoStream.WriteInt32L(iCerts.Count());
+ for (TInt i = 0 ; i < iCerts.Count() ; ++i)
+ {
+ iCerts[i]->ExternalizeL(infoStream);
+ }
+
+ // Commit info stream
+ infoStream.CommitL();
+ CleanupStack::PopAndDestroy(&infoStream);
+
+ return streamId;
+ }
+
+void CSWICertStoreTool::WriteRootStreamL(TStreamId aInfoStreamId)
+ {
+ // Create root stream - just contains id of info stream
+ ASSERT(aInfoStreamId != KNullStreamId);
+ RStoreWriteStream rootStream;
+ TStreamId rootStreamId = rootStream.CreateLC(*iStore);
+ iStore->SetRootL(rootStreamId);
+ rootStream << aInfoStreamId;
+ rootStream.CommitL();
+ CleanupStack::PopAndDestroy(&rootStream);
+ iStore->Commit();
+ }
+
+TUid CSWICertStoreTool::ParseApplicationNameL(const TDesC8& aName)
+ {
+ TUid result = KNullUid;
+ if (aName == KApplicationSWInstall)
+ {
+ result = KApplicationSWInstallUid;
+ }
+ else if (aName == KApplicationSWInstallOCSP)
+ {
+ result = KApplicationSWInstallOCSPUid;
+ }
+ else
+ {
+ User::Leave(KErrNotFound);
+ }
+ return result;
+ }
+
+TCapability CSWICertStoreTool::ParseCapabilityNameL(const TDesC8& aName)
+ {
+ TCapability result = ECapability_None;
+
+ if (aName == KCapabilityTCB) result = ECapabilityTCB;
+ else if (aName == KCapabilityCommDD) result = ECapabilityCommDD;
+ else if (aName == KCapabilityPowerMgmt) result = ECapabilityPowerMgmt;
+ else if (aName == KCapabilityMultimediaDD) result = ECapabilityMultimediaDD;
+ else if (aName == KCapabilityReadDeviceData) result = ECapabilityReadDeviceData;
+ else if (aName == KCapabilityWriteDeviceData) result = ECapabilityWriteDeviceData;
+ else if (aName == KCapabilityDRM) result = ECapabilityDRM;
+ else if (aName == KCapabilityTrustedUI) result = ECapabilityTrustedUI;
+ else if (aName == KCapabilityProtServ) result = ECapabilityProtServ;
+ else if (aName == KCapabilityDiskAdmin) result = ECapabilityDiskAdmin;
+ else if (aName == KCapabilityNetworkControl) result = ECapabilityNetworkControl;
+ else if (aName == KCapabilityAllFiles) result = ECapabilityAllFiles;
+ else if (aName == KCapabilitySwEvent) result = ECapabilitySwEvent;
+ else if (aName == KCapabilityNetworkServices) result = ECapabilityNetworkServices;
+ else if (aName == KCapabilityLocalServices) result = ECapabilityLocalServices;
+ else if (aName == KCapabilityReadUserData) result = ECapabilityReadUserData;
+ else if (aName == KCapabilityWriteUserData) result = ECapabilityWriteUserData;
+ else if (aName == KCapabilityLocation) result = ECapabilityLocation;
+ else if (aName == KCapabilitySurroundingsDD) result = ECapabilitySurroundingsDD;
+ else if (aName == KCapabilityUserEnvironment) result = ECapabilityUserEnvironment;
+
+ if (result == ECapability_None)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ return result;
+ }
+