--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vpnengine/ikecert/src/ikev2pkiservice.cpp Thu Dec 17 09:14:51 2009 +0200
@@ -0,0 +1,812 @@
+/*
+* Copyright (c) 2008-2009 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: IKEv2 specifig certificate reading related stuff
+*
+*/
+
+#include <x500dn.h>
+#include <x509cert.h>
+#include <asn1dec.h>
+
+#include "ikev2pkiservice.h"
+#include "utlcrypto.h"
+#include "ikecert.h"
+#include "ikecaelem.h"
+#include "ikecalist.h"
+#include "ikedebug.h"
+#include "ikepolparser.h"
+#include "ikev2const.h"
+#include "ikecertconst.h"
+//
+// CIkePkiService Class
+//
+_LIT8(KEmptyString, "");
+
+
+const TInt KDefaultCertificateBufferSize = 2048;
+
+//
+// Certificate field indicators for GetCertificateFieldDERL()
+//
+
+#ifdef _DEBUG
+
+#define SET_ACTIVE DEBUG_LOG2(_L("CIkeV2PkiService::SetActive (0x%x) %d\n"), this, __LINE__);\
+ SetActive()
+
+#else
+
+#define SET_ACTIVE SetActive()
+
+#endif
+
+
+EXPORT_C CIkeV2PkiService* CIkeV2PkiService::NewL(MIkeV2PkiServiceObserver& aObserver, MIkeDebug& aDebug)
+ {
+ CIkeV2PkiService* self = new (ELeave) CIkeV2PkiService(aObserver, aDebug);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+
+CIkeV2PkiService::CIkeV2PkiService(MIkeV2PkiServiceObserver& aObserver, MIkeDebug& aDebug)
+ :CActive(EPriorityStandard),
+ iObserver(aObserver),
+ iDebug(aDebug),
+ iState(EPkiServiceIdle),
+ iCertPtr(NULL, 0)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+
+void CIkeV2PkiService::ConstructL()
+ {
+ User::LeaveIfError(iPkiService.Connect());
+
+ iTrustedCAList = new (ELeave) CIkeCaList(2);
+ iReadCertificate = HBufC8::NewL(KDefaultCertificateBufferSize);
+ iCertPtr.Set(iReadCertificate->Des());
+
+ //The code assumes that these are not NULL.
+ //Reallocated, when needed
+ iSubjName = HBufC8::NewL(2);
+ iRfc822Name = HBufC8::NewL(2);
+ }
+
+
+EXPORT_C CIkeV2PkiService::~CIkeV2PkiService()
+ {
+ Cancel();
+
+ delete iUserCertificate;
+ delete i1Certificate;
+ delete i2Certificate;
+ delete i2CertificateName;
+ delete iTrustedCAList;
+
+ iCasTrustedByPeer.Reset();
+ iCasTrustedByPeer.Close();
+
+ delete iCaName;
+ delete iReadCertificate;
+ delete iSubjName;
+ delete iRfc822Name;
+
+ iPkiService.Close();
+ }
+
+
+void CIkeV2PkiService::DoCancel()
+ {
+
+ iPkiService.CancelPendingOperation();
+ iState = EPkiServiceIdle;
+
+ delete iCaName;
+ iCaName = NULL;
+
+ __ASSERT_DEBUG(iReadCertificate != NULL, User::Invariant());
+ iReadCertificate->Des().Zero();
+
+
+ __ASSERT_DEBUG(iSubjName != NULL, User::Invariant());
+ iSubjName->Des().Zero();
+
+ __ASSERT_DEBUG(iRfc822Name != NULL, User::Invariant());
+ iRfc822Name->Des().Zero();
+
+
+ iCasTrustedByPeer.Reset();
+
+ delete iIkeDataCAList;
+ iIkeDataCAList = NULL;
+
+ iTrustedCAList->ResetAndDestroy();
+ }
+
+
+TInt CIkeV2PkiService::RunError(TInt /*aError*/)
+ {
+ //Currently RunL may leave.
+ //But we seem to ignore the possible leave.
+
+ return KErrNone;
+ }
+
+
+EXPORT_C void CIkeV2PkiService::ReadTrustedUserCertificateL()
+ {
+ __ASSERT_ALWAYS(!IsActive(), User::Invariant());
+ __ASSERT_ALWAYS(iTrustedCAList != NULL, User::Invariant());
+ __ASSERT_ALWAYS(iIkeData->iOwnCert.iOwnCertExists, User::Invariant());
+
+ iCasTrustedByPeer.Reset();
+
+ for (TInt i = 0; i < iTrustedCAList->Count(); ++i)
+ {
+ CIkeCaElem* caElem = (*iTrustedCAList)[i];
+ User::LeaveIfError(iCasTrustedByPeer.Append(caElem));
+ }
+
+
+ iState = EReadingCertificate;
+
+ if (iTrustedCAList->Count() > 0)
+ {
+ CIkeCaElem* CaElem = iCasTrustedByPeer[0];
+ HBufC8* caName = IkeCert::GetCertificateFieldDERL(CaElem->Certificate(), KSubjectName);
+ if (caName == NULL)
+ {
+ User::Leave(KErrArgument);
+ }
+ delete iCaName;
+ iCaName = caName;
+
+ ReadUserCertificateL(*iCaName, EFalse);
+ }
+ else
+ {
+ //No CA's found.
+ //We can't read anything
+ User::Leave(KErrNotFound);
+ }
+ }
+
+
+EXPORT_C TInt CIkeV2PkiService::Ikev2SignatureL(const TDesC8& aTrustedAuthority,
+ const TOwnCertInfo& aOwnCertInfo,
+ const TDesC8& aMsgOctets,
+ TDes8& aSignature, TUint8 aAuthMeth)
+ {
+ __ASSERT_ALWAYS(!IsActive(), User::Invariant());
+
+ TPKIKeyAlgorithm keyAlgorithm = EPKIRSA;
+ TInt length = aOwnCertInfo.iSubjectDnSuffix.Length();
+ if ( length )
+ {
+ delete iSubjName;
+ iSubjName = NULL;
+ iSubjName = HBufC8::NewL(length);
+ iSubjName->Des().Copy(aOwnCertInfo.iSubjectDnSuffix);
+ }
+ else
+ {
+ iSubjName->Des().Zero();
+ }
+
+ length = aOwnCertInfo.iRfc822NameFqdn.Length();
+ if ( length )
+ {
+ delete iRfc822Name;
+ iRfc822Name = NULL;
+ iRfc822Name = HBufC8::NewL(length);
+ iRfc822Name->Des().Copy(aOwnCertInfo.iRfc822NameFqdn);
+ }
+ else
+ {
+ iRfc822Name->Des().Zero();
+ }
+
+ //
+ // Build PKCS1v15 format signature (ASN1 encoded) for RSA and SHA1 for DSA
+ //
+ CUtlMessageDigest* digest = TUtlCrypto::MakeMessageDigesterL(TUtlCrypto::EUtlMessageDigestSha1);
+ CleanupStack::PushL(digest);
+ HBufC8* asn1EncodedHash =NULL;
+ HBufC8* DSSHash = NULL;
+
+ switch( aAuthMeth )
+ {
+ case RSA_DIGITAL_SIGN:
+ asn1EncodedHash = IkeCert::BuildPkcs1v15HashL(digest->Final(aMsgOctets));
+ User::LeaveIfNull(asn1EncodedHash);
+ CleanupStack::PopAndDestroy(digest);
+ CleanupStack::PushL(asn1EncodedHash);
+ User::LeaveIfError(iPkiService.Sign(aTrustedAuthority, *iSubjName, *iRfc822Name,
+ EX509DigitalSignature, aOwnCertInfo.iPrivateKeyLength,
+ keyAlgorithm, *asn1EncodedHash, aSignature));
+ CleanupStack::PopAndDestroy(asn1EncodedHash);
+ DEBUG_LOG(_L("Signing Auth data using RSA key."));
+ break;
+ case DSS_DIGITAL_SIGN:
+ DSSHash = HBufC8::New(20);
+ DSSHash->Des().Append(digest->Final(aMsgOctets));
+ CleanupStack::PopAndDestroy(digest);
+ CleanupStack::PushL(DSSHash);
+ User::LeaveIfError(iPkiService.Sign(aTrustedAuthority, *iSubjName, *iRfc822Name,
+ EX509DigitalSignature, aOwnCertInfo.iPrivateKeyLength,
+ keyAlgorithm, *DSSHash, aSignature));
+ CleanupStack::PopAndDestroy(DSSHash);
+ DEBUG_LOG(_L("Signing Auth data using DSA key."));
+ break;
+ default:
+ DEBUG_LOG1(_L("Authentication method %d not supported when using digital signatures."), aAuthMeth);
+ User::Leave(KErrNotSupported);
+ break;
+ }
+
+ return aSignature.Length();
+ }
+
+
+EXPORT_C const CIkeCaList& CIkeV2PkiService::CaList() const
+ {
+ return *iTrustedCAList;
+ }
+
+
+EXPORT_C const TDesC8& CIkeV2PkiService::UserCertificateData() const
+ {
+ if (iUserCertificate != NULL)
+ {
+ return *iUserCertificate;
+ }
+ else
+ {
+ return KEmptyString;
+ }
+ }
+
+EXPORT_C const TDesC8& CIkeV2PkiService::I2CertificateData() const
+ {
+ if (i2Certificate != NULL)
+ {
+ return *i2Certificate;
+ }
+ else
+ {
+ return KEmptyString;
+ }
+ }
+
+EXPORT_C const TDesC8& CIkeV2PkiService::I1CertificateData() const
+ {
+ if (i1Certificate != NULL)
+ {
+ return *i1Certificate;
+ }
+ else
+ {
+ return KEmptyString;
+ }
+ }
+
+
+EXPORT_C const TDesC8& CIkeV2PkiService::TrustedCaName() const
+ {
+ if ( i2CertificateName != NULL )
+ {
+ return *i2CertificateName;
+ }
+ if (iCaName != NULL)
+ {
+ return *iCaName;
+ }
+ else
+ {
+ return KEmptyString;
+ }
+ }
+
+
+void CIkeV2PkiService::ReadUserCertificateL(const TDesC8& aTrustedAuthority, TBool aGetCACert)
+ {
+ __ASSERT_DEBUG(iReadCertificate != NULL, User::Invariant());
+ //
+ // Read certificate from PKI store using pkiserviceapi
+ //
+ TPKIKeyAlgorithm keyAlgorithm = EPKIRSA;
+ TPKICertificateOwnerType ownerType;
+ TUint keySize = 0;
+
+ if ( aGetCACert )
+ {
+ ownerType = EPKICACertificate;
+
+ //Init CA cert ident data.
+ //aTrustedAuthority (issuer) checking for CA certs is not supported.
+ //__ASSERT_ALWAYS(aTrustedAuthority.Length() == 0, User::Invariant());
+ if ( aTrustedAuthority.Length() == 0 )
+ {
+ delete iSubjName;
+ iSubjName = NULL;
+ iSubjName = iCaName->AllocL();
+ iRfc822Name->Des().Zero();
+ }
+ }
+ else
+ {
+ ownerType = EPKIUserCertificate;
+ TInt length = iIkeData->iOwnCert.iSubjectDnSuffix.Length();
+ if ( length )
+ {
+ delete iSubjName;
+ iSubjName = NULL;
+ iSubjName = HBufC8::NewL(length);
+ iSubjName->Des().Copy(iIkeData->iOwnCert.iSubjectDnSuffix);
+ }
+ else
+ {
+ iSubjName->Des().Zero();
+ }
+
+ length = iIkeData->iOwnCert.iRfc822NameFqdn.Length();
+ if ( length )
+ {
+ delete iRfc822Name;
+ iRfc822Name = NULL;
+ iRfc822Name = HBufC8::NewL(length);
+ iRfc822Name->Des().Copy(iIkeData->iOwnCert.iRfc822NameFqdn);
+ }
+ else
+ {
+ iRfc822Name->Des().Zero();
+ }
+ keySize = iIkeData->iOwnCert.iPrivateKeyLength;
+ }
+ iPkiService.ReadCertificateL(aTrustedAuthority,
+ *iSubjName, *iRfc822Name,
+ ownerType, keySize,
+ keyAlgorithm, iCertPtr,
+ &iResArray, iStatus);
+ SET_ACTIVE;
+ }
+
+
+void CIkeV2PkiService::CIkeV2PkiServiceApplUidArrayCleanup(TAny* any)
+ {
+ RArray<TUid>* applUidList = reinterpret_cast<RArray<TUid>*>(any);
+ applUidList->Reset();
+ applUidList->Close();
+ delete applUidList;
+ }
+
+
+void CIkeV2PkiService::RunL()
+ {
+ DEBUG_LOG1(_L("CIkeV2PkiService::RunL: Status %d"), iStatus.Int());
+
+ //
+ // A PKI service operation completed. Take actions according to
+ // iOperation code
+ //
+
+ TInt err = KErrNone;
+
+ TInt status = iStatus.Int();
+
+ iPkiService.Finalize(iResArray);
+ iResArray = NULL;
+
+
+ switch ( iState )
+ {
+ case EBuildingCaList:
+ TRAP(err, BuildingCaListRunL());
+ break;
+ case EReadingCertificate:
+ TRAP(err, ReadUserCertificateRunL());
+ break;
+ case EReadingCertificateChain:
+ TRAP(err, ReadCertificateChainRunL());
+ break;
+ default:
+ DEBUG_LOG(_L("RunL called in unknown state"));
+ User::Invariant();
+ break;
+ }
+
+ if ( err != KErrNone )
+ {
+ DEBUG_LOG(_L("Operation completed. Signalling observer."));
+
+ SignalObserverL(err);
+ }
+ }
+
+
+void CIkeV2PkiService::ReadUserCertificateRunL()
+ {
+ //
+ // A Certificate has been read PKI store.
+ // Build X509 certificate object from certificate data
+ //
+ switch(iStatus.Int())
+ {
+ case KErrNone:
+ iUserCertificate = iReadCertificate->AllocL();
+ iReadCertificate->Des().Zero();
+ SignalObserverL(KErrNone);
+ break;
+ case KPKIErrBufferTooShort:
+ {
+ //
+ // Allocate a new buffer for ASN1 coded certificate read from PKI store
+ // Buffer size is now asked from pkiserviceapi
+ //
+ TInt realCertSize;
+ User::LeaveIfError(iPkiService.GetRequiredBufferSize(realCertSize));
+
+ delete iReadCertificate;
+ iReadCertificate = NULL;
+
+ iReadCertificate = HBufC8::NewL(realCertSize);
+ iCertPtr.Set(iReadCertificate->Des());
+
+ ReadUserCertificateL(*iCaName, EFalse);
+ }
+ break;
+ case KPKIErrNotFound:
+ {
+ //
+ // Get next user certificate from PKI store using either Key
+ // identifier or CA name as read argument
+ //
+ iCasTrustedByPeer.Remove(0);
+ if ( iCasTrustedByPeer.Count() > 0 )
+ {
+
+ CIkeCaElem* CaElem = iCasTrustedByPeer[0];
+ HBufC8* caName = IkeCert::GetCertificateFieldDERL(CaElem->Certificate(), KSubjectName);
+ if (caName == NULL)
+ {
+ User::Leave(KErrArgument);
+ }
+ delete iCaName;
+ iCaName = caName;
+ caName=NULL;
+ delete caName;
+ ReadUserCertificateL(*iCaName, EFalse);
+ }
+ else
+ {
+ User::Leave(KErrNotFound);
+ }
+ }
+ break;
+ case KErrNotFound:
+ ReadCertificateChainL();
+ break;
+ default:
+ User::Leave(iStatus.Int());
+ break;
+ }
+ }
+
+
+void CIkeV2PkiService::BuildingCaListRunL()
+ {
+
+ switch(iStatus.Int())
+ {
+ case KErrNone:
+ {
+ iIkeDataCAList->Delete(0);
+
+ ASSERT(iReadCertificate);
+ HBufC8* caCert = iReadCertificate; // Link CA buffer to CIkeCaElem
+ CleanupStack::PushL(caCert);
+
+ iReadCertificate = NULL;
+ iReadCertificate = HBufC8::NewL(KDefaultCertificateBufferSize);
+ iCertPtr.Set(iReadCertificate->Des());
+
+
+ CIkeCaElem* caElem = CIkeCaElem::NewL(caCert);
+ CleanupStack::Pop(caCert);
+ CleanupStack::PushL(caElem);
+
+ //Append ca cert to list, if not already present.
+ if (iTrustedCAList->FindCaElem(caElem->KeyHash()) == NULL)
+ {
+ iTrustedCAList->AppendL(caElem);
+ CleanupStack::Pop(caElem);
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy(caElem);
+ }
+
+ if (iIkeDataCAList->Count() > 0)
+ {
+ ImportNextCaElemFromIkeDataListL();
+ }
+ else
+ {
+
+ if (iIkeData->iOwnCert.iOwnCertExists)
+ {
+ ReadTrustedUserCertificateL();
+ }
+ else
+ {
+ SignalObserverL(KErrNone);
+ }
+ }
+ }
+ break;
+ case KPKIErrBufferTooShort:
+ {
+
+ DEBUG_LOG(_L("Buffer too short"));
+
+ TInt certSize = 0;
+ User::LeaveIfError(iPkiService.GetRequiredBufferSize(certSize));
+
+ __ASSERT_DEBUG(iCertPtr.MaxLength() < certSize, User::Invariant());
+
+ delete iReadCertificate;
+ iReadCertificate = NULL;
+ iReadCertificate = HBufC8::NewL(certSize);
+ iCertPtr.Set(iReadCertificate->Des());
+
+ //Tries to reimport the certificate.
+ ImportNextCaElemFromIkeDataListL();
+ }
+ break;
+ default:
+ DEBUG_LOG1(_L("Error code %d"), iStatus.Int());
+ User::Leave(iStatus.Int());
+ break;
+ }
+ }
+
+
+EXPORT_C void CIkeV2PkiService::InitIkeV2PkiService(const CIkeData* aIkeData)
+ {
+ __ASSERT_DEBUG(iState == EPkiServiceIdle, User::Invariant());
+ __ASSERT_DEBUG(iIkeDataCAList == NULL, User::Invariant());
+ __ASSERT_DEBUG(aIkeData->iCAList != NULL, User::Invariant());
+ __ASSERT_DEBUG(aIkeData->iCAList->Count() > 0, User::Invariant());
+ __ASSERT_DEBUG(iIkeData == NULL, User::Invariant());
+
+ iIkeData = aIkeData;
+
+ iState = EBuildingCaList;
+ TRAPD(err, InitIkeV2PkiServiceL());
+ if (err != KErrNone)
+ {
+ iStatus = KRequestPending;
+ SET_ACTIVE;
+
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, err);
+ }
+ }
+
+
+void CIkeV2PkiService::InitIkeV2PkiServiceL()
+ {
+ if (iIkeData->iClientCertType != NULL)
+ {
+ if (iIkeData->iClientCertType->GetData().Compare(_L("DEVICE")) == 0)
+ {
+ User::LeaveIfError(iPkiService.SetStoreType(EPkiStoreTypeDevice));
+ }
+ else
+ {
+ User::LeaveIfError(iPkiService.SetStoreType(EPkiStoreTypeUser));
+ }
+ }
+
+ iIkeDataCAList = new (ELeave) CArrayFixFlat<TCertInfo>(2);
+ for (TInt i = 0; i < iIkeData->iCAList->Count(); ++i)
+ {
+ const TCertInfo* info = (*iIkeData->iCAList)[i];
+ iIkeDataCAList->AppendL(*info);
+ }
+
+ ImportNextCaElemFromIkeDataListL();
+ }
+
+
+void CIkeV2PkiService::ImportNextCaElemFromIkeDataListL()
+ {
+ __ASSERT_DEBUG(iIkeDataCAList != NULL, User::Invariant());
+ __ASSERT_DEBUG(iIkeDataCAList->Count() > 0, User::Invariant());
+
+ const TCertInfo certInfo = (*iIkeDataCAList)[0];
+ switch(certInfo.iFormat)
+ {
+ case CA_NAME:
+ delete iSubjName;
+ iSubjName = NULL;
+ iSubjName = HBufC8::NewL(certInfo.iData.Length());
+ iSubjName->Des().Copy(certInfo.iData);
+ iPkiService.ReadCertificateL(KEmptyString,
+ *iSubjName, KEmptyString,
+ EPKICACertificate, 0,
+ EPKIRSA, iCertPtr,
+ &iResArray, iStatus);
+ SET_ACTIVE;
+ break;
+ case KEY_ID:
+ if (!IkeParser::TextToHexOctets(certInfo.iData, iCertKeyId))
+ {
+ User::Leave(KErrArgument);
+ }
+ iPkiService.ReadCertificateL(iCertKeyId, iCertPtr,
+ &iResArray, iStatus);
+ SET_ACTIVE;
+ break;
+ case APPL_UID:
+ {
+ //Get the list of applicable CA certs and appends it
+ //to the original list, which was defined in the policy.
+ //After this removes the currently handled node and
+ //calls the method recursively.
+ RArray<TUid>* applUidList = IkeParser::GetApplUidListL(certInfo.iData);
+ CleanupStack::PushL(TCleanupItem(CIkeV2PkiServiceApplUidArrayCleanup,
+ applUidList));
+
+ CArrayFix<TCertificateListEntry>* applicableCaCertList;
+ iPkiService.ListApplicableCertificatesL(*applUidList, applicableCaCertList);
+
+ CleanupStack::PopAndDestroy(); //applUidList
+
+ if (applicableCaCertList->Count() > 0)
+ {
+ CleanupStack::PushL(applicableCaCertList);
+ TCertInfo* info = new (ELeave) TCertInfo;
+ CleanupDeletePushL(info);
+ for (TInt i = 0; i < applicableCaCertList->Count(); i++)
+ {
+ const TCertificateListEntry& entry = (*applicableCaCertList)[i];
+ info->iFormat = CA_NAME;
+ info->iData.Zero();
+ info->iData.Copy(entry.iIdentitySubjectName);
+
+ iIkeDataCAList->AppendL(*info);
+ DEBUG_LOG1(_L("Appending Applicable cert to the list (%S)"), &(info->iData));
+
+ }
+
+ CleanupStack::PopAndDestroy(info);
+ CleanupStack::PopAndDestroy(applicableCaCertList);
+
+ iIkeDataCAList->Delete(0);
+ ImportNextCaElemFromIkeDataListL();
+ }
+ else
+ {
+ delete applicableCaCertList;
+ applicableCaCertList = NULL;
+
+ iStatus = KRequestPending;
+ SET_ACTIVE;
+
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNotFound);
+ }
+ }
+ break;
+ default:
+ User::Leave(KErrArgument);
+ break;
+ }
+ }
+
+void CIkeV2PkiService::ReadCertificateChainL()
+ {
+ delete iCaName;
+ iCaName = NULL;
+ iCaName = IkeCert::GetCertificateFieldDERL(iCasTrustedByPeer[0]->Certificate(), KSubjectName);;
+ iState = EReadingCertificateChain;
+ ReadUserCertificateL(KEmptyString, EFalse);
+ }
+
+void CIkeV2PkiService::ReadCertificateChainRunL()
+ {
+ TInt err;
+ HBufC8* issuerName=NULL;
+ TRAP(err, issuerName = IkeCert::GetCertificateFieldDERL(iReadCertificate, KIssuerName));
+ if (err!=KErrNone)
+ {
+ err=KKmdIkeNoCertFoundErr;
+ User::Leave(err);
+ }
+ if ( issuerName->Compare(iCaName->Des())==0)
+ {
+ iReadCertificate->Des().Zero();
+ delete issuerName;
+ issuerName = NULL;
+ SignalObserverL(KErrNone);
+ }
+ else
+ {
+ delete issuerName;
+ issuerName = NULL;
+ delete iCaName;
+ iCaName = NULL;
+ iCaName = IkeCert::GetCertificateFieldDERL(iReadCertificate, KIssuerName);
+ delete iSubjName;
+ iSubjName = NULL;
+ iSubjName = iCaName->AllocL();
+ if ( !iUserCertificate)
+ iUserCertificate = iReadCertificate->AllocL();
+ else if ( !i2Certificate )
+ {
+ i2Certificate = iReadCertificate->AllocL();
+ i2CertificateName= IkeCert::GetCertificateFieldDERL(i2Certificate, KSubjectName);
+ }
+ else if ( !i1Certificate)
+ i1Certificate = iReadCertificate->AllocL();
+
+ iPkiService.ReadCertificateL(KEmptyString,
+ *iSubjName, KEmptyString,
+ EPKICACertificate, 0,
+ EPKIRSA, iCertPtr,
+ &iResArray, iStatus);
+ SET_ACTIVE;
+ }
+
+ }
+
+void CIkeV2PkiService::SignalObserverL(TInt aStatus)
+{
+ DEBUG_LOG1(_L("CIkeV2PkiService::SignalObserverL: Signalling with %d"), aStatus);
+
+ if (aStatus != KErrNone)
+ {
+ delete iUserCertificate;
+ iUserCertificate = NULL;
+
+ delete iCaName;
+ iCaName = NULL;
+
+ iCertPtr.Zero();
+
+ iTrustedCAList->ResetAndDestroy(); // Trusted CA certificate list
+
+ }
+
+ iIkeData = NULL;
+
+ iSubjName->Des().Zero();
+ iRfc822Name->Des().Zero();
+
+ iCertKeyId.Zero();
+ iResArray = NULL;
+
+ iCasTrustedByPeer.Reset();
+
+ delete iIkeDataCAList;
+ iIkeDataCAList = NULL;
+
+ iState = EPkiServiceIdle;
+ iObserver.IkeV2PkiInitCompleteL(aStatus);
+}