vpnengine/ikev2lib/src/ikev2pfkey.cpp
changeset 0 33413c0669b9
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: Utility methods to handle PFKEY messaging
       
    15 *
       
    16 */
       
    17 
       
    18 #include "ikev2pfkey.h"
       
    19 #include "ikev2pluginsession.h"
       
    20 #include "ikev2SAdata.h"
       
    21 #include "ipsecsadata.h"
       
    22 #include "pfkeyextdatautil.h"
       
    23 #include "ikev2acquire.h"
       
    24 #include "ikev2trafficselector.h"
       
    25 #include "ikev2ipsecsadata.h"
       
    26 #include <networking/pfkeyv2.h>
       
    27 #include "ikev2const.h"
       
    28 
       
    29 static const TUid KIkeV2PlugInUid3 = { 0x10206993 };
       
    30 
       
    31 void Ikev2Pfkey::UpdateIpsecSaDataBaseL(const TIkev2SAData& aIkev2SA, 
       
    32                                         const TIkeV2IpsecSAData& aChild, 
       
    33                                         CIkev2PluginSession& aIkePluginSession,
       
    34                                         CIkev2Acquire& aAcquire)
       
    35 {
       
    36 	//
       
    37 	//  Fill Ipsec SA info int TSAData object for PFKEY Update/Add
       
    38 	//  primitives. Take local and remote identity data from CIkev2Acquire object
       
    39 	//
       
    40     __ASSERT_DEBUG(aChild.iKeyMaterial != NULL, User::Invariant());
       
    41 
       
    42 	TUint16 LocalPort    = 0;
       
    43 	TUint16 RemotePort   = 0;	
       
    44 	TUint8  LocalIdType  = 0;
       
    45 	TUint8  RemoteIdType = 0;	
       
    46 	TUint8  Protocol     = 0;	
       
    47 	const CArrayFix<TIkeV2TrafficSelector>& TsI = aAcquire.TS_i();
       
    48 	const CArrayFix<TIkeV2TrafficSelector>& TsR = aAcquire.TS_r();
       
    49 	
       
    50 	__ASSERT_DEBUG(TsI.Count() > 0, User::Invariant());
       
    51 	__ASSERT_DEBUG(TsR.Count() > 0, User::Invariant());
       
    52 		
       
    53     HBufC8* localId  = aAcquire.LocalId();
       
    54     HBufC8* remoteId = NULL;		
       
    55     
       
    56     
       
    57     if ( aAcquire.RemoteId() )
       
    58         {
       
    59         remoteId = aAcquire.RemoteId()->AllocLC();
       
    60         }
       
    61     else
       
    62         {            
       
    63         if ( aAcquire.Response() )
       
    64             {
       
    65 	        remoteId = TsI[0].IdFromTsL();
       
    66 	        CleanupStack::PushL(remoteId);
       
    67 	        }
       
    68         else
       
    69             {
       
    70             remoteId = TsR[0].IdFromTsL();
       
    71             CleanupStack::PushL(remoteId);            
       
    72             }
       
    73 	}
       
    74 
       
    75 	//
       
    76 	//  Build Encryption and integrity keys for Ipsec SA:s
       
    77     //	Keying material MUST be taken from the expanded KEYMAT in the
       
    78 	//	following order:
       
    79 	//	- All keys for SAs carrying data from the initiator to the responder
       
    80 	//	  are taken before SAs going in the reverse direction.
       
    81 	//  If a single protocol has both encryption and authentication keys,
       
    82 	//  the encryption key is taken from the first octets of KEYMAT and
       
    83 	//	the authentication key is taken from the next octets.
       
    84 	//
       
    85     const TUint8* KeyMat = aChild.iKeyMaterial->Des().Ptr();
       
    86 	TPtrC8 InAuthKey(NULL,0), OutAuthKey(NULL,0);
       
    87 	TPtrC8 InEncrKey(NULL,0), OutEncrKey(NULL,0);
       
    88 
       
    89 	if ( aChild.iSaType == SADB_SATYPE_ESP )
       
    90 	{
       
    91 		if ( aAcquire.Response() )
       
    92 		{	
       
    93 		   KeyMat = Ikev2Pfkey::GetIpsecKeys(&InEncrKey, &InAuthKey, KeyMat, aChild.iCipherKeyLth, aChild.iIntegKeyLth);
       
    94 		   KeyMat = Ikev2Pfkey::GetIpsecKeys(&OutEncrKey, &OutAuthKey, KeyMat, aChild.iCipherKeyLth, aChild.iIntegKeyLth);		   
       
    95 		}   
       
    96         else
       
    97 		{
       
    98 		   KeyMat = Ikev2Pfkey::GetIpsecKeys(&OutEncrKey, &OutAuthKey, KeyMat, aChild.iCipherKeyLth, aChild.iIntegKeyLth);
       
    99 		   KeyMat = Ikev2Pfkey::GetIpsecKeys(&InEncrKey, &InAuthKey, KeyMat, aChild.iCipherKeyLth, aChild.iIntegKeyLth);		   
       
   100 		}	
       
   101 	}	
       
   102 	else     
       
   103 	{  // SADB_SATYPE_AH
       
   104 		if ( aAcquire.Response() )
       
   105 		{	
       
   106 			KeyMat = Ikev2Pfkey::GetIpsecKeys(&InEncrKey, &InAuthKey, KeyMat, 0, aChild.iIntegKeyLth);
       
   107 			KeyMat = Ikev2Pfkey::GetIpsecKeys(&OutEncrKey, &OutAuthKey, KeyMat, 0, aChild.iIntegKeyLth);		   			
       
   108 		}   
       
   109 		else
       
   110 		{
       
   111 			KeyMat = Ikev2Pfkey::GetIpsecKeys(&OutEncrKey, &OutAuthKey, KeyMat, 0, aChild.iIntegKeyLth);
       
   112 			KeyMat = Ikev2Pfkey::GetIpsecKeys(&InEncrKey, &InAuthKey, KeyMat, 0, aChild.iIntegKeyLth);
       
   113 		}	
       
   114 	}
       
   115 	TIpsecSAData SaData;
       
   116 	TUint32 SadbFlags;
       
   117 	if (aAcquire.DHGroup())
       
   118 		 SadbFlags = SADB_SAFLAGS_PFS;
       
   119 	else SadbFlags = 0;
       
   120 	
       
   121 	if ( !aChild.iTransport  )
       
   122 	{
       
   123 	    SaData.iInternalAddress.Init(KAfInet6);
       
   124 	    SaData.iInternalAddress.SetScope(aIkePluginSession.VpnInterfaceIndex());
       
   125 		SadbFlags |= SADB_SAFLAGS_INT_ADDR; 
       
   126 	}
       
   127 	
       
   128 	//
       
   129 	// Inbound SA
       
   130 	//
       
   131 	SaData.iSAType = aChild.iSaType;
       
   132 	if ( aAcquire.Response() )		
       
   133 		 SaData.iSeq = aAcquire.Id();
       
   134 	else SaData.iSeq = aAcquire.Seq();
       
   135 	SaData.iPid = KIkeV2PlugInUid3.iUid;
       
   136 	SaData.iSrc = aIkev2SA.iRemoteAddr;
       
   137 	SaData.iSrc.SetPort(RemotePort);
       
   138 	if ( aAcquire.SrcSpecific() )
       
   139 	{	
       
   140 	   SaData.iDst = aIkev2SA.iLocalAddr;
       
   141 	   SaData.iDst.SetPort(LocalPort);
       
   142 	}
       
   143 	else SaData.iDst.Init(0);
       
   144 	SaData.iProtocol  = Protocol;
       
   145 	SaData.iSrcIdType = RemoteIdType;
       
   146 	SaData.iDstIdType = LocalIdType;
       
   147     SaData.iSrcIdent.Set(remoteId->Des());
       
   148 	if ( !aAcquire.Response() && localId != NULL)		
       
   149        SaData.iDstIdent.Set(localId->Des());
       
   150 	
       
   151     TUint32 spi;
       
   152     TPtr8 spiPtr(reinterpret_cast<TUint8*>(&spi), sizeof(spi));
       
   153     spiPtr = aChild.iSPI_In;
       
   154 	SaData.iSPI = spi;
       
   155 	switch ( aChild.iIntegAlg )
       
   156 	{
       
   157 		case AUTH_HMAC_MD5_96:
       
   158 			SaData.iAuthAlg = SADB_AALG_MD5HMAC;
       
   159 			break;
       
   160 
       
   161 		case AUTH_HMAC_SHA1_96:
       
   162 			SaData.iAuthAlg = SADB_AALG_SHA1HMAC;
       
   163 			break;
       
   164 
       
   165 		default:
       
   166 			SaData.iAuthAlg = 0;
       
   167             break;	
       
   168 	}	
       
   169 	SaData.iEncrAlg = aChild.iEncrAlg;    // Should correspond PFKEY2.H !
       
   170 	SaData.iAuthKey.Set(InAuthKey);
       
   171 	SaData.iEncrKey.Set(InEncrKey);
       
   172     SaData.iHard = aAcquire.HardLifetime();
       
   173     SaData.iSoft = aAcquire.SoftLifetime();
       
   174 	SaData.iReplayWindowLength = aAcquire.ReplayWindow();
       
   175 	SaData.iFlags = SadbFlags;
       
   176 	
       
   177     //
       
   178     //  Get the following implementation specific information for PFKEY
       
   179     //  primitives:
       
   180     //  -- ESP UDP encapsulation info, if a NAT device detected 
       
   181     //  -- Interface index for  tunnel mode inbound SA
       
   182     //
       
   183 	HBufC8* GenExt = NULL;
       
   184     if ( aIkev2SA.iNATFlags )
       
   185     {
       
   186         GenExt = HBufC8::NewLC(128);
       
   187         TPtr8   GenExtPtr = GenExt->Des();        
       
   188         TInetAddr DummyAddr;
       
   189         DummyAddr.SetFamily(KAFUnspec);  
       
   190         PFKeyExtDataUtil::BuildUdpEncExtensionData(GenExtPtr, aIkev2SA.iNATFlags,
       
   191                                                    EFalse, EFalse, 0, 0, 
       
   192                                                    aIkev2SA.iDestinAddr, DummyAddr);                
       
   193     }
       
   194     else
       
   195     {
       
   196         GenExt = HBufC8::NewLC(1);
       
   197     }
       
   198     SaData.iGenericExtension.Set(*GenExt);
       
   199 	
       
   200     aIkePluginSession.UpdateSAL(SaData);
       
   201 
       
   202 	SaData.iFlags &= ~SADB_SAFLAGS_INT_ADDR; //No VPN interface index to outbound SA
       
   203 	//
       
   204 	// Outbound SA. Some changes in the SA, the rest is the same
       
   205 	//
       
   206 	if ( !aAcquire.Response() )	
       
   207 	   SaData.iPid = aAcquire.Pid();  // Use Acquire PID for OUT SA when initiator
       
   208 	if ( aAcquire.SrcSpecific() )
       
   209 	{	
       
   210 		SaData.iSrc = aIkev2SA.iLocalAddr;
       
   211 		SaData.iSrc.SetPort(LocalPort);
       
   212 	}
       
   213 	else SaData.iSrc.Init(0);
       
   214 	SaData.iDst = aIkev2SA.iRemoteAddr;
       
   215 	SaData.iDst.SetPort(RemotePort);	
       
   216 	SaData.iSrcIdType = LocalIdType;
       
   217 	SaData.iDstIdType = RemoteIdType;
       
   218 	SaData.iSrcIdent.Set(localId->Des());
       
   219 	SaData.iDstIdent.Set(remoteId->Des());
       
   220 	
       
   221     spiPtr = aChild.iSPI_Out;
       
   222 	SaData.iSPI = spi;
       
   223 	SaData.iAuthKey.Set(OutAuthKey);
       
   224 	SaData.iEncrKey.Set(OutEncrKey);
       
   225 
       
   226 	aIkePluginSession.AddSAL(SaData);
       
   227 	
       
   228 	CleanupStack::PopAndDestroy(GenExt);
       
   229 	CleanupStack::PopAndDestroy(remoteId);
       
   230 	
       
   231 }
       
   232 
       
   233 CIkev2Acquire* Ikev2Pfkey::DeleteInboundSPI(const TIkev2SAData& aIkev2SA, 
       
   234                                        CIkev2PluginSession& aIkePluginSession, 
       
   235                                        CIkev2Acquire* aAcquire)
       
   236 {
       
   237 	//
       
   238 	//  Issue PFKEY Delete SA for Inbound SPI in CIkev2Acquire object and
       
   239 	//  delete CIkev2Acquire object then
       
   240 	//
       
   241 	if ( aAcquire )
       
   242 	{
       
   243 		TInetAddr LocalAddr;
       
   244 		if ( aAcquire->SrcSpecific() )
       
   245 			 LocalAddr = aIkev2SA.iLocalAddr;
       
   246 		else LocalAddr.Init(0); 
       
   247 		LocalAddr.SetPort(0);	
       
   248 		TInetAddr RemoteAddr = aIkev2SA.iRemoteAddr;
       
   249 		RemoteAddr.SetPort(0);
       
   250 		
       
   251 		TUint32 spi;
       
   252 		TPtr8 spiPtr(reinterpret_cast<TUint8*>(&spi), sizeof(spi));
       
   253 		spiPtr = aAcquire->SPI_In();
       
   254 		aIkePluginSession.DeleteIpsecSA(spi, RemoteAddr, LocalAddr, aAcquire->IpsecProtocol());
       
   255 		delete aAcquire;
       
   256 	}
       
   257 	
       
   258 	return NULL;
       
   259 }	
       
   260 
       
   261 const TUint8* Ikev2Pfkey::GetIpsecKeys(TPtrC8* aEncrKey, TPtrC8* aIntegKey, const TUint8* aKeyMaterial, TInt aCipherKeyLth, TInt aIntegKeyLth )
       
   262 {
       
   263 	if ( aCipherKeyLth && aKeyMaterial)
       
   264 	{
       
   265 	   ASSERT(aEncrKey);
       
   266 	   aEncrKey->Set(aKeyMaterial, aCipherKeyLth);
       
   267 	   aKeyMaterial += aCipherKeyLth;
       
   268 	}
       
   269 	
       
   270     if ( aIntegKeyLth )
       
   271     {	
       
   272        ASSERT(aIntegKey && aKeyMaterial);
       
   273 	   aIntegKey->Set(aKeyMaterial, aIntegKeyLth);
       
   274 	   aKeyMaterial += aIntegKeyLth;
       
   275 	}
       
   276 
       
   277 	return aKeyMaterial;
       
   278 }	
       
   279