installationservices/swi/source/sisfile/siscontroller.cpp
changeset 0 ba25891c3a9e
child 25 7333d7932ef7
--- /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;
+	}