vpnengine/ikev2lib/src/ikev2negotiation.cpp
changeset 0 33413c0669b9
child 1 c9c2ad51f972
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:   IKEv2/IPSEC SA negotiation
       
    15 *
       
    16 */
       
    17 
       
    18 #include <random.h>
       
    19 #include <in_sock.h>
       
    20 
       
    21 #include "ikev2Negotiation.h"
       
    22 #include "ikedebug.h"
       
    23 #include "ikev2natt.h"
       
    24 #include "ikev2mobike.h"
       
    25 #include "ikev2proposal.h"
       
    26 #include "ikev2SAdata.h"
       
    27 #include "ikev2pluginsession.h"
       
    28 #include "ikev2pfkey.h"
       
    29 #include "ikev2config.h"
       
    30 #include "ikev2EapInterface.h"
       
    31 #include "ikev2payloads.h"
       
    32 #include "ikev2const.h"
       
    33 #include "ikemsgrec.h"
       
    34 #include "ipsecproposal.h"
       
    35 #include "ipsecselectors.h"
       
    36 #include "ikepolparser.h"
       
    37 #include "kmdapi.h"
       
    38 #include "ikecaelem.h"
       
    39 #include "ikecalist.h"
       
    40 #include "ikepkiutils.h"
       
    41 #include "vpnapidefs.h"
       
    42 #include "kmdeventloggerif.h"
       
    43 #include "ipsecsalist.h"
       
    44 #include "ikev2message.h"
       
    45 #include "ikev2identity.h"
       
    46 #include "ikev2acquire.h"
       
    47 #include "ikev2expire.h"
       
    48 #include "ikev2ipsecsarekeydata.h"
       
    49 #include "ikev2messagesendqueue.h"
       
    50 
       
    51 _LIT8(KIkev2PSKData, "Key Pad for IKEv2");
       
    52 _LIT8(KZeroDesc, "");
       
    53 
       
    54 CIkev2Negotiation* CIkev2Negotiation::NewL(CIkev2PluginSession& aIkeV2PlugInSession,
       
    55                                            CPFKeySocketIf& aPfKeySocketIf,
       
    56                                            MKmdEventLoggerIf& aEventLogger,
       
    57                                            CIkev2MessageSendQueue& aMessageSendQue,
       
    58                                            MIkeDebug& aDebug,
       
    59                                            CIkeData* aIkeData, 
       
    60                                            TUint32 aVpnIapId,
       
    61                                            TUint32 aSaId,
       
    62                                            TInetAddr aPhysicalInterfaceAddress,
       
    63                                            TInetAddr aRemoteAddress)
       
    64     {
       
    65     
       
    66     CIkev2Negotiation* self = new (ELeave) CIkev2Negotiation(aIkeV2PlugInSession, aPfKeySocketIf, 
       
    67                                                              aEventLogger, aMessageSendQue, 
       
    68                                                              aDebug, aSaId);
       
    69     CleanupStack::PushL(self);
       
    70     self->ConstructL();
       
    71 
       
    72     self->iHdr.iIkeData = aIkeData;
       
    73     self->iHdr.iVpnIapId = aVpnIapId;
       
    74     self->iProcessEvents     = ETrue;
       
    75     self->iHdr.iRemoteAddr = aRemoteAddress;
       
    76     self->iHdr.iRemoteAddr.SetPort(IKE_PORT);      
       
    77     
       
    78     //
       
    79     // Get IP address information for IKE SA negotiation
       
    80     // Remote address is taken from current IKE policy data (CIkeData)
       
    81     // Local address is resolved via IKE policy using policy handle
       
    82     //
       
    83     if ( self->iHdr.iRemoteAddr.IsUnspecified() )
       
    84     {        
       
    85         self->iHdr.iRemoteAddr = self->iHdr.iIkeData->iAddr;
       
    86         self->iHdr.iRemoteAddr.SetPort(IKE_PORT);
       
    87     }   
       
    88     self->iHdr.iDestinAddr = self->iHdr.iRemoteAddr;
       
    89     self->iHdr.iLocalAddr = aPhysicalInterfaceAddress;
       
    90     TInt Scope = self->iHdr.iRemoteAddr.Scope();
       
    91     if ( Scope )
       
    92         self->iHdr.iLocalAddr.SetScope(Scope); // Set local scope same with remote scope        
       
    93 
       
    94     CleanupStack::Pop(self);
       
    95     return self;
       
    96     }
       
    97 
       
    98 
       
    99 CIkev2Negotiation* CIkev2Negotiation::NewL(CIkev2PluginSession& aIkeV2PlugInSession,
       
   100                                            CPFKeySocketIf& aPfKeySocketIf,
       
   101                                            MKmdEventLoggerIf& aEventLogger,
       
   102                                            CIkev2MessageSendQueue& aMessageSendQue,
       
   103                                            MIkeDebug& aDebug,
       
   104                                            TIkev2SAData& aIkev2SAdata)
       
   105     {
       
   106     CIkev2Negotiation* self = new (ELeave) CIkev2Negotiation(aIkeV2PlugInSession, aPfKeySocketIf, 
       
   107                                                              aEventLogger, aMessageSendQue, 
       
   108                                                              aDebug, aIkev2SAdata.SaId());
       
   109     CleanupStack::PushL(self);
       
   110     self->ConstructL();
       
   111     
       
   112     self->iHdr.Copy(aIkev2SAdata);
       
   113     self->iState = KStateIkeSaCompleted;
       
   114     
       
   115     CleanupStack::Pop(self);
       
   116     return self;
       
   117     }
       
   118 
       
   119 
       
   120 CIkev2Negotiation::CIkev2Negotiation(CIkev2PluginSession& aIkeV2PlugInSession, CPFKeySocketIf& aPfKeySocketIf,
       
   121                                      MKmdEventLoggerIf& aEventLogger, CIkev2MessageSendQueue& aMessageSendQue,
       
   122                                      MIkeDebug& aDebug, TUint32 aSaId) 
       
   123 : iChild(aDebug), iIkeV2PlugInSession(aIkeV2PlugInSession), iPfKeySocketIf(aPfKeySocketIf), 
       
   124   iEventLogger(aEventLogger), iMessageSendQue(aMessageSendQue),iDebug(aDebug), iDHGroupGuess(1) 
       
   125     {
       
   126     DEBUG_LOG1(_L("CIkev2Negotiation::CIkev2Negotiation: 0x%08x"), this);
       
   127 
       
   128     iHdr.SetSaId(aSaId);
       
   129     iHdr.iWindowSize = DEF_MSG_ID_WINDOW;        
       
   130     }   
       
   131 
       
   132 
       
   133 void CIkev2Negotiation::ConstructL()
       
   134     {  
       
   135     iTimer = CIkev2RetransmitTimer::NewL(*this);    
       
   136     iSpiRetriever = CIpsecSaSpiRetriever::NewL(*this, iPfKeySocketIf);
       
   137         
       
   138     iIkeV2PlugInSession.LinkNegotiation(this); // <- takes ownership of this
       
   139     iProcessEvents = ETrue;
       
   140     }
       
   141 
       
   142 
       
   143 CIkev2Negotiation::~CIkev2Negotiation()
       
   144     {
       
   145     
       
   146     delete iSpiRetriever;
       
   147     // Turn off event processing to prevent EAPVPNIF event
       
   148 	iProcessEvents = EFalse;
       
   149     delete iTimer;
       
   150     
       
   151     DEBUG_LOG1(_L("CIkev2Negotiation::~CIkev2Negotiation: 0x%08x"), this);        
       
   152     iIkeV2PlugInSession.RemoveNegotiation(this);
       
   153 
       
   154     iHdr.CleanUp();
       
   155     
       
   156     //
       
   157     // Purge Acquire, Expire and Info message queues
       
   158     //
       
   159     CIkev2Acquire::PurgeQue(GetAcquireQue());
       
   160     CIkev2Expire::PurgeQue(GetExpireQue());
       
   161 	
       
   162 	delete iPeerCert;					   
       
   163     delete iSavedSaInit;
       
   164     delete iProposedSA;
       
   165     delete iDHKeys;
       
   166     delete iDHPublicPeer;
       
   167     delete iNonce_I;
       
   168     delete iNonce_R;
       
   169     delete iAuthMsgInit;
       
   170     delete iAuthMsgResp;
       
   171     delete iRemoteIdentity;
       
   172     delete iLocalIdentity;
       
   173     delete iNatNotify;
       
   174     delete iConfigMode;
       
   175     delete iEapPlugin;
       
   176     delete iPkiService; 
       
   177     delete iPresharedKey;
       
   178     delete iChildSaRequest;
       
   179     }
       
   180 
       
   181 void CIkev2Negotiation::StartIkeSANegotiationL()
       
   182     {
       
   183     __ASSERT_DEBUG(iChildSaRequest == NULL, User::Invariant());
       
   184     
       
   185     //This method should be called only if we have IA in use.
       
   186     //Otherwise the negotiation should start with ProcessAcquire
       
   187     __ASSERT_DEBUG(iHdr.iIkeData->iUseInternalAddr, User::Invariant());
       
   188     
       
   189 	//
       
   190 	// This method is called when an IKE SA negotiation is started due
       
   191 	// a RKMD::Activate() request with policy that uses IA.   
       
   192 	//    
       
   193 	iHdr.iInitiator = ETrue;
       
   194     LoadEapPluginL();
       
   195     
       
   196     GetNonceDataL(ETrue);
       
   197 
       
   198     CIkev2Acquire* Acquire = IpsecSelectors::BuildVirtualAcquireL(iIkeV2PlugInSession);
       
   199     CleanupStack::PushL(Acquire);
       
   200            
       
   201 	if ( !InitPkiServiceL() )
       
   202 	    {
       
   203 	    //No PkiService Needed.
       
   204 	    //Continue by requesting SPI for IPsecSA.	    
       
   205 	    CIkev2Acquire::Link(Acquire, GetAcquireQue());    
       
   206         //
       
   207         // Get SPI for inbound SA with PFKEY GETSPI primitive
       
   208         //
       
   209         GetIpsecSPI(Acquire);
       
   210 	    }
       
   211 	else
       
   212 	    {
       
   213 	    iChildSaRequest = Acquire;
       
   214 	    }
       
   215 	CleanupStack::Pop(Acquire);	
       
   216 	}
       
   217 
       
   218 TBool CIkev2Negotiation::StartRespondingL(const ThdrISAKMP& aIkeMessage)
       
   219     {
       
   220 	//
       
   221 	// This method is called when local end is going to ACT as a
       
   222 	// responder of an IKE SA negotiation.
       
   223 	// Initialize PKI service usage, if needed. Because PKI service
       
   224 	// initialisation is an asynchronous operation we must take a copy
       
   225 	// of incoming IKE message from where it is processed when PKI
       
   226 	// service initialisation is completed.
       
   227 	//
       
   228 	TBool Status( InitPkiServiceL() );
       
   229 	if ( Status )
       
   230 	    {
       
   231 	    TInt MsgLth = (TInt)aIkeMessage.GetLength(); 	
       
   232 	    delete iSavedSaInit;
       
   233 	    iSavedSaInit = NULL;
       
   234 	    iSavedSaInit = HBufC8::NewL(MsgLth);
       
   235 	    iSavedSaInit->Des().Copy((TUint8*)&aIkeMessage, MsgLth);
       
   236 	    }
       
   237 	return !Status;
       
   238     }
       
   239 
       
   240 void CIkev2Negotiation::StartIkeSADeleteL()
       
   241 {
       
   242 	//
       
   243 	// This method is called when an IKE SA shall be deleted either due
       
   244 	// IKE SA timeout or due a RKMD::Deactivate() request
       
   245 	//
       
   246 	BuildDeleteRequestL(NULL);
       
   247 }
       
   248 
       
   249 
       
   250 void CIkev2Negotiation::IkeSaCompletedL()
       
   251 {
       
   252 
       
   253 	//
       
   254 	// This method is when an IKE SA negotiation has been succesfully
       
   255 	// completed.
       
   256 	// The following actions are taken:
       
   257 	// -- Get Virtual IP from iConfigMode object, if present and
       
   258 	//    modify IKE SA lifetime if Virtual Ip expiration time is
       
   259 	//    shorter than configured iKE SA lifetime  
       
   260 	// -- Create a new IKE SA object, if not a rekeyd IKE SA
       
   261 	// -- If activation going, call IkeSaCompleted method in plug-in
       
   262 	//
       
   263     TVPNAddress VirtualIp;
       
   264 	if ( iConfigMode )
       
   265 	{
       
   266 	   VirtualIp = iConfigMode->VirtualIp();
       
   267 	   iHdr.StoreVirtualIp(VirtualIp.iVPNIfAddr);
       
   268 	   TUint32 ExpireTime = iConfigMode->ExpireTime();
       
   269 	   if ( ExpireTime && (ExpireTime < iHdr.iLifetime) )
       
   270 		   iHdr.iLifetime = ExpireTime;
       
   271 	}	
       
   272 	
       
   273 	if(!iIkeV2PlugInSession.FindIkev2SA(iHdr.SaId(), KSaStateNotDefined, KSaStateNotDefined))
       
   274 	    {
       
   275 	    iIkeV2PlugInSession.CreateIkev2SAL(iHdr);	
       
   276 	    }
       
   277 	
       
   278 	iIkeV2PlugInSession.IkeSaCompleted(KErrNone, VirtualIp);
       
   279 	
       
   280 	iEventLogger.LogEvent(MKmdEventLoggerIf::KLogInfo, R_VPN_MSG_VPN_GW_AUTH_OK, KErrNone, 
       
   281 	                      iHdr.iVpnIapId, &iHdr.iRemoteAddr);
       
   282 	iEventLogger.LogEvent(MKmdEventLoggerIf::KLogInfo, R_VPN_MSG_ADDR_INFO_FOR_VPN_AP,
       
   283                           iHdr.iNATFlags, iHdr.iVpnIapId,
       
   284                           (!VirtualIp.iVPNIfAddr.IsUnspecified() ? &(VirtualIp.iVPNIfAddr) : NULL));			
       
   285 
       
   286 	if ( iChildSaRequest )
       
   287 	{	
       
   288 	   IpsecSANegotiatedL();
       
   289 	}	
       
   290     if ( RequestsPending() )
       
   291 	{	
       
   292 	   ContinueIkeNegotiationL();
       
   293 	}   
       
   294 	else
       
   295 	{	
       
   296        if ( !iHdr.iInitiator )
       
   297 	   {	   
       
   298 	       iIkeV2PlugInSession.StopResponding();
       
   299 	       delete this;   // Current negotiation can be deleted
       
   300 	   }
       
   301 	   else iStopped = ETrue;
       
   302 	}
       
   303 }
       
   304 
       
   305 void CIkev2Negotiation::IkeSaFailed(TInt Status)
       
   306     {
       
   307 	//
       
   308 	// This method is when a IKE SA negotiation has failed
       
   309 	// The following actions are taken:
       
   310 	//
       
   311 
       
   312     TVPNAddress dummyVirtualIp;
       
   313 
       
   314 	iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest);	
       
   315 	
       
   316 	if ( !iHdr.iInitiator )
       
   317 	    iIkeV2PlugInSession.StopResponding();
       
   318 	
       
   319 	if ( (iSendAttempt <= KMaxSendAttemps ) &&
       
   320 	     ((iState == KStateIkeSaEapStarted) || 
       
   321 	      (iState == KStateIkeSaEapGoing)))
       
   322 		 iDeleteIkeSA = ETrue;
       
   323 	else iStopped = ETrue;
       
   324 
       
   325 	iEventLogger.LogEvent(MKmdEventLoggerIf::KLogError, R_VPN_MSG_REAL_IAP_ACT_FAILED, Status, 
       
   326 	                      iHdr.iVpnIapId, &iHdr.iRemoteAddr);
       
   327 	
       
   328     iIkeV2PlugInSession.IkeSaCompleted(Status, dummyVirtualIp);
       
   329     }
       
   330 
       
   331 void CIkev2Negotiation::IpsecSANegotiatedL()
       
   332 {
       
   333 	//
       
   334 	// This method is when an Ipsec SA negotiation has been succesfully
       
   335 	// completed.
       
   336 	// -- Update Ipsec SADB using PFKEY Update and Add primitives	
       
   337 	// -- Find a new IKE SA object and queue Ipsec SA data into it
       
   338 	// -- Try to start a new exchange from queue, if there is nothing
       
   339 	//    to start in queues mark current negotiation stopped
       
   340 	//
       
   341 	iChild.iSrcSpecific = iChildSaRequest->SrcSpecific();  
       
   342 	Ikev2Pfkey::UpdateIpsecSaDataBaseL(iHdr, iChild, iIkeV2PlugInSession, *iChildSaRequest);
       
   343 	
       
   344 	CIpsecSARekeyData* rekeyData = 
       
   345 	    CIpsecSARekeyData::NewL(iChildSaRequest->ReplayWindow(),
       
   346                                 iChildSaRequest->HardLifetime(),
       
   347                                 iChildSaRequest->SoftLifetime(),
       
   348                                 iChildSaRequest->TS_i(),
       
   349                                 iChildSaRequest->TS_r(),
       
   350                                 *iChildSaRequest->LocalId(),
       
   351                                 *iChildSaRequest->RemoteId());
       
   352 	
       
   353 	iChild.PurgeKeyMaterial();	// Ipsec Keymaterial not saved into IKE SA
       
   354 	iChild.DeleteRekeyData();
       
   355 	iChild.iRekeyData = rekeyData;
       
   356 	
       
   357 	iIkeV2PlugInSession.UpdateIkev2SAL(&iHdr, &iChild);
       
   358 	
       
   359 	delete iChildSaRequest;
       
   360 	iChildSaRequest = NULL;
       
   361 	
       
   362 	if ( RequestsPending() )	
       
   363 	     ContinueIkeNegotiationL();
       
   364 	else
       
   365 	{	if ( iState == KStateIkeChildSAResponse )
       
   366 		     delete this;
       
   367 		else iStopped = ETrue;
       
   368 	}	
       
   369 }
       
   370 
       
   371 
       
   372 void CIkev2Negotiation::ProcessIkeMessageL(const ThdrISAKMP& aIkeMessage, 
       
   373                                            const TInetAddr& aRemote, 
       
   374                                            TUint16 aLocalPort)
       
   375     {
       
   376 	//
       
   377 	// Start to process received IKE message by constructing a
       
   378 	// CIkev2Payloads object. CIkev2Payloads construction takes also
       
   379 	// care of the decryption of an Encrypted payload if present.  
       
   380 	//    
       
   381 	TBool Status( ETrue );
       
   382 	
       
   383 	CIkev2Payloads* IkeMsg = CIkev2Payloads::NewL(aIkeMessage, iHdr);
       
   384 	CleanupStack::PushL(IkeMsg);				 	
       
   385 	
       
   386     DEBUG_LOG2(_L("Process IKE message, SAID=%d, Msg ID=%d"),
       
   387             iHdr.SaId(), aIkeMessage.GetMessageId());	
       
   388 	if ( IkeMsg->Status() )
       
   389 	    {
       
   390 	    //
       
   391 	    //  An error occurred during IKE message parsing
       
   392 	    //
       
   393 	    SetNotifyCode(IkeMsg->Status());
       
   394         DEBUG_LOG1(_L("Error in parsing of received IKE message: %d"), IkeMsg->Status());
       
   395 
       
   396 	    if ( !iHdr.iInitiator && iState == KStateIdle )
       
   397 	        {
       
   398 		    iStopped = ETrue;   // Negotiation object shall be released
       
   399 	        }
       
   400 	    else 
       
   401 	        {
       
   402 	        CheckNotifyCodeL(IkeMsg);
       
   403 	        }
       
   404 	    CleanupStack::PopAndDestroy(IkeMsg); // IkeMsg
       
   405 	    return;
       
   406 	    }
       
   407 	
       
   408 	if ( (iHdr.iNATFlags & (REMOTE_END_NAT + MOBIKE_USED)) && 
       
   409 	    IkeMsg->Encrypted() )
       
   410 	    {
       
   411 	    //
       
   412 	    // Received IKE message contains Encrypted payload. Save source
       
   413 	    // IP as new destination IP to negotiation object
       
   414 	    //
       
   415 	    iHdr.iDestinAddr = aRemote;
       
   416 	    iHdr.iDestinAddr.SetPort(FLOATED_IKE_PORT);
       
   417 	    }	
       
   418 	
       
   419 	TPtrC8 ikeMsgDes((TUint8*)&aIkeMessage, aIkeMessage.GetLength());
       
   420 	
       
   421 	TInetAddr localAddr(iHdr.iLocalAddr);
       
   422 	localAddr.SetPort(aLocalPort);
       
   423 	TRACE_MSG(ikeMsgDes, aRemote, localAddr, 
       
   424               (CIkePcapTrace::TEncryptionType)iHdr.iEncrAlg);
       
   425 
       
   426 	//
       
   427 	// Process received IKE message according to Exchange type
       
   428 	//
       
   429 	switch ( aIkeMessage.GetExchange() )
       
   430 	{
       
   431 		case IKE_SA_INIT:
       
   432 		    DEBUG_LOG(_L("IKE_SA_INIT message received"));
       
   433 			Status = ProcessIkeSaInitL(IkeMsg, aRemote);
       
   434 			if ( !Status )
       
   435 			   IkeSaFailed(KKmdIkeNegotFailed);	
       
   436 			break;
       
   437 			
       
   438 		case IKE_AUTH:
       
   439 		    DEBUG_LOG(_L("IKE_AUTH message received"));
       
   440 			Status = ProcessIkeAuthL(IkeMsg);
       
   441 			if ( !Status )
       
   442 			   IkeSaFailed(KKmdIkeAuthFailedErr);
       
   443 			break;
       
   444 			
       
   445 		case CREATE_CHILD_SA:
       
   446 		    DEBUG_LOG(_L("CREATE_CHILD_SA message received"));
       
   447 			Status = ProcessChildSaL(IkeMsg);
       
   448 			break;
       
   449 
       
   450 		case INFORMATIONAL:
       
   451 		    DEBUG_LOG(_L("INFORMATION message received"));
       
   452 			Status = ProcessInfoMsgL(IkeMsg);			
       
   453 			break;
       
   454 
       
   455 		default:
       
   456 		    DEBUG_LOG(_L("UNKNOWN message received\n"));
       
   457 			Status = EFalse;  // Negotiation object shall be released			
       
   458 			break;
       
   459 	}
       
   460 
       
   461 	if ( !Status )
       
   462 	{
       
   463 	   if ( iDeleteIkeSA )
       
   464 	   {
       
   465 		  //
       
   466 		  // Used IKE SA shall be deleted due the fatal error occurred.
       
   467 		  //
       
   468 		   iDeleteIkeSA = EFalse;
       
   469 		   iIkeV2PlugInSession.DeleteIkev2SA(iHdr.SaId());			   
       
   470 		   BuildDeleteRequestL(NULL);
       
   471 	   }
       
   472 	   else
       
   473 	   {	   
       
   474 	       CheckNotifyCodeL(IkeMsg);
       
   475 	   }	  
       
   476 	}			
       
   477 	CleanupStack::PopAndDestroy(IkeMsg);	
       
   478 }
       
   479 
       
   480 void CIkev2Negotiation::ProcessAcquireL(const TPfkeyMessage &aPfkeyMsg)
       
   481     {
       
   482 	//
       
   483 	// Process received PFKEY Acquire primitive
       
   484 	// There is now the following possibilities:
       
   485 	// -- There already exists an IKE SA so new IPSEC SA is negotiated
       
   486 	//    using IKE_CHILD_SA exchange
       
   487 	// -- The is no IKE SA yet.
       
   488 	//    IPSEC SA can be negotiated concatenated during IKE_AUTH.	
       
   489 	//    If Virtual IP is specified, the CP payload is used to get
       
   490 	//    that virtual IP address. 
       
   491 	//
       
   492 	CIkev2Acquire* Acquire = CIkev2Acquire::NewL(aPfkeyMsg, iIkeV2PlugInSession.GetSAId(), 
       
   493 	    GetLocalAddr(),
       
   494 		Ikev2Proposal::GetDHGroup(iHdr.iIkeData->iGroupDesc_II), ImplicitChildSa());	
       
   495 
       
   496 	if ( iState == KStateIdle )
       
   497 	    {
       
   498 		CleanupStack::PushL(Acquire);				 								
       
   499 		LoadEapPluginL();		
       
   500 		iHdr.iInitiator = ETrue;
       
   501 		GetNonceDataL(ETrue);  // For IKE SA		
       
   502 		if ( iHdr.iIkeData->iUseInternalAddr )
       
   503 		    {
       
   504 		    CArrayFix<TIkeV2TrafficSelector>* TsI = new (ELeave) CArrayFixFlat<TIkeV2TrafficSelector>(1);
       
   505 		    CleanupStack::PushL(TsI);
       
   506 		    
       
   507 		    TInetAddr StartIp;
       
   508 			TInetAddr EndIp;	
       
   509 			StartIp.SetAddress(KInetAddrNone);    // 0.0.0.0
       
   510 			StartIp.SetPort(0);
       
   511 			EndIp.SetAddress(KInetAddrAll);	      // 255.255.255.255
       
   512 			EndIp.SetPort(0xffff);
       
   513 			
       
   514 			TIkeV2TrafficSelector ts(StartIp, EndIp, 
       
   515                                      aPfkeyMsg.iDstAddr.iExt->sadb_address_proto);
       
   516 			TsI->AppendL(ts);			
       
   517 			CleanupStack::Pop(TsI);
       
   518 			Acquire->ReplaceTS_i(TsI);						
       
   519 			Acquire->SetVirtualIp();						     						
       
   520 		    }
       
   521 		
       
   522 		if ( InitPkiServiceL() )
       
   523 		    {
       
   524 		    // Store Acquire to wait PKI service init
       
   525 			iChildSaRequest = Acquire;
       
   526 			CleanupStack::Pop(Acquire); 			 							
       
   527 			return;
       
   528 		    }
       
   529 		CleanupStack::Pop(Acquire);	
       
   530 	    }
       
   531 	CIkev2Acquire::Link(Acquire, GetAcquireQue());
       
   532 	GetIpsecSPI(Acquire);
       
   533     }
       
   534 
       
   535 
       
   536 void CIkev2Negotiation::ProcessExpireL(const TPfkeyMessage &aPfkeyMsg)
       
   537     {
       
   538 	//
       
   539 	// Process received PFKEY Expire primitive
       
   540 	// Try to find first IPSEC SA data from the "parent" IKE SA and set
       
   541 	// inbound SA to zero in TIpsecSAData 
       
   542 	//
       
   543     TPtrC8 spi(reinterpret_cast<const TUint8*>(&aPfkeyMsg.iSa.iExt->sadb_sa_spi),
       
   544                sizeof(aPfkeyMsg.iSa.iExt->sadb_sa_spi));    
       
   545     
       
   546 	TIkeV2IpsecSAData* SaData = 
       
   547                 iIkeV2PlugInSession.FindIpsecSAData(iHdr.SaId(), spi, ETrue);
       
   548 	if ( !SaData )
       
   549 	    {
       
   550 	    DEBUG_LOG(_L("PFKEY Expire received but no SA data found, stop negotiation"));    	
       
   551 
       
   552 	    iStopped = ETrue;	
       
   553 	    return;	
       
   554 	    }	
       
   555 	SaData->iSPI_In.Zero();	
       
   556 	CIkev2Expire* Expire = CIkev2Expire::NewL(aPfkeyMsg);	
       
   557 	CIkev2Expire::Link(Expire, GetExpireQue());
       
   558 	
       
   559 	ContinueIkeNegotiationL();
       
   560 }
       
   561 
       
   562 void CIkev2Negotiation::StartIpsecSaRekeyingL(const TPfkeyMessage &aPfkeyMsg)
       
   563 {
       
   564 
       
   565     TPtrC8 spi(reinterpret_cast<const TUint8*>(&aPfkeyMsg.iSa.iExt->sadb_sa_spi),
       
   566                sizeof(aPfkeyMsg.iSa.iExt->sadb_sa_spi));    
       
   567     TIkeV2IpsecSAData* SaData = 
       
   568                 iIkeV2PlugInSession.FindIpsecSAData(iHdr.SaId(), spi, ETrue);
       
   569 	if ( !SaData )
       
   570 	{
       
   571 	    DEBUG_LOG(_L("No IPSec SA data found, stop rekeying"));    	
       
   572 	    iStopped = ETrue;	
       
   573 	    return;	
       
   574     }
       
   575 
       
   576 	iStopped = ETrue;  
       
   577     
       
   578     CArrayFix<TIkeV2TrafficSelector>* tsIArray = SaData->iRekeyData->TsIL();
       
   579     CleanupStack::PushL(tsIArray);
       
   580 
       
   581     CArrayFix<TIkeV2TrafficSelector>* tsRArray = SaData->iRekeyData->TsRL();
       
   582     CleanupStack::PushL(tsRArray);
       
   583     
       
   584     __ASSERT_DEBUG(tsIArray->Count() > 0, User::Invariant());
       
   585     __ASSERT_DEBUG(tsRArray->Count() > 0, User::Invariant());
       
   586 
       
   587     TIkeV2TrafficSelector tsI = (*tsIArray)[0];
       
   588     TIkeV2TrafficSelector tsR = (*tsRArray)[0];
       
   589 
       
   590     CleanupStack::PopAndDestroy(tsRArray);
       
   591     CleanupStack::PopAndDestroy(tsIArray);
       
   592     
       
   593     
       
   594     TInetAddr localSelector;
       
   595     TInetAddr localSelectorMask;
       
   596     
       
   597     TInetAddr remoteSelector;
       
   598     TInetAddr remoteSelectorMask;
       
   599 
       
   600     if (iHdr.iInitiator)
       
   601         {
       
   602         localSelector = tsI.StartingAddress();
       
   603         localSelectorMask = tsI.Mask();
       
   604         
       
   605         remoteSelector = tsR.StartingAddress();
       
   606         remoteSelectorMask = tsR.Mask(); 
       
   607         }
       
   608     else
       
   609         {
       
   610         localSelector = tsR.StartingAddress();
       
   611         localSelectorMask = tsR.Mask();
       
   612         
       
   613         remoteSelector = tsI.StartingAddress();
       
   614         remoteSelectorMask = tsI.Mask();        
       
   615         }
       
   616     
       
   617     CIpsecSaSpecList* SaList = iIkeV2PlugInSession.GetIPsecSaSpecListL(localSelector, localSelectorMask, //local address/port info
       
   618                                                                        remoteSelector, remoteSelectorMask,
       
   619                                                                        aPfkeyMsg.iDstAddr.iExt->sadb_address_proto);
       
   620 
       
   621     
       
   622     CleanupStack::PushL(SaList);
       
   623     __ASSERT_DEBUG(SaList != NULL, User::Invariant());
       
   624     __ASSERT_DEBUG(SaList->Count() > 0, User::Invariant());
       
   625     iStopped = EFalse;  
       
   626     
       
   627     const TIpsecSaSpec& saSpec = SaList->At(0);
       
   628 	    
       
   629 	CIkev2Acquire* Acquire = CIkev2Acquire::NewL(aPfkeyMsg, iIkeV2PlugInSession.GetSAId(), GetLocalAddr(),
       
   630 									   Ikev2Proposal::GetDHGroup(iHdr.iIkeData->iGroupDesc_II), ImplicitChildSa(), 
       
   631 									   &saSpec, SaData->iRekeyData);	
       
   632 	CleanupStack::PopAndDestroy(SaList); //SaList
       
   633 	
       
   634 	Acquire->SetSPI_ToBeRekeyed(spi);
       
   635 
       
   636 	if ( iState == KStateIdle )
       
   637 	{
       
   638 		CleanupStack::PushL(Acquire);				 								
       
   639 		LoadEapPluginL();		
       
   640 		iHdr.iInitiator = ETrue;
       
   641 		GetNonceDataL(ETrue);  // For IKE SA		
       
   642 		if ( iHdr.iIkeData->iUseInternalAddr )
       
   643 		{			
       
   644 			CArrayFix<TIkeV2TrafficSelector>* TsI = new (ELeave) CArrayFixFlat<TIkeV2TrafficSelector>(1);
       
   645 			CleanupStack::PushL(TsI);
       
   646 
       
   647 			TInetAddr StartIp;
       
   648             TInetAddr EndIp;    
       
   649             StartIp.SetAddress(KInetAddrNone);    // 0.0.0.0
       
   650             StartIp.SetPort(0);
       
   651             EndIp.SetAddress(KInetAddrAll);       // 255.255.255.255
       
   652             EndIp.SetPort(0xffff);
       
   653 			
       
   654             TIkeV2TrafficSelector ts(StartIp, EndIp, 
       
   655                                      aPfkeyMsg.iDstAddr.iExt->sadb_address_proto);
       
   656             TsI->AppendL(ts);
       
   657 			Acquire->ReplaceTS_i(TsI);			
       
   658 			CleanupStack::Pop(TsI);
       
   659 			Acquire->SetVirtualIp();
       
   660         }
       
   661 
       
   662 		if ( InitPkiServiceL() )
       
   663 		{
       
   664 			iChildSaRequest = Acquire;  // Store Acquire to wait PKI service init
       
   665 			CleanupStack::Pop(Acquire); 			 							
       
   666 			return;
       
   667 		}
       
   668 		CleanupStack::Pop(Acquire); 	
       
   669 	}
       
   670 	CIkev2Acquire::Link(Acquire, GetAcquireQue());
       
   671 	GetIpsecSPI(Acquire);
       
   672 }
       
   673 
       
   674 void CIkev2Negotiation::GetIpsecSPI(CIkev2Acquire* aAcquire)
       
   675     {
       
   676     ASSERT(aAcquire);
       
   677 	//
       
   678 	// Get SPI for inbound SA with PFKEY GETSPI primitive
       
   679 	//
       
   680 	TInetAddr DstAddr;
       
   681 	if ( aAcquire->SrcSpecific() )
       
   682 		 DstAddr = iHdr.iLocalAddr;
       
   683 	else DstAddr.Init(0); 
       
   684 	DstAddr.SetPort(0);	
       
   685 	TInetAddr SrcAddr = iHdr.iRemoteAddr;
       
   686 	SrcAddr.SetPort(0);
       
   687 
       
   688 	iSpiRetriever->GetIpsecSaSpi(aAcquire->Id(),
       
   689                                  aAcquire->IpsecProtocol(),
       
   690                                  SrcAddr, DstAddr);
       
   691     }
       
   692 
       
   693 
       
   694 void CIkev2Negotiation::IpsecSaSpiRetrieved(TUint32 aSpiRequestId, 
       
   695                                             TInt aStatus, 
       
   696                                             TUint32 aSpi)
       
   697     {
       
   698     if (aStatus == KErrNone)
       
   699         {
       
   700         TRAP(aStatus, IpsecSaSpiRetrievedL(aSpiRequestId, aSpi));
       
   701         }
       
   702     
       
   703     if (aStatus != KErrNone)
       
   704         {
       
   705         //Leave that we have not been able to handle
       
   706         //above layers. We bail out and report error.
       
   707         iIkeV2PlugInSession.DeleteIkev2SA(iHdr.SaId());                         
       
   708         iIkeV2PlugInSession.IkeSaDeleted(aStatus); 
       
   709         delete this;
       
   710         }
       
   711     }
       
   712 
       
   713 void CIkev2Negotiation::CancelOperation()
       
   714     {
       
   715     if ( iTimer != NULL )
       
   716         {
       
   717         iTimer->Cancel();
       
   718         }
       
   719     if ( iSpiRetriever != NULL )
       
   720         {
       
   721         iSpiRetriever->Cancel();
       
   722         }
       
   723     }
       
   724 
       
   725 void CIkev2Negotiation::IpsecSaSpiRetrievedL(TUint32 aSpiRequestId, TUint32 aSpi)
       
   726     {
       
   727     DEBUG_LOG(_L("CIkev2Negotiation::SpiRetrievedL"));
       
   728     
       
   729 	//
       
   730 	// Ipsec SPI received. Find an Acquire object for received SPI and
       
   731 	// save SPI into found object.
       
   732 	//
       
   733 	CIkev2Acquire* Acquire = CIkev2Acquire::Find(aSpiRequestId, GetAcquireQue());
       
   734 	__ASSERT_DEBUG(Acquire, User::Invariant());
       
   735 
       
   736 	TPtrC8 spiPtr(reinterpret_cast<TUint8*>(&aSpi), sizeof(aSpi));
       
   737 	Acquire->SetSPI_In(spiPtr);
       
   738 	//
       
   739 	// Ipsec SPI received. Find an Acquire object for received SPI and
       
   740 	// save SPI into found object.
       
   741 	//	
       
   742     ContinueIkeNegotiationL();
       
   743     }
       
   744 
       
   745 void CIkev2Negotiation::ContinueIkeNegotiationL()
       
   746 {
       
   747 	//
       
   748 	// This method takes actions according to current state (iState) of
       
   749 	// the negotiation.     
       
   750 	//
       
   751 	CIkev2Acquire* Acquire;
       
   752 	CIkev2Expire*  Expire;
       
   753 
       
   754 	switch ( iState )
       
   755 	{
       
   756     case KStateIdle:
       
   757          //
       
   758          // Start IKE_SA_INIT exchange
       
   759          //
       
   760          StartIkeSaInitL();			 
       
   761          break;
       
   762 
       
   763     case KStateIkeSaAuthWaitSpi:
       
   764          {			    			 
       
   765          //
       
   766          // Complete IKE_AUTH exchange (with concatenated Child SA)
       
   767          //
       
   768          iChildSaRequest = CIkev2Acquire::GetNext(GetAcquireQue(), ETrue);
       
   769                      
       
   770          DEBUG_LOG(_L("CIkev2Negotiation::ContinueIkeNegotiationL"));
       
   771          DEBUG_LOG1(_L("iChildSaRequest is %d"), (TInt)iChildSaRequest);
       
   772          
       
   773          SendIkeAuthMessageL();			 
       
   774          }
       
   775          break;
       
   776          
       
   777     case KStateIkeSaCompleted:
       
   778          //
       
   779          // There is no activity going on this negotiation
       
   780          // If there is something in request queues start process
       
   781          // them in the following order:
       
   782          // -- Check if there is something in info queue (NIY)
       
   783          // -- Check if there is something in expire queue (NIY)
       
   784          // -- Check if there is ready responses in acquire queue
       
   785          // -- Check if there is ready request in acquire queue			 
       
   786          //
       
   787          Expire = CIkev2Expire::GetNext(GetExpireQue());
       
   788          if ( Expire )
       
   789          {
       
   790             CleanupStack::PushL(Expire);				 
       
   791             BuildDeleteRequestL(Expire);
       
   792             CleanupStack::PopAndDestroy(Expire);								
       
   793          }	
       
   794          else 
       
   795          {
       
   796             Acquire = CIkev2Acquire::GetNext(GetAcquireQue(), ETrue);
       
   797             if  ( Acquire )
       
   798             {
       
   799                 BuildChildSAMessageL(Acquire, EFalse);
       
   800             }
       
   801             else
       
   802             {
       
   803                 Acquire = CIkev2Acquire::GetNext(GetAcquireQue(), EFalse);				 
       
   804                 BuildChildSAMessageL(Acquire, ETrue);
       
   805             }
       
   806          }
       
   807          break;
       
   808     
       
   809     default:
       
   810          break;
       
   811 	}		
       
   812 }	
       
   813 
       
   814 void CIkev2Negotiation::StartIkeSaInitL()
       
   815     {
       
   816 	//
       
   817 	// Create Initiator SPI for the new IKE SA
       
   818 	//
       
   819 	CreateIkeSPI(iHdr.SpiI());
       
   820 
       
   821 	//
       
   822 	// Get required peer identity from policy (IDr)
       
   823 	//
       
   824 	iRemoteIdentity = Ikev2Proposal::GetRemoteIdentityL(iHdr.iIkeData);
       
   825 	
       
   826 	__ASSERT_ALWAYS(iHdr.iInitiator, User::Invariant());
       
   827 	//
       
   828 	// Build and send the first IKE_SA_INIT message (request)
       
   829 	// HDR, SAi1, KEi, Ni, N[NAT_SRC], N[NAT_DST]
       
   830 	//
       
   831 	CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(),
       
   832                                                 iHdr.SpiR(),
       
   833                                                 IKE_SA_INIT,
       
   834                                                 iHdr.iInitiator,
       
   835                                                 EFalse,
       
   836                                                 iHdr.NextRequestId(),
       
   837                                                 iDebug); 
       
   838 	CleanupStack::PushL(ikeMsg);
       
   839 	
       
   840     HBufC8* saBfr = Ikev2Proposal::FromPolicyToProposaL(iHdr, iSPI_Rekey, iDHGroupGuess);
       
   841     CleanupStack::PushL(saBfr);
       
   842 	ikeMsg->AppendSaPayloadL(*saBfr);
       
   843 	CleanupStack::Pop(saBfr);
       
   844 	SetProposedSa(saBfr);
       
   845 
       
   846     AppendKEPayloadL(*ikeMsg, iHdr.iDHGroup);
       
   847     ikeMsg->AppendNoncePayloadL(*iNonce_I);
       
   848 	if ( !iHdr.iIkeData->iUseNatProbing )
       
   849 	    {
       
   850 	    delete iNatNotify;
       
   851 	    iNatNotify = NULL;
       
   852 	    
       
   853 	    TInetAddr LocalIp;	
       
   854 	    if ( iHdr.iIkeData->iUseMobIke )
       
   855 		    LocalIp.SetAddress(KInetAddrNone);
       
   856 	    else LocalIp = iHdr.iLocalAddr; 	   
       
   857 	    iNatNotify = CIkev2NatT::NewL(
       
   858 	        LocalIp, iHdr.iRemoteAddr, IKE_PORT, ikeMsg->InitiatorSpi(), ikeMsg->ResponderSpi());
       
   859 	    	    	   
       
   860 	    ikeMsg->AppendNotifyPayloadL(IKEV2_PROTOCOL, KZeroDesc, NAT_DETECTION_SOURCE_IP, 
       
   861                                      iNatNotify->SourceNofify());
       
   862 	    ikeMsg->AppendNotifyPayloadL(IKEV2_PROTOCOL, KZeroDesc, NAT_DETECTION_DESTINATION_IP, 
       
   863                                      iNatNotify->DestinNofify());		  
       
   864 	    }	
       
   865 	CleanupStack::Pop(ikeMsg);
       
   866 	
       
   867 	SendIkeMsgL(ikeMsg);	
       
   868     iState = KStateIkeSaInitRequest;
       
   869     }
       
   870 
       
   871 void CIkev2Negotiation::SendIkeAuthMessageL()
       
   872 {
       
   873 	//
       
   874 	// Build and send IKE_AUTH message
       
   875 	// IKE_AUTH message sent by the initiator is the following:
       
   876 	//  HDR(A,B), SK {IDi, [CERT] [CERTREQ], [IDr], [AUTH], [CP], [SAi2,
       
   877 	//  TSi, TSr]} 
       
   878 	// IKE_AUTH message sent by the responder is the following:
       
   879 	//  HDR(A,B), SK {IDr, [CERT,] AUTH, [CP], [SAr2, TSi, TSr]}
       
   880 	// CERT and CERTREQ payloads are added into message on when needed.
       
   881 	// AUTH payload is missing from initiators message when EAP in use.
       
   882 	// IPSEC SA:s are not always negotiated within IKE_AUTH messages.
       
   883 	// In this sitution SAx2, TSi and TSr payloads shall be missing.
       
   884 	// CP payload is used the Virtual IP address (secure network DNS
       
   885 	// IP:s) for client Virtual IP interface.
       
   886 	// Initiators CP payload shall contain CFG_REQUEST and and
       
   887 	// responders CP payload CFG_REPLY.
       
   888 	// When CP payload is used IKE_AUTH message MUST always contain
       
   889 	// IPSEC SA negotiation payloads within. 
       
   890 	// In case INITIAL_CONTACT is used, the first IKE_AUTH request on given 
       
   891 	// IKE SA contains INITIAL_CONTACT Notification Payload that is added in
       
   892 	// the end of the IKE_AUTH message.
       
   893 	//
       
   894 
       
   895 	if ( !iLocalIdentity )
       
   896 	{
       
   897 	   //
       
   898 	   // Own identity does not exists yet. Do not build IKE_AUTH
       
   899 	   // message now
       
   900 	   //
       
   901 	   iState = KStateIkeWaitingId;
       
   902 	   return;
       
   903 	}
       
   904 	
       
   905 	TUint32 MsgId = (iHdr.iInitiator) ? iHdr.NextRequestId() : iHdr.ExpectedRequestId();	
       
   906     CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(),
       
   907                                                 iHdr.SpiR(),
       
   908                                                 IKE_AUTH,
       
   909                                                 iHdr.iInitiator,
       
   910                                                 !iHdr.iInitiator, //Initiator sends only requests
       
   911                                                 MsgId,
       
   912                                                 iDebug); 
       
   913     CleanupStack::PushL(ikeMsg);
       
   914 	
       
   915     ikeMsg->AppendEncryptedPayloadL(iHdr.iCipherBlkLth);
       
   916 
       
   917     __ASSERT_DEBUG(iLocalIdentity != NULL, User::Invariant());
       
   918     if (iHdr.iInitiator)
       
   919         {
       
   920         ikeMsg->AppendIdiPayloadL(*iLocalIdentity);
       
   921         }
       
   922     else
       
   923         {        
       
   924         ikeMsg->AppendIdrPayloadL(*iLocalIdentity);
       
   925         }
       
   926 
       
   927 	if ( iPkiService &&
       
   928 	     iPkiService->UserCertificateData().Length() > 0)
       
   929 	    {        
       
   930         ikeMsg->AppendCertPayloadL(iPkiService->UserCertificateData());
       
   931         }
       
   932 	
       
   933 	if ( iPkiService &&
       
   934 	     iPkiService->I2CertificateData().Length() > 0)
       
   935 	    {
       
   936 	    ikeMsg->AppendCertPayloadL(iPkiService->I2CertificateData());
       
   937 	    }
       
   938 	
       
   939 	if ( iPkiService &&
       
   940 	     iPkiService->I1CertificateData().Length() > 0)
       
   941 	    {
       
   942 	    ikeMsg->AppendCertPayloadL(iPkiService->I1CertificateData());
       
   943 	    }
       
   944 	  
       
   945 	if ( iHdr.iInitiator && iHdr.iIkeData->iInitialContact )
       
   946         {
       
   947         ikeMsg->AppendNotifyPayloadL(IKEV2_PROT_NONE, KZeroDesc, INITIAL_CONTACT, KZeroDesc);
       
   948         }
       
   949 
       
   950 
       
   951     if ( iHdr.iInitiator && iPkiService != NULL &&  iPkiService->CaList().Count() > 0)  
       
   952        {	    
       
   953        ikeMsg->AppendCertReqPayloadL(iPkiService->CaList());
       
   954        }
       
   955 
       
   956 	if ( iHdr.iInitiator && iRemoteIdentity )
       
   957 	    {
       
   958 	    //
       
   959 	    // Add IDr payload 
       
   960 	    //
       
   961 	    ikeMsg->AppendIdrPayloadL(*iRemoteIdentity);
       
   962 	    }	
       
   963     if ( !iEapPlugin )
       
   964 	    {	 
       
   965         HBufC8* authData = NULL; 
       
   966 	    if ( iHdr.iInitiator )
       
   967 	        {
       
   968 	        authData = SignAuthDataL(*iAuthMsgInit, (TUint8)iHdr.iAuthMethod);
       
   969 	        }
       
   970 	    else 
       
   971 	        {
       
   972 	        authData = SignAuthDataL(*iAuthMsgResp, (TUint8)iHdr.iAuthMethod);
       
   973 	        }
       
   974 	    CleanupStack::PushL(authData);
       
   975 	    ikeMsg->AppendAuthPayloadL(iHdr.iAuthMethod, *authData);	   
       
   976 	    CleanupStack::PopAndDestroy(authData);
       
   977 	    }
       
   978 	if ( iHdr.iIkeData->iUseMobIke )
       
   979 	    {
       
   980 	    //
       
   981 	    // Add MOBIKE_SUPPORTED notify payload
       
   982 	    //
       
   983 	    ikeMsg->AppendNotifyPayloadL(IKEV2_PROT_NONE,
       
   984                                      KZeroDesc,
       
   985                                      MOBIKE_SUPPORTED,
       
   986                                      KZeroDesc);
       
   987 	    }	
       
   988 
       
   989 
       
   990 	//
       
   991 	// Add Child SA and Traffic selector payloads into IKE_AUTH message
       
   992 	// if required
       
   993 	//
       
   994 	if ( iChildSaRequest )
       
   995 	{
       
   996 		iChild.iSPI_In = iChildSaRequest->SPI_In();
       
   997 		iChildSaRequest->AddIpsecSpiToSa(iChild.iSPI_In);
       
   998 		if ( iChildSaRequest->ForVirtualIp() )
       
   999 		    {
       
  1000 		    //
       
  1001 		    // As Virtual Ip from peer SGW using Config Payload
       
  1002 		    // Build CP request data by constructing CIkev2Config Object
       
  1003 		    //
       
  1004 		    if ( !iConfigMode )
       
  1005 		        iConfigMode = CIkev2Config::NewL(iChildSaRequest);
       
  1006 
       
  1007             ikeMsg->AppendConfigurationPayloadL(iConfigMode->CpType(), iConfigMode->Cp());
       
  1008 		    }	
       
  1009 		ikeMsg->AppendSaPayloadL(*iChildSaRequest->SA());
       
  1010 	 
       
  1011 		ikeMsg->AppendTsiPayloadL(iChildSaRequest->TS_i());
       
  1012 		ikeMsg->AppendTsrPayloadL(iChildSaRequest->TS_r());
       
  1013 	}
       
  1014 	
       
  1015 	CleanupStack::Pop(ikeMsg);
       
  1016 	SendIkeMsgL(ikeMsg);
       
  1017 	
       
  1018 	if ( iHdr.iInitiator )
       
  1019 	{	
       
  1020 	   if ( iEapPlugin )
       
  1021 	        iState = KStateIkeSaEapStarted;			   
       
  1022 	   else iState = KStateIkeSaAuthRequest;	
       
  1023 	}
       
  1024 	else 
       
  1025 	{    
       
  1026        iState = KStateIkeSaCompleted;
       
  1027        IkeSaCompletedL();
       
  1028 	}
       
  1029 
       
  1030 }
       
  1031 
       
  1032 void CIkev2Negotiation::SendKeepAliveMsgL()
       
  1033     {
       
  1034     CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(), 
       
  1035                                                 iHdr.SpiR(), 
       
  1036                                                 INFORMATIONAL, 
       
  1037                                                 iHdr.iInitiator,
       
  1038                                                 EFalse,
       
  1039                                                 iHdr.NextRequestId(), 
       
  1040                                                 iDebug);
       
  1041     
       
  1042     ikeMsg->AppendEncryptedPayloadL(iHdr.iCipherBlkLth);            
       
  1043     SendIkeMsgL(ikeMsg);
       
  1044     iState = KStateIkeInfoRequest;
       
  1045     
       
  1046 	DEBUG_LOG(_L("CIkev2Negotiation::SendKeepAliveMsgL"));
       
  1047     }
       
  1048 
       
  1049 
       
  1050 void CIkev2Negotiation::BuildChildSAMessageL(
       
  1051     CIkev2Acquire* aAcquire, TBool aInitiator)
       
  1052     {
       
  1053     ASSERT(aAcquire);
       
  1054 	//
       
  1055 	// Build and send CREATE_CHILD_SA message
       
  1056 	// CREATE_CHILD_SA request message sent is the following:
       
  1057 	//  HDR(A,B), SK {[N], SA, Ni, [KEi], [TSi, TSr]}
       
  1058 	// CREATE_CHILD_SA response message is the following:
       
  1059 	//  HDR(A,B), SK {SA, Nr, [KEi], [TSi, TSr]}
       
  1060 	//
       
  1061 	iChild.iSPI_In  = aAcquire->SPI_In();	
       
  1062 	iChildSaRequest = aAcquire;
       
  1063 	//TPayloadIkev2* PreviousPayload;
       
  1064 	//TPayloadIkev2* EncrPayload;
       
  1065 	GetNonceDataL(aInitiator);
       
  1066 	aAcquire->AddIpsecSpiToSa(aAcquire->SPI_In());
       
  1067 		
       
  1068 	TUint32 MsgId = (aInitiator) ? iHdr.NextRequestId() : iHdr.ExpectedRequestId();
       
  1069 	
       
  1070 	CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(),
       
  1071                                                 iHdr.SpiR(),
       
  1072                                                 CREATE_CHILD_SA,
       
  1073                                                 iHdr.iInitiator,
       
  1074                                                 !aInitiator,
       
  1075                                                 MsgId,
       
  1076                                                 iDebug);
       
  1077 	
       
  1078     ikeMsg->AppendEncryptedPayloadL(iHdr.iCipherBlkLth);            
       
  1079 	
       
  1080 	if (aInitiator && aAcquire->SPI_ToBeRekeyed().Length() > 0)
       
  1081         {         
       
  1082         ikeMsg->AppendNotifyPayloadL(aAcquire->IpsecProtocol(),
       
  1083                                      aAcquire->SPI_ToBeRekeyed(),
       
  1084                                      REKEY_SA, KZeroDesc);        
       
  1085         }
       
  1086 	ikeMsg->AppendSaPayloadL(*aAcquire->SA());
       
  1087 	
       
  1088 	if ( aInitiator )
       
  1089 	    {
       
  1090 	    ikeMsg->AppendNoncePayloadL(*iNonce_I);
       
  1091 	    }
       
  1092 	else 
       
  1093 	    {
       
  1094 	    ikeMsg->AppendNoncePayloadL(*iNonce_R);	
       
  1095 	    }
       
  1096 	
       
  1097 	delete iDHKeys;   // Delete old DH object 
       
  1098 	iDHKeys = NULL;
       
  1099 	if ( aAcquire->DHGroup() )
       
  1100 	    {	    
       
  1101 	    AppendKEPayloadL(*ikeMsg, aAcquire->DHGroup());
       
  1102 	    }
       
  1103 	ikeMsg->AppendTsiPayloadL(aAcquire->TS_i());
       
  1104 	ikeMsg->AppendTsrPayloadL(aAcquire->TS_r());
       
  1105 	      
       
  1106 	SendIkeMsgL(ikeMsg);
       
  1107 
       
  1108 	if ( aInitiator	)
       
  1109 	{	
       
  1110 	   iState = KStateIkeChildSARequest;	   
       
  1111     }
       
  1112 	else
       
  1113 	{
       
  1114         if (iDHKeys && iDHPublicPeer)
       
  1115             {
       
  1116             HBufC8* g_ir = iDHKeys->ComputeAgreedKeyL(iDHPublicPeer->Des());
       
  1117             CleanupStack::PushL(g_ir);
       
  1118         
       
  1119             iChild.GenerateIpsecKeysL(iHdr.iSK_d, *g_ir, 
       
  1120                                       *iNonce_I, *iNonce_R, iHdr.iPRFAlg);
       
  1121                 
       
  1122             g_ir->Des().FillZ(); // Wipe out shared secret value from buffer
       
  1123             CleanupStack::PopAndDestroy();  //g_ir
       
  1124             }
       
  1125         else
       
  1126             {
       
  1127             iChild.GenerateIpsecKeysL(iHdr.iSK_d, KZeroDesc, 
       
  1128                                       *iNonce_I, *iNonce_R, iHdr.iPRFAlg);            
       
  1129             }
       
  1130         
       
  1131 	   IpsecSANegotiatedL();
       
  1132 	   iState = KStateIkeChildSAResponse;
       
  1133 	}	
       
  1134 }
       
  1135 
       
  1136 void CIkev2Negotiation::BuildDeleteRequestL(CIkev2Expire* aExpire)
       
  1137 {
       
  1138 	//
       
  1139 	//  Build and send INFORMATIONAL exchange message with delete payload
       
  1140 	//  HDR(A,B), SK {D}
       
  1141 	//  If CIkev2Expire object defined, build a Delete payload with Ipsec
       
  1142 	//  SPI and protocl stored into CIkev2Expire object. If no CIkev2Expire build
       
  1143 	//  Delete payload for IKE SA.
       
  1144 	//    
       
  1145     CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(), 
       
  1146                                                 iHdr.SpiR(), 
       
  1147                                                 INFORMATIONAL, 
       
  1148                                                 iHdr.iInitiator,
       
  1149                                                 EFalse,
       
  1150                                                 iHdr.NextRequestId(), 
       
  1151                                                 iDebug);
       
  1152     
       
  1153     ikeMsg->AppendEncryptedPayloadL(iHdr.iCipherBlkLth);            
       
  1154 
       
  1155     CDesC8Array* spiArray = new (ELeave) CDesC8ArrayFlat(2);
       
  1156     CleanupStack::PushL(spiArray);
       
  1157 	if ( aExpire )
       
  1158 	    {	    	    
       
  1159 	    spiArray->AppendL(aExpire->SPI());
       
  1160 	    ikeMsg->AppendDeletePayloadL(aExpire->Protocol(), *spiArray);	    	        
       
  1161 	    }
       
  1162 	else
       
  1163 	    {	    
       
  1164 	    ikeMsg->AppendDeletePayloadL(IKEV2_PROTOCOL, *spiArray);
       
  1165 	    }
       
  1166 	CleanupStack::PopAndDestroy(spiArray);
       
  1167 	
       
  1168 	SendIkeMsgL(ikeMsg);
       
  1169     DEBUG_LOG(_L("CIkev2Negotiation::BuildDeleteRequestL() Delete send OK"));
       
  1170     
       
  1171     if ( aExpire ) 
       
  1172         {
       
  1173         iState = KStateChildDeleteRequest;
       
  1174         }
       
  1175     else 
       
  1176         {
       
  1177         iState = KStateIkeDeleteRequest;
       
  1178         }
       
  1179 }
       
  1180 
       
  1181 void CIkev2Negotiation::BuildIkeSaRekeyMsgL(TBool aRequest)
       
  1182 {
       
  1183 	//
       
  1184 	//  Build and send CHILD_SA exchange message which contains IKE SA
       
  1185 	//  rekey message (either request or response)
       
  1186 	//  HDR, SA, Nonce, KE	
       
  1187 	//
       
  1188 	HBufC8* SaBfr;		
       
  1189 	HBufC8* Nonce;	
       
  1190 	TUint32 MsgId;
       
  1191 	
       
  1192 	if ( aRequest )
       
  1193 	    {
       
  1194 	    // Get a new SA Id for rekeyed IKE SA		   
       
  1195 		iSAid_Rekey = iIkeV2PlugInSession.GetSAId(); 
       
  1196 		CreateIkeSPI(iSPI_Rekey, ETrue);
       
  1197 		SaBfr = Ikev2Proposal::FromPolicyToProposaL(iHdr, iSPI_Rekey, iDHGroupGuess, ETrue);
       
  1198 		SetProposedSa(SaBfr); // Save SA payload buffer
       
  1199 		GetNonceDataL(ETrue);
       
  1200 		Nonce = iNonce_I;
       
  1201 		MsgId = iHdr.NextRequestId();
       
  1202 	    }
       
  1203 	else
       
  1204 	    {
       
  1205 		SaBfr = PeekProposedSa();			
       
  1206 		Ikev2Proposal::ChangeSpiInProposal(SaBfr, iSPI_Rekey);
       
  1207 		GetNonceDataL(EFalse);
       
  1208 		Nonce = iNonce_R;
       
  1209         MsgId = iHdr.ExpectedRequestId();
       
  1210 	    }	
       
  1211 
       
  1212 	CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(), 
       
  1213                                                 iHdr.SpiR(), 
       
  1214                                                 CREATE_CHILD_SA, 
       
  1215                                                 iHdr.iInitiator, 
       
  1216                                                 !aRequest,
       
  1217                                                 MsgId, 
       
  1218                                                 iDebug);
       
  1219 
       
  1220     ikeMsg->AppendEncryptedPayloadL(iHdr.iCipherBlkLth);            
       
  1221     ikeMsg->AppendSaPayloadL(*SaBfr);
       
  1222     ikeMsg->AppendNoncePayloadL(*Nonce);	    
       
  1223     AppendKEPayloadL(*ikeMsg, iHdr.iDHGroup);
       
  1224 	     	
       
  1225 	SendIkeMsgL(ikeMsg);
       
  1226 
       
  1227 	if ( aRequest )
       
  1228 	{	
       
  1229        iState = KStateIkeSARekeyRequest;
       
  1230 	}
       
  1231 }
       
  1232 
       
  1233 void CIkev2Negotiation::CheckNotifyCodeL(CIkev2Payloads* aIkeMsg)
       
  1234     {
       
  1235     ASSERT(aIkeMsg);
       
  1236 	//
       
  1237 	// Some error has occurred during incoming IKE message handling
       
  1238 	// Build an error response with specified Notify message type
       
  1239 	//
       
  1240 	TInt MsgType( GetNotifyCode() );
       
  1241 	
       
  1242 	if ( MsgType )
       
  1243 	    {
       
  1244         //
       
  1245         // Build and error response/request with Notify payload
       
  1246         // If received message with error condition is a request
       
  1247         // Notify payload is transmitted in the response IKE message
       
  1248         // of ongoing exchange (with erronous request message id)
       
  1249         // If received message with error conditions is a response
       
  1250         // an informational exchange is initiated with Notify payload
       
  1251         //
       
  1252 		CIkeV2Message* XmitHdr = NULL;
       
  1253 		TBool Response(aIkeMsg->GetIkeMsg()->GetFlags() & IKEV2_RESPONSE_MSG);		  
       
  1254 		if ( Response )
       
  1255 		    {
       
  1256 		    iState  = KStateIkeInfoRequest;
       
  1257             TUint32 MsgId = aIkeMsg->GetIkeMsg()->GetMessageId();		  
       
  1258 		    XmitHdr = CIkeV2Message::NewL(iHdr.SpiI(), 
       
  1259                                           iHdr.SpiR(),
       
  1260                                           INFORMATIONAL, 
       
  1261                                           iHdr.iInitiator,
       
  1262                                           EFalse,
       
  1263                                           MsgId,
       
  1264                                           iDebug); 
       
  1265 		    		   
       
  1266 		    }
       
  1267 		else
       
  1268 		    {		    
       
  1269             XmitHdr = CIkeV2Message::NewL(iHdr.SpiI(), 
       
  1270                                           iHdr.SpiR(),
       
  1271                                           aIkeMsg->GetIkeMsg()->GetExchange(), 
       
  1272                                           iHdr.iInitiator,
       
  1273                                           ETrue,
       
  1274                                           iHdr.ExpectedRequestId(),
       
  1275                                           iDebug); 
       
  1276 		    }
       
  1277 		
       
  1278 		if (aIkeMsg->Encrypted())
       
  1279 		    {
       
  1280 		    XmitHdr->AppendEncryptedPayloadL(iHdr.iCipherBlkLth);            		    
       
  1281 		    }
       
  1282 		
       
  1283 		TInt notifyDataLength = 0;
       
  1284 		TUint8* notifyData = NotifyData(notifyDataLength);
       
  1285 		
       
  1286 		if (notifyDataLength == 0)
       
  1287 		    {
       
  1288 		    XmitHdr->AppendNotifyPayloadL(IKEV2_PROT_NONE, KZeroDesc, MsgType, KZeroDesc);
       
  1289 		    }
       
  1290 		else
       
  1291 		    {
       
  1292 		    TPtrC8 notifyDataPtrC(notifyData, notifyDataLength);
       
  1293 		    XmitHdr->AppendNotifyPayloadL(IKEV2_PROT_NONE, KZeroDesc, MsgType, notifyDataPtrC);
       
  1294 		    iNotifyDataLth = 0; //Reset notifydata
       
  1295 		    }
       
  1296 		
       
  1297 		SendIkeMsgL(XmitHdr);
       
  1298 		
       
  1299 		iEventLogger.LogEvent(MKmdEventLoggerIf::KLogError, R_VPN_MSG_SENT_ERROR_RESPONSE, 
       
  1300 		    MsgType, iHdr.iVpnIapId, &iHdr.iRemoteAddr);		
       
  1301 	    }	
       
  1302     }
       
  1303 
       
  1304 
       
  1305 void CIkev2Negotiation::GetNatStatus(TBool aSupported, const TInetAddr& aRemote)
       
  1306 {
       
  1307 	//
       
  1308 	// Examine NAT discovery status (from iHdr.iNATFlags) and set
       
  1309 	// floated port usage indicator, if required.
       
  1310 	//
       
  1311 	if ( aSupported )
       
  1312 	{
       
  1313 		if ( iHdr.iNATFlags & (REMOTE_END_NAT + LOCAL_END_NAT) )
       
  1314 		{
       
  1315 			if ( iHdr.iNATFlags & REMOTE_END_NAT )
       
  1316 			{	
       
  1317 			   //
       
  1318 	           // Remote end is behind NAT. Save current source IP to be
       
  1319 	           // used as further destination address. 
       
  1320 			   // When remote and is behind NAT it is supposed that it
       
  1321 			   // must be pure mapping between public- and private IP
       
  1322 			   // addresses (remote NAPT is NOT supported) 
       
  1323 			   // 
       
  1324 			   DEBUG_LOG(_L("Remote end is behind NAT"));
       
  1325 			   iHdr.iDestinAddr = aRemote; // Remote end behind NAT, use current source IP as destin
       
  1326 		    }
       
  1327 			
       
  1328 			if ( iHdr.iNATFlags & LOCAL_END_NAT ) 
       
  1329 			    {
       
  1330 			    DEBUG_LOG(_L("NAT discovery result: Local end is behind NAT"));
       
  1331 			    }
       
  1332 			iHdr.iFloatedPort = ETrue;			
       
  1333 		    iHdr.iDestinAddr.SetPort(FLOATED_IKE_PORT);			
       
  1334 		}
       
  1335 		else
       
  1336 		{
       
  1337 		   if ( iHdr.iMobikeUsed )
       
  1338 		   {
       
  1339 			   iHdr.iFloatedPort = ETrue;			
       
  1340 			   iHdr.iDestinAddr.SetPort(FLOATED_IKE_PORT);			
       
  1341 		   }	   
       
  1342 		   DEBUG_LOG(_L("NAT discovery result: There is no NAT between negotiating ends"));
       
  1343 		}			   
       
  1344 	}
       
  1345 	else
       
  1346     {
       
  1347         DEBUG_LOG(_L("NAT discovery operation failed"));
       
  1348     }		
       
  1349 }
       
  1350 
       
  1351 void CIkev2Negotiation::CreateIkeSPI(TIkeSPI& aSPI, TBool aRekey)
       
  1352 {
       
  1353 	//
       
  1354 	// Create IKE SPI for local end.
       
  1355 	// The SPI value is created from the following "parameters" in
       
  1356 	// IKEv2 negotiation object:
       
  1357 	// - The first 4 octets of SPI value are the SAId (32 bit value)
       
  1358 	// - The last 4 octets of SPI contains "pseudo random" value:
       
  1359 	//   X = (SAId + negotiation object pointer) >> (SAId & 3)
       
  1360 	//
       
  1361 	TUint32 SpiValue1;
       
  1362 	TUint32 SpiValue2;
       
  1363 	if ( aRekey )
       
  1364 		 SpiValue1 = iSAid_Rekey;		
       
  1365 	else SpiValue1 = iHdr.SaId();		
       
  1366 	Mem::Copy((TUint8*)&SpiValue2, (TUint8*)this, 4);
       
  1367 	SpiValue2 = (SpiValue2 + SpiValue1) >> (SpiValue1 & 3);  
       
  1368 	PUT32(aSPI.Ptr(), SpiValue1);	
       
  1369 	PUT32((aSPI.Ptr() + 4), SpiValue2);
       
  1370 	aSPI.SetLength(IKEV2_SPI_SIZE);
       
  1371 }
       
  1372 
       
  1373 void CIkev2Negotiation::LoadEapPluginL()
       
  1374 {
       
  1375 	//
       
  1376 	// If EAP configured in policy, construct EAP interface object to
       
  1377 	// communicate EAP ECOM plug-in
       
  1378 	// If consruction causes an error, stop negotiation request
       
  1379 	//
       
  1380 	iHdr.iEAPType = iHdr.iIkeData->iEAPProtocol;
       
  1381 	if ( !iEapPlugin && iHdr.iEAPType )
       
  1382 	{	
       
  1383 	   iEapPlugin = CIkev2EapIf::NewL(*this, (TUint8)iHdr.iEAPType, iHdr.iIkeData, iDebug);
       
  1384 	   TInt Status = iEapPlugin->Status();
       
  1385 	   if ( Status != KErrNone )
       
  1386 	   {
       
  1387 		  iStopped = ETrue;
       
  1388 	   }
       
  1389 	   else iEapPlugin->QueryIdentity();
       
  1390 	}									  
       
  1391 }
       
  1392 
       
  1393 TBool CIkev2Negotiation::InitPkiServiceL()
       
  1394 {
       
  1395     DEBUG_LOG(_L("-> CIkev2Negotiation::InitPkiServiceL"));
       
  1396 	//
       
  1397 	// If EAP configured in policy, construct EAP interface object to
       
  1398 	// communicate EAP ECOM plug-in
       
  1399 	// If consruction causes an error, return corresponding error code
       
  1400 	// to stop negotiation request
       
  1401 	//
       
  1402 	TBool Status = EFalse;
       
  1403 	if ( !iPkiService && Ikev2Proposal::PkiServiceNeeded(iHdr.iIkeData) )
       
  1404 	{
       
  1405 	   iPkiService = CIkeV2PkiService::NewL(*this, iDebug);
       
  1406 	   
       
  1407 	   if (iHdr.iIkeData->iCAList->Count() == 0)
       
  1408     	   {
       
  1409     	   User::Leave(KVpnErrInvalidCaCertFile);
       
  1410     	   }
       
  1411     	   
       
  1412        iPkiService->InitIkeV2PkiService(iHdr.iIkeData);    	   
       
  1413        iState = KStateIkeInitPkiService;
       
  1414        Status = ETrue;
       
  1415 	}	
       
  1416 
       
  1417     DEBUG_LOG(_L("<- CIkev2Negotiation::InitPkiServiceL"));
       
  1418 	return Status;
       
  1419 }
       
  1420 
       
  1421 
       
  1422 void CIkev2Negotiation::SendIkeMsgL(CIkeV2Message* aMsg)
       
  1423 {
       
  1424     ASSERT(aMsg);
       
  1425     
       
  1426     TPtrC8 encryptionKey;
       
  1427     TPtrC8 integrityKey;
       
  1428     if ( iHdr.iInitiator )
       
  1429     {   
       
  1430         encryptionKey.Set(iHdr.iSK_ei);
       
  1431         integrityKey.Set(iHdr.iSK_ai);
       
  1432     }
       
  1433     else
       
  1434     {
       
  1435         encryptionKey.Set(iHdr.iSK_er);
       
  1436         integrityKey.Set(iHdr.iSK_ar);    
       
  1437     }   
       
  1438 
       
  1439     TInetAddr sourceAddr(iHdr.iLocalAddr);
       
  1440     if (iHdr.iFloatedPort)
       
  1441         {
       
  1442         sourceAddr.SetPort(FLOATED_IKE_PORT);
       
  1443         }
       
  1444     else
       
  1445         {
       
  1446         sourceAddr.SetPort(IKE_PORT);
       
  1447         }
       
  1448     aMsg->PrepareIkeMessageDatagramL(iHdr.iEncrAlg, encryptionKey,
       
  1449                                      iHdr.iIntegAlg, integrityKey, 
       
  1450                                      sourceAddr, iHdr.iDestinAddr);
       
  1451     iMessageSendQue.SendIkeMessageL(aMsg->IkeMessageDatagram(), iHdr.iFloatedPort);     
       
  1452     	
       
  1453 	if (aMsg->Flags() & IKEV2_RESPONSE_MSG )
       
  1454 	{
       
  1455         iHdr.SaveRespMsg(aMsg);
       
  1456         iHdr.iRespRetryCount = 0;
       
  1457 	}
       
  1458 	else
       
  1459 	{
       
  1460         iSendAttempt = 1;
       
  1461         iTimer->Cancel();
       
  1462         iTimer->IssueRequest(iSendAttempt);     // Start retry timer
       
  1463     
       
  1464         iHdr.SaveRequestMsg(aMsg);
       
  1465 	}
       
  1466 }
       
  1467 
       
  1468 void CIkev2Negotiation::RetransmitRequest()
       
  1469     {
       
  1470     TRAPD(err, DoRetransmitL(EFalse));
       
  1471     if ( err != KErrNone )
       
  1472         {
       
  1473         iIkeV2PlugInSession.IkeSaDeleted( err );
       
  1474         }
       
  1475     }
       
  1476 
       
  1477 void CIkev2Negotiation::DoRetransmitL(TBool aResponse)
       
  1478 {	
       
  1479 	if ( aResponse )
       
  1480 	{
       
  1481 		//
       
  1482 		// Peer has retransmitted a request, retransmit last response
       
  1483 		// message saved.  
       
  1484 		//
       
  1485 		if ( iHdr.iLastResponse && (iHdr.iRespRetryCount <= KMaxSendAttemps) )
       
  1486 		{
       
  1487 			iHdr.iRespRetryCount ++;
       
  1488 			//iHdr.iLastResponse = NULL;
       
  1489 			DEBUG_LOG3(_L("IKE response message rexmitted on SAId: %d , Retry: %d  , State: %d"), iHdr.SaId(), iHdr.iRespRetryCount, iState );
       
  1490 
       
  1491 			iMessageSendQue.SendIkeMessageL(iHdr.iLastResponse->IkeMessageDatagram(), 
       
  1492                                             iHdr.iFloatedPort);
       
  1493 		}
       
  1494 		else iStopped = ETrue;
       
  1495 	}	
       
  1496 	else
       
  1497 	{	
       
  1498 	    //
       
  1499 	    // No response received to a transmitted IKE request message
       
  1500 	    // Retransmit message if retry count not exhausted
       
  1501 	    //	
       
  1502 	    DEBUG_LOG(_L("No response received for transmitted IKE request."));
       
  1503 
       
  1504 	    iSendAttempt++;            
       
  1505 	    iMessageSendQue.CancelSend(iHdr.iLastRequest->IkeMessageDatagram());
       
  1506 				
       
  1507 		if ( iSendAttempt <= KMaxSendAttemps )
       
  1508 		{	   		  
       
  1509            DEBUG_LOG3(_L("IKE Message rexmitted on SAId: %d , State: %d , Retry: %d"),iHdr.SaId(), iState, iSendAttempt );		   
       
  1510            iMessageSendQue.SendIkeMessageL(iHdr.iLastRequest->IkeMessageDatagram(), 
       
  1511                                            iHdr.iFloatedPort);
       
  1512 	       iTimer->IssueRequest(iSendAttempt); 	// Restart retry timer
       
  1513 		}
       
  1514 		else
       
  1515 		    {
       
  1516 		    DEBUG_LOG3(_L("Transmit retry count reached on SAId: %d , State: %d , retry: %d"),iHdr.SaId(), iState, iSendAttempt );
       
  1517 		    if ( iState < KStateIkeSaCompleted )
       
  1518 		        {
       
  1519 			    IkeSaFailed(KKmdIkeNegotFailed);  // IKE SA negotiation going 
       
  1520 		        }
       
  1521 		    else
       
  1522 		       {
       
  1523 			   iIkeV2PlugInSession.DeleteIkev2SA(iHdr.SaId());			   			   
       
  1524 			   iIkeV2PlugInSession.IkeSaDeleted(KKmdIkeNoResponseErr);	 //IKE SA deletion going
       
  1525 			   delete this;
       
  1526 		       }	    
       
  1527 		    }	
       
  1528 	    }	
       
  1529     }
       
  1530 
       
  1531 
       
  1532 void CIkev2Negotiation::IkeV2PkiInitCompleteL(TInt aStatus)
       
  1533     {
       
  1534 
       
  1535     DEBUG_LOG(_L("-> CIkev2Negotiation::IkeV2PkiInitCompleteL"));
       
  1536 	//
       
  1537 	// The implementation for class MPkiServiceComplete virtual function
       
  1538 	// This method is called when a PKI service operation is
       
  1539 	// completed.
       
  1540 	//
       
  1541 	
       
  1542 	__ASSERT_ALWAYS( iPkiService != NULL, User::Invariant());            	    
       
  1543     __ASSERT_ALWAYS(iState == KStateIkeInitPkiService, User::Invariant());
       
  1544 
       
  1545     switch(aStatus)
       
  1546         {
       
  1547         case KErrNone:
       
  1548             //
       
  1549             // PKI service object has been constructed
       
  1550             // Start IKE_SA_INIT exchange
       
  1551             //
       
  1552             iState = KStateIdle;
       
  1553             if ( iChildSaRequest )
       
  1554                 {	   
       
  1555                 CIkev2Acquire* Acquire = iChildSaRequest;
       
  1556                 iChildSaRequest = NULL;				   
       
  1557                 CIkev2Acquire::Link(Acquire, GetAcquireQue());
       
  1558                 GetIpsecSPI(Acquire);
       
  1559                 }
       
  1560             else if ( iSavedSaInit )
       
  1561                 {
       
  1562                 TPtr8 IkeMsg(iSavedSaInit->Des());
       
  1563                 const ThdrISAKMP* IkeMessage = ThdrISAKMP::Ptr(IkeMsg);
       
  1564                 ProcessIkeMessageL(*IkeMessage, iHdr.iRemoteAddr, IKE_PORT);
       
  1565                 if ( Stopped() )
       
  1566                    delete this;
       
  1567                 }	   
       
  1568             break;                
       
  1569         case KErrNotFound:       
       
  1570             DEBUG_LOG(_L("IKEv2 CA certificate retrieve failed. Certificate not found"));
       
  1571             IkeSaFailed(KVpnErrInvalidCaCertFile);
       
  1572             break;
       
  1573         default:                
       
  1574             {
       
  1575             DEBUG_LOG1(_L("IKEv2 CA certificate retrieve failed (%d)"), aStatus);
       
  1576             IkeSaFailed(aStatus);
       
  1577             }               		   
       
  1578             break;
       
  1579         }
       
  1580         
       
  1581     DEBUG_LOG(_L("<- CIkev2Negotiation::IkeV2PkiInitCompleteL"));        
       
  1582     }
       
  1583     
       
  1584 
       
  1585 void CIkev2Negotiation::SendEapDataL(HBufC8* aEapData)
       
  1586 {
       
  1587 	//
       
  1588 	// Send an IKE containing an EAP payload (within Encrypted Payload)
       
  1589 	// The entire EAP payload data is provided in aEapData buffer
       
  1590 	//
       
  1591     CleanupStack::PushL(aEapData);
       
  1592 	if ( iState == KStateIkeSaEapGoing )
       
  1593 	{
       
  1594         __ASSERT_DEBUG(iHdr.iInitiator, User::Invariant());
       
  1595 	
       
  1596         CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(), iHdr.SpiR(),
       
  1597                                                     IKE_AUTH, 
       
  1598                                                     iHdr.iInitiator,
       
  1599                                                     EFalse,
       
  1600                                                     iHdr.NextRequestId(), 
       
  1601                                                     iDebug);
       
  1602         CleanupStack::PushL(ikeMsg);               
       
  1603         ikeMsg->AppendEncryptedPayloadL(iHdr.iCipherBlkLth);
       
  1604         ikeMsg->AppendEapPayloadL(*aEapData);
       
  1605         CleanupStack::Pop(ikeMsg);
       
  1606 		SendIkeMsgL(ikeMsg);
       
  1607 	}	
       
  1608 	CleanupStack::PopAndDestroy(aEapData);
       
  1609 }
       
  1610 
       
  1611 void CIkev2Negotiation::EapEventL(TInt aEvent)
       
  1612     {
       
  1613     // See whether the object is accepting any events
       
  1614     // (it is, by default, but will not take events during destruction phase)
       
  1615     if (!iProcessEvents) 
       
  1616     {
       
  1617         return;
       
  1618     }
       
  1619 	//
       
  1620 	// An event idicated by the EAP plugin process event according to
       
  1621 	// event type
       
  1622 	//
       
  1623 	switch ( aEvent )
       
  1624 	    {
       
  1625 		case KEapEventSuccess:
       
  1626 			if ( (iState == KStateIkeSaEapGoing) || (iState == KStateIkeSaEapStarted) )
       
  1627 			    {			    
       
  1628 			    //
       
  1629 			    // EAP auhtentication succeeded.
       
  1630 			    // Build IKE message HDR, SK {AUTH}
       
  1631 			    //
       
  1632 			    __ASSERT_DEBUG( iHdr.iInitiator, User::Invariant());
       
  1633 			    
       
  1634 			    CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(), iHdr.SpiR(),
       
  1635                                                             IKE_AUTH, 
       
  1636                                                             iHdr.iInitiator,
       
  1637                                                             EFalse,
       
  1638                                                             iHdr.NextRequestId(), 
       
  1639                                                             iDebug);
       
  1640 			    CleanupStack::PushL(ikeMsg);               
       
  1641                 ikeMsg->AppendEncryptedPayloadL(iHdr.iCipherBlkLth);
       
  1642 								
       
  1643 		        
       
  1644 		        HBufC8* authData = SignAuthDataL(*iAuthMsgInit, (TUint8)iHdr.iAuthMethod);	           
       
  1645 		        CleanupStack::PushL(authData);
       
  1646 		        ikeMsg->AppendAuthPayloadL(iHdr.iAuthMethod, *authData);       
       
  1647 		        CleanupStack::PopAndDestroy(authData);				
       
  1648 
       
  1649 				CleanupStack::Pop(ikeMsg);
       
  1650 				SendIkeMsgL(ikeMsg);
       
  1651 				iState = KStateIkeSaAuthRequest;
       
  1652 				iEapCompleted = ETrue;				
       
  1653 			    } 
       
  1654 			break;
       
  1655 
       
  1656 		case KEapEventGetIdentity:
       
  1657 			GetOwnIdentityL(ETrue);  // Gets the Identity from EAP plugin			
       
  1658 			if ( iState == KStateIkeWaitingId )
       
  1659 			    {
       
  1660 			    //
       
  1661 			    // Identity data provided by the EAP plug-in
       
  1662 			    // Complete local signed data and send the first
       
  1663 			    // IKE_AUTH message
       
  1664 			    //
       
  1665 			    AddIdToSignedDataL(ETrue, iAuthMsgInit, iLocalIdentity->PayloadData()); 
       
  1666 			    SendIkeAuthMessageL();			    
       
  1667 			    }	
       
  1668 			break;
       
  1669 
       
  1670 		case KEapEventGetPSK:
       
  1671 			if ( iState == KStateIkeSaEapGoing )
       
  1672 			    {
       
  1673 			    //
       
  1674 			    // Preshared key provided by the EAP plug-in
       
  1675 			    // Get key data and link it into negotiation object
       
  1676 			    //
       
  1677 				iPresharedKey = iEapPlugin->MSK();
       
  1678 			    }	
       
  1679 			break;
       
  1680 
       
  1681 		default:  // = KEapEventFailed     
       
  1682 		    //
       
  1683 		    // EAP authentication is failed. Stop negotiation
       
  1684 		    //
       
  1685 		    IkeSaFailed(KKmdIkeAuthFailedErr);  // IKE SA negotiation going 
       
  1686 			break;
       
  1687 	    }	
       
  1688     }
       
  1689 
       
  1690 TBool CIkev2Negotiation::ProcessIkeSaInitL(CIkev2Payloads* aIkeMsg, const TInetAddr& aRemote)
       
  1691 {
       
  1692     ASSERT(aIkeMsg);
       
  1693 	//
       
  1694 	// Process IKE message of exchange type IKE_SA_INIT
       
  1695 	//
       
  1696 	ThdrISAKMP* IkeHdr = aIkeMsg->GetIkeMsg();  // IKE Message fixed header
       
  1697 	TBool   Response   = IkeHdr->GetFlags() & IKEV2_RESPONSE_MSG;
       
  1698 	TBool   Initiator  = IkeHdr->GetFlags() & IKEV2_INITIATOR;
       
  1699 	TUint32 MsgId      = IkeHdr->GetMessageId();
       
  1700 			
       
  1701 	if ( iHdr.iInitiator )
       
  1702 	{
       
  1703 		if ( Initiator ) {
       
  1704 			DEBUG_LOG1(_L("IKEv2 Message with Orig_Init-bit in wrong state: %d"), iState);
       
  1705 			return ETrue;		
       
  1706 		}	
       
  1707 		if ( !Response )
       
  1708 		{
       
  1709 			DEBUG_LOG1(_L("IKEv2 Message is not response; state: %d"), iState);
       
  1710 			return ETrue;		
       
  1711 		}
       
  1712 		if ( MsgId != iHdr.ExpectedResponseId() )
       
  1713 		{
       
  1714 			DEBUG_LOG1(_L("Wrong message id in response; state: %d"), iState);
       
  1715 			return ETrue;		
       
  1716 		}
       
  1717 		
       
  1718 		if (iState == KStateIkeSaInitRequest)
       
  1719 		{
       
  1720             //record responder SPI
       
  1721             aIkeMsg->GetIkeMsg()->GetSPI_R(iHdr.SpiR());			    
       
  1722             
       
  1723             //
       
  1724             // Received message should be a response to a
       
  1725             // IKE_SA_INIT request transmitted.
       
  1726             //
       
  1727             if (IkeHdr->GetPayload() == IKEV2_PAYLOAD_NOTIF)
       
  1728             {
       
  1729                 return ProcessNotifyPayloadsL(*aIkeMsg->iNotifs, EFalse, IKE_SA_INIT);		
       
  1730             }	
       
  1731             //
       
  1732             // Response message should be format:
       
  1733             // HDR(A,B), SAr1, KEr, Nr, [CERTREQ]
       
  1734             //
       
  1735             if ( !CheckPayloadsOrder(aIkeMsg, IKE_SA_INIT, ETrue) )
       
  1736             {
       
  1737                 DEBUG_LOG1(_L("Erroneous IKE_SA_INIT response: %d"), iState);
       
  1738                 return EFalse;
       
  1739             }
       
  1740             if ( !Ikev2Proposal::VerifySaResponseL(iHdr, iChild, *PeekProposedSa(), *aIkeMsg) )
       
  1741             {
       
  1742                 DEBUG_LOG1(_L("Unaccepted SA content in IKE_SA_INIT response: %d"),iState);				    
       
  1743                 return EFalse;
       
  1744             }
       
  1745             if ( aIkeMsg->iNonce->PlDataLen() < IKEV2_MIN_NONCE_SIZE )
       
  1746             {
       
  1747                 DEBUG_LOG1(_L("Nonce data too short %d"), iState);
       
  1748                 return EFalse;
       
  1749             }
       
  1750     
       
  1751             if ( iNatNotify )
       
  1752             {
       
  1753                 TBool Supported;
       
  1754                 TInetAddr LocalIp;	
       
  1755                 if ( iHdr.iIkeData->iUseMobIke )
       
  1756                      LocalIp.SetAddress(KInetAddrNone);
       
  1757                 else LocalIp = iHdr.iLocalAddr; 	   
       
  1758                 
       
  1759 #ifdef _DEBUG
       
  1760                 TBuf<80> debugBuf;
       
  1761                 DEBUG_LOG(_L("Calculating NAT detection:"));
       
  1762                 LocalIp.Output(debugBuf);					
       
  1763                 DEBUG_LOG2(_L("LocalIp %S:%d"), &debugBuf, IKE_PORT);
       
  1764                 iHdr.iRemoteAddr.Output(debugBuf);
       
  1765                 DEBUG_LOG2(_L("RemoteIp %S:%d"), &debugBuf, IKE_PORT);
       
  1766 #endif
       
  1767                 
       
  1768                 iHdr.iNATFlags = CIkev2NatT::CheckPeerNotifysL(*aIkeMsg->iNotifs, LocalIp, iHdr.iRemoteAddr, IKE_PORT,
       
  1769                                                               iHdr.SpiI(), iHdr.SpiR(), Supported);
       
  1770                 GetNatStatus(Supported, aRemote); 
       
  1771             }	
       
  1772     
       
  1773             delete iNonce_R;
       
  1774             iNonce_R = NULL;
       
  1775     
       
  1776             iNonce_R = HBufC8::NewL(aIkeMsg->iNonce->PlDataLen());
       
  1777             iNonce_R->Des().Copy(aIkeMsg->iNonce->PayloadData(), aIkeMsg->iNonce->PlDataLen());				
       
  1778             if ( !ProcessKeyExchangeL((TKEPayloadIkev2*)aIkeMsg->iKe, iHdr.iDHGroup) )
       
  1779             {
       
  1780                return EFalse;
       
  1781             }   
       
  1782     
       
  1783             //
       
  1784             // IKE_SA_INIT request is completed enter IKE_AUTH
       
  1785             //
       
  1786             GenerateIkeKeysL();				
       
  1787             TPtrC8 ikeHdrPtr((TUint8*)IkeHdr, IkeHdr->GetLength());
       
  1788             SaveSignedDataL(EFalse, ikeHdrPtr);  // Save IKE_AUTH message 2
       
  1789             
       
  1790             //We ignore possible cert req payloads and just work
       
  1791             //according our policy
       
  1792             if ( !iHdr.iEAPType &&
       
  1793                  (iHdr.iAuthMethod == RSA_DIGITAL_SIGN || iHdr.iAuthMethod == DSS_DIGITAL_SIGN) )
       
  1794             {                    			
       
  1795                 SaveSignedDataL(ETrue, iHdr.iLastRequest->IkeMessageDatagram()); // Own identity not yet saved to signed data																			
       
  1796     
       
  1797                 GetOwnIdentityL();    // Get own Identity from Certificate (or policy)                    
       
  1798                 AddIdToSignedDataL(ETrue, iAuthMsgInit, iLocalIdentity->PayloadData());    			    
       
  1799             }
       
  1800             else
       
  1801             {
       
  1802                 //
       
  1803                 // Check if "implicit" Child SA exchange required
       
  1804                 // by getting request CIkev2Acquire object from queue
       
  1805                 //
       
  1806                 GetOwnIdentityL();
       
  1807                 SaveSignedDataL(ETrue, iHdr.iLastRequest->IkeMessageDatagram()); // Own identity saved to signed data   				            
       
  1808             }	
       
  1809             iChildSaRequest = CIkev2Acquire::GetNext(GetAcquireQue(), EFalse);				
       
  1810             SendIkeAuthMessageL();
       
  1811 		}
       
  1812 		else
       
  1813 		{
       
  1814             //
       
  1815             // Ignore received message silently
       
  1816             //
       
  1817             DEBUG_LOG1(_L("IKE_SA_INIT response received in state %d"), iState);
       
  1818 		}	
       
  1819 	}
       
  1820 	else {
       
  1821 		if ( !Initiator )
       
  1822 		{
       
  1823 			DEBUG_LOG1(_L("IKEv2 Message without Orig_Init-bit in wrong, state: %d"), iState);
       
  1824 			return ETrue;		
       
  1825 		}	
       
  1826 		if ( Response )
       
  1827 		{
       
  1828 		    DEBUG_LOG1(_L("IKEv2 Message is not request, state: %d"), iState);			
       
  1829 			return ETrue;		
       
  1830 		}
       
  1831 		
       
  1832 		switch ( iState )
       
  1833 		{
       
  1834 			case KStateIdle:
       
  1835 			case KStateIkeSaInitResponse:
       
  1836 			    //Record Initiator SPI
       
  1837 			    aIkeMsg->GetIkeMsg()->GetSPI_I(iHdr.SpiI());
       
  1838 			    iHdr.SpiI().SetLength(IKEV2_SPI_SIZE);
       
  1839 			    
       
  1840 				//
       
  1841 				// Received message should be an IKE_SA_INIT request
       
  1842 				// Request message should be format:
       
  1843 				// HDR(A,0), SAi1, KEi, Ni, [CERTREQ]
       
  1844 				//
       
  1845 			    {
       
  1846 				if ( !CheckPayloadsOrder(aIkeMsg, IKE_SA_INIT, EFalse) )
       
  1847 				{
       
  1848 				    DEBUG_LOG1(_L("Erroneous IKE_SA_INIT request: %d"), iState);
       
  1849 					return EFalse;	
       
  1850 				}
       
  1851 				if ( MsgId != iHdr.ExpectedRequestId() ) {
       
  1852 					if ( iHdr.iLastResponse != NULL && 
       
  1853 					     MsgId == iHdr.iLastResponse->MessageId() && 
       
  1854 					     iState == KStateIkeSaInitResponse )
       
  1855 					{
       
  1856 					   //
       
  1857 					   // Retransmission of an earlier IKE_SA_INIT
       
  1858 					   // request. Retransmit current IKE_SA_INIT
       
  1859 					   // response (if retry count not exhausted)
       
  1860 					   //
       
  1861 					   DoRetransmitL(ETrue);
       
  1862 					   return ETrue;
       
  1863 					}
       
  1864 					else {	
       
  1865 					   DEBUG_LOG1(_L("Wrong message id in request, state: %d"), iState);					   
       
  1866 					   return EFalse;
       
  1867 					}  		   
       
  1868 				}
       
  1869 				if ( iState == KStateIkeSaInitResponse )
       
  1870 				   return EFalse; // IKE_SA_INIT request retry with a new message ID
       
  1871 				iIkeV2PlugInSession.StartResponding();
       
  1872 
       
  1873 				//
       
  1874 				// Build a SA payload from current IKE policy and
       
  1875 				// verify received IKE SA request with it
       
  1876 				//
       
  1877 				HBufC8* SaBfr = Ikev2Proposal::FromPolicyToProposaL(iHdr, iSPI_Rekey, iDHGroupGuess);
       
  1878 				CleanupStack::PushL(SaBfr);
       
  1879 				HBufC8* proposedSa = NULL;
       
  1880 				TBool SaOk = Ikev2Proposal::VerifySaRequestAndGetProposedSaBufferL(iHdr, iChild, 
       
  1881                                                                                    *SaBfr, *aIkeMsg, 
       
  1882                                                                                    proposedSa);
       
  1883 				CleanupStack::PopAndDestroy();				
       
  1884 				if ( !SaOk )
       
  1885 				{
       
  1886 				    DEBUG_LOG1(_L("Unaccepted SA content in IKE_SA_INIT request: %d"),iState);
       
  1887 					SetNotifyCode(NO_PROPOSAL_CHOSEN);
       
  1888 					return EFalse;  							
       
  1889 				}
       
  1890 				SetProposedSa(proposedSa);
       
  1891 				proposedSa = NULL;
       
  1892 				if ( aIkeMsg->iNonce->PlDataLen() < IKEV2_MIN_NONCE_SIZE )
       
  1893 				{
       
  1894 				    DEBUG_LOG1(_L("Nonce data too short %d"), iState);
       
  1895 					return EFalse;	
       
  1896 				}
       
  1897 		
       
  1898 				//Check peer NAT status
       
  1899 				TBool useNatDetection = EFalse;
       
  1900                 if ( !iHdr.iIkeData->iUseNatProbing )
       
  1901                 {
       
  1902                     TInetAddr LocalIp;  
       
  1903                     if ( iHdr.iIkeData->iUseMobIke )
       
  1904                          LocalIp.SetAddress(KInetAddrNone);
       
  1905                     else LocalIp = iHdr.iLocalAddr;        
       
  1906                     iHdr.iNATFlags = CIkev2NatT::CheckPeerNotifysL(*aIkeMsg->iNotifs, LocalIp, 
       
  1907                                                                    iHdr.iRemoteAddr, IKE_PORT,
       
  1908                                                                    iHdr.SpiI(), iHdr.SpiR(), useNatDetection);
       
  1909                 }
       
  1910 
       
  1911                 if ( !ProcessKeyExchangeL((TKEPayloadIkev2*)aIkeMsg->iKe, iHdr.iDHGroup) )
       
  1912                     return EFalse;
       
  1913 
       
  1914                 
       
  1915 				//
       
  1916 				// Create own SPI (responder)
       
  1917 				//
       
  1918   				CreateIkeSPI(iHdr.SpiR());
       
  1919 				delete iNonce_I;
       
  1920 				iNonce_I = NULL;
       
  1921 				iNonce_I = HBufC8::NewL(aIkeMsg->iNonce->PlDataLen());
       
  1922 				iNonce_I->Des().Copy(aIkeMsg->iNonce->PayloadData(), aIkeMsg->iNonce->PlDataLen());
       
  1923 				GetNonceDataL(EFalse);
       
  1924 
       
  1925 				TPtrC8 ikeHdrPtr((TUint8*)IkeHdr, IkeHdr->GetLength());
       
  1926 				SaveSignedDataL(EFalse, ikeHdrPtr);  // Save IKE_AUTH message 2 
       
  1927 				
       
  1928 				//
       
  1929 				// Build IKE_SA_INIT response message: HDR, SAr1, KEr, Nr, [CERTREQ]
       
  1930 				//
       
  1931 				__ASSERT_DEBUG(!iHdr.iInitiator, User::Invariant());				
       
  1932 				CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(), iHdr.SpiR(),
       
  1933                                                             IKE_SA_INIT, 
       
  1934                                                             iHdr.iInitiator,
       
  1935                                                             ETrue, 
       
  1936                                                             iHdr.ExpectedRequestId(),
       
  1937                                                             iDebug);
       
  1938 				CleanupStack::PushL(ikeMsg);
       
  1939 
       
  1940                 HBufC8* saBfr = Ikev2Proposal::FromPolicyToProposaL(iHdr, iSPI_Rekey, iDHGroupGuess);
       
  1941                 CleanupStack::PushL(saBfr);
       
  1942                 ikeMsg->AppendSaPayloadL(*saBfr);
       
  1943                 CleanupStack::Pop(saBfr);
       
  1944                 SetProposedSa(saBfr);
       
  1945 				
       
  1946                 AppendKEPayloadL(*ikeMsg, iHdr.iDHGroup);
       
  1947                 ikeMsg->AppendNoncePayloadL(*iNonce_R);
       
  1948                 
       
  1949 				if ( iPkiService )
       
  1950 				    {
       
  1951 				    ikeMsg->AppendCertReqPayloadL(iPkiService->CaList());
       
  1952 				    }
       
  1953 				
       
  1954 				if ( useNatDetection )
       
  1955 				{   
       
  1956                     delete iNatNotify;
       
  1957                     iNatNotify = NULL;
       
  1958 				
       
  1959 					TInetAddr LocalIp;	
       
  1960 					if ( iHdr.iIkeData->iUseMobIke )
       
  1961 						 LocalIp.SetAddress(KInetAddrNone);
       
  1962 					else LocalIp = iHdr.iLocalAddr; 	   
       
  1963                     
       
  1964                     
       
  1965 					iNatNotify = CIkev2NatT::NewL(LocalIp, iHdr.iRemoteAddr, IKE_PORT, ikeMsg->InitiatorSpi(), ikeMsg->ResponderSpi());				       
       
  1966 				    ikeMsg->AppendNotifyPayloadL(IKEV2_PROTOCOL, KZeroDesc, NAT_DETECTION_SOURCE_IP, 
       
  1967 				                                 iNatNotify->SourceNofify());
       
  1968 			        ikeMsg->AppendNotifyPayloadL(IKEV2_PROTOCOL, KZeroDesc, NAT_DETECTION_DESTINATION_IP, 
       
  1969 				                                 iNatNotify->DestinNofify());         					
       
  1970 				}
       
  1971 				GetNatStatus(useNatDetection, aRemote);
       
  1972 				CleanupStack::Pop(ikeMsg);
       
  1973 				SendIkeMsgL(ikeMsg);
       
  1974 				GenerateIkeKeysL();								
       
  1975 				
       
  1976 				SaveSignedDataL(ETrue, ikeMsg->IkeMessageDatagram()); // Own identity is not yet saved to signed data
       
  1977 			    iState = KStateIkeSaInitResponse;
       
  1978 				}
       
  1979                 break;
       
  1980 
       
  1981 			default:
       
  1982 				//
       
  1983 				// Ignore received message silently
       
  1984 				//
       
  1985 			    DEBUG_LOG1(_L("IKE_SA_INIT message received in state %d"), iState);
       
  1986 				break;
       
  1987 				
       
  1988 		}	
       
  1989 	}
       
  1990 	
       
  1991 	return ETrue;
       
  1992 }
       
  1993 
       
  1994 TBool CIkev2Negotiation::ProcessIkeAuthL(CIkev2Payloads* aIkeMsg)
       
  1995 {
       
  1996     ASSERT(aIkeMsg);
       
  1997 	//
       
  1998 	// Process IKE message of exchange type IKE_AUTH
       
  1999 	//
       
  2000 	ThdrISAKMP* IkeHdr = aIkeMsg->GetIkeMsg();  // IKE Message fixed header
       
  2001 	TBool   Response   = IkeHdr->GetFlags() & IKEV2_RESPONSE_MSG;
       
  2002 	TBool   Initiator  = IkeHdr->GetFlags() & IKEV2_INITIATOR;
       
  2003 	TUint32 MsgId      = IkeHdr->GetMessageId();
       
  2004 
       
  2005 	if ( iHdr.iInitiator )
       
  2006 	{
       
  2007 		if ( Initiator )
       
  2008 		{
       
  2009 		    DEBUG_LOG1(_L("IKEv2 Message with Orig_Init-bit in wrong state: %d"), iState);
       
  2010 			return ETrue;  	
       
  2011 		}	
       
  2012 		if ( !Response )
       
  2013 		{
       
  2014 		    DEBUG_LOG1(_L("IKEv2 Message is not response; state: %d"), iState);
       
  2015 			return ETrue;
       
  2016 		}
       
  2017 		if ( MsgId != iHdr.ExpectedResponseId() )
       
  2018 		{
       
  2019 		    DEBUG_LOG1(_L("Wrong message id in response; state: %d"), iState);
       
  2020 		    return ETrue;		
       
  2021 		}
       
  2022 
       
  2023 		switch ( iState )
       
  2024 		{
       
  2025 			case KStateIkeSaAuthRequest:
       
  2026 			    DEBUG_LOG(_L("Handling IKE_AUTH response"));
       
  2027 				//
       
  2028 				// Received message should be a response to a
       
  2029 				// IKE_AUTH request transmitted.
       
  2030 				// Response message should be format:
       
  2031 				// HDR(A,B), SK {IDr, [CERT,] AUTH, [CP], SAr2, TSi, TSr}				
       
  2032 				//
       
  2033 				if ( aIkeMsg->iEncr )
       
  2034 				{	
       
  2035 				   ProcessNotifyPayloadsL(*aIkeMsg->iNotifs, EFalse, IKE_AUTH);
       
  2036 				   if ( iDeleteIkeSA )
       
  2037 				   {
       
  2038 				      DEBUG_LOG1(_L("Error Notify in IKE_AUTH response: %d"), iState);			
       
  2039 					  
       
  2040 		              //Because we are just in IKE_AUTH no IKE_SAs exists --> we don't 
       
  2041     		          //want to delete one. So we set iDeleteIkeSA back to false.			          
       
  2042 			          iDeleteIkeSA = EFalse;
       
  2043 					 	
       
  2044 					  return EFalse;
       
  2045 				   }
       
  2046 				}   
       
  2047 				if ( !CheckPayloadsOrder(aIkeMsg, IKE_AUTH, ETrue) )
       
  2048 				{
       
  2049 				    DEBUG_LOG1(_L("Erroneous IKE_AUTH response: %d"), iState);
       
  2050 					SetNotifyCode(INVALID_SYNTAX);
       
  2051 				
       
  2052 				    if ( iChildSaRequest && !iChildSARejected && !aIkeMsg->iSa )
       
  2053 				        {
       
  2054 						iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest);	
       
  2055 						}
       
  2056 					
       
  2057 				    return EFalse;	
       
  2058 				}
       
  2059 				DEBUG_LOG(_L("IKE_AUTH payload order check passed"));
       
  2060 				TBool Status;
       
  2061 				if ( iEapCompleted )
       
  2062 				{	
       
  2063 				    Status = AuthenticatePeerL(aIkeMsg->iAuth);
       
  2064 				}   
       
  2065 				else
       
  2066 				{
       
  2067 					if ( iPkiService && !VerifyPeerCertificateL(aIkeMsg->iCerts, aIkeMsg->iIdR) )
       
  2068 					{
       
  2069 						SetNotifyCode(AUTHENTICATION_FAILED);					
       
  2070 						return EFalse;
       
  2071 					}
       
  2072 				    Status = AddIdAndAuthenticatePeerL(aIkeMsg);
       
  2073 				}	
       
  2074 				if ( !Status )
       
  2075 				{
       
  2076 					SetNotifyCode(AUTHENTICATION_FAILED);
       
  2077 					return EFalse;
       
  2078 				}
       
  2079 				//
       
  2080 				// If implicit Child SA negotiation requested,
       
  2081 				// verify IPSEC SA- and Traffic selector payloads, too
       
  2082 				//
       
  2083 				if ( iChildSaRequest )
       
  2084 				{
       
  2085                     DEBUG_LOG(_L("Processing CHILD_SA creation"));
       
  2086 					if ( !iChildSARejected )
       
  2087 					{
       
  2088 						if ( !Ikev2Proposal::VerifySaResponseL(iHdr, iChild, *iChildSaRequest->SA(), *aIkeMsg) )
       
  2089 						{
       
  2090 							DEBUG_LOG1(_L("Unaccepted SA payload content in IKE_AUTH response: %d"),iState);
       
  2091 							SetNotifyCode(NO_PROPOSAL_CHOSEN);
       
  2092 							iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest);							
       
  2093 							return EFalse;
       
  2094 						}
       
  2095 						DEBUG_LOG(_L("SA response verified"));
       
  2096 						if ( !IpsecSelectors::VerifyTrafficSelectorsL(iChildSaRequest, (TTSPayloadIkev2*)aIkeMsg->iTsI, (TTSPayloadIkev2*)aIkeMsg->iTsR ) )
       
  2097 						{
       
  2098 						    DEBUG_LOG1(_L("Unaccepted Traffic Selectors in IKE_AUTH response: %d"),iState);
       
  2099 							SetNotifyCode(TS_UNACCEPTABLE);
       
  2100 							iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest);
       
  2101 							return EFalse;
       
  2102 						}
       
  2103 						DEBUG_LOG(_L("Traffic selectors verified"));
       
  2104 						if ( aIkeMsg->iCp )
       
  2105 						{
       
  2106 							if ( iConfigMode )
       
  2107 							    {
       
  2108 								iConfigMode->ProcessCpL(aIkeMsg->iCp);
       
  2109 							    }
       
  2110 							else
       
  2111 							    {
       
  2112 							    DEBUG_LOG(_L("Unsolicited CP payload in IKE_AUTH response"));
       
  2113 							    }							
       
  2114 						}
       
  2115 						iChildSaRequest->SetSPI_Out(iChild.iSPI_Out);	
       
  2116 						DEBUG_LOG(_L("Generating IPsec keys"));
       
  2117 						iChild.GenerateIpsecKeysL(iHdr.iSK_d, KZeroDesc, 
       
  2118                                                   *iNonce_I, *iNonce_R, iHdr.iPRFAlg);
       
  2119 						DEBUG_LOG(_L("IPsec keys generated"));
       
  2120 					}	
       
  2121 					else	
       
  2122 					{
       
  2123 					    DEBUG_LOG1(_L("Implicit CHILD_SA rejected Notify in IKE_AUTH response: %d"), iState);
       
  2124 						iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest);
       
  2125 					}	
       
  2126 				}	
       
  2127 				//
       
  2128 				// IKE_AUTH request is completed and IKE SA has been
       
  2129 				// negotiated
       
  2130 				//
       
  2131 				IkeSaCompletedL();				   
       
  2132 				break;
       
  2133 
       
  2134 			case KStateIkeSaEapStarted:
       
  2135 				//
       
  2136 				// Received message should be an IKE_AUTH response
       
  2137 				// containing an EAP payload.
       
  2138 				// The content of received IKE message shall be:
       
  2139 				// HDR, SK {IDr, [CERT,] AUTH, EAP }
       
  2140 				//
       
  2141 				if ( !aIkeMsg->iEncr || !aIkeMsg->iIdR || !aIkeMsg->iAuth || !aIkeMsg->iEap )
       
  2142 				{
       
  2143 					DEBUG_LOG1(_L("Erroneous IKE_AUTH response: %d"), iState);
       
  2144 					SetNotifyCode(INVALID_SYNTAX);			
       
  2145 					return EFalse;	
       
  2146 				}
       
  2147 				if ( iPkiService && !VerifyPeerCertificateL(aIkeMsg->iCerts, aIkeMsg->iIdR) )
       
  2148 				{
       
  2149 					SetNotifyCode(AUTHENTICATION_FAILED);										
       
  2150 					return EFalse;
       
  2151 				}
       
  2152                 if ( !AddIdAndAuthenticatePeerL(aIkeMsg) )
       
  2153                 {
       
  2154                     SetNotifyCode(AUTHENTICATION_FAILED);										
       
  2155                     return EFalse;
       
  2156                 }
       
  2157 				iState = KStateIkeSaEapGoing;
       
  2158                 iEapPlugin->EapDataInbound(aIkeMsg->iEap);
       
  2159                 break;
       
  2160 				
       
  2161 			case KStateIkeSaEapGoing:
       
  2162 				//
       
  2163 				// Received message should be an IKE_AUTH response
       
  2164 				// containing an EAP payload.
       
  2165 				// The content of received IKE message shall be:
       
  2166 				// HDR, SK {EAP}				
       
  2167                 //
       
  2168 				if ( !aIkeMsg->iEncr || !aIkeMsg->iEap )
       
  2169 				{
       
  2170 					DEBUG_LOG1(_L("Erroneous IKE_AUTH response: %d"), iState);
       
  2171 					SetNotifyCode(INVALID_SYNTAX);				
       
  2172 					return EFalse;	
       
  2173 				}
       
  2174 				iEapPlugin->EapDataInbound(aIkeMsg->iEap);
       
  2175 				break;
       
  2176 
       
  2177 			default:
       
  2178 				//
       
  2179 				// Ignore received message silently
       
  2180 				//
       
  2181 				DEBUG_LOG1(_L("IKE_AUTH response received in state %d"), iState);
       
  2182 				break;
       
  2183 
       
  2184 		}	
       
  2185 	}
       
  2186 	else
       
  2187 	{
       
  2188 		if ( !Initiator )
       
  2189 		{
       
  2190 			DEBUG_LOG1(_L("IKEv2 Message without Orig_Init-bit in wrong, state: %d"), iState);
       
  2191 			return ETrue;		
       
  2192 		}	
       
  2193 		if ( Response )
       
  2194 		{
       
  2195 			DEBUG_LOG1(_L("IKEv2 Message is not request, state: %d"), iState);
       
  2196 			return ETrue;		
       
  2197 		}
       
  2198 		switch ( iState )
       
  2199 		{
       
  2200 			case KStateIkeSaInitResponse:
       
  2201 			case KStateIkeSaCompleted:	
       
  2202 				//
       
  2203 				// Received message should be an IKE_AUTH request
       
  2204 				// Request message should be format:
       
  2205 				// HDR(A,B), SK {IDi, [CERT,] [CERTREQ,] [IDr,] AUTH, SAi2, TSi, TSr} 
       
  2206 				//
       
  2207 				if ( !CheckPayloadsOrder(aIkeMsg, IKE_AUTH, EFalse) )
       
  2208 				{
       
  2209 					DEBUG_LOG1(_L("Erroneous IKE_AUTH request: %d"), iState);
       
  2210 					SetNotifyCode(INVALID_SYNTAX);
       
  2211 					return EFalse;	
       
  2212 				}
       
  2213 				if ( MsgId != iHdr.ExpectedRequestId() ) {
       
  2214 					if ( iHdr.iLastResponse != NULL &&
       
  2215 					     MsgId == iHdr.iLastResponse->MessageId() && 
       
  2216 					     iState == KStateIkeSaCompleted )
       
  2217 					{
       
  2218 					   //
       
  2219 					   // Retransmission of an earlier IKE_SA_INIT
       
  2220 					   // request. Retransmit current IKE_SA_INIT
       
  2221 					   // response (if retry count not exhausted)
       
  2222 					   //
       
  2223 						DoRetransmitL(ETrue);
       
  2224 						return ETrue;
       
  2225 					}
       
  2226 					else {	
       
  2227 						DEBUG_LOG1(_L("Wrong message id in request, state: %d"), iState);					
       
  2228 						SetNotifyCode(INVALID_MESSAGE_ID);
       
  2229 						StoreNotifyData32(MsgId);
       
  2230 						return EFalse;  								   
       
  2231 					}  		   
       
  2232 				}
       
  2233 				if ( iState == KStateIkeSaCompleted )
       
  2234 				   return EFalse; // IKE_AUTH request retry with a new message ID
       
  2235 
       
  2236 				//if ( aIkeMsg->iEncr )
       
  2237 				//{	
       
  2238 					ProcessNotifyPayloadsL(*aIkeMsg->iNotifs, EFalse, IKE_AUTH);
       
  2239 					if ( iDeleteIkeSA )
       
  2240 					{
       
  2241 						DEBUG_LOG1(_L("Error Notify in IKE_AUTH response: %d"), iState);
       
  2242 						return EFalse;
       
  2243 					}
       
  2244 				//}
       
  2245 				
       
  2246 				if ( iPkiService && !VerifyPeerCertificateL(aIkeMsg->iCerts, aIkeMsg->iIdI) )
       
  2247 				{
       
  2248 				    DEBUG_LOG(_L("Peer certificate validation failed."));
       
  2249 					SetNotifyCode(AUTHENTICATION_FAILED);
       
  2250 					return EFalse;
       
  2251 				}
       
  2252 				if ( !AddIdAndAuthenticatePeerL(aIkeMsg) )
       
  2253 				{	
       
  2254 					SetNotifyCode(AUTHENTICATION_FAILED);
       
  2255 					return EFalse;
       
  2256 		        }
       
  2257 				//
       
  2258 				// Process "concatenated" Child SA- and Traffic
       
  2259 				// Selector payloads if present  
       
  2260 				//
       
  2261 				if ( aIkeMsg->iSa )
       
  2262 				{
       
  2263 				    DEBUG_LOG(_L("IKE_AUTH request has SA and TS payload."));				
       
  2264 					CIkev2Acquire* Acquire = IpsecSelectors::GetIpsecPolicyL(iIkeV2PlugInSession, aIkeMsg);
       
  2265 					if ( !Acquire )
       
  2266 					{
       
  2267 					    DEBUG_LOG1(_L("Unaccepted Traffic Selectors in IKE_AUTH request: %d"),iState);
       
  2268 						SetNotifyCode(TS_UNACCEPTABLE);						
       
  2269 						return EFalse;
       
  2270 					}
       
  2271 					CleanupStack::PushL(Acquire);						
       
  2272 					HBufC8* proposedSaBuffer = NULL;
       
  2273 					if (!Ikev2Proposal::VerifySaRequestAndGetProposedSaBufferL(iHdr, iChild, 
       
  2274                                                                                *Acquire->SA(), *aIkeMsg,
       
  2275                                                                                proposedSaBuffer))
       
  2276 					{
       
  2277 						CleanupStack::PopAndDestroy(Acquire);  
       
  2278 						DEBUG_LOG1(_L("Unaccepted SA content in IKE_AUTH request: %d"),iState);
       
  2279 						SetNotifyCode(NO_PROPOSAL_CHOSEN);						
       
  2280 						return EFalse;  							
       
  2281 					}
       
  2282 					SetProposedSa(proposedSaBuffer);
       
  2283 					proposedSaBuffer = NULL;
       
  2284 					//
       
  2285 					// Replace SA payload buffer in CIkev2Acquire with
       
  2286 					// selected SA payload built in VerifySaRequestL
       
  2287 					//
       
  2288 					CleanupStack::Pop(Acquire); 							
       
  2289 					Acquire->ReplaceSA(GetProposedSa()); 
       
  2290 					Acquire->SetSPI_Out(iChild.iSPI_Out);
       
  2291 					Acquire->SetResponse();
       
  2292 					if ( iChild.iTransport )
       
  2293     					{
       
  2294 					    
       
  2295 						Acquire->SetTransport();				
       
  2296     					}
       
  2297  					CIkev2Acquire::Link(Acquire, GetAcquireQue());
       
  2298  					DEBUG_LOG(_L("Acquire linked."));
       
  2299  					
       
  2300 					if ( aIkeMsg->iCp )
       
  2301 					{
       
  2302 						//
       
  2303 						// CP payload received as IKE SA responder
       
  2304 						// Handle CP payload and return "dummy"
       
  2305 						// virtual IP to initiator. 
       
  2306 						//
       
  2307 						delete iConfigMode;
       
  2308 						iConfigMode = NULL;
       
  2309 						iConfigMode = CIkev2Config::NewL(Acquire, (TInetAddr*)&iHdr.iRemoteAddr);
       
  2310 						iConfigMode->ProcessCpL(aIkeMsg->iCp);
       
  2311 						Acquire->SetVirtualIp();
       
  2312 					}
       
  2313 	        		//
       
  2314 			        // Get SPI for new inbound SA
       
  2315         			//
       
  2316                     iChild.GenerateIpsecKeysL(iHdr.iSK_d, KZeroDesc, 
       
  2317                                                *iNonce_I, *iNonce_R, iHdr.iPRFAlg);
       
  2318 					
       
  2319 				    if ( iPkiService && !iEapPlugin && 
       
  2320 				         aIkeMsg->iCertReqs && 
       
  2321 				         aIkeMsg->iCertReqs->Count() )
       
  2322                 	{
       
  2323      			       GetOwnIdentityL();    // Get own Identity from Certificate (or policy)    			       
       
  2324     			       AddIdToSignedDataL(ETrue, iAuthMsgResp, iLocalIdentity->PayloadData());
       
  2325             					
       
  2326         			   CIkev2Acquire* Acquire = CIkev2Acquire::PeekFirst(GetAcquireQue());
       
  2327         			   if ( Acquire )
       
  2328         			   {
       
  2329         				   GetIpsecSPI(Acquire);
       
  2330         				   iState = KStateIkeSaAuthWaitSpi;
       
  2331         			   }
       
  2332         			   else 
       
  2333         			   {       
       
  2334         			       DEBUG_LOG(_L("CIkev2Acquire::PeekFirst returned NULL."));			    
       
  2335         			       DEBUG_LOG(_L("Sending IKE_AUTH response."));			    
       
  2336         			       SendIkeAuthMessageL();
       
  2337         			   }
       
  2338 
       
  2339                 	}	
       
  2340                     else
       
  2341 					{
       
  2342 						GetOwnIdentityL();
       
  2343 						AddIdToSignedDataL(ETrue, iAuthMsgResp, iLocalIdentity->PayloadData());
       
  2344 						GetIpsecSPI(Acquire);						
       
  2345 					    iState = KStateIkeSaAuthWaitSpi;
       
  2346 					}	
       
  2347 				}
       
  2348 				else
       
  2349 				{
       
  2350 					if ( iPkiService && !iEapPlugin && 
       
  2351 					     aIkeMsg->iCertReqs && 
       
  2352 					     aIkeMsg->iCertReqs->Count() )
       
  2353                     {                       
       
  2354        			        GetOwnIdentityL();    // Get own Identity from Certificate (or policy)
       
  2355         			    AddIdToSignedDataL(ETrue, iAuthMsgResp, iLocalIdentity->PayloadData());
       
  2356         			               						
       
  2357         			    CIkev2Acquire* Acquire = CIkev2Acquire::PeekFirst(GetAcquireQue());
       
  2358         			    if ( Acquire )
       
  2359         			    {
       
  2360         				   GetIpsecSPI(Acquire);
       
  2361         				   iState = KStateIkeSaAuthWaitSpi;
       
  2362         			    }
       
  2363         			    else 
       
  2364         			    {        			        
       
  2365         			       SendIkeAuthMessageL();
       
  2366         			    }
       
  2367 					}
       
  2368 					else
       
  2369 					{	
       
  2370 				       //
       
  2371 				       // Build and send an IKE_AUTH response
       
  2372 				       //
       
  2373 						GetOwnIdentityL();
       
  2374 						AddIdToSignedDataL(ETrue, iAuthMsgResp, iLocalIdentity->PayloadData());
       
  2375 				        SendIkeAuthMessageL();
       
  2376 					}		
       
  2377 				}   
       
  2378 				break;
       
  2379 
       
  2380 			default:
       
  2381 				//
       
  2382 				// Ignore received message silently
       
  2383 				//
       
  2384 				DEBUG_LOG1(_L("IKE_SA_INIT message received in state %d"), iState);
       
  2385 				break;
       
  2386 		}	
       
  2387 	}
       
  2388 	
       
  2389 	return ETrue;
       
  2390 }
       
  2391 
       
  2392 TBool CIkev2Negotiation::ProcessChildSaL(CIkev2Payloads* aIkeMsg)
       
  2393 {
       
  2394     ASSERT(aIkeMsg);
       
  2395 	//
       
  2396 	// Process IKE message of exchange type CREATE_CHILD_SA
       
  2397 	//
       
  2398 	TUint16 PfsDHGroup;
       
  2399 	ThdrISAKMP* IkeHdr = aIkeMsg->GetIkeMsg();  // IKE Message fixed header
       
  2400 	TBool   Response   = IkeHdr->GetFlags() & IKEV2_RESPONSE_MSG;
       
  2401 	TBool   Initiator  = IkeHdr->GetFlags() & IKEV2_INITIATOR;
       
  2402 	TUint32 MsgId      = IkeHdr->GetMessageId();
       
  2403 			
       
  2404 	if ( iHdr.iInitiator )
       
  2405 	{
       
  2406 		if ( Initiator )
       
  2407 		{
       
  2408 			DEBUG_LOG1(_L("IKEv2 Message with Orig_Init-bit in wrong state: %d"), iState);
       
  2409 			SetNotifyCode(INVALID_SYNTAX);		
       
  2410 			return EFalse;  	
       
  2411 		}	
       
  2412 	}
       
  2413 	else
       
  2414 	{
       
  2415 		if ( !Initiator )
       
  2416 		{
       
  2417 			DEBUG_LOG1(_L("IKEv2 Message without Orig_Init-bit in wrong state: %d"), iState);
       
  2418 			SetNotifyCode(INVALID_SYNTAX);		
       
  2419 			return EFalse;  	
       
  2420 		}	
       
  2421 	}
       
  2422 
       
  2423 	if ( Response )
       
  2424 	{
       
  2425 	   //
       
  2426 	   // CREATE_CHILD_SA response message received
       
  2427 	   //
       
  2428         switch ( iState )
       
  2429 	    {
       
  2430 		   case KStateIkeChildSARequest:
       
  2431 			  //
       
  2432 			  // Received message should be a response to a
       
  2433 			  // CREATE_CHILD_SA request transmitted.
       
  2434 			  // Response message should be format:
       
  2435 			  // HDR(A,B), SK { SA, Nr, [KEr], [TSi, TSr]}
       
  2436 			  //
       
  2437 			  if ( MsgId != iHdr.ExpectedResponseId() )
       
  2438 			  {
       
  2439 				   DEBUG_LOG1(_L("Wrong message id in response; state: %d"), iState);
       
  2440 
       
  2441 				   SetNotifyCode(INVALID_MESSAGE_ID);
       
  2442 				   StoreNotifyData32(MsgId);	 
       
  2443 				   return EFalse; 	
       
  2444 			  }
       
  2445 			  if ( aIkeMsg->iEncr )
       
  2446 			  {	
       
  2447 			      ProcessNotifyPayloadsL(*aIkeMsg->iNotifs, EFalse, CREATE_CHILD_SA);
       
  2448 			      if ( iDeleteIkeSA )
       
  2449 			      {
       
  2450 				     DEBUG_LOG1(_L("Error Notify in CREATE_CHILD_SA response: %d"), iState);
       
  2451 				     return EFalse;
       
  2452 				  }
       
  2453 				  if ( iChildSARejected )
       
  2454 				  {
       
  2455 					  DEBUG_LOG1(_L("CHILD_SA rejected Notify in CREATE_CHILD_SA response: %d"), iState);					  
       
  2456 					  iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest);
       
  2457 					  iStopped = ETrue;
       
  2458 					  return EFalse;
       
  2459 				  } 
       
  2460 			  }	
       
  2461 			  if ( !CheckPayloadsOrder(aIkeMsg, CREATE_CHILD_SA, ETrue) )
       
  2462 			  {
       
  2463 			     DEBUG_LOG1(_L("Erroneous CREATE_CHILD_SA response: %d"), iState);
       
  2464 				 SetNotifyCode(INVALID_SYNTAX);
       
  2465 				 iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest);
       
  2466 				 return EFalse;	
       
  2467 			  }
       
  2468 	  		  if ( aIkeMsg->iNonce->PlDataLen() < IKEV2_MIN_NONCE_SIZE )
       
  2469 			  {
       
  2470 			     DEBUG_LOG1(_L("Nonce data too short %d"), iState);
       
  2471 				 iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest);
       
  2472 				 iStopped = ETrue;
       
  2473 				 return EFalse;
       
  2474 			  }
       
  2475 			  
       
  2476 		      if ( !Ikev2Proposal::VerifySaResponseL(iHdr, iChild, *iChildSaRequest->SA(), *aIkeMsg) )
       
  2477 			  {
       
  2478 			     DEBUG_LOG1(_L("Unaccepted SA content in CREATE_CHILD_SA response: %d"),iState);				
       
  2479 				 SetNotifyCode(NO_PROPOSAL_CHOSEN);
       
  2480 				 iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest);
       
  2481 			     return EFalse;
       
  2482 			  }
       
  2483 			  if ( !IpsecSelectors::VerifyTrafficSelectorsL(iChildSaRequest, (TTSPayloadIkev2*)aIkeMsg->iTsI, (TTSPayloadIkev2*)aIkeMsg->iTsR ) )
       
  2484 			  {
       
  2485 			     DEBUG_LOG1(_L("Unaccepted Traffic Selectors in CREATE_CHILD_SA response: %d"),iState);	  						 
       
  2486 				 SetNotifyCode(TS_UNACCEPTABLE);
       
  2487 				 iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest);
       
  2488 				 return EFalse;
       
  2489 			  }
       
  2490 			  delete iNonce_R;
       
  2491 			  iNonce_R = NULL;
       
  2492 			  iNonce_R = HBufC8::NewL(aIkeMsg->iNonce->PlDataLen());
       
  2493 			  iNonce_R->Des().Copy(aIkeMsg->iNonce->PayloadData(), aIkeMsg->iNonce->PlDataLen());
       
  2494 			  PfsDHGroup = iChildSaRequest->DHGroup(); 
       
  2495 			  if ( PfsDHGroup  )
       
  2496 			  {
       
  2497 		         if ( !ProcessKeyExchangeL((TKEPayloadIkev2*)aIkeMsg->iKe, PfsDHGroup) )
       
  2498 				 {	 					 
       
  2499 					 iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest);
       
  2500 					 return EFalse;
       
  2501 				 }	
       
  2502                  HBufC8* g_ir = iDHKeys->ComputeAgreedKeyL(iDHPublicPeer->Des());
       
  2503 		         CleanupStack::PushL(g_ir);
       
  2504 
       
  2505 		         iChild.GenerateIpsecKeysL(iHdr.iSK_d, *g_ir, 
       
  2506                                            *iNonce_I, *iNonce_R, iHdr.iPRFAlg);
       
  2507 
       
  2508 		         
       
  2509 		         g_ir->Des().FillZ(); // Wipe out shared secret value from buffer
       
  2510 		         CleanupStack::PopAndDestroy();  //g_ir
       
  2511 
       
  2512 			  }
       
  2513 			  else if ( aIkeMsg->iKe )
       
  2514 			  {
       
  2515 			      DEBUG_LOG1(_L("Unsolicted Key Exchange payload present in CREATE_CHILD_SA response: %d"),iState);
       
  2516 				  SetNotifyCode(INVALID_KE_PAYLOAD);
       
  2517 				  iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest);				  
       
  2518 				  return EFalse;
       
  2519 			  }
       
  2520 			  else
       
  2521               {
       
  2522                   iChild.GenerateIpsecKeysL(iHdr.iSK_d, KZeroDesc, 
       
  2523                                             *iNonce_I, *iNonce_R, iHdr.iPRFAlg);
       
  2524               
       
  2525               }
       
  2526 			  //
       
  2527 			  //  CREATE_CHILD_SA request is completed Update 
       
  2528 			  //			  
       
  2529 			  IpsecSANegotiatedL();
       
  2530 			  break;
       
  2531 
       
  2532 		   case KStateIkeSARekeyRequest:
       
  2533 			  //
       
  2534 			  // Received message should be a response to a
       
  2535 			  // IKE SA rekey CHILD_SA request transmitted.
       
  2536 			  // Response message should be format:
       
  2537 			  // HDR(A,B), SK { SA, Nr, KEr }
       
  2538 			  //
       
  2539 			  if ( CheckPayloadsOrder(aIkeMsg, CREATE_CHILD_SA, ETrue) && aIkeMsg->iKe )
       
  2540 			  {
       
  2541 			     DEBUG_LOG1(_L("IKE SA rekey message received as CHILD_SA response: %d"), iState);
       
  2542 				 ProcessIkeSARekeyL(aIkeMsg);
       
  2543 			  }
       
  2544 			  else
       
  2545 		      {
       
  2546                   DEBUG_LOG1(_L("Erroneous IKE SA rekey message received as CHILD_SA response: %d"),iState);		      
       
  2547 		      }
       
  2548 			  //iIkeV2PlugInSession.UpdateIkev2SAL(&iHdr, NULL, EFalse);								  
       
  2549 			  BuildDeleteRequestL(NULL);  // Delete IKE SA rekeyed
       
  2550 			  iIkeV2PlugInSession.DeleteIkev2SA(iHdr.SaId());			  
       
  2551 			  break; 
       
  2552 
       
  2553 		   default:
       
  2554 			  //
       
  2555 			  // Ignore received message silently
       
  2556 			  //
       
  2557 			  DEBUG_LOG1(_L("CREATE_CHILD_SA response received in state %d"), iState);
       
  2558 			  break;
       
  2559 
       
  2560 	    }	
       
  2561 	}
       
  2562 	else
       
  2563 	{
       
  2564 	    //
       
  2565 	    // CREATE_CHILD_SA request message received
       
  2566 	    //
       
  2567 		if ( MsgId != iHdr.ExpectedRequestId() ) {
       
  2568 			if ( iHdr.iLastResponse != NULL &&
       
  2569 			     MsgId == iHdr.iLastResponse->MessageId() )
       
  2570 			{
       
  2571 			   //
       
  2572 			   // Retransmission of an earlier request.
       
  2573 			   // Retransmit current response 
       
  2574 			   //
       
  2575 				iState = KStateIkeChildSAResponse;
       
  2576 				DoRetransmitL(ETrue);
       
  2577 				return ETrue;
       
  2578 			}
       
  2579 			else {	
       
  2580 				DEBUG_LOG1(_L("Wrong message id in request, state: %d"), iState);
       
  2581 				SetNotifyCode(INVALID_MESSAGE_ID);
       
  2582 				StoreNotifyData32(MsgId);
       
  2583 				return EFalse;  								   
       
  2584 			}  		   
       
  2585 		}
       
  2586 	   
       
  2587 		if ( iState >= KStateIkeSaCompleted )
       
  2588 		{
       
  2589 		   //
       
  2590 		   // Received CREATE_CHILD_SA message can be one of the
       
  2591 		   // following:
       
  2592 		   // -- Create new Ipsec SA request:  
       
  2593 	       //    HDR(A,B), SK { SA, Nr, [KEi], [TSi, TSr]}
       
  2594 		   // -- Rekey Ipsec SA request:
       
  2595 		   //    HDR(A,B), SK { N, SA, Ni, [KEi], [TSi, TSr]} 
       
  2596 		   // -- Rekey IKE SA request: 
       
  2597 		   //    HDR(A,B), SK { SA, Ni, KEi} 
       
  2598 		   //   
       
  2599 			if ( !CheckPayloadsOrder(aIkeMsg, CREATE_CHILD_SA, EFalse) )
       
  2600 			{
       
  2601 				DEBUG_LOG1(_L("Erroneous CREATE_CHILD_SA request: %d"), iState);
       
  2602 				SetNotifyCode(INVALID_SYNTAX);						
       
  2603 				return EFalse;	
       
  2604 			}
       
  2605 		   //
       
  2606 		   // Check is the current request an IKE SA rekey by checking
       
  2607 		   // Proposal payload protocol value
       
  2608 		   //
       
  2609             if ( Ikev2Proposal::IkeSaRekey(aIkeMsg) ) 
       
  2610 			{
       
  2611 				TBool Status;
       
  2612 				if ( iState == KStateIkeSARekeyRequest )
       
  2613 				{
       
  2614 				   DEBUG_LOG1(_L("IKE SA Rekey collision for SAID: %d"), iHdr.SaId());										   
       
  2615 				   SetNotifyCode(NO_ADDITIONAL_SAS);
       
  2616 				   Status = EFalse;
       
  2617 				}
       
  2618 				else
       
  2619 				{	
       
  2620 				   DEBUG_LOG1(_L("IKE SA Rekey started by peer for SAID: %d"), iHdr.SaId());							   						   
       
  2621 				   iState = KStateIkeSARekeyResponse;
       
  2622 				   Status = ProcessIkeSARekeyL(aIkeMsg);
       
  2623 				   iIkeV2PlugInSession.UpdateIkev2SAL(&iHdr, NULL);
       
  2624 				}
       
  2625 				return Status;
       
  2626 			}
       
  2627 			if ( CIkev2Acquire::Responding(GetAcquireQue()) )
       
  2628 			{
       
  2629 				DEBUG_LOG1(_L("CREATE_CHILD_SA IKE SA request already pending: %d"), iState);
       
  2630 				SetNotifyCode(NO_ADDITIONAL_SAS);
       
  2631 				return EFalse;	
       
  2632 			}
       
  2633 		    	
       
  2634 		   //
       
  2635 		   // Get acceptable Ipsec policy for peer defined traffic
       
  2636 		   // selectors (and peer address)
       
  2637 		   //
       
  2638 		    CIkev2Acquire* Acquire = IpsecSelectors::GetIpsecPolicyL(iIkeV2PlugInSession, aIkeMsg, 
       
  2639                                                                      iHdr.iIkeData->iGroupDesc_II);
       
  2640 			if ( !Acquire )
       
  2641 			{
       
  2642 				DEBUG_LOG1(_L("Unaccepted Traffic Selectors in CREATE_CHILD_SA request: %d"),iState);
       
  2643 				SetNotifyCode(TS_UNACCEPTABLE);						
       
  2644 				return EFalse;
       
  2645 			}
       
  2646 			CleanupStack::PushL(Acquire);			
       
  2647 			HBufC8* proposedSaBuffer = NULL;
       
  2648 			if (!Ikev2Proposal::VerifySaRequestAndGetProposedSaBufferL(iHdr, iChild, *Acquire->SA(), 
       
  2649                                                                        *aIkeMsg, proposedSaBuffer))
       
  2650 			{
       
  2651 				CleanupStack::PopAndDestroy(Acquire);				
       
  2652 				DEBUG_LOG1(_L("Unaccepted SA content in CREATE_CHILD_SA request: %d"),iState);
       
  2653 				SetNotifyCode(NO_PROPOSAL_CHOSEN);						
       
  2654 				return EFalse;  							
       
  2655 			}
       
  2656 			this->SetProposedSa(proposedSaBuffer);
       
  2657 			proposedSaBuffer = NULL;
       
  2658 			delete iNonce_I;
       
  2659 			iNonce_I = NULL;
       
  2660 			iNonce_I = HBufC8::NewL(aIkeMsg->iNonce->PlDataLen());
       
  2661 			iNonce_I->Des().Copy(aIkeMsg->iNonce->PayloadData(), aIkeMsg->iNonce->PlDataLen());
       
  2662 			if ( aIkeMsg->iKe )
       
  2663 			{
       
  2664 				PfsDHGroup = Acquire->DHGroup();
       
  2665 				if ( PfsDHGroup == 0 )
       
  2666 				{	
       
  2667 					PfsDHGroup = Ikev2Proposal::GetDHGroup(iHdr.iIkeData->iGroupDesc_II);
       
  2668 					Acquire->DHGroup(PfsDHGroup);
       
  2669 				}	
       
  2670 				if ( !ProcessKeyExchangeL((TKEPayloadIkev2*)aIkeMsg->iKe, PfsDHGroup) )
       
  2671 				    {
       
  2672 				    CleanupStack::PopAndDestroy(Acquire);
       
  2673 					return EFalse;
       
  2674 				    }
       
  2675 			}
       
  2676 			CleanupStack::Pop(Acquire);						
       
  2677 			Acquire->SetSPI_Out(iChild.iSPI_Out);
       
  2678 			Acquire->SetResponse();
       
  2679 			if ( iChild.iTransport )
       
  2680 				Acquire->SetTransport();				
       
  2681 			CIkev2Acquire::Link(Acquire, GetAcquireQue());			
       
  2682 		    //
       
  2683 		    // Get SPI for new inbound SA
       
  2684 		    //
       
  2685 			GetIpsecSPI(Acquire);									
       
  2686 		}
       
  2687 		else
       
  2688 		{
       
  2689 		    //
       
  2690 			// Ignore received message silently
       
  2691 			//
       
  2692 			DEBUG_LOG1(_L("CREATE_CHILD_SA request received in state %d"), iState);
       
  2693 		}	
       
  2694 	}	
       
  2695 
       
  2696 	return ETrue;
       
  2697 }
       
  2698 
       
  2699 TBool CIkev2Negotiation::ProcessIkeSARekeyL(CIkev2Payloads* aIkeMsg)
       
  2700 {	
       
  2701     ASSERT(aIkeMsg);
       
  2702 	//
       
  2703 	// Process IKE SA rekey message (as IKE_CHILD_SA exchange)
       
  2704     // HDR(A,B), SK { SA, Nonce, KE}	
       
  2705 	//
       
  2706 
       
  2707 			
       
  2708 	if ( (iState == KStateIkeSARekeyRequest) || (iState == KStateIkeSARekeyResponse) )
       
  2709 	{
       
  2710 	   //
       
  2711 	   // Received CREATE_CHILD_SA message for IKE SA rekey must
       
  2712 	   // look like the following:  HDR(A,B), SK { SA, Ni, [KEi]}
       
  2713 	   // Allocate a new CIkev2Negotiation object for new IKE SA
       
  2714 	   //
       
  2715 	   //
       
  2716         CIkev2Negotiation* NewSA  = new (ELeave) CIkev2Negotiation(iIkeV2PlugInSession, iPfKeySocketIf, 
       
  2717                                                                    iEventLogger, iMessageSendQue, iDebug, 0);
       
  2718     	CleanupStack::PushL(NewSA);
       
  2719     	
       
  2720     	//Do not copy the previous sent request and response:
       
  2721    	    CIkeV2Message* lastResponse = iHdr.iLastResponse;
       
  2722    	    iHdr.iLastResponse = NULL;
       
  2723   	    CIkeV2Message* lastRequest = iHdr.iLastRequest; 
       
  2724   	    iHdr.iLastRequest = NULL;  	    
       
  2725 		NewSA->iHdr.Copy(iHdr);
       
  2726         iHdr.iLastResponse = lastResponse; 
       
  2727         iHdr.iLastRequest = lastRequest;       
       
  2728 		
       
  2729 		
       
  2730 		NewSA->iHdr.iWindowSize   = 1;
       
  2731 		NewSA->iHdr.iEncrAlg = 0;
       
  2732 		NewSA->iHdr.iPRFAlg = 0;
       
  2733 		NewSA->iHdr.iIntegAlg = 0;
       
  2734 		NewSA->iHdr.iDHGroup = 0;
       
  2735 		NewSA->iHdr.iAuthMethod = 0;
       
  2736 		NewSA->iHdr.iCipherKeyLth = 0;
       
  2737 		NewSA->iHdr.iCipherBlkLth = 0;
       
  2738 		NewSA->iHdr.iIntChkSumLth = 0;
       
  2739 				
       
  2740 		if ( iState == KStateIkeSARekeyRequest )
       
  2741 		{
       
  2742 		   NewSA->iHdr.iInitiator = ETrue;
       
  2743 		   NewSA->iHdr.SetSaId(iSAid_Rekey);		   
       
  2744 		   NewSA->iHdr.SetSpiI(iSPI_Rekey);
       
  2745 		   NewSA->iNonce_I    = iNonce_I; // Nonce was created in BuildIkeSaRekeyMsgL() earlier
       
  2746 		   NewSA->iDHKeys     = iDHKeys;  // DH keys object was created in BuildIkeSaRekeyMsgL() earlier		   
       
  2747 		   iNonce_I = NULL;
       
  2748 		   iDHKeys  = NULL;
       
  2749 		}
       
  2750 		else
       
  2751 		{
       
  2752 		   NewSA->iHdr.iInitiator = EFalse;
       
  2753 		   NewSA->iHdr.SetSaId(iIkeV2PlugInSession.GetSAId()); // Get a new SA Id		   
       
  2754 		   NewSA->CreateIkeSPI(NewSA->iHdr.SpiR());
       
  2755 		} 
       
  2756 		//
       
  2757 		// Build a SA payload from current IKE policy and
       
  2758 		// verify received IKE SA request with it
       
  2759 		//
       
  2760 		HBufC8* SaBfr = Ikev2Proposal::FromPolicyToProposaL(NewSA->iHdr, NewSA->iSPI_Rekey, NewSA->iDHGroupGuess, ETrue);
       
  2761 		CleanupStack::PushL(SaBfr);
       
  2762 		HBufC8* proposedSaBuffer = NULL;
       
  2763 		TBool SaOk = Ikev2Proposal::VerifySaRequestAndGetProposedSaBufferL(NewSA->iHdr, NewSA->iChild, 
       
  2764                                                                            *SaBfr, *aIkeMsg, proposedSaBuffer);
       
  2765 		CleanupStack::PopAndDestroy();
       
  2766 		if ( iState == KStateIkeSARekeyRequest )
       
  2767 	      	 SaOk &= Ikev2Proposal::GetRekeySpi(aIkeMsg, NewSA->iHdr.SpiR());			
       
  2768 	    else SaOk &= Ikev2Proposal::GetRekeySpi(aIkeMsg, NewSA->iHdr.SpiI());			
       
  2769 		if ( !SaOk )
       
  2770 		{
       
  2771 			DEBUG_LOG1(_L("Unaccepted SA content in IKE_SA Rekey request: %d"), iState);
       
  2772 			SetNotifyCode(NO_PROPOSAL_CHOSEN);
       
  2773 	    	CleanupStack::PopAndDestroy(NewSA);					
       
  2774 			return EFalse;  							
       
  2775 		}
       
  2776 		NewSA->SetProposedSa(proposedSaBuffer);
       
  2777 		proposedSaBuffer = NULL;
       
  2778 		if ( aIkeMsg->iNonce->PlDataLen() < IKEV2_MIN_NONCE_SIZE )
       
  2779 		{
       
  2780 		    DEBUG_LOG1(_L("Nonce data too short in IKE_SA Rekey request %d"), iState);
       
  2781 			SetNotifyCode(INVALID_SYNTAX);				
       
  2782 	    	CleanupStack::PopAndDestroy(NewSA);
       
  2783 			return EFalse;	
       
  2784 		}
       
  2785 		if ( iState == KStateIkeSARekeyRequest )
       
  2786 		{
       
  2787 		    NewSA->iNonce_R = HBufC8::NewL(aIkeMsg->iNonce->PlDataLen());
       
  2788 		    NewSA->iNonce_R->Des().Copy(aIkeMsg->iNonce->PayloadData(),	aIkeMsg->iNonce->PlDataLen()); 
       
  2789 	    }
       
  2790 	    else
       
  2791 	    {
       
  2792 		    NewSA->iNonce_I = HBufC8::NewL(aIkeMsg->iNonce->PlDataLen());
       
  2793 		    NewSA->iNonce_I->Des().Copy(aIkeMsg->iNonce->PayloadData(),	aIkeMsg->iNonce->PlDataLen()); 
       
  2794 		}
       
  2795 
       
  2796 		if ( !NewSA->ProcessKeyExchangeL((TKEPayloadIkev2*)aIkeMsg->iKe, NewSA->iHdr.iDHGroup) )
       
  2797 		{
       
  2798 		    //If there was notify code set, copy it to current negotiation before destroying NewSa
       
  2799 		    if(NewSA->GetNotifyCode())
       
  2800 		        {
       
  2801 		        SetNotifyCode(NewSA->GetNotifyCode());
       
  2802 		        }
       
  2803 		    TInt dataLth(0);
       
  2804 		    TUint8* notifyData = NewSA->NotifyData(dataLth);
       
  2805             if(dataLth == 2)
       
  2806                 {
       
  2807                 StoreNotifyData16(GET16(notifyData));
       
  2808                 }
       
  2809             else if(dataLth == 4)
       
  2810                 {
       
  2811                 StoreNotifyData32(GET32(notifyData));
       
  2812                 }
       
  2813 	        CleanupStack::PopAndDestroy(NewSA);
       
  2814 		    return EFalse;
       
  2815 		}
       
  2816 
       
  2817 		if ( iState == KStateIkeSARekeyResponse )
       
  2818 		{
       
  2819 		    //
       
  2820 		    // Build IKE SA rekey response (CHILD_SA response):
       
  2821 		    // HDR, SAr, Nr, KEr
       
  2822 		    //
       
  2823 		   iDHKeys    = NewSA->iDHKeys; // To calculate own DH value
       
  2824 		   iSPI_Rekey = NewSA->iHdr.SpiR();	
       
  2825 		   SetProposedSa(NewSA->GetProposedSa());	
       
  2826 		   BuildIkeSaRekeyMsgL(EFalse);
       
  2827 		   NewSA->iNonce_R = iNonce_R;  // Nonce is created in BuildIkeSaRekeyMsgL()
       
  2828 		   iNonce_R   = NULL;
       
  2829 		   iDHKeys    = NULL;		    
       
  2830 		}   
       
  2831 		//
       
  2832 		// Generate key material for new IKE SA
       
  2833 		//
       
  2834 		NewSA->GenerateIkeKeysL(&iHdr);
       
  2835 		
       
  2836 		//
       
  2837 		// Create a new IKE SA and swap IPSec SA from rekeyed IKE SA
       
  2838 		// to the new just created SA
       
  2839 		//
       
  2840        	iIkeV2PlugInSession.CreateIkev2SAL(NewSA->iHdr);
       
  2841 		iIkeV2PlugInSession.InheritIpsecSas(NewSA->iHdr.SaId(), iHdr.SaId());
       
  2842 		
       
  2843 		CleanupStack::PopAndDestroy(NewSA);		
       
  2844 	}
       
  2845 
       
  2846 	return ETrue;
       
  2847 }
       
  2848 
       
  2849 TBool CIkev2Negotiation::ProcessInfoMsgL(CIkev2Payloads* aIkeMsg)
       
  2850 {
       
  2851     ASSERT(aIkeMsg);
       
  2852 	//
       
  2853 	// Process IKE message of exchange type INFORMATIONAL
       
  2854 	// HDR, SK {[N,] [D,] [CP,] ...}
       
  2855 	// Only encyrpted and authenitcated are processed.
       
  2856 	//
       
  2857 	if ( !aIkeMsg->Encrypted() )
       
  2858 	{	
       
  2859 	   if ( iState == KStateIdle)
       
  2860 		  iStopped = ETrue;
       
  2861        return EFalse;
       
  2862 	}
       
  2863 	ThdrISAKMP* IkeHdr = aIkeMsg->GetIkeMsg();  // IKE Message fixed header
       
  2864 	TBool   Response   = IkeHdr->GetFlags() & IKEV2_RESPONSE_MSG;
       
  2865 	TUint32 MsgId      = IkeHdr->GetMessageId();
       
  2866 	
       
  2867     if ( Response )
       
  2868 	{
       
  2869 	   if ( (iState == KStateIkeInfoRequest) || (iState == KStateIkeDeleteRequest) )
       
  2870 	   {
       
  2871           //
       
  2872 		  // A response received to a transmitted Informational request
       
  2873 		  //
       
  2874 	      DEBUG_LOG(_L("Response received to a transmitted Informational request"));
       
  2875 	   
       
  2876 		  if ( MsgId == iHdr.ExpectedResponseId() )
       
  2877 		  {
       
  2878 			 iIkeV2PlugInSession.UpdateIkev2SAL(&iHdr, NULL);			 
       
  2879 			 if ( iState == KStateIkeDeleteRequest )
       
  2880 			 {	 
       
  2881 			    iIkeV2PlugInSession.IkeSaDeleted(KErrNone); //IKE SA deletion going
       
  2882 			 }	
       
  2883 			 else
       
  2884 			 {
       
  2885 				 if ( aIkeMsg->iNotifs->Count() )
       
  2886 				 {
       
  2887 					 ProcessNotifyPayloadsL(*aIkeMsg->iNotifs, EFalse, INFORMATIONAL);   
       
  2888 				 }
       
  2889 			 }
       
  2890 			 iStopped = ETrue;
       
  2891 			 return EFalse;
       
  2892 		  }
       
  2893 	   }
       
  2894 	   else if ( iState == KStateChildDeleteRequest )
       
  2895 	   {
       
  2896 		  //
       
  2897 		  // A response received to a transmitted Child SA delete request
       
  2898 		  //
       
  2899 		   if ( aIkeMsg->iDeletes->Count() )
       
  2900 		   {
       
  2901 			  ProcessDeletePayloadsL(*aIkeMsg->iDeletes, EFalse);   
       
  2902 		   }
       
  2903 		   
       
  2904 		   //
       
  2905 		   // Update sequence numbers and IKE SA data
       
  2906 		   //
       
  2907 		   iIkeV2PlugInSession.UpdateIkev2SAL(&iHdr, NULL);
       
  2908 		   iStopped = ETrue;		   
       
  2909 		   return EFalse;
       
  2910 	   }	   
       
  2911 	}
       
  2912 	else
       
  2913 	{
       
  2914 	   //
       
  2915 	   // A Informational request received. Process request according
       
  2916 	   // to payload content and send informational response.       
       
  2917 	   // 
       
  2918 	   DEBUG_LOG1(_L("INFORMATIONAL request received in state %d"), iState);
       
  2919 	   if ( MsgId == iHdr.ExpectedRequestId() )
       
  2920 	   {
       
  2921 		  TBool BuildResponse = ETrue;
       
  2922 		  if ( aIkeMsg->iDeletes->Count() )
       
  2923 		  {
       
  2924              BuildResponse = ProcessDeletePayloadsL(*aIkeMsg->iDeletes, ETrue);   
       
  2925 		  }
       
  2926 		  if ( aIkeMsg->iNotifs->Count() )
       
  2927 		  {
       
  2928 			 BuildResponse = ProcessNotifyPayloadsL(*aIkeMsg->iNotifs, ETrue, INFORMATIONAL);   
       
  2929 		  }
       
  2930 		  if ( BuildResponse )
       
  2931 		  {	  		                                
       
  2932               CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(),
       
  2933                                                           iHdr.SpiR(),
       
  2934                                                           INFORMATIONAL,
       
  2935                                                           iHdr.iInitiator,
       
  2936                                                           ETrue,
       
  2937                                                           iHdr.ExpectedRequestId(), 
       
  2938                                                           iDebug);
       
  2939              CleanupStack::PushL(ikeMsg);
       
  2940              ikeMsg->AppendEncryptedPayloadL(iHdr.iCipherBlkLth);            
       
  2941 		     CleanupStack::Pop(ikeMsg);
       
  2942 		     SendIkeMsgL(ikeMsg);
       
  2943              if ( (iState != KStateIkeInfoRequest) && (iState != KStateIkeDeleteRequest) && (iState != KStateIkeDeleteResponse) )
       
  2944                  {
       
  2945                  iState = KStateIkeInfoResponse;
       
  2946                  iIkeV2PlugInSession.UpdateIkev2SAL(&iHdr, NULL);
       
  2947                  }
       
  2948 		  }
       
  2949 	   }
       
  2950 	}	
       
  2951 
       
  2952 	return ETrue;
       
  2953 }
       
  2954 
       
  2955 TBool CIkev2Negotiation::ProcessNotifyPayloadsL(const CArrayFixFlat<TNotifPayloadIkev2*>& aNotifys, 
       
  2956                                                 TBool aRequest, TInt aExchange)
       
  2957 {
       
  2958 	if  ( Ikev2MobIke::ProcessNotifysL(this, aNotifys, aRequest, aExchange) )
       
  2959 	{	
       
  2960 		return EFalse; // Notify payload(s) was processed by MOBIKE protocol 
       
  2961 	}
       
  2962 	
       
  2963 	TInt MsgType;			
       
  2964 	TNotifPayloadIkev2* Payload;  
       
  2965 	TInt Count = aNotifys.Count();
       
  2966 	TInt i     = 0;
       
  2967 	
       
  2968 	while ( i < Count )
       
  2969 	{
       
  2970 	    Payload = aNotifys.At(i);
       
  2971 		MsgType = (TInt)Payload->GetMsgType();
       
  2972 		DEBUG_LOG1(_L("Received Notify payload message type %d"), MsgType);
       
  2973         // 
       
  2974 		//  Process possible error type Notify messages 
       
  2975 		//
       
  2976 		if (aExchange == IKE_SA_INIT)
       
  2977 		    {
       
  2978 		    switch ( MsgType )
       
  2979     		    {	
       
  2980     			case INVALID_SYNTAX:
       
  2981     			    //Fall through
       
  2982     			case NO_PROPOSAL_CHOSEN:
       
  2983     			    return EFalse;
       
  2984     		    case INVALID_KE_PAYLOAD:
       
  2985     		        ProcessInvalidKePayloadNotifyL();
       
  2986     		        return ETrue;
       
  2987     		    case COOKIE:
       
  2988     		    	return ProcessCookieL(aNotifys, aRequest);
       
  2989     			default:
       
  2990     				break;	
       
  2991     		    }
       
  2992 		    }
       
  2993 		else
       
  2994 		    {
       
  2995 		    switch ( MsgType )
       
  2996     		    {	
       
  2997     			case UNSUPPORTED_CRITICAL_PAYLOAD:
       
  2998     			case INVALID_SYNTAX:
       
  2999     			case INVALID_MESSAGE_ID:
       
  3000     			case AUTHENTICATION_FAILED:
       
  3001     			case INTERNAL_ADDRESS_FAILURE:
       
  3002     			case FAILED_CP_REQUIRED:
       
  3003     				//
       
  3004     				// When some of these error types received IKE SA shall
       
  3005     				// corresponding IKE SA shall be deleted
       
  3006     				//
       
  3007     				iDeleteIkeSA = ETrue;
       
  3008     				break;
       
  3009 
       
  3010     			case NO_PROPOSAL_CHOSEN:
       
  3011     			case SINGLE_PAIR_REQUIRED:
       
  3012     			case NO_ADDITIONAL_SAS:				
       
  3013     			case TS_UNACCEPTABLE:
       
  3014     			case INVALID_SELECTORS:
       
  3015     				//
       
  3016     				// When some of these error types received within
       
  3017     				// IKE_AUTH or CREATE_CHILD_SA exchange (in response)
       
  3018     				// Child SA request is interpreted to be failed 
       
  3019     				//
       
  3020     				if ( ((aExchange == IKE_AUTH) || (aExchange == CREATE_CHILD_SA) ) && !aRequest )
       
  3021     				   iChildSARejected = ETrue;
       
  3022     				break;
       
  3023     				
       
  3024     			default:
       
  3025     				break;	
       
  3026     		    }
       
  3027 		    }
       
  3028 	
       
  3029 	    i++;   
       
  3030 	}	
       
  3031 			
       
  3032 	return ETrue;
       
  3033 }
       
  3034 
       
  3035 TBool CIkev2Negotiation::ProcessCookieL(const CArrayFixFlat<TNotifPayloadIkev2*>& aNotifys, TBool aRequest)
       
  3036 {
       
  3037 
       
  3038 	//
       
  3039 	// Special handling for COOKIE Notify payload.
       
  3040 	// The following actions are taken:
       
  3041 	// - Assure that the first Notify payload in array is cookie
       
  3042 	// - When the COOKIE is received in response (aRequest = EFalse)
       
  3043 	//   - Retransmit IKE_SA_INIT request again in format:
       
  3044 	//     HDR(A,0), N(COOKIE), SAi1, KEi, Ni, [Nat Notifies]
       
  3045 	// - When the COOKIE is received in request (aRequest = ETrue)
       
  3046 	//   - Assure that COOKIE returned by the initiator is the we
       
  3047 	//     have earlier transmitted.  
       
  3048 	//			   		
       
  3049 	if ( aNotifys.Count() )
       
  3050 	{
       
  3051 		const TNotifPayloadIkev2* NotifyPayload = aNotifys.At(0);
       
  3052 		if ( NotifyPayload->GetMsgType() == COOKIE && !aRequest)
       
  3053 		{
       
  3054         //
       
  3055         // Local end COOKIE usage has not been implemented yet
       
  3056         //
       
  3057 
       
  3058           //
       
  3059           // Init a new IKE message buffer and copy received COOKIE
       
  3060           // Notify to the first payload. Concatenate then all
       
  3061           // payloads from original IKE_SA_INIT request to this new
       
  3062           // IKE message (and set next payload field in Notify)
       
  3063           //
       
  3064             DEBUG_LOG1(_L("Cookie received, IKE_SA_INIT repeated: %d"), iState);
       
  3065             if ( iCookieReturned )
       
  3066             {	
       
  3067                //
       
  3068                // One cookie already returned. Avoid cookie-loop
       
  3069                // by stopping ongoing IKE_SA_INIT exchange  
       
  3070                //
       
  3071                DEBUG_LOG(_L("Cookie already returned once, IKE_SA_INIT exchange stopped"));				   
       
  3072                return EFalse;
       
  3073             }		
       
  3074             CIkeV2Message* originalIkeSaInitRequest = iHdr.iLastRequest;            
       
  3075             const TPtrC8 cookieData(NotifyPayload->NotifData(), NotifyPayload->NotifDataLength());
       
  3076             originalIkeSaInitRequest->PrependCookieNotifyPayloadL(cookieData);
       
  3077             iHdr.iLastRequest = NULL; //claims the ownership of the message    
       
  3078             
       
  3079             SendIkeMsgL(originalIkeSaInitRequest);
       
  3080             iTimer->Cancel();    // Reset transmit retry timer                      
       
  3081             iTimer->IssueRequest(iSendAttempt);     // Start retry timer                        
       
  3082             iCookieReturned = ETrue;
       
  3083             return ETrue;
       
  3084         }
       
  3085 	}   
       
  3086 	DEBUG_LOG1(_L("Cookie required, NO COOKIE Notify found: %d"), iState);
       
  3087 	
       
  3088 	return EFalse;
       
  3089 }
       
  3090 
       
  3091 
       
  3092 
       
  3093 TBool CIkev2Negotiation::ProcessDeletePayloadsL(const CArrayFixFlat<TDeletePlIkev2*>& aDeletes, 
       
  3094                                                 TBool aRequest)
       
  3095 {
       
  3096 	//
       
  3097 	// Process delete payloads received.
       
  3098 	//
       
  3099 	CDesC8ArrayFlat* SpiList = NULL;
       
  3100 	TUint8  Protocol = IKEV2_PROT_NONE;
       
  3101 
       
  3102 	for (TInt i = 0; i < aDeletes.Count(); ++i)
       
  3103 	{
       
  3104 		const TDeletePlIkev2* Payload  = aDeletes.At(i);
       
  3105 		Protocol = Payload->GetProtocolId();
       
  3106 		switch ( Protocol )
       
  3107 		{
       
  3108 			case IKEV2_PROTOCOL:
       
  3109 				//
       
  3110 				// Deletion of current existing IKE SA. All IPSEC SA:s
       
  3111 				// negotiated within IKE SA are deleted implicitly 
       
  3112 				//
       
  3113 				iIkeV2PlugInSession.DeleteIkev2SA(iHdr.SaId());
       
  3114 				delete SpiList;
       
  3115 				SpiList = NULL;
       
  3116 				i = aDeletes.Count();   // Stop outer while loop
       
  3117 				iState = KStateIkeDeleteResponse;  // Set next state here
       
  3118 				break;
       
  3119 
       
  3120 			case IKEV2_IPSEC_AH:
       
  3121 			case IKEV2_IPSEC_ESP:
       
  3122 				if ( Payload->GetSPISize() == 4 )
       
  3123 				{
       
  3124 				   //
       
  3125 				   // Delete Ipsec SPI:s from IKE SA (and IPSEC SADB)
       
  3126 				   // If Delete payload received within Info request
       
  3127 				   // build inbound SPI list of corresponding inbound
       
  3128 				   // SA:s
       
  3129 				   //
       
  3130 				   TUint SpiCount = (TInt)Payload->GetNbrOfSpis();
       
  3131 				   if ( TPayloadIkev2::Cast(Payload)->GetLength() ==
       
  3132 					  ( TDeletePlIkev2::Size() + 4*SpiCount) )
       
  3133 				   {
       
  3134                       const TUint8* Spis = Payload->SPIs();
       
  3135 					  if ( aRequest && !SpiList )
       
  3136 					      {
       
  3137 					      SpiList = new (ELeave) CDesC8ArrayFlat(2);
       
  3138 					      CleanupStack::PushL(SpiList);
       
  3139 					      }
       
  3140 					  while ( SpiCount )
       
  3141 					  {	                            
       
  3142                           TPtrC8 Spi(Spis, 4);
       
  3143 						  if ( SpiList )
       
  3144 						  {	                               
       
  3145                              const TIkeV2IpsecSAData* IpsecSa = 
       
  3146                                  iIkeV2PlugInSession.FindIpsecSAData(iHdr.SaId(), Spi, EFalse);
       
  3147 							 if ( IpsecSa && IpsecSa->iSPI_In.Length() > 0 )
       
  3148 							 {                                
       
  3149                                 SpiList->AppendL(IpsecSa->iSPI_In);
       
  3150 							 }	
       
  3151 						  }	 
       
  3152 						  iIkeV2PlugInSession.DeleteIpsecSAData(iHdr.SaId(), Spi, EFalse);
       
  3153 						  Spis += 4;
       
  3154 						  SpiCount--;
       
  3155 					  }	  
       
  3156 				   }
       
  3157 				}   
       
  3158 				break;
       
  3159 			default:
       
  3160 			    break;				
       
  3161 		}
       
  3162 	}
       
  3163 		
       
  3164 	if ( SpiList )
       
  3165 	{
       
  3166 	    //
       
  3167 	    // Build Informational exchange response with a
       
  3168 	    // Delete payload containing SPI:s of corresponding
       
  3169 	    // inbound SA:s.  
       
  3170 	    //        
       
  3171         CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(),
       
  3172                                                     iHdr.SpiR(),
       
  3173                                                     INFORMATIONAL,
       
  3174                                                     iHdr.iInitiator,
       
  3175                                                     ETrue,
       
  3176                                                     iHdr.ExpectedRequestId(), iDebug);
       
  3177         CleanupStack::PushL(ikeMsg);
       
  3178         ikeMsg->AppendEncryptedPayloadL(iHdr.iCipherBlkLth);          
       
  3179         ikeMsg->AppendDeletePayloadL(Protocol, *SpiList);
       
  3180         CleanupStack::Pop(ikeMsg);
       
  3181         SendIkeMsgL(ikeMsg);
       
  3182     	CleanupStack::PopAndDestroy(SpiList); 
       
  3183 		iState = KStateIkeInfoResponse;		
       
  3184 		iIkeV2PlugInSession.UpdateIkev2SAL(&iHdr, NULL);
       
  3185 		aRequest = EFalse;
       
  3186 	}
       
  3187 		
       
  3188 	return aRequest;
       
  3189 }
       
  3190 
       
  3191 void CIkev2Negotiation::ProcessInvalidKePayloadNotifyL()
       
  3192 {
       
  3193     // Build and send new IKE_SA_INIT message (request) with another DH group #
       
  3194     // HDR, SAi1, KEi, Ni, N[NAT_SRC], N[NAT_DST]
       
  3195     //
       
  3196     iDHGroupGuess++;
       
  3197     delete iDHKeys;   // Delete old DH object 
       
  3198     iDHKeys = NULL;
       
  3199     iHdr.iDHGroup = 0;
       
  3200     
       
  3201     TUint32 lastRequestMsgId = 0;
       
  3202     if(iHdr.iLastRequest != NULL)
       
  3203         {
       
  3204         lastRequestMsgId = iHdr.iLastRequest->MessageId();
       
  3205         }    
       
  3206     
       
  3207     CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(),
       
  3208                                                 iHdr.SpiR(),
       
  3209                                                 IKE_SA_INIT,
       
  3210                                                 iHdr.iInitiator,
       
  3211                                                 EFalse,
       
  3212                                                 lastRequestMsgId,
       
  3213                                                 iDebug); 
       
  3214     CleanupStack::PushL(ikeMsg);
       
  3215 
       
  3216     HBufC8* saBfr = Ikev2Proposal::FromPolicyToProposaL(iHdr, iSPI_Rekey, iDHGroupGuess);
       
  3217     CleanupStack::PushL(saBfr);
       
  3218     ikeMsg->AppendSaPayloadL(*saBfr);
       
  3219     CleanupStack::Pop(saBfr);
       
  3220     SetProposedSa(saBfr);
       
  3221 
       
  3222     AppendKEPayloadL(*ikeMsg, iHdr.iDHGroup);
       
  3223     ikeMsg->AppendNoncePayloadL(*iNonce_I);
       
  3224     if ( !iHdr.iIkeData->iUseNatProbing )
       
  3225         {
       
  3226         delete iNatNotify;
       
  3227         iNatNotify = NULL;
       
  3228         
       
  3229         TInetAddr LocalIp;  
       
  3230         if ( iHdr.iIkeData->iUseMobIke )
       
  3231             LocalIp.SetAddress(KInetAddrNone);
       
  3232         else LocalIp = iHdr.iLocalAddr;        
       
  3233         iNatNotify = CIkev2NatT::NewL(
       
  3234             LocalIp, iHdr.iRemoteAddr, IKE_PORT, ikeMsg->InitiatorSpi(), ikeMsg->ResponderSpi());
       
  3235                        
       
  3236         ikeMsg->AppendNotifyPayloadL(IKEV2_PROTOCOL, KZeroDesc, NAT_DETECTION_SOURCE_IP, 
       
  3237                                      iNatNotify->SourceNofify());
       
  3238         ikeMsg->AppendNotifyPayloadL(IKEV2_PROTOCOL, KZeroDesc, NAT_DETECTION_DESTINATION_IP, 
       
  3239                                      iNatNotify->DestinNofify());         
       
  3240         }   
       
  3241           
       
  3242     CleanupStack::Pop(ikeMsg);
       
  3243     SendIkeMsgL(ikeMsg);
       
  3244     
       
  3245     iState = KStateIkeSaInitRequest;
       
  3246 }
       
  3247 
       
  3248 
       
  3249 
       
  3250 void CIkev2Negotiation::GetNonceDataL(TBool aInitiator)
       
  3251 {
       
  3252 	//
       
  3253 	//  Get random data for local nonce
       
  3254 	//
       
  3255 	HBufC8* Nonce;
       
  3256 	if ( aInitiator )
       
  3257 	{
       
  3258 		Nonce = HBufC8::NewL(IKEV2_DEF_NONCE_SIZE);
       
  3259 		delete iNonce_I;		
       
  3260 		iNonce_I = Nonce;
       
  3261 	}
       
  3262 	else
       
  3263 	{
       
  3264 		Nonce = HBufC8::NewL(IKEV2_DEF_NONCE_SIZE);
       
  3265 		delete iNonce_R;		
       
  3266 		iNonce_R = Nonce;
       
  3267 	}
       
  3268     TPtr8 RandOctet(Nonce->Des());	
       
  3269     RandOctet.SetLength(IKEV2_DEF_NONCE_SIZE);
       
  3270     TRandom::RandomL(RandOctet);
       
  3271 }
       
  3272 
       
  3273 void CIkev2Negotiation::GetOwnIdentityL(TBool aEapIdResponse)
       
  3274 {
       
  3275     if ( iLocalIdentity )
       
  3276     {
       
  3277         return;   // We already have own identity data
       
  3278     }      
       
  3279 
       
  3280     //
       
  3281     // The own IKE identity data is built with the following system:
       
  3282     // -- If Own Certificate exist take try to get identity data from it
       
  3283     // If no Certificate or identity cannot be get from certificate
       
  3284     // -- If EAP used use identity speficied by the EAP plugin
       
  3285     // -- If EAP not used, get own identity data information from current IKE policy
       
  3286     // If no identity information found use local IP address as
       
  3287     // identity.  Own IKE Identity information is stored in iLocalIdentity
       
  3288     // buffer (linked into negotiation object) in format of Identity
       
  3289     // payload (TIDPayloadIkev2)
       
  3290     //
       
  3291   
       
  3292 
       
  3293     HBufC8* IdBfr = NULL;
       
  3294     TUint8 IdType = ID_NOT_DEFINED;  
       
  3295     
       
  3296     
       
  3297     //Try to get the identity from the user certificate
       
  3298     if ( iPkiService && iPkiService->UserCertificateData().Length() > 0  )
       
  3299     {
       
  3300        IdType = iHdr.iIkeData->iIdType;
       
  3301        IdBfr  = IkePkiUtils::GetIdentityFromCertL(IdType, iPkiService->UserCertificateData());
       
  3302        if ( IdBfr != NULL)
       
  3303        {
       
  3304            if (IdType == ID_NOT_DEFINED)
       
  3305            {
       
  3306                IdType = ID_DER_ASN1_DN;
       
  3307            }
       
  3308        }   
       
  3309        else
       
  3310        {
       
  3311            //We didn't get the ID data from the user certificate.
       
  3312            //Make sure that the type is set to not defined.
       
  3313            IdType = ID_NOT_DEFINED;
       
  3314        }
       
  3315     }
       
  3316     
       
  3317     //If we didn't get the identity from the user certificate,
       
  3318     //try to get it from the EAP plugin. 
       
  3319     if ( IdType == ID_NOT_DEFINED && iEapPlugin )
       
  3320     {
       
  3321         __ASSERT_DEBUG(IdBfr == NULL, User::Invariant());
       
  3322         //
       
  3323         // Try to get Own identity data from EAP Plug-in
       
  3324         //
       
  3325         IdBfr = iEapPlugin->Identity();
       
  3326         if ( IdBfr != NULL && IdBfr->Length() )
       
  3327         {
       
  3328             //
       
  3329             // Identity data provided by EAP plug-in. Define IKE Id type
       
  3330             // value according to Identity data content. If Id data
       
  3331             // contains realm (format username@realm) Id type
       
  3332             // ID_RFC822_ADDR  is used. If no realm in ID use type ID_KEY_ID
       
  3333             //
       
  3334             TInt offset = IdBfr->Find(_L8("@"));
       
  3335             IdType = ( offset == KErrNotFound ) ? ID_KEY_ID : ID_RFC822_ADDR; 
       
  3336         }   
       
  3337         else
       
  3338         {
       
  3339             delete IdBfr;
       
  3340             IdBfr = NULL;
       
  3341             if ( !aEapIdResponse )
       
  3342                 return;   // Identity not yet available continue waiting             
       
  3343         }   
       
  3344     }
       
  3345     
       
  3346     //If we don't have identity so far, try to get it from the
       
  3347     //policy:
       
  3348     if ( IdType == ID_NOT_DEFINED && 
       
  3349          iHdr.iIkeData->iIdType != ID_NOT_DEFINED &&
       
  3350          iHdr.iIkeData->iFQDN.Length() > 0)
       
  3351     {   
       
  3352         __ASSERT_DEBUG(IdBfr == NULL, User::Invariant());
       
  3353         IdBfr = HBufC8::NewL(iHdr.iIkeData->iFQDN.Length());
       
  3354         IdBfr->Des().Copy(iHdr.iIkeData->iFQDN);
       
  3355         IdType = iHdr.iIkeData->iIdType;            
       
  3356     }
       
  3357     
       
  3358     
       
  3359     //If we have not been able to get the identity so far, we are using the default
       
  3360     //identity, which is our own IP address.
       
  3361     if ( IdType == ID_NOT_DEFINED)
       
  3362     {
       
  3363         __ASSERT_DEBUG(IdBfr == NULL, User::Invariant());
       
  3364         if ( (iHdr.iLocalAddr.Family()== KAfInet) || iHdr.iLocalAddr.IsV4Mapped() )
       
  3365         {
       
  3366             TUint32 num = ByteOrder::Swap32(iHdr.iLocalAddr.Address());//Put in network order
       
  3367             IdBfr = HBufC8::NewL(sizeof(num));            
       
  3368             IdBfr->Des().Append(reinterpret_cast<TUint8*>(&num), sizeof(num));
       
  3369             IdType = ID_IPV4_ADDR;    
       
  3370         }
       
  3371         else   
       
  3372         {
       
  3373             IdBfr = HBufC8::NewL(16);  
       
  3374             const TUint8* pnum = &iHdr.iLocalAddr.Ip6Address().u.iAddr8[0];  //Address in a bytestream
       
  3375             IdBfr->Des().Append(pnum, 16);
       
  3376             IdType = ID_IPV6_ADDR;                      
       
  3377         }          
       
  3378     }
       
  3379     
       
  3380     __ASSERT_DEBUG((IdType != ID_NOT_DEFINED && IdBfr != NULL), User::Invariant());
       
  3381     CleanupStack::PushL(IdBfr);
       
  3382     iLocalIdentity = CIkeV2Identity::NewL(IdType, *IdBfr);
       
  3383     CleanupStack::PopAndDestroy(IdBfr); 
       
  3384 }
       
  3385 
       
  3386 
       
  3387 void CIkev2Negotiation::GenerateIkeKeysL(TIkev2SAData* aRekeydSaData)
       
  3388 {
       
  3389 	//
       
  3390 	//  Generate IKE keying material. Start by calculating
       
  3391 	//  Diffie-Hellman secret.
       
  3392 	//
       
  3393 	User::LeaveIfNull(iDHPublicPeer);		
       
  3394 	if ( !iDHKeys )
       
  3395 	{	
       
  3396 		iDHKeys = CDHKeys::CreateDHKeyL(iHdr.iDHGroup);
       
  3397 		iDHKeys->XValueL(); // Calculate own DH public value	   
       
  3398 	}
       
  3399 	HBufC8* g_ir = iDHKeys->ComputeAgreedKeyL(iDHPublicPeer->Des());
       
  3400 	CleanupStack::PushL(g_ir);
       
  3401 	delete iDHKeys;
       
  3402 	iDHKeys = NULL;
       
  3403 
       
  3404 	HBufC8* Ni_Nr;
       
  3405 	HBufC8* SKEYSEED;
       
  3406 	TUint16 prfAlg(0);
       
  3407 	
       
  3408 	if ( aRekeydSaData )
       
  3409 	{
       
  3410 	    //
       
  3411 	    //  Calculate IKE keying material seed SKEYDSEED = prf(SK_d(old), [g^ir (new)] | Ni | Nr) 
       
  3412         //
       
  3413 		Ni_Nr = HBufC8::NewL(g_ir->Length() + iNonce_I->Length() + iNonce_R->Length());
       
  3414 		CleanupStack::PushL(Ni_Nr);		
       
  3415 		Ni_Nr->Des().Copy(g_ir->Des());		
       
  3416 		Ni_Nr->Des().Append(iNonce_I->Des());
       
  3417 		Ni_Nr->Des().Append(iNonce_R->Des());	
       
  3418 
       
  3419 		prfAlg = aRekeydSaData->iPRFAlg;
       
  3420 		SKEYSEED = IkeCrypto::PrfhmacL(*Ni_Nr, aRekeydSaData->iSK_d, prfAlg);
       
  3421 		CleanupStack::PushL(SKEYSEED);
       
  3422 	}
       
  3423 	else
       
  3424 	{	
       
  3425 	    //
       
  3426 	    //  Calculate IKE keying material seed SKEYDSEED = prf(Ni | Nr, g^ir)
       
  3427 	    //
       
  3428 		Ni_Nr = HBufC8::NewL(iNonce_I->Length() + iNonce_R->Length());
       
  3429 		CleanupStack::PushL(Ni_Nr);
       
  3430 		Ni_Nr->Des().Copy(iNonce_I->Des());
       
  3431 		Ni_Nr->Des().Append(iNonce_R->Des());	
       
  3432 		
       
  3433 		prfAlg = iHdr.iPRFAlg;
       
  3434 		SKEYSEED = IkeCrypto::PrfhmacL(*g_ir, *Ni_Nr, prfAlg);
       
  3435 		CleanupStack::PushL(SKEYSEED);		
       
  3436 	}  
       
  3437 
       
  3438 	g_ir->Des().FillZ(); // Wipe out shared secret value from buffer
       
  3439 	
       
  3440 	iHdr.GenerateIkeKeyDerivatesL(SKEYSEED->Des(),prfAlg, *iNonce_I, *iNonce_R);	
       
  3441 	SKEYSEED->Des().FillZ(); // Wipe out SKEYSEED value from buffer	
       
  3442 	
       
  3443 	CleanupStack::PopAndDestroy(3);  //g_ir , Ni_Nr and SKEYSEED
       
  3444 }
       
  3445 
       
  3446 
       
  3447 void CIkev2Negotiation::SaveSignedDataL(TBool aLocal,  const TDesC8& aIkeMsg)
       
  3448 { 
       
  3449 	//
       
  3450 	//  Allocate buffer for signed octets needed for IKE SA
       
  3451 	//  authentication with AUTH payload.
       
  3452 	//  The signed octet contains the following data:
       
  3453 	//  Initiator:
       
  3454 	//  - IKE_SA_INIT message content (message number 1)
       
  3455 	//    concatenated with responder nonce data and value
       
  3456 	//    prf(SK_pi,IDi") where IDi" is initiator ID data without fixed
       
  3457 	//    payload header
       
  3458 	//
       
  3459 	//  Responder:
       
  3460 	//  - IKE_SA_INIT message content (message number 2)
       
  3461 	//    concatenated with initiator nonce data and value
       
  3462 	//    prf(SK_pr,IDr") where IDr" is responder ID data without fixed
       
  3463 	//    payload header
       
  3464 	//
       
  3465 	TInt SignedLth = aIkeMsg.Length(); // Initial value
       
  3466 	HBufC8*  Nonce;
       
  3467 	HBufC8** SignedBfrPtr;	
       
  3468 	if ( aLocal )
       
  3469 	{	
       
  3470 	   if ( iHdr.iInitiator )
       
  3471 	   {
       
  3472 		  SignedBfrPtr = &iAuthMsgInit;
       
  3473 	 	  Nonce = iNonce_R;
       
  3474 	   }	  
       
  3475 	   else {
       
  3476 		  SignedBfrPtr = &iAuthMsgResp;		   
       
  3477 		  Nonce = iNonce_I;
       
  3478 	   }		  
       
  3479 	}
       
  3480 	else
       
  3481 	{
       
  3482 	   if ( iHdr.iInitiator )
       
  3483 	   {
       
  3484 		  SignedBfrPtr = &iAuthMsgResp;		   
       
  3485 		  Nonce = iNonce_I;
       
  3486 	   }		
       
  3487 	   else
       
  3488 	   {
       
  3489 		  SignedBfrPtr = &iAuthMsgInit;		   
       
  3490 		  Nonce = iNonce_R;
       
  3491 	   }	  
       
  3492 	}
       
  3493 
       
  3494 	SignedLth += Nonce->Length() + IkeCrypto::AlgorithmInfo(IKEV2_PRF, iHdr.iPRFAlg);
       
  3495 	HBufC8* Signed = HBufC8::NewL(SignedLth);
       
  3496 	Signed->Des().Copy(aIkeMsg);
       
  3497 	Signed->Des().Append(Nonce->Des());
       
  3498 	
       
  3499 	if ( aLocal && iLocalIdentity )
       
  3500 	{
       
  3501 	   //
       
  3502 	   // Add value prf(SK_px,IDx") into local signed data buffer end
       
  3503 	   //
       
  3504 	   AddIdToSignedDataL(ETrue, Signed, iLocalIdentity->PayloadData());
       
  3505 	}
       
  3506 	
       
  3507 	delete *SignedBfrPtr;
       
  3508 	*SignedBfrPtr = Signed;
       
  3509 }
       
  3510 
       
  3511 
       
  3512 void CIkev2Negotiation::AddIdToSignedDataL(TBool aLocal, HBufC8* aSigned, const TDesC8& aIdData)
       
  3513 {
       
  3514     ASSERT(aSigned);
       
  3515     //
       
  3516     // Add value prf(SK_px,IDx") into signed data buffer end
       
  3517     //
       
  3518 
       
  3519 	HBufC8* signedIdData = NULL;;
       
  3520 	if ( iHdr.iInitiator )
       
  3521 	{
       
  3522 		if ( aLocal )
       
  3523 		    {
       
  3524 		    signedIdData = IkeCrypto::PrfhmacL(aIdData, iHdr.iSK_pi, iHdr.iPRFAlg);
       
  3525 		    }
       
  3526 		else 
       
  3527 		    {
       
  3528 		    signedIdData = IkeCrypto::PrfhmacL(aIdData, iHdr.iSK_pr, iHdr.iPRFAlg);
       
  3529 		    }
       
  3530 	}		
       
  3531 	else
       
  3532 	{
       
  3533 		if ( aLocal )
       
  3534 		    {
       
  3535 		    signedIdData = IkeCrypto::PrfhmacL(aIdData, iHdr.iSK_pr, iHdr.iPRFAlg);
       
  3536 		    }
       
  3537 		else 
       
  3538 		    {
       
  3539 		    signedIdData = IkeCrypto::PrfhmacL(aIdData, iHdr.iSK_pi, iHdr.iPRFAlg);
       
  3540 		    }
       
  3541 	}
       
  3542 	aSigned->Des().Append(*signedIdData);
       
  3543 	delete signedIdData;	
       
  3544 }	
       
  3545 
       
  3546 HBufC8* CIkev2Negotiation::SignAuthDataL(const TDesC8& aAuthData, TUint8 aAuthMethod)
       
  3547 {
       
  3548 	//
       
  3549 	//  Sign aMsgData according to authentication method parameter
       
  3550 	//
       
  3551 	HBufC8* signedAuthData = NULL;
       
  3552 	
       
  3553 	if ( iPkiService && 
       
  3554 	     iPkiService->TrustedCaName().Length() > 0 &&
       
  3555 	     iPkiService->UserCertificateData().Length() > 0 )
       
  3556 	{		
       
  3557 	   //
       
  3558 	   // Message data <msg octets> is signed using private key
       
  3559 	   //		
       
  3560 		TPtrC8 TrustedCa(iPkiService->TrustedCaName());
       
  3561 		signedAuthData = HBufC8::NewLC(320); // reserved for sign (aware for 2048 bits signatures)
       
  3562 		TPtr8 signedAuthDataPtr(signedAuthData->Des()); 
       
  3563 		
       
  3564 		iPkiService->Ikev2SignatureL(TrustedCa, iHdr.iIkeData->iOwnCert, aAuthData, signedAuthDataPtr, aAuthMethod);
       
  3565 		CleanupStack::Pop(signedAuthData);
       
  3566 	}
       
  3567 	else		
       
  3568 	{
       
  3569 	   //
       
  3570 	   // Message data is signed using negotiated PRF function as
       
  3571 	   // follows:
       
  3572 	   // AUTH =
       
  3573 	   // prf(prf(Shared Secret,"Key Pad for IKEv2"), <msg octets>)
       
  3574 	   // If EAP method that creates a shared key as a side effect of
       
  3575 	   // authentication used, this shared key is used as Shared Secret
       
  3576 	   // Otherwise preshared key configured into policy is used as
       
  3577 	   // Shared secret.
       
  3578 	   //
       
  3579 	   if ( !iPresharedKey )
       
  3580 		  iPresharedKey = Ikev2Proposal::GetPSKFromPolicyL(iHdr.iIkeData);
       
  3581 	   //
       
  3582 	   // Calculate KEY = prf(Shared Secret,"Key Pad for IKEv2")
       
  3583 	   //   			
       
  3584 	   HBufC8* PskKey = IkeCrypto::PrfhmacL(KIkev2PSKData, *iPresharedKey, iHdr.iPRFAlg);
       
  3585 	   CleanupStack::PushL(PskKey);
       
  3586 	   //
       
  3587 	   // Calculate prf(KEY, <msg octets>)
       
  3588 	   //       	   
       
  3589 	   signedAuthData = IkeCrypto::PrfhmacL(aAuthData, *PskKey, iHdr.iPRFAlg);
       
  3590  	   CleanupStack::PopAndDestroy(PskKey);
       
  3591 	}
       
  3592 	return signedAuthData;		
       
  3593 }
       
  3594 
       
  3595 TBool CIkev2Negotiation::AddIdAndAuthenticatePeerL(CIkev2Payloads* aIkeMsg)
       
  3596 {
       
  3597     ASSERT(aIkeMsg);
       
  3598 	//
       
  3599 	// Verify that authentication payload of peer is correct
       
  3600 	// To do this the signed data octets of peer must be filled with
       
  3601 	// value: prf(SK_px,IDx")
       
  3602 	// So the peer ID payload must be verified first.
       
  3603 	//
       
  3604 	HBufC8* Signed;
       
  3605 	TIDPayloadIkev2* Id;
       
  3606 	if ( iHdr.iInitiator )
       
  3607 	{
       
  3608 	   Signed = iAuthMsgResp;	
       
  3609 	   Id = (TIDPayloadIkev2*)aIkeMsg->iIdR;
       
  3610 	}   
       
  3611 	else
       
  3612 	{
       
  3613 	   Signed = iAuthMsgInit;			
       
  3614 	   Id = (TIDPayloadIkev2*)aIkeMsg->iIdI;
       
  3615 	}	
       
  3616     if ( !Signed || !Id )
       
  3617 	   return EFalse;	
       
  3618 
       
  3619 	if ( !iPeerIdInSignedData )
       
  3620 	{	
       
  3621 	   TUint16 IdLth = TPayloadIkev2::Cast(Id)->GetLength();
       
  3622 	   if ( IdLth < TIDPayloadIkev2::Size() ) 
       
  3623 	   {
       
  3624 		  DEBUG_LOG1(_L("Peer ID payload too short; Length %d"), IdLth);		  
       
  3625 		  return EFalse;
       
  3626 	   }
       
  3627        //
       
  3628 	   // Add value prf(SK_px,IDx") into peer signed data buffer end
       
  3629 	   //
       
  3630 	   TPayloadIkev2* idPayload = TPayloadIkev2::Cast(Id);
       
  3631 	   TPtrC8 idPtr(idPayload->PayloadData(), (idPayload->GetLength() - TPayloadIkev2::Size()));
       
  3632 	   AddIdToSignedDataL(EFalse, Signed, idPtr);
       
  3633 	   iPeerIdInSignedData = ETrue;
       
  3634 	}
       
  3635 	
       
  3636 	return AuthenticatePeerL(aIkeMsg->iAuth); 
       
  3637 
       
  3638 }
       
  3639 
       
  3640 TBool CIkev2Negotiation::AuthenticatePeerL(TAuthPayloadIkev2* aAuth)
       
  3641 {
       
  3642 	//
       
  3643 	// Authenticate peer tication payload of peer is correct
       
  3644 	// To do this the signed data octets of peer must be filled with
       
  3645 	// value: prf(SK_px,IDx")
       
  3646 	// So the peer ID payload must be verified first.
       
  3647 	//
       
  3648 	HBufC8* Signed;	
       
  3649 	if ( iHdr.iInitiator )
       
  3650 		 Signed = iAuthMsgResp;	
       
  3651 	else Signed = iAuthMsgInit;
       
  3652 	
       
  3653 	if ( !Signed || !aAuth )
       
  3654 	   return EFalse;
       
  3655 
       
  3656 	TUint16 AuthLth = TPayloadIkev2::Cast(aAuth)->GetLength();	
       
  3657 	if ( AuthLth < TAuthPayloadIkev2::Size() ) 
       
  3658 	{					
       
  3659 		DEBUG_LOG1(_L("Peer Auth payload too short; Length %d"), AuthLth);
       
  3660 		return EFalse;
       
  3661 	}
       
  3662 	AuthLth = (TUint16)(AuthLth - TAuthPayloadIkev2::Size());
       
  3663 	TBool Status = EFalse;
       
  3664 	
       
  3665 	if ( aAuth->GetAuthMethod() == PRESHARED_KEY )
       
  3666 	{
       
  3667        DEBUG_LOG(_L("Authenticating SGW with PSK"));
       
  3668 	   //
       
  3669 	   // Pre shared key authentication is not accepted for peer if we
       
  3670 	   // have requested an certificate from peer (PKI authentication
       
  3671 	   // required) 
       
  3672 	   // 
       
  3673 		if ( !iPkiAuthRequired )
       
  3674 		{
       
  3675 			HBufC8* AuthRef = SignAuthDataL(*Signed, PRESHARED_KEY);
       
  3676 			CleanupStack::PushL(AuthRef);			
       
  3677 			if (  AuthRef->Length() == AuthLth )
       
  3678 			{
       
  3679 				Status = (Mem::Compare(AuthRef->Ptr(), AuthRef->Length(), aAuth->AuthData(), AuthLth ) == 0);		   
       
  3680 			}
       
  3681 			CleanupStack::PopAndDestroy();   // AuthRef			
       
  3682 		}	  
       
  3683 	}
       
  3684 	else
       
  3685 	{
       
  3686 	   //
       
  3687 	   // Authentication based on PKI (private key signature)
       
  3688 	   // 
       
  3689 		if ( iPkiService && iPeerCert )
       
  3690 		{
       
  3691 		    DEBUG_LOG(_L("Authenticating SGW with certs"));
       
  3692 		    
       
  3693 			TPtrC8 AuthData(Signed->Des());
       
  3694 			TPtrC8 Signature(aAuth->AuthData(), AuthLth);	   						
       
  3695 			Status = IkePkiUtils::VerifyIkev2SignatureL(Signature, AuthData, *iPeerCert);
       
  3696 			iPkiAuthRequired = EFalse;
       
  3697 		}			  
       
  3698 	}
       
  3699 	if (Status)
       
  3700 	    {
       
  3701 	    DEBUG_LOG(_L("SGW authentication success"));
       
  3702 	    }
       
  3703 	else
       
  3704 	    {
       
  3705 	    DEBUG_LOG(_L("SGW authentication failed"));
       
  3706 	    }
       
  3707 	
       
  3708 	return Status; 
       
  3709 }
       
  3710 
       
  3711 
       
  3712 TBool CIkev2Negotiation::VerifyPeerCertificateL(CArrayFixFlat<TCertPayloadIkev2*>* aCerts, TIDPayloadIkev2* aId )
       
  3713 {
       
  3714 	TBool Status        = EFalse;
       
  3715 	
       
  3716 	const CIkeCaList& trustedCaList = iPkiService->CaList();
       
  3717 	CX509Certificate* PeerCert = IkePkiUtils::VerifyCertificateL(*aCerts, trustedCaList);
       
  3718 	
       
  3719 	if ( PeerCert && aId )
       
  3720 	{
       
  3721 		CleanupStack::PushL(PeerCert);					 		
       
  3722 		TPtrC8 IdData(aId->IdData(), (TPayloadIkev2::Cast(aId)->GetLength() - TIDPayloadIkev2::Size()));	
       
  3723 		Status = IkePkiUtils::CertifyIdentityL(PeerCert, IdData, (TInt)aId->GetIdType());
       
  3724 		if ( Status )
       
  3725 		{
       
  3726 		    DEBUG_LOG(_L("IDr matches the SGW certificate"));
       
  3727 		    if (iRemoteIdentity && !iHdr.iIkeData->iSkipRemoteIdCheck ) //iRemoteIdentity if the REMOTE_IF from the policy
       
  3728 		        {
       
  3729 		        //TIDPayloadIkev2* peerIdentityPayload = TIDPayloadIkev2::Cast(iRemoteIdentity->Ptr());  
       
  3730 		        if (iRemoteIdentity->IdType() == aId->GetIdType())
       
  3731 		            {
       
  3732 		            TPtrC8 idPtr(aId->IdData(),
       
  3733 		                         TPayloadIkev2::Cast(aId)->GetLength() - TIDPayloadIkev2::Size());
       
  3734 		            TPtrC8 peerIdentityPtr(iRemoteIdentity->Identity());
       
  3735 		            
       
  3736 		            //Check if we accept partial remote id
       
  3737 		            if (iHdr.iIkeData->iAcceptPartialRemoteId && 
       
  3738 		                iRemoteIdentity->IdType() == ID_FQDN &&
       
  3739 		                peerIdentityPtr.Length() > idPtr.Length())
       
  3740 		                {
       
  3741 		                DEBUG_LOG(_L("Using PARTIAL_REMOTE_ID_CHECK"));
       
  3742 		                peerIdentityPtr.Set(peerIdentityPtr.Right(idPtr.Length()));
       
  3743 		                }
       
  3744 		            if (idPtr.Compare(peerIdentityPtr) == 0)
       
  3745 		                {
       
  3746 		                DEBUG_LOG(_L("IDr matches the REMOTE_ID"));
       
  3747 		                Status = ETrue;
       
  3748 		                }
       
  3749 		            else
       
  3750 		                {
       
  3751 		                DEBUG_LOG(_L("IDr does not match the REMOTE_ID"));
       
  3752 		                Status = EFalse;
       
  3753 		                }
       
  3754 		            }		        
       
  3755 		        else
       
  3756 		            {
       
  3757 		            DEBUG_LOG(_L("IDr payload ID does not match REMOTE_ID_TYPE"));
       
  3758 		            Status = EFalse;
       
  3759 		            }
       
  3760 		        }
       
  3761 		}	
       
  3762 	    else 
       
  3763 	    {
       
  3764 	        DEBUG_LOG(_L("IDr does not match the SGW certificate"));
       
  3765 	    }
       
  3766 		
       
  3767 		if ( Status )
       
  3768 		{
       
  3769 		   CleanupStack::Pop(PeerCert);		
       
  3770 		   delete iPeerCert;
       
  3771 		   iPeerCert = PeerCert;			
       
  3772 		}
       
  3773 		else CleanupStack::PopAndDestroy(PeerCert);
       
  3774 	}
       
  3775 	return Status;
       
  3776 }
       
  3777 
       
  3778 
       
  3779 TBool CIkev2Negotiation::ProcessKeyExchangeL(TKEPayloadIkev2* aKePayload, TUint16 aGroup)
       
  3780 {
       
  3781 	//
       
  3782 	//  Process key exchange payload received from peer
       
  3783 	//
       
  3784 	if ( !aKePayload )
       
  3785 	{
       
  3786 		DEBUG_LOG1(_L("Key Exchange payload not present, required Group %d"), aGroup);
       
  3787 		SetNotifyCode(INVALID_KE_PAYLOAD);
       
  3788 		StoreNotifyData16(aGroup);
       
  3789 		return EFalse;
       
  3790 	}	 
       
  3791 	TUint16 PlLth = TPayloadIkev2::Cast(aKePayload)->GetLength();
       
  3792 	if (( PlLth <= TKEPayloadIkev2::Size() ) || ( aKePayload->GetDHGroup() != aGroup ))
       
  3793 	{
       
  3794 		DEBUG_LOG1(_L("Peer Key Exchange DH group does not match, Group %d"), aKePayload->GetDHGroup());
       
  3795 		SetNotifyCode(INVALID_KE_PAYLOAD);
       
  3796 		StoreNotifyData16(aGroup);
       
  3797 	    return EFalse;
       
  3798 	}	
       
  3799 	if ( !iDHKeys )
       
  3800 		iDHKeys = CDHKeys::CreateDHKeyL(aGroup);
       
  3801 	PlLth = (TUint16)(PlLth - TKEPayloadIkev2::Size());
       
  3802 	if ( PlLth != iDHKeys->ModulusLength() )
       
  3803 	{
       
  3804 		DEBUG_LOG1(_L("Peer DH public value length does not match group, Length %d"), PlLth);
       
  3805 		SetNotifyCode(INVALID_KE_PAYLOAD);
       
  3806         StoreNotifyData16(aGroup);
       
  3807 		return EFalse;
       
  3808 	}	
       
  3809 	delete iDHPublicPeer;
       
  3810 	iDHPublicPeer = NULL;
       
  3811 	iDHPublicPeer = HBufC8::NewL(PlLth);
       
  3812 	iDHPublicPeer->Des().Copy(aKePayload->DHPublic(), PlLth);
       
  3813 
       
  3814 	return ETrue;
       
  3815 }
       
  3816 
       
  3817 void CIkev2Negotiation::AppendKEPayloadL(CIkeV2Message& aIkeMsg, TUint16 aDHGroup)
       
  3818 {    
       
  3819 	if ( !iDHKeys )
       
  3820        iDHKeys = CDHKeys::CreateDHKeyL(aDHGroup);
       
  3821 
       
  3822 	iDHKeys->XValueL(); // Calculate own DH public value
       
  3823 	HBufC8* dHPublic = iDHKeys->GetPubKey();    //save the public key in a buffer to have easy access
       
  3824 	User::LeaveIfNull(dHPublic);
       
  3825 	CleanupStack::PushL(dHPublic);
       
  3826 	
       
  3827 	TInt modulusLength = iDHKeys->ModulusLength();	
       
  3828 	HBufC8* kePayloadData = HBufC8::NewLC(modulusLength);
       
  3829 	TPtr8 kePayloadDataPtr(kePayloadData->Des());
       
  3830 	
       
  3831 	__ASSERT_DEBUG(modulusLength == dHPublic->Length(), User::Invariant());	
       
  3832 
       
  3833 	kePayloadDataPtr.Append(*dHPublic);	
       
  3834 	kePayloadDataPtr.SetLength(modulusLength); //adds zero padding, if needed
       
  3835 
       
  3836 	aIkeMsg.AppendKePayloadL(aDHGroup, *kePayloadData);
       
  3837 	
       
  3838 	CleanupStack::PopAndDestroy(kePayloadData);  
       
  3839 	CleanupStack::PopAndDestroy(dHPublic);
       
  3840 }
       
  3841 
       
  3842      
       
  3843 
       
  3844 TBool CIkev2Negotiation::CheckPayloadsOrder(CIkev2Payloads* aIkeMsg, TUint8 aExchange, TBool aResponse)
       
  3845     {
       
  3846 	switch ( aExchange )
       
  3847 	    {
       
  3848 		case IKE_SA_INIT:
       
  3849 		    if(!aIkeMsg->iSa || !aIkeMsg->iKe || !aIkeMsg->iNonce) return EFalse;
       
  3850             if(aIkeMsg->iSa->GetNextPayload() != IKEV2_PAYLOAD_KE) return EFalse;
       
  3851             if(aIkeMsg->iKe->GetNextPayload() != IKEV2_PAYLOAD_NONCE) return EFalse;
       
  3852 			break;
       
  3853 			
       
  3854 		case IKE_AUTH:
       
  3855 		    if(!iEapPlugin)
       
  3856 		        {
       
  3857 		        if(!aIkeMsg->iEncr || !aIkeMsg->iAuth || !aIkeMsg->iSa || !aIkeMsg->iTsI || !aIkeMsg->iTsR)
       
  3858 		            {
       
  3859            		    DEBUG_LOG(_L("1"));
       
  3860 		            return EFalse;
       
  3861 		            }
       
  3862                 if(aIkeMsg->iSa->GetNextPayload() != IKEV2_PAYLOAD_TS_I)
       
  3863                     {
       
  3864            		    DEBUG_LOG(_L("2"));                    
       
  3865                     return EFalse;
       
  3866                     }
       
  3867                 if(aIkeMsg->iTsI->GetNextPayload() != IKEV2_PAYLOAD_TS_R)
       
  3868                     {
       
  3869            		    DEBUG_LOG(_L("3"));      
       
  3870                     return EFalse;
       
  3871                     }
       
  3872 
       
  3873 		        if(aResponse)
       
  3874 		            {
       
  3875 		            if(!aIkeMsg->iIdR)
       
  3876 		                {
       
  3877            		        DEBUG_LOG(_L("4"));		                
       
  3878 		                return EFalse;
       
  3879 		                }
       
  3880                     if(!aIkeMsg->iCerts || aIkeMsg->iCerts->Count() == 0)
       
  3881                         {    
       
  3882                         if(aIkeMsg->iIdR->GetNextPayload() != IKEV2_PAYLOAD_AUTH)
       
  3883                             {
       
  3884                    		    DEBUG_LOG(_L("5"));                    
       
  3885                             return EFalse;
       
  3886                             }
       
  3887                         }
       
  3888 		            else
       
  3889 		                {
       
  3890                         if(aIkeMsg->iIdR->GetNextPayload() != IKEV2_PAYLOAD_CERT)
       
  3891                             {
       
  3892                    		    DEBUG_LOG(_L("6"));                    
       
  3893                             return EFalse;
       
  3894                             }
       
  3895                         TInt c = aIkeMsg->iCerts->Count();
       
  3896                         if(aIkeMsg->iCerts->At(c-1)->GetNextPayload() != IKEV2_PAYLOAD_AUTH)
       
  3897                             {
       
  3898                    		    DEBUG_LOG(_L("7"));
       
  3899                             return EFalse;
       
  3900                             }
       
  3901                         }
       
  3902 		            }
       
  3903 		        else
       
  3904 		            {
       
  3905 		            if(!aIkeMsg->iIdI)
       
  3906 		                {
       
  3907                		    DEBUG_LOG(_L("8"));	                
       
  3908 		                return EFalse;
       
  3909 		                }
       
  3910 		            if(aIkeMsg->iCerts && aIkeMsg->iCerts->Count() != 0)
       
  3911 		                {
       
  3912 		                if(aIkeMsg->iIdI->GetNextPayload() != IKEV2_PAYLOAD_CERT)
       
  3913 		                    {
       
  3914                    		    DEBUG_LOG(_L("9"));		                    
       
  3915 		                    return EFalse;
       
  3916 		                    }
       
  3917 		                }
       
  3918                     if(aIkeMsg->iCertReqs && aIkeMsg->iCertReqs->Count() != 0)
       
  3919                         {
       
  3920                         TInt c = aIkeMsg->iCertReqs->Count();
       
  3921                         if(aIkeMsg->iIdR && aIkeMsg->iCertReqs->At(c-1)->GetNextPayload() != IKEV2_PAYLOAD_ID_R)
       
  3922                             {
       
  3923                    		    DEBUG_LOG(_L("10"));                            
       
  3924                             return EFalse;
       
  3925                             }
       
  3926                         if(!aIkeMsg->iIdR && aIkeMsg->iCertReqs->At(c-1)->GetNextPayload() != IKEV2_PAYLOAD_AUTH)
       
  3927                             {
       
  3928                    		    DEBUG_LOG(_L("11"));                            
       
  3929                             return EFalse;
       
  3930                             }
       
  3931                         }
       
  3932                     if(aIkeMsg->iIdR && aIkeMsg->iIdR->GetNextPayload() != IKEV2_PAYLOAD_AUTH)
       
  3933                         {
       
  3934                		    DEBUG_LOG(_L("12"));                        
       
  3935                         return EFalse;
       
  3936                         }
       
  3937 		            }
       
  3938 		        }
       
  3939 			break;
       
  3940 			
       
  3941 		case CREATE_CHILD_SA:
       
  3942             if(!aIkeMsg->iEncr || !aIkeMsg->iSa || !aIkeMsg->iNonce) return EFalse;
       
  3943             if(aIkeMsg->iSa->GetNextPayload() != IKEV2_PAYLOAD_NONCE) return EFalse;
       
  3944             if(aIkeMsg->iKe && aIkeMsg->iNonce->GetNextPayload() != IKEV2_PAYLOAD_KE) return EFalse;
       
  3945             if(aIkeMsg->iTsI)
       
  3946                 {
       
  3947                 if(aIkeMsg->iKe && aIkeMsg->iKe->GetNextPayload() != IKEV2_PAYLOAD_TS_I) return EFalse;
       
  3948                 if(!aIkeMsg->iKe && aIkeMsg->iNonce->GetNextPayload() != IKEV2_PAYLOAD_TS_I) return EFalse;
       
  3949                 if(aIkeMsg->iTsI->GetNextPayload() != IKEV2_PAYLOAD_TS_R) return EFalse;
       
  3950                 }
       
  3951 			break;
       
  3952 
       
  3953 		default:
       
  3954 			break;
       
  3955 	    }
       
  3956     DEBUG_LOG(_L("13"));
       
  3957 	return ETrue;
       
  3958     }
       
  3959 
       
  3960 
       
  3961 TBool CIkev2Negotiation::Stopped() 
       
  3962     { 
       
  3963     return iStopped; 
       
  3964     }
       
  3965 
       
  3966 
       
  3967 TBool CIkev2Negotiation::ImplicitChildSa() 
       
  3968     { 
       
  3969     return (iState < KStateIkeSaCompleted); 
       
  3970     }
       
  3971 
       
  3972 
       
  3973 HBufC8* CIkev2Negotiation::PeekProposedSa() 
       
  3974     { 
       
  3975     return iProposedSA; 
       
  3976     }
       
  3977 
       
  3978 
       
  3979 HBufC8* CIkev2Negotiation::GetProposedSa()  
       
  3980     { 
       
  3981     HBufC8* Sa = iProposedSA; 
       
  3982     iProposedSA = NULL; 
       
  3983     return Sa; 
       
  3984     }
       
  3985 
       
  3986 
       
  3987 void CIkev2Negotiation::SetProposedSa(HBufC8* aSaPl) 
       
  3988     { 
       
  3989     delete iProposedSA; 
       
  3990     iProposedSA = aSaPl; 
       
  3991     }
       
  3992 
       
  3993 
       
  3994 CIkev2Acquire** CIkev2Negotiation::GetAcquireQue() 
       
  3995     { 
       
  3996     return &iAcquireFirst; 
       
  3997     }
       
  3998 
       
  3999 
       
  4000 CIkev2Expire** CIkev2Negotiation::GetExpireQue() 
       
  4001     { 
       
  4002     return &iExpireFirst; 
       
  4003     }
       
  4004 
       
  4005 
       
  4006 TBool CIkev2Negotiation::RequestsPending() 
       
  4007     { 
       
  4008     return (iAcquireFirst || iExpireFirst); 
       
  4009     }
       
  4010 
       
  4011 
       
  4012 void CIkev2Negotiation::SetNotifyCode(TInt aMsgType) 
       
  4013     { 
       
  4014     if (iNotifyCode == 0) 
       
  4015         iNotifyCode = aMsgType; 
       
  4016     }
       
  4017 
       
  4018 
       
  4019 TInt CIkev2Negotiation::GetNotifyCode() 
       
  4020     { 
       
  4021     return iNotifyCode; 
       
  4022     }
       
  4023 
       
  4024 
       
  4025 void CIkev2Negotiation::StoreNotifyData32(TUint32 aData) 
       
  4026     {
       
  4027     PUT32(iNotifyData, aData); 
       
  4028     iNotifyDataLth = 4;
       
  4029     }
       
  4030 
       
  4031 
       
  4032 void CIkev2Negotiation::StoreNotifyData16(TUint16 aData) 
       
  4033     {
       
  4034     PUT16(iNotifyData, aData); 
       
  4035     iNotifyDataLth = 2;
       
  4036     }               
       
  4037 
       
  4038 
       
  4039 TUint8* CIkev2Negotiation::NotifyData(TInt& aDataLth)
       
  4040     {
       
  4041     aDataLth = iNotifyDataLth;
       
  4042     if ( iNotifyDataLth )
       
  4043         return iNotifyData;
       
  4044     else return NULL;
       
  4045     }
       
  4046 
       
  4047 
       
  4048 TInetAddr CIkev2Negotiation::GetLocalAddr() const
       
  4049     {
       
  4050     if ( iHdr.iVirtualAddr.IsUnspecified() )
       
  4051         {
       
  4052         return iHdr.iLocalAddr;
       
  4053         }
       
  4054     else
       
  4055         {
       
  4056          return iHdr.iVirtualAddr;
       
  4057         }
       
  4058     }
       
  4059