--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/installationservices/swi/source/sisfile/siscontroller.cpp Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,305 @@
+/*
+* Copyright (c) 2004-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:
+* Definition of the Swi::Sis::CController
+*
+*/
+
+
+/**
+ @file siscontroller.cpp
+*/
+
+#include "siscontroller.h"
+#include "sisinfo.h"
+#include "sissupportedlanguages.h"
+#include "sissupportedoptions.h"
+#include "sisproperties.h"
+#include "sislogo.h"
+#include "sisinstallblock.h"
+#include "sisproperties.h"
+#include "sisprerequisites.h"
+#include "swi/sistruststatus.h"
+#include "certchainconstraints.h"
+#include "sisptrprovider.h"
+#include "log.h"
+
+using namespace Swi::Sis;
+
+
+EXPORT_C /*static*/ CController* CController::NewLC(MSisDataProvider& aDataProvider, TInt64& aBytesRead, TReadTypeBehaviour aTypeReadBehaviour)
+ {
+ CController* self = new(ELeave) CController();
+ CleanupStack::PushL(self);
+ self->ConstructL(aDataProvider, aBytesRead, aTypeReadBehaviour);
+ return self;
+ }
+
+EXPORT_C /*static*/ CController* CController::NewL(MSisDataProvider& aDataProvider, TInt64& aBytesRead, TReadTypeBehaviour aTypeReadBehaviour)
+ {
+ CController* self = NewLC(aDataProvider, aBytesRead, aTypeReadBehaviour);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+EXPORT_C /*static*/ CController* CController::NewLC(MSisDataProvider& aDataProvider, TReadTypeBehaviour aTypeReadBehaviour)
+ {
+ CController* self = new(ELeave) CController();
+ CleanupStack::PushL(self);
+ TInt64 bytesRead=0;
+ self->ConstructL(aDataProvider, bytesRead, aTypeReadBehaviour);
+ return self;
+ }
+
+EXPORT_C /*static*/ CController* CController::NewL(MSisDataProvider& aDataProvider, TReadTypeBehaviour aTypeReadBehaviour)
+ {
+ CController* self = NewLC(aDataProvider, aTypeReadBehaviour);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CController::CController() : iTrust(ESisPackageUnsignedOrSelfSigned)
+ {
+ }
+
+EXPORT_C CController* CController::NewLC(TPtrProvider& aDataProvider, TReadTypeBehaviour aTypeReadBehaviour)
+ {
+ CController* self = new(ELeave) CController();
+ CleanupStack::PushL(self);
+ TInt64 bytesRead(0);
+ self->ConstructL(aDataProvider, bytesRead, aTypeReadBehaviour);
+ return self;
+ }
+
+EXPORT_C CController* CController::NewL(TPtrProvider& aDataProvider, TReadTypeBehaviour aTypeReadBehaviour)
+ {
+ CController* self = NewLC(aDataProvider, aTypeReadBehaviour);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+EXPORT_C CController* CController::NewLC(TPtrProvider& aDataProvider, TInt64& aBytesRead, TReadTypeBehaviour aTypeReadBehaviour)
+ {
+ CController* self = new(ELeave) CController();
+ CleanupStack::PushL(self);
+ self->ConstructL(aDataProvider, aBytesRead, aTypeReadBehaviour);
+ return self;
+ }
+
+EXPORT_C CController* CController::NewL(TPtrProvider& aDataProvider, TInt64& aBytesRead, TReadTypeBehaviour aTypeReadBehaviour)
+ {
+ CController* self = NewLC(aDataProvider, aBytesRead, aTypeReadBehaviour);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+EXPORT_C CController::~CController()
+ {
+ delete iInfo;
+ delete iInstallBlock;
+ delete iLanguages;
+ delete iSupportedOptions;
+ delete iProperties;
+ delete iLogo;
+ delete iPrerequisites;
+ delete iDataIndex;
+ delete iTrustStatus;
+ delete iCertChainConstraints;
+
+ iCertChainIndices.Close();
+ iSignatureCertificateChains.ResetAndDestroy();
+ }
+
+void CController::ConstructL(MSisDataProvider& aDataProvider, TInt64& aBytesRead, TReadTypeBehaviour aTypeReadBehaviour)
+ {
+ iDataOffset=aBytesRead;
+
+ CField::ConstructL(aDataProvider, EFieldTypeController, aBytesRead, aTypeReadBehaviour);
+
+ iInfo=CInfo::NewL(aDataProvider, aBytesRead);
+
+ iSupportedOptions=CSupportedOptions::NewL(aDataProvider, aBytesRead);
+
+ iLanguages=CSupportedLanguages::NewL(aDataProvider, aBytesRead);
+
+ iPrerequisites=CPrerequisites::NewL(aDataProvider, aBytesRead);
+
+ iProperties=CProperties::NewL(aDataProvider, aBytesRead);
+
+ TFieldType fieldType;
+ CField::ReadEnumL<TFieldType,TUint32>(aDataProvider, fieldType, aBytesRead);
+
+ if (fieldType == EFieldTypeLogo)
+ {
+ // Logo present
+ iLogo=CLogo::NewL(aDataProvider, aBytesRead, EAssumeType);
+ iInstallBlock=CInstallBlock::NewL(aDataProvider, aBytesRead);
+ }
+ else if (fieldType == EFieldTypeInstallBlock)
+ {
+ // No logo present
+ iInstallBlock=CInstallBlock::NewL(aDataProvider, aBytesRead, EAssumeType);
+ }
+ else
+ {
+ User::Leave(KErrSISUnexpectedFieldType);
+ }
+
+ ReadMemberCollectionL(aDataProvider, iSignatureCertificateChains, EFieldTypeSignatureCertificateChain, EFieldTypeDataIndex, aBytesRead);
+
+ iDataIndex=CDataIndex::NewL(aDataProvider, aBytesRead, EAssumeType);
+
+ CField::SkipUnknownFieldsL(aDataProvider, aBytesRead - iDataOffset, aBytesRead, aTypeReadBehaviour);
+ CField::EnsureAlignedL(aDataProvider, aBytesRead - iDataOffset, aBytesRead, aTypeReadBehaviour);
+
+ iTrustStatus = new (ELeave)Swi::TSisTrustStatus();
+
+ // Create unconstrained cert chain constraints object; this may be replaced.
+ iCertChainConstraints = CCertChainConstraints::NewL();
+
+ iRemoveWithLastDependent = 0;
+
+ #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ iUserGrantableCapabilities.SetEmpty();
+ #endif
+ }
+
+void CController::ConstructL(TPtrProvider& aDataProvider, TInt64& aBytesRead, TReadTypeBehaviour aTypeReadBehaviour)
+ {
+ iDataOffset=aBytesRead;
+
+ CField::ConstructL(aDataProvider, EFieldTypeController, aBytesRead, aTypeReadBehaviour);
+
+ iInfo=CInfo::NewL(aDataProvider, aBytesRead);
+
+ iSupportedOptions=CSupportedOptions::NewL(aDataProvider, aBytesRead);
+
+ iLanguages=CSupportedLanguages::NewL(aDataProvider, aBytesRead);
+
+ iPrerequisites=CPrerequisites::NewL(aDataProvider, aBytesRead);
+
+ iProperties=CProperties::NewL(aDataProvider, aBytesRead);
+
+ TFieldType fieldType;
+ CField::ReadEnumL<TFieldType,TUint32>(aDataProvider, fieldType, aBytesRead);
+
+ if (fieldType == EFieldTypeLogo)
+ {
+ // Logo present
+ iLogo=CLogo::NewL(aDataProvider, aBytesRead, EAssumeType);
+ iInstallBlock=CInstallBlock::NewL(aDataProvider, aBytesRead);
+ }
+ else if (fieldType == EFieldTypeInstallBlock)
+ {
+ // No logo present
+ iInstallBlock=CInstallBlock::NewL(aDataProvider, aBytesRead, EAssumeType);
+ }
+ else
+ {
+ User::Leave(KErrSISUnexpectedFieldType);
+ }
+
+ ReadMemberCollectionL(aDataProvider, iSignatureCertificateChains, EFieldTypeSignatureCertificateChain, EFieldTypeDataIndex, aBytesRead);
+
+ iDataIndex=CDataIndex::NewL(aDataProvider, aBytesRead, EAssumeType);
+
+ CField::SkipUnknownFieldsL(aDataProvider, aBytesRead - iDataOffset, aBytesRead, aTypeReadBehaviour);
+ CField::EnsureAlignedL(aDataProvider, aBytesRead - iDataOffset, aBytesRead, aTypeReadBehaviour);
+
+ iTrustStatus = new (ELeave)Swi::TSisTrustStatus();
+
+ // Create unconstrained cert chain constraints object; this may be replaced.
+ iCertChainConstraints = CCertChainConstraints::NewL();
+
+ iRemoveWithLastDependent = 0;
+
+ #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+ iUserGrantableCapabilities.SetEmpty();
+ #endif
+ }
+
+EXPORT_C void CController::AddChainIndex(TInt aIndex) const
+ {
+ iCertChainIndices.Append(aIndex);
+ }
+
+EXPORT_C void CController::ClearCertChainIndices() const
+ {
+ iCertChainIndices.Reset();
+ }
+
+EXPORT_C void CController::SetCertChainConstraints(CCertChainConstraints* aConstraints)
+ {
+ // Delete existing cert chain constraints object.
+ delete iCertChainConstraints;
+ iCertChainConstraints=aConstraints;
+ }
+
+EXPORT_C TInt CController::RemoveWithLastDependent() const
+ {
+ return iRemoveWithLastDependent;
+ }
+
+EXPORT_C void CController::SetRemoveWithLastDependent()
+ {
+ iRemoveWithLastDependent = 1;
+ }
+
+
+EXPORT_C CMessageDigest* CController::GenerateControllerHashLC(const TDesC8& aController)
+ {
+ TInt64 infoLength = iInfo->Length() + iInfo->HeaderSize() + iInfo->PaddingSize();
+ TInt64 installBLength = iInstallBlock->Length() + iInstallBlock->HeaderSize() + iInstallBlock->PaddingSize();
+ TInt64 supportLLength = iLanguages->Length() + iLanguages->HeaderSize() + iLanguages->PaddingSize();
+ TInt64 supportOLength = iSupportedOptions->Length() + iSupportedOptions->HeaderSize() + iSupportedOptions->PaddingSize();
+ TInt64 propertiesLength = iProperties->Length() + iProperties->HeaderSize() + iProperties->PaddingSize();
+ TInt64 prerequisitesLength = iPrerequisites->Length() + iPrerequisites->HeaderSize() + iPrerequisites->PaddingSize();
+ TInt64 logoLength = 0;
+
+ if (iLogo)
+ {
+ logoLength = iLogo->Length() + iLogo->HeaderSize() + iLogo->PaddingSize();
+ }
+
+ TInt64 controllerLength = 0;
+ controllerLength = infoLength + installBLength + supportLLength + supportOLength + propertiesLength + prerequisitesLength + logoLength;
+
+ // Length octets are either 4 or 8 bytes but since controllers are loaded into
+ // bytes should ALWAYS be sufficient.
+ TInt offset = 4;
+
+ // Should really modify the length and not the offset skipping the length octets.
+ // This makes the controller hash independent of the signature chains.
+ //
+ // Unfortunately, this is fixed and changing it potentially breaks compatibility
+ // E.g. If the firmware is upgraded without reformatting the system drive then SWI
+ // may think that an application on removable media has not been installed.
+ controllerLength += (Length() > 0x80000000 ? 8 : 4);
+
+ DEBUG_PRINTF4(_L8("GenerateControllerHashLC aController.Length()=%d, offset=%d, controllerLength=%d"),
+ aController.Length(), offset, controllerLength);
+
+ if (offset + controllerLength >= aController.Length())
+ {
+ // Mid will panic if the lengths are outside the buffer.
+ User::Leave(KErrCorrupt);
+ }
+ TPtrC8 ptr;
+ ptr.Set(aController.Mid(offset, controllerLength));
+
+ CMessageDigest* digest = CMessageDigestFactory::NewDigestLC(CMessageDigest::ESHA1);
+ digest->Update(ptr);
+
+ return digest;
+ }