vpnengine/ikev1lib/src/ikev1negotiation.cpp
changeset 0 33413c0669b9
child 2 ef893827b4d1
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2005-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:   IKEv1/IPSEC SA negotiation 
       
    15 *
       
    16 */
       
    17 
       
    18 #include <x509cert.h>
       
    19 #include <x500dn.h>
       
    20 #include <random.h>
       
    21 #include <vpnlogmessages.rsg>
       
    22 
       
    23 #include "ikev1negotiation.h"
       
    24 #include "ikedebug.h"
       
    25 #include "ikev1isakmpstream.h"
       
    26 #include "ikev1timeout.h"
       
    27 #include "ikev1payload.h"
       
    28 #include "ikev1plugin.h"
       
    29 #include "ikev1crack.h"
       
    30 #include "ikev1trans.h"
       
    31 #include "ipsecsadata.h"
       
    32 #include "ipsecsalifetime.h"
       
    33 #include "pfkeymsg.h"
       
    34 #include "kmdapi.h"
       
    35 #include "ikev1pkiservice.h"
       
    36 #include "ikev1crypto.h"
       
    37 #include "ikev1natdiscovery.h"
       
    38 #include "ikev1private.h"
       
    39 #include "vpnapidefs.h"
       
    40 #include "ikepkiutils.h"
       
    41 #include "vpnclientuids.h"
       
    42 #include "ikecalist.h"
       
    43 #include "ikecaelem.h"
       
    44 #include "ikecert.h"
       
    45 #include "ikev1pluginsession.h"
       
    46 #include "ikesocketdefs.h"
       
    47 #include "kmdeventloggerif.h"
       
    48 #include "pfkeyextdatautil.h"
       
    49 #include "ipsecsalist.h"
       
    50 
       
    51 const TInt KSubjectName              = 1;
       
    52 
       
    53 /////////////////////////////////////////////////////////////////////////////////
       
    54 // CIkev1Negotiation related stuff
       
    55 /////////////////////////////////////////////////////////////////////////////////
       
    56 
       
    57 
       
    58 //
       
    59 //Proto negotiation to send a informational payload and be destroyed
       
    60 //
       
    61 CIkev1Negotiation* CIkev1Negotiation::NewL( CIkev1PluginSession* aPluginSession,
       
    62                                             CPFKeySocketIf& aPFKeySocketIf,
       
    63                                             MIkeDebug& aDebug,
       
    64                                             const TInetAddr& aRemote,
       
    65                                             const TCookie& aInitiator,
       
    66                                             const TCookie& aResponder )
       
    67     {   	
       
    68 	CIkev1Negotiation* self = new ( ELeave ) CIkev1Negotiation( aPluginSession,
       
    69                                                                 aPFKeySocketIf,
       
    70                                                                 aDebug );
       
    71 	CleanupStack::PushL( self );
       
    72 	self->iRemoteAddr = aRemote;
       
    73 	self->iCookie_I = aInitiator;
       
    74 	self->iCookie_R = aResponder;     
       
    75 	self->iExchange = ISAKMP_EXCHANGE_INFO;   
       
    76 	self->iDOI = IPSEC_DOI;
       
    77 	self->iTimer = CIkev1Timeout::NewL( *self );	
       
    78 	CleanupStack::Pop( self );	
       
    79 	return self;
       
    80     }
       
    81 
       
    82 CIkev1Negotiation* CIkev1Negotiation::NewL( CIkev1PluginSession* aPluginSession,
       
    83                                             CPFKeySocketIf& aPFKeySocketIf,
       
    84                                             MIkeDebug& aDebug,
       
    85                                             const TInetAddr& aRemote,
       
    86                                             const TCookie& aInitiator,
       
    87                                             TBool aAutoLogin ) 
       
    88     {
       
    89 	CIkev1Negotiation* self = new ( ELeave ) CIkev1Negotiation( aPluginSession,
       
    90                                                                 aPFKeySocketIf,
       
    91 	                                                            aDebug,
       
    92 	                                                            aRemote,
       
    93 	                                                            aInitiator );
       
    94 	CleanupStack::PushL( self );
       
    95     self->ConstructL( aAutoLogin );
       
    96     CleanupStack::Pop( self );
       
    97 	return self;
       
    98     }
       
    99 
       
   100 CIkev1Negotiation* CIkev1Negotiation::NewL( CIkev1PluginSession* aPluginSession,
       
   101                                             CPFKeySocketIf& aPFKeySocketIf,
       
   102                                             MIkeDebug& aDebug,
       
   103                                             TIkev1SAData* aIkev1SAdata,
       
   104                                             TUint aRole,
       
   105                                             const TPfkeyMessage *aReq )
       
   106     {
       
   107     CIkev1Negotiation* self = new ( ELeave ) CIkev1Negotiation( aPluginSession,
       
   108                                                                 aPFKeySocketIf,
       
   109                                                                 aDebug );
       
   110     CleanupStack::PushL( self );
       
   111     self->ConstructL( aIkev1SAdata, aRole, aReq );
       
   112     CleanupStack::Pop( self );
       
   113     return self;
       
   114     }
       
   115 
       
   116 
       
   117 CIkev1Negotiation* CIkev1Negotiation::NewL( CIkev1PluginSession* aPluginSession,
       
   118                                             CPFKeySocketIf& aPFKeySocketIf,
       
   119                                             MIkeDebug& aDebug,
       
   120                                             const TInetAddr& aRemote,
       
   121                                             TBool aAutoLogin ) 
       
   122     {
       
   123 	CIkev1Negotiation* self = new ( ELeave ) CIkev1Negotiation( aPluginSession,
       
   124                                                                 aPFKeySocketIf,
       
   125 	                                                            aDebug,
       
   126 	                                                            aRemote );
       
   127 	CleanupStack::PushL( self );
       
   128     self->iCookie_I = self->CreateCookieL();
       
   129     self->ConstructL( aAutoLogin );
       
   130     CleanupStack::Pop( self );
       
   131 	return self;
       
   132     }
       
   133 
       
   134 CIkev1Negotiation* CIkev1Negotiation::NewL( CIkev1PluginSession* aPluginSession,
       
   135                                             CPFKeySocketIf& aPFKeySocketIf,
       
   136                                             MIkeDebug& aDebug,
       
   137                                             const TInetAddr& aRemote,
       
   138                                             const TPfkeyMessage& aReq )
       
   139     {    
       
   140     CIkev1Negotiation* self = new (  ELeave ) CIkev1Negotiation( aPluginSession,
       
   141                                                                  aPFKeySocketIf,
       
   142                                                                  aDebug,
       
   143                                                                  aRemote );
       
   144     CleanupStack::PushL( self );
       
   145     self->iCookie_I = self->CreateCookieL();
       
   146     self->ConstructL( aReq );
       
   147     CleanupStack::Pop( self );
       
   148     return self;
       
   149     }
       
   150 
       
   151 //
       
   152 // Destructor
       
   153 //
       
   154 CIkev1Negotiation::~CIkev1Negotiation()
       
   155     {
       
   156     DEBUG_LOG1( _L("CIkev1Negotiation::~CIkev1Negotiation this=0x%x"), this );
       
   157     
       
   158     
       
   159     if ( iRole == INITIATOR &&
       
   160          iAcquirePending )
       
   161         {
       
   162         // Response with error to pending Acquire.
       
   163         AcquireSAErrorResponse( KKmdIkeNegotFailed );
       
   164         }
       
   165     
       
   166     delete iIpsecSaSpiRetriever;
       
   167     delete iSavedIkeMsgBfr;
       
   168     
       
   169     if( iPluginSession )
       
   170         { 		
       
   171 	    iPluginSession->RemoveNegotiation( this );  
       
   172         }
       
   173 		
       
   174     iCookie_I.FillZ(ISAKMP_COOKIE_SIZE);
       
   175     
       
   176     if(iTimer)
       
   177         {
       
   178         iTimer->Cancel();
       
   179         delete iTimer;
       
   180         }
       
   181 
       
   182     delete iOwnCert;
       
   183     delete iPeerX509Cert;
       
   184     delete iPeerTrustedCA;  // Peer trusted CA name 
       
   185     delete iICA1;
       
   186     delete iICA2;
       
   187 
       
   188     delete iPkiService;     // Trusted CA certificate list
       
   189 
       
   190     delete iSAPayload;
       
   191     delete iPeerIdentPayload;
       
   192     delete iOwnIdentPayload;
       
   193     
       
   194     //Keys
       
   195     delete iOwnKeys;        //structure containing the public and private keys
       
   196     delete iOwnPublicKey;   //Public Key
       
   197 
       
   198     //Phase_I Proposal
       
   199     TAttrib *attr;
       
   200     while ((attr = iProposal_I.iAttrList) != NULL)
       
   201     {
       
   202         iProposal_I.iAttrList = attr->iNext;
       
   203         delete attr;
       
   204     }
       
   205 
       
   206     delete iChosenProposal_I.iAttrList; //Only one transformation chosen
       
   207 
       
   208     //Phase_II proposals (include transformations)
       
   209     delete iProposal_IIList;
       
   210 
       
   211     //Phase_II chosen Proposal
       
   212     delete iChosenProp_IIList;
       
   213     delete iInboundSPIList;
       
   214     delete iCRACKneg;
       
   215     delete iTransactionNeg; // Transaction exchange 
       
   216     delete iInternalAddr;
       
   217     delete iNatDiscovery;
       
   218 	delete iSARekeyInfo;
       
   219 	delete iLastMsg;
       
   220 }
       
   221 
       
   222 
       
   223 //
       
   224 // CIkev1Negotiation
       
   225 //  Constructor for remote initiated negotiation
       
   226 //
       
   227 CIkev1Negotiation::CIkev1Negotiation( CIkev1PluginSession* aPluginSession,
       
   228                                       CPFKeySocketIf& aPFKeySocketIf,
       
   229                                       MIkeDebug& aDebug,
       
   230                                       const TInetAddr& aRemote,
       
   231                                       const TCookie& aInitiator )
       
   232  : iCookie_I( aInitiator ),
       
   233    iRemoteAddr( aRemote ),
       
   234    iPluginSession( aPluginSession ),
       
   235    iPFKeySocketIf( aPFKeySocketIf ),
       
   236    iDebug( aDebug )
       
   237 {
       
   238 
       
   239     DEBUG_LOG1( _L("CIkev1Negotiation::CIkev1Negotiation, RESPONDER this=0x%x"), this );
       
   240     iCookie_R.FillZ(ISAKMP_COOKIE_SIZE);
       
   241     iSAId = iPluginSession->GetSAId();
       
   242     iPluginSession->LinkNegotiation(this);         
       
   243     iRole = RESPONDER;
       
   244     iStage = 1; //next phase for the responder is 2
       
   245 }
       
   246 
       
   247 //
       
   248 //  Constructor for local initiated negotiation
       
   249 //
       
   250 
       
   251 CIkev1Negotiation::CIkev1Negotiation( CIkev1PluginSession* aPluginSession,
       
   252                                       CPFKeySocketIf& aPFKeySocketIf,
       
   253                                       MIkeDebug& aDebug,
       
   254                                       const TInetAddr& aRemote )
       
   255  : iRemoteAddr( aRemote ),
       
   256    iPluginSession( aPluginSession ),
       
   257    iPFKeySocketIf( aPFKeySocketIf ),
       
   258    iDebug( aDebug )
       
   259 {
       
   260     DEBUG_LOG1( _L("CIkev1Negotiation::CIkev1Negotiation, INITIATOR this=0x%x"), this );
       
   261     iCookie_I.FillZ(ISAKMP_COOKIE_SIZE);
       
   262     iCookie_R.FillZ(ISAKMP_COOKIE_SIZE);
       
   263     iSAId = iPluginSession->GetSAId();
       
   264     iPluginSession->LinkNegotiation(this);     
       
   265     iRole = INITIATOR;
       
   266     iStage = 0;
       
   267 }
       
   268 
       
   269 //
       
   270 //  Constructor for Phase II initiated negotiations
       
   271 //
       
   272 
       
   273 CIkev1Negotiation::CIkev1Negotiation( CIkev1PluginSession* aPluginSession,
       
   274                                       CPFKeySocketIf& aPFKeySocketIf,
       
   275                                       MIkeDebug& aDebug )
       
   276  : iPluginSession( aPluginSession ),
       
   277    iPFKeySocketIf( aPFKeySocketIf ),
       
   278    iDebug( aDebug )
       
   279 { 
       
   280     DEBUG_LOG1( _L("CIkev1Negotiation::CIkev1Negotiation, this=0x%x"), this );
       
   281     iCookie_I.FillZ(ISAKMP_COOKIE_SIZE);
       
   282     iCookie_R.FillZ(ISAKMP_COOKIE_SIZE);    
       
   283     iSAId = iPluginSession->GetSAId();
       
   284     iPluginSession->LinkNegotiation(this); 
       
   285 }
       
   286 
       
   287 //Used when creating a negotiation as a RESPONDER!
       
   288 //Used also when Initiator (= Phase 1 negotiation stated by the policy activation)
       
   289 //Leaves if error detected
       
   290 void CIkev1Negotiation::ConstructL(TBool aAutoLogin)
       
   291 {
       
   292     iIpsecSaSpiRetriever = CIpsecSaSpiRetriever::NewL( *this,
       
   293                                                        iPFKeySocketIf );
       
   294 
       
   295     iAutoLogin = aAutoLogin;
       
   296     CommonConstructL();
       
   297 }
       
   298 
       
   299 
       
   300 //Used when an Acquire is received
       
   301 //Leaves if error detected
       
   302 void CIkev1Negotiation::ConstructL(const TPfkeyMessage &aReq)
       
   303 {
       
   304     iIpsecSaSpiRetriever = CIpsecSaSpiRetriever::NewL( *this,
       
   305                                                        iPFKeySocketIf );
       
   306 
       
   307     CommonConstructL();     
       
   308     GetAcquireDataL(aReq);
       
   309 }
       
   310 
       
   311 //Used when initiating a new Phase II negotiation from a negotiated ISAKMP SA.
       
   312 void CIkev1Negotiation::ConstructL( TIkev1SAData* aSA,
       
   313                                     TUint aRole,
       
   314                                     const TPfkeyMessage *aReq )
       
   315 {
       
   316 
       
   317     iIpsecSaSpiRetriever = CIpsecSaSpiRetriever::NewL( *this,
       
   318                                                        iPFKeySocketIf );
       
   319 
       
   320     iPhase = PHASE_II;
       
   321 
       
   322     //Almost like common construct
       
   323     iTimer = CIkev1Timeout::NewL(*this);    
       
   324 
       
   325     //Phase II proposal lists
       
   326     iProposal_IIList = new (ELeave) CProposal_IIList(1);
       
   327 
       
   328     iRemoteAddr.SetPort(IKE_PORT);
       
   329 
       
   330     iSeq = aSA->iSeq;
       
   331     iLocalAddr  = aSA->iLocalAddr;
       
   332     iRemoteAddr = aSA->iRemoteAddr;         // Remote Address from peer
       
   333     iLastRemoteAddr = aSA->iDestinAddr;     // Remote Address last transmitted
       
   334     
       
   335     iLastIKEMsgInfo = aSA->iLastIKEMsgInfo;
       
   336     iLastMsg = HBufC8::NewL(4096);
       
   337     if ( aSA->iLastMsg != NULL )
       
   338         {        
       
   339         *iLastMsg = *aSA->iLastMsg;        
       
   340         }
       
   341     
       
   342     iRole = aRole;          // If we are initiator or responder
       
   343 
       
   344     //Header Data
       
   345     iCookie_I = aSA->iCookie_I; // Initiator Cookie (Used with responder to create KEYID)
       
   346     iCookie_R = aSA->iCookie_R; // Responder Cookie
       
   347     iPrevExchange = aSA->iPrevExchange;
       
   348     iExchange = IKE_QUICK_MODE;
       
   349 
       
   350     iMessageId = RandomMessageId();
       
   351 
       
   352     iFlags = aSA->iFlags;           // Flags in the msg header
       
   353     
       
   354 //  iNotifyMessageId = aSA->iHdr.iNotifyMessageId;   // Message Id. for Informational Exchanges
       
   355 
       
   356     //SA Data
       
   357     iDOI = IPSEC_DOI;
       
   358     
       
   359     iChosenProposal_I.iProtocol = PROTO_ISAKMP;
       
   360     iChosenProposal_I.iProposalNum = 0;
       
   361 //    iChosenProposal_I.iSPI.Copy(aSA->iChosenProposal_I.iSPI);
       
   362     iChosenProposal_I.iNumTransforms = 1;
       
   363     iChosenProposal_I.iAttrList = new (ELeave) TAttrib; //allocated now and deleted when destroying the obj
       
   364 //  *iChosenProposal_I.iAttrList = *aSA->iChosenProposal_I.iAttrList;
       
   365     iChosenProposal_I.iAttrList->iEncrAlg = aSA->iEncrAlg;
       
   366     iChosenProposal_I.iAttrList->iHashAlg = aSA->iHashAlg;
       
   367     iChosenProposal_I.iAttrList->iGroupDesc = aSA->iGroupDesc;
       
   368     iChosenProposal_I.iAttrList->iGroupType = aSA->iGroupType;
       
   369     iChosenProposal_I.iAttrList->iKeyLength = aSA->iKeyLength;  
       
   370     if ( aSA->iLifeTimeSecs )
       
   371        iChosenProposal_I.iAttrList->iLifeDurationSecs.Copy((TUint8 *)&aSA->iLifeTimeSecs, sizeof(TUint32)); 
       
   372     if ( aSA->iLifeTimeKB )
       
   373         iChosenProposal_I.iAttrList->iLifeDurationKBytes.Copy((TUint8 *)&aSA->iLifeTimeKB, sizeof(TUint32));    
       
   374 
       
   375  
       
   376     iHostData = aSA->iIkeData;
       
   377     if ( iHostData->iCAList && iHostData->iCAList->Count() )
       
   378     {
       
   379         iPkiService = CIkeV1PkiService::NewL(iHostData, iDebug);                                           
       
   380     }   
       
   381     
       
   382     if (aRole == INITIATOR)
       
   383     {
       
   384         GetAcquireDataL(*aReq); //Data needed from the acquire
       
   385     }
       
   386     else    //RESPONDER 
       
   387     {
       
   388         iAcquireSeq = 1;        //msg Seq. number
       
   389     }
       
   390 
       
   391     //
       
   392     //NAT Traversal data
       
   393     //
       
   394     iFamiliarPeer   = aSA->iFamiliarPeer;
       
   395     iNAT_T_Required = aSA->iNAT_T_Required;
       
   396     
       
   397     //
       
   398     //Copy an Internal address object (if exists) to the new negotiation 
       
   399     //
       
   400     if ( aSA->iVirtualIp )
       
   401     {
       
   402        iInternalAddr = CInternalAddress::NewL(*(aSA->iVirtualIp));    
       
   403     }
       
   404 
       
   405     iNAT_D_Flags  = aSA->iNAT_D_Flags;  
       
   406     if ( iNAT_D_Flags ) {
       
   407        //
       
   408        // Use IETF specified NAT traversal
       
   409        //
       
   410        iNatDiscovery = CIkev1NatDiscovery::NewL(aSA->iNAT_D_Flags);
       
   411     }
       
   412     
       
   413     //Keys  (DH Generated public value when own)
       
   414     iSKEYID.Copy(aSA->iSKEYID);
       
   415     iSKEYID_d.Copy(aSA->iSKEYID_d);
       
   416     iSKEYID_a.Copy(aSA->iSKEYID_a);
       
   417     iSKEYID_e.Copy(aSA->iSKEYID_e);
       
   418     
       
   419     //IV used by des_cbc and des3_cbc is 8 but digest returns 16 bytes for MDx and 20 for SHS (first 8 used)
       
   420     iIV = aSA->iIV;     //normal IV
       
   421     iIVSize = iIV.Length(); 
       
   422 
       
   423     iLastIV = aSA->iLastIV; //Saves the last IV of PHASE_I to compute iNotifIV everytime
       
   424 
       
   425     //Nonces
       
   426 //    iNONCE_I = aSA->iNONCE_I;
       
   427 //    iNONCE_R = aSA->iNONCE_R;
       
   428     //
       
   429     // If the ISAKMP SA (=aSA) has been originally negotiated due the policy activation (iAutoLogin = ETrue)
       
   430     // The iLocalAddr maybe then undefined in aSA.
       
   431     // If local end is acting as an initiator, method GetAcquireDataL updates iLocalAddr in CIkev1Negotiation object.
       
   432     // In that case take iLocalAddr value from there and store it to CIsakmpSa (aSA) object.
       
   433     // If local end is acting as a responder, resolve iLocalAddr value.
       
   434     //
       
   435     if ( aSA->iAutoLogin )
       
   436     {
       
   437         if ( aRole == INITIATOR)    
       
   438              iLocalAddr = aSA->iLocalAddr;
       
   439         else User::LeaveIfError( iPluginSession->GetLocalAddress( iLocalAddr ) );
       
   440     }
       
   441     iDPDSupported = aSA->iDPDSupported;
       
   442     
       
   443     iSAId = aSA->iSAId;    // Reference to existin ISAKMP SA
       
   444     iStage = 1; //if initiator the stage will be set in a subsequent call to InitPhase_IIL()
       
   445 }
       
   446 
       
   447 //Leaves if error detected
       
   448 void CIkev1Negotiation::CommonConstructL()
       
   449 {
       
   450     iPhase = PHASE_I;
       
   451     iTimer = CIkev1Timeout::NewL(*this);    
       
   452 
       
   453     //Phase II proposal lists
       
   454     iProposal_IIList = new (ELeave) CProposal_IIList(1);
       
   455 
       
   456     iRemoteAddr.SetPort(IKE_PORT);
       
   457     
       
   458     iHostData = &iPluginSession->IkeData();
       
   459     if (!iHostData)
       
   460     {
       
   461         DEBUG_LOG(_L("The host has no data. Negotiation aborted"));
       
   462         User::Leave(KKmdIkeNoPolicyErr);
       
   463     }   
       
   464 
       
   465 	if ( iHostData->iCAList && iHostData->iCAList->Count() )
       
   466 	{
       
   467 		iPkiService = CIkeV1PkiService::NewL(iHostData, iDebug);
       
   468 		TInt stat ( EFalse );
       
   469 		stat=ReadCAsL(iHostData->iCAList);  // Build trusted CA list
       
   470 		if ( !stat )
       
   471 		{
       
   472 			SetErrorStatus( KVpnErrInvalidCaCertFile );
       
   473 			User::Leave(KVpnErrInvalidCaCertFile);
       
   474 		}
       
   475 	}	
       
   476     iSendCert = iHostData->iAlwaysSendCert; //If true will always be sent, otherwise only with a CR
       
   477 
       
   478     //Proposals
       
   479     if (!BuildProposals1L())
       
   480     {
       
   481         SetFinished();
       
   482         User::Leave(KKmdIkePolicyFileErr); //if any error returns
       
   483     }
       
   484 
       
   485     iEncoding = X509_CERT_SIG;  //Only type in use
       
   486 
       
   487     iChosenProposal_I.iAttrList = new (ELeave) TAttrib; //allocated now and deleted when destroying the obj   
       
   488     User::LeaveIfError( iPluginSession->GetLocalAddress( iLocalAddr ) );
       
   489 
       
   490     //PFKEY data (is overwritten if initiator because we use the data given in the acquire
       
   491 
       
   492     iAcquireSeq = 1;//msg Seq. number of acquire needed for the UPDATE
       
   493     iSeq = 1;       //Sequence number for pfkey messages
       
   494 
       
   495 	iLastRemoteAddr = iRemoteAddr;   // Used as destination address when sending data
       
   496 #ifdef _DEBUG	
       
   497 	TBuf<40> txt_addr;
       
   498     iRemoteAddr.OutputWithScope(txt_addr);
       
   499 #endif            
       
   500     
       
   501     iLastMsg = HBufC8::NewL(4096);
       
   502     
       
   503     DEBUG_LOG1( _L("New negotiation with Host %S"),
       
   504             &txt_addr );
       
   505 
       
   506     if ( !iHostData->iUseNatProbing && iHostData->iEspUdpPort == 0 )
       
   507 	{
       
   508        //
       
   509        // Use IETF specified NAT traversal
       
   510        //
       
   511        iNatDiscovery = CIkev1NatDiscovery::NewL(0);   
       
   512     }
       
   513 	
       
   514 	if ( iRole == RESPONDER )
       
   515 	{
       
   516 	   //
       
   517 	   // Get base value internal address (=VPN virtual IP)
       
   518 	   //
       
   519 	   iInternalAddr = iPluginSession->InternalAddressL();
       
   520 	}	
       
   521 }
       
   522 
       
   523 
       
   524 TBool CIkev1Negotiation::ReadCAsL(CArrayFixFlat<TCertInfo*> *aCAList)
       
   525 {
       
   526 
       
   527 	TBool Status = iPkiService->ImportCACertsL(aCAList);
       
   528 
       
   529 #ifdef _DEBUG	
       
   530 	if ( !Status )
       
   531 	    {
       
   532 	    DEBUG_LOG( _L("Trusted CA list creation failed!") );
       
   533 	    }
       
   534 #endif // _DEBUG
       
   535 	
       
   536 	return Status;
       
   537 			   
       
   538 }
       
   539 
       
   540 TBool CIkev1Negotiation::ReadOwnCertL()
       
   541 {
       
   542     //
       
   543     // Read own certificate from PKI store using own trusted CA as
       
   544     // specified issuer
       
   545     //
       
   546     TBool Status = EFalse;
       
   547     _LIT(KVpnApplUid, "101F7993");
       
   548     if ( iPkiService && iHostData->iCAList )
       
   549 		{
       
   550        TCertInfo* CertInfo;
       
   551 	   HBufC8* CAName = HBufC8::NewLC(256);  	   
       
   552        TInt i = 0;
       
   553        if ( iHostData->iCAList->At(0)->iData!=KVpnApplUid )
       
   554           {
       
   555 	       while ( i < iHostData->iCAList->Count() )
       
   556 			   {
       
   557 
       
   558 	           CertInfo = iHostData->iCAList->At(i);
       
   559 	           CAName->Des().Copy(CertInfo->iData); // Assure that CA name is in ASCII format
       
   560                if ( iPkiService->ReadUserCertWithNameL(CAName->Des(), iHostData, EFalse) == KErrNone )
       
   561 				   {
       
   562 				   Status = ETrue;			   
       
   563 				   delete iOwnCert;  // delete old if exists			   
       
   564 				   iOwnCert = iPkiService->GetCertificate();
       
   565 				   delete iPeerTrustedCA;  // for sure
       
   566 				   iPeerTrustedCA = iPkiService->GetTrustedCA();
       
   567                    CleanupStack::PopAndDestroy(CAName);   //CAName
       
   568                    CAName=NULL;
       
   569 				   break;
       
   570 				   }
       
   571                i ++;           
       
   572                }
       
   573               if (!Status)
       
   574                   {
       
   575                   CleanupStack::PopAndDestroy(CAName);
       
   576                   CAName=NULL;
       
   577                   }
       
   578            }
       
   579        else
       
   580            {
       
   581            CIkeCaList* trustedCaList = iPkiService->CaList();
       
   582            CleanupStack::PopAndDestroy(CAName);        
       
   583            CAName=NULL;
       
   584            while ( i < trustedCaList->Count() )
       
   585                {
       
   586                
       
   587                CIkeCaElem* CaElem = (*trustedCaList)[i];                     
       
   588                CAName = IkeCert::GetCertificateFieldDERL(CaElem->Certificate(), KSubjectName);
       
   589                if (CAName == NULL)
       
   590                   {
       
   591                    User::Leave(KErrArgument);
       
   592                   }
       
   593                CleanupStack::PushL(CAName);
       
   594                if ( iPkiService->ReadUserCertWithNameL(*CAName, iHostData, ETrue) == KErrNone)
       
   595                    {
       
   596                    Status = ETrue;             
       
   597                    delete iOwnCert;  // delete old if exists               
       
   598                    iOwnCert = iPkiService->GetCertificate();
       
   599                    delete iPeerTrustedCA;
       
   600                    iPeerTrustedCA = iPkiService->GetTrustedCA();
       
   601                    CleanupStack::PopAndDestroy(CAName);        
       
   602                    CAName=NULL;
       
   603                    
       
   604                    
       
   605                    break;
       
   606                    }
       
   607                i ++;
       
   608                
       
   609                CleanupStack::PopAndDestroy(CAName);
       
   610                CAName=NULL;
       
   611                } 
       
   612            }
       
   613        if ( !Status )
       
   614 		   {	   
       
   615           DEBUG_LOG( _L("Error loading Own Certificate!") );
       
   616 		   }		   
       
   617     }
       
   618     return Status;
       
   619 }
       
   620 
       
   621 
       
   622 
       
   623 void CIkev1Negotiation::GetAcquireDataL(const TPfkeyMessage &aReq)
       
   624 {
       
   625     // ACQUIRE Contains: <Base, Addr(Src & Dest) (Addr(Proxy)), (Ident(S & D)), (Sensitivity), Proposal>
       
   626     
       
   627     iLocalAddr = *aReq.iSrcAddr.iAddr;    //Copies our own address because it's the only way to know it
       
   628 
       
   629     //Phase II proposals
       
   630     //Only one combination received so only one transform
       
   631     CProposal_II *prop_II = new (ELeave) CProposal_II();
       
   632     CleanupStack::PushL(prop_II);
       
   633     prop_II->ConstructL();
       
   634     iProposal_IIList->AppendL(prop_II);
       
   635     CleanupStack::Pop();            //prop_II safe in case of leave
       
   636 
       
   637     prop_II->iProposalNum   = FIRST_IPSEC_PROPOSAL;
       
   638     prop_II->iNumTransforms = 1;
       
   639     prop_II->iReplayWindowLength = aReq.iProposal.iExt->sadb_prop_replay;
       
   640     TAttrib_II *attr_II = new (ELeave) TAttrib_II();
       
   641     CleanupStack::PushL(attr_II);
       
   642     prop_II->iAttrList->AppendL(attr_II);   //added into the proposal so it's safe if function leaves
       
   643     CleanupStack::Pop();            //attr_II safe in case of leave
       
   644 
       
   645     attr_II->iTransformNum = FIRST_IPSEC_TRANSFORM;
       
   646 
       
   647     if (aReq.iBase.iMsg->sadb_msg_satype==SADB_SATYPE_AH)
       
   648     {
       
   649         prop_II->iProtocol = PROTO_IPSEC_AH;
       
   650         if (aReq.iProposal.iComb->sadb_comb_auth == SADB_AALG_MD5HMAC)
       
   651         {
       
   652             attr_II->iTransformID = AH_MD5;
       
   653             attr_II->iAuthAlg = DOI_HMAC_MD5;
       
   654         }
       
   655         else if (aReq.iProposal.iComb->sadb_comb_auth == SADB_AALG_SHA1HMAC)
       
   656         {
       
   657             attr_II->iTransformID=AH_SHA;
       
   658             attr_II->iAuthAlg = DOI_HMAC_SHA;
       
   659         }
       
   660         else
       
   661         {
       
   662             DEBUG_LOG(_L("Unsupported Authentication Algorithm in Acquire"));
       
   663 			SetFinished();					
       
   664             return;
       
   665         }
       
   666         // No auth with variable encryption
       
   667     }
       
   668     else if (aReq.iBase.iMsg->sadb_msg_satype == SADB_SATYPE_ESP)
       
   669     {
       
   670         prop_II->iProtocol=PROTO_IPSEC_ESP;
       
   671         /* Request ESP from peer host */
       
   672 
       
   673         attr_II->iTransformID = aReq.iProposal.iComb->sadb_comb_encrypt;
       
   674 		switch ( attr_II->iTransformID )
       
   675 		{
       
   676 			case ESP_DES_CBC:
       
   677 			case ESP_3DES_CBC:
       
   678 			case ESP_NULL:
       
   679 				break;
       
   680 				
       
   681 			case ESP_AES_CBC:
       
   682 				attr_II->iKeyLength = aReq.iProposal.iComb->sadb_comb_encrypt_maxbits;
       
   683 				break;
       
   684 
       
   685 			default:
       
   686 				DEBUG_LOG(_L("IPsec Encryption algorithm is not implemented. Wrong algorithms file"));
       
   687 				SetFinished();
       
   688 				return;
       
   689 				
       
   690 		}	
       
   691         if (aReq.iProposal.iComb->sadb_comb_auth != SADB_AALG_NONE)
       
   692         {
       
   693             if (aReq.iProposal.iComb->sadb_comb_auth == SADB_AALG_MD5HMAC)
       
   694                 attr_II->iAuthAlg = DOI_HMAC_MD5;
       
   695             else if (aReq.iProposal.iComb->sadb_comb_auth == SADB_AALG_SHA1HMAC)
       
   696                 attr_II->iAuthAlg = DOI_HMAC_SHA;
       
   697             else
       
   698             {
       
   699                 DEBUG_LOG(_L("Unsupported Authentication Algorithm in Acquire"));
       
   700 				SetFinished();
       
   701 				return;
       
   702             }
       
   703         }
       
   704     }
       
   705     
       
   706     //Check if PFS in use...
       
   707     if (aReq.iProposal.iComb->sadb_comb_flags & SADB_SAFLAGS_PFS)
       
   708     {
       
   709         iPFS=ETrue;
       
   710         switch (iHostData->iGroupDesc_II)
       
   711         {
       
   712         case IKE_PARSER_MODP_768:
       
   713             attr_II->iGroupDesc = MODP_768;
       
   714             break;
       
   715         case IKE_PARSER_MODP_1024:
       
   716             attr_II->iGroupDesc = MODP_1024;
       
   717             break;
       
   718         case IKE_PARSER_MODP_1536:
       
   719             attr_II->iGroupDesc = MODP_1536;
       
   720             break;
       
   721         case IKE_PARSER_MODP_2048:
       
   722             attr_II->iGroupDesc = MODP_2048;
       
   723             break;
       
   724         default:
       
   725             DEBUG_LOG(_L("ISAKMP Proposals error (Bad Group description)"));
       
   726 			SetFinished();
       
   727 			return;
       
   728         }
       
   729     }
       
   730     else
       
   731     {
       
   732         iPFS=EFalse;
       
   733         attr_II->iGroupDesc = 0;    //No group assigned because no PFS
       
   734     }
       
   735 
       
   736     if (aReq.iProposal.iComb->sadb_comb_flags & SADB_SAFLAGS_TUNNEL)
       
   737     {
       
   738         attr_II->iEncMode = DOI_TUNNEL;
       
   739     }
       
   740     else
       
   741     {
       
   742         attr_II->iEncMode = DOI_TRANSPORT;
       
   743     }
       
   744 
       
   745     iIDLocalPort = (TUint16)aReq.iSrcAddr.iAddr->Port();
       
   746     iIDRemotePort = (TUint16)aReq.iDstAddr.iAddr->Port();
       
   747     iIDProtocol = aReq.iDstAddr.iExt->sadb_address_proto;   //May be needed for phase II ID
       
   748 
       
   749     //Source Identity
       
   750     if (aReq.iSrcIdent.iExt)
       
   751     {
       
   752         if (aReq.iSrcIdent.iExt->sadb_ident_type == SADB_IDENTTYPE_PREFIX)
       
   753         {
       
   754 			if ( !ProcessIdentityData(aReq.iSrcIdent.iData, &iLocalIDType_II,
       
   755 								      &iLocalAddr1_ID_II, &iLocalAddr2_ID_II) )
       
   756 			{
       
   757 				SetFinished();
       
   758 				return;
       
   759 			}	
       
   760 		}
       
   761         else    //Invalid identity type
       
   762         {
       
   763             DEBUG_LOG1(_L("Invalid Local identity type (%d)"), aReq.iSrcIdent.iExt->sadb_ident_type);
       
   764 			SetFinished();
       
   765 			return;
       
   766         }
       
   767     }
       
   768     else
       
   769     {
       
   770         //We need to assign a default address if other info is to be sent in the same payload
       
   771         if (attr_II->iEncMode == DOI_TUNNEL || iIDLocalPort != 0 || iIDRemotePort != 0 ||
       
   772             iIDProtocol != 0 || aReq.iDstIdent.iExt)
       
   773         {
       
   774             DEBUG_LOG(_L("Local Identity not defined and needed. Using Own address as local identity."));
       
   775             iLocalAddr1_ID_II = iLocalAddr;
       
   776             if ((iLocalAddr.Family() == KAfInet) || iLocalAddr.IsV4Mapped() )
       
   777                 iLocalIDType_II = ID_IPV4_ADDR;
       
   778             else
       
   779                 iLocalIDType_II = ID_IPV6_ADDR;
       
   780             iDefaultLocalID = ETrue;    //Must be sent but won't be used when updating the SAD
       
   781         }
       
   782     }
       
   783 
       
   784     //Destination Identity
       
   785     if (aReq.iDstIdent.iExt)
       
   786     {
       
   787         if (aReq.iDstIdent.iExt->sadb_ident_type == SADB_IDENTTYPE_PREFIX)
       
   788         {
       
   789 			if ( !ProcessIdentityData(aReq.iDstIdent.iData, &iRemoteIDType_II,
       
   790 									  &iRemoteAddr1_ID_II, &iRemoteAddr2_ID_II) )
       
   791 			{
       
   792 				SetFinished();
       
   793 				return;
       
   794 			}
       
   795         }
       
   796         else    //Invalid identity type
       
   797         {
       
   798             
       
   799             DEBUG_LOG1( _L("Invalid Destination identity type (%d)"), aReq.iDstIdent.iExt->sadb_ident_type );
       
   800 			SetFinished();
       
   801 			return;
       
   802         }
       
   803     }
       
   804     else
       
   805     {
       
   806         //
       
   807         // RemoteID_II is required only if LocalID_II already exists
       
   808 		// If transports mode
       
   809         //      Build RemoteID_II for Quick mode negotiation from specified remote IP address
       
   810         // else Use subnet 0/0 as remote id
       
   811 		//
       
   812         if ( iLocalIDType_II != 0 )
       
   813         {
       
   814 		   if (	attr_II->iEncMode == DOI_TUNNEL ) {
       
   815 			  if ( iLocalIDType_II == ID_IPV4_ADDR || iLocalIDType_II == ID_IPV4_ADDR_SUBNET ) {
       
   816 				 iRemoteAddr1_ID_II.Init(KAfInet);
       
   817 				 iRemoteAddr2_ID_II.Init(KAfInet); 				 
       
   818 				 iRemoteIDType_II = ID_IPV4_ADDR_SUBNET;
       
   819 			  }	   
       
   820 			  else {
       
   821 			     iRemoteAddr1_ID_II.Init(KAfInet6);
       
   822 				 iRemoteAddr2_ID_II.Init(KAfInet6); 				 				 
       
   823 				 iRemoteIDType_II = ID_IPV6_ADDR_SUBNET;
       
   824 			  }	 
       
   825 		   }
       
   826 		   else {
       
   827               iRemoteAddr1_ID_II = *aReq.iDstAddr.iAddr;
       
   828 			  if ( iRemoteAddr1_ID_II.Family() == KAfInet6 )			  
       
   829 				   iRemoteIDType_II = ID_IPV6_ADDR;
       
   830 			  else iRemoteIDType_II = ID_IPV4_ADDR;
       
   831 		   }   
       
   832            iDefaultRemoteID = ETrue;  //Must be sent but won't be used when updating the SAD   
       
   833         }  
       
   834     }
       
   835 
       
   836     //Only Hard Lifetimes taken into account
       
   837     TInt64 lifetime64 = aReq.iProposal.iComb->sadb_comb_soft_addtime;
       
   838     iHardLifetime = aReq.iProposal.iComb->sadb_comb_hard_addtime;
       
   839     
       
   840     if ( lifetime64 == 0 )
       
   841         {
       
   842         lifetime64 = iHardLifetime;
       
   843         }
       
   844     
       
   845     TUint high = 0;
       
   846     TUint low = 0;
       
   847     if (lifetime64!=0)
       
   848     {
       
   849         high = ByteOrder::Swap32(I64HIGH(lifetime64));
       
   850         if (high > 0)
       
   851             attr_II->iLifeDurationSecs.Copy((TUint8 *)&high, sizeof(high));
       
   852         low = ByteOrder::Swap32(I64LOW(lifetime64));
       
   853         attr_II->iLifeDurationSecs.Append((TUint8 *)&low, sizeof(low));
       
   854     }
       
   855 
       
   856     //Bytes lifetime
       
   857     lifetime64 = aReq.iProposal.iComb->sadb_comb_soft_bytes;
       
   858     lifetime64 = (lifetime64/1024); //Bytes to KB
       
   859     if (lifetime64 != 0)
       
   860     {
       
   861         high = ByteOrder::Swap32(I64HIGH(lifetime64));      
       
   862         if (high > 0)
       
   863             attr_II->iLifeDurationKBytes.Copy((TUint8 *)&high, sizeof(high));
       
   864         low = ByteOrder::Swap32(I64LOW(lifetime64));        
       
   865         attr_II->iLifeDurationKBytes.Append((TUint8 *)&low, sizeof(low));
       
   866     }
       
   867 
       
   868     //Save some pf_key data to use later in PFKEY_UPDATE msg
       
   869     iAcquireSeq = aReq.iBase.iMsg->sadb_msg_seq;        //msg Seq. number
       
   870     iPfkeyAcquirePID = aReq.iBase.iMsg->sadb_msg_pid;   //msg PID.
       
   871     iAcquirePending = ETrue;
       
   872     DEBUG_LOG2( _L("Acq seq= %d , PID= %d"), iAcquireSeq, iPfkeyAcquirePID );
       
   873     
       
   874 }
       
   875 
       
   876 //
       
   877 //  CIkev1Negotiation::ExecuteL()
       
   878 //  An ISAKMP message has been received belonging to this negotiation.
       
   879 //  Process the message and advance the negotiation session to appropriate
       
   880 //  next state/stage.
       
   881 //
       
   882 TBool CIkev1Negotiation::ExecuteL( const ThdrISAKMP& aHdr,
       
   883                                    const TInetAddr& aRemote,
       
   884                                    TInt aLocalPort )
       
   885 {
       
   886     aLocalPort = aLocalPort;
       
   887 
       
   888     TBool ret=EFalse;
       
   889     const ThdrISAKMP *hdr;
       
   890     TUint8 *msg = NULL;   //to place the new msg
       
   891     TBuf8<IKEV1_MAX_IV_SIZE> tmp_IV(iIV);   //Temporal IV. Used to update the real one if the msg OK
       
   892     
       
   893     TLastIKEMsg msg_info(aHdr); //For retransmitted IKE msg detection
       
   894     if ( IsRetransmit(msg_info) ) {
       
   895        DEBUG_LOG(_L("Retransmitted IKE message received."));       
       
   896        TBool FloatedPort = EFalse; 
       
   897        if ( iNAT_D_Flags & (REMOTE_END_NAT + LOCAL_END_NAT) )
       
   898            FloatedPort = ETrue;
       
   899        TPtr8 lastMsg(iLastMsg->Des());
       
   900        iPluginSession->SendIkeMsgL(lastMsg, iLastRemoteAddr, FloatedPort);        
       
   901        return EFalse;              
       
   902     }
       
   903 
       
   904     if ( iPhase == PHASE_II &&
       
   905          aHdr.GetExchange() != IKE_QUICK_MODE )
       
   906     {
       
   907         DEBUG_LOG(_L("Bad packet (retransmission?)"));
       
   908 #ifdef _DEBUG                    
       
   909         const TPtrC8 ikeMsgPtr( (TUint8 *)&aHdr, (TUint16)aHdr.GetLength() );
       
   910         TInetAddr dstAddr;
       
   911         iPluginSession->GetLocalAddress( dstAddr );
       
   912         dstAddr.SetPort( aLocalPort );
       
   913         TRACE_MSG_IKEV1( ikeMsgPtr, iRemoteAddr, dstAddr );
       
   914 #endif // _DEBUG                            
       
   915 
       
   916         SetFinished();
       
   917         return EFalse;  //Bad packet, is a retransmission
       
   918     }    
       
   919     
       
   920 	iLastRemoteAddr = aRemote;  //Save last remote address (used in NAT cases)	
       
   921 
       
   922     iLengthLeft = aHdr.GetLength(); //Used to check the size in the payload are OK
       
   923 
       
   924     DEBUG_LOG2( _L("---------- Phase %d - Stage %d ----------"), iPhase, iStage );
       
   925 
       
   926     if ((iStage==1) && (iPhase==PHASE_I))   //Only saved for the first message
       
   927         iExchange = aHdr.GetExchange();
       
   928 
       
   929     DEBUG_LOG1( _L("Exchange %d"), aHdr.GetExchange() );
       
   930 
       
   931     if (aHdr.GetFlags() & ISAKMP_HDR_EFLAG) //if encrypted
       
   932     {
       
   933         //before anything, prints the packet
       
   934         DEBUG_LOG(_L("Received message (encr)."));
       
   935         DEBUG_LOG(_L("Decrypting..."));
       
   936         msg = new (ELeave)(TUint8[aHdr.GetLength()]);    //to place the new msg
       
   937 		CleanupStack::PushL(msg);
       
   938 		
       
   939         Mem::Copy(msg,(TUint8 *)&aHdr,sizeof(aHdr));    //The header is not encrypted
       
   940 
       
   941         if ((iPhase==PHASE_II) && (iStage == 1))
       
   942         {
       
   943             iMessageId = aHdr.GetMessageId();   //Saves the ID to compute IV
       
   944             DEBUG_LOG(_L("Quick IV:"));
       
   945             ComputeIVL(iIV, iMessageId);
       
   946         }
       
   947 
       
   948         DecryptL((TUint8 *)aHdr.Next(),&msg[sizeof(aHdr)], aHdr.GetLength()-sizeof(aHdr),iIV, iSKEYID_e, iChosenProposal_I.iAttrList->iEncrAlg);
       
   949         if ((iStage == 6 && iExchange == ISAKMP_EXCHANGE_ID) || 
       
   950             (iStage == 3 && iExchange == ISAKMP_EXCHANGE_AGGR))
       
   951         {
       
   952             iLastIV.Copy(iIV);  //Saves last IV in Phase 1
       
   953             DEBUG_LOG(_L("Last IV Saved!"));
       
   954         }
       
   955         hdr=(ThdrISAKMP *)msg;  //decrypted msg
       
   956 
       
   957     }
       
   958     else if (iFlags & ISAKMP_HDR_EFLAG)  // IKE message SHOULD be encrypted
       
   959     {
       
   960         hdr=&aHdr;  //no encryption    
       
   961         DEBUG_LOG(_L("Received message."));
       
   962 #ifdef _DEBUG                    
       
   963         const TPtrC8 ikeMsgPtr( (TUint8 *)hdr, (TUint16)hdr->GetLength() );
       
   964         TInetAddr dstAddr;
       
   965         iPluginSession->GetLocalAddress( dstAddr );
       
   966         dstAddr.SetPort( aLocalPort );
       
   967         TRACE_MSG_IKEV1( ikeMsgPtr, iRemoteAddr, dstAddr );
       
   968 #endif // _DEBUG                            
       
   969         DEBUG_LOG(_L("The message is NOT encrypted (ignored)"));
       
   970         return EFalse;
       
   971     }
       
   972     else
       
   973         hdr=&aHdr;  //no encryption
       
   974 
       
   975     DEBUG_LOG(_L("Received message."));
       
   976 #ifdef _DEBUG                    
       
   977     const TPtrC8 ikeMsgPtr( (TUint8 *)hdr, (TUint16)hdr->GetLength() );
       
   978     TInetAddr dstAddr;
       
   979     iPluginSession->GetLocalAddress( dstAddr );
       
   980     dstAddr.SetPort( aLocalPort );
       
   981     TRACE_MSG_IKEV1( ikeMsgPtr, iRemoteAddr, dstAddr );
       
   982 #endif // _DEBUG                            
       
   983 
       
   984     if (iPhase==PHASE_I)
       
   985         ret = Phase_IExchangeL(*hdr);//MAIN MODE && AGGRESSIVE MODE
       
   986     else
       
   987     {
       
   988         ret = Phase_IIExchangeL(*hdr);//QUICK MODE 
       
   989     }
       
   990     if (!ret)   //Incorrect packet. Restore the IV
       
   991     {
       
   992         DEBUG_LOG(_L("Restoring previous IV"));
       
   993         iIV.Copy(tmp_IV);
       
   994     }
       
   995     else    //correct packet
       
   996     {
       
   997         SaveRetransmitInfo(msg_info); // store new last received IKE message info        
       
   998     }
       
   999 
       
  1000     if ( msg )    //If used erase it (when encryption)
       
  1001  	   CleanupStack::PopAndDestroy(); 
       
  1002 
       
  1003     return ret;
       
  1004 }
       
  1005 
       
  1006 TBool CIkev1Negotiation::ExecutePhase2L( const ThdrISAKMP &aHdr,
       
  1007                                          const TInetAddr &aRemote,
       
  1008                                          TInt aLocalPort )
       
  1009 {
       
  1010     return ExecuteL( aHdr, aRemote, aLocalPort );
       
  1011 }
       
  1012 
       
  1013 //
       
  1014 // CIkev1Negotiation::ExecuteTransactionL
       
  1015 // An ISAKMP Transaction exchange message received.
       
  1016 // Call CTransNegotiation::ExecuteL method and process returned status
       
  1017 //
       
  1018 TBool CIkev1Negotiation::ExecuteTransactionL( const ThdrISAKMP& aHdr,
       
  1019                                               const TInetAddr& aRemote,
       
  1020                                               TInt aLocalPort )
       
  1021 {
       
  1022     TInt  status;
       
  1023 	TBool ret = ETrue;
       
  1024     if ( iTransactionNeg ) {
       
  1025        status = iTransactionNeg->ExecuteL( aHdr, aRemote, aLocalPort );
       
  1026        if ( status == TRANSACTION_SUCCESS ) {
       
  1027           //
       
  1028           // XAUTH / CONFIG-MODE completed succesfully
       
  1029           //
       
  1030           IsakmpPhase1CompletedL(); 
       
  1031        }
       
  1032        else {
       
  1033           if ( status == TRANSACTION_FAILED ) {
       
  1034              //
       
  1035              // XAUTH / CONFIG-MODE completed succesfully
       
  1036              //
       
  1037 			 LOG_KMD_EVENT( MKmdEventLoggerIf::KLogError,
       
  1038 			                R_VPN_MSG_VPN_GW_AUTH_FAIL,
       
  1039 			                KKmdIkeAuthFailedErr,
       
  1040 			                iPluginSession->VpnIapId(),
       
  1041 			                &iRemoteAddr );
       
  1042 			 SendDeleteL(PROTO_ISAKMP);
       
  1043              SetFinished(); 
       
  1044           }   
       
  1045        }       
       
  1046     }
       
  1047 	else ret = EFalse;
       
  1048 
       
  1049     return ret;
       
  1050 }
       
  1051 
       
  1052 
       
  1053 //
       
  1054 // CIkev1Negotiation::AuthDialogCompletedL
       
  1055 // Authentication dialog is completed. Check CAuthDialogInfo object ID
       
  1056 // and call eithet CIKECRACKNegotiation::ProcessUserResponseL or
       
  1057 // CTransNegotiation::ProcessUserResponseL to handle dialog data
       
  1058 //
       
  1059 void CIkev1Negotiation::AuthDialogCompletedL(CAuthDialogInfo *aUserInfo)
       
  1060 {
       
  1061 	if ( !aUserInfo || (!aUserInfo->iUsername && !aUserInfo->iSecret) ) 
       
  1062 	{
       
  1063 	   DEBUG_LOG(_L("Legacy authentication cancelled by user!"));		
       
  1064 	   SendDeleteL(PROTO_ISAKMP);		
       
  1065 	   LOG_KMD_EVENT( MKmdEventLoggerIf::KLogError,
       
  1066 	                  R_VPN_MSG_VPN_GW_AUTH_FAIL,
       
  1067 	                  KErrCancel,
       
  1068 	                  iPluginSession->VpnIapId(),
       
  1069 	                  &iRemoteAddr );
       
  1070 	   SetErrorStatus(KErrCancel);
       
  1071 	   return;
       
  1072 	}	
       
  1073 		
       
  1074     TInt status;
       
  1075 
       
  1076     if ( aUserInfo->GetObjId() == XAUTH_DIALOG_ID ) 
       
  1077     {
       
  1078        if ( iTransactionNeg )
       
  1079             status = iTransactionNeg->ProcessUserResponseL(aUserInfo);       
       
  1080        else status = TRANSACTION_FAILED;
       
  1081        
       
  1082        if ( status == TRANSACTION_FAILED ) 
       
  1083        {
       
  1084          /*--------------------------------------------------------
       
  1085           *
       
  1086           *  XAUTH negotiation failed. Negotiation shall be deleted
       
  1087           *
       
  1088           *--------------------------------------------------------*/
       
  1089 		  LOG_KMD_EVENT( MKmdEventLoggerIf::KLogError,
       
  1090 		                 R_VPN_MSG_VPN_GW_AUTH_FAIL,
       
  1091 		                 status,
       
  1092 		                 iPluginSession->VpnIapId(),
       
  1093 		                 &iRemoteAddr );
       
  1094 		  SetErrorStatus(KKmdIkeAuthFailedErr);
       
  1095           AcquireSAErrorResponse(KKmdIkeAuthFailedErr);
       
  1096        }      
       
  1097     }
       
  1098     else 
       
  1099     {
       
  1100        if ( iCRACKneg )
       
  1101             status = iCRACKneg->ProcessUserResponseL(aUserInfo);       
       
  1102        else status = CRACK_FAILED;
       
  1103 
       
  1104        if ( status == CRACK_FAILED ) 
       
  1105        {
       
  1106          /*--------------------------------------------------------
       
  1107           *
       
  1108           *  Crack negotiation failed. Negotiation shall be deleted
       
  1109           *
       
  1110           *--------------------------------------------------------*/
       
  1111 		  LOG_KMD_EVENT( MKmdEventLoggerIf::KLogError,
       
  1112 		                 R_VPN_MSG_VPN_GW_AUTH_FAIL,
       
  1113 		                 status,
       
  1114 		                 iPluginSession->VpnIapId(),
       
  1115 		                 &iRemoteAddr );		   
       
  1116 		  SetErrorStatus(KKmdIkeAuthFailedErr);		  
       
  1117           AcquireSAErrorResponse(KKmdIkeAuthFailedErr);
       
  1118        }      
       
  1119     }
       
  1120 }
       
  1121 
       
  1122 
       
  1123 //
       
  1124 // CIkev1Negotiation::StartCRACKAuthL
       
  1125 //      Start CRACK authentication phase of IKE phase I negotiation
       
  1126 //      - Create CIKECRACKNegotiation object and call it`s ConstructL
       
  1127 //      - Set iStage variable to 7 to indicate that CRACK authentication
       
  1128 //        is going
       
  1129 //
       
  1130 TBool CIkev1Negotiation::StartCRACKAuthL()
       
  1131 {
       
  1132 TInt status;    
       
  1133 
       
  1134     iStage = 7;
       
  1135     
       
  1136     if ( !iCRACKneg ) {
       
  1137        iCRACKneg = new(ELeave) CIKECRACKNegotiation( iDebug );
       
  1138 	   TBuf<2> DummyDomain;
       
  1139 	   //
       
  1140 	   // If the IKE Id-type value is configured to value "Opaque
       
  1141 	   // String" and iFQDN length is larger than zero in the current
       
  1142 	   // policy ==> iFQDN value contains "Group name" value
       
  1143 	   // which shall be conveyed to the peer in CRACK "Domain name"
       
  1144 	   // attribute  
       
  1145 	   //
       
  1146        iFlags |= ISAKMP_HDR_EFLAG; //From now on encryption is used    
       
  1147 	   
       
  1148 	   if ( (iHostData->iIdType == ID_KEY_ID) && (iHostData->iFQDN.Length() > 0 ) )
       
  1149             status = iCRACKneg->ConstructL(iHostData->iCRACKLAMType, this, iHostData->iFQDN);
       
  1150 	   else status = iCRACKneg->ConstructL(iHostData->iCRACKLAMType, this, DummyDomain);
       
  1151        if ( status == CRACK_FAILED ) {
       
  1152           return EFalse;
       
  1153        }
       
  1154     }
       
  1155     
       
  1156     return ETrue;
       
  1157 }
       
  1158 
       
  1159 //
       
  1160 // CIkev1Negotiation::IsakmpPhase1CompletedL
       
  1161 // This method is called when an ISAKMP phase 1 negotiation is succesfully
       
  1162 // completed. The following actions are taken:
       
  1163 // -- If either Extended authentication or/and Config mode required
       
  1164 //    If iTransactionNeg data member exists it means that XAUTH/CONFIG mode
       
  1165 //    has been succesfully completed.
       
  1166 //    If iTransactionNeg data member is NULL, XAUTH/CONFIG mode shall be initiated
       
  1167 // -- If No XAUTH/CONFIG mode (or if XAUTH/CONFIG mode already completed).
       
  1168 //    If iAutoLogin is TRUE save ISAKMP SA and deconstruct negotiation.
       
  1169 //    If iAutoLogin is False, save ISAKMP SA and;
       
  1170 //       if negotiation role is initiator continue with Quick mode exchange. 
       
  1171 //       if negotiation role is responder deconstruct negotiation.
       
  1172 //
       
  1173 TBool CIkev1Negotiation::IsakmpPhase1CompletedL()
       
  1174 {
       
  1175     TBool Status;
       
  1176 
       
  1177     if ( iTransactionNeg ) {
       
  1178        //
       
  1179        // Try to get Internal address information and delete iTransactionNeg
       
  1180        //
       
  1181        delete iInternalAddr;  
       
  1182        iInternalAddr = iTransactionNeg->GetInternalAddr();
       
  1183        delete iTransactionNeg;
       
  1184        iTransactionNeg = NULL;
       
  1185     }
       
  1186     else {
       
  1187        if ( (iRole == INITIATOR) && (iHostData->iUseXauth || iHostData->iUseCfgMode) )
       
  1188 	   {
       
  1189 		  TBool useModeCfg;
       
  1190 		  if ( iSARekeyInfo )
       
  1191 		       useModeCfg = EFalse;  // Use existing virtual Ip, if any
       
  1192 		  else 
       
  1193 		      useModeCfg = iHostData->iUseCfgMode; 
       
  1194 		  
       
  1195           iTransactionNeg = CTransNegotiation::NewL( iHostData->iUseXauth,
       
  1196                                                      useModeCfg,
       
  1197                                                      iPluginSession,
       
  1198                                                      this,
       
  1199                                                      iDebug );
       
  1200           
       
  1201           // If only MODE_CFG is needed a request is sent
       
  1202           if(useModeCfg && !iHostData->iUseXauth)
       
  1203               iTransactionNeg->BuildConfigRequestL();
       
  1204           
       
  1205           iStage = 8;                    
       
  1206           return ETrue; 
       
  1207        }       
       
  1208     }   
       
  1209 
       
  1210 	SaveISAKMPSAL();
       
  1211 
       
  1212     if ( iAutoLogin ) {
       
  1213        //
       
  1214        // ISAKMP Phase 1 completed. Quick mode is NOT started because there is no acquire pending
       
  1215        // but phase 1 negotiation is started by the policy activation.   
       
  1216        //
       
  1217        CInternalAddress* internalAddr = NULL;
       
  1218        if ( iInternalAddr != NULL )
       
  1219            {
       
  1220            internalAddr = CInternalAddress::NewL(*iInternalAddr);        
       
  1221            }
       
  1222        iPluginSession->IkeSaCompleted(KErrNone, internalAddr);
       
  1223 	   SetFinished(); // Causes negotiation object destruction	   
       
  1224 	   iAutoLogin = EFalse; 	   
       
  1225        Status     = EFalse;
       
  1226     }
       
  1227     else {
       
  1228 	   if ( iRole == INITIATOR ) {
       
  1229 	      TBool internalAddressChanged = EFalse;
       
  1230 		  if ( iInternalAddr ) {
       
  1231 		     //
       
  1232 		     // Report internal IP address changed event
       
  1233 		     //
       
  1234 	         internalAddressChanged = iPluginSession->InternalAddressChangedL(*iInternalAddr);
       
  1235 		  }
       
  1236 		  if ( (!iSARekeyInfo ||
       
  1237 		       iPhaseIIAfterIkeSaRekey) &&
       
  1238 		       !internalAddressChanged )
       
  1239 		  {	  
       
  1240              iPhaseIIAfterIkeSaRekey = EFalse;
       
  1241              iPrevExchange = iExchange;  //Needed to know how to begin Phase II (Sending or receiving)
       
  1242 		     iExchange  = IKE_QUICK_MODE;
       
  1243 		     iPhase     = PHASE_II;
       
  1244 		     iStage     = 1;
       
  1245  	         Status     = ETrue;
       
  1246              iMessageId = RandomMessageId(); 
       
  1247              InitPhase2L();  //Immediately inits PHASE_II. No reply expected.
       
  1248 		  }
       
  1249 		  else {
       
  1250 			  //
       
  1251 			  // Rekeyed IKE SA or internal address changed. No IKE quick mode started
       
  1252 		      // Pending acquire will be failed, if internal address has changed.
       
  1253 			  //
       
  1254 			  SetFinished(); 
       
  1255 			  Status    = EFalse;
       
  1256 		  }	  
       
  1257 	   }
       
  1258 	   else {
       
  1259 	      SetFinished(); // Causes negotiation object destruction
       
  1260 		  Status    = EFalse;
       
  1261 	   }	   
       
  1262     }
       
  1263 	
       
  1264 	LOG_KMD_EVENT( MKmdEventLoggerIf::KLogInfo,
       
  1265 	               R_VPN_MSG_VPN_GW_AUTH_OK,
       
  1266 	               KErrNone,
       
  1267 	               iPluginSession->VpnIapId(),
       
  1268 	               &iRemoteAddr );
       
  1269 
       
  1270 	TInt NatStatus = iNAT_D_Flags;   // Record "IETF" NAT status  
       
  1271 	if ( NatStatus == 0 )
       
  1272 	{	
       
  1273 	   if ( iNAT_T_Required )
       
  1274 			NatStatus = 4;           // Local end is NAT:ted (discovered via "Nokia" NAT-T)    
       
  1275 	   else if ( !iHostData->iUseNatProbing )
       
  1276 		       NatStatus = iHostData->iEspUdpPort; // "Forced" ESP UDP encapsulation ?
       
  1277 	}
       
  1278 
       
  1279 	TInetAddr localAddr;
       
  1280 	iPluginSession->GetLocalAddress( localAddr );
       
  1281     LOG_KMD_EVENT2( MKmdEventLoggerIf::KLogInfo,
       
  1282                     R_VPN_MSG_ADDR_INFO_FOR_VPN_AP,
       
  1283                     NatStatus, iPluginSession->VpnIapId(),
       
  1284                     (iInternalAddr ? &iInternalAddr->iClientIntAddr : NULL),
       
  1285                     &localAddr );	
       
  1286 
       
  1287     return Status;
       
  1288 }   
       
  1289 
       
  1290 
       
  1291 //Sends the initial IKE packets to start the negotiation. PHASE I
       
  1292 void CIkev1Negotiation::InitNegotiationL()   //Equiv. to stage 1
       
  1293 {
       
  1294     TIkev1IsakmpStream* msg = SaveIkeMsgBfr( new (ELeave) TIkev1IsakmpStream(iDebug) );
       
  1295 	
       
  1296     TInt  vendor_id_type;
       
  1297 
       
  1298     //Main mode stage 1
       
  1299 
       
  1300     switch (iHostData->iMode)
       
  1301     {
       
  1302         case IKE_PARSER_MAIN:
       
  1303             iExchange = ISAKMP_EXCHANGE_ID;     // Identity Protection (Main mode in IKE)
       
  1304             DEBUG_LOG(_L("IKE: Initiating negotiation (Main Mode)"));
       
  1305             break;
       
  1306         case IKE_PARSER_AGGRESSIVE:
       
  1307             iExchange = ISAKMP_EXCHANGE_AGGR;   // Agressive
       
  1308             DEBUG_LOG(_L("IKE: Initiating negotiation (Aggressive Mode)"));
       
  1309             break;
       
  1310         default:
       
  1311             DEBUG_LOG1(_L("Bad Mode used (%d)"), iHostData->iMode);
       
  1312             return;
       
  1313     }
       
  1314     iStage = 1;
       
  1315     DEBUG_LOG2(_L("---------- Phase %d - Stage %d ----------"),iPhase, iStage);
       
  1316 
       
  1317     iCookie_R.FillZ(ISAKMP_COOKIE_SIZE);  //Set responder Cookie to 0
       
  1318 
       
  1319     iDOI = IPSEC_DOI;
       
  1320     iEncoding = X509_CERT_SIG;  //Only cert Allowed
       
  1321     msg->IsakmpInit(this);
       
  1322     msg->IsakmpSa();
       
  1323 
       
  1324     const TUint8 *ptr = msg->iBuf.Ptr() + sizeof(ThdrISAKMP);
       
  1325     const TSAISAKMP *sa = (TSAISAKMP*)ptr;
       
  1326     //Generic payload NOT included
       
  1327     iSAPayloadSize = sa->GetLength() - sizeof(TPayloadISAKMP);
       
  1328     delete iSAPayload;
       
  1329 	iSAPayload = NULL;
       
  1330     iSAPayload = new (ELeave) TUint8[iSAPayloadSize];   
       
  1331     ptr += sizeof(TPayloadISAKMP);  
       
  1332     Mem::Copy(iSAPayload, ptr,iSAPayloadSize);
       
  1333 
       
  1334     TBool cert_required = EFalse;   //If any proposal requires a cert to send a CR if needed
       
  1335     TBool preshared_key = EFalse;   //Preshared key authentication        
       
  1336     TBool crack_used = EFalse;
       
  1337     
       
  1338     TAttrib *transf = iProposal_I.iAttrList;
       
  1339     for (TInt i=0; (i < iProposal_I.iNumTransforms) && (!cert_required); i++)
       
  1340     {
       
  1341         switch (transf->iAuthMethod)
       
  1342         {
       
  1343         case RSA_SIG:   //Proposals involving certificates
       
  1344         case DSS_SIG:
       
  1345             cert_required = ETrue;
       
  1346             break;
       
  1347         case IKE_A_CRACK:           
       
  1348             cert_required = ETrue;
       
  1349             crack_used = ETrue;
       
  1350             break;
       
  1351         default:    // No cert involved
       
  1352             preshared_key = ETrue;
       
  1353             transf = transf->iNext;
       
  1354         }
       
  1355     }
       
  1356     
       
  1357     if (crack_used &&
       
  1358         !iHostData->iCRACKLAMUserName && 
       
  1359         !iHostData->iCRACKLAMPassword)
       
  1360         {
       
  1361         TBuf<256> UserName;
       
  1362         TBuf<64> Password;
       
  1363         CIkev1Dialog* Dialog = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug);                     
       
  1364         if (KErrNone != Dialog->GetSyncUNPWCacheDialog(UserName, Password))
       
  1365             {
       
  1366             DEBUG_LOG(_L("Failed to get credentials for crack auth!"));
       
  1367             SetFinished();
       
  1368             delete Dialog;
       
  1369             return;
       
  1370             }
       
  1371         iHostData->iCRACKLAMUserName = TStringData::NewL(UserName);
       
  1372         iHostData->iCRACKLAMPassword = TStringData::NewL(Password);
       
  1373         delete Dialog;
       
  1374     }
       
  1375 
       
  1376     if (iExchange == ISAKMP_EXCHANGE_AGGR) //Aggressive contains more payloads
       
  1377     {
       
  1378         if ( preshared_key && !cert_required ) {
       
  1379            //
       
  1380            // Only pre-shared key authentication proposal(s) exists
       
  1381            // Check if is necessary to ask user name/password (= IKE ID/preshared key)
       
  1382            // from user
       
  1383            //
       
  1384            if ( CheckCredentials(iHostData) != KErrNone ) {
       
  1385               DEBUG_LOG(_L("Failed to get credentials for Aggressive pre-shared auth!"));
       
  1386               SetFinished();
       
  1387               return;
       
  1388            }
       
  1389         }   
       
  1390         ComputeNonceL();         //Nonce to be sent
       
  1391         if ( cert_required && !iOwnCert ) 
       
  1392            ReadOwnCertL();    // For possible DER ASN1 distuingish name Ident
       
  1393         msg->IsakmpKeyL();
       
  1394         msg->IsakmpNonce();
       
  1395         msg->IsakmpOwnIdentL();
       
  1396 		
       
  1397         //For aggressive mode we send a CR if a cert is going to be needed
       
  1398         if ((!iPeerX509Cert) && (cert_required))
       
  1399         {
       
  1400            msg->IsakmpCertificateReqL();   
       
  1401         }
       
  1402         if ( iHostData->iUseNatProbing )
       
  1403              vendor_id_type = EXPANDED_VENDOR_ID;
       
  1404         else vendor_id_type = HASH_VENDOR_ID;           
       
  1405         msg->IsakmpVendorId(vendor_id_type,
       
  1406                             (TUint8*)iCookie_I.Ptr(),
       
  1407                             (TUint8*)iCookie_R.Ptr(), iLocalAddr);
       
  1408             
       
  1409     }
       
  1410 	
       
  1411 	if ( iHostData->iDPDHeartBeat != 0 )
       
  1412 	   BuildDPDVendorId(*msg);
       
  1413 	
       
  1414     if ( iNatDiscovery ) {
       
  1415        iNatDiscovery->BuildNatVendorId(*msg);
       
  1416        iNatDiscovery->BuildRfcNatVendorId(*msg);
       
  1417     }
       
  1418 	
       
  1419     if ( iHostData->iUseXauth || iHostData->iUseCfgMode ) {  
       
  1420        CTransNegotiation::BuildXauthVendorId(*msg);  
       
  1421     }
       
  1422 
       
  1423     SendL(*msg);
       
  1424     iStage = 2;
       
  1425 }
       
  1426 
       
  1427 //Builds the proposal list from the structure in the engine
       
  1428 TBool CIkev1Negotiation::BuildProposals1L()
       
  1429 {
       
  1430     TProposalData *p_list = iHostData->iPropList;
       
  1431 
       
  1432     if (!p_list)
       
  1433     {
       
  1434         DEBUG_LOG(_L("ERROR: No proposals in the configuration file. Negotiation Cancelled"));
       
  1435         return EFalse;
       
  1436     }
       
  1437     iProposal_I.iSPI.FillZ(4);  //filled with 0 (not send anyway)
       
  1438     iProposal_I.iProposalNum   = FIRST_ISAKMP_PROPOSAL; 
       
  1439     iProposal_I.iProtocol      = PROTO_ISAKMP;
       
  1440     iProposal_I.iNumTransforms = 0;
       
  1441     
       
  1442     TUint8 trans_num = FIRST_ISAKMP_TRANSFORM;
       
  1443 
       
  1444     TAttrib *prev=NULL,*attrlist=NULL;
       
  1445     
       
  1446     while ( p_list )
       
  1447     {
       
  1448         iProposal_I.iNumTransforms ++;
       
  1449         attrlist = new (ELeave) TAttrib;
       
  1450         if (!iProposal_I.iAttrList) //First transform
       
  1451             iProposal_I.iAttrList=attrlist; //attrlist safe
       
  1452         if (prev)
       
  1453             prev->iNext = attrlist;
       
  1454         prev = attrlist;
       
  1455         
       
  1456         attrlist->iTransformID  = KEY_IKE; //only one allowed by Protocol ISAKMP (KEY_IKE)
       
  1457         attrlist->iTransformNum = trans_num;
       
  1458         trans_num++;        
       
  1459         switch (p_list->iEncrAlg)
       
  1460         {
       
  1461         case IKE_PARSER_DES_CBC:
       
  1462             attrlist->iEncrAlg=DES_CBC;     //DES_CBC
       
  1463             break;
       
  1464         case IKE_PARSER_DES3_CBC:
       
  1465             attrlist->iEncrAlg=DES3_CBC;    //DES3_CBC
       
  1466             break;
       
  1467         case IKE_PARSER_AES_CBC:
       
  1468             attrlist->iEncrAlg   = AES_CBC;     //AES_CBC
       
  1469             attrlist->iKeyLength = (TUint16)p_list->iEncrKeyLth;
       
  1470             if (!attrlist->iKeyLength)
       
  1471                attrlist->iKeyLength = 128; //default AES key size   
       
  1472             break;
       
  1473         default:
       
  1474             DEBUG_LOG(_L("ISAKMP Proposals error (Bad Encryption algorithm)"));
       
  1475             return EFalse;
       
  1476         }
       
  1477         switch (p_list->iHashAlg)
       
  1478         {
       
  1479         case IKE_PARSER_MD5:
       
  1480             attrlist->iHashAlg=HASH_MD5;    //HASH_MD5
       
  1481             break;
       
  1482         case IKE_PARSER_SHA1:
       
  1483             attrlist->iHashAlg=HASH_SHA1;   //HASH_SHA1
       
  1484             break;
       
  1485         default:
       
  1486             DEBUG_LOG(_L("ISAKMP Proposals error (Bad Hash algorithm)"));
       
  1487             return EFalse;
       
  1488         }
       
  1489         switch (p_list->iAuthMeth)
       
  1490         {
       
  1491         case IKE_PARSER_RSA_SIG:
       
  1492             attrlist->iAuthMethod=RSA_SIG;
       
  1493             break;
       
  1494         case IKE_PARSER_DSS_SIG:
       
  1495             attrlist->iAuthMethod=DSS_SIG;
       
  1496             break;
       
  1497         case IKE_PARSER_PRE_SHARED:
       
  1498             attrlist->iAuthMethod=PRE_SHARED;           
       
  1499             break;
       
  1500         case IKE_PARSER_CRACK:
       
  1501             attrlist->iAuthMethod=IKE_A_CRACK; //CRACK authentication
       
  1502             break;
       
  1503             
       
  1504         default:
       
  1505             DEBUG_LOG(_L("ISAKMP Proposals error (Bad Authentication Method)"));
       
  1506             return EFalse;
       
  1507         }
       
  1508         
       
  1509         switch (p_list->iGroupDesc)
       
  1510         {
       
  1511         case IKE_PARSER_MODP_768:
       
  1512             attrlist->iGroupDesc = MODP_768;
       
  1513             break;
       
  1514         case IKE_PARSER_MODP_1024:
       
  1515             attrlist->iGroupDesc = MODP_1024;
       
  1516             break;
       
  1517         case IKE_PARSER_MODP_1536:
       
  1518             attrlist->iGroupDesc = MODP_1536;
       
  1519             break;
       
  1520         case IKE_PARSER_MODP_2048:
       
  1521             attrlist->iGroupDesc = MODP_2048;
       
  1522             break;
       
  1523         default:
       
  1524             DEBUG_LOG(_L("ISAKMP Proposals error (Bad Group description)"));
       
  1525             return EFalse;      
       
  1526         }
       
  1527 
       
  1528         switch (p_list->iGroupType)
       
  1529         {
       
  1530         case IKE_PARSER_MODP:
       
  1531             attrlist->iGroupType = MODP;
       
  1532             break;
       
  1533         case IKE_PARSER_DEFAULT:
       
  1534             break;
       
  1535         default:
       
  1536             DEBUG_LOG(_L("ISAKMP Proposals error (Bad Group Type)"));
       
  1537             return EFalse;
       
  1538         }
       
  1539 
       
  1540         switch (p_list->iPRF)
       
  1541         {
       
  1542         case IKE_PARSER_DES3_CBC_MAC:
       
  1543             attrlist->iPRF=OAKLEY_PRF_3DES_CBC_MAC;
       
  1544             break;
       
  1545         case IKE_PARSER_NONE:
       
  1546             break;
       
  1547         default:
       
  1548             DEBUG_LOG(_L("ISAKMP Proposals error (Bad PRF specified)"));
       
  1549             return EFalse;
       
  1550         }
       
  1551 
       
  1552         TUint32 lifetime = ByteOrder::Swap32(p_list->iLifetimeSec);
       
  1553         if (lifetime)
       
  1554             attrlist->iLifeDurationSecs.Copy((TUint8 *)&lifetime, sizeof(lifetime));
       
  1555 
       
  1556         lifetime = ByteOrder::Swap32(p_list->iLifetimeKb);
       
  1557         if (lifetime)
       
  1558             attrlist->iLifeDurationKBytes.Copy((TUint8 *)&lifetime, sizeof(lifetime));
       
  1559 
       
  1560         //
       
  1561         // Store parameters for extended authentication
       
  1562         //
       
  1563         attrlist->iXauthUsed = iHostData->iUseXauth;
       
  1564         attrlist->iRole      = iRole;
       
  1565         
       
  1566         p_list = p_list->iNext;
       
  1567         
       
  1568     }
       
  1569     attrlist->iNext=NULL;   //Last transform
       
  1570 
       
  1571 
       
  1572     return ETrue;
       
  1573 }
       
  1574 
       
  1575 //Builds Phase_II proposals from the config. file to when acting as RESPONDER to see if 
       
  1576 //proposals received are acceptable.
       
  1577 TInt CIkev1Negotiation::BuildProposals2L()
       
  1578 {
       
  1579     CIpsecSaSpecList* SaList = NULL;
       
  1580     TInetAddr empty_addr;  //empty address
       
  1581     TInt err = KErrNone;
       
  1582     
       
  1583     TRAP(err,
       
  1584         if ( iLocalIDType_II == 0 )  //Local ID not received (so remote neither) so it's the same as gateway
       
  1585             {
       
  1586             TInetAddr localSelector(iLocalAddr);
       
  1587             localSelector.SetPort(iIDLocalPort);
       
  1588             TInetAddr remoteSelector(iRemoteAddr);
       
  1589             remoteSelector.SetPort(iIDRemotePort);
       
  1590             
       
  1591             SaList = iPluginSession->GetIpseSaSpecListLC(localSelector, empty_addr, 
       
  1592                                                          remoteSelector, empty_addr,
       
  1593                                                          iIDProtocol );
       
  1594             }
       
  1595         else    // either none or both (RFC 2409 5.5 so we must have both)
       
  1596             {
       
  1597             TInetAddr localSelector(iLocalAddr1_ID_II);
       
  1598             localSelector.SetPort(iIDLocalPort);
       
  1599             TInetAddr remoteSelector(iRemoteAddr1_ID_II);
       
  1600             remoteSelector.SetPort(iIDRemotePort);
       
  1601     
       
  1602             
       
  1603             SaList = iPluginSession->GetIpseSaSpecListLC(localSelector,
       
  1604                                                          iLocalAddr2_ID_II,
       
  1605                                                          remoteSelector,
       
  1606                                                          iRemoteAddr2_ID_II,
       
  1607                                                          iIDProtocol );
       
  1608             }
       
  1609         
       
  1610         CleanupStack::Pop(SaList);
       
  1611     );
       
  1612     
       
  1613     if (err != KErrNone)
       
  1614         return err;
       
  1615     
       
  1616     CleanupStack::PushL(SaList);
       
  1617 
       
  1618     //Phase II proposals
       
  1619 
       
  1620     CProposal_II *prop = NULL;
       
  1621     TAttrib_II *attr_II = NULL;
       
  1622     const TIpsecSaSpec *spec = NULL;
       
  1623     TInt count = SaList->Count();
       
  1624     TInt i     = 0;
       
  1625 
       
  1626     while ( i < count ) 
       
  1627     {
       
  1628         prop = new (ELeave) CProposal_II();
       
  1629         CleanupStack::PushL(prop);
       
  1630         prop->ConstructL(1);
       
  1631         iProposal_IIList->AppendL(prop);
       
  1632         CleanupStack::Pop();    //prop safe
       
  1633         //
       
  1634         // Only 1 proposal which may be AND'd (many prop with same num) if many bundles
       
  1635         // Only 1 transform because no OR'ing implemented in IPSEC
       
  1636         //
       
  1637         prop->iProposalNum   = FIRST_IPSEC_PROPOSAL;
       
  1638         prop->iNumTransforms = 1;  
       
  1639 
       
  1640         attr_II = new (ELeave) TAttrib_II();
       
  1641         CleanupStack::PushL(attr_II);
       
  1642         prop->iAttrList->AppendL(attr_II);
       
  1643         CleanupStack::Pop();    //attr_II safe
       
  1644         
       
  1645         attr_II->iTransformNum = FIRST_IPSEC_TRANSFORM;     
       
  1646 
       
  1647         spec = &(SaList->At(i));
       
  1648         
       
  1649         if (spec->iType == SADB_SATYPE_AH)
       
  1650         {
       
  1651             prop->iProtocol=PROTO_IPSEC_AH;
       
  1652             if (spec->iAalg == SADB_AALG_MD5HMAC)
       
  1653             {
       
  1654                 attr_II->iTransformID = AH_MD5;
       
  1655                 attr_II->iAuthAlg = DOI_HMAC_MD5;
       
  1656             }
       
  1657             else if (spec->iAalg == SADB_AALG_SHA1HMAC)
       
  1658             {
       
  1659                 attr_II->iTransformID=AH_SHA;
       
  1660                 attr_II->iAuthAlg = DOI_HMAC_SHA;
       
  1661             }
       
  1662             else
       
  1663             {
       
  1664                 DEBUG_LOG(_L("Unsupported Authentication Algorithm in IPsec Policy"));
       
  1665                 err = KKmdIkeNoProposalErr;
       
  1666                 break;
       
  1667             }
       
  1668             // No auth with variable encryption
       
  1669         }
       
  1670         else if (spec->iType == SADB_SATYPE_ESP)
       
  1671         {
       
  1672             prop->iProtocol = PROTO_IPSEC_ESP;
       
  1673             // Request ESP from peer host
       
  1674 
       
  1675             attr_II->iTransformID = spec->iEalg;
       
  1676 			switch ( attr_II->iTransformID )
       
  1677 			{
       
  1678 				case ESP_DES_CBC:
       
  1679 				case ESP_3DES_CBC:
       
  1680 				case ESP_NULL:
       
  1681 					break;
       
  1682 
       
  1683 				case ESP_AES_CBC:
       
  1684 					attr_II->iKeyLength = spec->iEalgLen;   //If 0 it won't be sent
       
  1685 					break;
       
  1686 
       
  1687 				default:
       
  1688 					DEBUG_LOG(_L("IPsec Encryption algorithm is not implemented. Wrong algorithms file"));
       
  1689 	                err = KKmdIkeNoProposalErr;
       
  1690 	                break;
       
  1691 			}	
       
  1692 			
       
  1693 			if (err != KErrNone)
       
  1694 			    {
       
  1695 			    break;
       
  1696 			    }
       
  1697 			
       
  1698             if (spec->iAalg != SADB_AALG_NONE)
       
  1699             {
       
  1700                 if (spec->iAalg == SADB_AALG_MD5HMAC)
       
  1701                     attr_II->iAuthAlg = DOI_HMAC_MD5;
       
  1702                 else if (spec->iAalg == SADB_AALG_SHA1HMAC)
       
  1703                     attr_II->iAuthAlg = DOI_HMAC_SHA;
       
  1704                 else
       
  1705                 {
       
  1706                     DEBUG_LOG(_L("Unsupported Authentication Algorithm in IPsec Policy"));
       
  1707                     err = KKmdIkeNoProposalErr;
       
  1708                     break;
       
  1709                 }
       
  1710             }
       
  1711         }
       
  1712 
       
  1713         //Check if PFS in use...
       
  1714         iPFS = spec->iPfs;
       
  1715 
       
  1716         if (spec->iTransportMode)
       
  1717              attr_II->iEncMode = DOI_TRANSPORT;
       
  1718         else attr_II->iEncMode = DOI_TUNNEL;
       
  1719 
       
  1720         //////////////////////////////////////////////////////////
       
  1721         //
       
  1722         // Check if remote identity defined in Security Policy
       
  1723         // If it is not set iDefaultLocalID = ETrue.
       
  1724         // This prevents destination identity information to IPSEC
       
  1725         // in PFKEY Update- and Add primitives
       
  1726         // (see UpdateSADatabaseL() method)
       
  1727         //
       
  1728         //////////////////////////////////////////////////////////
       
  1729         if ( spec->iRemoteIdentity.Length() == 0 )
       
  1730            iDefaultLocalID = ETrue;
       
  1731 		if ( !ExamineRemoteIdentity(spec->iRemoteIdentity) )
       
  1732 		{
       
  1733 			DEBUG_LOG(_L("Remote Identity mismatch with IPsec Policy"));
       
  1734             err = KKmdIkeNoProposalErr;
       
  1735             break;
       
  1736 		}
       
  1737 		
       
  1738         //Only Hard Lifetimes taken into account
       
  1739         TInt64 lifetime64 = spec->iHard.iAddTime;
       
  1740         TUint high = 0;
       
  1741         TUint low = 0;
       
  1742         if (lifetime64!=0)
       
  1743         {
       
  1744             high = ByteOrder::Swap32(I64HIGH(lifetime64));          
       
  1745             if (high > 0)
       
  1746                 attr_II->iLifeDurationSecs.Copy((TUint8 *)&high, sizeof(high));
       
  1747             low = ByteOrder::Swap32(I64LOW(lifetime64));                        
       
  1748             attr_II->iLifeDurationSecs.Append((TUint8 *)&low, sizeof(low));
       
  1749         }
       
  1750 
       
  1751         //Bytes lifetime
       
  1752         lifetime64 = spec->iHard.iBytes;
       
  1753         lifetime64 = (lifetime64/1024); //Bytes to KB
       
  1754         if (lifetime64 != 0)
       
  1755         {
       
  1756             high = ByteOrder::Swap32(I64HIGH(lifetime64));                      
       
  1757             if (high > 0)
       
  1758                 attr_II->iLifeDurationKBytes.Copy((TUint8 *)&high, sizeof(high));
       
  1759             low = ByteOrder::Swap32(I64LOW(lifetime64));                                    
       
  1760             attr_II->iLifeDurationKBytes.Append((TUint8 *)&low, sizeof(low));
       
  1761         }
       
  1762         if (iPFS)
       
  1763         {
       
  1764             switch (iHostData->iGroupDesc_II)
       
  1765             {
       
  1766             case IKE_PARSER_MODP_768:
       
  1767                 attr_II->iGroupDesc = MODP_768;
       
  1768                 break;
       
  1769             case IKE_PARSER_MODP_1024:
       
  1770                 attr_II->iGroupDesc = MODP_1024;
       
  1771                 break;
       
  1772             case IKE_PARSER_MODP_1536:
       
  1773                 attr_II->iGroupDesc = MODP_1536;
       
  1774                 break;
       
  1775             case IKE_PARSER_MODP_2048:
       
  1776                 attr_II->iGroupDesc = MODP_2048;
       
  1777                 break;
       
  1778             default:    //Shouldn't happen but the error will be detected later
       
  1779                 err = KKmdIkeNoProposalErr;
       
  1780                 break;
       
  1781             }
       
  1782             
       
  1783             if (err != KErrNone)
       
  1784                 {
       
  1785                 break;
       
  1786                 }            
       
  1787         }
       
  1788         
       
  1789         prop->iReplayWindowLength = spec->iReplayWindowLength;
       
  1790 
       
  1791         i ++;
       
  1792     }   //while
       
  1793 
       
  1794     if (err != KErrNone)
       
  1795         {
       
  1796         delete iProposal_IIList;
       
  1797         iProposal_IIList = NULL;        
       
  1798         }
       
  1799     
       
  1800     CleanupStack::PopAndDestroy(SaList);  //SAList
       
  1801     
       
  1802     return err;
       
  1803 }
       
  1804 
       
  1805 TBool CIkev1Negotiation::ExamineRemoteIdentity(const TDesC8& aRemoteIdInPolicy)
       
  1806 {
       
  1807    //////////////////////////////////////////////////////////////////
       
  1808    //
       
  1809    // This method is called when we are acting as a Quick mode responder.   
       
  1810    // The purpose of this method is compare remote Identity information
       
  1811    // received in Quick Mode IKE message (=IDi) to the remote Identity
       
  1812    // information in the local Ipsec Policy.
       
  1813    // If Identitiea are NOT matching the FALSE response is returned.
       
  1814    // There is the following special "kludge" is done in these test:
       
  1815    // Identity IPv4 address and IPv4 subnet with prefix 32 are
       
  1816    // interpreted to be same as well as IPv6 address and IPv6 subnet
       
  1817    // with prefix 128. When this situation occurs a special flag 
       
  1818    // (iSwapRemoteIdType = ETrue) is set in CIkev1Negotiation object
       
  1819    //
       
  1820    //////////////////////////////////////////////////////////////////
       
  1821    TBool      AddrMatch;   
       
  1822    TInetAddr  IpAddr;
       
  1823    TInetAddr  IpMask;
       
  1824    TUint8     IdType;
       
  1825    TInt       PrefixLength = 0;
       
  1826    TInetAddr* PrefixPtr    = NULL;      
       
  1827    
       
  1828    if ( !ProcessIdentityData(aRemoteIdInPolicy, &IdType, &IpAddr, &IpMask) )
       
  1829 	  return EFalse;
       
  1830    
       
  1831    AddrMatch = IpAddr.Match(iRemoteAddr1_ID_II);
       
  1832 
       
  1833    if ( AddrMatch )
       
  1834    {	   
       
  1835       if ( (IdType == ID_IPV4_ADDR_SUBNET ) || (IdType == ID_IPV6_ADDR_SUBNET) ) 
       
  1836       {
       
  1837 		 // 
       
  1838 		 // Identity in policy is IP subnet
       
  1839 		 //
       
  1840 	     if ( iRemoteIDType_II == IdType )
       
  1841 		 {
       
  1842 		    // 
       
  1843 		    // Both identity in policy and identity in IKE IDi payload are
       
  1844 		    // IP subnets. The subnet masks MUST match, too
       
  1845 		    //
       
  1846 			AddrMatch = IpMask.Match(iRemoteAddr2_ID_II);
       
  1847 		 }
       
  1848 		 else
       
  1849 		 {
       
  1850 			 if ( ( (IdType == ID_IPV4_ADDR_SUBNET ) && (iRemoteIDType_II == ID_IPV4_ADDR)) ||
       
  1851 			      ( (IdType == ID_IPV6_ADDR_SUBNET ) && (iRemoteIDType_II == ID_IPV6_ADDR)))
       
  1852 			 {	 
       
  1853 			    // 
       
  1854 			    // Identity in IKE IDi payload is an IP address
       
  1855 			    // Do the special check: There must be full mask in the
       
  1856 			    // subnet identity configured in policy
       
  1857 			    //
       
  1858 				if ( IdType == ID_IPV6_ADDR_SUBNET )
       
  1859 					 PrefixLength = 128;
       
  1860 				else PrefixLength = 32;
       
  1861 				PrefixPtr = &IpMask;
       
  1862 				DEBUG_LOG(_L("Peer is using IP address IDi, full mask subnet required in local end!"));
       
  1863 			 }
       
  1864 			 else AddrMatch = EFalse;  
       
  1865 		 }	 
       
  1866       }	   
       
  1867       else
       
  1868       {
       
  1869 	     // 
       
  1870 	     // Identity in policy is IP address.
       
  1871 	     //
       
  1872 		 if ( ( (IdType == ID_IPV4_ADDR ) && (iRemoteIDType_II == ID_IPV4_ADDR_SUBNET)) ||
       
  1873 			  ( (IdType == ID_IPV6_ADDR ) && (iRemoteIDType_II == ID_IPV6_ADDR_SUBNET)))
       
  1874 		 {	 
       
  1875 				// 
       
  1876 				// Identity in IKE IDi payload is an IP subnet
       
  1877 				// Do the special check: There must be full mask in the
       
  1878 				// subnet identity in IKE IDi payload
       
  1879 				//
       
  1880 			 if ( IdType == ID_IPV6_ADDR )
       
  1881 			      PrefixLength = 128;
       
  1882 			 else PrefixLength = 32;
       
  1883 			 PrefixPtr = &iRemoteAddr2_ID_II;
       
  1884 			 DEBUG_LOG(_L("An IP address ID used in local end, full mask subnet required in peer IDi!"));
       
  1885 		 }
       
  1886 		 else if ( iRemoteIDType_II != IdType )
       
  1887 				 AddrMatch = EFalse;
       
  1888 		 
       
  1889       }
       
  1890    }
       
  1891 
       
  1892    if ( PrefixPtr )
       
  1893    {	   	   
       
  1894 	  if ( PrefixLength == PrefixLen(*PrefixPtr) )
       
  1895 	  {	  
       
  1896 	  	 iSwapRemoteIdType = ETrue;
       
  1897 		 DEBUG_LOG(_L("Required ID OK, modified remote IDi informed to IPsec!"));		 
       
  1898 	  }	 
       
  1899 	  else AddrMatch = EFalse;
       
  1900    }
       
  1901    
       
  1902    return AddrMatch;
       
  1903 }
       
  1904 
       
  1905 TBool CIkev1Negotiation::ProcessIdentityData(const TDesC8& aIdentity, TUint8* aToIdType,
       
  1906 										TInetAddr* aToIpAddr1, TInetAddr* aToIpAddr2)
       
  1907 {
       
  1908    if ( !aToIdType || !aToIpAddr1 || !aToIpAddr2 )
       
  1909 	  return EFalse;
       
  1910    
       
  1911    aToIpAddr1->Init(KAFUnspec);
       
  1912    aToIpAddr2->Init(KAFUnspec);
       
  1913    *aToIdType = 0;
       
  1914 		   
       
  1915    if ( aIdentity.Length() )
       
  1916    {	   
       
  1917       TInt offset = aIdentity.Find(_L8("/"));
       
  1918    
       
  1919       switch (offset)
       
  1920       {
       
  1921 	     case KErrNotFound:  //Simple address
       
  1922          { 
       
  1923 #ifdef _UNICODE
       
  1924 		    HBufC *unibuf = HBufC::New(aIdentity.Length());
       
  1925 			if ( !unibuf )
       
  1926 			    return EFalse;	
       
  1927 	        unibuf->Des().Copy(aIdentity);
       
  1928 	    	if ( aToIpAddr1->Input(unibuf->Des()) != KErrNone )
       
  1929 	    	{
       
  1930 				delete unibuf;
       
  1931 		    	DEBUG_LOG(_L("Bad IP address identity!"));
       
  1932 				return EFalse;
       
  1933 	    	}  
       
  1934 		    delete unibuf;
       
  1935 #else
       
  1936 		    if (aToIpAddr1->Input(aIdentity) != KErrNone)
       
  1937 		    {
       
  1938 				DEBUG_LOG(_L("Bad IP address identity!"));
       
  1939 				return EFalse;
       
  1940 		    }
       
  1941 #endif  
       
  1942 		    if ( aToIpAddr1->Family() == KAfInet )
       
  1943 			     *aToIdType = ID_IPV4_ADDR;
       
  1944 		    else *aToIdType = ID_IPV6_ADDR;
       
  1945 		    break;
       
  1946      	 }
       
  1947 		 
       
  1948 	     default:    //Subnet
       
  1949 	     {
       
  1950 				//addr1 - subnet
       
  1951 		 TInt prefix_len;	 
       
  1952 #ifdef _UNICODE
       
  1953 		    HBufC *unibuf = HBufC::New(aIdentity.Length());
       
  1954 			if ( !unibuf )
       
  1955 				return EFalse;
       
  1956 			unibuf->Des().Copy(aIdentity);			
       
  1957 		    TPtrC addr_buf(unibuf->Ptr(), offset);
       
  1958 		    if (aToIpAddr1->Input(addr_buf) != KErrNone)
       
  1959 		    {
       
  1960 				delete unibuf;				
       
  1961 			    DEBUG_LOG(_L("Bad Subnet Identity address!"));
       
  1962 				return EFalse;
       
  1963 		    }
       
  1964 		    TPtrC prefix_ptr(unibuf->Ptr() + offset + 1, unibuf->Length() - offset - 1);
       
  1965 #else
       
  1966 		    TPtrC addr_buf(aIdentity.Ptr(), offset);
       
  1967 			if (aToIpAddr1->.Input(addr_buf) != KErrNone)
       
  1968 			{
       
  1969 				DEB(LogError(_L("Bad Subnet Identity address!"));)
       
  1970 				return EFalse;
       
  1971 			}
       
  1972 		    TPtrC prefix_ptr(aIdentity.Ptr() + offset + 1, aIdentity.Length() - offset - 1);
       
  1973 #endif  
       
  1974 				//addr2 - mask
       
  1975 		    TLex lex(prefix_ptr);
       
  1976 		    if (lex.Val(prefix_len) != KErrNone)
       
  1977 		    {
       
  1978 			   DEBUG_LOG(_L("Bad Subnet Identity PREFIX Length!"));
       
  1979 			   return EFalse;
       
  1980 		    }
       
  1981 #ifdef _UNICODE
       
  1982 		    delete unibuf;
       
  1983 #endif
       
  1984 			if ( aToIpAddr1->Family() == KAfInet )
       
  1985 			{
       
  1986 			   if ( prefix_len > 32 )	
       
  1987 			   {
       
  1988 				  DEBUG_LOG(_L("Bad Subnet Identity: Prefix too long!"));
       
  1989 				  return EFalse;
       
  1990 			   }
       
  1991 			   *aToIdType = ID_IPV4_ADDR_SUBNET;
       
  1992 			   PrefixMask(*aToIpAddr2, prefix_len, KAfInet);
       
  1993 			}
       
  1994 			else    //KAfInet6
       
  1995 			{
       
  1996 				if ( prefix_len > 128 )	
       
  1997 				{
       
  1998 					DEBUG_LOG(_L("Bad Subnet Identity: Prefix too long!"));
       
  1999 					return EFalse;
       
  2000 				}
       
  2001 				*aToIdType = ID_IPV6_ADDR_SUBNET;
       
  2002 				PrefixMask(*aToIpAddr2, prefix_len, KAfInet);
       
  2003 			}
       
  2004 
       
  2005 		 }
       
  2006 		 
       
  2007 	  } //end switch
       
  2008    }	  
       
  2009 
       
  2010    return ETrue;
       
  2011 }
       
  2012 
       
  2013 //First msg of PHASE_II as initiator
       
  2014 void CIkev1Negotiation::InitPhase2L()
       
  2015 {
       
  2016     //Quick mode stage 1
       
  2017     DEBUG_LOG(_L("-------- IKE: Initiating PHASE II --------"));
       
  2018     iPhase = PHASE_II;
       
  2019     iDOI=IPSEC_DOI;
       
  2020     iStage = 1;
       
  2021 
       
  2022     GetSPIL();
       
  2023     //the rest will be done in ReceiveSPI
       
  2024 }
       
  2025 
       
  2026 //Requests an SPI from the kernel
       
  2027 
       
  2028 void CIkev1Negotiation::GetSPIL()
       
  2029 {
       
  2030     CProposal_IIList *propII_List;
       
  2031     CProposal_II *prop=NULL;
       
  2032     TUint8 sa_type = 0;
       
  2033 
       
  2034     DEBUG_LOG1(_L("GetSPI in stage: %d"), iStage);
       
  2035 
       
  2036     iInboundSPIList = new (ELeave) CArrayFixFlat<TSPINode>(1);
       
  2037 
       
  2038     if (iRole == RESPONDER) //If Phase II proposal Chosen
       
  2039         propII_List = iChosenProp_IIList;   //If RESPONDER
       
  2040     else
       
  2041         propII_List = iProposal_IIList; //If INITIATOR
       
  2042 
       
  2043     TInt i, count = propII_List->Count();
       
  2044     for (i = 0; i < count; i++) //May have many Phase_II proposals
       
  2045     {
       
  2046         prop = propII_List->At(i);
       
  2047         if (prop->iProtocol == PROTO_IPSEC_AH)
       
  2048             sa_type = SADB_SATYPE_AH;
       
  2049         else if (prop->iProtocol == PROTO_IPSEC_ESP)
       
  2050             sa_type = SADB_SATYPE_ESP;
       
  2051         else
       
  2052             sa_type = 0;    //Unknown Protocol
       
  2053 
       
  2054         TInetAddr myAddr(iLocalAddr);
       
  2055 		if ( myAddr.IsUnspecified() )
       
  2056 		    User::LeaveIfError( iPluginSession->GetLocalAddress( myAddr ) );
       
  2057         TInetAddr peerAddr(iRemoteAddr);
       
  2058         peerAddr.SetPort(0);
       
  2059         TSPINode node;
       
  2060         node.iPropNum = prop->iProposalNum;
       
  2061         node.iSeq = iSeq;
       
  2062         iInboundSPIList->AppendL(node);
       
  2063         
       
  2064         
       
  2065         __ASSERT_DEBUG( iIpsecSaSpiRetriever != NULL,
       
  2066                         User::Invariant() );
       
  2067         iIpsecSaSpiRetriever->Cancel();
       
  2068         iIpsecSaSpiRetriever->GetIpsecSaSpi( iSeq++, sa_type, peerAddr, myAddr );        
       
  2069         iPendingSPI++;      //To know when all received in ReceiveSPIL()
       
  2070     }
       
  2071 
       
  2072     DEBUG_LOG1(_L("GetSPI seq= %d"), iSeq);
       
  2073 }
       
  2074 
       
  2075 //aSPI received in Network order.
       
  2076 void CIkev1Negotiation::ReceiveSPIL(TUint32 aSPI, TUint32 aSeq)
       
  2077 {
       
  2078 	TIkev1IsakmpStream* msg = SaveIkeMsgBfr( new (ELeave) TIkev1IsakmpStream(iDebug) );
       
  2079 	
       
  2080     DEBUG_LOG2(_L("ReceiveSPIL: SPI=%x, Seq=%u"), ByteOrder::Swap32(aSPI), aSeq);
       
  2081 
       
  2082     CProposal_IIList *propII_List = iProposal_IIList;
       
  2083     TInt i;
       
  2084     for (i = 0; i < iInboundSPIList->Count(); i++)
       
  2085     {
       
  2086         if (iInboundSPIList->At(i).iSeq == aSeq)
       
  2087         {
       
  2088             iInboundSPIList->At(i).iSPI = aSPI;
       
  2089             break;
       
  2090         }
       
  2091         //prop = prop->iNext;   //To assign the SPI to the correct proposal
       
  2092     }
       
  2093     if (iRole==INITIATOR)
       
  2094         propII_List->At(i)->iSPI.Copy((TUint8*)&aSPI,sizeof(TUint32));  //needed to send it to the other Peer
       
  2095 
       
  2096     if (--iPendingSPI)  // Check if still waiting for some SPI
       
  2097         return;
       
  2098 
       
  2099     iExchange = IKE_QUICK_MODE; //Current mode being used.
       
  2100     //Builds and send the packet
       
  2101 
       
  2102     if ((iHostData->iCommit) && (iRole==RESPONDER)) //Responder  && if commit bit used we set the flag
       
  2103         iFlags |= ISAKMP_HDR_CFLAG; //Sets the Commit bit if this side set it else
       
  2104 
       
  2105     msg->IsakmpInit(this);
       
  2106     msg->IsakmpHashL();
       
  2107     msg->IsakmpSa();
       
  2108     ComputeNonceL();     //Computes a new Nonce for PHASE_II
       
  2109     msg->IsakmpNonce();
       
  2110     if (iPFS)   //Only sent if PFS in use...
       
  2111         msg->IsakmpKeyL();
       
  2112 
       
  2113     if (iStage==1)  //Initiator
       
  2114     {
       
  2115         //
       
  2116         // If Internal address private extension used change iLocalAddr1_ID_II to
       
  2117         // correspond that address
       
  2118         //
       
  2119         if ( iInternalAddr ) {
       
  2120            iLocalAddr1_ID_II = iInternalAddr->iClientIntAddr;       
       
  2121            iLocalIDType_II   = ID_IPV4_ADDR;
       
  2122            iDefaultLocalID   = ETrue;  
       
  2123         }   
       
  2124         DEBUG_LOG(_L("PhaseII IV:"));   //New IV for phase II
       
  2125         ComputeIVL(iIV, iMessageId);
       
  2126         //IDs must be sent if TUNNEL mode or is explicitly specified in the acquire
       
  2127         if ((!iLocalAddr1_ID_II.IsUnspecified()) || (!iRemoteAddr1_ID_II.IsUnspecified()) ||
       
  2128             (iIDProtocol != 0) || (iIDLocalPort != 0) || (iIDRemotePort != 0))
       
  2129         {
       
  2130             msg->IsakmpOwnIdentL();     //Own proxy
       
  2131             msg->IsakmpPeerIdentL();    //Peer Proxy
       
  2132         }
       
  2133     }
       
  2134     else if (iStage==2) //Responder
       
  2135     {
       
  2136         if (iIDReceived)    //If received we send it back, otherwise no
       
  2137         {
       
  2138             msg->IsakmpPeerIdentL();
       
  2139             msg->IsakmpOwnIdentL(); 
       
  2140         }
       
  2141         if (iHostData->iResponderLifetime)
       
  2142             CheckSendResponderLifetime(*msg);    //Adds to the message the RESPONDER_LIFETIME payload if needed
       
  2143     }
       
  2144     else return;
       
  2145 
       
  2146     if (iHostData->iReplayStatus)
       
  2147     {
       
  2148         DEBUG_LOG(_L("Constructing REPLAY-STATUS"));
       
  2149     
       
  2150         TInt i;
       
  2151         CProposal_II *prop;
       
  2152         for (i = 0 ; i < iProposal_IIList->Count(); i++)
       
  2153         {
       
  2154             prop = iProposal_IIList->At(i);
       
  2155             msg->IsakmpReplayStatus(prop->iProtocol, iInboundSPIList->At(i).iSPI, prop->iReplayWindowLength);
       
  2156         }
       
  2157     }
       
  2158     msg->IsakmpHashContL(); //inserts the hash in the correct position of the buffer
       
  2159     SendL(*msg);
       
  2160 
       
  2161     iStage++;   //Next stage
       
  2162 }
       
  2163 
       
  2164 void CIkev1Negotiation::AcquireSAErrorResponse(TInt aError)
       
  2165 	{
       
  2166 	DEBUG_LOG(_L("CIkev1Negotiation::AcquireSAErrorResponse"));
       
  2167 		
       
  2168 	if ( iProposal_IIList )
       
  2169 		{
       
  2170 		for ( TInt j=0; j<iProposal_IIList->Count(); j++ )
       
  2171 			{			
       
  2172 			TIpsecSAData sa_data;	
       
  2173 		    sa_data.iSeq = iAcquireSeq;
       
  2174 		    sa_data.iPid = iPfkeyAcquirePID;
       
  2175 			sa_data.iSPI = 0;	
       
  2176 			sa_data.iDst = iRemoteAddr;
       
  2177 			
       
  2178 			CProposal_II* prop_II = iProposal_IIList->At( j );
       
  2179 
       
  2180 			if ( prop_II->iProtocol == PROTO_IPSEC_AH )
       
  2181 				{
       
  2182 				sa_data.iSAType = SADB_SATYPE_AH;				
       
  2183 				}
       
  2184 	        else if ( prop_II->iProtocol == PROTO_IPSEC_ESP )
       
  2185 	            {
       
  2186 	            sa_data.iSAType = SADB_SATYPE_ESP;
       
  2187 	            }
       
  2188 			iPluginSession->AcquireSAError( sa_data, aError );
       
  2189 			}
       
  2190 		}
       
  2191     iAcquirePending = EFalse;
       
  2192 	}
       
  2193 
       
  2194 //Will update the outbound
       
  2195 void CIkev1Negotiation::UpdateSADatabaseL()
       
  2196 {
       
  2197 #ifdef _DEBUG
       
  2198     TBuf<40> addr_buf;
       
  2199 #endif    
       
  2200     TUint8 sa_type=0;
       
  2201     TUint8 auth_alg=0;
       
  2202     TUint8 encr_alg=0;
       
  2203     TUint32 updateSPI,addSPI;
       
  2204     TIpsecSAData sa_data;
       
  2205     TBool   TunnelMode;
       
  2206 	//
       
  2207     // Received Phase II key (Might be Auth + Encr keys)
       
  2208 	// (Buffers are allocated for max 1024 bits key material
       
  2209 	HBufC8* outboundKey_II = HBufC8::NewLC(128);
       
  2210 	HBufC8* inboundKey_II  = HBufC8::NewLC(128);     	
       
  2211     TPtrC8 in_authKey(0,0), out_authKey(0,0);
       
  2212     TPtrC8 in_encrKey(0,0), out_encrKey(0,0);
       
  2213     //Identities
       
  2214 #ifdef _UNICODE	
       
  2215 	TBuf<80> id_work;
       
  2216 #endif						
       
  2217 	HBufC8* local_id   = HBufC8::NewLC(128);
       
  2218 	HBufC8* remote_id  = HBufC8::NewLC(128);
       
  2219     // ESP UDP Encapsulation extension data	
       
  2220 	HBufC8* gen_ext_data = HBufC8::NewLC(128);     	
       
  2221 	TPtr8 GenExtData((TUint8*)gen_ext_data->Ptr(), 0, gen_ext_data->Des().MaxLength());
       
  2222 	
       
  2223 	DEBUG_LOG(_L("---UPDATING SAD---"));	
       
  2224 	
       
  2225     if ((!iDefaultLocalID) && (iLocalIDType_II != 0))
       
  2226     {
       
  2227         switch (iLocalIDType_II)
       
  2228         {   
       
  2229         case ID_IPV4_ADDR:
       
  2230         case ID_IPV6_ADDR:
       
  2231 #ifdef _UNICODE				
       
  2232             iLocalAddr1_ID_II.OutputWithScope(id_work);
       
  2233 			local_id->Des().Copy(id_work);			
       
  2234 #else
       
  2235 			iLocalAddr1_ID_II.OutputWithScope(local_id->Des());			
       
  2236 #endif			
       
  2237             break;
       
  2238 			
       
  2239         case ID_IPV4_ADDR_SUBNET:
       
  2240         case ID_IPV6_ADDR_SUBNET:
       
  2241 #ifdef _UNICODE							
       
  2242             iLocalAddr1_ID_II.OutputWithScope(id_work);
       
  2243 			local_id->Des().Copy(id_work);			
       
  2244 #else
       
  2245 			iLocalAddr1_ID_II.OutputWithScope(local_id->Des());			
       
  2246 #endif						
       
  2247             local_id->Des().AppendFormat(_L8("/%d"),PrefixLen(iLocalAddr2_ID_II));  //PrefixLen can't fail because checked before
       
  2248             break;
       
  2249         default:    //Should never come here
       
  2250             DEBUG_LOG1(_L("Local ID type %d not supported"), iLocalIDType_II);
       
  2251 			CleanupStack::PopAndDestroy(5);  //key buffer, identities and ESP UDP encaps data
       
  2252             return;
       
  2253         }
       
  2254     }
       
  2255 
       
  2256     if ((!iDefaultRemoteID) && (iRemoteIDType_II != 0) )
       
  2257     {
       
  2258         switch (iRemoteIDType_II)
       
  2259         {   
       
  2260         case ID_IPV4_ADDR:
       
  2261         case ID_IPV6_ADDR:
       
  2262 #ifdef _UNICODE				
       
  2263 			iRemoteAddr1_ID_II.OutputWithScope(id_work);
       
  2264 			remote_id->Des().Copy(id_work);			
       
  2265 #else
       
  2266 			iRemoteAddr1_ID_II.OutputWithScope(remote_id->Des());			
       
  2267 #endif
       
  2268 			if ( iSwapRemoteIdType )
       
  2269 			{
       
  2270 			   if ( iRemoteIDType_II == ID_IPV4_ADDR )
       
  2271 				    remote_id->Des().AppendFormat(_L8("/%d"), 32);
       
  2272 			   else remote_id->Des().AppendFormat(_L8("/%d"), 128);
       
  2273 			}	
       
  2274             break;
       
  2275 			
       
  2276         case ID_IPV4_ADDR_SUBNET:
       
  2277         case ID_IPV6_ADDR_SUBNET:
       
  2278 #ifdef _UNICODE				
       
  2279 			iRemoteAddr1_ID_II.OutputWithScope(id_work);
       
  2280 			remote_id->Des().Copy(id_work);			
       
  2281 #else
       
  2282 			iRemoteAddr1_ID_II.OutputWithScope(remote_id->Des());			
       
  2283 #endif
       
  2284 			if ( !iSwapRemoteIdType )
       
  2285                remote_id->Des().AppendFormat(_L8("/%d"),PrefixLen(iRemoteAddr2_ID_II));    //PrefixLen can't fail because checked before
       
  2286             break;
       
  2287 			
       
  2288         default:    //Should never come here
       
  2289             DEBUG_LOG1(_L("Remote ID type %d not supported"), iRemoteIDType_II);
       
  2290 			CleanupStack::PopAndDestroy(5);  //key buffer, identities and ESP UDP encaps data					
       
  2291             return;
       
  2292         }
       
  2293     }
       
  2294 
       
  2295     TUint32 flags = 0;
       
  2296     if (iPFS)
       
  2297     {
       
  2298         flags = SADB_SAFLAGS_PFS;
       
  2299         DEBUG_LOG(_L("PFS enabled"));
       
  2300     }
       
  2301 
       
  2302     TUint32 addPID;
       
  2303     if (iRole==INITIATOR)
       
  2304         addPID = iPfkeyAcquirePID;  //Require to remove the Larval SA
       
  2305     else
       
  2306         addPID = iPluginSession->Uid();
       
  2307     
       
  2308     DEBUG_LOG2(_L("SAD seq= %d , PID= %d"), iAcquireSeq, addPID);
       
  2309 
       
  2310     TInt i, j;
       
  2311     for (i = 0; i < iInboundSPIList->Count(); i++)
       
  2312     {
       
  2313         if (iInboundSPIList->At(i).iPropNum == iProposalNum)
       
  2314             break;
       
  2315     }
       
  2316 
       
  2317     CProposal_II *prop;
       
  2318     TSPINode inboundspi_node;
       
  2319     TInt key_len, encr_len, auth_len;
       
  2320     TChosenAttrib_II *attr_II;
       
  2321     TInt count = iChosenProp_IIList->Count();
       
  2322 
       
  2323     for (j = 0 ; j < count; j++)
       
  2324     {
       
  2325         prop = iChosenProp_IIList->At(j);
       
  2326         inboundspi_node = iInboundSPIList->At(i);
       
  2327         attr_II = (TChosenAttrib_II *)prop->iAttrList->At(0);   //only 1 transform is chosen no matter how many there are
       
  2328         if (prop->iProtocol == PROTO_IPSEC_AH)
       
  2329         {
       
  2330             
       
  2331             sa_type  = SADB_SATYPE_AH;
       
  2332             encr_alg = 0;
       
  2333             auth_alg = attr_II->iTransformID;
       
  2334 			auth_len = (TInt)HMAC_KeyLength((TUint8)auth_alg);
       
  2335 			
       
  2336 			TPtr8 AHOutKey((TUint8*)outboundKey_II->Ptr(), 0, outboundKey_II->Des().MaxLength());
       
  2337 			TPtr8 AHInKey((TUint8*)inboundKey_II->Ptr(), 0, inboundKey_II->Des().MaxLength());
       
  2338 			
       
  2339             ComputeKeys2L(prop, auth_len, inboundspi_node, AHOutKey, AHInKey);
       
  2340             in_encrKey.Set(NULL, 0);
       
  2341             out_encrKey.Set(NULL, 0);
       
  2342             in_authKey.Set(inboundKey_II->Ptr(), auth_len/8);
       
  2343             out_authKey.Set(outboundKey_II->Ptr(),auth_len/8);
       
  2344         }
       
  2345         else if (prop->iProtocol == PROTO_IPSEC_ESP)
       
  2346         {
       
  2347             sa_type = SADB_SATYPE_ESP;
       
  2348             encr_alg = attr_II->iTransformID;
       
  2349             if (attr_II->iKeyLength!=0)
       
  2350                 encr_len = attr_II->iKeyLength;
       
  2351             else    //not sent means constant size or variable and use default
       
  2352             {
       
  2353 				switch ( encr_alg )
       
  2354 				{
       
  2355 					case ESP_DES_CBC:
       
  2356 						encr_len = 64;
       
  2357 						break;
       
  2358 					case ESP_3DES_CBC:
       
  2359 						encr_len = 3*64;
       
  2360 						break;
       
  2361 					case ESP_NULL:
       
  2362 						encr_len = 0;
       
  2363 						break;
       
  2364 					case ESP_AES_CBC:
       
  2365 						encr_len = 128;
       
  2366 						break;
       
  2367 					default:	
       
  2368 						encr_len = 0;
       
  2369 						break;
       
  2370 						
       
  2371 				}	
       
  2372             }
       
  2373 
       
  2374             if (attr_II->iAuthAlg==DOI_HMAC_MD5)
       
  2375                 auth_alg = SADB_AALG_MD5HMAC;
       
  2376             else if (attr_II->iAuthAlg==DOI_HMAC_SHA)
       
  2377                 auth_alg = SADB_AALG_SHA1HMAC;
       
  2378             else
       
  2379                 auth_alg = 0;
       
  2380 
       
  2381             auth_len = (TInt)HMAC_KeyLength((TUint8)auth_alg);
       
  2382             key_len = encr_len + auth_len;
       
  2383 
       
  2384 			TPtr8 ESPOutKey((TUint8*)outboundKey_II->Ptr(), 0, outboundKey_II->Des().MaxLength());
       
  2385 			TPtr8 ESPInKey((TUint8*)inboundKey_II->Ptr(), 0, inboundKey_II->Des().MaxLength());			
       
  2386             ComputeKeys2L(prop, key_len, inboundspi_node, ESPOutKey, ESPInKey);
       
  2387 
       
  2388             in_encrKey.Set(inboundKey_II->Ptr(), encr_len/8);
       
  2389             out_encrKey.Set(outboundKey_II->Ptr(), encr_len/8);
       
  2390 
       
  2391             //If no HMAC selected the next instr does nothing because size will be 0
       
  2392             in_authKey.Set(inboundKey_II->Ptr() + in_encrKey.Length(),auth_len/8);
       
  2393             out_authKey.Set(outboundKey_II->Ptr() + out_encrKey.Length(),auth_len/8);
       
  2394             //
       
  2395             // Nokia specific NAT traversal info (=ESP UDP tunneling)  
       
  2396             // If iNAT_T_Required is true connection is over NAT:ted
       
  2397             // newtork (=local end behind NAT).
       
  2398 			//
       
  2399             if ( iNAT_T_Required ) {
       
  2400                flags |= SADB_SAFLAGS_NAT_T;
       
  2401             }
       
  2402         }
       
  2403         else
       
  2404 		{	
       
  2405 			DEBUG_LOG1(_L("Unknown IPsec protocol %d"), prop->iProtocol);
       
  2406 			CleanupStack::PopAndDestroy(5);  //key buffer, identities and ESP UDP encaps data					
       
  2407 			return;
       
  2408 		}	
       
  2409 
       
  2410         updateSPI = inboundspi_node.iSPI;
       
  2411         Mem::Copy((TUint8*)&addSPI, prop->iSPI.Ptr(), sizeof(TUint32));
       
  2412 
       
  2413         TInetAddr local_addr(iLocalAddr);
       
  2414         local_addr.SetPort(iIDLocalPort);
       
  2415         TInetAddr remote_addr(iRemoteAddr);    
       
  2416         remote_addr.SetPort(iIDRemotePort);
       
  2417     
       
  2418         //This will be always outbound
       
  2419         
       
  2420         TInt64 time(0), bytes(0);
       
  2421         TPtrC8 time_ptr(attr_II->iLifeDurationSecs);
       
  2422         TPtrC8 bytes_ptr(attr_II->iLifeDurationKBytes);
       
  2423         if (attr_II->iReducedLifeSecs.Length() != 0)
       
  2424             time_ptr.Set(attr_II->iReducedLifeSecs);
       
  2425 
       
  2426         if (attr_II->iReducedLifeKBytes.Length() != 0)
       
  2427             bytes_ptr.Set(attr_II->iReducedLifeKBytes);
       
  2428 
       
  2429         ComputeLifetimes_II(time_ptr, bytes_ptr, time, bytes);
       
  2430         if (time == 0)  //default lifetime applied
       
  2431             time = DEFAULT_IPSEC_SA_LIFETIME;
       
  2432         
       
  2433         if (iHardLifetime > time)
       
  2434             {
       
  2435             DEBUG_LOG2(_L("Time %u, hard lifetime %d"),
       
  2436                     I64LOW(time), I64LOW(iHardLifetime));
       
  2437             time = iHardLifetime;
       
  2438             }
       
  2439 
       
  2440         if (attr_II->iEncMode==DOI_TUNNEL)
       
  2441         {
       
  2442             TunnelMode = ETrue;
       
  2443             DEBUG_LOG(_L("TUNNEL MODE"));
       
  2444 #ifdef _DEBUG            
       
  2445             iLocalAddr1_ID_II.OutputWithScope(addr_buf);
       
  2446             DEBUG_LOG1(_L("Local ID: net %S"), &addr_buf);
       
  2447             
       
  2448             if ((iLocalIDType_II == ID_IPV4_ADDR_SUBNET) || (iLocalIDType_II == ID_IPV6_ADDR_SUBNET))
       
  2449                 {
       
  2450                 iLocalAddr2_ID_II.OutputWithScope(addr_buf);
       
  2451                 DEBUG_LOG1(_L(", mask %S"), &addr_buf);
       
  2452                 }
       
  2453             DEBUG_LOG1(_L(" (port %d)"), iIDLocalPort);
       
  2454             iRemoteAddr1_ID_II.OutputWithScope(addr_buf);
       
  2455             DEBUG_LOG1(_L("Remote ID: addr %S"), &addr_buf);
       
  2456             if ((iRemoteIDType_II == ID_IPV4_ADDR_SUBNET) || (iRemoteIDType_II == ID_IPV6_ADDR_SUBNET))
       
  2457                 {
       
  2458                 iRemoteAddr2_ID_II.OutputWithScope(addr_buf);
       
  2459                 DEBUG_LOG1(_L(", mask %S"), &addr_buf);
       
  2460                 }
       
  2461             DEBUG_LOG1(_L(" (port %d)"), iIDRemotePort);
       
  2462 #endif // _DEBUG            
       
  2463             
       
  2464         }
       
  2465         else {
       
  2466             TunnelMode = EFalse;        
       
  2467             DEBUG_LOG(_L("TRANSPORT MODE"));
       
  2468         }
       
  2469         DEBUG_LOG1(_L("Sec Lifetime set to %u"),I64LOW(time));
       
  2470         DEBUG_LOG1(_L("KB Lifetime set to %u"),I64LOW(bytes));
       
  2471 
       
  2472         //Inbound SA.
       
  2473         sa_data.iSAType = sa_type;
       
  2474         sa_data.iSeq = iAcquireSeq;
       
  2475         sa_data.iSrc = remote_addr;
       
  2476         sa_data.iDst = local_addr;
       
  2477         sa_data.iProtocol = iIDProtocol;
       
  2478         sa_data.iSrcIdType = iRemoteIDType_II;
       
  2479         sa_data.iDstIdType = iLocalIDType_II;       
       
  2480         sa_data.iSrcIdent.Set((TUint8 *)remote_id->Ptr(), remote_id->Length(), remote_id->Length());
       
  2481         sa_data.iDstIdent.Set((TUint8 *)local_id->Ptr(), local_id->Length(), local_id->Length());
       
  2482         sa_data.iPid = iPluginSession->Uid();
       
  2483         sa_data.iSPI = updateSPI;
       
  2484         sa_data.iAuthAlg = auth_alg;
       
  2485         sa_data.iEncrAlg = encr_alg;
       
  2486         sa_data.iAuthKey.Set(in_authKey);
       
  2487         sa_data.iEncrKey.Set(in_encrKey);
       
  2488         TIpsecSALifetime lifetime(0, bytes, time, 0);
       
  2489         sa_data.iHard = &lifetime;
       
  2490         sa_data.iReplayWindowLength = prop->iReplayWindowLength;
       
  2491 
       
  2492         if ( (sa_type == SADB_SATYPE_ESP) && (GenExtData.Length() == 0) ) {     
       
  2493            //
       
  2494            // Store possible NAT traversal info for IPSEC to do ESP UDP encapsulation correctly
       
  2495            //
       
  2496             PFKeyExtDataUtil::BuildUdpEncExtensionData( GenExtData,
       
  2497                                                         iNAT_D_Flags,
       
  2498                                                         (flags & SADB_SAFLAGS_NAT_T),
       
  2499                                                         iHostData->iUseNatProbing,
       
  2500                                                         (TUint16)iHostData->iEspUdpPort, 
       
  2501                                                         UDP_KEEPALIVE_TIME,
       
  2502                                                         iLastRemoteAddr,
       
  2503                                                         iRemoteOriginalAddr );
       
  2504         }
       
  2505         
       
  2506         if ( GenExtData.Length() ) {
       
  2507            sa_data.iGenericExtension.Set(GenExtData);      
       
  2508         }
       
  2509 
       
  2510         if ( TunnelMode ) {
       
  2511            //
       
  2512            // Get VPN interface index 
       
  2513            //
       
  2514            TUint32 vpnInterfaceIndex = iPluginSession->VpnInterfaceIndex();
       
  2515            if ( vpnInterfaceIndex != 0 )
       
  2516                {
       
  2517                sa_data.iInternalAddress.Init( KAfInet6 );
       
  2518                sa_data.iInternalAddress.SetScope( vpnInterfaceIndex );
       
  2519                flags |= SADB_SAFLAGS_INT_ADDR;
       
  2520                }
       
  2521            }
       
  2522         sa_data.iFlags = flags;
       
  2523 		iPluginSession->UpdateSAL(sa_data);
       
  2524 		TIpsecSPI SpiData;
       
  2525 		SpiData.iProtocol = sa_type;
       
  2526 		SpiData.iSrcAddr  = remote_addr;
       
  2527 		SpiData.iDstAddr  = local_addr;
       
  2528 		SpiData.iSPI      = updateSPI;
       
  2529 		SpiData.iInbound  = ETrue;
       
  2530 		iPluginSession->AddIpsecSPIToSAL(iSAId, SpiData);
       
  2531 
       
  2532         sa_data.iFlags &= ~SADB_SAFLAGS_INT_ADDR; //No VPN interface index to outbound SA
       
  2533         //Outbound SA.
       
  2534         //First check there's no other SA with the same parameters and
       
  2535         //erase it if happens (very unlikely, but still possible)
       
  2536 		SpiData.iDstAddr = remote_addr;
       
  2537 		SpiData.iSrcAddr = local_addr;
       
  2538 		SpiData.iSPI     = addSPI;
       
  2539 		SpiData.iInbound = EFalse;
       
  2540 		if ( iPluginSession->DeleteIpsecSpi(iSAId, addSPI, EFalse) )		
       
  2541         {
       
  2542             DEBUG_LOG(_L("Deleting previously negotiated IPsec SA"));
       
  2543 			iPluginSession->DeleteIpsecSA(SpiData.iSPI, SpiData.iSrcAddr, SpiData.iDstAddr, 
       
  2544                                               SpiData.iProtocol);
       
  2545         }
       
  2546         //Some changes in the SA, the rest is the same
       
  2547         sa_data.iSrc = local_addr;
       
  2548         sa_data.iDst = remote_addr;
       
  2549         sa_data.iSrcIdType = iLocalIDType_II;
       
  2550         sa_data.iDstIdType = iRemoteIDType_II;
       
  2551         sa_data.iSrcIdent.Set((TUint8 *)local_id->Ptr(), local_id->Length(), local_id->Length());
       
  2552         sa_data.iDstIdent.Set((TUint8 *)remote_id->Ptr(), remote_id->Length(), remote_id->Length());
       
  2553         sa_data.iPid = addPID;
       
  2554         sa_data.iSPI = addSPI;
       
  2555         sa_data.iAuthKey.Set(out_authKey);
       
  2556         sa_data.iEncrKey.Set(out_encrKey);
       
  2557         
       
  2558         iPluginSession->AddSAL(sa_data);
       
  2559 		iPluginSession->AddIpsecSPIToSAL(iSAId, SpiData);
       
  2560         
       
  2561         i++;    //To get the correct SPIs from iInboundSPIList
       
  2562 	} //end for
       
  2563 
       
  2564 	CleanupStack::PopAndDestroy(5);  //key buffer, identities and ESP UDP encaps data
       
  2565 	
       
  2566 	iAcquirePending = EFalse;
       
  2567 	
       
  2568 }
       
  2569 
       
  2570 void CIkev1Negotiation::ComputeLifetimes_II(const TDesC8 &aLifetime, const TDesC8 &aLifesize, TInt64 &aTime, TInt64 &aBytes)
       
  2571 {
       
  2572     TInt64 maxnum = MAKE_TINT64(0x7fffffffu, 0xffffffffu);
       
  2573         
       
  2574     if (Desc8ToTInt64(aLifetime, aTime) != KErrNone)
       
  2575         {
       
  2576         DEBUG_LOG(_L("Phase_II Lifetime(sec) Overflowed Setting to maximum value"));
       
  2577         }
       
  2578     if (Desc8ToTInt64(aLifesize, aBytes) != KErrNone) {
       
  2579         DEBUG_LOG(_L("Phase_II Lifetime(kbytes) Overflowed Setting to maximum value"));
       
  2580     }       
       
  2581     else 
       
  2582     {   if (aBytes < maxnum / 1024) //Make sure no overflow
       
  2583             aBytes = aBytes * 1024; //KB to Bytes
       
  2584         else
       
  2585         {
       
  2586             aBytes = MAKE_TINT64(KMaxTInt, KMaxTUint);            
       
  2587             DEBUG_LOG(_L("Phase_II Lifetime(kbytes) Overflowed Setting to maximum value"));
       
  2588         }
       
  2589     }
       
  2590 
       
  2591 }
       
  2592 
       
  2593 
       
  2594 TBool CIkev1Negotiation::Phase_IExchangeL(const ThdrISAKMP &aHdr)
       
  2595 {       
       
  2596     if (!ProcessHeaderL(aHdr))
       
  2597         return EFalse;
       
  2598 
       
  2599     DEBUG_LOG2(_L("---------- Phase %d - Stage %d ----------"),iPhase, iStage);
       
  2600     if (iPhase == PHASE_I)
       
  2601     {
       
  2602         if (aHdr.GetExchange() == ISAKMP_EXCHANGE_ID)
       
  2603             MainModeReplyL();   //Main Mode
       
  2604         else
       
  2605             AggressiveReplyL(); //Aggressive Mode
       
  2606     }
       
  2607     else
       
  2608     {
       
  2609         QuickModeReplyL();
       
  2610     }
       
  2611     return ETrue;
       
  2612 }
       
  2613 
       
  2614 TBool CIkev1Negotiation::Phase_IIExchangeL(const ThdrISAKMP &aHdr)
       
  2615 {       
       
  2616     if (!ProcessHeaderL(aHdr))
       
  2617         return EFalse;
       
  2618 
       
  2619     DEBUG_LOG2(_L("---------- Phase %d - Stage %d ----------"),iPhase, iStage);
       
  2620 
       
  2621     QuickModeReplyL();
       
  2622 
       
  2623     return ETrue;
       
  2624 }
       
  2625 
       
  2626 void CIkev1Negotiation::QuickModeReplyL()
       
  2627 {
       
  2628 
       
  2629 	TIkev1IsakmpStream* msg = SaveIkeMsgBfr( new (ELeave) TIkev1IsakmpStream(iDebug) );	
       
  2630     switch(iStage)
       
  2631     {
       
  2632     //INITIATOR cases
       
  2633     case 3: //Send last message (if no COMMIT)
       
  2634         msg->IsakmpInit(this);
       
  2635         msg->IsakmpHashL();
       
  2636         SendL(*msg);
       
  2637         iStage = 4;  
       
  2638 
       
  2639         if (iRecvFlags & ISAKMP_HDR_CFLAG)  //Commit Bit set
       
  2640              return; //Not finished yet. We wait for CONNECTED
       
  2641         
       
  2642         //No Commot bit, Update SA database
       
  2643         UpdateSADatabaseL();
       
  2644         SetFinished();    //No more stages.
       
  2645         break;
       
  2646 	case 1: 
       
  2647 		DEBUG_LOG(_L("QuickModeReplyL in Stage 1 ?"));		
       
  2648 		break;
       
  2649     case 5: //Send last message (extra message waiting for commit(
       
  2650         //No more processing required
       
  2651         SetFinished();    //No more stages.
       
  2652         break;
       
  2653     //RESPONDER cases
       
  2654     case 2:
       
  2655         GetSPIL();
       
  2656         //rest done in receiveSPI
       
  2657         break;
       
  2658     case 4:
       
  2659         if (iRecvFlags & ISAKMP_HDR_CFLAG)  //Commit Bit set
       
  2660         {
       
  2661             DEBUG_LOG(_L("Sending CONNECTED Status message"));
       
  2662             msg->IsakmpInit(this);
       
  2663 
       
  2664             //HASH Payload only if payload protected with encryption
       
  2665             if (iFlags & ISAKMP_HDR_EFLAG)
       
  2666                 msg->IsakmpHashL();
       
  2667         
       
  2668             msg->IsakmpNotification(CONNECTED, iChosenProp_IIList->At(0)->iProtocol);
       
  2669 
       
  2670             if (iFlags & ISAKMP_HDR_EFLAG)
       
  2671                 msg->IsakmpHashContL();
       
  2672                 
       
  2673             SendL(*msg);
       
  2674         }
       
  2675         SetFinished();
       
  2676         break;
       
  2677     }
       
  2678 }
       
  2679 
       
  2680 //Builds and sends a Phase I reply for Main Mode
       
  2681 void CIkev1Negotiation::MainModeReplyL()
       
  2682 {
       
  2683 	TIkev1IsakmpStream* msg = SaveIkeMsgBfr( new (ELeave) TIkev1IsakmpStream(iDebug) );		
       
  2684     TInt          vendor_type;
       
  2685  
       
  2686     switch(iStage)
       
  2687     {
       
  2688     //
       
  2689     //RESPONDER replies
       
  2690     //
       
  2691     case 2: 
       
  2692         msg->IsakmpInit(this);
       
  2693         msg->IsakmpSa();
       
  2694         if ( iHostData->iDPDHeartBeat != 0 )
       
  2695            BuildDPDVendorId(*msg);        
       
  2696         if ( iNatDiscovery ) {
       
  2697            iNatDiscovery->BuildNatVendorId(*msg); 
       
  2698            iNatDiscovery->BuildRfcNatVendorId(*msg);
       
  2699         }   
       
  2700         SendL(*msg);
       
  2701         iStage = 3;
       
  2702         break;
       
  2703     case 4:
       
  2704         ComputeNonceL();         //Nonce to be sent
       
  2705         msg->IsakmpInit(this);
       
  2706         msg->IsakmpKeyL();
       
  2707         msg->IsakmpNonce();
       
  2708         if (((iChosenProposal_I.iAttrList->iAuthMethod == RSA_SIG) ||
       
  2709              (iChosenProposal_I.iAttrList->iAuthMethod == DSS_SIG)) && !iPeerX509Cert)
       
  2710            msg->IsakmpCertificateReqL();
       
  2711 		if ( iNatDiscovery ) {
       
  2712 			iNatDiscovery->BuildDiscoveryPayloadsL(*msg, iChosenProposal_I.iAttrList->iHashAlg,
       
  2713 				                                  (TUint8*)iCookie_I.Ptr(), (TUint8*)iCookie_R.Ptr(),
       
  2714 				                                  iLocalAddr, iLastRemoteAddr);    
       
  2715 		}
       
  2716 		SendL(*msg);
       
  2717         iStage = 5; //next stage
       
  2718         iFlags |= ISAKMP_HDR_EFLAG; //From now on encryption is used
       
  2719         if (!ComputeKeysL())    //Generates keying material for encryption stages
       
  2720             return; //error don't send reply packet
       
  2721         break;
       
  2722     case 6:
       
  2723         msg->IsakmpInit(this);
       
  2724         
       
  2725         switch(iChosenProposal_I.iAttrList->iAuthMethod)
       
  2726         {
       
  2727         case RSA_SIG:
       
  2728         case DSS_SIG:
       
  2729             msg->IsakmpOwnIdentL();
       
  2730             msg->IsakmpCertificateL();
       
  2731             msg->IsakmpSignatureL();
       
  2732             break;
       
  2733         case PRE_SHARED:
       
  2734             msg->IsakmpOwnIdentL();
       
  2735             msg->IsakmpHashL();
       
  2736             break;
       
  2737         }
       
  2738         
       
  2739         if ( iHostData->iInitialContact &&   
       
  2740              iRole == INITIATOR &&
       
  2741              iSARekeyInfo == NULL ) 
       
  2742         {
       
  2743            DEBUG_LOG(_L("Constructing INITIAL-CONTACT"));
       
  2744            msg->IsakmpNotification(DOI_INITIAL_CONTACT, PROTO_ISAKMP); //Not protected by the hash!
       
  2745         }
       
  2746         
       
  2747         SendL(*msg);
       
  2748 
       
  2749 		IsakmpPhase1CompletedL();
       
  2750         break;
       
  2751     //
       
  2752     //INITIATOR replies
       
  2753     //
       
  2754     case 3:
       
  2755         ComputeNonceL();         //Nonce to be sent
       
  2756         msg->IsakmpInit(this);
       
  2757         msg->IsakmpKeyL();
       
  2758         msg->IsakmpNonce();
       
  2759         if ( iChosenProposal_I.iAttrList->iAuthMethod == IKE_A_CRACK && !iPeerX509Cert )
       
  2760 		{
       
  2761             msg->IsakmpCertificateReqL();
       
  2762         }
       
  2763         if ( iHostData->iUseNatProbing )
       
  2764              vendor_type = EXPANDED_VENDOR_ID;
       
  2765         else vendor_type = HASH_VENDOR_ID;
       
  2766         msg->IsakmpVendorId(vendor_type,       
       
  2767                               (TUint8*)iCookie_I.Ptr(),
       
  2768                               (TUint8*)iCookie_R.Ptr(), iLocalAddr);
       
  2769         if ( iNatDiscovery )
       
  2770 		{
       
  2771            iNatDiscovery->BuildDiscoveryPayloadsL(*msg, iChosenProposal_I.iAttrList->iHashAlg,
       
  2772                                                  (TUint8*)iCookie_I.Ptr(), (TUint8*)iCookie_R.Ptr(),
       
  2773                                                  iLocalAddr, iLastRemoteAddr);    
       
  2774         }   
       
  2775         SendL(*msg);
       
  2776         iStage = 4; //next stage
       
  2777         break;
       
  2778 
       
  2779     case 5:
       
  2780         iFlags |= ISAKMP_HDR_EFLAG; //From now on encryption is used
       
  2781         if (!ComputeKeysL())    //Generates keying material for encryption stages
       
  2782             return; //error don't send reply packet
       
  2783         
       
  2784         msg->IsakmpInit(this);
       
  2785         
       
  2786         switch(iChosenProposal_I.iAttrList->iAuthMethod)
       
  2787         {
       
  2788         case RSA_SIG:
       
  2789         case DSS_SIG:
       
  2790             msg->IsakmpOwnIdentL(); //Also fills iOwnIdentPayload!
       
  2791             msg->IsakmpCertificateL();
       
  2792             msg->IsakmpSignatureL();
       
  2793             if (!iPeerX509Cert)
       
  2794                msg->IsakmpCertificateReqL(); 
       
  2795             break;
       
  2796         case PRE_SHARED:
       
  2797             msg->IsakmpOwnIdentL();
       
  2798             msg->IsakmpHashL();
       
  2799             break;
       
  2800         }
       
  2801         
       
  2802         
       
  2803         if ( iFamiliarPeer && iHostData->iUseInternalAddr )
       
  2804            msg->IsakmpIntnet(0);  /* null IPV4 address as parameter */
       
  2805 
       
  2806 		if ( iHostData->iInitialContact &&
       
  2807 		    !iPluginSession->FindIkev1SADataWithAddr(iRemoteAddr) &&
       
  2808             iRole == INITIATOR &&
       
  2809 		    iSARekeyInfo == NULL ) 
       
  2810 		{
       
  2811 			DEBUG_LOG(_L("Constructing INITIAL-CONTACT"));
       
  2812 			msg->IsakmpNotification(DOI_INITIAL_CONTACT, PROTO_ISAKMP); //Not protected by the hash!
       
  2813 		}
       
  2814 		
       
  2815         SendL(*msg);
       
  2816         iStage = 6; //next stage
       
  2817         
       
  2818         break;
       
  2819     case 7:
       
  2820         // CRACK authentication going. No actions required here !
       
  2821         break;
       
  2822     default:
       
  2823         DEBUG_LOG1(_L("Main mode Wrong Phase number requested (%d) !!"),iStage);
       
  2824     }
       
  2825 
       
  2826 }
       
  2827 
       
  2828 
       
  2829 //Builds and sends a Phase I reply for Aggressive Mode
       
  2830 void CIkev1Negotiation::AggressiveReplyL()
       
  2831 {
       
  2832 	TIkev1IsakmpStream* msg = SaveIkeMsgBfr( new (ELeave) TIkev1IsakmpStream(iDebug) );			
       
  2833 	
       
  2834     switch(iStage)
       
  2835     {
       
  2836     case 2://RESPONDER Sends the 2nd msg. of the exchange
       
  2837         ComputeNonceL();         //Nonce to be sent
       
  2838         msg->IsakmpInit(this);
       
  2839         msg->IsakmpSa();
       
  2840         msg->IsakmpKeyL();
       
  2841         msg->IsakmpNonce();
       
  2842         msg->IsakmpOwnIdentL();
       
  2843         
       
  2844         if (!ComputeKeysL()) //Needed to compute hash before computing signature
       
  2845 		{
       
  2846 		   return;
       
  2847 		}   
       
  2848         
       
  2849         if ( iHostData->iDPDHeartBeat != 0 )
       
  2850            BuildDPDVendorId(*msg);        
       
  2851         if ( iNatDiscovery ) {
       
  2852            iNatDiscovery->BuildNatVendorId(*msg);
       
  2853            iNatDiscovery->BuildRfcNatVendorId(*msg);
       
  2854            iNatDiscovery->BuildDiscoveryPayloadsL(*msg, iChosenProposal_I.iAttrList->iHashAlg,
       
  2855                                                  (TUint8*)iCookie_I.Ptr(), (TUint8*)iCookie_R.Ptr(),
       
  2856                                                  iLocalAddr, iLastRemoteAddr);    
       
  2857         }   
       
  2858         
       
  2859         switch (iChosenProposal_I.iAttrList->iAuthMethod)
       
  2860         {
       
  2861         case RSA_SIG:
       
  2862         case DSS_SIG:
       
  2863             msg->IsakmpCertificateL();
       
  2864             msg->IsakmpSignatureL();
       
  2865             if (!iPeerX509Cert) //No stored cert so send a CR
       
  2866             {
       
  2867                 msg->IsakmpCertificateReqL();
       
  2868             }
       
  2869             break;
       
  2870         case PRE_SHARED:
       
  2871             msg->IsakmpHashL();
       
  2872             break;
       
  2873         }
       
  2874         SendL(*msg);
       
  2875 		
       
  2876         iStage = 3; //next stage
       
  2877 		
       
  2878         break;
       
  2879     case 3://INITIATOR
       
  2880         iFlags |= ISAKMP_HDR_EFLAG; //From now on encryption is used                
       
  2881         msg->IsakmpInit(this);
       
  2882         if ( iNatDiscovery ) {
       
  2883            iNatDiscovery->BuildDiscoveryPayloadsL(*msg, iChosenProposal_I.iAttrList->iHashAlg,
       
  2884                                                  (TUint8*)iCookie_I.Ptr(), (TUint8*)iCookie_R.Ptr(),
       
  2885                                                  iLocalAddr, iLastRemoteAddr);    
       
  2886         }   
       
  2887         
       
  2888         switch (iChosenProposal_I.iAttrList->iAuthMethod)
       
  2889         {
       
  2890         case RSA_SIG:
       
  2891         case DSS_SIG:
       
  2892             msg->IsakmpCertificateL();   
       
  2893             msg->IsakmpSignatureL(); 
       
  2894             break;
       
  2895         case PRE_SHARED:
       
  2896             msg->IsakmpHashL();
       
  2897             break;
       
  2898         }
       
  2899 		if ( iHostData->iInitialContact &&
       
  2900 		     !iPluginSession->FindIkev1SADataWithAddr(iRemoteAddr) &&
       
  2901              iRole == INITIATOR &&
       
  2902 		     iSARekeyInfo == NULL ) //Only sent if no ISAKMP SA established
       
  2903 		{
       
  2904 			DEBUG_LOG(_L("Constructing INITIAL-CONTACT"));
       
  2905 			msg->IsakmpNotification(DOI_INITIAL_CONTACT, PROTO_ISAKMP); //Not protected by the hash!
       
  2906 		}
       
  2907 
       
  2908         SendL(*msg);
       
  2909         IsakmpPhase1CompletedL();       
       
  2910         break;
       
  2911 	case 4:
       
  2912 		// Aggressive mode as responder completed
       
  2913 		DEBUG_LOG(_L("Aggressive mode as responder completed"));		
       
  2914 		break;
       
  2915 		
       
  2916     case 7:
       
  2917         // CRACK authentication going. No actions required here !
       
  2918         break;
       
  2919     default:
       
  2920         DEBUG_LOG1(_L("Main mode Wrong Phase number requested (%d) !! "),iStage);
       
  2921     }
       
  2922 	
       
  2923 }
       
  2924 
       
  2925 void CIkev1Negotiation::SaveISAKMPSAL()
       
  2926 {
       
  2927 	//
       
  2928 	// Create a new IKEv1 SA object       
       
  2929 	//
       
  2930 	TIkev1SAData SaData;
       
  2931 	SaData.iCookie_I       = iCookie_I;
       
  2932 	SaData.iCookie_R       = iCookie_R;
       
  2933 	SaData.iSAId           = iSAId;
       
  2934 	SaData.iSAState        = 0;
       
  2935 	SaData.iInitiator      = (iRole == INITIATOR);
       
  2936 	SaData.iAutoLogin      = iAutoLogin;
       
  2937 	SaData.iDPDSupported   = iDPDSupported;
       
  2938 	SaData.iFamiliarPeer   = iFamiliarPeer;
       
  2939 	SaData.iNAT_T_Required = iNAT_T_Required;
       
  2940 	SaData.iNAT_D_Flags    = iNAT_D_Flags;
       
  2941 	SaData.iIkeData        = iHostData;
       
  2942 	SaData.iLocalAddr      = iLocalAddr;
       
  2943 	SaData.iRemoteAddr     = iRemoteAddr;
       
  2944 	SaData.iDestinAddr     = iLastRemoteAddr;
       
  2945 	SaData.iVirtualIp      = iInternalAddr;
       
  2946 	SaData.iSeq            = iSeq;
       
  2947 	SaData.iPrevExchange   = iPrevExchange;
       
  2948 	SaData.iFlags          = iFlags;
       
  2949 	
       
  2950 	SaData.iEncrAlg        = iChosenProposal_I.iAttrList->iEncrAlg;
       
  2951 	SaData.iHashAlg        = iChosenProposal_I.iAttrList->iHashAlg;
       
  2952 	SaData.iGroupDesc      = iChosenProposal_I.iAttrList->iGroupDesc;
       
  2953 	SaData.iGroupType      = iChosenProposal_I.iAttrList->iGroupType;				
       
  2954 	SaData.iKeyLength      = iChosenProposal_I.iAttrList->iKeyLength;
       
  2955 
       
  2956 	TUint32 Lifetime = 0;
       
  2957 	TUint Len = iChosenProposal_I.iAttrList->iLifeDurationSecs.Length();
       
  2958 	if (Len > 0)
       
  2959 	{
       
  2960 		if (Len > sizeof(TUint32))
       
  2961 		{
       
  2962 			Lifetime = KMaxTUint32;
       
  2963 		}
       
  2964 		else    // (len <= sizeof(TUint32))
       
  2965 		{
       
  2966 			Mem::Copy(&Lifetime, iChosenProposal_I.iAttrList->iLifeDurationSecs.Ptr(), Len);
       
  2967 			Lifetime = ByteOrder::Swap32(Lifetime);
       
  2968 			Lifetime = Lifetime >> (sizeof(TUint32)*8 - Len*8);   //To set the correct value (shift in bits)
       
  2969 		}
       
  2970 	}
       
  2971 	SaData.iLifeTimeSecs = Lifetime;
       
  2972 	
       
  2973 	Lifetime = 0;
       
  2974 	Len = iChosenProposal_I.iAttrList->iLifeDurationKBytes.Length();
       
  2975 	if (Len > 0)
       
  2976 	{
       
  2977 		if (Len > sizeof(TUint32))
       
  2978 		{
       
  2979 			Lifetime = KMaxTUint32;
       
  2980 		}
       
  2981 		else    // (len <= sizeof(TUint32))
       
  2982 		{
       
  2983 			Mem::Copy(&Lifetime, iChosenProposal_I.iAttrList->iLifeDurationKBytes.Ptr(), Len);
       
  2984 			Lifetime = ByteOrder::Swap32(Lifetime);
       
  2985 			Lifetime = Lifetime >> (sizeof(TUint32)*8 - Len*8);   //To set the correct value (shift in bits)
       
  2986 		}
       
  2987 	}
       
  2988 	SaData.iLifeTimeKB = Lifetime;
       
  2989 
       
  2990 	SaData.iSKEYID     = iSKEYID;
       
  2991 	SaData.iSKEYID_d   = iSKEYID_d;
       
  2992 	SaData.iSKEYID_a   = iSKEYID_a;
       
  2993 	SaData.iSKEYID_e   = iSKEYID_e;
       
  2994 	SaData.iLastIV     = iLastIV;
       
  2995 	SaData.iIV         = iIV;
       
  2996 
       
  2997 	if ( iDPDSupported && iHostData->iDPDHeartBeat )
       
  2998 	{
       
  2999 	   //
       
  3000 	   //  Initialize DPD protocol parameters in TIkev1SAData
       
  3001 	   //
       
  3002 		TPtr8 ptr((TUint8*)&SaData.iDPDSequence, sizeof(TUint32));	 
       
  3003 		ptr.SetLength(sizeof(TUint32));
       
  3004 		TRandom::RandomL(ptr);	
       
  3005 		SaData.iDPDSequence &= 0x7fffffff;
       
  3006 		SaData.iDPDRetry = 0;
       
  3007 		SaData.iPendingDPDSequence  = 0;
       
  3008 		SaData.iExpectedDPDSequence = 0;		
       
  3009 	}	
       
  3010 		
       
  3011 	iLastIKEMsgInfo.Store(SaData.iLastIKEMsgInfo);
       
  3012     SaData.iLastMsg = iLastMsg;
       
  3013 	iPluginSession->CreateIkev1SAL(SaData, iSARekeyInfo);   // Add rekey info later
       
  3014 }
       
  3015 
       
  3016 TBool CIkev1Negotiation::ProcessHeaderL(const ThdrISAKMP &aHdr)
       
  3017 {
       
  3018     //checks on the header    
       
  3019     if (!CheckCookies(aHdr.GetCookieI(), aHdr.GetCookieR()))
       
  3020         return EFalse;
       
  3021 
       
  3022     if (iStage == 1)
       
  3023     {
       
  3024         if (iPhase == PHASE_I)
       
  3025         {
       
  3026             iCookie_I = aHdr.GetCookieI();  //save initiator cookie
       
  3027             iCookie_R = CreateCookieL(); //create responder cookie
       
  3028         }
       
  3029         iMessageId = aHdr.GetMessageId();
       
  3030     }
       
  3031     
       
  3032     //checks on the header    
       
  3033     if (!CheckPayloadCode(aHdr.GetPayload()))
       
  3034         return EFalse;
       
  3035 
       
  3036     if (!CheckVersionL(aHdr.GetVersion()))
       
  3037         return EFalse;
       
  3038     
       
  3039     if (!CheckExchangeTypeL(aHdr.GetExchange()))
       
  3040         return EFalse;
       
  3041 
       
  3042     if (!CheckFlagsL(aHdr.GetFlags()))
       
  3043         return EFalse;
       
  3044     iRecvFlags = aHdr.GetFlags();   //Save the flags for later use
       
  3045 
       
  3046     if (!CheckMessageIdL(aHdr.GetMessageId()))
       
  3047         return EFalse;
       
  3048 
       
  3049     iLengthLeft -= ISAKMP_HEADER_SIZE;  //Updates the length left in the buffer
       
  3050 
       
  3051     //EVEN stages RESPONDER, ODD ones INITIATOR
       
  3052     DEBUG_LOG(_L("Processing packet..."));
       
  3053     if (iPhase == PHASE_I)
       
  3054     {
       
  3055         switch (iStage)
       
  3056         {
       
  3057             case 1:
       
  3058                 if (!ProcessStage1L(aHdr))
       
  3059                     return EFalse;
       
  3060                 break;
       
  3061             case 2:
       
  3062                 if (!ProcessStage2L(aHdr))
       
  3063                     return EFalse;
       
  3064                 break;
       
  3065             case 3:
       
  3066                 if (iExchange == ISAKMP_EXCHANGE_ID)
       
  3067                 {
       
  3068                     if (!ProcessStage3MainL(aHdr))
       
  3069                         return EFalse;
       
  3070                 }
       
  3071                 else    //ISAKMP_EXCHANGE_AGGR
       
  3072                 {
       
  3073                     if (!ProcessStage3AggrL(aHdr))
       
  3074                         return EFalse;
       
  3075                 }
       
  3076                 break;
       
  3077             case 4:
       
  3078                 if (!ProcessStage4L(aHdr))
       
  3079                     return EFalse;
       
  3080                 break;
       
  3081             case 5:
       
  3082                 if (!ProcessStage5L(aHdr))
       
  3083                     return EFalse;
       
  3084                 break;
       
  3085             case 6:
       
  3086                 if (!ProcessStage6L(aHdr))
       
  3087                     return EFalse;
       
  3088                 break;
       
  3089             case 7:
       
  3090                 if (!ProcessStage7L(aHdr))   /* For CRACK negotiation */
       
  3091                     return EFalse;
       
  3092                 break;
       
  3093             default:
       
  3094                 return EFalse;
       
  3095         }
       
  3096     }
       
  3097     else    //PHASE_II
       
  3098     {
       
  3099         switch (iStage)
       
  3100         {
       
  3101             case 1:
       
  3102                 if (!ProcessStage1Phase2L(aHdr))
       
  3103                     return EFalse;
       
  3104                 break;
       
  3105             case 2:
       
  3106                 if (!ProcessStage2Phase2L(aHdr))
       
  3107                     return EFalse;
       
  3108                 break;
       
  3109             case 3:
       
  3110                 if (!ProcessStage3Phase2L(aHdr))
       
  3111                     return EFalse;
       
  3112                 break;
       
  3113             case 4:
       
  3114                 if (!ProcessCONNECTEDL(aHdr))
       
  3115                     return EFalse;
       
  3116                 break;
       
  3117             default:
       
  3118                 DEBUG_LOG(_L("Quick Bad Stage"));
       
  3119         }
       
  3120     }
       
  3121     return ETrue;
       
  3122 }
       
  3123 
       
  3124 //Process payloads appearing in Stage 1. Responder Role
       
  3125 TBool CIkev1Negotiation::ProcessStage1L(const ThdrISAKMP &aHdr)
       
  3126 {
       
  3127 	CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug);
       
  3128 	if (!payload)
       
  3129 	   return EFalse;	
       
  3130 
       
  3131 	CleanupStack::PushL(payload);
       
  3132 	
       
  3133     //SA Payload processing (all modes)
       
  3134     if (!ProcessSAL(payload->iSa, NULL))
       
  3135     {
       
  3136 		CleanupStack::PopAndDestroy();  //payload
       
  3137         return EFalse;
       
  3138     }
       
  3139 
       
  3140 	//Process vendor ID:s  
       
  3141 	ProcessVendorL(payload->iVids);
       
  3142 	
       
  3143     TUint16 auth_method = iChosenProposal_I.iAttrList->iAuthMethod;
       
  3144 	
       
  3145 	switch (auth_method)
       
  3146 	{
       
  3147 		case RSA_SIG:
       
  3148 		case DSS_SIG:
       
  3149 			//Process the possible CR payloads
       
  3150 			if ( !ProcessCertificateReqArrayL(payload->iCertReqs) ) {
       
  3151 				CleanupStack::PopAndDestroy();  //payload
       
  3152 				return EFalse;
       
  3153 			}
       
  3154 			//Process the possible CERT payloads
       
  3155 			if ( !ProcessCertificateArrayL(payload->iCerts) ) {
       
  3156 				CleanupStack::PopAndDestroy();  //payload
       
  3157 				return EFalse;
       
  3158 			}
       
  3159 			break;
       
  3160 
       
  3161 		default:
       
  3162 			break;
       
  3163 	}
       
  3164 
       
  3165 	
       
  3166     if (iExchange == ISAKMP_EXCHANGE_ID)
       
  3167     {
       
  3168 		if ( payload->iKe || payload->iNonce || payload->iHash || payload->iSign ||
       
  3169 			 payload->iIds->Count() )
       
  3170 		{
       
  3171 			CleanupStack::PopAndDestroy();  //payload
       
  3172 			return EFalse;
       
  3173 		}	
       
  3174     }
       
  3175     else //ISAKMP_EXCHANGE_AGGR
       
  3176     {
       
  3177 		if ( !payload->iKe || !payload->iNonce || (payload->iIds->Count() != 1) )
       
  3178 		{
       
  3179 			CleanupStack::PopAndDestroy();  //payload
       
  3180 			return EFalse;
       
  3181 		}	
       
  3182 		
       
  3183         //Key Payload processing (all modes)
       
  3184         if (!ProcessKeyL(payload->iKe))
       
  3185         {
       
  3186             CleanupStack::PopAndDestroy();  //payload
       
  3187             return EFalse;
       
  3188         }
       
  3189 		TIdentISAKMP* id_payload    = (TIdentISAKMP*)payload->iIds->At(0);  // The first ID		
       
  3190 		TNonceISAKMP* nonce_payload = (TNonceISAKMP*)payload->iNonce;
       
  3191 		
       
  3192         //Nonce Payload processing
       
  3193         if (!ProcessNonceL(nonce_payload))
       
  3194         {
       
  3195 			CleanupStack::PopAndDestroy();  //payload
       
  3196             return EFalse;
       
  3197         }
       
  3198         //ID Payload processing
       
  3199         if (!CheckIdentL(id_payload))
       
  3200         {
       
  3201 			CleanupStack::PopAndDestroy();  //payload
       
  3202 			return EFalse;
       
  3203         }
       
  3204         //Save the ident payload for HASH_I/R computing
       
  3205         delete iPeerIdentPayload;
       
  3206 		iPeerIdentPayload = NULL;
       
  3207         iPeerIdentPayloadSize = id_payload->GetLength() - sizeof(TPayloadISAKMP);
       
  3208         iPeerIdentPayload = new (ELeave) TUint8[iPeerIdentPayloadSize];
       
  3209         Mem::Copy(iPeerIdentPayload,((TUint8 *)id_payload)+sizeof(TPayloadISAKMP),iPeerIdentPayloadSize);
       
  3210         
       
  3211         if ( iNatDiscovery )
       
  3212 		{
       
  3213 		   if ( payload->iNatDs->Count() )
       
  3214 		   {	   
       
  3215                iNAT_D_Flags = iNatDiscovery->CheckDiscoveryPayloadsL(payload->iNatDs, iChosenProposal_I.iAttrList->iHashAlg,
       
  3216                                                                     (TUint8*)iCookie_I.Ptr(), (TUint8*)iCookie_R.Ptr(),
       
  3217                                                                      iLocalAddr, iLastRemoteAddr);
       
  3218 		       if ( iNAT_D_Flags )
       
  3219 			      iLastRemoteAddr.SetPort(FLOATED_IKE_PORT);
       
  3220 		   }
       
  3221 		   else
       
  3222 		   {
       
  3223 			   if ( iLastRemoteAddr.Port() == FLOATED_IKE_PORT )
       
  3224 				   iNAT_D_Flags |= LOCAL_END_NAT; 
       
  3225 		   }	   
       
  3226         }
       
  3227         
       
  3228     }//end aggressive
       
  3229 
       
  3230 				   
       
  3231     CleanupStack::PopAndDestroy();  //payload
       
  3232     iStage = 2;
       
  3233     return ETrue;
       
  3234     
       
  3235 }
       
  3236                 
       
  3237 //Process payloads appearing in Stage 3. Initiator Role
       
  3238 TBool CIkev1Negotiation::ProcessStage2L(const ThdrISAKMP &aHdr)
       
  3239 {
       
  3240 	CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug);
       
  3241 	if (!payload)
       
  3242 		return EFalse;
       
  3243 	
       
  3244 	CleanupStack::PushL(payload);
       
  3245 	
       
  3246 	iCookie_R = aHdr.GetCookieR();    //Save the responder Cookie	
       
  3247 
       
  3248     //SA Payload processing (all modes)
       
  3249     if (!ProcessSAL(payload->iSa, NULL)) {
       
  3250         CleanupStack::PopAndDestroy();  // payload
       
  3251         return EFalse;
       
  3252     }
       
  3253 
       
  3254 	ProcessVendorL(payload->iVids);
       
  3255 	
       
  3256     if ( iAutoLogin && (iLocalAddr.Family() == KAFUnspec ) ) {
       
  3257         User::LeaveIfError( iPluginSession->GetLocalAddress( iLocalAddr ) ); //No local address, get it now (used later with NAT traversal)
       
  3258     }
       
  3259 
       
  3260     //NOW we know the auth method chosen!
       
  3261     TUint16 auth_method = iChosenProposal_I.iAttrList->iAuthMethod;
       
  3262 
       
  3263     switch (auth_method)
       
  3264     {
       
  3265     case RSA_SIG:
       
  3266     case DSS_SIG:
       
  3267         //Process the possible CR payloads
       
  3268         if ( !ProcessCertificateReqArrayL(payload->iCertReqs) )
       
  3269 		{
       
  3270             CleanupStack::PopAndDestroy();  //payload
       
  3271             return EFalse;
       
  3272         }
       
  3273 	    if (!ProcessCertificateArrayL(payload->iCerts))
       
  3274 		{
       
  3275 		    CleanupStack::PopAndDestroy();  //payload
       
  3276 		    return EFalse;
       
  3277  		}
       
  3278         break;
       
  3279 		
       
  3280     default:
       
  3281 		break;
       
  3282     }
       
  3283 
       
  3284 	if (iExchange == ISAKMP_EXCHANGE_ID)
       
  3285 	{
       
  3286 		if ( payload->iKe || payload->iNonce || payload->iHash || payload->iSign ||
       
  3287 			 payload->iIds->Count() )
       
  3288 		{
       
  3289 			CleanupStack::PopAndDestroy();  //payload
       
  3290 			return EFalse;
       
  3291 		}	
       
  3292 	}
       
  3293     else //ISAKMP_EXCHANGE_AGGR
       
  3294     {
       
  3295 		if ( !payload->iKe || 
       
  3296 		     !payload->iNonce || 
       
  3297 		     (!payload->iHash && auth_method == PRE_SHARED) // hash is a must only with PSK
       
  3298 		     || (payload->iIds->Count() != 1) )
       
  3299 		{
       
  3300 			CleanupStack::PopAndDestroy();  //payload
       
  3301 			return EFalse;
       
  3302 		}	
       
  3303         //Key Payload processing (all modes)
       
  3304         if (!ProcessKeyL(payload->iKe))
       
  3305 		{
       
  3306 			CleanupStack::PopAndDestroy();  //payload			
       
  3307             return EFalse;
       
  3308 		}
       
  3309 		TIdentISAKMP* id_payload    = (TIdentISAKMP*)payload->iIds->At(0);  // The first ID		
       
  3310 		TNonceISAKMP* nonce_payload = (TNonceISAKMP*)payload->iNonce;
       
  3311 		
       
  3312 		//Nonce Payload processing
       
  3313 		if (!ProcessNonceL(nonce_payload))
       
  3314 		{
       
  3315 			CleanupStack::PopAndDestroy();  //payload
       
  3316 			return EFalse;
       
  3317 		}
       
  3318 		
       
  3319 		//ID Payload processing
       
  3320 		if (!CheckIdentL(id_payload))
       
  3321 		{
       
  3322 			CleanupStack::PopAndDestroy();  //payload
       
  3323 			return EFalse;
       
  3324 		}
       
  3325 		
       
  3326         //Save the ident payload for HASH_I/R computing
       
  3327         delete iPeerIdentPayload;
       
  3328 		iPeerIdentPayload = NULL;
       
  3329         iPeerIdentPayloadSize = id_payload->GetLength()-sizeof(TPayloadISAKMP);
       
  3330         iPeerIdentPayload = new (ELeave) TUint8[iPeerIdentPayloadSize];
       
  3331         Mem::Copy(iPeerIdentPayload,((TUint8 *)id_payload)+sizeof(TPayloadISAKMP),iPeerIdentPayloadSize);
       
  3332         
       
  3333         if (!ComputeKeysL())    //Computes the keys to be used. Needed to compute HASH_R
       
  3334 		{
       
  3335 			CleanupStack::PopAndDestroy();  //payload
       
  3336 			return EFalse;
       
  3337 		}	
       
  3338 			
       
  3339         switch (auth_method)
       
  3340         {
       
  3341         case PRE_SHARED:
       
  3342 			if (!ProcessHashL(payload->iHash))
       
  3343 			{
       
  3344 				CleanupStack::PopAndDestroy();  //payload			
       
  3345 				return EFalse;
       
  3346 			}
       
  3347 			DEBUG_LOG(_L("HASH OK!"));
       
  3348             break;
       
  3349         case RSA_SIG:
       
  3350         case DSS_SIG:
       
  3351         case IKE_A_CRACK:
       
  3352             //Signature payload processing and checking
       
  3353             if (!ProcessSignatureL(payload->iSign)) {
       
  3354 				CleanupStack::PopAndDestroy();  //payload	
       
  3355                 return EFalse;
       
  3356 			}	
       
  3357             if ( auth_method == IKE_A_CRACK ) {
       
  3358 			   CleanupStack::PopAndDestroy();  //payload					
       
  3359                return StartCRACKAuthL();
       
  3360             }
       
  3361 			else {
       
  3362 				if (!CertifyRemoteIdentityL(id_payload))
       
  3363 				{
       
  3364 					DEBUG_LOG(_L("ProcessStage2L RSA_SIG CertifyRemoteIdentityL failed"));
       
  3365 					DEBUG_LOG(_L("AUTHENTICATION_FAILED"));
       
  3366 					SetErrorStatus( KKmdIkeAuthFailedErr );
       
  3367 					SendNotifyL(AUTHENTICATION_FAILED);
       
  3368 					CleanupStack::PopAndDestroy();  //payload			
       
  3369 					return EFalse;
       
  3370 				}
       
  3371 			}	
       
  3372             break;
       
  3373 
       
  3374 		default:
       
  3375 			break;
       
  3376 			
       
  3377 		}
       
  3378 		
       
  3379 		if ( iNatDiscovery && payload->iNatDs->Count()) {
       
  3380 			iNAT_D_Flags = iNatDiscovery->CheckDiscoveryPayloadsL(payload->iNatDs, iChosenProposal_I.iAttrList->iHashAlg,
       
  3381 				                                                 (TUint8*)iCookie_I.Ptr(), (TUint8*)iCookie_R.Ptr(),
       
  3382 				                                                  iLocalAddr, iLastRemoteAddr);
       
  3383 			if ( iNAT_D_Flags )
       
  3384 				iLastRemoteAddr.SetPort(FLOATED_IKE_PORT); 
       
  3385 		}
       
  3386     }
       
  3387 	
       
  3388 	CleanupStack::PopAndDestroy();  //payload
       
  3389 	
       
  3390     iStage = 3;
       
  3391     return ETrue;
       
  3392 }
       
  3393 
       
  3394 // Process payloads appearing in Stage 4. Order NOT relevant. Only Main Mode
       
  3395 // Handles message: HDR, KE, [HASH(1),] <IDii>PubKey_r, <Ni>PubKey_r for RSAENCR
       
  3396 // Handles message: HDR, KE, Ni for the rest [CERTREQ] in certificates
       
  3397 TBool CIkev1Negotiation::ProcessStage3MainL(const ThdrISAKMP &aHdr)
       
  3398 {
       
  3399 	CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug);
       
  3400 	if (!payload)
       
  3401 		return EFalse;
       
  3402 
       
  3403 	CleanupStack::PushL(payload);
       
  3404 
       
  3405 	if ( payload->iSa || !payload->iNonce || payload->iHash || payload->iSign )
       
  3406 	{
       
  3407 		CleanupStack::PopAndDestroy();  //payload
       
  3408 		return EFalse;
       
  3409 	}	
       
  3410 	
       
  3411     TUint16 auth_method = iChosenProposal_I.iAttrList->iAuthMethod;
       
  3412 	
       
  3413     //Process payloads
       
  3414     //Main mode (ONLY)
       
  3415     //Key Payload processing (all methods)
       
  3416     if (!ProcessKeyL(payload->iKe))
       
  3417     {
       
  3418         CleanupStack::PopAndDestroy();  //payload
       
  3419         return EFalse;
       
  3420     }
       
  3421 
       
  3422     if ((auth_method == RSA_SIG) || (auth_method == DSS_SIG))
       
  3423     {
       
  3424         //Process the possible CR payloads
       
  3425         if ( !ProcessCertificateReqArrayL(payload->iCertReqs) )
       
  3426 		{
       
  3427             CleanupStack::PopAndDestroy();  //payload
       
  3428             return EFalse;
       
  3429         }
       
  3430     }
       
  3431 
       
  3432 	TNonceISAKMP* nonce_payload = (TNonceISAKMP*)payload->iNonce;
       
  3433 	
       
  3434 	ProcessVendorL(payload->iVids);
       
  3435 	
       
  3436 	if ( iNatDiscovery && payload->iNatDs->Count() )
       
  3437 	{ 
       
  3438 		iNAT_D_Flags = iNatDiscovery->CheckDiscoveryPayloadsL(payload->iNatDs, iChosenProposal_I.iAttrList->iHashAlg,
       
  3439 		                                                     (TUint8*)iCookie_I.Ptr(), (TUint8*)iCookie_R.Ptr(),
       
  3440                                                    			  iLocalAddr, iLastRemoteAddr);
       
  3441 		if ( iNAT_D_Flags )
       
  3442 			iLastRemoteAddr.SetPort(FLOATED_IKE_PORT); 
       
  3443 	}
       
  3444 	
       
  3445     //Nonce Payload processing (all methods)
       
  3446 	TBool Status = ProcessNonceL(nonce_payload);
       
  3447 	if ( Status )
       
  3448 	{
       
  3449 	   iStage = 4;
       
  3450 	}   
       
  3451 	CleanupStack::PopAndDestroy();  //payload
       
  3452 	
       
  3453     return Status;
       
  3454 }
       
  3455 
       
  3456 
       
  3457 //Process payloads appearing in 3(Aggressive). Order NOT relevant
       
  3458 TBool CIkev1Negotiation::ProcessStage3AggrL(const ThdrISAKMP &aHdr)
       
  3459 {
       
  3460 	CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug);
       
  3461 	if (!payload)
       
  3462 		return EFalse;
       
  3463 
       
  3464 	CleanupStack::PushL(payload);
       
  3465 
       
  3466     TUint16 auth_method = iChosenProposal_I.iAttrList->iAuthMethod;
       
  3467 
       
  3468     //Mode-dependent processing
       
  3469     switch (auth_method)
       
  3470     {
       
  3471     case PRE_SHARED:
       
  3472         //Hash payload processing
       
  3473         if (!ProcessHashL(payload->iHash))
       
  3474 		{
       
  3475 			CleanupStack::PopAndDestroy();  //payload			
       
  3476             return EFalse;
       
  3477 		}
       
  3478         DEBUG_LOG(_L("HASH OK!"));
       
  3479         break;
       
  3480     case RSA_SIG:
       
  3481     case DSS_SIG:
       
  3482         //Certificate payload processing
       
  3483         if (!ProcessCertificateArrayL(payload->iCerts))
       
  3484 		{
       
  3485 			CleanupStack::PopAndDestroy();  //payload
       
  3486             return EFalse;
       
  3487 		}
       
  3488         //Signature payload processing
       
  3489         if (!ProcessSignatureL(payload->iSign))
       
  3490 		{	
       
  3491 			CleanupStack::PopAndDestroy();  //payload			
       
  3492             return EFalse;
       
  3493 		}	
       
  3494         break;
       
  3495 		
       
  3496     default:
       
  3497 		break;
       
  3498     }
       
  3499 
       
  3500 	ProcessVendorL(payload->iVids);			
       
  3501 	
       
  3502 	if ( iNatDiscovery && payload->iNatDs->Count() ) { 
       
  3503 		iNAT_D_Flags = iNatDiscovery->CheckDiscoveryPayloadsL(payload->iNatDs, iChosenProposal_I.iAttrList->iHashAlg,
       
  3504 			                                                 (TUint8*)iCookie_I.Ptr(), (TUint8*)iCookie_R.Ptr(),
       
  3505 			                                                  iLocalAddr, iLastRemoteAddr);
       
  3506 		if ( iNAT_D_Flags )
       
  3507 			iLastRemoteAddr.SetPort(FLOATED_IKE_PORT); 
       
  3508 	}
       
  3509 
       
  3510 	CleanupStack::PopAndDestroy();  //payload
       
  3511 	
       
  3512     iFlags |= ISAKMP_HDR_EFLAG; //From now on encryption is used
       
  3513 	IsakmpPhase1CompletedL();
       
  3514 	iStage = 4;                 
       
  3515     return ETrue;
       
  3516 
       
  3517 }
       
  3518 
       
  3519 
       
  3520 //Process payloads appearing in Stage 5. Order NOT relevant. ONLY for MAIN Mode
       
  3521 // Preshared and signatures: HDR, KE, Nr
       
  3522 // RSA Encr. : HDR, <IDir>PubKey_i, <Nr_b>PubKey_i
       
  3523 // RSA Revised Encr. : HDR, <Nr_b>PubKey_i , <KE_b>Ke_r, <IDir>Ke_r
       
  3524 TBool CIkev1Negotiation::ProcessStage4L(const ThdrISAKMP &aHdr)
       
  3525 {
       
  3526 	CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug);
       
  3527 	if (!payload)
       
  3528 		return EFalse;
       
  3529 
       
  3530 	CleanupStack::PushL(payload);
       
  3531 
       
  3532 	if (  payload->iSa || !payload->iNonce || !payload->iKe )
       
  3533 	{
       
  3534 		CleanupStack::PopAndDestroy();  //payload
       
  3535 		return EFalse;
       
  3536 	}	
       
  3537 
       
  3538 	TUint16 auth_method = iChosenProposal_I.iAttrList->iAuthMethod;	
       
  3539 
       
  3540     if ((auth_method == RSA_SIG) || (auth_method == DSS_SIG))
       
  3541     {
       
  3542         //Process the possible CR payloads
       
  3543         if ( !ProcessCertificateReqArrayL(payload->iCertReqs) )
       
  3544 		{
       
  3545             CleanupStack::PopAndDestroy();  //payload
       
  3546             return EFalse;
       
  3547         }
       
  3548     }
       
  3549 
       
  3550     //Key Payload processing (all methods)
       
  3551     if (!ProcessKeyL(payload->iKe))
       
  3552 	{
       
  3553 		CleanupStack::PopAndDestroy();  //payload		
       
  3554         return EFalse;
       
  3555 	}
       
  3556 	if ( auth_method != PRE_SHARED ) {
       
  3557 		if (!ProcessCertificateArrayL(payload->iCerts)) {
       
  3558 			CleanupStack::PopAndDestroy();  //payload
       
  3559 			return EFalse;
       
  3560 		}
       
  3561 	}	
       
  3562 	TNonceISAKMP* nonce_payload = (TNonceISAKMP*)payload->iNonce;	
       
  3563 	
       
  3564     //Nonce Payload processing (all modes)
       
  3565 	TBool Status = ProcessNonceL(nonce_payload);
       
  3566     if (!Status)
       
  3567     {
       
  3568 		CleanupStack::PopAndDestroy();  //payload
       
  3569         return EFalse;
       
  3570     }
       
  3571 	ProcessVendorL(payload->iVids);
       
  3572 	
       
  3573 	if ( iNatDiscovery && payload->iNatDs->Count() )
       
  3574 	{ 
       
  3575 		iNAT_D_Flags = iNatDiscovery->CheckDiscoveryPayloadsL(payload->iNatDs, iChosenProposal_I.iAttrList->iHashAlg,
       
  3576 		                                                   	 (TUint8*)iCookie_I.Ptr(), (TUint8*)iCookie_R.Ptr(),
       
  3577 			                                                  iLocalAddr, iLastRemoteAddr);
       
  3578 		if ( iNAT_D_Flags )
       
  3579 			iLastRemoteAddr.SetPort(FLOATED_IKE_PORT); 
       
  3580 	}
       
  3581 
       
  3582     if ( auth_method == IKE_A_CRACK )
       
  3583 	{
       
  3584        /*---------------------------------------------------
       
  3585         * Process message: HDR, [CERT], KEr, Nr, SIG
       
  3586         * - Verify CRACK signature and if OK
       
  3587         * - Initialize CRACK authentication
       
  3588         *---------------------------------------------------*/
       
  3589 		Status = ComputeKeysL();
       
  3590         if ( Status )  //Generates keying material for encryption stages
       
  3591 		{
       
  3592 			Status = ProcessSignatureL(payload->iSign); 
       
  3593 			if ( Status ) //Signature payload processing and checking
       
  3594 			{
       
  3595 				Status = StartCRACKAuthL();   			   
       
  3596 			} 	   
       
  3597 		}
       
  3598     }
       
  3599 	else
       
  3600 	{
       
  3601 	    iStage = 5;	    
       
  3602 	}	
       
  3603 
       
  3604 	CleanupStack::PopAndDestroy();  //payload			
       
  3605     return Status;
       
  3606 }
       
  3607 
       
  3608 
       
  3609 //Process payloads appearing in Stage 6. Order NOT relevant
       
  3610 TBool CIkev1Negotiation::ProcessStage5L(const ThdrISAKMP &aHdr)
       
  3611 {
       
  3612 	CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug);
       
  3613 	if (!payload)
       
  3614 		return EFalse;
       
  3615 
       
  3616 	CleanupStack::PushL(payload);
       
  3617 	if (  payload->iSa || payload->iNonce || payload->iKe )
       
  3618 	{
       
  3619 		CleanupStack::PopAndDestroy();  //payload
       
  3620 		return EFalse;
       
  3621 	}	
       
  3622 
       
  3623     TUint16 auth_method      = iChosenProposal_I.iAttrList->iAuthMethod;
       
  3624 	TIdentISAKMP* id_payload = NULL;
       
  3625 	// ID Payload processing (all modes)
       
  3626 	if ( payload->iIds->Count() != 1 )
       
  3627 	{
       
  3628 		CleanupStack::PopAndDestroy();  //payload
       
  3629 		return EFalse;
       
  3630 	}
       
  3631 	id_payload = (TIdentISAKMP*)payload->iIds->At(0);  // The first ID						
       
  3632 	if (!CheckIdentL(id_payload))
       
  3633 	{
       
  3634 		CleanupStack::PopAndDestroy();  //payload						
       
  3635 		return EFalse;
       
  3636 	}	
       
  3637 		//Save the ident payload for HASH_I/R computing
       
  3638 	delete iPeerIdentPayload;
       
  3639 	iPeerIdentPayload = NULL;		
       
  3640 	iPeerIdentPayloadSize=id_payload->GetLength()-sizeof(TPayloadISAKMP);
       
  3641 	iPeerIdentPayload = new (ELeave) TUint8[iPeerIdentPayloadSize];
       
  3642 	Mem::Copy(iPeerIdentPayload,((TUint8 *)id_payload)+sizeof(TPayloadISAKMP),iPeerIdentPayloadSize);
       
  3643 
       
  3644     //Mode-dependent processing
       
  3645     switch (auth_method)
       
  3646     {
       
  3647     case PRE_SHARED:
       
  3648         //Hash payload processing
       
  3649         if (!ProcessHashL(payload->iHash))
       
  3650 		{
       
  3651 			CleanupStack::PopAndDestroy();  //payload			
       
  3652             return EFalse;
       
  3653 		}
       
  3654 		DEBUG_LOG(_L("HASH OK!"));		
       
  3655         break;
       
  3656     case RSA_SIG:
       
  3657     case DSS_SIG:
       
  3658         //Certificate payload processing
       
  3659         if (!ProcessCertificateArrayL(payload->iCerts))
       
  3660 		{
       
  3661 			CleanupStack::PopAndDestroy();  //payload									
       
  3662             return EFalse;
       
  3663 		}
       
  3664 		if (!CertifyRemoteIdentityL(id_payload))
       
  3665 		{
       
  3666     		DEBUG_LOG(_L("ProcessStage5L RSA_SIG CertifyRemoteIdentityL failed"));
       
  3667 			DEBUG_LOG(_L("AUTHENTICATION_FAILED"));
       
  3668 			SetErrorStatus( KKmdIkeAuthFailedErr );
       
  3669 			SendNotifyL(AUTHENTICATION_FAILED);
       
  3670 			CleanupStack::PopAndDestroy();  //payload			
       
  3671 			return EFalse;
       
  3672 		}
       
  3673         //Signature payload processing and checking
       
  3674         if (!ProcessSignatureL(payload->iSign))
       
  3675 		{
       
  3676 			CleanupStack::PopAndDestroy();  //payload
       
  3677             return EFalse;
       
  3678 		}
       
  3679 		//Process the possible CR payloads (needed if we are responder)
       
  3680 		if ( iRole == RESPONDER )
       
  3681 		{	
       
  3682 		   if ( !ProcessCertificateReqArrayL(payload->iCertReqs) )
       
  3683 		   {
       
  3684 			  CleanupStack::PopAndDestroy();  //payload
       
  3685 			  return EFalse;
       
  3686 		   }
       
  3687 		   if ( !iOwnCert ) 
       
  3688 			   ReadOwnCertL(); // Peer does not required a specific cert. Get any
       
  3689 		}   
       
  3690         break;
       
  3691 		
       
  3692     default:
       
  3693 		break;
       
  3694     }//end switch
       
  3695 
       
  3696     // Process notification payloads
       
  3697 	TInt i = 0;
       
  3698 	while ( i < payload->iNotifs->Count() ) {
       
  3699 		if (!ProcessNotificationL(payload->iNotifs->At(i)))
       
  3700 		{
       
  3701 			CleanupStack::PopAndDestroy();  //payload
       
  3702 			return EFalse;
       
  3703 		}		
       
  3704         i ++; 		
       
  3705 	}	
       
  3706 
       
  3707 	ProcessVendorL(payload->iVids);
       
  3708 
       
  3709 	CleanupStack::PopAndDestroy();  //payload			
       
  3710 	
       
  3711     if (iExchange == ISAKMP_EXCHANGE_ID)
       
  3712          iStage = 6;
       
  3713     else iStage = 3;
       
  3714 
       
  3715     return ETrue;
       
  3716 }
       
  3717 
       
  3718 
       
  3719 //Process payloads appearing in Stage 6(Main)  Order NOT relevant
       
  3720 TBool CIkev1Negotiation::ProcessStage6L(const ThdrISAKMP &aHdr)
       
  3721 {
       
  3722 	CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug);
       
  3723 	if (!payload)
       
  3724 		return EFalse;
       
  3725 
       
  3726 	CleanupStack::PushL(payload);
       
  3727 	if (  payload->iSa || payload->iNonce || payload->iKe )
       
  3728 	{
       
  3729 		CleanupStack::PopAndDestroy();  //payload
       
  3730 		return EFalse;
       
  3731 	}	
       
  3732 	
       
  3733 
       
  3734     TUint16 auth_method = iChosenProposal_I.iAttrList->iAuthMethod;
       
  3735 	TIdentISAKMP* id_payload = NULL;
       
  3736     //ID Payload processing (all modes)
       
  3737 	if ( payload->iIds->Count() != 1 )
       
  3738 	{
       
  3739 		CleanupStack::PopAndDestroy();  //payload
       
  3740 		return EFalse;
       
  3741 	}
       
  3742 	id_payload = (TIdentISAKMP*)payload->iIds->At(0);  // The first ID						
       
  3743 	if (!CheckIdentL(id_payload))
       
  3744 	{
       
  3745 		CleanupStack::PopAndDestroy();  //payload
       
  3746 		return EFalse;
       
  3747 	}	
       
  3748 	//Save the ident payload for HASH_I/R computing
       
  3749     delete iPeerIdentPayload;
       
  3750 	iPeerIdentPayload = NULL;		
       
  3751 	iPeerIdentPayloadSize=id_payload->GetLength()-sizeof(TPayloadISAKMP);
       
  3752 	iPeerIdentPayload = new (ELeave) TUint8[iPeerIdentPayloadSize];
       
  3753 	Mem::Copy(iPeerIdentPayload,((TUint8 *)id_payload)+sizeof(TPayloadISAKMP),iPeerIdentPayloadSize);
       
  3754 
       
  3755     //Mode-dependent processing
       
  3756     switch (auth_method)
       
  3757     {
       
  3758     case PRE_SHARED:
       
  3759         //Hash payload processing
       
  3760         if (!ProcessHashL(payload->iHash))
       
  3761 		{
       
  3762 			CleanupStack::PopAndDestroy();  //payload			
       
  3763             return EFalse;
       
  3764 		}
       
  3765 		DEBUG_LOG(_L("HASH OK!"));		
       
  3766         break;
       
  3767     case RSA_SIG:
       
  3768     case DSS_SIG:
       
  3769 		//Certificate payload processing
       
  3770 		if (!ProcessCertificateArrayL(payload->iCerts))
       
  3771 		{
       
  3772 			CleanupStack::PopAndDestroy();  //payload									
       
  3773 			return EFalse;
       
  3774 		}
       
  3775 		if (!CertifyRemoteIdentityL(id_payload))
       
  3776 		{
       
  3777 			DEBUG_LOG(_L("ProcessStage6L RSA_SIG CertifyRemoteIdentityL failed"));
       
  3778 			DEBUG_LOG(_L("AUTHENTICATION_FAILED"));
       
  3779 			SetErrorStatus( KKmdIkeAuthFailedErr );
       
  3780 			SendNotifyL(AUTHENTICATION_FAILED);
       
  3781 			CleanupStack::PopAndDestroy();  //payload			
       
  3782 			return EFalse;
       
  3783 		}
       
  3784 		//Signature payload processing and checking
       
  3785 		if (!ProcessSignatureL(payload->iSign))
       
  3786 		{
       
  3787 			CleanupStack::PopAndDestroy();  //payload
       
  3788 			return EFalse;
       
  3789 		}
       
  3790         break;
       
  3791     default:
       
  3792         break;
       
  3793     }
       
  3794 
       
  3795 	// Process notification payloads
       
  3796 	TInt i = 0;
       
  3797 	while ( i < payload->iNotifs->Count() ) {
       
  3798 		if (!ProcessNotificationL(payload->iNotifs->At(i)))
       
  3799 		{
       
  3800 			CleanupStack::PopAndDestroy();  //payload
       
  3801 			return EFalse;
       
  3802 		}		
       
  3803 		i ++; 		
       
  3804 	}	
       
  3805 
       
  3806 	ProcessVendorL(payload->iVids);	
       
  3807     // Internal address payload processing
       
  3808     ProcessIntAddrL(payload->iIaddr);
       
  3809 
       
  3810 	CleanupStack::PopAndDestroy();  //payload	
       
  3811 
       
  3812 	return IsakmpPhase1CompletedL();	
       
  3813 	
       
  3814 }
       
  3815 
       
  3816 //Process payloads appearing in Stage 7 = CRACK authentication going
       
  3817 TBool CIkev1Negotiation::ProcessStage7L(const ThdrISAKMP &aHdr)
       
  3818 {
       
  3819 TBool status = ETrue;
       
  3820 TInt  crack_status;
       
  3821 
       
  3822     if ( iCRACKneg ) {
       
  3823        crack_status = iCRACKneg->ExecuteCRACKMsgL(aHdr);
       
  3824        
       
  3825        switch ( crack_status ) {
       
  3826            
       
  3827            case CRACK_SUCCESS:
       
  3828                /*-------------------------------------------------------
       
  3829                 * CRACK authentication has been succesfully completed
       
  3830                 * Take actions to start Quick mode negotiation
       
  3831                 *------------------------------------------------------*/
       
  3832                delete iCRACKneg;
       
  3833                iCRACKneg = NULL;
       
  3834                iLastIV.Copy(iIV);  //Saves last IV in Phase 1
       
  3835                DEBUG_LOG(_L("Last IV Saved!"));
       
  3836                IsakmpPhase1CompletedL();
       
  3837                break;
       
  3838                
       
  3839            case CRACK_CONTINUE:
       
  3840                /*----------------------------------------------------------
       
  3841                 * CRACK authentication continues, no further actions needed
       
  3842                 *----------------------------------------------------------*/
       
  3843                break;
       
  3844 
       
  3845            case CRACK_IGNORE_MSG:
       
  3846                /*----------------------------------------------------------
       
  3847                 * CRACK authentication continues, received message ignored
       
  3848                 *----------------------------------------------------------*/
       
  3849                status = EFalse;            
       
  3850                break;
       
  3851                
       
  3852            default:
       
  3853                /*----------------------------------------------------------
       
  3854                 * CRACK authentication failed, negotiation failed
       
  3855                 *----------------------------------------------------------*/
       
  3856 			   LOG_KMD_EVENT( MKmdEventLoggerIf::KLogError,
       
  3857 			                  R_VPN_MSG_VPN_GW_AUTH_FAIL,
       
  3858 			                  KKmdIkeAuthFailedErr,
       
  3859 			                  iPluginSession->VpnIapId(),
       
  3860 			                  &iRemoteAddr );		   			   
       
  3861                status    = EFalse;                         
       
  3862 			   SetErrorStatus(KKmdIkeAuthFailedErr);
       
  3863                AcquireSAErrorResponse(KKmdIkeAuthFailedErr);
       
  3864                break;
       
  3865 
       
  3866        }       
       
  3867     }
       
  3868 
       
  3869     return status;
       
  3870 }
       
  3871 
       
  3872 //Called as a RESPONDER for PHASE_II
       
  3873 //Checks HASH(1),SA,KE,NONCE,[ID,ID] from INITIATOR
       
  3874 TBool CIkev1Negotiation::ProcessStage1Phase2L(const ThdrISAKMP &aHdr)
       
  3875 {
       
  3876 	CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug);
       
  3877 	if (!payload)
       
  3878 		return EFalse;
       
  3879 
       
  3880 	CleanupStack::PushL(payload);
       
  3881 	
       
  3882 	if (  !payload->iSa || !payload->iNonce )
       
  3883 	{
       
  3884 		CleanupStack::PopAndDestroy();  //payload
       
  3885 		return EFalse;
       
  3886 	}	
       
  3887 	
       
  3888     //Payload Processing
       
  3889 
       
  3890     CProposal_IIList *recv_proposals = new (ELeave) CProposal_IIList(1);    //, *prop
       
  3891     CleanupStack::PushL(recv_proposals);
       
  3892 
       
  3893     //SA
       
  3894     if (!ProcessSAL(payload->iSa, (TUint8 *)recv_proposals))
       
  3895     {
       
  3896         CleanupStack::PopAndDestroy(2); //recv_proposals + payload
       
  3897         return EFalse;
       
  3898     }
       
  3899 
       
  3900     //ID payloads (if existing)
       
  3901 	if ( payload->iIds->Count() == 2 )
       
  3902 	{
       
  3903        if (!ProcessStage1_II_IDsL(payload->iIds->At(0), payload->iIds->At(1), recv_proposals))
       
  3904        {
       
  3905           CleanupStack::PopAndDestroy(2); //recv_proposals + payload
       
  3906           return EFalse;
       
  3907        }
       
  3908 	}
       
  3909 	else if ( payload->iIds->Count() != 0 )
       
  3910 	{
       
  3911 		DEBUG_LOG(_L("Unsupported Phase II ID payload count"));		
       
  3912 		CleanupStack::PopAndDestroy(2); //recv_proposals + payload
       
  3913 		return EFalse;
       
  3914 	}	
       
  3915     //After ID to know what address to search in the "SAD"
       
  3916 	TInt err = BuildProposals2L();
       
  3917     if (err != KErrNone)
       
  3918     {
       
  3919         DEBUG_LOG(_L("NO_PROPOSAL_CHOSEN: No policy matching"));
       
  3920         SendNotifyL(NO_PROPOSAL_CHOSEN);
       
  3921         CleanupStack::PopAndDestroy(2); //recv_proposals + payload
       
  3922         return EFalse;
       
  3923     }
       
  3924 
       
  3925     //Contains the transform nums matching if multiple proposals
       
  3926     CTransModifierList *trans_array = new (ELeave) CTransModifierList(1);
       
  3927     CleanupStack::PushL(trans_array);
       
  3928 
       
  3929     TInt num = iProposal_IIList->MultiMatchL(recv_proposals, iRole == RESPONDER, trans_array);//If RESPONDER relaxed comparison (no lifetimes checked)
       
  3930     iProposalNum = num; // Set to num not 1
       
  3931 #ifdef _DEBUG
       
  3932     TBuf<128> err_buf;
       
  3933 #endif    
       
  3934     if (num < 0)
       
  3935     {
       
  3936 #ifdef _DEBUG    
       
  3937         err_buf.Copy(_L("NO_PROPOSAL_CHOSEN: Phase II proposal not accepted - "));
       
  3938         AppendAttributeError(num, err_buf);
       
  3939         DEBUG_LOG(err_buf);
       
  3940 #endif        
       
  3941         SetErrorStatus( KKmdIkeNoProposalErr );
       
  3942         SendNotifyL(NO_PROPOSAL_CHOSEN);
       
  3943         CleanupStack::PopAndDestroy(3); //transarray + recv_proposals + payload
       
  3944         return EFalse;
       
  3945     }
       
  3946 
       
  3947     //Copy the chosen transform
       
  3948     //Actually is the same one as recv_proposals because we should always receive a single proposal with a single transform.
       
  3949     CreateChosenProposalL(recv_proposals, num, trans_array);
       
  3950 
       
  3951     CleanupStack::PopAndDestroy(2); //transarray + recv_proposals
       
  3952 
       
  3953     //Process the possible NOTIFICATION payloads
       
  3954     for (TInt i = 0; i < payload->iNotifs->Count(); i++)
       
  3955     {
       
  3956         if (!ProcessNotificationL(payload->iNotifs->At(i)))
       
  3957         {
       
  3958             CleanupStack::PopAndDestroy();  //payload
       
  3959             return EFalse;
       
  3960         }
       
  3961     }
       
  3962     
       
  3963     if (!ProcessNonceL(payload->iNonce))
       
  3964 	{
       
  3965 		CleanupStack::PopAndDestroy();  //payload		
       
  3966         return EFalse;
       
  3967 	}
       
  3968     //HASH
       
  3969     if (!ProcessHash2L(aHdr, payload->iHash, payload->iPadding))
       
  3970 	{
       
  3971 		CleanupStack::PopAndDestroy();  //payload				
       
  3972         return EFalse;
       
  3973 	} 
       
  3974     
       
  3975     if (!ProcessKeyL(payload->iKe))
       
  3976 	{
       
  3977 		CleanupStack::PopAndDestroy();  //payload								
       
  3978         return EFalse;
       
  3979 	}
       
  3980 
       
  3981 	ProcessVendorL(payload->iVids);		
       
  3982 	
       
  3983     if ( iNatDiscovery ) {
       
  3984        iNAT_D_Flags |= iNatDiscovery->GetPeerOriginalAddress(payload->iNatOa, iRemoteOriginalAddr, iChosenProp_IIList);
       
  3985     }
       
  3986 	
       
  3987 	CleanupStack::PopAndDestroy();  //notif_payload_array	
       
  3988     iStage = 2;
       
  3989     return ETrue;
       
  3990 }
       
  3991 
       
  3992 //Creates a new proposal list from a selected part of another list (Certain proposal and transforms) 
       
  3993 void CIkev1Negotiation::CreateChosenProposalL(CProposal_IIList* aPropList, TInt aPropNum, CTransModifierList *aTransArray)
       
  3994 {
       
  3995 
       
  3996     CProposal_II *prop, *new_propII;
       
  3997     TAttrib_II *attr_II;
       
  3998     TChosenAttrib_II *new_attr_II;
       
  3999     TInt count = aPropList->Count();
       
  4000     TInt i = 0;
       
  4001     TInt j = 0;
       
  4002 
       
  4003     //
       
  4004     // Find selected proroposal from list
       
  4005     //
       
  4006     while ( i < count)
       
  4007     {
       
  4008         if (aPropList->At(i)->iProposalNum == aPropNum)
       
  4009             break;
       
  4010         i ++;
       
  4011     }
       
  4012     
       
  4013     TTransModifier *tmodif;
       
  4014     TInt64 own_time, own_bytes, peer_time, peer_bytes;
       
  4015     delete iChosenProp_IIList;  //Must be erased because can contain data from previous retransmissions
       
  4016 	iChosenProp_IIList = NULL;	
       
  4017     iChosenProp_IIList = new (ELeave) CProposal_IIList(1);
       
  4018     while ( i < count )
       
  4019     {
       
  4020         prop = aPropList->At(i);
       
  4021         if ( prop->iProposalNum != aPropNum)
       
  4022             break; // Stop, another Proposal 
       
  4023 
       
  4024         new_propII = new (ELeave) CProposal_II();
       
  4025         CleanupStack::PushL(new_propII);
       
  4026         new_propII->ConstructL(1);
       
  4027         iChosenProp_IIList->AppendL(new_propII);
       
  4028         CleanupStack::Pop();    //new_propII safe
       
  4029 
       
  4030         new_propII->iProtocol = prop->iProtocol;
       
  4031         new_propII->iNumTransforms = 1; //We only choose 1 transform for each proposal
       
  4032         new_propII->iProposalNum   = (TUint8)aPropNum;
       
  4033         new_propII->iSPI.Copy(prop->iSPI);
       
  4034         tmodif = aTransArray->At(j);
       
  4035         new_propII->iReplayWindowLength = tmodif->iReplayWindowLength;
       
  4036 
       
  4037         attr_II = prop->iAttrList->At(tmodif->iTransNum);   //look for the chosen transform in the prop
       
  4038         ComputeLifetimes_II(tmodif->iReducedLifeSecs, tmodif->iReducedLifeKBytes, own_time, own_bytes);
       
  4039         ComputeLifetimes_II(attr_II->iLifeDurationSecs, attr_II->iLifeDurationKBytes, peer_time, peer_bytes);
       
  4040         
       
  4041         //Only copy the chosen transform
       
  4042         new_attr_II = new (ELeave) TChosenAttrib_II();
       
  4043         CleanupStack::PushL(new_attr_II);
       
  4044         new_attr_II->Copy(*attr_II);
       
  4045         if ((peer_time > own_time) && (own_time != 0))
       
  4046         {
       
  4047             new_attr_II->iReducedLifeSecs.Set(tmodif->iReducedLifeSecs);
       
  4048             DEBUG_LOG1(_L("Lifetime bigger than the one set. Reducing to %d"), own_time);
       
  4049         }
       
  4050         else
       
  4051             new_attr_II->iReducedLifeSecs.Set(NULL, 0);
       
  4052             
       
  4053         if ((peer_bytes > own_bytes) && (own_bytes != 0))
       
  4054         {
       
  4055             new_attr_II->iReducedLifeKBytes.Set(tmodif->iReducedLifeKBytes);
       
  4056             DEBUG_LOG1(_L("Lifesize bigger than the one set. Reducing to %d"), own_bytes);
       
  4057         }
       
  4058         else
       
  4059             new_attr_II->iReducedLifeKBytes.Set(NULL, 0);
       
  4060 
       
  4061         new_propII->iAttrList->AppendL(new_attr_II);
       
  4062         CleanupStack::Pop();    //new_attrII safe
       
  4063 
       
  4064         j++;  // Next transform modifer
       
  4065         i++;  // Next proposal
       
  4066         
       
  4067     }
       
  4068 }
       
  4069 
       
  4070 
       
  4071 //Called as a INITIATOR for PHASE_II
       
  4072 //Checks HASH(1),SA, ,NONCE,[KE] [ID,ID] from RESPONDER
       
  4073 TBool CIkev1Negotiation::ProcessStage2Phase2L(const ThdrISAKMP &aHdr)
       
  4074 {
       
  4075 	CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug);
       
  4076 	if (!payload)
       
  4077 		return EFalse;
       
  4078 
       
  4079 	CleanupStack::PushL(payload);
       
  4080 
       
  4081 	if (  !payload->iSa || !payload->iNonce  )
       
  4082 	{
       
  4083 		CleanupStack::PopAndDestroy();  //payload
       
  4084 		return EFalse;
       
  4085 	}	
       
  4086 
       
  4087     CProposal_IIList *recv_proposals = new (ELeave) CProposal_IIList(1);
       
  4088     CleanupStack::PushL(recv_proposals);
       
  4089 
       
  4090 	//SA
       
  4091 	if (!ProcessSAL(payload->iSa, (TUint8 *)recv_proposals))
       
  4092 	{
       
  4093 		CleanupStack::PopAndDestroy(2); //recv_proposals + payload
       
  4094 		return EFalse;
       
  4095 	}
       
  4096 
       
  4097 	//ID payloads (if existing)
       
  4098 	if ( payload->iIds->Count() == 2 )
       
  4099 	{
       
  4100 		if (!ProcessStage2_II_IDsL(payload->iIds->At(0), payload->iIds->At(1)))
       
  4101 		{
       
  4102 			CleanupStack::PopAndDestroy(2); //recv_proposals + payload
       
  4103 			return EFalse;
       
  4104 		}
       
  4105 	}
       
  4106 	else if ( payload->iIds->Count() != 0 )
       
  4107 	{
       
  4108 		DEBUG_LOG(_L("Unsupported Phase II ID payload count"));		
       
  4109 				CleanupStack::PopAndDestroy(2); //recv_proposals + payload
       
  4110 		return EFalse;
       
  4111 	}	
       
  4112 	
       
  4113     //Contains the transform nums matching if multiple proposals
       
  4114     CTransModifierList *trans_array = new (ELeave) CTransModifierList(1);
       
  4115     CleanupStack::PushL(trans_array);
       
  4116 
       
  4117     //Check the received proposals match the proposed one (Got from
       
  4118     //acquire msg.) 
       
  4119    	TInt num = iProposal_IIList->MultiMatchL(recv_proposals, iRole == RESPONDER, trans_array);//If RESPONDER relaxed comparison (no lifetimes checked)
       
  4120 #ifdef _DEBUG   	
       
  4121     TBuf<128> err_buf;
       
  4122 #endif    
       
  4123     if (num < 0)
       
  4124     {
       
  4125 #ifdef _DEBUG    
       
  4126         err_buf.Copy(_L("BAD_PROPOSAL_SYNTAX: Phase II reply doesn't match proposal - "));
       
  4127         AppendAttributeError(num, err_buf);
       
  4128         DEBUG_LOG(err_buf);
       
  4129 #endif        
       
  4130         SetErrorStatus( KKmdIkeNegotFailed );
       
  4131         SendNotifyL(BAD_PROPOSAL_SYNTAX);
       
  4132         CleanupStack::PopAndDestroy(3); //transarray + recv_proposals + payload
       
  4133         return EFalse;
       
  4134     }
       
  4135     // iProposalNum set to correspond local proposal numbering
       
  4136     iProposalNum = trans_array->At(0)->iPropNum; 
       
  4137     //Copy the chosen transform
       
  4138     CreateChosenProposalL(recv_proposals, num, trans_array);
       
  4139 
       
  4140     CleanupStack::PopAndDestroy(2); //transarray + recv_proposals
       
  4141 
       
  4142 	//Process the possible NOTIFICATION payloads
       
  4143 	for (TInt i = 0; i < payload->iNotifs->Count(); i++)
       
  4144 	{
       
  4145 		if (!ProcessNotificationL(payload->iNotifs->At(i)))
       
  4146 		{
       
  4147 			CleanupStack::PopAndDestroy();  //payload
       
  4148 			return EFalse;
       
  4149 		}
       
  4150 	}
       
  4151 	//NONCE
       
  4152    	if (!ProcessNonceL(payload->iNonce))
       
  4153    	{
       
  4154     	CleanupStack::PopAndDestroy();  //payload		
       
  4155 	    return EFalse;
       
  4156 	}
       
  4157 	//HASH
       
  4158 	if (!ProcessHash2L(aHdr, payload->iHash, payload->iPadding))
       
  4159 	{
       
  4160 		CleanupStack::PopAndDestroy();  //payload				
       
  4161 		return EFalse;
       
  4162 	} 
       
  4163 	//KEY (if present (PFS))
       
  4164 	if (!ProcessKeyL(payload->iKe))
       
  4165 	{
       
  4166 	    SetErrorStatus( KKmdIkeNegotFailed );
       
  4167 		SendNotifyL(PAYLOAD_MALFORMED);					
       
  4168 		CleanupStack::PopAndDestroy();  //payload
       
  4169 		return EFalse;
       
  4170 	}   
       
  4171 
       
  4172 	ProcessVendorL(payload->iVids);
       
  4173 	
       
  4174 	if ( iNatDiscovery ) {
       
  4175 		iNAT_D_Flags |= iNatDiscovery->GetPeerOriginalAddress(payload->iNatOa, iRemoteOriginalAddr, iChosenProp_IIList);
       
  4176 	}
       
  4177 
       
  4178     if ( iRecvFlags & ISAKMP_HDR_CFLAG )   //Commit Bit set       
       
  4179     {
       
  4180         iFlags |= ISAKMP_HDR_CFLAG; //Sets the Commit bit if this side set it else
       
  4181         DEBUG_LOG(_L("SAD update delayed until CONNECTED received"));
       
  4182     }
       
  4183 
       
  4184 	CleanupStack::PopAndDestroy();  //payload				
       
  4185     iStage = 3;
       
  4186     return ETrue;
       
  4187 
       
  4188 }
       
  4189 
       
  4190 TBool CIkev1Negotiation::ProcessStage3Phase2L(const ThdrISAKMP &aHdr)
       
  4191 {
       
  4192 	CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug);
       
  4193 	if (!payload)
       
  4194 		return EFalse;
       
  4195 
       
  4196 	CleanupStack::PushL(payload);
       
  4197 
       
  4198 	if ( payload->iSa || payload->iNonce || payload->iKe || payload->iIds->Count() != 0 ) 
       
  4199 	{
       
  4200 		CleanupStack::PopAndDestroy();  //payload
       
  4201 		return EFalse;
       
  4202 	}	
       
  4203 	
       
  4204     //Hash Payload
       
  4205 	TBool Status = ProcessHash2L(aHdr, payload->iHash, payload->iPadding);
       
  4206     if ( Status )
       
  4207 	{
       
  4208        	//END OF THE PHASE II (Quick mode) negotiation.
       
  4209 		//Now we need to update the PFKEY SA database
       
  4210 		ProcessVendorL(payload->iVids);				
       
  4211 		UpdateSADatabaseL();
       
  4212 		iStage = 4;
       
  4213 	}
       
  4214 	CleanupStack::PopAndDestroy();  //payload		
       
  4215     return Status;
       
  4216 }
       
  4217 
       
  4218 TBool CIkev1Negotiation::ProcessCONNECTEDL(const ThdrISAKMP &aHdr)
       
  4219 {
       
  4220 	CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug);
       
  4221 	if (!payload)
       
  4222 		return EFalse;
       
  4223 
       
  4224 	CleanupStack::PushL(payload);
       
  4225 
       
  4226 	if ( !payload->iHash || (payload->iNotifs->Count() != 1) || payload->iSa ||
       
  4227 		 payload->iNonce || payload->iKe || (payload->iIds->Count() != 0) ) 
       
  4228 	{
       
  4229 		DEBUG_LOG(_L("PAYLOAD_MALFORMED (no hash or notfic payload)"));
       
  4230 		SetErrorStatus( KKmdIkeNegotFailed );
       
  4231 		SendNotifyL(PAYLOAD_MALFORMED);
       
  4232 		CleanupStack::PopAndDestroy();  //payload
       
  4233 		return EFalse;
       
  4234 	}	
       
  4235 
       
  4236     //Checks if the hash value is OK. Here because need the
       
  4237     //notification payload
       
  4238 	const TNotificationISAKMP* notif_payload = payload->iNotifs->At(0);
       
  4239 	TBool Status = VerifyInformationalHashL(payload->iHash, notif_payload, iMessageId);	 
       
  4240     if ( Status )
       
  4241     {  //Hash OK
       
  4242 		if ((notif_payload->GetDOI() == IPSEC_DOI) && (notif_payload->GetMsgType() == CONNECTED))
       
  4243 		{
       
  4244 			//END OF THE PHASE II (Quick mode) negotiation.
       
  4245 			//Now we need to update the PFKEY SA database
       
  4246 			DEBUG_LOG(_L("CONNECTED message received. Updating SAD"));
       
  4247 			UpdateSADatabaseL();
       
  4248 			iStage = 5;			
       
  4249 		}
       
  4250     }
       
  4251     else   
       
  4252     {
       
  4253 		DEBUG_LOG(_L("AUTHENTICATION_FAILED (Informational hash)"));
       
  4254 		SetErrorStatus( KKmdIkeAuthFailedErr );
       
  4255 		SendNotifyL(AUTHENTICATION_FAILED);
       
  4256     }
       
  4257 	CleanupStack::PopAndDestroy();  //payload		
       
  4258     return Status;
       
  4259 }
       
  4260 
       
  4261 //returns KErrNone if OK, otherwise error already treated.
       
  4262 TBool CIkev1Negotiation::ProcessSAL(const TSAISAKMP *aSA, TUint8 *aRecvProposals)
       
  4263 {
       
  4264     //payload not present
       
  4265     if (!aSA)
       
  4266     {
       
  4267         DEBUG_LOG(_L("NO SA PAYLOAD"));
       
  4268         SetErrorStatus( KKmdIkeNegotFailed );
       
  4269         SendNotifyL(PAYLOAD_MALFORMED);
       
  4270         return EFalse;
       
  4271     }
       
  4272 
       
  4273     //requires a special length check to know the proposals and transforms are not bigger than 
       
  4274     //the size specified in th SA
       
  4275     TUint32 SALengthLeft = aSA->GetLength() - aSA->Size();
       
  4276 
       
  4277     TUint8 next_payload = aSA->GetPayload();
       
  4278     if ((next_payload == ISAKMP_PAYLOAD_P) || (next_payload == ISAKMP_PAYLOAD_T))
       
  4279     {
       
  4280         DEBUG_LOG(_L("INVALID_PAYLOAD_TYPE (Bad next payload for the SA)"));
       
  4281         SetErrorStatus( KKmdIkeNegotFailed );
       
  4282         SendNotifyL(INVALID_PAYLOAD_TYPE);   // Payloads and transforms are processed as a part of the SA,
       
  4283         return EFalse;
       
  4284     }
       
  4285 
       
  4286     TUint32 doi=aSA->GetDOI();
       
  4287     if (!CheckDOI(doi))
       
  4288     {
       
  4289         DEBUG_LOG(_L("DOI_NOT_SUPPORTED in SA payload"));
       
  4290         SetErrorStatus( KKmdIkeNegotFailed );
       
  4291         SendNotifyL(DOI_NOT_SUPPORTED);  //send the informational exchange
       
  4292         return EFalse;
       
  4293     }
       
  4294 
       
  4295     if (iStage == 1)
       
  4296         iDOI = doi;
       
  4297 
       
  4298     //Process SITuation depending on DOI. In this implementation always is IPSEC DOI
       
  4299     if (!CheckSituationL(aSA->GetSIT()))
       
  4300         return EFalse;
       
  4301 
       
  4302     if (aSA->HasLDId()) //If no Labeled Domain Identifier no more processing for the SA
       
  4303     {
       
  4304         DEBUG_LOG(_L("Label Domain Identifier (LDI) not supported"));
       
  4305         return EFalse;
       
  4306     }
       
  4307     
       
  4308     if (iPhase==PHASE_I)    //Only used in Phase_I. PHASE_II hashs check it directly from received paylaod
       
  4309     {
       
  4310         //Store the SA payload for further calculations in Hash.
       
  4311         if (iRole==RESPONDER)
       
  4312         {
       
  4313             iSAPayloadSize = aSA->GetLength()-sizeof(TPayloadISAKMP);
       
  4314             delete iSAPayload;
       
  4315 			iSAPayload = NULL;
       
  4316             iSAPayload = new (ELeave) (TUint8[iSAPayloadSize]); //Generic payload NOT included
       
  4317             Mem::Copy(iSAPayload,(((TUint8 *)aSA)+sizeof(TPayloadISAKMP)),iSAPayloadSize);
       
  4318         }
       
  4319     }
       
  4320     const TPayloadISAKMP *payload = aSA->Payload();
       
  4321     return ProcessProposalsL(payload, SALengthLeft, aRecvProposals);
       
  4322 }
       
  4323 
       
  4324 
       
  4325 //Do the process required for proposals and transforms. The aPayload given must be a proposal
       
  4326 TBool CIkev1Negotiation::ProcessProposalsL(const TPayloadISAKMP *aPayload, TUint32 aLengthLeft, TUint8 *aRecvProposals)
       
  4327 {
       
  4328     TProposalISAKMP *proposal;
       
  4329     const TPayloadISAKMP *ppayload=aPayload;
       
  4330     TUint8 payType = ppayload->GetPayload();
       
  4331     TUint32 len_left;
       
  4332     CProposal_IIList *recv_proposals = (CProposal_IIList *)aRecvProposals;
       
  4333     CProposal_II *auxProp_II;
       
  4334     TBool found = EFalse;   //At least 1 transform matching
       
  4335 
       
  4336     //Many Proposals. The RESPONDER MUST choose a transform for each proposal or reject the 
       
  4337     //full suite of attributes.
       
  4338     do  
       
  4339     {       
       
  4340         //General payload check
       
  4341         if ((payType != ISAKMP_PAYLOAD_NONE) && (payType != ISAKMP_PAYLOAD_P))
       
  4342         {
       
  4343             DEBUG_LOG(_L("INVALID_PAYLOAD_TYPE (Bad next payload for the proposal)"));
       
  4344             SetErrorStatus( KKmdIkeNegotFailed );
       
  4345             SendNotifyL(INVALID_PAYLOAD_TYPE);
       
  4346             return EFalse;
       
  4347         }
       
  4348 
       
  4349         if (aPayload->GetReserved() != 0)   //Must be always 0
       
  4350         {
       
  4351             DEBUG_LOG(_L("INVALID RESERVED FIELD"));
       
  4352             SetErrorStatus( KKmdIkeNegotFailed );
       
  4353             SendNotifyL(PAYLOAD_MALFORMED);
       
  4354             return EFalse;
       
  4355         }
       
  4356         
       
  4357         //requires special length check
       
  4358         if ((aPayload->GetLength() < MIN_ISAKMP_PAYLOAD_SIZE) || (aPayload->GetLength() > aLengthLeft))
       
  4359         {
       
  4360             DEBUG_LOG(_L("BAD PAYLOAD SIZE"));
       
  4361             SetErrorStatus( KKmdIkeNegotFailed );
       
  4362             SendNotifyL(PAYLOAD_MALFORMED);
       
  4363             return EFalse;
       
  4364         }
       
  4365 
       
  4366         aLengthLeft -= aPayload->GetLength();   //dcreases the length of the prop. and its transforms
       
  4367 
       
  4368         proposal = TProposalISAKMP::Ptr(ppayload);
       
  4369         
       
  4370         
       
  4371         if (!CheckProtocolL(proposal->GetProtocol()))
       
  4372             return EFalse;
       
  4373 
       
  4374         if (!CheckSPIL(proposal))
       
  4375             return EFalse;
       
  4376 
       
  4377         len_left = proposal->GetLength() - (proposal->Size() + proposal->GetSPISize()); 
       
  4378         //len_left contains the length of the transforms only
       
  4379 
       
  4380         TInt ret = KErrNotFound;
       
  4381         if (iPhase == PHASE_I)
       
  4382         {
       
  4383             iChosenProposal_I.iProtocol = proposal->GetProtocol();
       
  4384             iChosenProposal_I.iSPI.Copy((TUint8 *)proposal->SPI(), proposal->GetSPISize());
       
  4385             iChosenProposal_I.iNumTransforms = 1;   //Phase I only one transf chosen
       
  4386             iChosenProposal_I.iProposalNum = proposal->GetNum();//Not compulsory but preferable to speed up the search process in the peer
       
  4387             
       
  4388             ret = ProcessTransformsL(ppayload,len_left);
       
  4389             
       
  4390             if (ret == KErrNone)
       
  4391                 return ETrue;//valid transform found
       
  4392             else if (ret != KErrNotFound)
       
  4393             {
       
  4394                 DEBUG_LOG(_L("ATTRIBUTES_NOT_SUPPORTED"));
       
  4395                 SetErrorStatus( KKmdIkeNegotFailed );
       
  4396                 SendNotifyL(ATTRIBUTES_NOT_SUPPORTED);
       
  4397                 return EFalse;
       
  4398             }
       
  4399             //If not found there may be other proposal to check
       
  4400         }
       
  4401         else    //PHASE_II
       
  4402         {
       
  4403             auxProp_II = new (ELeave) CProposal_II();
       
  4404             CleanupStack::PushL(auxProp_II);
       
  4405             auxProp_II->ConstructL(proposal->GetNumTrans());
       
  4406             auxProp_II->iProtocol=proposal->GetProtocol();
       
  4407             auxProp_II->iSPI.Copy((TUint8 *)proposal->SPI(), proposal->GetSPISize());
       
  4408             auxProp_II->iNumTransforms = proposal->GetNumTrans();   //Number of transforms in the proposal
       
  4409             auxProp_II->iProposalNum = proposal->GetNum();  //Proposal num
       
  4410             
       
  4411             ret = ProcessTransforms2L(ppayload, auxProp_II, len_left);
       
  4412             if (ret==KErrNone)//valid transform found
       
  4413             {   
       
  4414                 //Adds the new proposal to the list of chosen proposals
       
  4415                 recv_proposals->AppendL(auxProp_II);
       
  4416                 CleanupStack::Pop();    //auxProp_II safe
       
  4417                 found = ETrue;
       
  4418                 //go for the next proposal
       
  4419             }
       
  4420             else
       
  4421             {
       
  4422                 DEBUG_LOG(_L("ATTRIBUTES_NOT_SUPPORTED"));
       
  4423                 SendNotifyL(ATTRIBUTES_NOT_SUPPORTED);
       
  4424                 CleanupStack::PopAndDestroy();  //delete auxProp_II;    //delete the current proposal
       
  4425                 return EFalse;
       
  4426             }
       
  4427         }
       
  4428 
       
  4429         payType = ppayload->GetPayload();
       
  4430         ppayload = ppayload->Next();    //Next payload if there's any
       
  4431     } while (payType!=ISAKMP_PAYLOAD_NONE); //Proposal loop
       
  4432 
       
  4433     if (!found)
       
  4434     {
       
  4435         DEBUG_LOG(_L("ATTRIBUTES_NOT_SUPPORTED"));
       
  4436         SendNotifyL(ATTRIBUTES_NOT_SUPPORTED);
       
  4437         return EFalse;
       
  4438     }
       
  4439 
       
  4440     return found;
       
  4441 }
       
  4442 
       
  4443 //processes all the  PHASE I transforms. The parameter payload is the proposal containing
       
  4444 //the transforms to be able to access the # of transforms.
       
  4445 //Returns if any transform accepted (KErrNone) or not (KErrNotFound) or processing error (KErrGeneral)
       
  4446 TInt CIkev1Negotiation::ProcessTransformsL(const TPayloadISAKMP *aPayload,TUint32 aLengthLeft)
       
  4447 {
       
  4448     DEBUG_LOG(_L("-> CIkev1Negotiation::ProcessTransformsL()"));
       
  4449     TUint16 reason;             
       
  4450     TInt ret = KErrGeneral;
       
  4451      const TTransformISAKMP *transf;
       
  4452     const TProposalISAKMP *proposal=TProposalISAKMP::Ptr(aPayload);
       
  4453     //First transform. Not Next() because would be the next proposal or non-sa payload
       
  4454     const TPayloadISAKMP *tpayload=proposal->Payload();
       
  4455     
       
  4456     TInt payType = tpayload->GetPayload();  //Type of the payload following the first transform
       
  4457     transf = TTransformISAKMP::Ptr(tpayload);
       
  4458     
       
  4459     TInt numTransf  = (TInt)transf->GetNum();  // First transform number
       
  4460     TInt lastTransf = numTransf + (TInt)proposal->GetNumTrans(); // Last transform number
       
  4461     
       
  4462     while ( numTransf < lastTransf ) 
       
  4463     {
       
  4464         //only permited payload codes
       
  4465         if ((payType != ISAKMP_PAYLOAD_NONE) && (payType != ISAKMP_PAYLOAD_T))
       
  4466         {
       
  4467             DEBUG_LOG(_L("INVALID_PAYLOAD_TYPE (Bad next payload for the transform)"));
       
  4468             SendNotifyL(INVALID_PAYLOAD_TYPE);
       
  4469             return KErrGeneral;
       
  4470         }
       
  4471 
       
  4472         if (tpayload->GetReserved() != 0)   //Must be always 0
       
  4473         {
       
  4474             DEBUG_LOG(_L("INVALID RESERVED FIELD"));
       
  4475             SendNotifyL(PAYLOAD_MALFORMED);
       
  4476             return KErrGeneral;
       
  4477         }
       
  4478         
       
  4479         //requires special length check
       
  4480         if ((tpayload->GetLength() < MIN_ISAKMP_PAYLOAD_SIZE) || (tpayload->GetLength() > aLengthLeft))
       
  4481         {
       
  4482             DEBUG_LOG(_L("BAD PAYLOAD SIZE"));
       
  4483             SendNotifyL(PAYLOAD_MALFORMED);
       
  4484             return KErrGeneral;
       
  4485         }
       
  4486         
       
  4487         if (!CheckTransformID(PROTO_ISAKMP,transf->GetID()))
       
  4488             {
       
  4489             DEBUG_LOG(_L(" Continue"));
       
  4490 
       
  4491             numTransf++;                          // Next supposed transform #              
       
  4492             payType = tpayload->GetPayload();
       
  4493             tpayload = tpayload->Next();    //next payload (transform)
       
  4494             transf = TTransformISAKMP::Ptr(tpayload);
       
  4495 
       
  4496             continue;   //If fails, transform discarded!, not error
       
  4497             }
       
  4498         
       
  4499         if ( transf->GetNum() != numTransf )  //Not the correct #
       
  4500         {
       
  4501             DEBUG_LOG1(_L("BAD_PROPOSAL_SYNTAX (Non conscutive transform number (%d)"),transf->GetNum());
       
  4502             SendNotifyL(BAD_PROPOSAL_SYNTAX);
       
  4503             DEBUG_LOG(_L("<- CIkev1Negotiation::ProcessTransformsL() KErrGeneral"));
       
  4504             return KErrGeneral;
       
  4505         }
       
  4506 
       
  4507         if (transf->GetReserved() != 0 )    //Should be always 0
       
  4508         {
       
  4509             DEBUG_LOG(_L("INVALID RESERVED FIELD"));
       
  4510             SendNotifyL(PAYLOAD_MALFORMED);
       
  4511             DEBUG_LOG(_L("<- CIkev1Negotiation::ProcessTransformsL() KErrGeneral"));
       
  4512             return KErrGeneral;
       
  4513         }
       
  4514 
       
  4515         numTransf++;                          // Next supposed transform #              
       
  4516         //Attributes to be checked depending on Transf ID
       
  4517         TAttrib attrib;
       
  4518         
       
  4519         ret = ProcessAttributesL(tpayload, &attrib);
       
  4520         
       
  4521         if (ret != KErrNone)
       
  4522         {
       
  4523             if (ret != KErrNotFound)
       
  4524                 {
       
  4525                 DEBUG_LOG(_L("<- CIkev1Negotiation::ProcessTransformsL() KErrGeneral"));
       
  4526                 return KErrGeneral; //Error in the attributes. Already reported
       
  4527                 }
       
  4528             //Not accepted but correct
       
  4529         }
       
  4530         else    // Accepted attributes if (AttrChosen(attrib))
       
  4531         {  
       
  4532             //Checks the response or proposal is the same as one of our proposals
       
  4533             TAttrib *attr_list = iProposal_I.iAttrList;
       
  4534             TInt ret = KErrNotFound;
       
  4535 #ifdef _DEBUG            
       
  4536             TBuf<256> buf;
       
  4537 #endif            
       
  4538             while (attr_list && (ret != KErrNone) )
       
  4539             {
       
  4540                 ret = attrib.Compare(*attr_list, iRole==RESPONDER); //If RESPONDER relaxed comparison (no lifetimes checked)                
       
  4541                 if (ret != KErrNone)
       
  4542                 {
       
  4543 #ifdef _DEBUG                
       
  4544                     DEBUG_LOG1(_L("Transform #%d not matching proposal Reason: "), attrib.iTransformNum);
       
  4545                     AppendAttributeError(ret, buf);
       
  4546                     DEBUG_LOG(buf);
       
  4547 #endif                    
       
  4548                 }
       
  4549                 attr_list = attr_list->iNext;   //next transform proposed
       
  4550 
       
  4551             }
       
  4552             if (ret == KErrNone)
       
  4553             {
       
  4554                *iChosenProposal_I.iAttrList = attrib;       
       
  4555                DEBUG_LOG(_L("<- CIkev1Negotiation::ProcessTransformsL() KErrNone"));
       
  4556                return KErrNone; //If the attibute are supported there's no need to check more SA
       
  4557             }   
       
  4558             else    //No proposal matches
       
  4559             {
       
  4560                if ( numTransf == lastTransf ) //Is there more transforms to check
       
  4561                {    
       
  4562                   if (iRole == INITIATOR)
       
  4563                   {
       
  4564                       reason = BAD_PROPOSAL_SYNTAX;
       
  4565                       DEBUG_LOG(_L("BAD_PROPOSAL_SYNTAX (Phase I reply don't match proposal)"));
       
  4566                       SetErrorStatus( KKmdIkeNegotFailed );
       
  4567                   }                           
       
  4568                   else
       
  4569                   {
       
  4570                       reason = NO_PROPOSAL_CHOSEN;                    
       
  4571                       DEBUG_LOG(_L("NO_PROPOSAL_CHOSEN (Received Proposal doesn't match accepted attributes (Check own proposals))"));
       
  4572                   }           
       
  4573                   SendNotifyL(reason);
       
  4574                   DEBUG_LOG(_L("<- CIkev1Negotiation::ProcessTransformsL() KErrNotFound"));
       
  4575                   return KErrNotFound;
       
  4576                }    
       
  4577             }
       
  4578         }
       
  4579 
       
  4580         payType = tpayload->GetPayload();
       
  4581         tpayload = tpayload->Next();    //next payload (transform)
       
  4582         transf = TTransformISAKMP::Ptr(tpayload);
       
  4583         
       
  4584     }
       
  4585 
       
  4586     DEBUG_LOG(_L("<- CIkev1Negotiation::ProcessTransformsL() KErrNotFound"));
       
  4587 
       
  4588     //if reaches this point meanse no transform accepted in this proposal
       
  4589     //Notifies to the upper level
       
  4590     return KErrNotFound;
       
  4591 
       
  4592 }
       
  4593 
       
  4594 
       
  4595 //Logs the error when comparing a proposal
       
  4596 //void CIkev1Negotiation::LogAttributeError(TInt aTransformNum, TInt aErr)
       
  4597 void CIkev1Negotiation::AppendAttributeError(TInt aErr, TDes &aBuf) const
       
  4598 {
       
  4599 #ifndef _DEBUG
       
  4600     (void)aErr;
       
  4601     (void)aBuf;
       
  4602 #endif
       
  4603 
       
  4604 #ifdef _DEBUG
       
  4605     switch (aErr)
       
  4606     {
       
  4607     case KErrNotFound:
       
  4608         aBuf.Append(_L("No proposals\n"));
       
  4609         break;
       
  4610     case KErrTransformID:
       
  4611         aBuf.Append(_L("Different Transform Algorithm\n"));
       
  4612         break;
       
  4613     case KErrEncrAlg:
       
  4614         aBuf.Append(_L("Different Encryption Algorithm\n"));
       
  4615         break;
       
  4616     case KErrHashAlg:
       
  4617         aBuf.Append(_L("Different Hash Algorithm\n"));
       
  4618         break;
       
  4619     case KErrAuthMethod:
       
  4620         aBuf.Append(_L("Different Authentication Method\n"));
       
  4621         break;
       
  4622     case KErrGroupDesc:
       
  4623         aBuf.Append(_L("Different Group Description\n"));
       
  4624         break;
       
  4625     case KErrGroupType:
       
  4626         aBuf.Append(_L("Different Group Type\n"));
       
  4627         break;
       
  4628     case KErrGroupPrime:
       
  4629         aBuf.Append(_L("Different Group Prime\n"));
       
  4630         break;
       
  4631     case KErrGroupGen1:
       
  4632         aBuf.Append(_L("Different Group Generator 1\n"));
       
  4633         break;
       
  4634     case KErrGroupGen2:
       
  4635         aBuf.Append(_L("Different Group Generator 2\n"));
       
  4636         break;
       
  4637     case KErrGroupCurveA:
       
  4638         aBuf.Append(_L("Different Group Curve A\n"));
       
  4639         break;
       
  4640     case KErrGroupCurveB:
       
  4641         aBuf.Append(_L("Different Group Curve A\n"));
       
  4642         break;
       
  4643     case KErrPRF:
       
  4644         aBuf.Append(_L("Different PRF\n"));
       
  4645         break;
       
  4646     case KErrKeyLength:
       
  4647         aBuf.Append(_L("Different Key Length\n"));
       
  4648         break;
       
  4649     case KErrFieldSize:
       
  4650         aBuf.Append(_L("Different Field Size\n"));
       
  4651         break;
       
  4652     case KErrGroupOrder:
       
  4653         aBuf.Append(_L("Different Group Order\n"));
       
  4654         break;
       
  4655     case KErrLifeTime:
       
  4656         aBuf.Append(_L("Different Lifetime\n"));
       
  4657         break;
       
  4658     case KErrLifeSize:
       
  4659         aBuf.Append(_L("Different LifeSize\n"));
       
  4660         break;
       
  4661     case KErrEncMode:
       
  4662         aBuf.Append(_L("Different Encapsulation Mode\n"));
       
  4663         break;
       
  4664     case KErrAuthAlg:
       
  4665         aBuf.Append(_L("Different Authentication Algorithm\n"));
       
  4666         break;
       
  4667     case KErrKeyRounds:
       
  4668         aBuf.Append(_L("Different Key Rounds\n"));
       
  4669         break;
       
  4670     case KErrComprDicSize:
       
  4671         aBuf.Append(_L("Different Compress Dictionary Size\n"));
       
  4672         break;
       
  4673     case KErrComprPrivAlg:
       
  4674         aBuf.Append(_L("Different Compress Private Algorithm\n"));
       
  4675         break;
       
  4676     case KErrTransformNum:
       
  4677         aBuf.Append(_L("Different Transform Num.\n"));
       
  4678         break;
       
  4679     case KErrPropProtocol:
       
  4680         aBuf.Append(_L("Proposals have different protocol.\n"));
       
  4681         break;
       
  4682     case KErrNoTransforms:
       
  4683         aBuf.Append(_L("Proposal has no transforms \n"));
       
  4684         break;
       
  4685     case KErrNoRemoteProposals:
       
  4686         aBuf.Append(_L("Remote Proposals list is empty\n"));
       
  4687         break;
       
  4688     case KErrNoLocalProposals:
       
  4689         aBuf.Append(_L("Local Proposals list is empty\n"));
       
  4690         break;
       
  4691     case KErrPropNumberMismatch:
       
  4692         aBuf.Append(_L("The proposals lists have diferent number of AND'd proposals"));
       
  4693         break;
       
  4694     default:
       
  4695         aBuf.Append(_L("Unknown\n"));
       
  4696     }
       
  4697 #endif  
       
  4698 }
       
  4699 
       
  4700 //processes all the PHASE II transforms. The parameter payload is the proposal containing
       
  4701 //the transforms to be able to access the # of transforms.
       
  4702 //Returns if any transform accepted (KErrNone) or not (KErrNotFound) or processing error (KErrGeneral)
       
  4703 TInt CIkev1Negotiation::ProcessTransforms2L(const TPayloadISAKMP *aPayload,CProposal_II *aProp,TUint32 aLengthLeft)
       
  4704 {
       
  4705     DEBUG_LOG(_L("-> CIkev1Negotiation::ProcessTransforms2L()"));
       
  4706 
       
  4707     TInt ret;
       
  4708     const TTransformISAKMP *transf;
       
  4709     const TProposalISAKMP *proposal=TProposalISAKMP::Ptr(aPayload);
       
  4710     //First transform. Not Next() because would be the next proposal or non-sa payload
       
  4711     const TPayloadISAKMP *tpayload = proposal->Payload();
       
  4712 
       
  4713     TAttrib_II *attr_II = NULL; 
       
  4714     TInt payType = tpayload->GetPayload();  //Type of the payload following the first transform
       
  4715     transf = TTransformISAKMP::Ptr(tpayload);
       
  4716     
       
  4717     TInt numTransf  = (TInt)transf->GetNum();  // First transform number
       
  4718     TInt lastTransf = numTransf + (TInt)proposal->GetNumTrans(); // Last transform number   
       
  4719 
       
  4720     while ( numTransf < lastTransf ) 
       
  4721     {
       
  4722         //only permited payload codes
       
  4723         if ((payType != ISAKMP_PAYLOAD_NONE) && (payType != ISAKMP_PAYLOAD_T))
       
  4724         {
       
  4725             DEBUG_LOG(_L("INVALID_PAYLOAD_TYPE (Bad next payload for the transform)"));
       
  4726             SendNotifyL(INVALID_PAYLOAD_TYPE);
       
  4727             return KErrGeneral;
       
  4728         }
       
  4729         
       
  4730         if (tpayload->GetReserved() != 0)   //Must be always 0
       
  4731         {
       
  4732             DEBUG_LOG(_L("INVALID RESERVED FIELD"));
       
  4733             SendNotifyL(PAYLOAD_MALFORMED);
       
  4734             return KErrGeneral;
       
  4735         }
       
  4736         
       
  4737         //requires special length check
       
  4738         if ((tpayload->GetLength() < MIN_ISAKMP_PAYLOAD_SIZE) || (tpayload->GetLength() > aLengthLeft))
       
  4739         {
       
  4740             DEBUG_LOG(_L("BAD PAYLOAD SIZE"));
       
  4741             SendNotifyL(PAYLOAD_MALFORMED);
       
  4742             return KErrGeneral;
       
  4743         }
       
  4744         
       
  4745         if (!CheckTransformID(aProp->iProtocol,transf->GetID()))
       
  4746             {
       
  4747             DEBUG_LOG(_L(" Transform doesn't match, moving on to the next one"));
       
  4748             payType = tpayload->GetPayload();
       
  4749             tpayload = tpayload->Next();    //next payload (transform)
       
  4750             transf = TTransformISAKMP::Ptr(tpayload);
       
  4751             numTransf++;                          // Next supposed transform #
       
  4752             continue;   //If fails, transform discarded!, not error
       
  4753             }
       
  4754         
       
  4755         if ( transf->GetNum() != numTransf )  //Not the correct #. Must be consecutive
       
  4756         {   
       
  4757             DEBUG_LOG1(_L("BAD_PROPOSAL_SYNTAX (Non conscutive transform number (%d)"),transf->GetNum());
       
  4758             SendNotifyL(BAD_PROPOSAL_SYNTAX);
       
  4759             return KErrGeneral;
       
  4760         }
       
  4761 
       
  4762         if (transf->GetReserved() != 0 )    //Must be always 0
       
  4763         {
       
  4764             DEBUG_LOG(_L("INVALID RESERVED FIELD"));
       
  4765             SendNotifyL(PAYLOAD_MALFORMED);
       
  4766             return KErrGeneral;
       
  4767         }
       
  4768         
       
  4769         //Attributes to be checked depending on Transf ID
       
  4770         attr_II = new (ELeave) TAttrib_II();
       
  4771         CleanupStack::PushL(attr_II);
       
  4772         ret = ProcessAttributes2L(tpayload, attr_II, aProp->iProtocol);
       
  4773         if (ret != KErrNone)    //Some invalid attribute
       
  4774         {
       
  4775             DEBUG_LOG(_L(" Invalid attribute"));
       
  4776             CleanupStack::PopAndDestroy();  //delete attr_II;
       
  4777             if (ret != KErrNotFound)
       
  4778                 return KErrGeneral; //Error in the attributes. Already reported
       
  4779             else    //Invalid transform- Ignored
       
  4780             {
       
  4781                 DEBUG_LOG2(_L("Transform %d of proposal %d ignored"), transf->GetNum(), aProp->iProposalNum);
       
  4782             }
       
  4783         }
       
  4784         else    //Accepted, must check if really proposed or if matches the configuration if RESPONDER
       
  4785         {
       
  4786             DEBUG_LOG(_L(" Adding new attribute"));
       
  4787             aProp->iAttrList->AppendL(attr_II); //Add the new attribute
       
  4788             CleanupStack::Pop();    //attr_II saf
       
  4789         }
       
  4790         payType = tpayload->GetPayload();
       
  4791         tpayload = tpayload->Next();    //next payload (transform)
       
  4792         transf = TTransformISAKMP::Ptr(tpayload);
       
  4793         numTransf++;                          // Next supposed transform #
       
  4794         
       
  4795     }
       
  4796 
       
  4797     //No valid transform found
       
  4798     if (aProp->iAttrList->Count() == 0)
       
  4799         {
       
  4800         DEBUG_LOG(_L("<- CIkev1Negotiation::ProcessTransforms2L() KErrNotFound"));
       
  4801         return KErrNotFound;
       
  4802         }
       
  4803 
       
  4804     DEBUG_LOG(_L("<- CIkev1Negotiation::ProcessTransforms2L() KErrNone"));
       
  4805     return KErrNone;
       
  4806 }
       
  4807 
       
  4808 
       
  4809 //Copies and checks the values of the attributes. The parameter aPayload must be a transform
       
  4810 //aAttrib will contain the sent attributes if the return value is KErrNone, otherwise should be
       
  4811 //ignore because there was an error reading them (KErrGeneral) or the transform was not accepted (KErrNotFound)
       
  4812 TInt CIkev1Negotiation::ProcessAttributesL(const TPayloadISAKMP *aPayload, TAttrib *aAttrib)
       
  4813 {
       
  4814     const TTransformISAKMP *transf = TTransformISAKMP::Ptr(aPayload);
       
  4815     TInt length= aPayload->GetLength() - sizeof(*transf); //To process the attribs
       
  4816     TDataISAKMP *attr= transf->SAAttrib();
       
  4817     
       
  4818     aAttrib->iTransformNum = transf->GetNum();
       
  4819     aAttrib->iTransformID  = transf->GetID();
       
  4820     //
       
  4821 	// Store parameters for extended authentication
       
  4822 	//
       
  4823 	aAttrib->iXauthUsed = iHostData->iUseXauth;
       
  4824 	aAttrib->iRole      = iRole;
       
  4825 	
       
  4826     TUint16 lifeType  = 0; //No type assigned yet
       
  4827     TUint32 lifeValue = 0; //No value assigned yet
       
  4828     TUint16 val;
       
  4829     
       
  4830     while ( length>0 )
       
  4831     {
       
  4832         length = length - attr->Size();
       
  4833         if (length<0)   //Mismatch between lengths!!!
       
  4834         {
       
  4835             DEBUG_LOG(_L("BAD_PROPOSAL_SYNTAX (Length mismatch in the attibutes)"));
       
  4836             SendNotifyL(BAD_PROPOSAL_SYNTAX);
       
  4837             return KErrGeneral;
       
  4838         }
       
  4839         switch (attr->Type())
       
  4840         {
       
  4841         case OAKLEY_ATTR_TYPE_ENCR_ALG:
       
  4842             if (!CheckEncrAlg(attr->Value()))
       
  4843                 return KErrNotFound;
       
  4844             aAttrib->iEncrAlg=attr->Value();
       
  4845             break;
       
  4846         case OAKLEY_ATTR_TYPE_HASH_ALG:
       
  4847             if (!CheckHashAlg(attr->Value()))
       
  4848                 return KErrNotFound;
       
  4849             aAttrib->iHashAlg = attr->Value();
       
  4850             break;
       
  4851         case OAKLEY_ATTR_TYPE_AUTH_METH:
       
  4852             val = CTransNegotiation::GetAuthMethod(attr->Value(), iHostData->iUseXauth, iRole);
       
  4853             if (!CheckAuthMethod(val))
       
  4854                 return KErrNotFound;
       
  4855             aAttrib->iAuthMethod = val;
       
  4856             break;
       
  4857         case OAKLEY_ATTR_TYPE_GROUP_DESC:
       
  4858             if (!CheckGroupDesc(attr->Value()))
       
  4859                 return KErrNotFound;
       
  4860             aAttrib->iGroupDesc = attr->Value();
       
  4861             break;
       
  4862         case OAKLEY_ATTR_TYPE_GROUP_TYPE:
       
  4863             if (!CheckGroupType(attr->Value()))
       
  4864                 return KErrNotFound;
       
  4865             aAttrib->iGroupType = attr->Value();
       
  4866             break;
       
  4867         case OAKLEY_ATTR_TYPE_GROUP_PRIME:
       
  4868             if (attr->IsBasic())
       
  4869             {
       
  4870                 val = attr->Value();
       
  4871                 aAttrib->iGroupPrime.Copy((TUint8*)&val, sizeof(val));
       
  4872             }
       
  4873             else
       
  4874                 aAttrib->iGroupPrime.Copy(attr->VarValue(),attr->Length());
       
  4875             break;
       
  4876         case OAKLEY_ATTR_TYPE_GROUP_GEN1:
       
  4877             if (attr->IsBasic())
       
  4878             {
       
  4879                 val = attr->Value();
       
  4880                 aAttrib->iGroupGen1.Copy((TUint8*)&val, sizeof(val));
       
  4881             }
       
  4882             else
       
  4883                 aAttrib->iGroupGen1.Copy(attr->VarValue(),attr->Length());
       
  4884             break;
       
  4885         case OAKLEY_ATTR_TYPE_GROUP_GEN2:
       
  4886             if (attr->IsBasic())
       
  4887             {
       
  4888                 val = attr->Value();
       
  4889                 aAttrib->iGroupGen2.Copy((TUint8*)&val, sizeof(val));
       
  4890             }
       
  4891             else
       
  4892                 aAttrib->iGroupGen2.Copy(attr->VarValue(),attr->Length());
       
  4893             break;
       
  4894         case OAKLEY_ATTR_TYPE_GROUP_CRVA:
       
  4895             if (attr->IsBasic())
       
  4896             {
       
  4897                 val = attr->Value();
       
  4898                 aAttrib->iGroupCurveA.Copy((TUint8*)&val, sizeof(val));
       
  4899             }
       
  4900             else
       
  4901                 aAttrib->iGroupCurveA.Copy(attr->VarValue(),attr->Length());
       
  4902             break;
       
  4903         case OAKLEY_ATTR_TYPE_GROUP_CRVB:
       
  4904             if (attr->IsBasic())
       
  4905             {
       
  4906                 val = attr->Value();
       
  4907                 aAttrib->iGroupCurveB.Copy((TUint8*)&val, sizeof(val));
       
  4908             }
       
  4909             else
       
  4910                 aAttrib->iGroupCurveB.Copy(attr->VarValue(),attr->Length());
       
  4911             break;
       
  4912         case OAKLEY_ATTR_TYPE_LIFE_TYPE:
       
  4913             lifeType = attr->Value();
       
  4914             if (!CheckLifeType(lifeType))
       
  4915             {
       
  4916                 DEBUG_LOG(_L("BAD_PROPOSAL_SYNTAX (Invalid lifetime type)"));
       
  4917                 SendNotifyL(BAD_PROPOSAL_SYNTAX);
       
  4918                 return KErrGeneral;
       
  4919             }
       
  4920             break;
       
  4921         case OAKLEY_ATTR_TYPE_LIFE_DUR:
       
  4922             if (attr->IsBasic())
       
  4923             {
       
  4924                 lifeValue = ByteOrder::Swap32(attr->Value());
       
  4925                 if (lifeType == SECONDS)
       
  4926                     aAttrib->iLifeDurationSecs.Copy((TUint8 *)&lifeValue, sizeof(lifeValue));
       
  4927                 else if (lifeType == KBYTES)
       
  4928                     aAttrib->iLifeDurationKBytes.Copy((TUint8 *)&lifeValue, sizeof(lifeValue));
       
  4929                 else
       
  4930                 {
       
  4931                     DEBUG_LOG(_L("BAD_PROPOSAL_SYNTAX (Invalid lifetime type)"));
       
  4932                     SendNotifyL(BAD_PROPOSAL_SYNTAX);
       
  4933                     return KErrGeneral;
       
  4934                 }
       
  4935             }
       
  4936             else    //Not basic
       
  4937             {
       
  4938                 if (lifeType == SECONDS)
       
  4939                     aAttrib->iLifeDurationSecs.Copy(attr->VarValue(),attr->Length());
       
  4940                 else if (lifeType == KBYTES)
       
  4941                     aAttrib->iLifeDurationKBytes.Copy(attr->VarValue(),attr->Length());
       
  4942                 else
       
  4943                 {
       
  4944                     DEBUG_LOG(_L("BAD_PROPOSAL_SYNTAX (Invalid lifetime type)"));
       
  4945                     SendNotifyL(BAD_PROPOSAL_SYNTAX);
       
  4946                     return KErrGeneral;
       
  4947                 }
       
  4948             }
       
  4949             break;
       
  4950         case OAKLEY_ATTR_TYPE_PRF:
       
  4951             if (!CheckPRF(attr->Value()))
       
  4952                 return KErrNotFound;
       
  4953             aAttrib->iPRF=attr->Value();
       
  4954             break;
       
  4955         case OAKLEY_ATTR_TYPE_KEY_LEN:
       
  4956             aAttrib->iKeyLength = attr->Value();
       
  4957             break;
       
  4958         case OAKLEY_ATTR_TYPE_FIELD_SIZE:
       
  4959             if (!CheckFieldSize(attr->Value()))
       
  4960                 return KErrNotFound;
       
  4961             aAttrib->iFieldSize=attr->Value();
       
  4962             break;
       
  4963         case OAKLEY_ATTR_TYPE_GROUP_ORDER:
       
  4964             if (attr->IsBasic())
       
  4965             {
       
  4966                 val = attr->Value();
       
  4967                 aAttrib->iGroupOrder.Copy((TUint8*)&val, sizeof(val));
       
  4968             }
       
  4969             else
       
  4970                 aAttrib->iGroupOrder.Copy(attr->VarValue(),attr->Length());
       
  4971             break;
       
  4972         default:
       
  4973             DEBUG_LOG(_L("ATTRIBUTES_NOT_SUPPORTED (Invalid attribute number)"));
       
  4974             SendNotifyL(ATTRIBUTES_NOT_SUPPORTED);
       
  4975             return KErrGeneral;
       
  4976         }
       
  4977         attr = attr->Next();
       
  4978     }
       
  4979     
       
  4980     //Done here to ensure both received
       
  4981     if (aAttrib->iKeyLength !=0)
       
  4982         if (!CheckKeyLength(aAttrib->iKeyLength, (TUint8)aAttrib->iEncrAlg ,PROTO_ISAKMP))
       
  4983             return KErrNotFound;
       
  4984 
       
  4985     return KErrNone;
       
  4986 }
       
  4987 
       
  4988 //Copies and checks the values of the attributes. The parameter aPayload must be a transform
       
  4989 //aAttrib will contain the sent attributes if the return value is KErrNone, otherwise should be
       
  4990 //ignore because there was an error reading them (KErrGeneral) or the transform was not accepted (KErrNotFound)
       
  4991 TInt CIkev1Negotiation::ProcessAttributes2L(const TPayloadISAKMP *aPayload, TAttrib_II *aAttrib,TUint8 aProtocol)
       
  4992 {
       
  4993     const TTransformISAKMP *transf = TTransformISAKMP::Ptr(aPayload);
       
  4994     TInt length= aPayload->GetLength() - sizeof(*transf); //To process the attribs
       
  4995     
       
  4996     aAttrib->iTransformNum = transf->GetNum();
       
  4997     aAttrib->iTransformID = transf->GetID();
       
  4998     TDataISAKMP *attr= transf->SAAttrib();
       
  4999     TUint16 lifeType = 0;   //No type assigned yet
       
  5000     TUint32 lifeValue = 0;
       
  5001     while (length>0)
       
  5002     {
       
  5003         length = length - attr->Size();
       
  5004         if (length<0)   //Mismatch between lengths!!!
       
  5005         {
       
  5006             DEBUG_LOG(_L("BAD_PROPOSAL_SYNTAX (Length mismatch in the attibutes)"));
       
  5007             SendNotifyL(BAD_PROPOSAL_SYNTAX);
       
  5008             return KErrGeneral;
       
  5009         }
       
  5010         switch (attr->Type())
       
  5011         {
       
  5012         case DOI_ATTR_TYPE_LIFE_TYPE:
       
  5013             lifeType=attr->Value();
       
  5014             if (!CheckLifeType(lifeType))
       
  5015             {
       
  5016                 DEBUG_LOG(_L("BAD_PROPOSAL_SYNTAX (Invalid lifetime type)"));
       
  5017                 SendNotifyL(BAD_PROPOSAL_SYNTAX);
       
  5018                 return KErrGeneral;
       
  5019             }
       
  5020             break;
       
  5021         case DOI_ATTR_TYPE_LIFE_DUR:
       
  5022             if (attr->IsBasic())
       
  5023             {
       
  5024                 lifeValue = ByteOrder::Swap32(attr->Value());
       
  5025                 if (lifeType==SECONDS)
       
  5026                     aAttrib->iLifeDurationSecs.Copy((TUint8 *)&lifeValue, sizeof(lifeValue));
       
  5027                 else if (lifeType==KBYTES)
       
  5028                     aAttrib->iLifeDurationKBytes.Copy((TUint8 *)&lifeValue, sizeof(lifeValue));
       
  5029                 else
       
  5030                 {
       
  5031                     DEBUG_LOG(_L("BAD_PROPOSAL_SYNTAX (No lifetime type received)"));
       
  5032                     SendNotifyL(BAD_PROPOSAL_SYNTAX);
       
  5033                     return KErrGeneral;
       
  5034                 }
       
  5035             }
       
  5036             else
       
  5037             {
       
  5038                 if (lifeType==SECONDS)
       
  5039                     aAttrib->iLifeDurationSecs.Copy(attr->VarValue(),attr->Length());
       
  5040                 else if (lifeType==KBYTES)
       
  5041                     aAttrib->iLifeDurationKBytes.Copy(attr->VarValue(),attr->Length());
       
  5042                 else
       
  5043                 {
       
  5044                     DEBUG_LOG(_L("BAD_PROPOSAL_SYNTAX (No lifetime type received)"));
       
  5045                     SendNotifyL(BAD_PROPOSAL_SYNTAX);
       
  5046                     return KErrGeneral;
       
  5047                 }
       
  5048             }
       
  5049             lifeType = 0;   //Cannot received another lifetime without setting the type again
       
  5050             break;
       
  5051         case DOI_ATTR_TYPE_GROUP_DESC:
       
  5052             if (!CheckGroupDesc(attr->Value()))
       
  5053                 return KErrNotFound;
       
  5054             aAttrib->iGroupDesc=attr->Value();
       
  5055             break;
       
  5056         case DOI_ATTR_TYPE_ENC_MODE:    //Encapsulation Mode
       
  5057             if (!CheckEncMode(attr->Value()))
       
  5058                 return KErrNotFound;
       
  5059             aAttrib->iEncMode=attr->Value();
       
  5060             if ( aAttrib->iEncMode == UDP_ENC_TUNNEL || aAttrib->iEncMode == UDP_RFC_ENC_TUNNEL  )
       
  5061                aAttrib->iEncMode = DOI_TUNNEL;
       
  5062             if ( aAttrib->iEncMode == UDP_ENC_TRANSPORT || aAttrib->iEncMode == UDP_RFC_ENC_TRANSPORT)
       
  5063                aAttrib->iEncMode = DOI_TRANSPORT;
       
  5064             break;
       
  5065         case DOI_ATTR_TYPE_AUTH_ALG:
       
  5066             if (!CheckAuthAlg(attr->Value()))
       
  5067                 return KErrNotFound;
       
  5068             aAttrib->iAuthAlg=attr->Value();
       
  5069             break;
       
  5070         case DOI_ATTR_TYPE_KEY_LEN:
       
  5071             aAttrib->iKeyLength = attr->Value();
       
  5072             break;  
       
  5073         case DOI_ATTR_TYPE_KEY_ROUNDS:
       
  5074             aAttrib->iKeyRounds=attr->Value();
       
  5075             break;
       
  5076 /*          
       
  5077         case DOI_ATTR_TYPE_COMP_DIC_SIZE:   //Compress Dictionary size
       
  5078             aAttrib->iComprDicSize=attr->Value();
       
  5079             break;  
       
  5080         case DOI_ATTR_TYPE_COMP_PRIV_ALG:   //Compress Dictionary size
       
  5081             aAttrib->iComprPrivAlg=attr->Value();
       
  5082             break;
       
  5083 */          
       
  5084         default:
       
  5085             DEBUG_LOG(_L("ATTRIBUTES_NOT_SUPPORTED (Invalid attribute number)"));
       
  5086             SendNotifyL(ATTRIBUTES_NOT_SUPPORTED);
       
  5087             return KErrGeneral;
       
  5088         }
       
  5089         attr = attr->Next();
       
  5090     }
       
  5091 
       
  5092     if (lifeType != 0)  //Type set but not sent
       
  5093     {
       
  5094         DEBUG_LOG(_L("Lifetime type set but value not sent!"));
       
  5095         return KErrNotFound;
       
  5096     }
       
  5097 
       
  5098     if (aAttrib->iKeyLength !=0)
       
  5099         if (!CheckKeyLength(aAttrib->iKeyLength,transf->GetID(),aProtocol)) //Check key length correct
       
  5100             return KErrNotFound;
       
  5101 
       
  5102     return KErrNone;
       
  5103 }
       
  5104 
       
  5105 
       
  5106 //returns KErrNone if OK, otherwise error already treated.
       
  5107 TBool CIkev1Negotiation::ProcessKeyL(const TKeyISAKMP *aKey)
       
  5108 {
       
  5109     //const TKeyISAKMP *key = TKeyISAKMP::Ptr(aPayload);
       
  5110     
       
  5111     //payload not present
       
  5112     if (iPhase==PHASE_I)
       
  5113     {
       
  5114         if (!aKey)
       
  5115         {
       
  5116             DEBUG_LOG(_L("NO KEY Payload"));
       
  5117             SetErrorStatus( KKmdIkeNegotFailed );
       
  5118             SendNotifyL(PAYLOAD_MALFORMED);
       
  5119             return EFalse;
       
  5120         }
       
  5121         //Doesn't return yet because it needs to copy the received key
       
  5122     }
       
  5123     else    //PHASE_II
       
  5124     {
       
  5125         if (!aKey)
       
  5126         {
       
  5127             if (iPFS)
       
  5128             {
       
  5129                 DEBUG_LOG(_L("KEY Payload Expected (PFS is enabled)"));
       
  5130                 return EFalse;
       
  5131             }
       
  5132 
       
  5133             return ETrue;
       
  5134             
       
  5135         }
       
  5136         else    // Key present
       
  5137         {
       
  5138             if (!iPFS)
       
  5139             {
       
  5140                 DEBUG_LOG(_L("KEY Payload NOT Expected (PFS is disabled)"));
       
  5141                 return EFalse;
       
  5142             }
       
  5143             //Doesn't return yet because it needs to copy the received key
       
  5144         }
       
  5145     }
       
  5146         
       
  5147     //stores the public key sent by the other peer. Only if key received and PFS enabled (PHASE II only)
       
  5148     iPeerPublicKey.Copy(aKey->KeyData(), aKey->GetLength() - sizeof(*aKey));
       
  5149     return ETrue;
       
  5150 }
       
  5151 
       
  5152 
       
  5153 TBool CIkev1Negotiation::ProcessNonceL(const TPayloadISAKMP *aPayload)
       
  5154 {
       
  5155     const TNonceISAKMP *nonce = TNonceISAKMP::Ptr(aPayload);
       
  5156 
       
  5157     //payload not present
       
  5158     if (!nonce)
       
  5159     {
       
  5160         DEBUG_LOG(_L("NO NONCE PAYLOAD"));
       
  5161         SetErrorStatus( KKmdIkeNegotFailed );
       
  5162         SendNotifyL(PAYLOAD_MALFORMED);
       
  5163         return EFalse;
       
  5164     }
       
  5165 
       
  5166     //stores the nonce sent by the other peer
       
  5167     if (iRole==RESPONDER)
       
  5168         iNONCE_I.Copy(nonce->NonceData(),nonce->NonceDataLen());
       
  5169     else
       
  5170         iNONCE_R.Copy(nonce->NonceData(),nonce->NonceDataLen());
       
  5171 
       
  5172     return ETrue;
       
  5173 
       
  5174 }
       
  5175 
       
  5176 TBool CIkev1Negotiation::ProcessStage1_II_IDsL(const TIdentISAKMP *aInit_ID_payload,const TIdentISAKMP *aResp_ID_payload, CProposal_IIList *aRecv_proposals)
       
  5177 {
       
  5178     //IDci
       
  5179     //First we check the received IDs to be able to build the proposals for phase_II
       
  5180     TInt32 addr;        //Contains a numeric IPv4 addr to be sent
       
  5181     TBuf<40> addr_buf;  //Contains a text IPv4/IPv6 addr to be sent
       
  5182 
       
  5183     TIp6Addr ip6addr;   //IPV6 raw address
       
  5184 
       
  5185     //We receive the peer proxy address or gateway client
       
  5186     TAttrib_II *attr_II = aRecv_proposals->At(0)->iAttrList->At(0);
       
  5187     if (aInit_ID_payload)   //ID Payload received
       
  5188     {
       
  5189         iIDReceived = ETrue;
       
  5190         if (!CheckIdentL(aInit_ID_payload))  
       
  5191             return EFalse;
       
  5192 
       
  5193         iIDRemotePort = aInit_ID_payload->GetPort();
       
  5194         iIDProtocol = aInit_ID_payload->GetProtocol();
       
  5195         iRemoteIDType_II = aInit_ID_payload->GetIDType();
       
  5196 
       
  5197         switch (aInit_ID_payload->GetIDType())
       
  5198         {
       
  5199             case ID_IPV4_ADDR:
       
  5200                 Mem::Copy((TUint8 *)&addr, aInit_ID_payload->IDData(),sizeof(TInt32));
       
  5201                 iRemoteAddr1_ID_II.SetAddress(ByteOrder::Swap32(addr));
       
  5202                 DEBUG_LOG(_L("Remote ID received"));
       
  5203                 DEBUG_LOG(_L("Setting Remote ID to:"));
       
  5204                 iRemoteAddr1_ID_II.OutputWithScope(addr_buf);
       
  5205                 DEBUG_LOG(addr_buf);
       
  5206                 if (iRemoteAddr.Match(iRemoteAddr1_ID_II))
       
  5207                     iDefaultRemoteID = ETrue;   //Must be sent but won't be used when updating the SAD
       
  5208                 else if (attr_II->iEncMode == DOI_TRANSPORT)
       
  5209                 {
       
  5210                     DEBUG_LOG(_L("ADDRESS_NOTIFICATION (Received ID MUST match the Remote addr in Transport mode)"));
       
  5211                     SendNotifyL(ADDRESS_NOTIFICATION);
       
  5212                     return EFalse;
       
  5213                 }
       
  5214                 break;
       
  5215             case ID_IPV4_ADDR_SUBNET:
       
  5216                 Mem::Copy((TUint8 *)&addr, aInit_ID_payload->IDData(),sizeof(TInt32));  //Address
       
  5217                 iRemoteAddr1_ID_II.SetAddress(ByteOrder::Swap32(addr));
       
  5218                 Mem::Copy((TUint8 *)&addr, aInit_ID_payload->IDData() + sizeof(TInt32),sizeof(TInt32)); //Mask
       
  5219                 iRemoteAddr2_ID_II.SetAddress(ByteOrder::Swap32(addr));
       
  5220                 iRemoteAddr1_ID_II.OutputWithScope(addr_buf);
       
  5221                 DEBUG_LOG(_L("Setting Remote ID to: addr = "));
       
  5222                 DEBUG_LOG(addr_buf);
       
  5223                 iRemoteAddr2_ID_II.OutputWithScope(addr_buf);
       
  5224                 DEBUG_LOG(_L(" mask = "));
       
  5225                 DEBUG_LOG(addr_buf);
       
  5226                 if (PrefixLen(iRemoteAddr2_ID_II) < KErrNone)   //Invalid Mask  (can't be > 32 bec. we get only 4 bytes)
       
  5227                 {
       
  5228                     DEBUG_LOG(_L("INVALID_ID_INFORMATION (Invalid peer proxy mask for type ID_IPV4_ADDR_SUBNET)"));
       
  5229                     SetErrorStatus( KKmdIkeNegotFailed );
       
  5230                     SendNotifyL(INVALID_ID_INFORMATION);
       
  5231                     return EFalse;
       
  5232                 }
       
  5233                 if (attr_II->iEncMode == DOI_TRANSPORT)
       
  5234                 {
       
  5235                     if (!iRemoteAddr.Match(iRemoteAddr1_ID_II, iRemoteAddr2_ID_II))
       
  5236                     {
       
  5237                         DEBUG_LOG(_L("ADDRESS_NOTIFICATION (Remote ID MUST match the net & mask received)"));
       
  5238                         SetErrorStatus( KKmdIkeNegotFailed );
       
  5239                         SendNotifyL(ADDRESS_NOTIFICATION);
       
  5240                         return EFalse;
       
  5241                     }
       
  5242                 }
       
  5243                 break;
       
  5244             case ID_IPV6_ADDR:
       
  5245                 Mem::Copy(&ip6addr.u.iAddr8, aInit_ID_payload->IDData(), sizeof(ip6addr.u.iAddr8));
       
  5246                 iRemoteAddr1_ID_II.SetAddress(ip6addr);
       
  5247                 DEBUG_LOG(_L("Remote ID received"));
       
  5248                 DEBUG_LOG(_L("Setting Remote ID to:"));
       
  5249                 iRemoteAddr1_ID_II.OutputWithScope(addr_buf);
       
  5250                 DEBUG_LOG(addr_buf);
       
  5251                 if (iRemoteAddr.Match(iRemoteAddr1_ID_II))
       
  5252                     iDefaultRemoteID = ETrue;   //Must be sent but won't be used when updating the SAD
       
  5253                 else if (attr_II->iEncMode == DOI_TRANSPORT)
       
  5254                 {
       
  5255                     DEBUG_LOG(_L("ADDRESS_NOTIFICATION (Remote ID doesn't match received IDi in Transport mode)"));
       
  5256                     SendNotifyL(ADDRESS_NOTIFICATION);
       
  5257                     return EFalse;
       
  5258                 }
       
  5259                 break;
       
  5260             case ID_IPV6_ADDR_SUBNET:
       
  5261                 Mem::Copy(&ip6addr.u.iAddr8, aInit_ID_payload->IDData(), sizeof(ip6addr.u.iAddr8)); //Address               
       
  5262                 iRemoteAddr1_ID_II.SetAddress(ip6addr);
       
  5263                 Mem::Copy(&ip6addr.u.iAddr8, aInit_ID_payload->IDData() + sizeof(ip6addr.u.iAddr8), sizeof(ip6addr.u.iAddr8));  //Mask
       
  5264                 iRemoteAddr2_ID_II.SetAddress(ip6addr);
       
  5265                 DEBUG_LOG(_L("Remote ID (subnet) received"));
       
  5266                 DEBUG_LOG(_L("Setting Remote ID to: addr = "));
       
  5267                 iRemoteAddr1_ID_II.OutputWithScope(addr_buf);
       
  5268                 DEBUG_LOG(addr_buf);
       
  5269                 DEBUG_LOG(_L(" mask = "));
       
  5270                 iRemoteAddr2_ID_II.OutputWithScope(addr_buf);
       
  5271                 DEBUG_LOG(addr_buf);
       
  5272                 if (PrefixLen(iRemoteAddr2_ID_II) < 0)  //Invalid Mask
       
  5273                 {
       
  5274                     DEBUG_LOG(_L("INVALID_ID_INFORMATION (Invalid peer proxy mask for type ID_IPV6_ADDR_SUBNET)"));
       
  5275                     SetErrorStatus( KKmdIkeNegotFailed );
       
  5276                     SendNotifyL(INVALID_ID_INFORMATION);
       
  5277                     return EFalse;
       
  5278                 }
       
  5279                 if (attr_II->iEncMode == DOI_TRANSPORT)
       
  5280                 {
       
  5281                     if (!iRemoteAddr.Match(iRemoteAddr1_ID_II, iRemoteAddr2_ID_II))
       
  5282                     {
       
  5283                         DEBUG_LOG(_L("ADDRESS_NOTIFICATION (Remote ID MUST match the net & mask received)"));
       
  5284                         SetErrorStatus( KKmdIkeNegotFailed );
       
  5285                         SendNotifyL(ADDRESS_NOTIFICATION);
       
  5286                         return EFalse;
       
  5287                     }
       
  5288                 }
       
  5289                 break;
       
  5290             default:    //redundant. Detected in CheckIdentL()
       
  5291                 DEBUG_LOG(_L("INVALID_ID_INFORMATION (ID Type not supported)"));
       
  5292                 SetErrorStatus( KKmdIkeNegotFailed );
       
  5293                 SendNotifyL(INVALID_ID_INFORMATION);
       
  5294                 return EFalse;
       
  5295         }//switch
       
  5296     }
       
  5297     else    //No id received (That means we're negotiating directly with the end host) (RFC 2409 5.5)
       
  5298     {
       
  5299         //For TRANSPORT we don't need to do anything
       
  5300         iIDLocalPort = 0;
       
  5301         iIDRemotePort = 0;
       
  5302         iIDProtocol = 0;
       
  5303         return ETrue;   //No need to check the Responder ID if no Initiator ID received
       
  5304     }
       
  5305 
       
  5306     //IDcr
       
  5307     //Receive our proxy. We don't know it because we are responders so the other peer tells us who does it
       
  5308     //want to communicate with
       
  5309     if (aResp_ID_payload)   //ID Payload received
       
  5310     {
       
  5311         if (!CheckIdentL(aResp_ID_payload))
       
  5312             return EFalse;
       
  5313 
       
  5314         iIDLocalPort = aResp_ID_payload->GetPort();
       
  5315         iLocalIDType_II = aResp_ID_payload->GetIDType();
       
  5316         if (iIDProtocol != aResp_ID_payload->GetProtocol()) //Must be the same sent in the IDCi
       
  5317         {
       
  5318             DEBUG_LOG(_L("INVALID_ID_INFORMATION (Local ID Protocol different from Remote ID Protocol. Must be the same)"));
       
  5319             SetErrorStatus( KKmdIkeNegotFailed );
       
  5320             SendNotifyL(INVALID_ID_INFORMATION);
       
  5321             return EFalse;
       
  5322         }
       
  5323 
       
  5324         switch (aResp_ID_payload->GetIDType())
       
  5325         {
       
  5326             case ID_IPV4_ADDR:
       
  5327                 Mem::Copy((TUint8 *)&addr, aResp_ID_payload->IDData(),sizeof(TInt32));
       
  5328                 iLocalAddr1_ID_II.SetAddress(ByteOrder::Swap32(addr));
       
  5329                 DEBUG_LOG(_L("Local ID received"));
       
  5330                 DEBUG_LOG(_L("Setting Local ID to:"));
       
  5331                 iLocalAddr1_ID_II.OutputWithScope(addr_buf);
       
  5332                 DEBUG_LOG(addr_buf);
       
  5333                 if ( iInternalAddr ) {
       
  5334                    //
       
  5335                    // Check ID against internal address instead of local address
       
  5336                    //
       
  5337                    if (iInternalAddr->iClientIntAddr.Match(iLocalAddr1_ID_II))
       
  5338                        iDefaultLocalID = ETrue;  //Must be sent but won't be used when updating the SAD
       
  5339                 }
       
  5340                 else {
       
  5341                    if (iLocalAddr.Match(iLocalAddr1_ID_II))
       
  5342                         iDefaultLocalID = ETrue; //Must be sent but won't be used when updating the SAD
       
  5343                    else if (attr_II->iEncMode == DOI_TRANSPORT)
       
  5344                    {
       
  5345                        DEBUG_LOG(_L("ADDRESS_NOTIFICATION (Local ID MUST match the net & mask received)"));
       
  5346                        SetErrorStatus( KKmdIkeNegotFailed );
       
  5347                        SendNotifyL(ADDRESS_NOTIFICATION);
       
  5348                        return EFalse;
       
  5349                    }   
       
  5350                 }
       
  5351                 break;
       
  5352             case ID_IPV4_ADDR_SUBNET:
       
  5353                 Mem::Copy((TUint8 *)&addr, aResp_ID_payload->IDData(),sizeof(TInt32));  //Address
       
  5354                 iLocalAddr1_ID_II.SetAddress(ByteOrder::Swap32(addr));
       
  5355                 Mem::Copy((TUint8 *)&addr, aResp_ID_payload->IDData() + sizeof(TInt32),sizeof(TInt32)); //Mask
       
  5356                 iLocalAddr2_ID_II.SetAddress(ByteOrder::Swap32(addr));
       
  5357                 DEBUG_LOG(_L("Setting Local ID to: addr = "));
       
  5358                 iLocalAddr1_ID_II.OutputWithScope(addr_buf);
       
  5359                 DEBUG_LOG(addr_buf);
       
  5360                 DEBUG_LOG(_L(" mask = "));
       
  5361                 iLocalAddr2_ID_II.OutputWithScope(addr_buf);
       
  5362                 DEBUG_LOG(addr_buf);
       
  5363                 if (PrefixLen(iLocalAddr2_ID_II) < 0)   //Invalid Mask
       
  5364                 {
       
  5365                     DEBUG_LOG(_L("INVALID_ID_INFORMATION (Invalid Remote ID mask for type ID_IPV4_ADDR_SUBNET)"));
       
  5366                     SetErrorStatus( KKmdIkeNegotFailed );
       
  5367                     SendNotifyL(INVALID_ID_INFORMATION);
       
  5368                     return EFalse;
       
  5369                 }
       
  5370                 if (attr_II->iEncMode == DOI_TRANSPORT)
       
  5371                 {
       
  5372                     if (!iLocalAddr.Match(iLocalAddr1_ID_II, iLocalAddr2_ID_II))
       
  5373                     {
       
  5374                         DEBUG_LOG(_L("ADDRESS_NOTIFICATION (Local ID MUST match the net & mask received)"));
       
  5375                         SetErrorStatus( KKmdIkeNegotFailed );
       
  5376                         SendNotifyL(ADDRESS_NOTIFICATION);
       
  5377                         return EFalse;
       
  5378                     }
       
  5379                 }
       
  5380                 break;
       
  5381             case ID_IPV6_ADDR:
       
  5382                 Mem::Copy(&ip6addr.u.iAddr8, aResp_ID_payload->IDData(), sizeof(ip6addr.u.iAddr8));
       
  5383                 //iOwnProxyAddr.SetAddress(ip6addr);
       
  5384                 iLocalAddr1_ID_II.SetAddress(ip6addr);
       
  5385                 DEBUG_LOG(_L("Own Proxy received"));
       
  5386                 DEBUG_LOG(_L("Setting Own Proxy address to:"));
       
  5387                 iLocalAddr1_ID_II.OutputWithScope(addr_buf);
       
  5388                 DEBUG_LOG(addr_buf);
       
  5389                 if (iLocalAddr.Match(iLocalAddr1_ID_II))
       
  5390                     iDefaultLocalID = ETrue;    //Must be sent but won't be used when updating the SAD
       
  5391                 else if (attr_II->iEncMode == DOI_TRANSPORT)
       
  5392                 {
       
  5393                     DEBUG_LOG(_L("ADDRESS_NOTIFICATION (Local ID MUST match the net & mask received)"));
       
  5394                     SendNotifyL(ADDRESS_NOTIFICATION);
       
  5395                     return EFalse;
       
  5396                 }
       
  5397                 break;
       
  5398             case ID_IPV6_ADDR_SUBNET:
       
  5399                 Mem::Copy(&ip6addr.u.iAddr8, aResp_ID_payload->IDData(), sizeof(ip6addr.u.iAddr8)); //Address
       
  5400                 iLocalAddr1_ID_II.SetAddress(ip6addr);
       
  5401                 Mem::Copy(&ip6addr.u.iAddr8, aResp_ID_payload->IDData() + sizeof(ip6addr.u.iAddr8), sizeof(ip6addr.u.iAddr8));  //Mask
       
  5402                 iLocalAddr2_ID_II.SetAddress(ip6addr);
       
  5403                 DEBUG_LOG(_L("Setting Own Proxy to: addr = "));
       
  5404                 iLocalAddr1_ID_II.OutputWithScope(addr_buf);
       
  5405                 DEBUG_LOG(addr_buf);
       
  5406                 DEBUG_LOG(_L(" mask = "));
       
  5407                 iLocalAddr2_ID_II.OutputWithScope(addr_buf);
       
  5408                 DEBUG_LOG(addr_buf);
       
  5409                 if (PrefixLen(iLocalAddr2_ID_II) < 0)   //Invalid Mask
       
  5410                 {
       
  5411                     DEBUG_LOG(_L("INVALID_ID_INFORMATION (Invalid Remote ID mask for type ID_IPV6_ADDR_SUBNET)"));
       
  5412                     SetErrorStatus( KKmdIkeNegotFailed );
       
  5413                     SendNotifyL(INVALID_ID_INFORMATION);
       
  5414                     return EFalse;
       
  5415                 }
       
  5416                 if (attr_II->iEncMode == DOI_TRANSPORT)
       
  5417                 {
       
  5418                     if (!iLocalAddr.Match(iLocalAddr1_ID_II, iLocalAddr2_ID_II))
       
  5419                     {
       
  5420                         DEBUG_LOG(_L("ADDRESS_NOTIFICATION (Local ID MUST match the net & mask received)"));
       
  5421                         SetErrorStatus( KKmdIkeNegotFailed );
       
  5422                         SendNotifyL(ADDRESS_NOTIFICATION);
       
  5423                         return EFalse;
       
  5424                     }
       
  5425                 }
       
  5426                 break;
       
  5427             default:
       
  5428                 DEBUG_LOG(_L("INVALID_ID_INFORMATION (ID Type not supported)"));
       
  5429                 SetErrorStatus( KKmdIkeNegotFailed );
       
  5430                 SendNotifyL(INVALID_ID_INFORMATION);
       
  5431                 return EFalse;
       
  5432         }//switch
       
  5433     }
       
  5434 
       
  5435     return ETrue;
       
  5436 }
       
  5437 
       
  5438 
       
  5439 TBool CIkev1Negotiation::ProcessStage2_II_IDsL(const TIdentISAKMP *aInit_ID_payload,const TIdentISAKMP *aResp_ID_payload)//, CProposal_IIList *aRecv_proposals)
       
  5440 {
       
  5441     TInt32 addr4_int;       //Contains a numeric IPv4 addr to be sent
       
  5442     TIp6Addr ip6addr;   //IPV6 raw address
       
  5443     TInetAddr tmp_addr;
       
  5444     //Here we check the initator proxy (Our client) sent by us has been received correctly
       
  5445     if (aInit_ID_payload)   //ID Payload received
       
  5446     {
       
  5447         if (!CheckIdentL(aInit_ID_payload))
       
  5448             return EFalse;
       
  5449 
       
  5450         if (aInit_ID_payload->GetPort() != iIDLocalPort)
       
  5451         {
       
  5452             DEBUG_LOG(_L("INVALID_ID_INFORMATION (Local ID Port different from the one sent)"));
       
  5453             SetErrorStatus( KKmdIkeNegotFailed );
       
  5454             SendNotifyL(INVALID_ID_INFORMATION);
       
  5455             return EFalse;
       
  5456         }
       
  5457 
       
  5458         if (aInit_ID_payload->GetProtocol() != iIDProtocol)
       
  5459         {
       
  5460             DEBUG_LOG(_L("INVALID_ID_INFORMATION (Local ID Protocol different from the one sent)"));
       
  5461             SetErrorStatus( KKmdIkeNegotFailed );
       
  5462             SendNotifyL(INVALID_ID_INFORMATION);
       
  5463             return EFalse;
       
  5464         }
       
  5465 
       
  5466         switch (aInit_ID_payload->GetIDType())
       
  5467         {
       
  5468         case ID_IPV4_ADDR:
       
  5469             Mem::Copy((TUint8 *)&addr4_int,aInit_ID_payload->IDData(),sizeof(TInt32));
       
  5470             tmp_addr.SetAddress(ByteOrder::Swap32(addr4_int));
       
  5471             if (!tmp_addr.Match(iLocalAddr1_ID_II))
       
  5472             {
       
  5473                 DEBUG_LOG(_L("Wrong Own ID received (Different from the one sent)"));
       
  5474                 SetErrorStatus( KKmdIkeNegotFailed );
       
  5475                 SendNotifyL(INVALID_ID_INFORMATION);
       
  5476                 return EFalse;
       
  5477             }
       
  5478             break;
       
  5479         case ID_IPV4_ADDR_SUBNET:
       
  5480             //Subnet
       
  5481             Mem::Copy((TUint8 *)&addr4_int,aInit_ID_payload->IDData(),sizeof(TInt32));
       
  5482             tmp_addr.SetAddress(ByteOrder::Swap32(addr4_int));
       
  5483             if (!tmp_addr.Match(iLocalAddr1_ID_II))
       
  5484             {
       
  5485                 //The ID subnet is not the one we sent!
       
  5486                 DEBUG_LOG(_L("Wrong Own ID subnet received (Different from the one sent)"));
       
  5487                 SetErrorStatus( KKmdIkeNegotFailed );
       
  5488                 SendNotifyL(INVALID_ID_INFORMATION);
       
  5489                 return EFalse;
       
  5490             }
       
  5491             //Mask
       
  5492             Mem::Copy((TUint8 *)&addr4_int,aInit_ID_payload->IDData() + sizeof(TInt32),sizeof(TInt32));
       
  5493             tmp_addr.SetAddress(ByteOrder::Swap32(addr4_int));          
       
  5494             if (!tmp_addr.Match(iLocalAddr2_ID_II))
       
  5495             {
       
  5496                 //The ID mask is not the one we sent!
       
  5497                 DEBUG_LOG(_L("Wrong Own ID mask received (Different from the one sent)"));
       
  5498                 SetErrorStatus( KKmdIkeNegotFailed );
       
  5499                 SendNotifyL(INVALID_ID_INFORMATION);
       
  5500                 return EFalse;
       
  5501             }
       
  5502             break;
       
  5503         case ID_IPV6_ADDR:
       
  5504             Mem::Copy(&ip6addr.u.iAddr8, aInit_ID_payload->IDData(), sizeof(ip6addr.u.iAddr8));
       
  5505             tmp_addr.SetAddress(ip6addr);
       
  5506             if (!tmp_addr.Match(iLocalAddr1_ID_II))
       
  5507             {
       
  5508                 //The ID is not the one we sent!
       
  5509                 DEBUG_LOG(_L("Wrong Local ID received (Different from the one sent)"));
       
  5510                 SetErrorStatus( KKmdIkeNegotFailed );
       
  5511                 SendNotifyL(INVALID_ID_INFORMATION);
       
  5512                 return EFalse;
       
  5513             }
       
  5514             break;
       
  5515         case ID_IPV6_ADDR_SUBNET:
       
  5516             //subnet
       
  5517             Mem::Copy(&ip6addr.u.iAddr8, aInit_ID_payload->IDData(), sizeof(ip6addr.u.iAddr8));
       
  5518             tmp_addr.SetAddress(ip6addr);
       
  5519             if (!tmp_addr.Match(iLocalAddr1_ID_II))
       
  5520             {
       
  5521                 //The ID is not the one we sent!
       
  5522                 DEBUG_LOG(_L("Wrong Local ID subnet received (Different from the one sent)"));
       
  5523                 SetErrorStatus( KKmdIkeNegotFailed );
       
  5524                 SendNotifyL(INVALID_ID_INFORMATION);
       
  5525                 return EFalse;
       
  5526             }
       
  5527             //mask
       
  5528             Mem::Copy(&ip6addr.u.iAddr8, aInit_ID_payload->IDData() + sizeof(ip6addr.u.iAddr8), sizeof(ip6addr.u.iAddr8));
       
  5529             tmp_addr.SetAddress(ip6addr);
       
  5530             if (!tmp_addr.Match(iLocalAddr2_ID_II))
       
  5531             {
       
  5532                 //The ID is not the one we sent!
       
  5533                 DEBUG_LOG(_L("Wrong Local ID mask received (Different from the one sent)"));
       
  5534                 SetErrorStatus( KKmdIkeNegotFailed );
       
  5535                 SendNotifyL(INVALID_ID_INFORMATION);
       
  5536                 return EFalse;
       
  5537             }
       
  5538             break;
       
  5539         default:
       
  5540             DEBUG_LOG(_L("INVALID_ID_INFORMATION (ID Type not supported)"));
       
  5541             SetErrorStatus( KKmdIkeNegotFailed );
       
  5542             SendNotifyL(INVALID_ID_INFORMATION);
       
  5543             return EFalse;
       
  5544         }//switch
       
  5545     }
       
  5546     else    //No id sent (That means we're negotiating directly with the end host
       
  5547     {
       
  5548         if (!iLocalAddr1_ID_II.IsUnspecified())
       
  5549         {
       
  5550             DEBUG_LOG(_L("IDci expected and not received!"));
       
  5551             SetErrorStatus( KKmdIkeNegotFailed );
       
  5552             SendNotifyL(INVALID_ID_INFORMATION);
       
  5553             return EFalse;
       
  5554         }
       
  5555     }
       
  5556 
       
  5557     //We receive the peer (responder) proxy address or gateway client
       
  5558     if (aResp_ID_payload)   //ID Payload received
       
  5559     {
       
  5560         if (!CheckIdentL(aResp_ID_payload))
       
  5561             return EFalse;
       
  5562 
       
  5563         if (aResp_ID_payload->GetPort() != iIDRemotePort)
       
  5564         {
       
  5565             DEBUG_LOG(_L("INVALID_ID_INFORMATION (Remote Port different from the one sent)"));
       
  5566             SetErrorStatus( KKmdIkeNegotFailed );
       
  5567             SendNotifyL(INVALID_ID_INFORMATION);
       
  5568             return EFalse;
       
  5569         }
       
  5570 
       
  5571         if (aResp_ID_payload->GetProtocol() != iIDProtocol)
       
  5572         {
       
  5573             DEBUG_LOG(_L("INVALID_ID_INFORMATION (Responder ID Protocol different from the one sent)"));
       
  5574             SetErrorStatus( KKmdIkeNegotFailed );
       
  5575             SendNotifyL(INVALID_ID_INFORMATION);
       
  5576             return EFalse;
       
  5577         }
       
  5578 
       
  5579         switch (aResp_ID_payload->GetIDType())
       
  5580         {
       
  5581             case ID_IPV4_ADDR:
       
  5582                 Mem::Copy((TUint8 *)&addr4_int,aResp_ID_payload->IDData(),sizeof(TInt32));
       
  5583                 tmp_addr.SetAddress(ByteOrder::Swap32(addr4_int));
       
  5584                 DEBUG_LOG(_L("IDcr received"));
       
  5585                 if (!iRemoteAddr1_ID_II.Match(tmp_addr))
       
  5586                 {
       
  5587                     DEBUG_LOG(_L("INVALID_ID_INFORMATION (Wrong Remote ID, doesn't match sent one)"));
       
  5588                     SetErrorStatus( KKmdIkeNegotFailed );
       
  5589                     SendNotifyL(INVALID_ID_INFORMATION);
       
  5590                     return EFalse;
       
  5591                 }
       
  5592                 break;
       
  5593             case ID_IPV4_ADDR_SUBNET:
       
  5594                 //subnet address
       
  5595                 Mem::Copy((TUint8 *)&addr4_int,aResp_ID_payload->IDData(),sizeof(TInt32));
       
  5596                 tmp_addr.SetAddress(ByteOrder::Swap32(addr4_int));
       
  5597                 if (!tmp_addr.Match(iRemoteAddr1_ID_II))
       
  5598                 {
       
  5599                     //The ID subnet is not the one we sent!
       
  5600                     DEBUG_LOG(_L("Wrong Remote ID subnet received (Different from the one sent)"));
       
  5601                     SetErrorStatus( KKmdIkeNegotFailed );
       
  5602                     SendNotifyL(INVALID_ID_INFORMATION);
       
  5603                     return EFalse;
       
  5604                 }
       
  5605                 //Mask address
       
  5606                 Mem::Copy((TUint8 *)&addr4_int,aResp_ID_payload->IDData() + sizeof(TInt32),sizeof(TInt32));
       
  5607                 tmp_addr.SetAddress(ByteOrder::Swap32(addr4_int));          
       
  5608                 if (!tmp_addr.Match(iRemoteAddr2_ID_II))
       
  5609                 {
       
  5610                     //The ID mask is not the one we sent!
       
  5611                     DEBUG_LOG(_L("Wrong Remote ID mask received (Different from the one sent)"));
       
  5612                     SetErrorStatus( KKmdIkeNegotFailed );
       
  5613                     SendNotifyL(INVALID_ID_INFORMATION);
       
  5614                     return EFalse;
       
  5615                 }
       
  5616                 break;
       
  5617             case ID_IPV6_ADDR:
       
  5618                 Mem::Copy(&ip6addr.u.iAddr8,aResp_ID_payload->IDData(), sizeof(ip6addr.u.iAddr8));
       
  5619                 tmp_addr.SetAddress(ip6addr);
       
  5620                 DEBUG_LOG(_L("IDcr received"));
       
  5621                 if (!iRemoteAddr1_ID_II.Match(tmp_addr))
       
  5622                 {
       
  5623                     DEBUG_LOG(_L("INVALID_ID_INFORMATION (Wrong ID, doesn't match sent proxy)"));
       
  5624                     SetErrorStatus( KKmdIkeNegotFailed );
       
  5625                     SendNotifyL(INVALID_ID_INFORMATION);
       
  5626                     return EFalse;
       
  5627                 }
       
  5628                 break;
       
  5629             case ID_IPV6_ADDR_SUBNET:
       
  5630                 //subnet
       
  5631                 Mem::Copy(&ip6addr.u.iAddr8, aResp_ID_payload->IDData(), sizeof(ip6addr.u.iAddr8));
       
  5632                 tmp_addr.SetAddress(ip6addr);
       
  5633                 if (!tmp_addr.Match(iRemoteAddr1_ID_II))
       
  5634                 {
       
  5635                     //The ID is not the one we sent!
       
  5636                     DEBUG_LOG(_L("Wrong Remote ID subnet received (Different from the one sent)"));
       
  5637                     SetErrorStatus( KKmdIkeNegotFailed );
       
  5638                     SendNotifyL(INVALID_ID_INFORMATION);
       
  5639                     return EFalse;
       
  5640                 }
       
  5641                 //mask
       
  5642                 Mem::Copy(&ip6addr.u.iAddr8, aResp_ID_payload->IDData() + sizeof(ip6addr.u.iAddr8), sizeof(ip6addr.u.iAddr8));
       
  5643                 tmp_addr.SetAddress(ip6addr);
       
  5644                 if (!tmp_addr.Match(iRemoteAddr2_ID_II))
       
  5645                 {
       
  5646                     //The ID is not the one we sent!
       
  5647                     DEBUG_LOG(_L("Wrong Remote ID mask received (Different from the one sent)"));
       
  5648                     SetErrorStatus( KKmdIkeNegotFailed );
       
  5649                     SendNotifyL(INVALID_ID_INFORMATION);
       
  5650                     return EFalse;
       
  5651                 }
       
  5652                 break;
       
  5653             default:    //Only these 2 modes make sense no reason for subnets or range
       
  5654                 DEBUG_LOG(_L("INVALID_ID_INFORMATION (Remote ID Type not supported)"));
       
  5655                 SetErrorStatus( KKmdIkeNegotFailed );
       
  5656                 SendNotifyL(INVALID_ID_INFORMATION);
       
  5657                 return EFalse;
       
  5658         }//switch
       
  5659     }
       
  5660     else    //No id sent (That means we're negotiating directly with the end host. We check it's TRUE!
       
  5661     {
       
  5662         if (!iRemoteAddr1_ID_II.IsUnspecified())
       
  5663         {
       
  5664             DEBUG_LOG(_L("IDcr expected and not received!"));
       
  5665             SetErrorStatus( KKmdIkeNegotFailed );
       
  5666             SendNotifyL(INVALID_ID_INFORMATION);
       
  5667             return EFalse;
       
  5668         }
       
  5669     }
       
  5670 
       
  5671     return ETrue;
       
  5672 }
       
  5673 
       
  5674 
       
  5675 TBool CIkev1Negotiation::CheckIdentL(const TPayloadISAKMP *aPayload)
       
  5676 {
       
  5677     const TIdentISAKMP *ident = TIdentISAKMP::Ptr(aPayload);
       
  5678     
       
  5679     //payload not present
       
  5680     if (!ident)
       
  5681     {
       
  5682         DEBUG_LOG(_L("NO ID PAYLOAD"));
       
  5683         SetErrorStatus( KKmdIkeNegotFailed );
       
  5684         SendNotifyL(PAYLOAD_MALFORMED);
       
  5685         return EFalse;
       
  5686     }
       
  5687 
       
  5688     if (iPhase  == PHASE_I)
       
  5689     {
       
  5690         TUint8 protocol = ident->GetProtocol();
       
  5691         if ((protocol != KProtocolInetUdp) && (protocol != 0))
       
  5692         {
       
  5693             DEBUG_LOG(_L("INVALID_ID_INFORMATION: Bad Phase I Protocol (Only UDP(17) or 0 accepted)"));
       
  5694             SetErrorStatus( KKmdIkeNegotFailed );
       
  5695             SendNotifyL(INVALID_ID_INFORMATION);
       
  5696             return EFalse;
       
  5697         }
       
  5698         TUint16 port = ident->GetPort();
       
  5699         if ((port != 0) && (port != IKE_PORT) && (port != FLOATED_IKE_PORT) )
       
  5700         {
       
  5701             DEBUG_LOG(_L("INVALID_ID_INFORMATION: Invalid Bad Phase I Port. (Only 0, 500 or 4500 accepted)"));
       
  5702             SetErrorStatus( KKmdIkeNegotFailed );
       
  5703             SendNotifyL(INVALID_ID_INFORMATION);
       
  5704             return EFalse;
       
  5705         }
       
  5706         switch (ident->GetIDType())
       
  5707         {
       
  5708         case ID_IPV4_ADDR:
       
  5709         case ID_IPV6_ADDR:
       
  5710         case ID_FQDN:                       
       
  5711         case ID_USER_FQDN:
       
  5712         case ID_DER_ASN1_DN:
       
  5713             break;
       
  5714         default:
       
  5715             DEBUG_LOG(_L("INVALID_ID_INFORMATION: Invalid Type (Only IPV4/IPV6/User FQDN and DER ASN1 DN accepted in PHASE I)"));
       
  5716             SetErrorStatus( KKmdIkeNegotFailed );
       
  5717             SendNotifyL(INVALID_ID_INFORMATION);
       
  5718             return EFalse;
       
  5719         }
       
  5720     }
       
  5721 
       
  5722     return ETrue;
       
  5723 }
       
  5724 
       
  5725 
       
  5726 //Certificate Request Payload processing (all modes).
       
  5727 TBool CIkev1Negotiation::ProcessCertificateReqL(const TCertificateReqISAKMP *aCertReq)
       
  5728 {
       
  5729     if (iChosenProposal_I.iAttrList->iAuthMethod == IKE_A_CRACK)
       
  5730     {
       
  5731         DEBUG_LOG(_L("CR ignored when CRACK auth !)"));
       
  5732         return ETrue;
       
  5733     }
       
  5734 
       
  5735     TInt ret = CheckEncodingL(aCertReq->GetEncoding());
       
  5736     switch (ret)
       
  5737     {
       
  5738     case KErrGeneral:
       
  5739         return EFalse;
       
  5740     case KErrNotSupported:  //Not supported but not an error, just ignored
       
  5741         return ETrue;   
       
  5742     }
       
  5743 
       
  5744 	if ( !iPkiService )
       
  5745 	   return EFalse;
       
  5746 	TBool Status = EFalse;
       
  5747 	    //
       
  5748         // No specific CA asked. Find a certificate using own trusted CA list
       
  5749         //
       
  5750     if ( ReadOwnCertL())
       
  5751         {
       
  5752          Status = ETrue; 
       
  5753         }
       
  5754    
       
  5755     return Status;
       
  5756 
       
  5757 }
       
  5758 
       
  5759 
       
  5760 //Certificate Request Payload(s) processing (all modes).
       
  5761 TBool CIkev1Negotiation::ProcessCertificateReqArrayL(const CArrayFixFlat<const TCertificateReqISAKMP *> *aCRPayloadArray)
       
  5762 {
       
  5763 	
       
  5764     TInt count = aCRPayloadArray->Count();
       
  5765     if ( count == 0 )
       
  5766 	{
       
  5767        return ETrue;   // No Certificate requests   
       
  5768     }
       
  5769     
       
  5770     if ( ProcessCertificateReqL(aCRPayloadArray->At(0)) )
       
  5771        {
       
  5772         DEBUG_LOG(_L("User Certificate required by peer found"));           
       
  5773         iSendCert = ETrue;  //Requires sending our cert in next interchange where allowed/expected, otherwise not sent
       
  5774         return ETrue;
       
  5775        }
       
  5776     HBufC8* CAName = NULL;
       
  5777     CIkeCaList* trustedCaList = iPkiService->CaList();
       
  5778     
       
  5779     TInt Status=0;
       
  5780     
       
  5781     for (TInt i=0; i < trustedCaList->Count(); i++)
       
  5782         {
       
  5783         CIkeCaElem* CaElem = (*trustedCaList)[i];                     
       
  5784                 
       
  5785         CAName = IkeCert::GetCertificateFieldDERL(CaElem->Certificate(), KSubjectName);
       
  5786         CleanupStack::PushL(CAName);
       
  5787         
       
  5788         TRAP_IGNORE(Status=iPkiService->ReadChainL(iHostData, CAName)); 
       
  5789         
       
  5790         CleanupStack::PopAndDestroy(CAName);
       
  5791         CAName=NULL;
       
  5792         
       
  5793         if ( Status == KErrNone )
       
  5794             {
       
  5795              delete iOwnCert;
       
  5796              iOwnCert = iPkiService->GetCertificate();
       
  5797              
       
  5798              iICA1 = iPkiService->GetTrustedICA1();
       
  5799                     
       
  5800              iICA2 = iPkiService->GetTrustedICA2();
       
  5801              
       
  5802              iPeerTrustedCA = iPkiService->GetTrustedCA();
       
  5803              
       
  5804              iSendCert = ETrue;  //Requires sending our cert in next interchange where allowed/expected, otherwise not sent
       
  5805              
       
  5806              DEBUG_LOG(_L("Certificate chain Found!"));
       
  5807              return ETrue;
       
  5808              }
       
  5809         }
       
  5810     
       
  5811    
       
  5812     if ( Status == KVpnErrInvalidCaCertFile)
       
  5813         {
       
  5814          SetErrorStatus(KVpnErrInvalidCaCertFile);  
       
  5815          
       
  5816          SendNotifyL(CERTIFICATE_UNAVAILABLE);
       
  5817          
       
  5818          DEBUG_LOG(_L("Certificate chain read failed!"));
       
  5819            
       
  5820          return EFalse;
       
  5821         }
       
  5822 	
       
  5823     SetErrorStatus(KKmdIkeNoCertFoundErr);  
       
  5824     SendNotifyL(CERTIFICATE_UNAVAILABLE);
       
  5825     DEBUG_LOG(_L("Certificate Chain r!"));
       
  5826     
       
  5827     return EFalse;
       
  5828 }
       
  5829 
       
  5830 //Certificate Payload(s) processing (all modes).
       
  5831 TBool CIkev1Negotiation::ProcessCertificateArrayL(CArrayFixFlat<const TCertificateISAKMP *>* aCertArray)
       
  5832 {
       
  5833 	TBool Status;	
       
  5834 	if ( iCertRequested )
       
  5835 		 Status = EFalse;
       
  5836 	else Status = ETrue;
       
  5837 
       
  5838 	if ( iPkiService && aCertArray->Count() )
       
  5839 	{	        
       
  5840         const CIkeCaList* trustedCaList = iPkiService->CaList();
       
  5841     	CX509Certificate* PeerCert = IkePkiUtils::VerifyCertificateL(*aCertArray,
       
  5842     	                                                             *trustedCaList);
       
  5843     	if ( PeerCert )
       
  5844 	    {
       
  5845 		   delete iPeerX509Cert;
       
  5846 		   iPeerX509Cert = PeerCert;
       
  5847 	       DEBUG_LOG(_L("Peer Certificate is OK"));
       
  5848 		   Status = ETrue; 		
       
  5849 	    }
       
  5850 		else
       
  5851 		{
       
  5852 		   Status = EFalse;					
       
  5853 	       DEBUG_LOG(_L("Peer Certificate is rejected"));
       
  5854 		}			   
       
  5855 	}			
       
  5856 			
       
  5857 	return Status; 
       
  5858 }
       
  5859 
       
  5860 //Checks the signature sent by the peer host
       
  5861 TBool CIkev1Negotiation::ProcessSignatureL(const TSignatureISAKMP *aSigPayload)
       
  5862 {
       
  5863     TBool ret;
       
  5864     //payload not present
       
  5865     if (!aSigPayload || !iPeerX509Cert )
       
  5866     {
       
  5867         DEBUG_LOG(_L("NO SIG PAYLOAD"));
       
  5868 		SetErrorStatus(KKmdIkePeerAuthFailed);  				
       
  5869         SendNotifyL(PAYLOAD_MALFORMED);
       
  5870         return EFalse;
       
  5871     }
       
  5872 
       
  5873     //DSS only allows SHA1 as hash
       
  5874     TUint16 tmp = iChosenProposal_I.iAttrList->iHashAlg;
       
  5875     if (iChosenProposal_I.iAttrList->iAuthMethod==DSS_SIG)
       
  5876         iChosenProposal_I.iAttrList->iHashAlg = HASH_SHA1;
       
  5877 
       
  5878     TBuf8<ISAKMP_HASH_SIZE> hash;
       
  5879     //Verify the peer signature
       
  5880     if (iRole==RESPONDER)
       
  5881     {
       
  5882         ComputeHash1L(hash);   //Computes the value of iHASH_I the signature checking
       
  5883                             //Nothing else to compute.
       
  5884     }
       
  5885     else    //Initiator
       
  5886     {
       
  5887         ComputeHashrL(hash); //Computes the value of CRACK digest for signature checking
       
  5888     }
       
  5889 
       
  5890     ret = VerifySignatureL(iPeerX509Cert, (TUint8 *)hash.Ptr(), hash.Length(), aSigPayload->SigData(),aSigPayload->GetDataLength());
       
  5891 
       
  5892     //restores the value of the Hash alg.
       
  5893     iChosenProposal_I.iAttrList->iHashAlg = tmp;
       
  5894 
       
  5895     if (!ret)
       
  5896     {
       
  5897         DEBUG_LOG(_L("INVALID_SIGNATURE 2"));
       
  5898 		SetErrorStatus(KKmdIkePeerAuthFailed);				
       
  5899         SendNotifyL(INVALID_SIGNATURE);
       
  5900         return EFalse;
       
  5901     }
       
  5902 
       
  5903 	DEBUG_LOG(_L("Peer Signature is OK"));           	
       
  5904     return ETrue;
       
  5905 }
       
  5906 
       
  5907 
       
  5908 TBool CIkev1Negotiation::ProcessHashL(const THashISAKMP *aHashPayload)
       
  5909 {
       
  5910 	TBool Status = EFalse;
       
  5911 	if (aHashPayload)
       
  5912 	{
       
  5913         //Compute peer's hash							
       
  5914 		TBuf8<ISAKMP_HASH_SIZE> hash;
       
  5915 		if ( (iStage == 6) || ((iStage == 2) && (iExchange == ISAKMP_EXCHANGE_AGGR)))
       
  5916 			 ComputeHashrL(hash);
       
  5917 		else ComputeHash1L(hash);
       
  5918 		Status = (Mem::Compare((TUint8 *)hash.Ptr(), hash.Length(), aHashPayload->Data(), aHashPayload->DataLen()) == 0 );
       
  5919 		if ( !Status )
       
  5920 		{
       
  5921 			DEBUG_LOG(_L("INVALID_HASH_INFORMATION"));
       
  5922 			SendNotifyL(INVALID_HASH_INFORMATION);
       
  5923 		}
       
  5924 	}	
       
  5925 	
       
  5926     return Status;
       
  5927 }
       
  5928 
       
  5929 
       
  5930 TBool CIkev1Negotiation::ProcessHash2L(const ThdrISAKMP &aHdr, const THashISAKMP *aHashPayload, TUint aPadding)
       
  5931 {
       
  5932 	TBool Status = EFalse;
       
  5933     if ( aHashPayload )
       
  5934 	{
       
  5935 	   TUint8* hashMsg = (TUint8*)aHashPayload->Next();
       
  5936 	   TInt hashMsgLen = aHdr.GetLength() - sizeof(aHdr) - aHashPayload->GetLength() - aPadding;
       
  5937 	   Status = VerifyHash2L(aHashPayload, hashMsg, hashMsgLen);
       
  5938 	   if (!Status)
       
  5939 	   {
       
  5940 		   DEBUG_LOG(_L("INVALID_HASH_INFORMATION"));
       
  5941 		   SendNotifyL(INVALID_HASH_INFORMATION);
       
  5942        }
       
  5943 	}   
       
  5944 	else   
       
  5945     {
       
  5946        DEBUG_LOG(_L("PAYLOAD_MALFORMED"));
       
  5947        SendNotifyL(PAYLOAD_MALFORMED);
       
  5948     }
       
  5949 
       
  5950     return Status;
       
  5951 }
       
  5952 
       
  5953 
       
  5954 //Check a notification Payload inserted in a normal exchange (MAIN , AGGR, QUICK)
       
  5955 TBool CIkev1Negotiation::ProcessNotificationL(const TNotificationISAKMP *aNotifPayload)
       
  5956 {
       
  5957     if (!aNotifPayload)
       
  5958         return ETrue;   //optional so noting happens
       
  5959 
       
  5960     if (!CheckDOI(aNotifPayload->GetDOI()))
       
  5961     {
       
  5962         DEBUG_LOG(_L("Bad DOI in the NOT payload"));
       
  5963         SetErrorStatus( KKmdIkeNegotFailed );
       
  5964         SendNotifyL(DOI_NOT_SUPPORTED);  //send the informational exchange
       
  5965         return EFalse;
       
  5966     }
       
  5967     
       
  5968     switch(aNotifPayload->GetMsgType())
       
  5969     {
       
  5970     case DOI_RESPONDER_LIFETIME:
       
  5971         return ProcessResponderLifetimeL(aNotifPayload);
       
  5972     case DOI_REPLAY_STATUS:
       
  5973         return ProcessReplayStatus(aNotifPayload);
       
  5974     case DOI_INITIAL_CONTACT:
       
  5975         return ProcessInitialContactL(aNotifPayload);
       
  5976     default:
       
  5977         DEBUG_LOG(_L("INVALID MESSAGE TYPE in NOT payload"));
       
  5978         SetErrorStatus( KKmdIkeNegotFailed );
       
  5979         SendNotifyL(PAYLOAD_MALFORMED);
       
  5980         return EFalse;
       
  5981     }
       
  5982 
       
  5983 }
       
  5984 
       
  5985 
       
  5986 //Processes a RESPONDER-LIFETIME NOT payload
       
  5987 TBool CIkev1Negotiation::ProcessResponderLifetimeL(const TNotificationISAKMP *aNotifPayload)
       
  5988 {
       
  5989     TBuf8<2 * ISAKMP_COOKIE_SIZE> spi, own_neg_spi;
       
  5990     DEBUG_LOG(_L("Processing RESPONDER-LIFETIME"));
       
  5991 
       
  5992 			
       
  5993     if (!((iPhase == PHASE_II) && (iStage == 2)))
       
  5994     {
       
  5995 		if ( iPhase == PHASE_I ) {
       
  5996 		   DEBUG_LOG(_L("RESPONDER-LIFETIME payload in phase 1, ignored !!"));
       
  5997 		   return ETrue;		
       
  5998 		}
       
  5999 		else {
       
  6000   		   DEBUG_LOG(_L("Unexpected RESPONDER-LIFETIME payload (Bad stage)"));
       
  6001   		   SetErrorStatus( KKmdIkeNegotFailed );
       
  6002 		   SendNotifyL(INVALID_PAYLOAD_TYPE);
       
  6003     	   return EFalse;
       
  6004 		}	
       
  6005     }
       
  6006 
       
  6007     TUint8 protocol = aNotifPayload->GetProtocol();
       
  6008     if ((protocol != PROTO_IPSEC_AH) && (protocol != PROTO_IPSEC_ESP) &&
       
  6009         (protocol != PROTO_ISAKMP)   && (protocol != 0))
       
  6010     {
       
  6011         DEBUG_LOG(_L("Bad protocol in the RESPONDER-LIFETIME payload"));
       
  6012         SetErrorStatus( KKmdIkeNegotFailed );
       
  6013         SendNotifyL(INVALID_PROTOCOL_ID);
       
  6014         return EFalse;
       
  6015     }
       
  6016 
       
  6017     TUint8 spi_size = aNotifPayload->GetSPISize();
       
  6018     CProposal_II *prop;
       
  6019     TInt i;
       
  6020     //If SPI sent
       
  6021     switch (spi_size)
       
  6022     {
       
  6023     case 2 * ISAKMP_COOKIE_SIZE:    //ISAKMP spi
       
  6024         spi.Copy(aNotifPayload->GetSPI(), aNotifPayload->GetSPISize());
       
  6025         own_neg_spi.Copy(iCookie_I);
       
  6026         own_neg_spi.Append(iCookie_R);
       
  6027 
       
  6028         if (spi.Compare(own_neg_spi) != 0)
       
  6029         {
       
  6030             DEBUG_LOG(_L("Invalid SPI size in the RESPONDER-LIFETIME payload. Payload ignored"));
       
  6031             SetErrorStatus( KKmdIkeNegotFailed );
       
  6032             SendNotifyL(INVALID_SPI);
       
  6033             return EFalse;
       
  6034         }
       
  6035         if (iChosenProp_IIList->Count() > 1)    
       
  6036         {
       
  6037             DEBUG_LOG(_L("RESPONDER-LIFETIME ignored. More than one SA (need a IPsec SPI to know which one to use) "));
       
  6038             return EFalse;
       
  6039         }
       
  6040         prop = iChosenProp_IIList->At(0);       //Only one proposal
       
  6041         break;
       
  6042     case 0: //Compatibility with Alchemy cc500
       
  6043         if (iChosenProp_IIList->Count() > 1)    
       
  6044         {
       
  6045             DEBUG_LOG(_L("RESPONDER-LIFETIME ignored. More than one SA (need a IPsec SPI to know which one to use) "));
       
  6046             return EFalse;
       
  6047         }
       
  6048 
       
  6049         prop = iChosenProp_IIList->At(0);       //Only one proposal
       
  6050         break;
       
  6051     case sizeof(TUint32):           //IPSEC SPI
       
  6052         spi.Copy(aNotifPayload->GetSPI(), aNotifPayload->GetSPISize());
       
  6053         prop = NULL;    //Only for the debugger, the loop will have at least one proposal
       
  6054         for (i = 0; i < iChosenProp_IIList->Count(); i++)
       
  6055         {
       
  6056             prop = iChosenProp_IIList->At(i);       //Only one proposal
       
  6057             if (((prop->iSPI.Compare(spi) == 0) && prop->iProtocol == protocol)) //right prop   
       
  6058                 break;
       
  6059         }
       
  6060 
       
  6061         if (i == iChosenProp_IIList->Count())   //No prop matches
       
  6062         {
       
  6063             DEBUG_LOG(_L("RESPONDER-LIFETIME ignored. IPsec SPI doesn't match any chosen proposal"));
       
  6064             return EFalse;
       
  6065         }
       
  6066         break;
       
  6067     default:
       
  6068         DEBUG_LOG(_L("Bad SPI size in the RESPONDER-LIFETIME payload"));
       
  6069         return EFalse;
       
  6070     }
       
  6071     TAttrib_II *transform = prop->iAttrList->At(0); //Only one transform
       
  6072     TInt data_len = aNotifPayload->GetNotifDataSize();
       
  6073     TUint8 *data_ptr = aNotifPayload->GetNotifData();
       
  6074     TUint16 lifeType = 0;   //No type assigned yet
       
  6075     TInt64 lifeValue = 0;   //No type assigned yet
       
  6076     TInt64 lifeValue32;
       
  6077     TInt64 curr_lifeValue = 0;
       
  6078     TInt32 duration;
       
  6079 
       
  6080     TDataISAKMP *attr = (TDataISAKMP*)data_ptr;
       
  6081     while (data_len > 0)
       
  6082     {
       
  6083         data_len = data_len - attr->Size();
       
  6084         if (data_len < 0)   //Mismatch between lengths!!!
       
  6085         {
       
  6086             DEBUG_LOG(_L("RESPONDER-LIFETIME (Length mismatch in the attibutes)"));
       
  6087             return EFalse;
       
  6088         }
       
  6089         switch (attr->Type())
       
  6090         {
       
  6091         case DOI_ATTR_TYPE_LIFE_TYPE:           
       
  6092         case OAKLEY_ATTR_TYPE_LIFE_TYPE:
       
  6093             lifeType = attr->Value();
       
  6094             if (!CheckLifeType(lifeType))
       
  6095             {
       
  6096                 DEBUG_LOG(_L("RESPONDER-LIFETIME (Invalid lifetime type)"));
       
  6097                 return EFalse;
       
  6098             }
       
  6099             break;
       
  6100         case DOI_ATTR_TYPE_LIFE_DUR:                        
       
  6101         case OAKLEY_ATTR_TYPE_LIFE_DUR:
       
  6102             if (attr->IsBasic())
       
  6103             {
       
  6104                 duration = ByteOrder::Swap32(attr->Value());
       
  6105                 lifeValue = MAKE_TINT64(0, duration);
       
  6106                 lifeValue32 = I64LOW(lifeValue);                
       
  6107                 if (lifeType == SECONDS)
       
  6108                 {
       
  6109                     Desc8ToTInt64(transform->iLifeDurationSecs, curr_lifeValue);        //can't fail
       
  6110                     if (lifeValue < curr_lifeValue)
       
  6111                         transform->iLifeDurationSecs.Copy((TUint8 *)&lifeValue32, sizeof(lifeValue32));
       
  6112                 }
       
  6113                 else if (lifeType == KBYTES)
       
  6114                 {
       
  6115                     Desc8ToTInt64(transform->iLifeDurationKBytes, curr_lifeValue);  //can't fail
       
  6116                     if (lifeValue < curr_lifeValue)
       
  6117                         transform->iLifeDurationKBytes.Copy((TUint8 *)&lifeValue32, sizeof(lifeValue32));
       
  6118                 }
       
  6119                 else
       
  6120                 {
       
  6121                     DEBUG_LOG(_L("RESPONDER-LIFETIME (Invalid lifetime type)"));
       
  6122                     return EFalse;
       
  6123                 }
       
  6124             }
       
  6125             else    //Not basic
       
  6126             {
       
  6127                 TPtrC8 ptr(attr->VarValue(),attr->Length());
       
  6128 
       
  6129                 if (lifeType == SECONDS)
       
  6130                 {
       
  6131                     if (Desc8ToTInt64(ptr, lifeValue) != KErrNone)
       
  6132                         {
       
  6133                         DEBUG_LOG(_L("RESPONDER-LIFETIME Lifetime(Sec) Overflowed Setting to maximum value"));
       
  6134                         }
       
  6135                     Desc8ToTInt64(transform->iLifeDurationSecs, curr_lifeValue);        //can't fail
       
  6136                     if (lifeValue < curr_lifeValue)
       
  6137                         transform->iLifeDurationSecs.Copy(attr->VarValue(),attr->Length());
       
  6138                 }
       
  6139                 else if (lifeType == KBYTES)
       
  6140                 {
       
  6141                     if (Desc8ToTInt64(ptr, lifeValue) != KErrNone)
       
  6142                         {
       
  6143                         DEBUG_LOG(_L("RESPONDER-LIFETIME Lifetime(KBytes) Overflowed Setting to maximum value"));
       
  6144                         }
       
  6145                     Desc8ToTInt64(transform->iLifeDurationKBytes, curr_lifeValue);  //can't fail
       
  6146                     if (lifeValue < curr_lifeValue)
       
  6147                         transform->iLifeDurationKBytes.Copy(attr->VarValue(),attr->Length());
       
  6148                 }
       
  6149                 else
       
  6150                 {
       
  6151                     DEBUG_LOG(_L("RESPONDER-LIFETIME (Invalid lifetime type)"));
       
  6152                     return EFalse;
       
  6153                 }
       
  6154             }
       
  6155             break;
       
  6156         default:
       
  6157             DEBUG_LOG1(_L("RESPONDER-LIFETIME (Invalid attribute (%d) received)"), attr->Type());
       
  6158             return EFalse;
       
  6159         }//switch
       
  6160         attr = attr->Next();
       
  6161     }//while
       
  6162 
       
  6163     return ETrue;
       
  6164 }
       
  6165 
       
  6166 //Processes a REPLAY-STATUS NOT payload
       
  6167 TBool CIkev1Negotiation::ProcessReplayStatus(const TNotificationISAKMP *aNotifPayload)
       
  6168 {
       
  6169     TBuf8<2 * ISAKMP_COOKIE_SIZE> spi, own_neg_spi;
       
  6170 
       
  6171     DEBUG_LOG(_L("Processing REPLAY-STATUS"));
       
  6172 
       
  6173     if (!((iPhase == PHASE_II) && ((iStage == 1) || (iStage == 2))))
       
  6174     {
       
  6175         DEBUG_LOG(_L("Unexpected REPLAY-STATUS payload (Bad stage)"));
       
  6176         return EFalse;
       
  6177     }
       
  6178 
       
  6179     TUint8 protocol = aNotifPayload->GetProtocol();
       
  6180     if ((protocol != PROTO_IPSEC_AH) && (protocol != PROTO_IPSEC_ESP) &&
       
  6181         (protocol != PROTO_ISAKMP)   && (protocol != 0))
       
  6182     {
       
  6183         DEBUG_LOG(_L("Bad protocol in the REPLAY-STATUS payload"));
       
  6184         return EFalse;
       
  6185     }
       
  6186     
       
  6187     TInt i;
       
  6188     TUint8 spi_size = aNotifPayload->GetSPISize();
       
  6189     CProposal_II *prop;
       
  6190     //If SPI sent
       
  6191     switch (spi_size)
       
  6192     {
       
  6193     case 2 * ISAKMP_COOKIE_SIZE:    //ISAKMP spi
       
  6194         spi.Copy(aNotifPayload->GetSPI(), aNotifPayload->GetSPISize());
       
  6195         own_neg_spi.Copy(iCookie_I);
       
  6196         own_neg_spi.Append(iCookie_R);
       
  6197         if (spi.Compare(own_neg_spi) != 0)
       
  6198         {
       
  6199             DEBUG_LOG(_L("Invalid SPI size in the REPLAY-STATUS payload. Payload ignored"));
       
  6200             return EFalse;
       
  6201         }
       
  6202         if (iChosenProp_IIList->Count() > 1)    
       
  6203         {
       
  6204             DEBUG_LOG(_L("REPLAY-STATUS ignored. More than one IPsec SA (need an IPsec SPI to know which one to use) "));
       
  6205             return EFalse;
       
  6206         }
       
  6207         break;
       
  6208     case 0: //Compatibility with Alchemy cc500
       
  6209         if (iChosenProp_IIList->Count() > 1)
       
  6210         {
       
  6211             DEBUG_LOG(_L("RESPONDER-LIFETIME ignored. More than one SA (need a IPsec SPI to know which one to use) "));
       
  6212             return EFalse;
       
  6213         }
       
  6214         prop = iChosenProp_IIList->At(0);       //Only one proposal
       
  6215         break;
       
  6216     case sizeof(TUint32):           //IPSEC SPI
       
  6217         spi.Copy(aNotifPayload->GetSPI(), aNotifPayload->GetSPISize());
       
  6218         for (i = 0; i < iChosenProp_IIList->Count(); i++)
       
  6219         {
       
  6220             prop = iChosenProp_IIList->At(i);       //Only one proposal
       
  6221             if (((prop->iSPI.Compare(spi) == 0) && prop->iProtocol == protocol)) //right prop
       
  6222                 break;
       
  6223         }
       
  6224         if (i == iChosenProp_IIList->Count())   //No prop matches
       
  6225         {
       
  6226             DEBUG_LOG(_L("REPLAY-STATUS ignored. IPsec SPI doesn't match any chosen proposal"));
       
  6227             return EFalse;
       
  6228         }
       
  6229         break;
       
  6230     default:
       
  6231         DEBUG_LOG(_L("Bad SPI size in the REPLAY-STATUS payload"));
       
  6232         return EFalse;
       
  6233     }
       
  6234 
       
  6235     TInt data_len = aNotifPayload->GetNotifDataSize();
       
  6236     TUint32 *data = (TUint32 *)aNotifPayload->GetNotifData();
       
  6237     if (STATIC_CAST(TUint, data_len) < sizeof(*data))
       
  6238     {
       
  6239         DEBUG_LOG(_L("REPLAY-STATUS (Length mismatch in the attibutes)"));
       
  6240         return EFalse;
       
  6241     }
       
  6242 
       
  6243 #ifdef _DEBUG
       
  6244     if (ByteOrder::Swap32(*data) == 0)
       
  6245         DEBUG_LOG(_L("Anti-Replay Disabled on Peer Host"));
       
  6246     else
       
  6247         DEBUG_LOG(_L("Anti-Replay Enabled on Peer Host"));
       
  6248 #endif        
       
  6249     return ETrue;
       
  6250 }
       
  6251 
       
  6252 
       
  6253 TBool CIkev1Negotiation::ProcessInitialContactL(const TNotificationISAKMP *aNotifPayload)
       
  6254 {
       
  6255     TBuf8<2 * ISAKMP_COOKIE_SIZE> spi, neg_spi;
       
  6256 
       
  6257     DEBUG_LOG(_L("Processing INITIAL-CONTACT"));
       
  6258                                                               // 7 = CRACK 
       
  6259     if (!(iPhase == PHASE_I && (iStage == 5 || iStage == 6 || iStage == 7)))
       
  6260     {
       
  6261         DEBUG_LOG(_L("Unexpected INITIAL-CONTACT payload (Bad stage)"));
       
  6262         SetErrorStatus( KKmdIkeNegotFailed );
       
  6263         SendNotifyL(INVALID_PAYLOAD_TYPE);
       
  6264         return EFalse;
       
  6265     }
       
  6266 
       
  6267     if (aNotifPayload->GetProtocol() != PROTO_ISAKMP &&
       
  6268         aNotifPayload->GetProtocol() != 0 )
       
  6269         
       
  6270     {
       
  6271         DEBUG_LOG(_L("Bad protocol in the INITIAL_CONTACT payload"));
       
  6272         SetErrorStatus( KKmdIkeNegotFailed );
       
  6273         SendNotifyL(INVALID_PROTOCOL_ID);
       
  6274         return EFalse;
       
  6275     }
       
  6276 
       
  6277     if (aNotifPayload->GetSPISize() != 2 * ISAKMP_COOKIE_SIZE)
       
  6278     {
       
  6279         DEBUG_LOG(_L("Bad SPI size in the INITIAL_CONTACT payload"));
       
  6280         SetErrorStatus( KKmdIkeNegotFailed );
       
  6281         SendNotifyL(INVALID_SPI);
       
  6282         return EFalse;
       
  6283     }
       
  6284     spi.Copy(aNotifPayload->GetSPI(), aNotifPayload->GetSPISize());
       
  6285     neg_spi.Copy(iCookie_I);
       
  6286     neg_spi.Append(iCookie_R);
       
  6287 
       
  6288     if (spi.Compare(neg_spi) != 0)
       
  6289     {
       
  6290         DEBUG_LOG(_L("Invalid SPI size in the INITIAL_CONTACT payload"));
       
  6291         SetErrorStatus( KKmdIkeNegotFailed );
       
  6292         SendNotifyL(INVALID_SPI);
       
  6293         return EFalse;
       
  6294     }
       
  6295    
       
  6296     if ( iRole == RESPONDER )
       
  6297         {        
       
  6298         // Expired SAs are not returned.
       
  6299         TIkev1SAData* sa = iPluginSession->FindIkev1SADataWithAddr( iRemoteAddr );	
       
  6300         while ( sa != NULL )
       
  6301             {
       
  6302             iPluginSession->UpdateIkev1SAL( sa->iSAId, ETrue );
       
  6303             sa = iPluginSession->FindIkev1SADataWithAddr( iRemoteAddr );
       
  6304             }
       
  6305         
       
  6306         // Delete other ongoing negotiations.
       
  6307         CIkev1Negotiation* next = iPluginSession->FirstNegotiation();    
       
  6308         while ( next != NULL )
       
  6309             {
       
  6310             CIkev1Negotiation* current = next;
       
  6311             next = current->iNext;
       
  6312             if ( current != this )
       
  6313                 {
       
  6314                 delete current;
       
  6315                 }
       
  6316             }
       
  6317         }
       
  6318 
       
  6319     return ETrue;
       
  6320 }
       
  6321 
       
  6322 
       
  6323 
       
  6324 void CIkev1Negotiation::ProcessVendorL(CArrayFixFlat<const TVendorISAKMP*>* aVids)
       
  6325 {
       
  6326 	TBool result;	
       
  6327     TInt i = 0;
       
  6328 
       
  6329 	while ( i < aVids->Count() )
       
  6330 	{
       
  6331     	TVendorISAKMP* VendorPayload = (TVendorISAKMP*)aVids->At(i);
       
  6332         DEBUG_LOG(_L("Vendor ID received!\nHex: "));
       
  6333         DEBUG_LOG_ARRAY(VendorPayload->VIDData(), VendorPayload->GetLength() - sizeof(*VendorPayload));
       
  6334 				
       
  6335         if ( iLocalAddr.Family() == KAFUnspec )
       
  6336             User::LeaveIfError( iPluginSession->GetLocalAddress( iLocalAddr ) ); // No local address info, get it !
       
  6337 
       
  6338 		result = EFalse;
       
  6339         iNAT_T_Required = ProcessVendorId(&result,
       
  6340                                           (TUint8*)iCookie_I.Ptr(),
       
  6341                                           (TUint8*)iCookie_R.Ptr(),
       
  6342                                           iLocalAddr,
       
  6343                                           VendorPayload);
       
  6344         if ( result )
       
  6345 		{
       
  6346            iFamiliarPeer = result;
       
  6347 #ifdef _DEBUG           
       
  6348            DEBUG_LOG(_L("Nokia VPN gateway in peer!"));
       
  6349 		   if ( iNAT_T_Required  ) { 
       
  6350 	  	      DEBUG_LOG(_L("NAT Traversal needed!"));
       
  6351 		      if ( !iHostData->iUseNatProbing )
       
  6352 		      DEBUG_LOG(_L(" NAT probe not requested! NAT-T not used!"));    
       
  6353 		   }
       
  6354 #endif // _DEBUG	   
       
  6355 		   iNAT_T_Required = iNAT_T_Required & iHostData->iUseNatProbing;				   
       
  6356         }   
       
  6357         else
       
  6358 		{
       
  6359 		   if ( CheckDPDVendorId(VendorPayload) )
       
  6360 		   {
       
  6361 			  DEBUG_LOG(_L("Peer supports IETF Dead Peer Detection!"));			   
       
  6362 			  iDPDSupported = ETrue;
       
  6363 		   }	  
       
  6364 		   else if ( iNatDiscovery )
       
  6365 		   {
       
  6366               result = iNatDiscovery->CheckNatVendorId(VendorPayload);
       
  6367               if ( result )
       
  6368               {
       
  6369               	DEBUG_LOG(_L("Peer supports IETF (draft-03) NAT Traversal!"));              	
       
  6370               }
       
  6371               else
       
  6372               {
       
  6373               	result = iNatDiscovery->CheckRfcNatVendorId(VendorPayload);
       
  6374               	if ( result )
       
  6375               	    {
       
  6376               		iVendorIDRfc=ETrue;
       
  6377               	    DEBUG_LOG(_L("Peer supports IETF NAT Traversal!"));
       
  6378               	    }
       
  6379               }	
       
  6380 		   }		  
       
  6381 		}
       
  6382 
       
  6383 		i ++;		
       
  6384 	}
       
  6385 
       
  6386 }
       
  6387 
       
  6388 //
       
  6389 //Process Internal address payload received
       
  6390 //
       
  6391 void CIkev1Negotiation::ProcessIntAddrL(const TINTNETISAKMP *aIntnetPayload)
       
  6392 {
       
  6393     if ( aIntnetPayload && iFamiliarPeer && iHostData->iUseInternalAddr ) {
       
  6394        delete iInternalAddr; //delete if already exists (old)
       
  6395 	   iInternalAddr = NULL;
       
  6396        iInternalAddr = ProcessIntNetL((TINTNETISAKMP*) aIntnetPayload);
       
  6397 #ifdef _DEBUG       
       
  6398        if ( iInternalAddr) {  
       
  6399           TBuf<80> buf;
       
  6400           TBuf<40> txt_addr;
       
  6401           iInternalAddr->iClientIntAddr.OutputWithScope(txt_addr);
       
  6402           DEBUG_LOG1(_L("Internal address received: %S"),&txt_addr);
       
  6403        }
       
  6404 #endif       
       
  6405     }   
       
  6406 }
       
  6407 
       
  6408 //Computes the hash for phase II
       
  6409 void CIkev1Negotiation::ComputeHash2L(TDes8& aHash, TInt aStage, const TUint8 *aHashMsg, TInt aHashMsgLen)
       
  6410 {
       
  6411 	
       
  6412 	HBufC8* prf_data =
       
  6413     HBufC8::NewLC(((aHashMsgLen + iNONCE_I.Length() + iNONCE_R.Length() + (2*sizeof(TUint32))) | 0x3) + 1);
       
  6414 
       
  6415     if (aStage == 3)
       
  6416         prf_data->Des().Append(0);
       
  6417 
       
  6418     TUint32 id = ByteOrder::Swap32(iMessageId);
       
  6419     prf_data->Des().Append((TUint8*)&id,sizeof(iMessageId));
       
  6420     DEBUG_LOG(_L("ID"));
       
  6421     switch (aStage)
       
  6422     {
       
  6423     case 2:
       
  6424         prf_data->Des().Append(iNONCE_I);
       
  6425         //No break is intended
       
  6426     case 1:
       
  6427         prf_data->Des().Append(aHashMsg,aHashMsgLen);
       
  6428         break;
       
  6429     case 3:
       
  6430         
       
  6431         prf_data->Des().Append(iNONCE_I);
       
  6432         DEBUG_LOG(_L("iNONCE_I"));
       
  6433         prf_data->Des().Append(iNONCE_R);
       
  6434         DEBUG_LOG(_L("iNONCE_R"));
       
  6435         break;
       
  6436     default:
       
  6437 		CleanupStack::PopAndDestroy();  //prf_data		
       
  6438         return;
       
  6439     }
       
  6440 
       
  6441     DEBUG_LOG1(_L("Hash_II(%d) prf"),aStage);
       
  6442 
       
  6443     ComputePRFL(aHash, iSKEYID_a, prf_data->Des());
       
  6444     
       
  6445     DEBUG_LOG(_L("HASH"));
       
  6446 
       
  6447 	CleanupStack::PopAndDestroy();  //prf_data
       
  6448 
       
  6449 }
       
  6450 
       
  6451 //Computes the hash for a protected informational exchange
       
  6452 void CIkev1Negotiation::ComputeHashInfL(TDes8& aHash, const TUint8 *aHashMsg, TInt aHashMsgLen)
       
  6453 {
       
  6454 	
       
  6455 	HBufC8* prf_data =
       
  6456     HBufC8::NewLC(((aHashMsgLen + sizeof(iMessageId)) | 0x3) + 1);
       
  6457 
       
  6458     //prf(SKEYID_a, M_ID | N/D)
       
  6459     TUint32 id = ByteOrder::Swap32(iMessageId);
       
  6460     prf_data->Des().Append((TUint8*)&id, sizeof(iMessageId));
       
  6461 
       
  6462     prf_data->Des().Append(aHashMsg, aHashMsgLen);
       
  6463     
       
  6464     DEBUG_LOG(_L("Hash_NOT prf"));
       
  6465 
       
  6466     ComputePRFL(aHash, iSKEYID_a, prf_data->Des());
       
  6467 
       
  6468     DEBUG_LOG(_L("HASH"));
       
  6469 
       
  6470 	CleanupStack::PopAndDestroy();  //prf_data			
       
  6471 
       
  6472 }
       
  6473 
       
  6474 //Verifies that aHash is correct
       
  6475 TBool CIkev1Negotiation::VerifyHash2L(const THashISAKMP *aHash,const TUint8 *aHashMsg, TInt aHashMsgLen)
       
  6476 {
       
  6477 	TBuf8<ISAKMP_HASH_SIZE> tmp_hash;	
       
  6478 	
       
  6479     ComputeHash2L(tmp_hash, iStage, aHashMsg, aHashMsgLen);    //Computes the specified phase II hash
       
  6480 
       
  6481     TBool Status = (Mem::Compare((TUint8*)tmp_hash.Ptr(), tmp_hash.Length(), aHash->Data(), aHash->DataLen()) == 0);
       
  6482 
       
  6483 	return Status;
       
  6484 }
       
  6485 
       
  6486 //Verifies the hash of a Notification or Delete payload
       
  6487 // Used also to verify the hash of Transaction exchange (Attribute payload) 
       
  6488 TBool CIkev1Negotiation::VerifyInformationalHashL(const THashISAKMP *aHash,const TPayloadISAKMP *aPayload, TUint32 aMessageId)
       
  6489 {
       
  6490     TBuf8<MAX_PRF_LENGTH> tmp_hash;
       
  6491 
       
  6492     TUint32 tmp_id = ByteOrder::Swap32(aMessageId);
       
  6493     HBufC8 *prf_buf = HBufC8::NewLC(sizeof(tmp_id) + aPayload->GetLength());
       
  6494     prf_buf->Des().Copy((TUint8 *)&tmp_id , sizeof(tmp_id));
       
  6495     prf_buf->Des().Append((TUint8 *)aPayload, aPayload->GetLength());
       
  6496 
       
  6497     ComputePRFL(tmp_hash, iSKEYID_a, prf_buf->Des());
       
  6498     TPtrC8 hash_ptr(aHash->Data(),aHash->DataLen());
       
  6499     TBool b = (tmp_hash.Compare(hash_ptr)==0);
       
  6500     CleanupStack::PopAndDestroy();  //prf_buf
       
  6501     return (b);
       
  6502 }
       
  6503 
       
  6504 
       
  6505 //Computes Own Nonce using current time a seed
       
  6506 void CIkev1Negotiation::ComputeNonceL()
       
  6507 {
       
  6508     DEBUG_LOG(_L("Computed NONCE."));
       
  6509     if (iRole==INITIATOR)
       
  6510     {
       
  6511         iNONCE_I.SetLength(OAKLEY_DEFAULT_NONCE_SIZE);
       
  6512         TRandom::RandomL(iNONCE_I);
       
  6513     }
       
  6514     else
       
  6515     {       
       
  6516         iNONCE_R.SetLength(OAKLEY_DEFAULT_NONCE_SIZE);
       
  6517         TRandom::RandomL(iNONCE_R);
       
  6518     }
       
  6519 }
       
  6520 
       
  6521 //Computes HASH_R value
       
  6522 void CIkev1Negotiation::ComputeHashrL(TDes8 &aHash)
       
  6523 {
       
  6524     TInt    id_size = 0;
       
  6525     TUint16 auth_method = iChosenProposal_I.iAttrList->iAuthMethod;
       
  6526 
       
  6527     DEBUG_LOG(_L("Computing HASH_R"));
       
  6528 
       
  6529     if ( auth_method != IKE_A_CRACK ) {         
       
  6530        if (iRole==INITIATOR)   
       
  6531        {  //peer id. payload
       
  6532           id_size = iPeerIdentPayloadSize;
       
  6533           DEBUG_LOG(_L("PeerID"));
       
  6534        }
       
  6535        else    
       
  6536        {  //Own identification payload
       
  6537           id_size = iOwnIdentPayloadSize;
       
  6538           DEBUG_LOG(_L("OwnID"));
       
  6539        }
       
  6540     }   
       
  6541             
       
  6542     DEBUG_LOG(_L("SKEYID"));
       
  6543 
       
  6544     HBufC8 *prf_data;
       
  6545     if (iRole==INITIATOR)   //peer id. payload
       
  6546     {
       
  6547         prf_data = HBufC8::NewLC(iPeerPublicKey.Length() + iOwnPublicKey_ptr.Length() + iCookie_R.Length()
       
  6548         + iCookie_I.Length() + iSAPayloadSize + id_size);
       
  6549         prf_data->Des().Copy(iPeerPublicKey);
       
  6550         prf_data->Des().Append(iOwnPublicKey_ptr);
       
  6551         prf_data->Des().Append(iCookie_R);
       
  6552         prf_data->Des().Append(iCookie_I);
       
  6553         prf_data->Des().Append(iSAPayload,iSAPayloadSize);  //stored at the begining
       
  6554         if ( auth_method != IKE_A_CRACK )
       
  6555            prf_data->Des().Append(iPeerIdentPayload, iPeerIdentPayloadSize);
       
  6556     }
       
  6557     else    //RESPONDER
       
  6558     {
       
  6559         prf_data = HBufC8::NewLC(iOwnPublicKey_ptr.Length() + iPeerPublicKey.Length() + iCookie_R.Length()
       
  6560         + iCookie_I.Length() + iSAPayloadSize + id_size);
       
  6561         prf_data->Des().Copy(iOwnPublicKey_ptr);
       
  6562         prf_data->Des().Append(iPeerPublicKey);
       
  6563         prf_data->Des().Append(iCookie_R);
       
  6564         prf_data->Des().Append(iCookie_I);
       
  6565         prf_data->Des().Append(iSAPayload,iSAPayloadSize);  //stored at the begining
       
  6566         if ( auth_method != IKE_A_CRACK )
       
  6567            prf_data->Des().Append(iOwnIdentPayload, iOwnIdentPayloadSize);
       
  6568     }
       
  6569 
       
  6570     DEBUG_LOG(_L("PRF"));
       
  6571 
       
  6572     ComputePRFL(aHash, iSKEYID, prf_data->Des());
       
  6573 
       
  6574     CleanupStack::PopAndDestroy();  //prf_data
       
  6575 
       
  6576     DEBUG_LOG(_L("HASH_R"));
       
  6577 
       
  6578 }
       
  6579 
       
  6580 
       
  6581 //Computes the value of iHASH_I
       
  6582 void CIkev1Negotiation::ComputeHash1L(TDes8 &aHash)
       
  6583 {
       
  6584     TInt    id_size = 0;
       
  6585     TUint16 auth_method = iChosenProposal_I.iAttrList->iAuthMethod; 
       
  6586 
       
  6587     DEBUG_LOG(_L("Computing HASH_I"));
       
  6588 
       
  6589     if ( auth_method != IKE_A_CRACK ) {         
       
  6590        if (iRole==INITIATOR)   //Own identification payload
       
  6591        {
       
  6592           id_size = iOwnIdentPayloadSize;
       
  6593           DEBUG_LOG(_L("OwnID"));
       
  6594        }
       
  6595        else    //peer id. payload
       
  6596        {
       
  6597           id_size = iPeerIdentPayloadSize;
       
  6598           DEBUG_LOG(_L("PeerID"));
       
  6599        }
       
  6600     }   
       
  6601             
       
  6602             
       
  6603     DEBUG_LOG(_L("SKEYID"));
       
  6604 
       
  6605     HBufC8 *prf_data;
       
  6606     if (iRole==INITIATOR)
       
  6607     {
       
  6608         prf_data = HBufC8::NewLC(iOwnPublicKey_ptr.Length() + iPeerPublicKey.Length() + iCookie_I.Length()
       
  6609         + iCookie_R.Length() + iSAPayloadSize + id_size);
       
  6610         prf_data->Des().Copy(iOwnPublicKey_ptr);
       
  6611         prf_data->Des().Append(iPeerPublicKey);
       
  6612         prf_data->Des().Append(iCookie_I);
       
  6613         prf_data->Des().Append(iCookie_R);
       
  6614         prf_data->Des().Append(iSAPayload,iSAPayloadSize);  //stored at the begining
       
  6615         if ( auth_method != IKE_A_CRACK )
       
  6616            prf_data->Des().Append(iOwnIdentPayload,iOwnIdentPayloadSize);      
       
  6617     }
       
  6618     else    //RESPONDER
       
  6619     {
       
  6620         prf_data = HBufC8::NewLC(iPeerPublicKey.Length() + iOwnPublicKey_ptr.Length() + iCookie_I.Length()
       
  6621                                  + iCookie_R.Length() + iSAPayloadSize + id_size);
       
  6622         prf_data->Des().Copy(iPeerPublicKey);
       
  6623         prf_data->Des().Append(iOwnPublicKey_ptr);
       
  6624         prf_data->Des().Append(iCookie_I);
       
  6625         prf_data->Des().Append(iCookie_R);
       
  6626         prf_data->Des().Append(iSAPayload,iSAPayloadSize);  //stored at the begining
       
  6627 
       
  6628         if ( auth_method != IKE_A_CRACK )       
       
  6629            prf_data->Des().Append(iPeerIdentPayload, iPeerIdentPayloadSize);        
       
  6630     }   
       
  6631 
       
  6632     DEBUG_LOG(_L("PRF"));
       
  6633 
       
  6634     ComputePRFL(aHash, iSKEYID, prf_data->Des());
       
  6635     CleanupStack::PopAndDestroy();  //prf_buf
       
  6636     DEBUG_LOG(_L("HASH_I"));
       
  6637 }
       
  6638 
       
  6639 
       
  6640 //Checks the encryption alg is valid
       
  6641 TBool CIkev1Negotiation::CheckEncrAlg(TUint16 aValue)
       
  6642 {
       
  6643     switch (aValue)
       
  6644     {
       
  6645     case DES_CBC:
       
  6646     case DES3_CBC:
       
  6647     case AES_CBC:
       
  6648         return ETrue;
       
  6649     case IDEA_CBC:
       
  6650     case BLOWFISH_CBC:
       
  6651     case RC5_R16_B64_CBC:
       
  6652     case CAST_CBC:
       
  6653         DEBUG_LOG(_L("Not implemented Encr algorithm"));
       
  6654         return ETrue; // Unknown attribute value NOT a fatal error !            
       
  6655     }
       
  6656     DEBUG_LOG(_L("Bad Encr algorithm"));
       
  6657 
       
  6658     return ETrue; // Unknown attribute value NOT a fatal error !
       
  6659 }
       
  6660 
       
  6661 
       
  6662 
       
  6663 TBool CIkev1Negotiation::CheckHashAlg(TUint16 aValue)
       
  6664 {
       
  6665     switch (aValue)
       
  6666     {
       
  6667     case HASH_MD5:
       
  6668     case HASH_SHA1:
       
  6669         return ETrue;
       
  6670     case HASH_TIGER:
       
  6671         DEBUG_LOG(_L("Not implemented Hash algorithm"));
       
  6672         return ETrue; // Unknown attribute value NOT a fatal error !                            
       
  6673     }
       
  6674     DEBUG_LOG(_L("Bad Hash algorithm"));
       
  6675         return ETrue; // Unknown attribute value NOT a fatal error !                        
       
  6676 
       
  6677 }
       
  6678 
       
  6679 
       
  6680 TBool CIkev1Negotiation::CheckAuthMethod(TUint16 aValue)
       
  6681 {
       
  6682     switch (aValue)
       
  6683     {   
       
  6684     case PRE_SHARED:
       
  6685         if (iHostData->iPresharedKey.iKey.Length()==0)  //No preshared key defined
       
  6686         {
       
  6687             DEBUG_LOG(_L("Authentication method error (No Preshared key available"));
       
  6688             return EFalse;
       
  6689         }
       
  6690         return ETrue;
       
  6691     case RSA_SIG:
       
  6692     case DSS_SIG:
       
  6693     case IKE_A_CRACK:       
       
  6694         return ETrue;
       
  6695     }
       
  6696     DEBUG_LOG(_L("Bad Authentication method"));
       
  6697     return ETrue; // Unknown attribute value NOT a fatal error !
       
  6698 
       
  6699 }
       
  6700 
       
  6701 TBool CIkev1Negotiation::CheckGroupDesc(TUint16 aValue)
       
  6702 {
       
  6703     switch (aValue)
       
  6704     {
       
  6705     case MODP_768:
       
  6706     case MODP_1024:
       
  6707     case MODP_1536:     
       
  6708     case MODP_2048:
       
  6709         return ETrue;
       
  6710     case EC2N_155:
       
  6711     case EC2N_185:
       
  6712         break;
       
  6713     }
       
  6714 
       
  6715     return ETrue; // Unknown attribute value NOT a fatal error !    
       
  6716 }
       
  6717 
       
  6718 
       
  6719 TBool CIkev1Negotiation::CheckGroupType(TUint16 aValue)
       
  6720 {
       
  6721     switch(aValue)
       
  6722     {
       
  6723     case MODP:
       
  6724         return ETrue;
       
  6725     case ECP:
       
  6726     case EC2N:
       
  6727         break;      
       
  6728     }
       
  6729 
       
  6730     return ETrue; // Unknown attribute value NOT a fatal error !        
       
  6731 
       
  6732 }
       
  6733 
       
  6734 TBool CIkev1Negotiation::CheckGroupPrime(const TUint8* /* aValue */, TUint16 /* length */)
       
  6735 {
       
  6736     return ETrue;
       
  6737 }
       
  6738 
       
  6739 TBool CIkev1Negotiation::CheckGroupGen(const TUint8* /* aValue */, TUint16 /* length */)
       
  6740 {
       
  6741     return ETrue;
       
  6742 }
       
  6743 
       
  6744 TBool CIkev1Negotiation::CheckGroupCurve(const TUint8* /* aValue */, TUint16 /* length */)
       
  6745 {
       
  6746     return ETrue;
       
  6747 }
       
  6748 
       
  6749 //Used for Phase I and II
       
  6750 TBool CIkev1Negotiation::CheckLifeType(TUint16 aValue)
       
  6751 {
       
  6752     switch(aValue)
       
  6753     {
       
  6754     case SECONDS:
       
  6755     case KBYTES:
       
  6756         return ETrue;
       
  6757     }
       
  6758     return EFalse;
       
  6759 }
       
  6760 
       
  6761 TBool CIkev1Negotiation::CheckLifeDuration(const TUint8* /* aValue */, TUint16 /* length */)
       
  6762 {
       
  6763     return ETrue;
       
  6764 }
       
  6765 
       
  6766 TBool CIkev1Negotiation::CheckPRF(TUint16 aValue)
       
  6767 {
       
  6768     if (aValue!=OAKLEY_PRF_3DES_CBC_MAC)
       
  6769     {
       
  6770         DEBUG_LOG(_L("Bad PRF"));    
       
  6771         return EFalse;
       
  6772     }
       
  6773     return ETrue;
       
  6774 }
       
  6775 
       
  6776 TBool CIkev1Negotiation::CheckKeyLength(TUint16 /*aValue*/,TUint8 aID,TUint8 aProtocol)
       
  6777 {
       
  6778     TBool Status = ETrue;
       
  6779     switch (aProtocol)
       
  6780     {
       
  6781     case PROTO_ISAKMP:
       
  6782         if ( aID != AES_CBC )
       
  6783 		{	
       
  6784            Status = EFalse; //all other supported algs have fixed size
       
  6785 		   DEBUG_LOG(_L("Key length specified with fixed ISAKMP encryption algorithm"));
       
  6786 		}
       
  6787         break;
       
  6788     case PROTO_IPSEC_AH:
       
  6789         Status = EFalse;      //Supported algorithms have fixed key length
       
  6790 		DEBUG_LOG(_L("Key length specified with fixed AH integrity algorithm"));
       
  6791         break;
       
  6792     case PROTO_IPSEC_ESP:
       
  6793 		if ( aID != ESP_AES_CBC )
       
  6794 		{	
       
  6795 		   Status = EFalse;
       
  6796 		   DEBUG_LOG(_L("Key length specified with fixed ESP encryption algorithm"));		   
       
  6797 		}   
       
  6798         break;
       
  6799     default:    //Unsupported SA type
       
  6800 		Status = EFalse;      //Supported algorithms have fixed key length
       
  6801 		break;
       
  6802     }
       
  6803 
       
  6804 	return Status;
       
  6805 }
       
  6806 
       
  6807 TBool CIkev1Negotiation::CheckFieldSize(TUint16 /* aValue */)
       
  6808 {
       
  6809     DEBUG_LOG(_L("Field size not supported"));
       
  6810     return EFalse;
       
  6811 }
       
  6812 
       
  6813 TBool CIkev1Negotiation::CheckGroupOrder(const TUint8* /* aValue */, TUint16 /* length */)
       
  6814 {
       
  6815     DEBUG_LOG(_L("Group Order not supported "));
       
  6816     return ETrue; // Unknown attribute value NOT a fatal error !                    
       
  6817 }
       
  6818 
       
  6819 //Encapsulation mode
       
  6820 TBool CIkev1Negotiation::CheckEncMode(TUint16 aValue)
       
  6821 {
       
  6822     switch (aValue)
       
  6823     {
       
  6824     case DOI_TUNNEL:
       
  6825     case DOI_TRANSPORT:
       
  6826         return ETrue;
       
  6827     case UDP_ENC_TUNNEL:
       
  6828     case UDP_RFC_ENC_TUNNEL:
       
  6829 //  case UDP_ENC_TRANSPORT:  
       
  6830         if ( iNAT_D_Flags )
       
  6831            return ETrue;
       
  6832         break;
       
  6833     }
       
  6834 
       
  6835     DEBUG_LOG(_L("Bad Encapsulation mode"));
       
  6836     return EFalse;
       
  6837     
       
  6838 }
       
  6839 
       
  6840 //defined authentication algorithm types. Other are invalid.
       
  6841 TBool CIkev1Negotiation::CheckAuthAlg(TUint16 aValue)
       
  6842 {
       
  6843     switch (aValue)
       
  6844     {
       
  6845     case DOI_HMAC_MD5:
       
  6846     case DOI_HMAC_SHA:
       
  6847         return ETrue;
       
  6848 	case DOI_DES_MAC:		
       
  6849     case DOI_KPDK:
       
  6850         DEBUG_LOG(_L("Unimplemented Auhentication Algorithm"));
       
  6851     }
       
  6852     DEBUG_LOG(_L("Bad Auhentication Algorithm"));
       
  6853     return ETrue; // Unknown attribute value NOT a fatal error !                        
       
  6854 }
       
  6855 
       
  6856 //By now only X509_CERT_SIG. Tristate error codes:
       
  6857 //KErrNone -> accepted
       
  6858 //KErrNotSupported ignored but no error Notification.
       
  6859 //KErrGeneral: NOT accepted 
       
  6860 TInt CIkev1Negotiation::CheckEncodingL(TUint8 aEncoding)
       
  6861 {
       
  6862     switch (aEncoding)
       
  6863     {
       
  6864     case X509_CERT_SIG://X.509 Certificate - Signature
       
  6865         break;
       
  6866     case CRL://Certificate Revocation List (CRL)
       
  6867         DEBUG_LOG(_L("WARNING: CRL ignored because not supported"));
       
  6868         return KErrNotSupported;    //No notification, just ignored!
       
  6869     case PKCS://PKCS #7 wrapped X.509 certificate
       
  6870     case PGP://PGP Certificate
       
  6871     case DNS ://DNS Signed Key
       
  6872     case X509_CERT_KE://X.509 Certificate - Key Exchange
       
  6873     case KERBEROS://Kerberos Tokens
       
  6874     case ARL://Authority Revocation List (ARL)
       
  6875     case SPKI://SPKI Certificate
       
  6876     case X509_CERT_ATTR://X.509 Certificate - Attribute
       
  6877         DEBUG_LOG(_L("CERT_TYPE_UNSUPPORTED (not supported CERT type)"));
       
  6878         SendNotifyL(CERT_TYPE_UNSUPPORTED);
       
  6879         return KErrNotSupported;    // No notification, just ignored!        
       
  6880 
       
  6881     default://Invalid encoding type
       
  6882         DEBUG_LOG(_L("INVALID_CERT_ENCODING (not existent CERT type)"));
       
  6883         SendNotifyL(INVALID_CERT_ENCODING);
       
  6884         return KErrNotSupported;    // No notification, just ignored!                
       
  6885 
       
  6886     }
       
  6887 
       
  6888     return KErrNone;
       
  6889 }
       
  6890 
       
  6891 
       
  6892 //Provisional (Uses as a seed time, Address and port)
       
  6893 TCookie CIkev1Negotiation::CreateCookieL() const
       
  6894 {
       
  6895     TCookie c;
       
  6896     //Cookie generation is Random no longer uses known data like addr
       
  6897     //or port (wrong?)
       
  6898     c.SetLength(ISAKMP_COOKIE_SIZE);
       
  6899 	TRandom::RandomL(c);
       
  6900     return c;
       
  6901 }
       
  6902 
       
  6903 TInt32 CIkev1Negotiation::RandomMessageId()
       
  6904 {
       
  6905     TTime tmp_time;
       
  6906     tmp_time.UniversalTime();
       
  6907     TInt64 seed = tmp_time.Int64();
       
  6908     TInt32 rand = Math::Rand(seed);
       
  6909     return rand;
       
  6910 }
       
  6911 
       
  6912 TBool CIkev1Negotiation::CheckCookies(const TCookie& aInit, const TCookie& aResp)
       
  6913     {
       
  6914     TCookie NULL_COOKIE;
       
  6915     NULL_COOKIE.FillZ(ISAKMP_COOKIE_SIZE);
       
  6916 
       
  6917     if ( iCookie_I.Compare(NULL_COOKIE) != 0 &&
       
  6918          iCookie_I.Compare(aInit) != 0 )
       
  6919         {
       
  6920         DEBUG_LOG(_L("Initiator COOKIE incorrect"));
       
  6921         return EFalse;
       
  6922         }
       
  6923     if ( iCookie_R.Compare(NULL_COOKIE) != 0 &&
       
  6924          iCookie_R.Compare(aResp) != 0 )
       
  6925         {
       
  6926         DEBUG_LOG(_L("Responder COOKIE incorrect"));
       
  6927         return EFalse;
       
  6928         }
       
  6929 
       
  6930     return ETrue;    
       
  6931     }
       
  6932 
       
  6933 //Checks if the payload value is correct
       
  6934 TBool CIkev1Negotiation::CheckPayloadCode(TUint8 aPayload)
       
  6935 {
       
  6936     switch (aPayload)
       
  6937     {
       
  6938     case ISAKMP_PAYLOAD_NONE:
       
  6939     case ISAKMP_PAYLOAD_SA:
       
  6940     case ISAKMP_PAYLOAD_P:
       
  6941     case ISAKMP_PAYLOAD_T:
       
  6942     case ISAKMP_PAYLOAD_KE:
       
  6943     case ISAKMP_PAYLOAD_ID:
       
  6944     case ISAKMP_PAYLOAD_CERT:
       
  6945     case ISAKMP_PAYLOAD_CR:
       
  6946     case ISAKMP_PAYLOAD_HASH:
       
  6947     case ISAKMP_PAYLOAD_SIG:
       
  6948     case ISAKMP_PAYLOAD_NONCE:
       
  6949     case ISAKMP_PAYLOAD_NOTIF:
       
  6950     case ISAKMP_PAYLOAD_D:
       
  6951     case ISAKMP_PAYLOAD_VID:
       
  6952     case ISAKMP_PAYLOAD_ATTRIBUTES:                         
       
  6953     case ISAKMP_PAYLOAD_CHRE:
       
  6954     case ISAKMP_INT_NETWORK:
       
  6955     case IETF_NAT_DISCOVERY:
       
  6956     case IETF_RFC_NAT_DISCOVERY:
       
  6957     case IETF_NAT_ORIG_ADDR:
       
  6958     case IETF_RFC_NAT_ORIG_ADDR:
       
  6959         return ETrue;   //supported payload type
       
  6960     }
       
  6961     DEBUG_LOG1(_L("INVALID_PAYLOAD_TYPE (%x)"),aPayload);
       
  6962     return EFalse;
       
  6963 
       
  6964 }
       
  6965 
       
  6966 
       
  6967 //Checks if the version (major,minor) is supported
       
  6968 TBool CIkev1Negotiation::CheckVersionL(TUint8 aVersion)
       
  6969 {
       
  6970     if (aVersion >> 4  > MAJOR)
       
  6971     {
       
  6972         DEBUG_LOG(_L("INVALID_MAJOR_VERSION"));
       
  6973         SendNotifyL(INVALID_MAJOR_VERSION);
       
  6974         return EFalse;
       
  6975     }
       
  6976 
       
  6977     if (aVersion & (0x0f) > MINOR)
       
  6978     {
       
  6979         DEBUG_LOG(_L("INVALID_MINOR_VERSION"));
       
  6980         SendNotifyL(INVALID_MINOR_VERSION);
       
  6981         return EFalse;
       
  6982     }
       
  6983 
       
  6984     return ETrue;   //version correct
       
  6985 }
       
  6986 
       
  6987 //Checks if the exchange type is valid and the same as in the negotiation
       
  6988 TBool CIkev1Negotiation::CheckExchangeTypeL(TUint8 aType)
       
  6989 {
       
  6990     switch (aType)
       
  6991     {
       
  6992     case ISAKMP_EXCHANGE_ID:    //Main
       
  6993     case ISAKMP_EXCHANGE_AGGR:  // Agressive
       
  6994     case ISAKMP_EXCHANGE_INFO:
       
  6995     case IKE_QUICK_MODE:
       
  6996         //invalid Exchange Type Not the same being used and not an error notification
       
  6997         if (aType != iExchange)
       
  6998         {
       
  6999             DEBUG_LOG(_L("INVALID_EXCHANGE_TYPE"));  //send the informational exchange
       
  7000             SendNotifyL(INVALID_EXCHANGE_TYPE);  //send the informational exchange
       
  7001             return EFalse;  //invalid Exchange Type
       
  7002         }
       
  7003         break;
       
  7004     case ISAKMP_EXCHANGE_BASE:  // Base
       
  7005     case ISAKMP_EXCHANGE_NONE:  // Identity Protection (Main mode in IKE)
       
  7006     case ISAKMP_EXCHANGE_AUTH:  // Authentication Only
       
  7007     case IKE_NEW_GROUP_MODE:    // New Group Mode
       
  7008         DEBUG_LOG(_L("INVALID_EXCHANGE_TYPE"));  //send the informational exchange
       
  7009         SendNotifyL(UNSUPPORTED_EXCHANGE_TYPE);  //send the informational exchange
       
  7010         return EFalse;
       
  7011     }
       
  7012 
       
  7013     return ETrue;
       
  7014 }
       
  7015 
       
  7016 //Checks the non-relevant bits are 0. Other comprovations are done when needed
       
  7017 TBool CIkev1Negotiation::CheckFlagsL(TUint8 aFlags)
       
  7018 {
       
  7019     if (aFlags >> 3 != 0)
       
  7020     {
       
  7021         DEBUG_LOG(_L("INVALID_FLAGS"));  //send the informational exchange
       
  7022         SendNotifyL(INVALID_FLAGS);  //send the informational exchange
       
  7023         return EFalse;
       
  7024     }
       
  7025 
       
  7026     return ETrue;
       
  7027 }
       
  7028 
       
  7029 //Checks the Id has a correct value. 0 in Phase I, the correct one in Phase II
       
  7030 TBool CIkev1Negotiation::CheckMessageIdL(TUint32 aId)
       
  7031 {
       
  7032     if (aId != iMessageId)    //iMessageId will be 0 during Phase I
       
  7033     {
       
  7034         DEBUG_LOG2(_L("INVALID_MESSAGE_ID %u (neg=%u)"),aId, iMessageId);
       
  7035         SendNotifyL(INVALID_MESSAGE_ID); //send the informational exchange
       
  7036         return EFalse;
       
  7037     }
       
  7038     return ETrue;
       
  7039 }
       
  7040 
       
  7041 //Checks the DOI is valid
       
  7042 TBool CIkev1Negotiation::CheckDOI(TUint32 aDOI)
       
  7043 {
       
  7044     if (aDOI > IPSEC_DOI)    //Not IPSEC nor ISAKMP DOI
       
  7045         return EFalse;
       
  7046 
       
  7047     return ETrue;
       
  7048 }
       
  7049 
       
  7050 //Checks the SIT is valid
       
  7051 TBool CIkev1Negotiation::CheckSituationL(TUint32 aSIT)
       
  7052 {
       
  7053     //Secrecy and integrity not yet supported
       
  7054     if ((aSIT & IPSEC_SIT_SECRECY) || (aSIT & IPSEC_SIT_INTEGRITY))
       
  7055     {
       
  7056         DEBUG_LOG(_L("SITUATION_NOT_SUPPORTED"));    //send the informational exchange
       
  7057         SendNotifyL(SITUATION_NOT_SUPPORTED);    //send the informational exchange
       
  7058         return EFalse;
       
  7059     }
       
  7060 
       
  7061     return ETrue;
       
  7062 }
       
  7063 //check the generic payload is OK. Correct payload + Reserved==0
       
  7064 TBool CIkev1Negotiation::CheckGenericPayloadL(const TPayloadISAKMP *aPayload)
       
  7065 {
       
  7066     if (!CheckPayloadCode(aPayload->GetPayload()))
       
  7067         return EFalse;
       
  7068 
       
  7069     if (aPayload->GetReserved() != 0)   //Must be always 0
       
  7070     {
       
  7071         DEBUG_LOG(_L("INVALID RESERVED FIELD"));
       
  7072         SendNotifyL(PAYLOAD_MALFORMED);
       
  7073         return EFalse;
       
  7074     }
       
  7075 
       
  7076     if ((aPayload->GetLength() < MIN_ISAKMP_PAYLOAD_SIZE) || (aPayload->GetLength() > iLengthLeft))
       
  7077     {
       
  7078         DEBUG_LOG(_L("BAD PAYLOAD SIZE"));
       
  7079         SendNotifyL(PAYLOAD_MALFORMED);
       
  7080         return EFalse;
       
  7081     }
       
  7082 
       
  7083     iLengthLeft -= aPayload->GetLength();   //Updates the length left in the buffer
       
  7084 
       
  7085     return ETrue;
       
  7086 
       
  7087 }
       
  7088 
       
  7089 //checks if protocol supported
       
  7090 TBool CIkev1Negotiation::CheckProtocolL(TUint8 aProtocol)
       
  7091 {
       
  7092     switch (aProtocol)
       
  7093     {
       
  7094         //PHASE_I Protocol
       
  7095         case PROTO_ISAKMP:  //Only when establishing own SA??
       
  7096             if (iPhase != PHASE_I)
       
  7097             {
       
  7098                 DEBUG_LOG(_L("INVALID_PROTOCOL_ID (ISAKMP only allowed in Phase I)"));
       
  7099                 SendNotifyL(INVALID_PROTOCOL_ID);
       
  7100                 return EFalse;
       
  7101             }
       
  7102             return ETrue;
       
  7103 			
       
  7104         //PHASE_II Protocols
       
  7105         case PROTO_IPSEC_AH:
       
  7106         case PROTO_IPSEC_ESP:
       
  7107             if (iPhase != PHASE_II)
       
  7108             {
       
  7109                 DEBUG_LOG1(_L("INVALID_PROTOCOL_ID (Prot (%u) only allowed in Phase II)"),aProtocol);
       
  7110                 SendNotifyL(INVALID_PROTOCOL_ID);
       
  7111                 return EFalse;
       
  7112             }
       
  7113             return ETrue;
       
  7114     }
       
  7115     DEBUG_LOG1(_L("INVALID_PROTOCOL_ID (Unknown Protocol (%u))"),aProtocol);
       
  7116     SendNotifyL(INVALID_PROTOCOL_ID);
       
  7117     return EFalse;
       
  7118 }
       
  7119 
       
  7120 TBool CIkev1Negotiation::CheckSPIL(const TProposalISAKMP *aProposal)
       
  7121 {
       
  7122 
       
  7123     TUint size=aProposal->GetSPISize();
       
  7124     if (iPhase == PHASE_I)
       
  7125     {
       
  7126         if (size > MAX_SPI_SIZE)
       
  7127         {
       
  7128             DEBUG_LOG(_L("INVALID_SPI (Bad Size)"));
       
  7129             SendNotifyL(INVALID_SPI);
       
  7130             return EFalse;
       
  7131         }
       
  7132     }
       
  7133     else    //Phase II
       
  7134     {
       
  7135         TUint32 spi = 0;
       
  7136         if (aProposal->GetSPISize() > sizeof(TUint32))
       
  7137         {
       
  7138             DEBUG_LOG(_L("INVALID_SPI (Too big. Max. is 32 bits)"));
       
  7139             SendNotifyL(INVALID_SPI);
       
  7140             return EFalse;
       
  7141         }
       
  7142         Mem::Copy((TUint8 *)&spi, ((TProposalISAKMP *)aProposal)->SPI(), aProposal->GetSPISize());
       
  7143         spi = ByteOrder::Swap32(spi);
       
  7144         if (spi < 256)  //The first 256 are reserved
       
  7145         {
       
  7146             DEBUG_LOG(_L("INVALID_SPI (spi's < 256 are RESERVED)"));
       
  7147             SendNotifyL(INVALID_SPI);
       
  7148             return EFalse;
       
  7149         }
       
  7150     }
       
  7151     return ETrue;
       
  7152 }
       
  7153 
       
  7154 //Checks for transform payloads. MUST NOT abort processing, just discard the payload
       
  7155 TBool CIkev1Negotiation::CheckTransformID(TUint8 aProtocol,TUint8 aID)
       
  7156 {
       
  7157     switch (aProtocol)
       
  7158     {
       
  7159     case PROTO_ISAKMP:
       
  7160         if (aID != KEY_IKE)
       
  7161             return EFalse;
       
  7162         break;
       
  7163 		
       
  7164     case PROTO_IPSEC_AH:
       
  7165 		if ( (aID != AH_MD5) && (aID != AH_SHA))
       
  7166 		{
       
  7167 			DEBUG_LOG(_L("Unsupported Authentication Algorithm"));					
       
  7168 			return EFalse;
       
  7169 		}
       
  7170         break;
       
  7171     case PROTO_IPSEC_ESP:
       
  7172 		switch ( aID )
       
  7173 		{
       
  7174 			case ESP_DES_CBC:
       
  7175 			case ESP_3DES_CBC:
       
  7176 			case ESP_NULL:
       
  7177 			case ESP_AES_CBC:				
       
  7178 				break;
       
  7179 			default:
       
  7180 				DEBUG_LOG(_L("Unsupported Encryption Algorithm"));
       
  7181 				return EFalse;
       
  7182 		}	
       
  7183         break;
       
  7184 		
       
  7185     default:
       
  7186         return EFalse;
       
  7187     }
       
  7188 
       
  7189     return ETrue;
       
  7190 }
       
  7191 
       
  7192 
       
  7193 //Diffie-Hellman key exchange
       
  7194 //The info in iNegotiation MUST be correct
       
  7195 TBool CIkev1Negotiation::ComputeDHPublicValueL()
       
  7196 {
       
  7197     TUint desc;
       
  7198     if (iPhase == PHASE_I)
       
  7199     {
       
  7200         //If aggressive sends the SA and KE at the same time b4 knowing the chosen group.
       
  7201         //The group in the first proposed transform is chosen. Shouldn't be transforms with 
       
  7202         //different groups sent. Checked when using the configuration tool?
       
  7203         if ((iExchange == ISAKMP_EXCHANGE_AGGR) && (iRole == INITIATOR))
       
  7204             desc = iProposal_I.iAttrList->iGroupDesc;
       
  7205         else
       
  7206             desc = iChosenProposal_I.iAttrList->iGroupDesc;
       
  7207     }
       
  7208     else
       
  7209     {
       
  7210         if (iRole == INITIATOR) //We have to use one of the proposals because we don't have the reply yet
       
  7211                                 //Anyay only one group can be specified for phase II so it's fine
       
  7212             desc = iProposal_IIList->At(0)->iAttrList->At(0)->iGroupDesc;
       
  7213         else    //RESPONDER
       
  7214             desc = iChosenProp_IIList->At(0)->iAttrList->At(0)->iGroupDesc;
       
  7215     }
       
  7216 
       
  7217     delete iOwnKeys;    //Happens in phase II because we may recalculate the DH value.
       
  7218 	iOwnKeys = NULL;
       
  7219     delete iOwnPublicKey;   // Happens in phase II because we may recalculate the DH value.
       
  7220     iOwnPublicKey = NULL;
       
  7221 
       
  7222     iOwnKeys = GeneratePubPrivKeysL(desc);
       
  7223     if (!iOwnKeys)
       
  7224     {
       
  7225         DEBUG_LOG(_L("Error generating DH public and private keys"));
       
  7226         return EFalse;
       
  7227     }
       
  7228     iOwnPublicKey = iOwnKeys->GetPubKey();    //save the public key in a buffer to have easy access
       
  7229     iOwnPublicKey_ptr.Set(iOwnPublicKey->Des());
       
  7230     return ETrue;
       
  7231 }
       
  7232 
       
  7233 
       
  7234 //Initial IV computation
       
  7235 //Pre:Requires correct Public keys alredy stored!!!
       
  7236 TBool CIkev1Negotiation::InitIVL()
       
  7237 {
       
  7238 	HBufC8* prf_data =
       
  7239     HBufC8::NewLC(((iOwnPublicKey_ptr.Length() + iPeerPublicKey.Length()) | 0x3) + 1);
       
  7240 	
       
  7241     if (iRole == INITIATOR)
       
  7242     {
       
  7243         prf_data->Des().Copy(iOwnPublicKey_ptr);
       
  7244         prf_data->Des().Append(iPeerPublicKey);
       
  7245 
       
  7246     }
       
  7247     else    //RESPONDER
       
  7248     {
       
  7249         prf_data->Des().Copy(iPeerPublicKey);
       
  7250         prf_data->Des().Append(iOwnPublicKey_ptr);
       
  7251     }
       
  7252     if (iChosenProposal_I.iAttrList->iHashAlg == HASH_MD5)
       
  7253          MD5HashL(prf_data->Des(), iIV);
       
  7254     else SHA1HashL(prf_data->Des(), iIV);
       
  7255 
       
  7256     if (iChosenProposal_I.iAttrList->iEncrAlg == AES_CBC )
       
  7257          iIVSize = 16;
       
  7258     else iIVSize = 8;
       
  7259     iIV.SetLength(iIVSize); 
       
  7260     DEBUG_LOG(_L("Init"));
       
  7261 
       
  7262 	CleanupStack::PopAndDestroy();  //prf_data
       
  7263     
       
  7264     return ETrue;
       
  7265 }
       
  7266 
       
  7267 
       
  7268 
       
  7269 //subsequent IV computations. Like when send notifications or beginning of Phase II
       
  7270 TBool CIkev1Negotiation::ComputeIVL(TDes8 &aIV, TInt32 aMessageId)
       
  7271 { 
       
  7272 	HBufC8* prf_data =
       
  7273     HBufC8::NewLC(((aIV.Length() + sizeof(aMessageId)) | 0x3) + 1);
       
  7274 	
       
  7275     if ((iChosenProposal_I.iAttrList->iEncrAlg != DES3_CBC) &&
       
  7276 	    (iChosenProposal_I.iAttrList->iEncrAlg != AES_CBC)  &&
       
  7277 	    (iChosenProposal_I.iAttrList->iEncrAlg != DES_CBC))
       
  7278     {
       
  7279         return EFalse;
       
  7280     }
       
  7281     //former IV
       
  7282     prf_data->Des().Copy(aIV);
       
  7283     //Message ID
       
  7284     TInt32 id = ByteOrder::Swap32(aMessageId);  //Needed to add it
       
  7285 
       
  7286     prf_data->Des().Append((TUint8 *)&id, sizeof(id));
       
  7287     
       
  7288     DEBUG_LOG(_L("prf"));
       
  7289     if (iChosenProposal_I.iAttrList->iHashAlg == HASH_MD5)
       
  7290 		 MD5HashL(prf_data->Des(), aIV);
       
  7291     else SHA1HashL(prf_data->Des(), aIV);
       
  7292 		
       
  7293     DEBUG_LOG(_L("Computed IV"));
       
  7294 			
       
  7295     CleanupStack::PopAndDestroy();  //prf_data			
       
  7296     return ETrue;
       
  7297 }
       
  7298 
       
  7299 //Generates all the keying material SKEYID,SKEYID_d,SKEYID_a,SKEYID_e
       
  7300 TBool CIkev1Negotiation::ComputeKeysL()
       
  7301 {
       
  7302 	TUint desc;			
       
  7303     //If aggressive sends the SA and KE at the same time b4 knowing the chosen group.
       
  7304     //The group in the first proposed transform is chosen. Shouldn't be transforms with 
       
  7305     //different groups sent
       
  7306     if ((iExchange == ISAKMP_EXCHANGE_AGGR) && (iRole == INITIATOR))
       
  7307         desc = iProposal_I.iAttrList->iGroupDesc;
       
  7308     else
       
  7309         desc = iChosenProposal_I.iAttrList->iGroupDesc;
       
  7310 	//
       
  7311 	//Computes agreed key 
       
  7312 	//
       
  7313 	HBufC8* agreedKey = ComputeAgreedKeyL(desc, iPeerPublicKey, iOwnKeys);  //(gxy)
       
  7314 	if ( !agreedKey ) {
       
  7315 		DEBUG_LOG(_L("DH secret creation failed (ComputeAgreedKeyL)"));
       
  7316 		SetErrorStatus( KKmdIkeNegotFailed );
       
  7317 		SendNotifyL(INVALID_KEY_INFORMATION);				
       
  7318 		return EFalse;
       
  7319 	}
       
  7320 	CleanupStack::PushL(agreedKey);  //agreedKey
       
  7321 
       
  7322 	// Use prf and agreed DH-key to generate keying material
       
  7323 	HBufC8* prf_data =
       
  7324     HBufC8::NewLC(((iNONCE_I.Length() + iNONCE_R.Length() + 2*ISAKMP_COOKIE_SIZE) | 0x3) + 1);
       
  7325 	HBufC8* prf_key  =
       
  7326     HBufC8::NewLC(((iNONCE_I.Length() + iNONCE_R.Length() ) | 0x3) + 1);
       
  7327 
       
  7328     DEBUG_LOG(_L("Agreed Key."));
       
  7329 
       
  7330     switch(iChosenProposal_I.iAttrList->iAuthMethod)
       
  7331     {
       
  7332     case RSA_SIG:
       
  7333     case DSS_SIG:
       
  7334     case IKE_A_CRACK:       
       
  7335         //For signatures:
       
  7336         //SKEYID = prf(Ni_b|Nr_b, g^xy)
       
  7337         //key
       
  7338         prf_key->Des().Copy(iNONCE_I);
       
  7339         prf_key->Des().Append(iNONCE_R);
       
  7340         ComputePRFL(iSKEYID, prf_key->Des(), agreedKey->Des());
       
  7341         break;
       
  7342     case PRE_SHARED:
       
  7343         {
       
  7344         //pre-shared keys:
       
  7345         //SKEYID=prf(pre_shared key, Ni_b | Nr_b);
       
  7346         //data
       
  7347         prf_data->Des().Copy(iNONCE_I.Ptr(),iNONCE_I.Length());
       
  7348         prf_data->Des().Append(iNONCE_R.Ptr(),iNONCE_R.Length());
       
  7349         DEBUG_LOG(_L("Pre-shared Key"));
       
  7350 #ifdef _UNICODE
       
  7351         HBufC8 *preshared_key_buf = HBufC8::NewLC(iHostData->iPresharedKey.iKey.Length());
       
  7352         preshared_key_buf->Des().Copy(iHostData->iPresharedKey.iKey);
       
  7353         TPtrC8 preshared_key_ptr(preshared_key_buf->Des());
       
  7354 #else
       
  7355         TPtrC8 preshared_key_ptr(iHostData->iPresharedKey.iKey);
       
  7356 #endif
       
  7357         ComputePRFL(iSKEYID, preshared_key_ptr, prf_data->Des());
       
  7358 #ifdef _UNICODE
       
  7359         CleanupStack::PopAndDestroy();  //presharedkey_buf
       
  7360 #endif
       
  7361         }
       
  7362         break;
       
  7363     default://method not implemented
       
  7364         DEBUG_LOG1(_L("ATTRIBUTES_NOT_SUPPORTED:Auth Method %d not supported "),iChosenProposal_I.iAttrList->iAuthMethod);
       
  7365         SetErrorStatus( KKmdIkeNegotFailed );
       
  7366         SendNotifyL(ATTRIBUTES_NOT_SUPPORTED);
       
  7367         return EFalse;
       
  7368     }
       
  7369 	
       
  7370 	CleanupStack::PopAndDestroy(2);  //prf_data and prf_key
       
  7371 	prf_data =
       
  7372 	HBufC8::NewLC(((agreedKey->Length() + iSKEYID.Length() + 2*ISAKMP_COOKIE_SIZE + 4) | 0x3) + 1);
       
  7373 	
       
  7374     prf_data->Des().Copy(agreedKey->Des());
       
  7375     prf_data->Des().Append(iCookie_I);
       
  7376     prf_data->Des().Append(iCookie_R);
       
  7377     prf_data->Des().Append(0);
       
  7378     ComputePRFL(iSKEYID_d, iSKEYID, prf_data->Des());
       
  7379 
       
  7380     prf_data->Des().Copy(iSKEYID_d);
       
  7381     prf_data->Des().Append(agreedKey->Des());
       
  7382     prf_data->Des().Append(iCookie_I);
       
  7383     prf_data->Des().Append(iCookie_R);
       
  7384     prf_data->Des().Append(1);
       
  7385     ComputePRFL(iSKEYID_a, iSKEYID, prf_data->Des());
       
  7386 
       
  7387     prf_data->Des().Copy(iSKEYID_a);
       
  7388     prf_data->Des().Append(agreedKey->Des());
       
  7389     prf_data->Des().Append(iCookie_I);
       
  7390     prf_data->Des().Append(iCookie_R);
       
  7391     prf_data->Des().Append(2);
       
  7392     ComputePRFL(iSKEYID_e, iSKEYID, prf_data->Des());
       
  7393 
       
  7394 	agreedKey->Des().FillZ();  // Zeroe DH secret g^xy
       
  7395 
       
  7396     //Builds the IV 
       
  7397     if (!InitIVL())
       
  7398     {
       
  7399         DEBUG_LOG(_L("Error Computing IV"));
       
  7400         return EFalse;
       
  7401     }
       
  7402     if (iExchange == ISAKMP_EXCHANGE_AGGR)
       
  7403     {
       
  7404         iLastIV.Copy(iIV);      //Saves last IV in Phase 1
       
  7405         iLastIV.SetLength(iIVSize);   
       
  7406         DEBUG_LOG(_L("Last IV Saved!"));
       
  7407     }
       
  7408 
       
  7409     //if key extension required:
       
  7410     TUint8 *key;
       
  7411     TInt key_len=0;
       
  7412     TInt total_key_len = ISAKMPEncrKeyLength((TUint8)iChosenProposal_I.iAttrList->iEncrAlg);
       
  7413     if (iSKEYID_e.Length() < total_key_len)
       
  7414     {
       
  7415         DEBUG_LOG(_L("Extending encrytion key..."));
       
  7416         key = new (ELeave) TUint8[total_key_len*2];
       
  7417         CleanupStack::PushL(key);
       
  7418         key[0] = 0;
       
  7419         TPtr8 kx0_ptr(key, 1, 1);
       
  7420         TPtr8 kx1_ptr(key, 0, total_key_len * 2);
       
  7421         ComputePRFL(kx1_ptr, iSKEYID_e, kx0_ptr); //K1=prf(SKEYID_e,0)
       
  7422         key_len += kx1_ptr.Length();
       
  7423         
       
  7424         while (key_len < total_key_len)
       
  7425         {
       
  7426             kx0_ptr.Set(&key[key_len - kx1_ptr.Length()], kx1_ptr.Length(), total_key_len);
       
  7427             kx1_ptr.Set(&key[key_len], 0, total_key_len);
       
  7428             ComputePRFL(kx1_ptr, iSKEYID_e, kx0_ptr); //Kx=prf(SKEYID_e,K<x-1>)
       
  7429             key_len += kx1_ptr.Length();
       
  7430         }
       
  7431         iSKEYID_e.Copy(key, total_key_len);
       
  7432         CleanupStack::PopAndDestroy();  //key
       
  7433         DEBUG_LOG(_L(" SKEYID_e (EXTENDED)"));
       
  7434     }
       
  7435 	else
       
  7436 	{
       
  7437 		iSKEYID_e.SetLength(total_key_len);		
       
  7438 		DEBUG_LOG(_L(" SKEYID_e"));
       
  7439 	}
       
  7440     
       
  7441     DEBUG_LOG(_L(" Init IV"));
       
  7442 
       
  7443 	CleanupStack::PopAndDestroy(2);  //prf_data and agreedKey
       
  7444 	
       
  7445     return ETrue;
       
  7446 }
       
  7447 
       
  7448 //Computes the IPSEC keys needed for each IPSEC SA
       
  7449 //KEYMAT = prf(SKEY_ID, protocol | SPI | Ni_b | Nr_b)
       
  7450 //if PFS:
       
  7451 //KEYMAT = prf(SKEY_ID, g(qm)^xy | protocol | SPI | Ni_b | Nr_b)
       
  7452 void CIkev1Negotiation::ComputeKeys2L(const CProposal_II *aProp, TInt aKeyLen, TSPINode &aInboundSpiNode, TDes8& aOutboundKey_II, TDes8& aInboundKey_II)
       
  7453 {
       
  7454     DEBUG_LOG(_L("Computing PHASE II keys "));
       
  7455     
       
  7456     aOutboundKey_II.SetLength(0);
       
  7457     aInboundKey_II.SetLength(0);
       
  7458     DEBUG_LOG(_L("Total Computed Key Length="));
       
  7459     DEBUG_LOG_NUM(aKeyLen);
       
  7460 
       
  7461 	HBufC8* agreedKey = NULL; //g(qm)^xy
       
  7462 	TInt  prf_len = iSKEYID_d.Length() + iNONCE_I.Length() + iNONCE_R.Length() + 8; // 8 for protocol and SPI
       
  7463 	
       
  7464     if (iPFS)
       
  7465     {
       
  7466         agreedKey = ComputeAgreedKeyL(iChosenProp_IIList->At(0)->iAttrList->At(0)->iGroupDesc, iPeerPublicKey, iOwnKeys);
       
  7467 		if ( !agreedKey )
       
  7468 			User::Leave(KErrGeneral);
       
  7469 		CleanupStack::PushL(agreedKey);
       
  7470 		prf_len += agreedKey->Length(); 
       
  7471         DEBUG_LOG(_L(" Agreed Key"));
       
  7472     }
       
  7473 #ifdef _DEBUG    
       
  7474 	else DEBUG_LOG(_L("(NO PFS)"));
       
  7475 #endif // _DEBUG	
       
  7476 
       
  7477     DEBUG_LOG(_L("Protocol:"));
       
  7478     DEBUG_LOG_NUM(aProp->iProtocol);
       
  7479   
       
  7480     TUint32 in_spi = aInboundSpiNode.iSPI;  //inbound spi in Network Order
       
  7481     DEBUG_LOG(_L("InSPI:"));
       
  7482     DEBUG_LOG_NUM(ByteOrder::Swap32(in_spi));
       
  7483     TUint32 out_spi;
       
  7484     Mem::Copy((TUint8 *)&out_spi, aProp->iSPI.Ptr(), aProp->iSPI.Length());
       
  7485     DEBUG_LOG1(_L("OutSPI: %x"), out_spi);
       
  7486     //Inbound and outbound calculations only differ in the SPI
       
  7487     //If the key is not long enough we need to extend it
       
  7488     TPtr8 key_ptr((TUint8 *)aOutboundKey_II.Ptr() + aOutboundKey_II.Length(), 0, aOutboundKey_II.MaxLength());
       
  7489 	
       
  7490 	HBufC8* prf_data = HBufC8::NewLC((prf_len | 0x3) + 1);
       
  7491 	
       
  7492     while ((aOutboundKey_II.Length() * 8) < aKeyLen)  //include the key extension algorithm
       
  7493     {
       
  7494         prf_data->Des().Copy(key_ptr);
       
  7495         if (agreedKey)//Only used if PFS
       
  7496         {
       
  7497             prf_data->Des().Append(agreedKey->Des());
       
  7498         }
       
  7499         prf_data->Des().Append(&aProp->iProtocol, sizeof(aProp->iProtocol));
       
  7500         prf_data->Des().Append(aProp->iSPI.Ptr(),aProp->iSPI.Length());
       
  7501         prf_data->Des().Append(iNONCE_I);
       
  7502         prf_data->Des().Append(iNONCE_R);
       
  7503         key_ptr.Set((TUint8 *)aOutboundKey_II.Ptr() + aOutboundKey_II.Length(), 0, aOutboundKey_II.MaxLength() - aOutboundKey_II.Length());
       
  7504         ComputePRFL(key_ptr, iSKEYID_d, prf_data->Des());
       
  7505         aOutboundKey_II.SetLength(aOutboundKey_II.Length() + key_ptr.Length());
       
  7506     }
       
  7507 
       
  7508     key_ptr.Set((TUint8 *)aInboundKey_II.Ptr() + aInboundKey_II.Length(), 0, aOutboundKey_II.MaxLength());
       
  7509     while ((aInboundKey_II.Length() * 8) < aKeyLen)  //include the key extension algorithm
       
  7510     {
       
  7511         prf_data->Des().Copy(key_ptr);
       
  7512         if (agreedKey)//Only used if PFS
       
  7513         {
       
  7514             prf_data->Des().Append(agreedKey->Des());
       
  7515         }
       
  7516         prf_data->Des().Append(&aProp->iProtocol,sizeof(aProp->iProtocol));
       
  7517         prf_data->Des().Append((TUint8 *)&in_spi, sizeof(TUint32));
       
  7518         prf_data->Des().Append(iNONCE_I);
       
  7519         prf_data->Des().Append(iNONCE_R);
       
  7520         
       
  7521         key_ptr.Set((TUint8 *)aInboundKey_II.Ptr() + aInboundKey_II.Length(), 0, aInboundKey_II.MaxLength() - aInboundKey_II.Length());
       
  7522         ComputePRFL(key_ptr, iSKEYID_d, prf_data->Des());
       
  7523         aInboundKey_II.SetLength(aInboundKey_II.Length() + key_ptr.Length());
       
  7524     }
       
  7525 
       
  7526 	if ( agreedKey )		
       
  7527 	     CleanupStack::PopAndDestroy(2);  //prf_data and agreedKey
       
  7528 	else CleanupStack::PopAndDestroy();   //prf_data
       
  7529 			
       
  7530 }
       
  7531 
       
  7532 
       
  7533 /* This function is called by oakley module to do pseudo random computation for
       
  7534    given data */
       
  7535 //IMPORTANT: If some func added or modified check MAX_PRF_LENGTH is correct in ike.h
       
  7536 
       
  7537 void CIkev1Negotiation::ComputePRFL(TDes8 &prf_output, const TDesC8 &prf_key, const TDesC8 &prf_data)
       
  7538 {
       
  7539 // All actions taken are moved into the crypto module IKE_CRYPTO.CPP
       
  7540     
       
  7541     if ( iChosenProposal_I.iAttrList->iPRF == OAKLEY_PRF_3DES_CBC_MAC)
       
  7542     {
       
  7543        DEBUG_LOG(_L("PRF (3DES_CBC_MAC)"));        
       
  7544        Hmac3DesCbcL(prf_data, prf_output, prf_key);  
       
  7545     }
       
  7546     else
       
  7547     {
       
  7548       // Use HMAC version of the negotiated hash function as default PRF
       
  7549         if ( iChosenProposal_I.iAttrList->iHashAlg == HASH_MD5 ) {
       
  7550            DEBUG_LOG(_L("PRF (MD5)"));           
       
  7551            MD5HmacL(prf_data, prf_output, prf_key);
       
  7552         }   
       
  7553         else {
       
  7554            if ( iChosenProposal_I.iAttrList->iHashAlg == HASH_SHA1 ) {
       
  7555               DEBUG_LOG(_L("PRF (SHA1)"));              
       
  7556               SHA1HmacL(prf_data, prf_output, prf_key);
       
  7557            }
       
  7558         }   
       
  7559     }
       
  7560 
       
  7561 }
       
  7562 
       
  7563 
       
  7564 //NOTE: Must be called after ProcessCertificate() !!!
       
  7565 TBool CIkev1Negotiation::CertifyRemoteIdentityL(const TIdentISAKMP *aIdPayload)
       
  7566 {
       
  7567   TBool Status = EFalse;
       
  7568   TInt id_len  = aIdPayload->IDDataLen();
       
  7569 
       
  7570   if ( id_len && iPkiService && iPeerX509Cert )
       
  7571   {
       
  7572     TPtrC8 IdData((TUint8 *)aIdPayload->IDData(), id_len);
       
  7573 
       
  7574     // Leave is trapped and handled here because the event log is easily accessible
       
  7575     // and in the upper layers it would not be possible to identify the
       
  7576     // cause of the error based on the generic leave code.
       
  7577     TRAPD(err, Status = IkePkiUtils::CertifyIdentityL(iPeerX509Cert, IdData, (TInt)aIdPayload->GetIDType()));
       
  7578 
       
  7579     if( KErrNotSupported == err )
       
  7580     {
       
  7581       LOG_KMD_EVENT( MKmdEventLoggerIf::KLogError,
       
  7582                      R_VPN_MSG_CERT_ERROR,
       
  7583                      KErrNotSupported,
       
  7584                      iPluginSession->VpnIapId(),
       
  7585                      &iRemoteAddr );
       
  7586     }
       
  7587 
       
  7588 #ifdef _DEBUG    
       
  7589     if (Status)
       
  7590         DEBUG_LOG(_L("Remote identity has been certified"));
       
  7591 #endif // _DEBUG    
       
  7592   }
       
  7593        
       
  7594   return Status;
       
  7595 }
       
  7596 
       
  7597 
       
  7598 //Digests aHash with the key in aCert and compares it to the stored value aSig
       
  7599 //Needs to be check after the Signature payload has been processed
       
  7600 TBool CIkev1Negotiation::VerifySignatureL(CX509Certificate *aCert,TUint8 *aHash, TInt aHashLength,TUint8 *aSig, TUint aSigLength)
       
  7601 {
       
  7602 
       
  7603 	TBool ret = EFalse;
       
  7604 	if ( iPkiService )
       
  7605 	{
       
  7606 		TPtrC8 Signature(aSig, aSigLength);
       
  7607 		TPtrC8 RefHash(aHash, aHashLength);	   							   			
       
  7608 	    ret = IkePkiUtils::VerifyIkev1SignatureL(Signature, RefHash, *aCert);
       
  7609 	}   
       
  7610 	
       
  7611     return ret;
       
  7612 
       
  7613 
       
  7614 }
       
  7615 
       
  7616 //NOTE!!! The func sets iFinished to TRUE always so after detecting an error the communication finishes.
       
  7617 //If it doesn't have to iFinished should be set outside the function.
       
  7618 void CIkev1Negotiation::SendNotifyL(TUint16 aError)
       
  7619 {
       
  7620 	SetFinished();  //Ends the negotiation (error condition detected) If CONNECTED also should end
       
  7621 	
       
  7622 #ifdef _DEBUG	
       
  7623     TBuf<60> buf;
       
  7624     DEBUG_LOG(_L("SendNotifyL(), Reason: "));
       
  7625     buf.Append(TextNotifyType(aError));
       
  7626     DEBUG_LOG(buf);
       
  7627 #endif // _DEBUG    
       
  7628     TUint8 protocol = PROTO_ISAKMP;
       
  7629     TUint8 tmp_exchange = iExchange;
       
  7630     TUint32 tmp_msg_id = iMessageId;
       
  7631 	TIkev1IsakmpStream* msg = SaveIkeMsgBfr( new (ELeave) TIkev1IsakmpStream(iDebug) );			
       
  7632     //If configured to send notification payloads for errors
       
  7633     if (iHostData->iNotify)
       
  7634     {
       
  7635         iExchange = ISAKMP_EXCHANGE_INFO;
       
  7636         iMessageId = RandomMessageId();
       
  7637         msg->IsakmpInit(this);
       
  7638 		
       
  7639         //HASH Payload only if payload protected with encyption
       
  7640         if (iFlags & ISAKMP_HDR_EFLAG)
       
  7641       		msg->IsakmpHashL();		
       
  7642 
       
  7643         if (iPhase == PHASE_I)
       
  7644             protocol = iChosenProposal_I.iProtocol;
       
  7645         else
       
  7646         {
       
  7647             if (iChosenProp_IIList) //May be the begining of PHASE_II when still not decided
       
  7648                 protocol = iChosenProp_IIList->At(0)->iProtocol;
       
  7649         }
       
  7650         msg->IsakmpNotification(aError, protocol);
       
  7651 
       
  7652         if (iFlags & ISAKMP_HDR_EFLAG)
       
  7653         {
       
  7654             msg->IsakmpHashContL();
       
  7655         }
       
  7656 
       
  7657         iExchange  = tmp_exchange;
       
  7658         iMessageId = tmp_msg_id;
       
  7659 
       
  7660 		SendL(*msg);
       
  7661 
       
  7662   		LOG_KMD_EVENT( MKmdEventLoggerIf::KLogError,
       
  7663   		               R_VPN_MSG_SENT_ERROR_RESPONSE,
       
  7664   		               aError,
       
  7665   		               iPluginSession->VpnIapId(),
       
  7666   		               &iRemoteAddr );
       
  7667     }
       
  7668 
       
  7669 }
       
  7670 
       
  7671 
       
  7672 //Hash function key length (in bytes)
       
  7673 TInt CIkev1Negotiation::HashLength()
       
  7674 {
       
  7675     if (iChosenProposal_I.iAttrList->iPRF == OAKLEY_PRF_3DES_CBC_MAC)
       
  7676         return 24;
       
  7677         
       
  7678     //If no PRF hash alg used instead.
       
  7679     if (iChosenProposal_I.iAttrList->iPRF==0)
       
  7680     {
       
  7681         if (iChosenProposal_I.iAttrList->iHashAlg==HASH_MD5)
       
  7682             return HMAC_MD5_SIZE/8; //16 bytes
       
  7683             //return MD5_DIGEST_LENGTH;
       
  7684         else if (iChosenProposal_I.iAttrList->iHashAlg==HASH_SHA1)
       
  7685             return HMAC_SHA1_SIZE/8;
       
  7686             //return SHA_DIGEST_LENGTH;
       
  7687     }
       
  7688     
       
  7689     return 0;
       
  7690 }
       
  7691 
       
  7692 
       
  7693 //Could be done using directly iEncrAlg from the chosen transform (in bytes)
       
  7694 TUint32 CIkev1Negotiation::ISAKMPEncrKeyLength(TUint8 aAlgId) const
       
  7695 {
       
  7696     TUint32 KeyLth = 0;
       
  7697     switch (aAlgId) {
       
  7698         case DES_CBC:
       
  7699             KeyLth = 8;
       
  7700             break;
       
  7701         case DES3_CBC:
       
  7702             KeyLth = 24;
       
  7703             break;
       
  7704         case AES_CBC:
       
  7705             if ( iChosenProposal_I.iAttrList->iKeyLength )
       
  7706                  KeyLth = (TUint32)(iChosenProposal_I.iAttrList->iKeyLength/8);
       
  7707             else KeyLth = 16;  // default
       
  7708             break;
       
  7709         default:
       
  7710             break;
       
  7711     }           
       
  7712         
       
  7713     return KeyLth;
       
  7714 }
       
  7715 
       
  7716 TIkev1IsakmpStream* CIkev1Negotiation::SaveIkeMsgBfr(TIkev1IsakmpStream* aMsg)
       
  7717 {
       
  7718 	delete iSavedIkeMsgBfr;
       
  7719     iSavedIkeMsgBfr = aMsg;
       
  7720 	return aMsg;
       
  7721 }	
       
  7722 
       
  7723 //Returns the key length (in bits) of an algorithm for iAuth (TAttrib_II) field when protocol is AH
       
  7724 TUint32 CIkev1Negotiation::HMAC_KeyLength(TUint8 aId) const
       
  7725 {
       
  7726     if (aId == SADB_AALG_MD5HMAC)
       
  7727         return (HMAC_MD5_SIZE);
       
  7728     else if (aId == SADB_AALG_SHA1HMAC)
       
  7729         return (HMAC_SHA1_SIZE);
       
  7730 
       
  7731   return (0); // Error 
       
  7732 }
       
  7733 
       
  7734 //Exchange Type
       
  7735 TPtrC CIkev1Negotiation::TextNotifyType(TUint16 aNotif)
       
  7736 {
       
  7737 #ifndef _DEBUG
       
  7738     (void)aNotif;
       
  7739 #endif
       
  7740 
       
  7741 #ifdef _DEBUG
       
  7742     //TBuf<35> err;
       
  7743     switch(aNotif)
       
  7744     {
       
  7745     case INVALID_PAYLOAD_TYPE:
       
  7746         return _L("INVALID_PAYLOAD_TYPE");
       
  7747     case DOI_NOT_SUPPORTED:
       
  7748         return _L("DOI_NOT_SUPPORTED");
       
  7749     case SITUATION_NOT_SUPPORTED:
       
  7750         return _L("SITUATION_NOT_SUPPORTED");
       
  7751     case INVALID_COOKIE:
       
  7752         return _L("INVALID_COOKIE");
       
  7753     case INVALID_MAJOR_VERSION:
       
  7754         return _L("INVALID_MAJOR_VERSION");
       
  7755     case INVALID_MINOR_VERSION:
       
  7756         return _L("INVALID_MINOR_VERSION");
       
  7757     case INVALID_EXCHANGE_TYPE:
       
  7758         return _L("INVALID_EXCHANGE_TYPE");
       
  7759     case INVALID_FLAGS:
       
  7760         return _L("INVALID_FLAGS");
       
  7761     case INVALID_MESSAGE_ID:
       
  7762         return _L("INVALID_MESSAGE_ID");
       
  7763     case INVALID_PROTOCOL_ID:
       
  7764         return _L("INVALID_PROTOCOL_ID");
       
  7765     case INVALID_SPI:
       
  7766         return _L("INVALID_SPI");
       
  7767     case INVALID_TRANSFORM_ID:
       
  7768         return _L("INVALID_TRANSFORM_ID");
       
  7769     case ATTRIBUTES_NOT_SUPPORTED:
       
  7770         return _L("ATTRIBUTES_NOT_SUPPORTED");
       
  7771     case NO_PROPOSAL_CHOSEN:
       
  7772         return _L("NO_PROPOSAL_CHOSEN");
       
  7773     case BAD_PROPOSAL_SYNTAX:
       
  7774         return _L("BAD_PROPOSAL_SYNTAX");
       
  7775     case PAYLOAD_MALFORMED:
       
  7776         return _L("PAYLOAD_MALFORMED");
       
  7777     case INVALID_KEY_INFORMATION:
       
  7778         return _L("INVALID_KEY_INFORMATION");
       
  7779     case INVALID_ID_INFORMATION:
       
  7780         return _L("INVALID_ID_INFORMATION");
       
  7781     case INVALID_CERT_ENCODING:
       
  7782         return _L("INVALID_CERT_ENCODING");
       
  7783     case INVALID_CERTIFICATE:
       
  7784         return _L("INVALID_CERTIFICATE");
       
  7785     case CERT_TYPE_UNSUPPORTED:
       
  7786         return _L("CERT_TYPE_UNSUPPORTED");
       
  7787     case INVALID_CERT_AUTHORITY:
       
  7788         return _L("INVALID_CERT_AUTHORITY");
       
  7789     case INVALID_HASH_INFORMATION:
       
  7790         return _L("INVALID_HASH_INFORMATION");
       
  7791     case AUTHENTICATION_FAILED:
       
  7792         return _L("AUTHENTICATION_FAILED");
       
  7793     case INVALID_SIGNATURE:
       
  7794         return _L("INVALID_SIGNATURE");
       
  7795     case ADDRESS_NOTIFICATION:
       
  7796         return _L("ADDRESS_NOTIFICATION");
       
  7797     case NOTIFY_SA_LIFETIME:
       
  7798         return _L("NOTIFY_SA_LIFETIME");
       
  7799     case CERTIFICATE_UNAVAILABLE:
       
  7800         return _L("CERTIFICATE_UNAVAILABLE");
       
  7801     case UNSUPPORTED_EXCHANGE_TYPE:
       
  7802         return _L("UNSUPPORTED_EXCHANGE_TYPE");
       
  7803     case UNEQUAL_PAYLOAD_LENGTHS:
       
  7804         return _L("UNEQUAL_PAYLOAD_LENGTHS");
       
  7805     case CONNECTED:
       
  7806         return _L("CONNECTED");
       
  7807 	case DOI_RESPONDER_LIFETIME:
       
  7808 		return _L("RESPONDER_LIFETIME");
       
  7809 	case DOI_REPLAY_STATUS:
       
  7810 		return _L("REPLAY_STATUS");
       
  7811 	case DOI_INITIAL_CONTACT:
       
  7812 		return _L("INITIAL_CONTACT");
       
  7813     }
       
  7814     return _L("Unknown ");
       
  7815 #else
       
  7816     return NULL;
       
  7817 #endif          
       
  7818 }
       
  7819 
       
  7820 
       
  7821 void CIkev1Negotiation::TextPayload(TDes &aBuf, TUint8 aPayload)
       
  7822 {
       
  7823 #ifndef _DEBUG
       
  7824     (void)aBuf;
       
  7825     (void)aPayload;
       
  7826 #endif
       
  7827 
       
  7828 #ifdef _DEBUG
       
  7829     switch(aPayload)
       
  7830     {
       
  7831     case ISAKMP_PAYLOAD_NONE:// (Terminator)
       
  7832         aBuf = _L("ISAKMP_PAYLOAD_NONE");
       
  7833         break;
       
  7834     case ISAKMP_PAYLOAD_SA:// Security Association
       
  7835         aBuf = _L("ISAKMP_PAYLOAD_SA");
       
  7836         break;
       
  7837     case ISAKMP_PAYLOAD_P:// Proposal
       
  7838         aBuf = _L("ISAKMP_PAYLOAD_P");
       
  7839         break;
       
  7840     case ISAKMP_PAYLOAD_T:// Transform
       
  7841         aBuf = _L("ISAKMP_PAYLOAD_T");
       
  7842         break;
       
  7843     case ISAKMP_PAYLOAD_KE:// Key Exchange
       
  7844         aBuf = _L("ISAKMP_PAYLOAD_KE");
       
  7845         break;
       
  7846     case ISAKMP_PAYLOAD_ID:// Identification
       
  7847         aBuf = _L("ISAKMP_PAYLOAD_ID");
       
  7848         break;
       
  7849     case ISAKMP_PAYLOAD_CERT:// Certificate
       
  7850         aBuf = _L("ISAKMP_PAYLOAD_CERT");
       
  7851         break;
       
  7852     case ISAKMP_PAYLOAD_CR:// Certificate Request
       
  7853         aBuf = _L("ISAKMP_PAYLOAD_CR");
       
  7854         break;
       
  7855     case ISAKMP_PAYLOAD_HASH:// Hash
       
  7856         aBuf = _L("ISAKMP_PAYLOAD_HASH");
       
  7857         break;
       
  7858     case ISAKMP_PAYLOAD_SIG:// Signature
       
  7859         aBuf = _L("ISAKMP_PAYLOAD_SIG");
       
  7860         break;
       
  7861     case ISAKMP_PAYLOAD_NONCE:// Nonce
       
  7862         aBuf = _L("ISAKMP_PAYLOAD_NONCE");
       
  7863         break;
       
  7864     case ISAKMP_PAYLOAD_NOTIF:// Notification
       
  7865         aBuf = _L("ISAKMP_PAYLOAD_NOTIF");
       
  7866         break;
       
  7867     case ISAKMP_PAYLOAD_D:// Delete
       
  7868         aBuf = _L("ISAKMP_PAYLOAD_D");
       
  7869         break;
       
  7870     case ISAKMP_PAYLOAD_VID:// Vendor ID
       
  7871         aBuf = _L("ISAKMP_PAYLOAD_VID");
       
  7872         break;
       
  7873     case ISAKMP_PAYLOAD_PRIVATE:// Private use (up to 255)
       
  7874         aBuf = _L("ISAKMP_PAYLOAD_PRIVATE");
       
  7875         break;
       
  7876     default:
       
  7877         aBuf.Format(_L("Unknown (%d) "),aPayload);
       
  7878     }
       
  7879 #endif                  
       
  7880 }
       
  7881 
       
  7882 //Sends the built message through the socket
       
  7883 void CIkev1Negotiation::SendL(TIkev1IsakmpStream &aMsg)
       
  7884 {
       
  7885     if (aMsg.iError)
       
  7886     {
       
  7887         DEBUG_LOG(_L("Error Building message"));
       
  7888         return;
       
  7889     }
       
  7890     TBuf8<IKEV1_MAX_IV_SIZE> tmp_IV;
       
  7891     
       
  7892     ThdrISAKMP *hdr = (ThdrISAKMP *)aMsg.iBuf.Ptr();
       
  7893     hdr->SetLength(aMsg.iBuf.Length());
       
  7894     DEBUG_LOG(_L("Sending (clear)..."));
       
  7895     
       
  7896     TBool FloatedPort = EFalse; 
       
  7897     if ( iNAT_D_Flags & (REMOTE_END_NAT + LOCAL_END_NAT) )
       
  7898         FloatedPort = ETrue;
       
  7899     
       
  7900 #ifdef _DEBUG
       
  7901     const TPtrC8 ikeMsgPtr( aMsg.iBuf.Ptr(), aMsg.iBuf.Length() );
       
  7902     TInetAddr localAddr;
       
  7903     iPluginSession->GetLocalAddress( localAddr );    
       
  7904     TInt port = ( FloatedPort ? IkeSocket::KIkePort4500 : IkeSocket::KIkePort500 );
       
  7905     localAddr.SetPort( port );
       
  7906     TRACE_MSG_IKEV1( ikeMsgPtr, localAddr, iLastRemoteAddr );
       
  7907 #endif // _DEBUG
       
  7908     
       
  7909     TPtr8 lastMsg(iLastMsg->Des());   
       
  7910 
       
  7911     if (hdr->GetFlags() & ISAKMP_HDR_EFLAG)
       
  7912     {
       
  7913         DEBUG_LOG(_L("Encrypting..."));
       
  7914 
       
  7915         if (hdr->GetExchange()==ISAKMP_EXCHANGE_INFO || hdr->GetExchange()==ISAKMP_EXCHANGE_TRANSACT )
       
  7916         {
       
  7917             if ( hdr->GetExchange()==ISAKMP_EXCHANGE_TRANSACT )
       
  7918             {
       
  7919                //
       
  7920                // Get current IV via CTransNegotiation object linked into
       
  7921                // CIkev1Negotiation  
       
  7922                //
       
  7923                if ( !iTransactionNeg ||
       
  7924                     !iTransactionNeg->GetIV(hdr->GetMessageId(), tmp_IV) )
       
  7925                {
       
  7926                    DEBUG_LOG(_L("Send error ! Cannot get Transaction IV !"));
       
  7927                    return;
       
  7928                }       
       
  7929                DEBUG_LOG(_L("Transaction IV"));                     
       
  7930                EncryptL(aMsg.iBuf, lastMsg, tmp_IV, iSKEYID_e, iChosenProposal_I.iAttrList->iEncrAlg);
       
  7931                iTransactionNeg->SetIV(hdr->GetMessageId(), tmp_IV);
       
  7932             }   
       
  7933             else
       
  7934             {
       
  7935                if (iLastIV.Length() != 0)
       
  7936                     tmp_IV.Copy(iLastIV);
       
  7937                else    //iLastIV not yet computed so current iIV is used
       
  7938                     tmp_IV.Copy(iIV);
       
  7939                ComputeIVL(tmp_IV, hdr->GetMessageId());
       
  7940                DEBUG_LOG(_L("Notif IV"));
       
  7941                EncryptL(aMsg.iBuf, lastMsg, tmp_IV, iSKEYID_e, iChosenProposal_I.iAttrList->iEncrAlg);
       
  7942             }   
       
  7943 
       
  7944         }
       
  7945         else    //Normal exchange MAIN, AGGR or QUICK
       
  7946         {
       
  7947             DEBUG_LOG(_L("IV"));
       
  7948             EncryptL(aMsg.iBuf, lastMsg, iIV, iSKEYID_e, iChosenProposal_I.iAttrList->iEncrAlg);
       
  7949             DEBUG_LOG(_L("New IV (dec)"));
       
  7950             //Saves last iIV in Phase 1
       
  7951             if (((iStage==6) && (iExchange == ISAKMP_EXCHANGE_ID)) ||
       
  7952                 ((iStage==3) && (iExchange == ISAKMP_EXCHANGE_AGGR)))
       
  7953             {
       
  7954                 iLastIV.Copy(iIV);  
       
  7955                 DEBUG_LOG(_L("Last IV Saved!"));
       
  7956             }
       
  7957         }
       
  7958 
       
  7959         DEBUG_LOG(_L("Sending ..."));
       
  7960         DEBUG_LOG1(_L("EncrLen = %d"), lastMsg.Length());
       
  7961     }
       
  7962     else
       
  7963         {
       
  7964         lastMsg.Copy(aMsg.iBuf);
       
  7965         }
       
  7966 
       
  7967     hdr = (ThdrISAKMP *)lastMsg.Ptr();
       
  7968     hdr->SetLength(lastMsg.Length());  //Set the total length!!!		
       
  7969 
       
  7970     if (hdr->GetExchange() == ISAKMP_EXCHANGE_INFO)
       
  7971     {
       
  7972         SendAndSaveIkeMsgL(lastMsg, iLastRemoteAddr, FloatedPort);   //No timers!
       
  7973     }
       
  7974     else    //Normal msg.
       
  7975     {
       
  7976         iTimer->Cancel();   //Cancel previous timer because reply received & processed
       
  7977         DEBUG_LOG(_L("Timer Cancelled!"));
       
  7978         iRetryNum = 0;
       
  7979 		SendAndSaveIkeMsgL(lastMsg, iLastRemoteAddr, FloatedPort);
       
  7980         iTimer->IssueRequest(MAX_RETRANS_TIMER * 1000000); // 1000000 = 1 second
       
  7981     }
       
  7982     
       
  7983 }
       
  7984 
       
  7985 
       
  7986 void CIkev1Negotiation::ReSendL()
       
  7987 {
       
  7988     //Will resend a packet in the interval (MAX_RETRANS_TIMER/2 , MAX_RETRANS_TIMER)
       
  7989     if ( iRetryNum < MAX_RETRANS_COUNT ) 
       
  7990     {
       
  7991         DEBUG_LOG2(_L("---------- Phase %d - Stage %d ----------"),iPhase, iStage - 1);
       
  7992         DEBUG_LOG1(_L("ReSending(%d)..."), iRetryNum);
       
  7993 		TBool FloatedPort = EFalse;	
       
  7994 		if ( iNAT_D_Flags & (REMOTE_END_NAT + LOCAL_END_NAT) )
       
  7995 			FloatedPort = ETrue;
       
  7996 		TPtr8 lastMsg(iLastMsg->Des());
       
  7997 		iPluginSession->SendIkeMsgL(lastMsg, iLastRemoteAddr, FloatedPort);  
       
  7998         //next retransmission between MAX_RETRANS_TIMER/2 and MAX_RETRANS_TIMER seconds
       
  7999         TTime tmp_time;
       
  8000         TReal secs = 0;
       
  8001         tmp_time.UniversalTime();
       
  8002         TInt64 seed = tmp_time.Int64();
       
  8003         TInt rand = Math::Rand(seed);
       
  8004         TInt err = Math::Round(secs, rand / (KMaxTInt / MAX_RETRANS_TIMER/2), 0);
       
  8005         secs = Math::Round(secs, secs + MAX_RETRANS_TIMER/2, 0);
       
  8006         if ((!secs) || (err != KErrNone))
       
  8007             secs = MAX_RETRANS_TIMER/2;
       
  8008         iTimer->IssueRequest((TInt)secs * 1000000);  // 1000000 = 1 second
       
  8009         iRetryNum++;
       
  8010     }
       
  8011     else
       
  8012     {
       
  8013 		SendDeleteL(PROTO_ISAKMP);
       
  8014 		if ( iPhase == PHASE_I )
       
  8015 		{	
       
  8016            DEBUG_LOG(_L("Max num retries reached!!!"));
       
  8017 		}		
       
  8018 		else
       
  8019 		{		    
       
  8020 		    DEBUG_LOG(_L("Quick mode failed, Max num retries reached!!!"));
       
  8021 		}
       
  8022 	
       
  8023 		if ( iPhase == PHASE_I &&
       
  8024 		     iPluginSession->FindIkev1SA() == NULL )
       
  8025 		{
       
  8026             // Set error status in Phase 1, if there are no IKE SAs.
       
  8027             if ( GetNotifyStatus() )
       
  8028                  SetErrorStatus(KKmdIkeNoProposalErr);                                           
       
  8029             else SetErrorStatus(KKmdIkeNoResponseErr);
       
  8030 		}
       
  8031 		
       
  8032         LOG_KMD_EVENT( MKmdEventLoggerIf::KLogError,
       
  8033                        R_VPN_MSG_VPN_GW_NO_RESP,
       
  8034                        ErrorStatus(),
       
  8035                        iPluginSession->VpnIapId(),
       
  8036                        &iRemoteAddr );								
       
  8037         iPluginSession->DeleteNegotiation( this );
       
  8038     }
       
  8039 }
       
  8040 
       
  8041 void CIkev1Negotiation::SendDeleteL(TUint8 aProtocol, TUint32 aIpsecSPI)
       
  8042 {
       
  8043 	TIkev1IsakmpStream* msg = SaveIkeMsgBfr( new (ELeave) TIkev1IsakmpStream(iDebug) );							
       
  8044 	
       
  8045     TBuf8<MAX_SPI_SIZE> SPI;
       
  8046 
       
  8047     DEBUG_LOG(_L("Sending Delete payload..."));
       
  8048     
       
  8049     //Creates a DUMMY negotiation with the info to send the packet
       
  8050     TUint8 tmp_exchange = iExchange;
       
  8051     iExchange=ISAKMP_EXCHANGE_INFO; //Set the exchange type as info
       
  8052 
       
  8053     msg->IsakmpInit(this);
       
  8054 
       
  8055     //HASH Payload only if payload protected with encyption
       
  8056     if (iFlags & ISAKMP_HDR_EFLAG)
       
  8057 	    msg->IsakmpHashL();	
       
  8058 
       
  8059     if (aProtocol == PROTO_ISAKMP)  //ISAKMP SPI are the cookies
       
  8060     {
       
  8061         SPI.Copy(iCookie_I);
       
  8062         SPI.Append(iCookie_R);
       
  8063     }
       
  8064     else    //IPSECSPI
       
  8065     {
       
  8066         SPI.Copy((TUint8 *)&aIpsecSPI, sizeof(TUint32));
       
  8067     }
       
  8068     msg->IsakmpDelete(SPI, aProtocol);
       
  8069 
       
  8070     if (iFlags & ISAKMP_HDR_EFLAG)
       
  8071     {
       
  8072         msg->IsakmpHashContL();
       
  8073     }
       
  8074     DEBUG_LOG(_L("Sending Delete Payload..."));
       
  8075 	SendL(*msg);
       
  8076 
       
  8077     iExchange = tmp_exchange;
       
  8078 }
       
  8079 
       
  8080 void CIkev1Negotiation::CheckSendResponderLifetime(TIkev1IsakmpStream &aMsg)
       
  8081 {
       
  8082     TInt count = iChosenProp_IIList->Count();
       
  8083     CProposal_II *prop;
       
  8084     TChosenAttrib_II *attr_II;
       
  8085     TSPINode inboundspi_node;
       
  8086     TInt j;
       
  8087     for (j = 0 ; j < count; j++)    //Check all the chosen proposals (Probably one)
       
  8088     {
       
  8089         prop = iChosenProp_IIList->At(j);
       
  8090         inboundspi_node = iInboundSPIList->At(j);
       
  8091         attr_II = (TChosenAttrib_II *)prop->iAttrList->At(0);   //only 1 transform is chosen no matter how many there are
       
  8092 
       
  8093         if ((attr_II->iReducedLifeSecs.Length() != 0) || (attr_II->iReducedLifeKBytes.Length() != 0))   //Any lifetime to update
       
  8094             aMsg.IsakmpResponderLifetime(prop->iProtocol, inboundspi_node.iSPI, attr_II->iReducedLifeSecs, attr_II->iReducedLifeKBytes);
       
  8095 
       
  8096     }
       
  8097 }
       
  8098 
       
  8099 
       
  8100 /**--------------------------------------------------------------------
       
  8101  *
       
  8102  *  The following methods are used to implement the Dead Peer Detection
       
  8103  *  protocol defined in <draft-ietf-ipsec-dpd-04.txt>
       
  8104  *  When timeout expires the R-U-THERE notify message is transmitted
       
  8105  *  if there has not been any activity during the last timeout
       
  8106  *
       
  8107  *--------------------------------------------------------------------*/
       
  8108 void CIkev1Negotiation::DpdNotifyMessageReceivedL(TIkev1SAData* aSa, TUint16 aMsgType, TUint32 aSequence)
       
  8109 {
       
  8110 
       
  8111 	if ( aMsgType == DPD_R_U_THERE )
       
  8112 	{
       
  8113 	  //
       
  8114 	  // -- Assure that sequence number in notify data is what expected
       
  8115 	  // -- If ok, transmit a R-U-THERE-ACK
       
  8116 	  //
       
  8117 		DEBUG_LOG(_L("DPD R-U-THERE Notify received"));	  
       
  8118 		if ( (aSa->iExpectedDPDSequence == aSequence) || (aSa->iExpectedDPDSequence == 0) )
       
  8119 		{
       
  8120 			aSa->iExpectedDPDSequence = GetNextSequence(aSequence);
       
  8121 			DEBUG_LOG(_L("Sending DPD R-U-THERE_ACK notify"));
       
  8122 			SendDpdNotifyMessageL(DPD_R_U_THERE_ACK, aSequence);
       
  8123 			iPluginSession->UpdateIkev1SAL(aSa->iSAId, EFalse, aSa);			
       
  8124 		}
       
  8125 #ifdef _DEBUG		
       
  8126 		else DEBUG_LOG(_L("Wrong sequence number in DPD notify message"));
       
  8127 #endif // _DEBUG		
       
  8128 	}
       
  8129 	else if ( aMsgType == DPD_R_U_THERE_ACK )
       
  8130 	{
       
  8131 	  //
       
  8132 	  // -- Assure that sequence number in notify data is corresponds
       
  8133 	  //    current pending sequence
       
  8134 	  //
       
  8135 		DEBUG_LOG(_L("DPD R-U-THERE-ACK Notify received"));
       
  8136 		if ( aSa->iPendingDPDSequence == aSequence )
       
  8137 		{
       
  8138 			aSa->iPendingDPDSequence = 0;
       
  8139 			aSa->iDPDRetry           = 0;
       
  8140 			iPluginSession->UpdateIkev1SAL(aSa->iSAId, EFalse, aSa);
       
  8141 		}
       
  8142 #ifdef _DEBUG		
       
  8143 		else DEBUG_LOG(_L("Wrong sequence number in DPD notify ack message"));
       
  8144 #endif // _DEBUG		
       
  8145 	}	
       
  8146 }
       
  8147 
       
  8148 void CIkev1Negotiation::SendKeepAliveMsgL(TIkev1SAData* aSa)
       
  8149 {
       
  8150 	if ( aSa->iDPDRetry > KMaxDpdRetryCount )
       
  8151 	{
       
  8152 		//
       
  8153 		//  DPD Retry count exhausted, current IKE SA in interpreted to
       
  8154 		//  be closed
       
  8155 		//
       
  8156         LOG_KMD_EVENT( MKmdEventLoggerIf::KLogError,
       
  8157                        R_VPN_MSG_VPN_GW_NO_RESP,
       
  8158                        KKmdIkeNoResponseErr,
       
  8159                        iPluginSession->VpnIapId(),
       
  8160                        &iRemoteAddr );      	
       
  8161         
       
  8162 		iPluginSession->DeleteIpsecSAs(aSa->iSAId);		
       
  8163 		iPluginSession->UpdateIkev1SAL(aSa->iSAId, ETrue);
       
  8164 	}
       
  8165 	else
       
  8166 	{
       
  8167 	    //
       
  8168 	    //  Send DPD R-U-THERE notify message 
       
  8169 	    //
       
  8170 		if ( aSa->iPendingDPDSequence == 0 )
       
  8171 		{	
       
  8172 			aSa->iPendingDPDSequence = aSa->iDPDSequence;
       
  8173 			aSa->iDPDSequence = GetNextSequence(aSa->iDPDSequence);			
       
  8174 		}	
       
  8175 		else
       
  8176 		{
       
  8177 		    aSa->iDPDRetry ++;
       
  8178 		}
       
  8179 		DEBUG_LOG(_L("Sending DPD R-U-THERE notify"));		
       
  8180 		SendDpdNotifyMessageL(DPD_R_U_THERE, aSa->iPendingDPDSequence);
       
  8181 	}
       
  8182 	SetFinished();
       
  8183 }
       
  8184 
       
  8185 MKmdEventLoggerIf& CIkev1Negotiation::EventLogger()
       
  8186 {
       
  8187     return iPluginSession->EventLogger();
       
  8188 }
       
  8189 
       
  8190 void CIkev1Negotiation::IpsecSaSpiRetrieved(TUint32 aSpiRequestId, 
       
  8191                                             TInt aStatus, 
       
  8192                                             TUint32 aSpi) 
       
  8193 {
       
  8194     DEBUG_LOG3(_L("IPsec SA SPI retrieved, seq=%d, SPI=%d, status=%d"),
       
  8195             aSpiRequestId, aSpi, aStatus);
       
  8196     if ( aStatus == KErrNone )
       
  8197         {
       
  8198         TRAP( aStatus, ReceiveSPIL( aSpi, aSpiRequestId ) );
       
  8199         }
       
  8200     else
       
  8201         {
       
  8202         iPluginSession->HandleError( aStatus );
       
  8203         }
       
  8204 }
       
  8205 
       
  8206 TBool CIkev1Negotiation::IsRekeyingIkeSa()
       
  8207 {
       
  8208     return ( iSARekeyInfo != NULL );
       
  8209 }
       
  8210 
       
  8211 void CIkev1Negotiation::PreparePhase2L(const TPfkeyMessage &aReq)
       
  8212 {
       
  8213     DEBUG_LOG(_L("Prepare for Phase II"));
       
  8214     GetAcquireDataL(aReq);
       
  8215     iPhaseIIAfterIkeSaRekey = ETrue;
       
  8216 }
       
  8217 
       
  8218 TUint32 CIkev1Negotiation::GetNextSequence(TUint32 aSequence)
       
  8219 {
       
  8220 	aSequence ++;
       
  8221 	if ( aSequence == 0 )
       
  8222 		aSequence = 1;
       
  8223 	return aSequence;
       
  8224 }
       
  8225 
       
  8226 void CIkev1Negotiation::SendDpdNotifyMessageL(TUint16 aMsgType, TUint32 aSequence)
       
  8227 {
       
  8228 	iExchange  = ISAKMP_EXCHANGE_INFO;
       
  8229 	iMessageId = RandomMessageId();
       
  8230 	TIkev1IsakmpStream* Msg = SaveIkeMsgBfr( new (ELeave) TIkev1IsakmpStream(iDebug) );
       
  8231 	Msg->IsakmpInit(this);
       
  8232 	Msg->IsakmpHashL();
       
  8233 	TUint32 NotifData = ByteOrder::Swap32(aSequence);
       
  8234 	Msg->IsakmpNotification(aMsgType, PROTO_ISAKMP, (TUint8*)&NotifData, sizeof(NotifData));
       
  8235 	Msg->IsakmpHashContL();
       
  8236 	SendL(*Msg);
       
  8237 }
       
  8238 
       
  8239 TInt CIkev1Negotiation::ErrorStatus()
       
  8240 {
       
  8241     TInt ret( KErrNone );
       
  8242     if ( iPluginSession )
       
  8243     {
       
  8244         ret = iPluginSession->ErrorStatus();
       
  8245     }
       
  8246     return ret;
       
  8247 }
       
  8248 
       
  8249 void CIkev1Negotiation::SetErrorStatus(TInt aStatus)
       
  8250 {
       
  8251     SetFinished();
       
  8252     iPluginSession->SetErrorStatus(aStatus);
       
  8253 }
       
  8254 
       
  8255 void CIkev1Negotiation::SendAndSaveIkeMsgL( const TDesC8& aIkeMsg,
       
  8256                                             TInetAddr& aDestAddr,
       
  8257                                             TBool aUseNatPort )
       
  8258 {
       
  8259     iPluginSession->SendIkeMsgL( aIkeMsg, aDestAddr, aUseNatPort );
       
  8260     SaveLastMsgL();
       
  8261 }
       
  8262 
       
  8263 
       
  8264 TBool CIkev1Negotiation::IsRetransmit(TLastIKEMsg& aRef)
       
  8265 {       
       
  8266     TBool isRetransmit(EFalse);
       
  8267     if (iLastIKEMsgInfo.IsUninitialized())
       
  8268         {
       
  8269         TIkev1SAData* ikev1SAData = iPluginSession->FindIkev1SAData(iSAId);
       
  8270         if (ikev1SAData && ikev1SAData->iLastIKEMsgInfo.IsReTransmit(aRef))
       
  8271             {
       
  8272             isRetransmit = ETrue;
       
  8273             }
       
  8274         }
       
  8275     else
       
  8276         {
       
  8277         isRetransmit = iLastIKEMsgInfo.IsReTransmit(aRef);
       
  8278         }
       
  8279     return isRetransmit;
       
  8280 }
       
  8281 
       
  8282 void CIkev1Negotiation::SaveRetransmitInfo(TLastIKEMsg& aRef)
       
  8283 {
       
  8284     aRef.Store(iLastIKEMsgInfo);
       
  8285     TIkev1SAData* ikev1SAData = iPluginSession->FindIkev1SAData(iSAId);
       
  8286     if (ikev1SAData != NULL)
       
  8287         {
       
  8288         aRef.Store(ikev1SAData->iLastIKEMsgInfo);
       
  8289         }
       
  8290 }
       
  8291 
       
  8292 void CIkev1Negotiation::SaveLastMsgL()
       
  8293 {
       
  8294     if ( iLastMsg != NULL )
       
  8295         {
       
  8296         TIkev1SAData* ikev1SAData = iPluginSession->FindIkev1SAData(iSAId);
       
  8297         if ( ikev1SAData != NULL )
       
  8298             {
       
  8299             delete ikev1SAData->iLastMsg;
       
  8300             ikev1SAData->iLastMsg = iLastMsg->AllocL(); 
       
  8301             }                
       
  8302         }    
       
  8303 }
       
  8304 
       
  8305 
       
  8306