diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2acquire.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2acquire.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,531 @@ +/* +* Copyright (c) 2003-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 Acquire definition +* Class CIkev2Acquire is a IKEv2 specific data structure +* containing information needed, when establishing a new +* IPsec SA +*/ + +#include + +#include "ikev2acquire.h" +#include "pfkeymsg.h" +#include "ipsecproposal.h" +#include "ipsecselectors.h" +#include "ikev2payloads.h" +#include "ikev2ipsecsarekeydata.h" + +_LIT8(KZeroDesc, ""); +// +// +// CIkev2Acquire +// +// This class is used to handle PFKEY Acquire primitives received from +// Ipsec plug-in. +// +// +CIkev2Acquire::CIkev2Acquire(TInt aId) +:iId(aId), iSPIIn(0), iSPIOut(0), iSPIToBeRekeyed(0), iDHGroup(0), + iTransport(EFalse), iResponse(EFalse), iSrcSpecific(ETrue), iForVirtualIp(EFalse), + iReplayWindow(0), iProtocol(SADB_SATYPE_ESP), iPfKeyPid(0), iPfKeySeq(0), + iHard(0,0,0,0), iSoft(0,0,0,0), + iSA(0), iTS_i(0), iTS_r(0), iLocalId(0), iRemoteId(0), iNext(0) + { + } + + +CIkev2Acquire::~CIkev2Acquire() +{ + delete iSA; + iSA = NULL; + delete iTS_i; + iTS_i = NULL; + delete iTS_r; + iTS_r = NULL; + delete iLocalId; + iLocalId = NULL; + delete iRemoteId; + iRemoteId = NULL; +} + +void CIkev2Acquire::ConstructL(const TPfkeyMessage& aReq, const TInetAddr& aLocalAddr, + TUint16 aDHGroup, TBool aImplicitSa, + const TIpsecSaSpec* aSaSpec, const CIpsecSARekeyData* aRekeyData) +{ + SetIpsecProtocol(aReq.iBase.iMsg->sadb_msg_satype); + SetPid(aReq.iBase.iMsg->sadb_msg_pid); + SetSeq(aReq.iBase.iMsg->sadb_msg_seq); + iSrcSpecific = !(aReq.iSrcAddr.iAddr->IsUnspecified()); + + if (!aRekeyData) + { + // SADB_ACQUIRE was received + if ( aReq.iProposal.iComb->sadb_comb_flags & SADB_SAFLAGS_PFS ) + { + iDHGroup = (TUint32)aDHGroup; + } + + if ( aReq.iProposal.iComb->sadb_comb_flags & SADB_SAFLAGS_TUNNEL ) + { + iTransport = EFalse; + } + else + { + iTransport = ETrue; + } + + iHard.iAllocations = aReq.iProposal.iComb->sadb_comb_hard_allocations; + iHard.iBytes = aReq.iProposal.iComb->sadb_comb_hard_bytes; + iHard.iAddtime = aReq.iProposal.iComb->sadb_comb_hard_addtime; + iHard.iUsetime = aReq.iProposal.iComb->sadb_comb_hard_usetime; + + iSoft.iAllocations = aReq.iProposal.iComb->sadb_comb_soft_allocations; + iSoft.iBytes = aReq.iProposal.iComb->sadb_comb_soft_bytes; + iSoft.iAddtime = aReq.iProposal.iComb->sadb_comb_soft_addtime; + iSoft.iUsetime = aReq.iProposal.iComb->sadb_comb_soft_usetime; + + SetReplayWindow(aReq.iProposal.iExt->sadb_prop_replay); + + // + // Build SA payload (including Proposal and Transform payload) + // using parameters in TPfkeyMessage + // + if ( aImplicitSa ) + { + aDHGroup = 0; // No D-H group used with ipmplicit SA although PFS defined + } + iSA = IpsecProposal::BuildIpsecSaRequestL(aReq, aDHGroup); + + // + // Build Traffic selectors using parameters in TPfkeyMessage. + // For some reason the selectors are build using identity + // fields. + // + IpsecSelectors::BuildTrafficSelectorsL(this, aLocalAddr, + aReq.iSrcIdent, aReq.iDstIdent, + aReq.iDstAddr.iExt->sadb_address_proto); + // + // Store identity information from TPfkeyMessage to Acquire + // + if ( aReq.iSrcIdent.iExt ) + { + iLocalId = HBufC8::NewL(aReq.iSrcIdent.iData.Length()); + iLocalId->Des().Copy(aReq.iSrcIdent.iData); + } + else + { + iLocalId = KZeroDesc().AllocL(); + } + + if ( aReq.iDstIdent.iExt ) + { + iRemoteId = HBufC8::NewL(aReq.iDstIdent.iData.Length()); + iRemoteId->Des().Copy(aReq.iDstIdent.iData); + } + else + { + iRemoteId = KZeroDesc().AllocL(); + } + } + else + { + // SADB_EXPIRE was received due to soft lifetime expiration + TUint16 flags = (TUint16)(aReq.iSa.iExt->sadb_sa_flags | (aSaSpec->iTransportMode ? 0 : SADB_SAFLAGS_TUNNEL)); + if ( flags & SADB_SAFLAGS_PFS ) + { + iDHGroup = (TUint32)aDHGroup; + } + + if ( flags & SADB_SAFLAGS_TUNNEL ) + { + iTransport = EFalse; + } + else + { + iTransport = ETrue; + } + + if ( aImplicitSa ) + { + aDHGroup = 0; // No D-H group used with ipmplicit SA although PFS defined + } + + iSA = IpsecProposal::BuildIpsecSaRequestL(iProtocol, + aSaSpec->iEalg, aSaSpec->iEalgLen, aSaSpec->iAalg, + flags, aDHGroup); + + iReplayWindow = aRekeyData->ReplayWindow(); + iHard = aRekeyData->HardLifetime(); + iSoft = aRekeyData->SoftLifetime(); + + iTS_i = aRekeyData->TsIL(); + iTS_r = aRekeyData->TsRL(); + + + iLocalId = aRekeyData->LocalId().AllocL(); + iRemoteId = aRekeyData->RemoteId().AllocL(); + + iResponse = EFalse; + } +} + + +CIkev2Acquire* CIkev2Acquire::NewL(const TPfkeyMessage& aPfkeyMessage, TUint32 aId, + const TInetAddr& aLocalAddr, TUint16 aDHGroup, TBool aImplicitSa, + const TIpsecSaSpec* aSaSpec, const CIpsecSARekeyData* aRekeyData) +{ + CIkev2Acquire* Acquire = new (ELeave)CIkev2Acquire(aId); + CleanupStack::PushL(Acquire); + Acquire->ConstructL(aPfkeyMessage, aLocalAddr, aDHGroup, aImplicitSa, aSaSpec, aRekeyData); + CleanupStack::Pop(Acquire); + return Acquire; +} + + +void CIkev2Acquire::AddIpsecSpiToSa(const TDesC8& aSpi) + { + __ASSERT_DEBUG(aSpi.Length() == 4, User::Invariant()); + + TUint8* saBuffer = const_cast(iSA->Ptr()); + TProposalIkev2* Prop = TProposalIkev2::Cast(saBuffer); + + while ( Prop ) + { + TUint32 spiValue = 0; + TPtr8 spiValueDesc(reinterpret_cast(&spiValue), sizeof(spiValue)); + spiValueDesc = aSpi; + Prop->SetIpsecSPI(spiValue); + if ( !Prop->Last() ) + { + Prop = TProposalIkev2::Cast(TPayloadIkev2::Cast(Prop)->Next()); + } + else + { + Prop = NULL; + } + } + } + + +CIkev2Acquire* CIkev2Acquire::NewL(TUint32 aId, HBufC8* aSa, + CArrayFix* aTS_i, + CArrayFix* aTS_r ) +{ + CIkev2Acquire* Acquire = new (ELeave)CIkev2Acquire(aId); + Acquire->iSA = aSa; + Acquire->iTS_i = aTS_i; + Acquire->iTS_r = aTS_r; + return Acquire; +} + +void CIkev2Acquire::Link(CIkev2Acquire* aAcquire, CIkev2Acquire** aAnchor) +{ + ASSERT(aAcquire && aAnchor); + aAcquire->iNext = NULL; + CIkev2Acquire* Last = *aAnchor; + if ( Last ) + { + while ( Last->iNext ) + { + Last = Last->iNext; + } + Last->iNext = aAcquire; + } + else *aAnchor = aAcquire; +} + +CIkev2Acquire* CIkev2Acquire::Find(TUint32 aId, CIkev2Acquire** aAnchor, TBool aRemove) +{ + ASSERT(aAnchor); + CIkev2Acquire* Prev = NULL; + CIkev2Acquire* Elem = *aAnchor; + while ( Elem ) + { + if ( Elem->iId == aId ) + { + if ( aRemove ) + { + if ( Prev ) + Prev->iNext = Elem->iNext; + else *aAnchor = Elem->iNext; + } + break; + } + Prev = Elem; + Elem = Elem->iNext; + } + return Elem; +} + +CIkev2Acquire* CIkev2Acquire::GetNext(CIkev2Acquire** aAnchor, TBool aResponse) +{ + ASSERT(aAnchor); + CIkev2Acquire* Elem = *aAnchor; + while ( Elem ) + { + if ( Elem->SPI_In().Length() > 0 && (Elem->Response() == aResponse) ) + { + RemoveFromQue(Elem->Id(), aAnchor); + break; + } + Elem = Elem->iNext; + } + return Elem; +} + +TBool CIkev2Acquire::Responding(CIkev2Acquire** aAnchor) +{ + ASSERT(aAnchor); + CIkev2Acquire* Elem = *aAnchor; + while ( Elem ) + { + if ( Elem->Response() ) + { + return ETrue; + } + Elem = Elem->iNext; + } + return EFalse; +} + + +void CIkev2Acquire::PurgeQue(CIkev2Acquire** aAnchor) +{ + ASSERT(aAnchor); + CIkev2Acquire* Elem = *aAnchor; + while ( Elem ) + { + RemoveFromQue(Elem->Id(), aAnchor); + delete Elem; + Elem = *aAnchor; + } +} + +void CIkev2Acquire::SetFirst(CIkev2Acquire* aAcquire, CIkev2Acquire** aAnchor) + { + ASSERT(aAcquire && aAnchor); + aAcquire->iNext = *aAnchor; + *aAnchor = aAcquire; + } + +CIkev2Acquire* CIkev2Acquire::PeekFirst(CIkev2Acquire** aAnchor) + { + return *aAnchor; + } + +CIkev2Acquire* CIkev2Acquire::RemoveFromQue(TUint32 aId, CIkev2Acquire** aAnchor) + { + return CIkev2Acquire::Find(aId, aAnchor, ETrue); + } + +TUint32 CIkev2Acquire::Id() + { + return iId; + } + +TPtrC8 CIkev2Acquire::SPI_In() + { + return iSPIIn; + } + +TPtrC8 CIkev2Acquire::SPI_Out() + { + return iSPIOut; + } + +TPtrC8 CIkev2Acquire::SPI_ToBeRekeyed() + { + return iSPIToBeRekeyed; + } + +void CIkev2Acquire::SetSPI_In(const TDesC8& aSPI) + { + iSPIIn = aSPI; + } + +void CIkev2Acquire::SetSPI_Out(const TDesC8& aSPI) + { + iSPIOut = aSPI; + } + +void CIkev2Acquire::SetSPI_ToBeRekeyed(const TDesC8& aSPI) + { + iSPIToBeRekeyed = aSPI; + } + +TUint16 CIkev2Acquire::DHGroup() + { + return (TUint16)iDHGroup; + } + +void CIkev2Acquire::DHGroup(TUint16 aDHGroup) + { + iDHGroup = aDHGroup; + } + +TBool CIkev2Acquire::Transport() + { + return iTransport; + } + +void CIkev2Acquire::SetTransport() + { + iTransport = ETrue; + } + +TBool CIkev2Acquire::Response() + { + return iResponse; + } + +void CIkev2Acquire::SetResponse() + { + iResponse = ETrue; + } + +void CIkev2Acquire::SetHardLifetime(const TIpsecSALifetime& aHard ) + { + iHard = aHard; + } + +TIpsecSALifetime* CIkev2Acquire::HardLifetime() + { + return &iHard; + } + +void CIkev2Acquire::SetSoftLifetime(const TIpsecSALifetime& aSoft ) + { + iSoft = aSoft; + } + +TIpsecSALifetime* CIkev2Acquire::SoftLifetime() + { + return &iSoft; + } + +TUint8 CIkev2Acquire::ReplayWindow() + { + return (TUint8)iReplayWindow; + } + +void CIkev2Acquire::SetReplayWindow(TUint8 aReplayWindow) + { + iReplayWindow = (TInt)aReplayWindow; + } + +TUint32 CIkev2Acquire::Pid() + { + return iPfKeyPid; + } + +void CIkev2Acquire::SetPid(TUint32 aPfKeyPid) + { + iPfKeyPid = aPfKeyPid; + } + +TUint32 CIkev2Acquire::Seq() + { + return iPfKeySeq; + } + +void CIkev2Acquire::SetSeq(TUint32 aPfKeySeq) + { + iPfKeySeq = aPfKeySeq; + } + +void CIkev2Acquire::SetVirtualIp() + { + iForVirtualIp = ETrue; + } + +TBool CIkev2Acquire::ForVirtualIp() + { + return iForVirtualIp; + } + +TBool CIkev2Acquire::SrcSpecific() + { + return iSrcSpecific; + } + +void CIkev2Acquire::SetSrcSpecific(TBool aSrcSpecific) + { + iSrcSpecific = aSrcSpecific; + } + +TUint8 CIkev2Acquire::IpsecProtocol() + { + return (TUint8)iProtocol; + } + +void CIkev2Acquire::SetIpsecProtocol(TUint8 aProtocol) + { + iProtocol = (TInt)aProtocol; + } + +HBufC8* CIkev2Acquire::LocalId() + { + return iLocalId; + } + +HBufC8* CIkev2Acquire::RemoteId() + { + return iRemoteId; + } + +HBufC8* CIkev2Acquire::SA()const + { + return iSA; + } + +const CArrayFix& CIkev2Acquire::TS_i() + { + return *iTS_i; + } + +const CArrayFix& CIkev2Acquire::TS_r() + { + return *iTS_r; + } + +void CIkev2Acquire::ReplaceSA(HBufC8* aSA) + { + delete iSA; + iSA = aSA; + } + +void CIkev2Acquire::ReplaceTS_i(CArrayFix* aTS) + { + delete iTS_i; + iTS_i = aTS; + } + +void CIkev2Acquire::ReplaceTS_r(CArrayFix* aTS) + { + delete iTS_r; + iTS_r = aTS; + } + +void CIkev2Acquire::ReplaceLocalId(HBufC8* aId) + { + delete iLocalId; + iLocalId = aId; + } + +void CIkev2Acquire::ReplaceRemoteId(HBufC8* aId) + { + delete iRemoteId; + iRemoteId = aId; + } +