vpnengine/vpnmanager/src/policyimporter.cpp
changeset 0 33413c0669b9
child 2 ef893827b4d1
--- /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 <f32file.h>
+#include <x509cert.h>
+
+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<TUid> 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<TExtVpnPolicyId>(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<TFileName>(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<TFileName>(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<TFileName>(2);
+
+    delete iCurrUserCertList;
+    iCurrUserCertList = NULL;
+    iCurrUserCertList = new (ELeave) CArrayFixFlat<TFileName>(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<TFileName>(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;i<dirList->Count();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<TUid> 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<TFileName>* 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<TFileName>* aCertFileArray)
+    {
+    TFileName rootCa;
+    TInt currCaIndex=0;
+    TInt currIndex=1;
+    TInt keySize = 0;
+    for ( TInt i=0; i<aCertFileArray->Count(); 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; i<aCertFileArray->Count();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);
+    
+    }
+/***/