vpnengine/ikev2lib/src/ikev2acquire.cpp
changeset 0 33413c0669b9
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  IKEv2 Acquire definition
       
    15 *                Class CIkev2Acquire is a IKEv2 specific data structure
       
    16 *                containing information needed, when establishing a new 
       
    17 *                IPsec SA
       
    18 */
       
    19 
       
    20 #include <ipsecpolapi.h>
       
    21 
       
    22 #include "ikev2acquire.h"
       
    23 #include "pfkeymsg.h"
       
    24 #include "ipsecproposal.h"
       
    25 #include "ipsecselectors.h"
       
    26 #include "ikev2payloads.h"
       
    27 #include "ikev2ipsecsarekeydata.h"
       
    28 
       
    29 _LIT8(KZeroDesc, "");
       
    30 //
       
    31 //
       
    32 //  CIkev2Acquire
       
    33 //
       
    34 //  This class is used to handle PFKEY Acquire primitives received from
       
    35 //  Ipsec plug-in. 
       
    36 //  
       
    37 //
       
    38 CIkev2Acquire::CIkev2Acquire(TInt aId) 
       
    39 :iId(aId), iSPIIn(0), iSPIOut(0), iSPIToBeRekeyed(0), iDHGroup(0), 
       
    40  iTransport(EFalse), iResponse(EFalse), iSrcSpecific(ETrue), iForVirtualIp(EFalse), 
       
    41  iReplayWindow(0), iProtocol(SADB_SATYPE_ESP), iPfKeyPid(0), iPfKeySeq(0), 
       
    42  iHard(0,0,0,0), iSoft(0,0,0,0),
       
    43  iSA(0), iTS_i(0), iTS_r(0), iLocalId(0), iRemoteId(0), iNext(0) 
       
    44     {    
       
    45     }      
       
    46 
       
    47 
       
    48 CIkev2Acquire::~CIkev2Acquire()
       
    49 {
       
    50     delete iSA;
       
    51     iSA = NULL;
       
    52     delete iTS_i;
       
    53     iTS_i = NULL;
       
    54     delete iTS_r;
       
    55     iTS_r = NULL;
       
    56     delete iLocalId;
       
    57     iLocalId = NULL;
       
    58     delete iRemoteId;   
       
    59     iRemoteId = NULL;
       
    60 }
       
    61 
       
    62 void CIkev2Acquire::ConstructL(const TPfkeyMessage& aReq, const TInetAddr& aLocalAddr, 
       
    63                           TUint16 aDHGroup, TBool aImplicitSa, 
       
    64                           const TIpsecSaSpec* aSaSpec, const CIpsecSARekeyData* aRekeyData)
       
    65 {
       
    66     SetIpsecProtocol(aReq.iBase.iMsg->sadb_msg_satype); 
       
    67     SetPid(aReq.iBase.iMsg->sadb_msg_pid);
       
    68     SetSeq(aReq.iBase.iMsg->sadb_msg_seq);
       
    69     iSrcSpecific = !(aReq.iSrcAddr.iAddr->IsUnspecified());
       
    70 
       
    71     if (!aRekeyData)
       
    72         {
       
    73         // SADB_ACQUIRE was received
       
    74         if ( aReq.iProposal.iComb->sadb_comb_flags & SADB_SAFLAGS_PFS )
       
    75             {
       
    76             iDHGroup = (TUint32)aDHGroup;
       
    77             }
       
    78     
       
    79         if ( aReq.iProposal.iComb->sadb_comb_flags & SADB_SAFLAGS_TUNNEL )
       
    80             {
       
    81             iTransport = EFalse;        
       
    82             }
       
    83         else 
       
    84             {
       
    85             iTransport = ETrue;
       
    86             }
       
    87 
       
    88         iHard.iAllocations = aReq.iProposal.iComb->sadb_comb_hard_allocations;
       
    89         iHard.iBytes = aReq.iProposal.iComb->sadb_comb_hard_bytes;
       
    90         iHard.iAddtime = aReq.iProposal.iComb->sadb_comb_hard_addtime;
       
    91         iHard.iUsetime = aReq.iProposal.iComb->sadb_comb_hard_usetime;
       
    92     
       
    93         iSoft.iAllocations = aReq.iProposal.iComb->sadb_comb_soft_allocations;
       
    94         iSoft.iBytes = aReq.iProposal.iComb->sadb_comb_soft_bytes;
       
    95         iSoft.iAddtime = aReq.iProposal.iComb->sadb_comb_soft_addtime;
       
    96         iSoft.iUsetime = aReq.iProposal.iComb->sadb_comb_soft_usetime;
       
    97 
       
    98         SetReplayWindow(aReq.iProposal.iExt->sadb_prop_replay);
       
    99 
       
   100         //
       
   101         //  Build SA payload (including Proposal and Transform payload)
       
   102         //  using parameters in TPfkeyMessage
       
   103         //
       
   104         if ( aImplicitSa )
       
   105             {
       
   106             aDHGroup = 0; // No D-H group used with ipmplicit SA although PFS defined   
       
   107             }
       
   108         iSA = IpsecProposal::BuildIpsecSaRequestL(aReq, aDHGroup);
       
   109     
       
   110         //
       
   111         //  Build Traffic selectors using parameters in TPfkeyMessage.
       
   112         //  For some reason the selectors are build using identity 
       
   113         //  fields.
       
   114         //  
       
   115         IpsecSelectors::BuildTrafficSelectorsL(this, aLocalAddr,
       
   116                                                aReq.iSrcIdent, aReq.iDstIdent,
       
   117                                                aReq.iDstAddr.iExt->sadb_address_proto);
       
   118         //
       
   119         //  Store identity information from TPfkeyMessage to Acquire
       
   120         //
       
   121         if ( aReq.iSrcIdent.iExt )
       
   122             {            
       
   123             iLocalId = HBufC8::NewL(aReq.iSrcIdent.iData.Length());
       
   124             iLocalId->Des().Copy(aReq.iSrcIdent.iData);
       
   125             }
       
   126         else
       
   127             {
       
   128             iLocalId = KZeroDesc().AllocL();
       
   129             }
       
   130 
       
   131         if ( aReq.iDstIdent.iExt )
       
   132             {            
       
   133             iRemoteId = HBufC8::NewL(aReq.iDstIdent.iData.Length());
       
   134             iRemoteId->Des().Copy(aReq.iDstIdent.iData);
       
   135             }
       
   136         else
       
   137             {
       
   138             iRemoteId = KZeroDesc().AllocL();
       
   139             }
       
   140         }
       
   141     else
       
   142         {
       
   143         // SADB_EXPIRE was received due to soft lifetime expiration
       
   144         TUint16 flags = (TUint16)(aReq.iSa.iExt->sadb_sa_flags | (aSaSpec->iTransportMode ? 0 : SADB_SAFLAGS_TUNNEL));
       
   145         if ( flags & SADB_SAFLAGS_PFS )
       
   146             {
       
   147             iDHGroup = (TUint32)aDHGroup;
       
   148             }
       
   149     
       
   150         if ( flags & SADB_SAFLAGS_TUNNEL )
       
   151             {
       
   152             iTransport = EFalse;        
       
   153             }
       
   154         else 
       
   155             {
       
   156             iTransport = ETrue;
       
   157             }
       
   158                     
       
   159         if ( aImplicitSa )
       
   160             {
       
   161             aDHGroup = 0; // No D-H group used with ipmplicit SA although PFS defined   
       
   162             } 
       
   163         
       
   164         iSA = IpsecProposal::BuildIpsecSaRequestL(iProtocol, 
       
   165                                                   aSaSpec->iEalg, aSaSpec->iEalgLen, aSaSpec->iAalg, 
       
   166                                                   flags, aDHGroup);
       
   167                                                     
       
   168         iReplayWindow = aRekeyData->ReplayWindow();
       
   169         iHard = aRekeyData->HardLifetime();
       
   170         iSoft = aRekeyData->SoftLifetime();
       
   171         
       
   172         iTS_i = aRekeyData->TsIL();
       
   173         iTS_r = aRekeyData->TsRL();
       
   174 
       
   175         
       
   176         iLocalId = aRekeyData->LocalId().AllocL();
       
   177         iRemoteId = aRekeyData->RemoteId().AllocL();
       
   178 
       
   179         iResponse = EFalse;
       
   180         }
       
   181 }
       
   182 
       
   183 
       
   184 CIkev2Acquire* CIkev2Acquire::NewL(const TPfkeyMessage& aPfkeyMessage, TUint32 aId, 
       
   185                          const TInetAddr& aLocalAddr, TUint16 aDHGroup, TBool aImplicitSa,
       
   186                          const TIpsecSaSpec* aSaSpec, const CIpsecSARekeyData* aRekeyData)
       
   187 {
       
   188     CIkev2Acquire* Acquire = new (ELeave)CIkev2Acquire(aId);
       
   189     CleanupStack::PushL(Acquire);
       
   190     Acquire->ConstructL(aPfkeyMessage, aLocalAddr, aDHGroup, aImplicitSa, aSaSpec, aRekeyData);
       
   191     CleanupStack::Pop(Acquire);     
       
   192     return Acquire;
       
   193 }
       
   194 
       
   195 
       
   196 void CIkev2Acquire::AddIpsecSpiToSa(const TDesC8& aSpi)
       
   197     {
       
   198     __ASSERT_DEBUG(aSpi.Length() == 4, User::Invariant());
       
   199 
       
   200     TUint8* saBuffer = const_cast<TUint8*>(iSA->Ptr());
       
   201     TProposalIkev2* Prop = TProposalIkev2::Cast(saBuffer);
       
   202 
       
   203     while ( Prop )
       
   204         {
       
   205         TUint32 spiValue = 0;
       
   206         TPtr8 spiValueDesc(reinterpret_cast<TUint8*>(&spiValue), sizeof(spiValue));
       
   207         spiValueDesc = aSpi;
       
   208         Prop->SetIpsecSPI(spiValue);
       
   209         if ( !Prop->Last() )
       
   210             {
       
   211             Prop = TProposalIkev2::Cast(TPayloadIkev2::Cast(Prop)->Next());
       
   212             }  
       
   213         else
       
   214             {
       
   215             Prop = NULL;
       
   216             }
       
   217         }       
       
   218     }
       
   219 
       
   220 
       
   221 CIkev2Acquire* CIkev2Acquire::NewL(TUint32 aId, HBufC8* aSa, 
       
   222                          CArrayFix<TIkeV2TrafficSelector>* aTS_i, 
       
   223                          CArrayFix<TIkeV2TrafficSelector>* aTS_r )
       
   224 {
       
   225     CIkev2Acquire* Acquire = new (ELeave)CIkev2Acquire(aId);
       
   226     Acquire->iSA   = aSa;
       
   227     Acquire->iTS_i = aTS_i;
       
   228     Acquire->iTS_r = aTS_r;     
       
   229     return Acquire;
       
   230 }
       
   231 
       
   232 void CIkev2Acquire::Link(CIkev2Acquire* aAcquire, CIkev2Acquire** aAnchor)
       
   233 {
       
   234     ASSERT(aAcquire && aAnchor);
       
   235     aAcquire->iNext = NULL;
       
   236     CIkev2Acquire* Last  = *aAnchor;
       
   237     if ( Last )
       
   238     {   
       
   239         while ( Last->iNext )
       
   240         {
       
   241             Last = Last->iNext;
       
   242         }
       
   243         Last->iNext = aAcquire;
       
   244     }
       
   245     else *aAnchor = aAcquire;   
       
   246 }
       
   247 
       
   248 CIkev2Acquire* CIkev2Acquire::Find(TUint32 aId, CIkev2Acquire** aAnchor, TBool aRemove)
       
   249 {
       
   250     ASSERT(aAnchor);
       
   251     CIkev2Acquire* Prev = NULL;
       
   252     CIkev2Acquire* Elem = *aAnchor;
       
   253     while ( Elem )
       
   254     {
       
   255         if ( Elem->iId == aId )
       
   256         {
       
   257            if ( aRemove )
       
   258            {
       
   259               if ( Prev )
       
   260                    Prev->iNext = Elem->iNext;
       
   261               else *aAnchor = Elem->iNext;
       
   262            }       
       
   263            break;
       
   264         }
       
   265         Prev = Elem;
       
   266         Elem = Elem->iNext;
       
   267     }
       
   268     return Elem;
       
   269 }
       
   270 
       
   271 CIkev2Acquire* CIkev2Acquire::GetNext(CIkev2Acquire** aAnchor, TBool aResponse)
       
   272 {
       
   273     ASSERT(aAnchor);
       
   274     CIkev2Acquire* Elem = *aAnchor;
       
   275     while ( Elem )
       
   276     {
       
   277         if ( Elem->SPI_In().Length() > 0 && (Elem->Response() == aResponse) )
       
   278         {
       
   279             RemoveFromQue(Elem->Id(), aAnchor);
       
   280             break;
       
   281         }
       
   282         Elem = Elem->iNext;
       
   283     }
       
   284     return Elem;
       
   285 }
       
   286 
       
   287 TBool CIkev2Acquire::Responding(CIkev2Acquire** aAnchor)
       
   288 {
       
   289     ASSERT(aAnchor);
       
   290     CIkev2Acquire* Elem = *aAnchor;
       
   291     while ( Elem )
       
   292     {
       
   293         if ( Elem->Response() )
       
   294         {
       
   295             return ETrue;
       
   296         }
       
   297         Elem = Elem->iNext;
       
   298     }
       
   299     return EFalse;
       
   300 }
       
   301 
       
   302 
       
   303 void CIkev2Acquire::PurgeQue(CIkev2Acquire** aAnchor)
       
   304 {
       
   305     ASSERT(aAnchor);
       
   306     CIkev2Acquire* Elem = *aAnchor;
       
   307     while ( Elem )
       
   308     {
       
   309         RemoveFromQue(Elem->Id(), aAnchor);
       
   310         delete Elem;
       
   311         Elem = *aAnchor;
       
   312     }   
       
   313 }
       
   314 
       
   315 void CIkev2Acquire::SetFirst(CIkev2Acquire* aAcquire, CIkev2Acquire** aAnchor)
       
   316     { 
       
   317     ASSERT(aAcquire && aAnchor); 
       
   318     aAcquire->iNext = *aAnchor; 
       
   319     *aAnchor = aAcquire; 
       
   320     }
       
   321 
       
   322 CIkev2Acquire* CIkev2Acquire::PeekFirst(CIkev2Acquire** aAnchor) 
       
   323     { 
       
   324     return *aAnchor; 
       
   325     }
       
   326 
       
   327 CIkev2Acquire* CIkev2Acquire::RemoveFromQue(TUint32 aId, CIkev2Acquire** aAnchor)
       
   328     { 
       
   329     return CIkev2Acquire::Find(aId, aAnchor, ETrue);
       
   330     }
       
   331 
       
   332 TUint32 CIkev2Acquire::Id() 
       
   333     { 
       
   334     return iId;
       
   335     }
       
   336 
       
   337 TPtrC8 CIkev2Acquire::SPI_In() 
       
   338     { 
       
   339     return iSPIIn;
       
   340     }
       
   341 
       
   342 TPtrC8 CIkev2Acquire::SPI_Out() 
       
   343     { 
       
   344     return iSPIOut;
       
   345     }          
       
   346 
       
   347 TPtrC8 CIkev2Acquire::SPI_ToBeRekeyed() 
       
   348     { 
       
   349     return iSPIToBeRekeyed;
       
   350     }
       
   351 
       
   352 void CIkev2Acquire::SetSPI_In(const TDesC8& aSPI) 
       
   353     { 
       
   354     iSPIIn = aSPI;
       
   355     }
       
   356 
       
   357 void CIkev2Acquire::SetSPI_Out(const TDesC8& aSPI) 
       
   358     { 
       
   359     iSPIOut = aSPI;
       
   360     }
       
   361 
       
   362 void CIkev2Acquire::SetSPI_ToBeRekeyed(const TDesC8& aSPI) 
       
   363     { 
       
   364     iSPIToBeRekeyed = aSPI;
       
   365     }
       
   366 
       
   367 TUint16 CIkev2Acquire::DHGroup() 
       
   368     { 
       
   369     return (TUint16)iDHGroup;
       
   370     }
       
   371 
       
   372 void CIkev2Acquire::DHGroup(TUint16 aDHGroup) 
       
   373     { 
       
   374     iDHGroup = aDHGroup;
       
   375     }
       
   376 
       
   377 TBool CIkev2Acquire::Transport() 
       
   378     { 
       
   379     return iTransport;
       
   380     }
       
   381 
       
   382 void CIkev2Acquire::SetTransport() 
       
   383     { 
       
   384     iTransport = ETrue;
       
   385     }       
       
   386 
       
   387 TBool CIkev2Acquire::Response() 
       
   388     { 
       
   389     return iResponse;
       
   390     }
       
   391 
       
   392 void CIkev2Acquire::SetResponse() 
       
   393     { 
       
   394     iResponse = ETrue;
       
   395     }
       
   396 
       
   397 void CIkev2Acquire::SetHardLifetime(const TIpsecSALifetime& aHard ) 
       
   398     { 
       
   399     iHard = aHard;
       
   400     }
       
   401 
       
   402 TIpsecSALifetime* CIkev2Acquire::HardLifetime() 
       
   403     { 
       
   404     return &iHard;
       
   405     }
       
   406 
       
   407 void CIkev2Acquire::SetSoftLifetime(const TIpsecSALifetime& aSoft ) 
       
   408     { 
       
   409     iSoft = aSoft;
       
   410     }
       
   411 
       
   412 TIpsecSALifetime* CIkev2Acquire::SoftLifetime() 
       
   413     { 
       
   414     return &iSoft;
       
   415     }
       
   416 
       
   417 TUint8 CIkev2Acquire::ReplayWindow() 
       
   418     { 
       
   419     return (TUint8)iReplayWindow;
       
   420     }
       
   421 
       
   422 void CIkev2Acquire::SetReplayWindow(TUint8 aReplayWindow) 
       
   423     { 
       
   424     iReplayWindow = (TInt)aReplayWindow;
       
   425     }
       
   426 
       
   427 TUint32 CIkev2Acquire::Pid() 
       
   428     { 
       
   429     return iPfKeyPid;
       
   430     }
       
   431 
       
   432 void CIkev2Acquire::SetPid(TUint32 aPfKeyPid) 
       
   433     { 
       
   434     iPfKeyPid = aPfKeyPid;
       
   435     }
       
   436 
       
   437 TUint32 CIkev2Acquire::Seq() 
       
   438     { 
       
   439     return iPfKeySeq;
       
   440     }
       
   441 
       
   442 void CIkev2Acquire::SetSeq(TUint32 aPfKeySeq) 
       
   443     { 
       
   444     iPfKeySeq = aPfKeySeq;
       
   445     }
       
   446 
       
   447 void CIkev2Acquire::SetVirtualIp() 
       
   448     { 
       
   449     iForVirtualIp = ETrue; 
       
   450     }
       
   451 
       
   452 TBool CIkev2Acquire::ForVirtualIp() 
       
   453     { 
       
   454     return iForVirtualIp; 
       
   455     }
       
   456 
       
   457 TBool CIkev2Acquire::SrcSpecific() 
       
   458     { 
       
   459     return iSrcSpecific;
       
   460     }
       
   461 
       
   462 void CIkev2Acquire::SetSrcSpecific(TBool aSrcSpecific) 
       
   463     { 
       
   464     iSrcSpecific = aSrcSpecific;
       
   465     }
       
   466 
       
   467 TUint8 CIkev2Acquire::IpsecProtocol() 
       
   468     { 
       
   469     return (TUint8)iProtocol;
       
   470     }
       
   471 
       
   472 void CIkev2Acquire::SetIpsecProtocol(TUint8 aProtocol) 
       
   473     { 
       
   474     iProtocol = (TInt)aProtocol;
       
   475     }                      
       
   476 
       
   477 HBufC8* CIkev2Acquire::LocalId() 
       
   478     { 
       
   479     return iLocalId;
       
   480     }
       
   481 
       
   482 HBufC8* CIkev2Acquire::RemoteId() 
       
   483     { 
       
   484     return iRemoteId;
       
   485     }
       
   486 
       
   487 HBufC8* CIkev2Acquire::SA()const 
       
   488     { 
       
   489     return iSA;
       
   490     }
       
   491 
       
   492 const CArrayFix<TIkeV2TrafficSelector>& CIkev2Acquire::TS_i() 
       
   493     { 
       
   494     return *iTS_i;
       
   495     }
       
   496 
       
   497 const CArrayFix<TIkeV2TrafficSelector>& CIkev2Acquire::TS_r() 
       
   498     { 
       
   499     return *iTS_r;
       
   500     }
       
   501 
       
   502 void CIkev2Acquire::ReplaceSA(HBufC8* aSA) 
       
   503     { 
       
   504     delete iSA; 
       
   505     iSA = aSA; 
       
   506     }
       
   507 
       
   508 void CIkev2Acquire::ReplaceTS_i(CArrayFix<TIkeV2TrafficSelector>* aTS) 
       
   509     { 
       
   510     delete iTS_i; 
       
   511     iTS_i = aTS; 
       
   512     }
       
   513 
       
   514 void CIkev2Acquire::ReplaceTS_r(CArrayFix<TIkeV2TrafficSelector>* aTS) 
       
   515     { 
       
   516     delete iTS_r; 
       
   517     iTS_r = aTS; 
       
   518     }
       
   519 
       
   520 void CIkev2Acquire::ReplaceLocalId(HBufC8* aId) 
       
   521     { 
       
   522     delete iLocalId; 
       
   523     iLocalId = aId; 
       
   524     }
       
   525 
       
   526 void CIkev2Acquire::ReplaceRemoteId(HBufC8* aId) 
       
   527     { 
       
   528     delete iRemoteId; 
       
   529     iRemoteId = aId; 
       
   530     }
       
   531