diff -r 000000000000 -r 33413c0669b9 vpnengine/vpnmanager/src/policyimporter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/vpnmanager/src/policyimporter.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,1154 @@ +/* +* Copyright (c) 2003-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "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: Policy importer +* +*/ + + + +#include "policyimporter.h" +#include "vpnapiservant.h" +#include "fileutil.h" +#include "policypatcher.h" +#include "policystore.h" +#include "vpnclientuids.h" +#include "vpnmanagerserverdefs.h" +#include "ikepolparser.h" +#include "pkiutil.h" +#include "cmmanagerutils.h" +#include "log_r6.h" + +#include +#include + +const TInt KDefaultKeySize(1024); + +enum TImportState + { + EStateBeginPolicyImport = 1, + EStateImportCaCert, + EStateAfterImportCaCert, + EStateImportPeerCert, + EStateAfterImportPeerCert, + EStateImportUserPrivKey, + EStateAfterImportUserPrivKey, + EStateAttachCertificate, + EStateAfterAttachCertificate, + EStateImportPinAndPol, + EStateCreateVpnDestination, + EStateEndPolicyImport + }; + +CPolicyImporter* CPolicyImporter::NewL(const RMessage2& aMessage, CVpnApiServant& aVpnApiServant, + CPolicyStore& aPolicyStore, RFs& aFs) + { + LOG_("-> CPolicyImporter::NewL()"); + CPolicyImporter* self = new (ELeave) CPolicyImporter(aMessage, aVpnApiServant, aPolicyStore, aFs); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); // self + LOG_("<- CPolicyImporter::NewL()"); + return self; + } + +CPolicyImporter* CPolicyImporter::NewL(TRequestStatus& aStatus, CVpnApiServant& aVpnApiServant, + CPolicyStore& aPolicyStore, RFs& aFs) + { + LOG_("-> CPolicyImporter::NewL()"); + CPolicyImporter* self = new (ELeave) CPolicyImporter(aStatus, aVpnApiServant, aPolicyStore, aFs); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); // self + LOG_("<- CPolicyImporter::NewL()"); + return self; + } + +CPolicyImporter::CPolicyImporter(const RMessage2& aMessage, CVpnApiServant& aVpnApiServant, + CPolicyStore& aPolicyStore, RFs& aFs) : + CActive(0), iMessage(aMessage), iVpnApiServant(aVpnApiServant), + iPolicyStore(aPolicyStore), iFs(aFs), iFileUtil(aFs) + { + } + +CPolicyImporter::CPolicyImporter(TRequestStatus& aStatus, CVpnApiServant& aVpnApiServant, + CPolicyStore& aPolicyStore, RFs& aFs) : + CActive(0), iExtStatus(&aStatus), iVpnApiServant(aVpnApiServant), + iPolicyStore(aPolicyStore), iFs(aFs), iFileUtil(aFs) + { + } + +void CPolicyImporter::ConstructL() + { + CActiveScheduler::Add(this); + User::LeaveIfError(iPkiService.Connect()); + } + +CPolicyImporter::~CPolicyImporter() + { + LOG_("-> CPolicyImporter::~CPolicyImporter()"); + Cancel(); + iPkiService.Close(); + + delete iPolicyIdList; + + delete iCurrIkeDataArray; + + delete iCurrCaCertList; + delete iCurrPeerCertList; + delete iCurrUserPrivKeyList; + delete iCurrUserCertList; + delete iCurrOtherCaCertList; + + delete iCertFileData; + delete iKeyFileData; + LOG_("<- CPolicyImporter::~CPolicyImporter()"); + } + +TInt CPolicyImporter::RunError(TInt aError) + { + LOG_EVENT_2B(R_VPN_MSG_POLICY_INSTALL_FAIL, iNewPolicyId, NULL, + aError, iImportSinglePolicy); + + ImportComplete(aError); + return KErrNone; + } + +void CPolicyImporter::RunL() + { + ChangeStateL(); + } + +void CPolicyImporter::DoCancel() + { + CancelOngoingOperation(); + if (iImportSinglePolicy) + { + User::RequestComplete(iExtStatus, KErrCancel); + } + else + { + iMessage.Complete(KErrCancel); + } + CleanImportDirectory(); + } + +void CPolicyImporter::GotoState(TInt aState) + { + LOG_1("-> CPolicyImporter::GotoState() STATE %d", aState); + SetNextState(aState); + SetActive(); + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + LOG_("<- CPolicyImporter::GotoState()"); + } + +void CPolicyImporter::SetCurrState(TInt aState) + { + iCurrState = aState; + } + +void CPolicyImporter::SetNextState(TInt aState) + { + iNextState = aState; + } + +TInt CPolicyImporter::CurrState() + { + return iCurrState; + } + +TInt CPolicyImporter::NextState() + { + return iNextState; + } + +void CPolicyImporter::ChangeStateL() + { + switch (NextState()) + { + case EStateBeginPolicyImport: + StateBeginPolicyImportL(); + break; + + case EStateImportCaCert: + StateImportCaCertL(); + break; + + case EStateAfterImportCaCert: + StateAfterImportCaCertL(); + break; + + case EStateImportPeerCert: + StateImportPeerCertL(); + break; + + case EStateAfterImportPeerCert: + StateAfterImportPeerCertL(); + break; + + case EStateImportUserPrivKey: + StateImportUserPrivKeyL(); + break; + + case EStateAfterImportUserPrivKey: + StateAfterImportUserPrivKeyL(); + break; + + case EStateAttachCertificate: + StateAttachCertificateL(); + break; + + case EStateAfterAttachCertificate: + StateAfterAttachCertificateL(); + break; + + case EStateImportPinAndPol: + StateImportPinAndPolL(); + break; + + case EStateCreateVpnDestination: + StateCreateVpnDestinationL(); + break; + + case EStateEndPolicyImport: + StateEndPolicyImportL(); + break; + + default: + User::Panic(KVpnManagerServer, EInvalidImportState); + break; + } + } + +void CPolicyImporter::CancelOngoingOperation() + { + switch (CurrState()) + { + case EStateImportCaCert: + case EStateImportPeerCert: + case EStateImportUserPrivKey: + case EStateAttachCertificate: + iPkiService.CancelPendingOperation(); + iPkiService.Finalize(iPkiOpContext); + break; + + default: + break; + } + } + +void CPolicyImporter::ImportComplete(TInt aReturnValue) + { + LOG_("-> CPolicyImporter::ImportComplete()"); + if (iImportSinglePolicy) + { + User::RequestComplete(iExtStatus, aReturnValue); + } + else + { + iMessage.Complete(aReturnValue); + } + CleanImportDirectory(); + iVpnApiServant.PolicyImportComplete(); + LOG_("<- CPolicyImporter::ImportComplete()"); + } + +void CPolicyImporter::ImportPolicyL(const TDesC& aDir) + { + LOG_("-> CPolicyImporter::ImportPolicyL()"); + iImportSinglePolicy = EFalse; + iNewPolicyId = &iPolicyId; + DoImportPolicyL(aDir); + LOG_("<- CPolicyImporter::ImportPolicyL()"); + } + +void CPolicyImporter::ImportSinglePolicyL(const TDesC& aDir, TVpnPolicyId& aNewPolicyId) + { + LOG_("-> CPolicyImporter::ImportSinglePolicyL()"); + iImportSinglePolicy = ETrue; + iNewPolicyId = &aNewPolicyId; + DoImportPolicyL(aDir); + LOG_("<- CPolicyImporter::ImportSinglePolicyL()"); + } + +void CPolicyImporter::DoImportPolicyL(const TDesC& aDir) + { + LOG_("-> CPolicyImporter::DoImportPolicyL()"); + iImportDir.Copy(aDir); + iCurrPolicyIdIndex = -1; + + BuildPolicyIdListL(); + + if (iPolicyIdList->Count() == 0) + { + ImportComplete(KErrNone); + return; + } + + if (iImportSinglePolicy && iPolicyIdList->Count() != 1) + { + // We're supposed to import a single policy + // only but the import directory contains + // multiple policies... + ImportComplete(KErrArgument); + return; + } + + // All is well, so begin import + GotoState(EStateBeginPolicyImport); + LOG_("<- CPolicyImporter::DoImportPolicyL()"); + } + +void CPolicyImporter::StateBeginPolicyImportL() + { + SetCurrState(EStateBeginPolicyImport); + + iCurrPolicyIdIndex++; + + if (iCurrPolicyIdIndex == iPolicyIdList->Count()) + { + ImportComplete(KErrNone); + return; + } + + iCurrPolicyId.Copy(iPolicyIdList->At(iCurrPolicyIdIndex)); + + ParseIkeDataL(); + + BuildCaCertListL(); + iCurrCaCertIndex = -1; + + BuildPeerCertListL(); + iCurrPeerCertIndex = -1; + + BuildUserPrivKeyAndUserCertListL(); + iCurrUserPrivKeyIndex = -1; + iCurrUserCertIndex = -1; + + BuildOtherCaCertListL(); + iCurrOtherCaCertIndex=-1; + GotoState(EStateImportCaCert); + } + +void CPolicyImporter::StateImportCaCertL() + { + LOG_("CPolicyImporter::StateImportCaCertL() entry"); + SetCurrState(EStateImportCaCert); + + iCurrCaCertIndex++; + + if (iCurrCaCertIndex == iCurrCaCertList->Count()) + { + GotoState(EStateImportPeerCert); + LOG_("CPolicyImporter::StateImportCaCertL() exit (all CA certs imported)"); + return; + } + + delete iCertFileData; + iCertFileData = NULL; + iCertFileData = iFileUtil.LoadFileDataL(iCurrCaCertList->At(iCurrCaCertIndex)); + + iPkiService.StoreCertificateL(EPKICACertificate, KDefaultKeySize, EPKIRSA, *iCertFileData, + &iPkiOpContext, iStatus); + + SetNextState(EStateAfterImportCaCert); + SetActive(); + LOG_("CPolicyImporter::StateImportCaCertL() exit"); + } + +void CPolicyImporter::StateAfterImportCaCertL() + { + SetCurrState(EStateAfterImportCaCert); + + iPkiService.Finalize(iPkiOpContext); + + + if (iStatus == KErrArgument) + { + User::Leave(KVpnErrInvalidCaCertFile); + } + else if (iStatus != KErrNone) + { + User::Leave(iStatus.Int()); + } + + // Set VPN trusted + CX509Certificate* tempCert = CX509Certificate::NewLC(*iCertFileData); + RArray appArray; + CleanupClosePushL(appArray); + appArray.AppendL(TUid::Uid(KUidVpnManager)); + + const TPtrC8* serialNumber = tempCert->DataElementEncoding( + CX509Certificate::ESerialNumber); + const TPtrC8* issuername = tempCert->DataElementEncoding( + CX509Certificate::EIssuerName); + + iPkiService.SetApplicabilityL( + *issuername, + *serialNumber, + appArray); + + CleanupStack::PopAndDestroy(2); // appArray, tempCert + + // Handle the next certificate, if present + GotoState(EStateImportCaCert); + } + +void CPolicyImporter::StateImportPeerCertL() + { + LOG_("CPolicyImporter::StateImportOtherCaCertL() entry"); + SetCurrState(EStateImportPeerCert); + + iCurrOtherCaCertIndex++; + + if (iCurrOtherCaCertIndex == iCurrOtherCaCertList->Count()) + { + GotoState(EStateImportUserPrivKey); + LOG_("CPolicyImporter::StateImportOtherCaCertL() exit (all intermediate CAs imported)"); + return; + } + + delete iCertFileData; + iCertFileData = NULL; + iCertFileData = iFileUtil.LoadFileDataL(iCurrOtherCaCertList->At(iCurrOtherCaCertIndex)); + CIkeData* data = iCurrIkeDataArray->At(iCurrIkeDataIndex); + TPkiServiceStoreType storeType = GetStoreTypeL(data); + iPkiService.SetStoreType(storeType); + + iPkiService.StoreCertificateL(EPKICACertificate, KDefaultKeySize, EPKIRSA, *iCertFileData, + &iPkiOpContext, iStatus); + + SetNextState(EStateAfterImportPeerCert); + SetActive(); + LOG_("CPolicyImporter::StateImportOtherCACertL() exit"); + } + +void CPolicyImporter::StateAfterImportPeerCertL() + { + SetCurrState(EStateAfterImportPeerCert); + + iPkiService.Finalize(iPkiOpContext); + + if (iStatus != KErrNone) + { + User::Leave(iStatus.Int()); + } + + // Handle the next certificate, if present + GotoState(EStateImportPeerCert); + } + +TPkiServiceStoreType CPolicyImporter::GetStoreTypeL(CIkeData* aData) + { + TPkiServiceStoreType ret(EPkiStoreTypeAny); + if (aData->iClientCertType) + { + HBufC8* storename = aData->iClientCertType->GetAsciiDataL(); + CleanupStack::PushL(storename); + LOG(Log::Printf(_L8("CPolicyImporter::BuildPeerCertListL() Store type defined in policy: %S\n"), &(*storename))); + + if (storename->Compare(_L8("DEVICE")) == 0) + { + LOG_("CPolicyImporter::BuildPeerCertListL() Policy uses DEVICE store\n"); + ret = EPkiStoreTypeDevice; + } + else + { + LOG_("CPolicyImporter::BuildPeerCertListL() Policy uses USER store\n"); + ret = EPkiStoreTypeUser; + } + + CleanupStack::PopAndDestroy(storename); + } + else + { + LOG_("CPolicyImporter::GetStoreType() No store type specified in policy"); + } + return ret; + } +void CPolicyImporter::StateImportUserPrivKeyL() + { + LOG_("CPolicyImporter::StateImportUserPrivKeyL() entry"); + SetCurrState(EStateImportUserPrivKey); + + iCurrUserPrivKeyIndex++; + + if (iCurrUserPrivKeyIndex == iCurrUserPrivKeyList->Count()) + { + GotoState(EStateImportPinAndPol); + LOG_("CPolicyImporter::StateImportUserPrivKeyL() exit (all keys imported)"); + return; + } + + delete iKeyFileData; + iKeyFileData = NULL; + iKeyFileData = iFileUtil.LoadFileDataL(iCurrUserPrivKeyList->At(iCurrUserPrivKeyIndex)); + CIkeData* data = iCurrIkeDataArray->At(iCurrIkeDataIndex); + TPkiServiceStoreType storeType = GetStoreTypeL(data); + iPkiService.SetStoreType(storeType); + + iPkiService.StoreKeypair(iCurrKeyId, *iKeyFileData, iStatus); + + SetNextState(EStateAfterImportUserPrivKey); + SetActive(); + LOG_("CPolicyImporter::StateImportUserPrivKeyL() exit"); + } + +void CPolicyImporter::StateAfterImportUserPrivKeyL() + { + SetCurrState(EStateAfterImportUserPrivKey); + + if (iStatus == KErrArgument || iStatus == KErrNotSupported) + { + User::Leave(KVpnErrInvalidUserPrivKeyFile); + } + else if (iStatus != KErrNone) + { + User::Leave(iStatus.Int()); + } + + // Attach user certificates to the imported private key + iCurrIkeDataIndex = -1; + GotoState(EStateAttachCertificate); + } + +void CPolicyImporter::StateAttachCertificateL() + { + LOG_("CPolicyImporter::StateAttachCertificateL() entry"); + SetCurrState(EStateAttachCertificate); + + iCurrIkeDataIndex++; + + if (iCurrIkeDataIndex == iCurrIkeDataArray->Count()) + { + // Import the next private key, if present + GotoState(EStateImportUserPrivKey); + return; + } + + CIkeData* ikeData = iCurrIkeDataArray->At(iCurrIkeDataIndex); + HBufC* fileName(NULL); + TPkiServiceStoreType storeType = GetStoreTypeL(ikeData); + iPkiService.SetStoreType(storeType); + + fileName = iFileUtil.MakeFileName(iImportDir, ikeData->iPrivKey.iData).AllocLC(); + + if (fileName->CompareF(iCurrUserPrivKeyList->At(iCurrUserPrivKeyIndex)) == 0) + { + CleanupStack::PopAndDestroy(fileName); + fileName = NULL; + + fileName = iFileUtil.MakeFileName(iImportDir, ikeData->iOwnCert.iData).AllocLC(); + + delete iCertFileData; + iCertFileData = NULL; + iCertFileData = iFileUtil.LoadFileDataL(*fileName); + + iPkiService.AttachCertificateL(iCurrKeyId, KDefaultKeySize, EPKIRSA, *iCertFileData, + &iPkiOpContext, iStatus); + + SetNextState(EStateAfterAttachCertificate); + SetActive(); + } + else + { + // Attach the next certificate, if present + GotoState(EStateAttachCertificate); + } + CleanupStack::PopAndDestroy(fileName); // fileName + LOG_("CPolicyImporter::StateAttachCertificateL() exit"); + } + +void CPolicyImporter::StateAfterAttachCertificateL() + { + SetCurrState(EStateAfterAttachCertificate); + + iPkiService.Finalize(iPkiOpContext); + + if (iStatus == KErrArgument) + { + User::Leave(KVpnErrInvalidUserCertFile); + } + else if (iStatus != KErrNone) + { + User::Leave(iStatus.Int()); + } + + // Attach the next certificate, if present + GotoState(EStateAttachCertificate); + } + +void CPolicyImporter::StateImportPinAndPolL() + { + LOG_("-> CPolicyImporter::StateImportPinAndPolL()"); + SetCurrState(EStateImportPinAndPol); + + HBufC* pinFile = iFileUtil.MakeFileNameLC(iImportDir, iCurrPolicyId, KPinFileExt); + HBufC* polFile = iFileUtil.MakeFileNameLC(iImportDir, iCurrPolicyId, KPolFileExt); + + if (!iFileUtil.FileExists(*pinFile)) + { + LOG_("<- CPolicyImporter::StateImportPinAndPolL() LEAVE: KVpnErrNoPolicyInfoFile"); + User::Leave(KVpnErrNoPolicyInfoFile); + } + else if (!iFileUtil.FileExists(*polFile)) + { + LOG_("<- CPolicyImporter::StateImportPinAndPolL() LEAVE: KVpnErrNoPolicyFile"); + User::Leave(KVpnErrNoPolicyFile); + } + else + { + PatchPolicyCaCertInfoL(*polFile); + + iPolicyStore.ImportPolicyL(*pinFile, *polFile, iNewPolicyId); + + //iImportSinglePolicy is used when policy is installed via + //OMA DM or ACU. If the policy is installed from .vpn file + //the iImportSinglePolicy is not used. + //The VPN destination is only created in .vpn case. + if (iImportSinglePolicy) + { + GotoState(EStateEndPolicyImport); + } + else + { + GotoState(EStateCreateVpnDestination); + } + } + CleanupStack::PopAndDestroy(2); // polfile, pinfile + LOG_("<- CPolicyImporter::StateImportPinAndPolL()"); + } + +void CPolicyImporter::StateCreateVpnDestinationL() + { + LOG_("-> CPolicyImporter::StateCreateVpnDestinationL()"); + SetCurrState(EStateCreateVpnDestination); + + //Gets the IAP name from policy name + TVpnPolicyInfo* policyInfo = new (ELeave) TVpnPolicyInfo; + CleanupDeletePushL(policyInfo); + + User::LeaveIfError(iPolicyStore.GetPolicyInfo(*iNewPolicyId, *policyInfo)); + + CmManagerUtils::CreateVPNConnectionMethodToIntranetL(*policyInfo, + *(iVpnApiServant.iEventLogger)); + + CleanupStack::PopAndDestroy(); //policyInfo + GotoState(EStateEndPolicyImport); + + LOG_("<- CPolicyImporter::StateCreateVpnDestinationL()"); + } + +void CPolicyImporter::StateEndPolicyImportL() + { + LOG_("-> CPolicyImporter::StateEndPolicyImportL()"); + + STACK_LEFT; + + SetCurrState(EStateEndPolicyImport); + + // Delete the files that were just imported from the import/install directory + + HBufC* fileFilter = iFileUtil.MakeFileNameLC(iImportDir, iCurrPolicyId, KAllFilesPat); + iFileUtil.DeleteFilesL(*fileFilter); + + CleanupStack::PopAndDestroy(); // fileFilter + + LOG_EVENT_2B(R_VPN_MSG_INSTALLED_POLICY_FILE, iNewPolicyId, NULL, 0, iImportSinglePolicy); + + GotoState(EStateBeginPolicyImport); + LOG_("<- CPolicyImporter::StateEndPolicyImportL()"); + } + +void CPolicyImporter::BuildPolicyIdListL() + { + delete iPolicyIdList; + iPolicyIdList = NULL; + iPolicyIdList = new (ELeave) CArrayFixFlat(2); + + TFindFile* fileFinder = new (ELeave) TFindFile(iFs); + CleanupStack::PushL(fileFinder); + + CDir* fileList; + + TInt ret = fileFinder->FindWildByDir(KPinFilePat, iImportDir, fileList); + + if (ret == KErrNone) + { + CleanupStack::PushL(fileList); + + for (TInt i = 0; i < fileList->Count(); i++) + { + TParse* fileNameParser = new (ELeave) TParse(); + CleanupStack::PushL(fileNameParser); + + fileNameParser->Set((*fileList)[i].iName, NULL, NULL); + + TExtVpnPolicyId policyId; + policyId.Copy(fileNameParser->Name()); + + iPolicyIdList->AppendL(policyId); + + CleanupStack::PopAndDestroy(); // fileNameParser + } + CleanupStack::PopAndDestroy(); // fileList + } + CleanupStack::PopAndDestroy(); // fileFinder + } + +void CPolicyImporter::BuildCaCertListL() + { + LOG_("-> CPolicyImporter::BuildCaCertListL()"); + delete iCurrCaCertList; + iCurrCaCertList = NULL; + iCurrCaCertList = new (ELeave) CArrayFixFlat(2); + + TFileName *fileName = new (ELeave) TFileName; + CleanupStack::PushL(fileName); + + LOG_("Pre-for"); + for (TInt i = 0; i < iCurrIkeDataArray->Count(); i++) + { + LOG_("For start"); + CIkeData* ikeData = iCurrIkeDataArray->At(i); + fileName->Zero(); + + if (ikeData->iCAList) + { + LOG_("CAlist found"); + for (TInt j = 0; j < ikeData->iCAList->Count(); j++) + { + LOG_("CA iter start"); + if (ikeData->iCAList->At(j)->iFormat == BIN_CERT) + { + LOG_("Bin cert found"); + *fileName = iFileUtil.MakeFileName(iImportDir, ikeData->iCAList->At(j)->iData); + if (!iFileUtil.FileExists(*fileName)) + { + LOG_("<- CPolicyImporter::BuildCaCertListL() LEAVE (KVpnErrCaCertFileMissing)"); + User::Leave(KVpnErrInvalidCaCertFile); + } + //Makes sure every file name is appended only once. + AppendIfNotFoundL( iCurrCaCertList, fileName ); + } + } + } + } + + CleanupStack::PopAndDestroy(); //fileName + LOG_("<- CPolicyImporter::BuildCaCertListL()"); + } + + +void CPolicyImporter::BuildPeerCertListL() + { + LOG(Log::Printf(_L8("-> CPolicyImporter::BuildPeerCertListL()\n"))); + delete iCurrPeerCertList; + iCurrPeerCertList = NULL; + iCurrPeerCertList = new (ELeave) CArrayFixFlat(2); + + TFileName *fileName = new (ELeave) TFileName; + CleanupStack::PushL(fileName); + + for (TInt i = 0; i < iCurrIkeDataArray->Count(); i++) + { + CIkeData* ikeData = iCurrIkeDataArray->At(i); + fileName->Zero(); + + if (ikeData->iPeerCert.iData.Length() > 0 && + ikeData->iPeerCert.iFormat == BIN_CERT) + { + *fileName = iFileUtil.MakeFileName(iImportDir, ikeData->iPeerCert.iData); + if (!iFileUtil.FileExists(*fileName)) + { + User::Leave(KVpnErrPeerCertFileMissing); + } + AppendIfNotFoundL( iCurrPeerCertList, fileName ); + } + } + + CleanupStack::PopAndDestroy(); //fileName + LOG_("<- CPolicyImporter::BuildPeerCertListL()"); + } + + +void CPolicyImporter::BuildUserPrivKeyAndUserCertListL() + { + LOG_("-> CPolicyImporter::BuildUserPrivKeyAndUserCertListL()"); + delete iCurrUserPrivKeyList; + iCurrUserPrivKeyList = NULL; + iCurrUserPrivKeyList = new (ELeave) CArrayFixFlat(2); + + delete iCurrUserCertList; + iCurrUserCertList = NULL; + iCurrUserCertList = new (ELeave) CArrayFixFlat(2); + + TFileName *fileName = new (ELeave) TFileName; + CleanupStack::PushL(fileName); + + + for (TInt i = 0; i < iCurrIkeDataArray->Count(); i++) + { + CIkeData* ikeData = iCurrIkeDataArray->At(i); + fileName->Zero(); + + if (ikeData->iOwnCert.iData.Length() > 0 && + ikeData->iOwnCert.iFormat == BIN_CERT) + { + //First check that defined user cert is found and if so + //add the file name to the list + + *fileName = iFileUtil.MakeFileName(iImportDir, ikeData->iOwnCert.iData); + if (!iFileUtil.FileExists(*fileName)) + { + User::Leave(KVpnErrInvalidUserCertFile); + } + AppendIfNotFoundL( iCurrUserCertList, fileName ); + + //After the user cert is found check that the assosiated private key + //is found. + if (ikeData->iPrivKey.iData.Length() > 0 && + ikeData->iPrivKey.iFormat == BIN_CERT) + { + fileName->Zero(); + *fileName = iFileUtil.MakeFileName(iImportDir, ikeData->iPrivKey.iData); + if (!iFileUtil.FileExists(*fileName)) + { + User::Leave(KVpnErrInvalidUserPrivKeyFile); + } + AppendIfNotFoundL( iCurrUserPrivKeyList, fileName ); + } + else + { + User::Leave(KVpnErrInvalidPolicyFile); + } + } + } + + CleanupStack::PopAndDestroy(); //fileName + LOG_("<- CPolicyImporter::BuildUserPrivKeyAndUserCertListL()"); + } + +void CPolicyImporter::BuildOtherCaCertListL() + { + LOG(Log::Printf(_L8("-> CPolicyImporter::BuildOtherCACertListL()\n"))); + delete iCurrOtherCaCertList; + iCurrOtherCaCertList = NULL; + iCurrOtherCaCertList = new (ELeave) CArrayFixFlat(2); + TFileName *fileName = new (ELeave) TFileName; + CleanupStack::PushL(fileName); + TFileName *totalPath= new (ELeave) TFileName; + CleanupStack::PushL(totalPath); + CDir* dirList=NULL; + _LIT(KFileSpec, "*ca-?.*er"); + *totalPath=iImportDir; + totalPath->Append(KFileSpec); + + + User::LeaveIfError( + iFs.GetDir(*totalPath, + KEntryAttMaskSupported, + ESortByName, dirList)); + CleanupStack::PushL(dirList); + if ( dirList->Count()>1 ) + { + for (TInt i=0;iCount();i++) + { + *fileName = (*dirList)[i].iName; + *totalPath = iImportDir; + totalPath->Append(*fileName); + AppendIfNotFoundL(iCurrOtherCaCertList, totalPath); + } + } + CleanupStack::PopAndDestroy(dirList); + CleanupStack::PopAndDestroy(totalPath); + + CleanupStack::PopAndDestroy(); //fileName + LOG_("<- CPolicyImporter::BuildOtherCaCertListL()"); + } + +void CPolicyImporter::ParseIkeDataL() + { + LOG_("-> CPolicyImporter::ParseIkeDataL()"); + + HBufC* polFile = iFileUtil.MakeFileNameLC(iImportDir, iCurrPolicyId, KPolFileExt); + + if (!iFileUtil.FileExists(*polFile)) + { + LOG_("<- CPolicyImporter::ParseIkeDataL() LEAVE (KVpnErrNoPolicyFile)"); + User::Leave(KVpnErrNoPolicyFile); + } + + HBufC8* fileData = iFileUtil.LoadFileDataL(*polFile); + CleanupStack::PushL(fileData); + + HBufC* fileData16 = HBufC::NewLC(fileData->Length()); + + fileData16->Des().Copy(*fileData); + + delete iCurrIkeDataArray; + iCurrIkeDataArray = NULL; + iCurrIkeDataArray = CIkeDataArray::NewL(1); + + TIkeParser* ikeParser = new (ELeave) TIkeParser(*fileData16); + CleanupStack::PushL(ikeParser); + ikeParser->ParseIKESectionsL(iCurrIkeDataArray); + + CleanupStack::PopAndDestroy(4); // ikeParser, fileData16, fileData, polFile + LOG_("<- CPolicyImporter::ParseIkeDataL()"); + } + + +void CPolicyImporter::PatchPolicyCaCertInfoL(const TFileName& aPolicyFile) + { + LOG_("-> CPolicyImporter::PatchPolicyCaCertInfoL()"); + HBufC8* policyData = iFileUtil.LoadFileDataL(aPolicyFile); + CleanupStack::PushL(policyData); + + CPolicyPatchInfoList* patchInfoList = BuildPolicyPatchInfoListL(); + CleanupStack::PushL(patchInfoList); + + CPolicyPatcher* patcher = CPolicyPatcher::NewL(); + CleanupStack::PushL(patcher); + + HBufC8* patchedPolicyData = patcher->PatchPolicyL(*policyData, patchInfoList); + CleanupStack::PushL(patchedPolicyData); + + iFileUtil.SaveFileDataL(aPolicyFile, *patchedPolicyData); + + CleanupStack::PopAndDestroy(4); // patchedPolicyData, patcher, patchInfoList, policyData + LOG_("<- CPolicyImporter::PatchPolicyCaCertInfoL()"); + } + +CPolicyPatchInfoList* CPolicyImporter::BuildPolicyPatchInfoListL() + { + LOG_("-> CPolicyImporter::BuildPolicyPatchInfoListL()"); + CPolicyPatchInfoList* patchInfoList = new (ELeave) CPolicyPatchInfoList(2); + CleanupStack::PushL(patchInfoList); + HBufC8* subjectName; + // First, append the CA certs to patch list... + for (TInt i = 0; i < iCurrCaCertList->Count(); i++) + { + + CPolicyPatchInfo* patchInfo = new (ELeave) CPolicyPatchInfo(); + CleanupStack::PushL(patchInfo); + + TParse fileNameParser; + fileNameParser.Set(iCurrCaCertList->At(i), NULL, NULL); + + patchInfo->iCertFileName.Copy(fileNameParser.NameAndExt()); + subjectName = CertSubjectNameL(iCurrCaCertList->At(i)); + CleanupStack::PushL(subjectName); + if ( iCurrOtherCaCertList->Count()>1 && iCurrCaCertList->Count()==1 ) //if other than basic CA certificate exists + { + // Set original intermediate CA untrusted. . + HBufC8* certData = iFileUtil.LoadFileDataL(iCurrCaCertList->At(0)); + CleanupStack::PushL(certData); + CX509Certificate* tempCert = CX509Certificate::NewLC(*certData); + RArray appArray; + CleanupClosePushL(appArray); + const TPtrC8* serialNumber = tempCert->DataElementEncoding( + CX509Certificate::ESerialNumber); + const TPtrC8* issuername = tempCert->DataElementEncoding( + CX509Certificate::EIssuerName); + + iPkiService.SetApplicabilityL( + *issuername, + *serialNumber, + appArray); + + CleanupStack::PopAndDestroy(3); // appArray, tempcert + + //get CA from chain + TFileName rootCAFile=GetCAFromFileListL(*subjectName, iCurrOtherCaCertList); + CleanupStack::PopAndDestroy(subjectName); + subjectName=NULL; + subjectName = CertSubjectNameL(rootCAFile); + CleanupStack::PushL(subjectName); + + //Set highest CA as trusted + certData = iFileUtil.LoadFileDataL(rootCAFile); + CleanupStack::PushL(certData); + tempCert = CX509Certificate::NewLC(*certData); + CleanupClosePushL(appArray); + appArray.AppendL(TUid::Uid(KUidVpnManager)); + serialNumber = tempCert->DataElementEncoding( + CX509Certificate::ESerialNumber); + issuername = tempCert->DataElementEncoding( + CX509Certificate::EIssuerName); + + iPkiService.SetApplicabilityL( + *issuername, + *serialNumber, + appArray); + + CleanupStack::PopAndDestroy(3); // appArray, tempcert, certData + } + patchInfo->SetCertSubjectNameL(*subjectName); + + patchInfoList->AppendL(patchInfo); + CleanupStack::PopAndDestroy(subjectName); + subjectName=NULL; + CleanupStack::Pop(patchInfo); // patcInfo (now owned by the list) + } + + // ... then, append also the user certificates. + for (TInt i = 0; i < iCurrUserCertList->Count(); i++) + { + TInt keySize = 0; + HBufC8* subjectName = CertInfoL(iCurrUserCertList->At(i), keySize); + CleanupStack::PushL(subjectName); + + CPolicyPatchInfo* patchInfo = new (ELeave) CPolicyPatchInfo(); + CleanupStack::PushL(patchInfo); + + TParse fileNameParser; + fileNameParser.Set(iCurrUserCertList->At(i), NULL, NULL); + + patchInfo->iCertFileName.Copy(fileNameParser.NameAndExt()); + patchInfo->SetCertSubjectNameL(*subjectName); + patchInfo->SetUserCertKeyLen(keySize); + + patchInfoList->AppendL(patchInfo); + + CleanupStack::Pop(); // patchInfo (now owned by the list) + CleanupStack::PopAndDestroy(); // subjectName + } + + CleanupStack::Pop(); // patchInfoList, ownership transferred + + LOG_("<- CPolicyImporter::BuildPolicyPatchInfoListL()"); + return patchInfoList; + } + +HBufC8* CPolicyImporter::CertSubjectNameL(const TFileName& aCertFile) + { + TInt keySize = KDoNotGetKeySize; + return CertInfoL(aCertFile,keySize); + } + +void CPolicyImporter::CleanImportDirectory() + { + LOG_("-> CPolicyImporter::CleanImportDirectory()"); + + TRAP_IGNORE( + { + HBufC* fileFilter = iFileUtil.MakeFileNameLC(iImportDir, KNullDesC, KAllFilesPat); + iFileUtil.DeleteFilesL(*fileFilter); + CleanupStack::PopAndDestroy(); + }); + + LOG_("<- CPolicyImporter::CleanImportDirectory()"); + } + +void CPolicyImporter::AppendIfNotFoundL(CArrayFixFlat* aList, + TFileName* aFileName) + { + ASSERT(aList && aFileName); + + TKeyArrayFix arrayKey(0, ECmpFolded); + TInt position; + if ( aList->FindIsq( *aFileName, arrayKey, position ) ) + { + aList->AppendL( *aFileName ); + } + } + +HBufC8* CPolicyImporter::CertInfoL(const TFileName& aCertFile, TInt& aKeySize) + { + HBufC8* certData = iFileUtil.LoadFileDataL(aCertFile); + CleanupStack::PushL(certData); + + HBufC* subjectName = PkiUtil::CertSubjectNameL(*certData); + CleanupStack::PushL(subjectName); + + HBufC8* subjectName8 = HBufC8::NewL(subjectName->Length()); + subjectName8->Des().Copy(*subjectName); + + if(KDoNotGetKeySize != aKeySize) + { + aKeySize = PkiUtil::CertKeySizeL(*certData); + } + + CleanupStack::PopAndDestroy(2); // subjectName, certData + + return subjectName8; + } + +HBufC8* CPolicyImporter::CertIssuerL(const TFileName& aCertFile) + { + HBufC8* certData = iFileUtil.LoadFileDataL(aCertFile); + CleanupStack::PushL(certData); + + HBufC* issuerName = PkiUtil::CertIssuerNameL(*certData); + CleanupStack::PushL(issuerName); + + HBufC8* issuerName8 = HBufC8::NewL(issuerName->Length()); + issuerName8->Des().Copy(*issuerName); + + CleanupStack::PopAndDestroy(2); // subjectName, certData + + return issuerName8; + } + +TFileName CPolicyImporter::GetCAFromFileListL(const TDesC8& aCertSubjectName, CArrayFixFlat* aCertFileArray) + { + TFileName rootCa; + TInt currCaIndex=0; + TInt currIndex=1; + TInt keySize = 0; + for ( TInt i=0; iCount(); i++) + { + HBufC8* certSubjectName = CertInfoL(aCertFileArray->At(i), keySize); + CleanupStack::PushL(certSubjectName); + if ( certSubjectName->Compare(aCertSubjectName) == 0) + currCaIndex=i; + CleanupStack::PopAndDestroy(certSubjectName); + certSubjectName=NULL; + } + + + while ( currIndex< aCertFileArray->Count()) + { + HBufC8* issuerName = CertIssuerL(aCertFileArray->At(currCaIndex)); + CleanupStack::PushL(issuerName); + HBufC8* subjectName = CertInfoL(aCertFileArray->At(currCaIndex), keySize); + CleanupStack::PushL(subjectName); + + for (TInt i=0; iCount();i++) + { + HBufC8* certSubjectName = CertInfoL(aCertFileArray->At(i), keySize); + CleanupStack::PushL(certSubjectName); + if ( certSubjectName->Compare(*issuerName)==0 ) + { + currCaIndex=i; + CleanupStack::PopAndDestroy(certSubjectName); + certSubjectName=NULL; + break; + } + CleanupStack::PopAndDestroy(certSubjectName); + certSubjectName=NULL; + } + + CleanupStack::PopAndDestroy(subjectName); + subjectName=NULL; + CleanupStack::PopAndDestroy(issuerName); + issuerName=NULL; + currIndex++; + } + + return aCertFileArray->At(currCaIndex); + + } +/***/