vpnengine/ikev2lib/src/ikev2message.cpp
changeset 0 33413c0669b9
child 1 c9c2ad51f972
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 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:
       
    15 *
       
    16 */
       
    17 
       
    18 #include <es_sock.h>
       
    19 #include <badesca.h>
       
    20 #include <random.h>
       
    21 
       
    22 #include "ikev2message.h"
       
    23 #include "ikev2const.h"
       
    24 #include "ikecalist.h"
       
    25 #include "ikecaelem.h"
       
    26 #include "ikev2trafficselector.h"
       
    27 #include "ikecrypto.h"
       
    28 #include "ikev2identity.h"
       
    29 #include "ikemsgheader.h"
       
    30 #include "ikedebug.h"
       
    31 
       
    32 static const TUint8 KMessageIdFieldOffset = 20; 
       
    33 
       
    34 static const TUint KIkePayloadGenericHeaderLength = 4;
       
    35 static const TUint8 KLengthFieldOffset = 2;
       
    36 
       
    37 static const TUint32 KSha1Length = 20;
       
    38 static const TUint32 KCertReqHeaderLength = 5;
       
    39 static const TUint32 KCertHeaderLength = 5;
       
    40 static const TUint32 KSaHeaderLength = 4;
       
    41 static const TUint32 KKeHeaderLength = 8;
       
    42 static const TUint32 KNonceHeaderLength = 4;
       
    43 static const TUint32 KAuthHeaderLength = 8;
       
    44 static const TUint32 KNotifyHeaderLength = 8;
       
    45 static const TUint32 KConfigurationHeaderLength = 8;
       
    46 static const TUint32 KVendorIdHeaderLength = 4;
       
    47 static const TUint32 KDeleteHeaderLength = 8;
       
    48 static const TUint32 KEapHeaderLength = 4;
       
    49 static const TUint32 KTsHeaderLength = 8;
       
    50 static const TUint32 KEncryptedHeaderLength = 4;
       
    51 
       
    52 _LIT8(KNonEspMarker, "\0\0\0\0");
       
    53 
       
    54 CIkeV2Payload::CIkeV2Payload(TUint8 aPayloadType)
       
    55 :iPayloadType(aPayloadType)
       
    56     {    
       
    57     }
       
    58 
       
    59 
       
    60 CIkeV2Payload::~CIkeV2Payload()
       
    61     {
       
    62     delete iPayloadData;
       
    63     }
       
    64 
       
    65 TUint8 CIkeV2Payload::PayloadType() const
       
    66     {
       
    67     return iPayloadType;
       
    68     }
       
    69 
       
    70 
       
    71 TUint8 CIkeV2Payload::NextPayload() const
       
    72     {
       
    73     __ASSERT_DEBUG(iPayloadData->Length() >= KIkePayloadGenericHeaderLength,
       
    74                    User::Invariant());
       
    75     
       
    76     return (*iPayloadData)[0];
       
    77     }
       
    78 
       
    79 
       
    80 void CIkeV2Payload::SetNextPayload(TUint8 aNextPayload)
       
    81     {
       
    82     __ASSERT_DEBUG(iPayloadData->Length() >= KIkePayloadGenericHeaderLength,
       
    83                    User::Invariant());
       
    84     
       
    85     TPtr8 payloadDataPtr(iPayloadData->Des());
       
    86     payloadDataPtr[0] = aNextPayload;
       
    87     }
       
    88 
       
    89 
       
    90 TUint16 CIkeV2Payload::PayloadLength() const
       
    91     {
       
    92     __ASSERT_DEBUG(iPayloadData->Length() >= KIkePayloadGenericHeaderLength,
       
    93                    User::Invariant());
       
    94     
       
    95     return BigEndian::Get16(iPayloadData->Ptr() + KLengthFieldOffset);
       
    96     }
       
    97 
       
    98 
       
    99 void CIkeV2Payload::SetPayloadLength(TUint16 aLength)
       
   100     {
       
   101     __ASSERT_DEBUG(iPayloadData->Length() >= KIkePayloadGenericHeaderLength,
       
   102                    User::Invariant());
       
   103     const TUint KLengthPosition = 2; 
       
   104     
       
   105     BigEndian::Put16(reinterpret_cast<TUint8*>(&aLength), aLength);
       
   106     TPtrC8 length(reinterpret_cast<TUint8*>(&aLength), sizeof(aLength));
       
   107     
       
   108     TPtr8 lengthPtr(iPayloadData->Des().MidTPtr(KLengthPosition, 
       
   109                                                 length.Length()));    
       
   110     lengthPtr = length; 
       
   111     }
       
   112 
       
   113 TPtrC8 CIkeV2Payload::PayloadData() const
       
   114     {
       
   115     return TPtrC8(*iPayloadData);
       
   116     }
       
   117 
       
   118 
       
   119 CIkevV2CertReqPayload* CIkevV2CertReqPayload::NewL(const CIkeCaList& aCaList)
       
   120     {
       
   121     CIkevV2CertReqPayload* self = new (ELeave) CIkevV2CertReqPayload;
       
   122     CleanupStack::PushL(self);
       
   123     self->ConstructL(aCaList);
       
   124     CleanupStack::Pop(self);
       
   125     
       
   126     return self;
       
   127     }
       
   128 
       
   129 
       
   130 
       
   131 CIkevV2CertReqPayload::CIkevV2CertReqPayload()
       
   132 :CIkeV2Payload(IKEV2_PAYLOAD_CR)
       
   133     {
       
   134     }
       
   135 
       
   136 
       
   137 void CIkevV2CertReqPayload::ConstructL(const CIkeCaList& aCaList)
       
   138     {
       
   139     __ASSERT_DEBUG(aCaList.Count() > 0, User::Invariant());
       
   140     TUint16 length = (aCaList.Count() * KSha1Length) + KCertReqHeaderLength;
       
   141     
       
   142     iPayloadData = HBufC8::NewL(length);
       
   143     TPtr8 payloadDataPtr(iPayloadData->Des());
       
   144     payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength);
       
   145     payloadDataPtr.FillZ();
       
   146     
       
   147     SetPayloadLength(length);
       
   148     
       
   149     TUint8 encoding = X509_CERTIFICATE_SIGN;       
       
   150     TPtrC8 encodingPtr(&encoding, sizeof(encoding));
       
   151     payloadDataPtr.Append(encodingPtr);
       
   152     
       
   153     for (TUint i = 0; i < aCaList.Count(); ++i)
       
   154         {
       
   155         payloadDataPtr.Append(aCaList[i]->KeyHash());
       
   156         }
       
   157     
       
   158     __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant());
       
   159     }
       
   160 
       
   161 
       
   162 CIkevV2CertPayload* CIkevV2CertPayload::NewL(const TDesC8& aCertData)
       
   163     {
       
   164     CIkevV2CertPayload* self = new (ELeave) CIkevV2CertPayload;
       
   165     CleanupStack::PushL(self);
       
   166     self->ConstructL(aCertData);
       
   167     CleanupStack::Pop(self);
       
   168     
       
   169     return self;
       
   170     }
       
   171 
       
   172 
       
   173 CIkevV2CertPayload::CIkevV2CertPayload()
       
   174 :CIkeV2Payload(IKEV2_PAYLOAD_CERT)
       
   175     {
       
   176     
       
   177     }
       
   178 
       
   179 
       
   180 void CIkevV2CertPayload::ConstructL(const TDesC8& aCertData)
       
   181     {
       
   182     TUint16 length = aCertData.Length() + KCertHeaderLength;
       
   183     
       
   184     iPayloadData = HBufC8::NewL(length);
       
   185     TPtr8 payloadDataPtr(iPayloadData->Des());
       
   186     payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength);  
       
   187     payloadDataPtr.FillZ();
       
   188     
       
   189     SetPayloadLength(length);
       
   190 
       
   191     TUint8 encoding = X509_CERTIFICATE_SIGN;     
       
   192     TPtrC8 encodingPtr(&encoding, sizeof(encoding));
       
   193     payloadDataPtr.Append(encodingPtr);       
       
   194     payloadDataPtr.Append(aCertData);   
       
   195     
       
   196     __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant());
       
   197     }
       
   198 
       
   199 
       
   200 CIkevV2SaPayload* CIkevV2SaPayload::NewL(const TDesC8& aSaData)
       
   201     {
       
   202     CIkevV2SaPayload* self = new (ELeave) CIkevV2SaPayload; 
       
   203     CleanupStack::PushL(self);
       
   204     self->ConstructL(aSaData);
       
   205     CleanupStack::Pop(self);
       
   206     
       
   207     return self;
       
   208     }
       
   209 
       
   210 
       
   211 CIkevV2SaPayload::CIkevV2SaPayload()
       
   212 :CIkeV2Payload(IKEV2_PAYLOAD_SA)
       
   213     {    
       
   214     }
       
   215 
       
   216 
       
   217 void CIkevV2SaPayload::ConstructL(const TDesC8& aSaData)
       
   218     {
       
   219     TUint16 length = aSaData.Length() + KSaHeaderLength;
       
   220     
       
   221     iPayloadData = HBufC8::NewL(length);
       
   222     TPtr8 payloadDataPtr(iPayloadData->Des());
       
   223     payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength);
       
   224     payloadDataPtr.FillZ();
       
   225     
       
   226     SetPayloadLength(length);
       
   227     
       
   228     payloadDataPtr.Append(aSaData);
       
   229     
       
   230     __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant());
       
   231     }
       
   232 
       
   233 
       
   234 CIkevV2KePayload* CIkevV2KePayload::NewL(TUint16 aDHGroup, const TDesC8& aKeData)
       
   235     {    
       
   236     CIkevV2KePayload* self = new (ELeave) CIkevV2KePayload;
       
   237     CleanupStack::PushL(self);
       
   238     self->ConstructL(aDHGroup, aKeData);
       
   239     CleanupStack::Pop(self);
       
   240     
       
   241     return self;
       
   242     }
       
   243 
       
   244 
       
   245 CIkevV2KePayload::CIkevV2KePayload()
       
   246 :CIkeV2Payload(IKEV2_PAYLOAD_KE)
       
   247     {
       
   248     }
       
   249 
       
   250 void CIkevV2KePayload::ConstructL(TUint16 aDHGroup, const TDesC8& aKeData)
       
   251     {
       
   252     static const TUint8 KReservedFieldLength = 2;
       
   253     
       
   254     TUint16 length = aKeData.Length() + KKeHeaderLength;
       
   255     
       
   256     iPayloadData = HBufC8::NewL(length);
       
   257     TPtr8 payloadDataPtr(iPayloadData->Des());
       
   258     payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength);
       
   259     payloadDataPtr.FillZ();
       
   260     
       
   261     SetPayloadLength(length);
       
   262     
       
   263     BigEndian::Put16(reinterpret_cast<TUint8*>(&aDHGroup), aDHGroup);
       
   264     TPtrC8 dhGroupPtr(reinterpret_cast<TUint8*>(&aDHGroup), sizeof(aDHGroup));
       
   265     payloadDataPtr.Append(dhGroupPtr);
       
   266     
       
   267     //Leave reserved bytes zero
       
   268     payloadDataPtr.SetLength(payloadDataPtr.Length() + KReservedFieldLength);
       
   269     TPtr8 reservedBytes = payloadDataPtr.RightTPtr(KReservedFieldLength);
       
   270     reservedBytes.FillZ();
       
   271     
       
   272     payloadDataPtr.Append(aKeData);  
       
   273     
       
   274     __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant());
       
   275     }
       
   276 
       
   277 
       
   278 CIkevV2NoncePayload* CIkevV2NoncePayload::NewL(const TDesC8& aNonceData)
       
   279     {
       
   280     CIkevV2NoncePayload* self = new (ELeave) CIkevV2NoncePayload;
       
   281     CleanupStack::PushL(self);
       
   282     self->ConstructL(aNonceData);
       
   283     CleanupStack::Pop(self);
       
   284     
       
   285     return self;
       
   286     }
       
   287 
       
   288 
       
   289 CIkevV2NoncePayload::CIkevV2NoncePayload()
       
   290 :CIkeV2Payload(IKEV2_PAYLOAD_NONCE)
       
   291     {
       
   292     }
       
   293 
       
   294 
       
   295 void CIkevV2NoncePayload::ConstructL(const TDesC8& aNonceData)
       
   296     {
       
   297     TUint16 length = aNonceData.Length() + KNonceHeaderLength;
       
   298 
       
   299     iPayloadData = HBufC8::NewL(length);
       
   300     TPtr8 payloadDataPtr(iPayloadData->Des());
       
   301     payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength);  
       
   302     payloadDataPtr.FillZ();
       
   303     
       
   304     SetPayloadLength(length);
       
   305 
       
   306     payloadDataPtr.Append(aNonceData);
       
   307     
       
   308     __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant());
       
   309     }
       
   310 
       
   311 
       
   312 CIkevV2IdPayload::CIkevV2IdPayload(TUint8 aPayloadType)
       
   313 :CIkeV2Payload(aPayloadType)
       
   314     {    
       
   315     }
       
   316 
       
   317 void CIkevV2IdPayload::ConstructL(const CIkeV2Identity& aIdentity)
       
   318     {        
       
   319     TPtrC8 idPayloadData = aIdentity.PayloadData();
       
   320     TUint32 length = idPayloadData.Length() + KIkePayloadGenericHeaderLength;
       
   321 
       
   322     iPayloadData = HBufC8::NewL(length);
       
   323     TPtr8 payloadDataPtr(iPayloadData->Des());
       
   324     payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength);    
       
   325     payloadDataPtr.FillZ();
       
   326     
       
   327     SetPayloadLength(length);
       
   328 
       
   329     payloadDataPtr.Append(idPayloadData);
       
   330     
       
   331     __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant());
       
   332     }
       
   333 
       
   334 
       
   335 CIkevV2IdiPayload* CIkevV2IdiPayload::NewL(const CIkeV2Identity& aIdentity)
       
   336     {    
       
   337     CIkevV2IdiPayload* self = new (ELeave) CIkevV2IdiPayload;
       
   338     CleanupStack::PushL(self);
       
   339     self->ConstructL(aIdentity);
       
   340     CleanupStack::Pop(self);
       
   341     return self;
       
   342     }
       
   343 
       
   344 
       
   345 CIkevV2IdiPayload::CIkevV2IdiPayload()
       
   346 :CIkevV2IdPayload(IKEV2_PAYLOAD_ID_I)
       
   347     {  
       
   348     }
       
   349 
       
   350 
       
   351 CIkevV2IdrPayload* CIkevV2IdrPayload::NewL(const CIkeV2Identity& aIdentity)
       
   352     {    
       
   353     CIkevV2IdrPayload* self = new (ELeave) CIkevV2IdrPayload;
       
   354     CleanupStack::PushL(self);
       
   355     self->ConstructL(aIdentity);
       
   356     CleanupStack::Pop(self);
       
   357     return self;    
       
   358     }
       
   359 
       
   360 
       
   361 CIkevV2IdrPayload::CIkevV2IdrPayload()
       
   362 :CIkevV2IdPayload(IKEV2_PAYLOAD_ID_R)
       
   363     {    
       
   364     }
       
   365 
       
   366 
       
   367 CIkeV2AuthPayload* CIkeV2AuthPayload::NewL(TUint8 aAuthMethod, const TDesC8& aAuthData)
       
   368     {
       
   369     CIkeV2AuthPayload* self = new (ELeave) CIkeV2AuthPayload;
       
   370     CleanupStack::PushL(self);
       
   371     self->ConstructL(aAuthMethod, aAuthData);
       
   372     CleanupStack::Pop(self);
       
   373     
       
   374     return self;
       
   375     }
       
   376 
       
   377 
       
   378 CIkeV2AuthPayload::CIkeV2AuthPayload()
       
   379 :CIkeV2Payload(IKEV2_PAYLOAD_AUTH)
       
   380     {
       
   381     }
       
   382 
       
   383 
       
   384 void CIkeV2AuthPayload::ConstructL(TUint8 aAuthMethod, const TDesC8& aAuthData)
       
   385     {
       
   386     static const TUint8 KReservedFieldLength = 3;
       
   387     
       
   388     TUint32 length = aAuthData.Length() + KAuthHeaderLength;
       
   389 
       
   390     iPayloadData = HBufC8::NewL(length);
       
   391     TPtr8 payloadDataPtr(iPayloadData->Des());
       
   392     payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength);    
       
   393     payloadDataPtr.FillZ();
       
   394     
       
   395     SetPayloadLength(length);
       
   396     
       
   397     TPtrC8 authTypePtr(&aAuthMethod, sizeof(aAuthMethod));
       
   398     payloadDataPtr.Append(authTypePtr);
       
   399     //Leave reserved bytes zero
       
   400     payloadDataPtr.SetLength(payloadDataPtr.Length() + KReservedFieldLength);    
       
   401     TPtr8 reservedField = payloadDataPtr.RightTPtr(KReservedFieldLength);
       
   402     reservedField.FillZ();
       
   403     
       
   404     payloadDataPtr.Append(aAuthData);   
       
   405     
       
   406     __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant());
       
   407     }
       
   408 
       
   409 
       
   410 CIkeV2NotifyPayload* CIkeV2NotifyPayload::NewL(TUint8 aProtocolId,
       
   411                                                const TDesC8& aSpi,
       
   412                                                TUint16 aNotifyType,
       
   413                                                const TDesC8& aNotifyData)
       
   414     {    
       
   415     CIkeV2NotifyPayload* self = new (ELeave) CIkeV2NotifyPayload;
       
   416     CleanupStack::PushL(self);
       
   417     self->ConstructL(aProtocolId, aSpi, aNotifyType, aNotifyData);
       
   418     CleanupStack::Pop(self);
       
   419     
       
   420     return self;
       
   421     }
       
   422 
       
   423 
       
   424 CIkeV2NotifyPayload::CIkeV2NotifyPayload()
       
   425 :CIkeV2Payload(IKEV2_PAYLOAD_NOTIF)
       
   426     {
       
   427     }
       
   428 
       
   429 
       
   430 void CIkeV2NotifyPayload::ConstructL(TUint8 aProtocolId,
       
   431                                      const TDesC8& aSpi,
       
   432                                      TUint16 aNotifyType,
       
   433                                      const TDesC8& aNotifyData)
       
   434     {    
       
   435     TUint32 length = aSpi.Length() + aNotifyData.Length() + KNotifyHeaderLength;
       
   436 
       
   437     iPayloadData = HBufC8::NewL(length);
       
   438     TPtr8 payloadDataPtr(iPayloadData->Des());
       
   439     payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength);    
       
   440     payloadDataPtr.FillZ();
       
   441     
       
   442     SetPayloadLength(length);
       
   443 
       
   444     TPtrC8 protocolIdPtr(&aProtocolId, sizeof(aProtocolId));
       
   445     TUint8 spiSize = aSpi.Length();
       
   446     TPtrC8 spiSizePtr(&spiSize, sizeof(spiSize));
       
   447     
       
   448     BigEndian::Put16(reinterpret_cast<TUint8*>(&aNotifyType), aNotifyType);
       
   449     TPtrC8 notifyTypePtr(reinterpret_cast<TUint8*>(&aNotifyType), sizeof(aNotifyType));
       
   450     
       
   451     
       
   452     payloadDataPtr.Append(protocolIdPtr);
       
   453     payloadDataPtr.Append(spiSizePtr);
       
   454     payloadDataPtr.Append(notifyTypePtr);
       
   455     payloadDataPtr.Append(aSpi);
       
   456     payloadDataPtr.Append(aNotifyData);  
       
   457     
       
   458     __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant());
       
   459     }
       
   460 
       
   461 
       
   462 CIkeV2ConfigurationPayload* CIkeV2ConfigurationPayload::NewL(TUint8 aCfgType, 
       
   463                                                              const TDesC8& aConfigurationData)
       
   464     {
       
   465     CIkeV2ConfigurationPayload* self = new (ELeave) CIkeV2ConfigurationPayload;
       
   466     CleanupStack::PushL(self);
       
   467     self->ConstructL(aCfgType, aConfigurationData);
       
   468     CleanupStack::Pop(self);
       
   469     
       
   470     return self;
       
   471     }
       
   472 
       
   473 
       
   474 CIkeV2ConfigurationPayload::CIkeV2ConfigurationPayload()
       
   475 : CIkeV2Payload(IKEV2_PAYLOAD_CONFIG)
       
   476     {    
       
   477     }
       
   478 
       
   479 
       
   480 void CIkeV2ConfigurationPayload::ConstructL(TUint8 aCfgType, 
       
   481                                             const TDesC8& aConfigurationData)
       
   482     {
       
   483     static const TUint8 KReservedFieldLength = 3;
       
   484     
       
   485     TUint32 length = aConfigurationData.Length() + KConfigurationHeaderLength;
       
   486 
       
   487     iPayloadData = HBufC8::NewL(length);
       
   488     TPtr8 payloadDataPtr(iPayloadData->Des());
       
   489     payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength);    
       
   490     payloadDataPtr.FillZ();
       
   491     
       
   492     SetPayloadLength(length);
       
   493 
       
   494     TPtrC8 cfgTypePtr(reinterpret_cast<TUint8*>(&aCfgType), sizeof(aCfgType));
       
   495     payloadDataPtr.Append(cfgTypePtr);
       
   496     
       
   497     //Leave reserved bytes zero
       
   498     payloadDataPtr.SetLength(payloadDataPtr.Length() + KReservedFieldLength);    
       
   499     TPtr8 reservedField = payloadDataPtr.RightTPtr(KReservedFieldLength);
       
   500     reservedField.FillZ();
       
   501     
       
   502     payloadDataPtr.Append(aConfigurationData);  
       
   503 
       
   504     __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant());
       
   505     }
       
   506 
       
   507 
       
   508 CIkeV2VendorIdPayload* CIkeV2VendorIdPayload::NewL(const TDesC8& aVendorIdData)
       
   509     {
       
   510     CIkeV2VendorIdPayload* self = new (ELeave) CIkeV2VendorIdPayload;
       
   511     CleanupStack::PushL(self);
       
   512     self->ConstructL(aVendorIdData);
       
   513     CleanupStack::Pop(self);
       
   514     
       
   515     return self;
       
   516     }
       
   517 
       
   518 
       
   519 CIkeV2VendorIdPayload::CIkeV2VendorIdPayload()
       
   520 :CIkeV2Payload(IKEV2_PAYLOAD_VID)
       
   521     {    
       
   522     }
       
   523 
       
   524 
       
   525 void CIkeV2VendorIdPayload::ConstructL(const TDesC8& aVendorIdData)
       
   526     {        
       
   527     TUint32 length = aVendorIdData.Length() + KVendorIdHeaderLength;
       
   528 
       
   529     iPayloadData = HBufC8::NewL(length);
       
   530     TPtr8 payloadDataPtr(iPayloadData->Des());
       
   531     payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength);
       
   532     payloadDataPtr.FillZ();
       
   533     
       
   534     SetPayloadLength(length);
       
   535     
       
   536     payloadDataPtr.Append(aVendorIdData);    
       
   537     
       
   538     __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant());
       
   539     }
       
   540 
       
   541 
       
   542 CIkeV2DeletePayload* CIkeV2DeletePayload::NewL(TUint8 aProtocolId, 
       
   543                                               const CDesC8Array& aSpiList)
       
   544     {
       
   545     CIkeV2DeletePayload* self = new (ELeave) CIkeV2DeletePayload;
       
   546     CleanupStack::PushL(self);
       
   547     self->ConstructL(aProtocolId, aSpiList);
       
   548     CleanupStack::Pop(self);
       
   549     
       
   550     return self;
       
   551     }
       
   552 
       
   553 
       
   554 CIkeV2DeletePayload::CIkeV2DeletePayload()
       
   555 :CIkeV2Payload(IKEV2_PAYLOAD_DELETE)
       
   556     {    
       
   557     }
       
   558 
       
   559 
       
   560 void CIkeV2DeletePayload::ConstructL(TUint8 aProtocolId, const CDesC8Array& aSpiList)
       
   561     {
       
   562     TUint16 spiCount = aSpiList.Count();
       
   563     TUint8 spiLength = (spiCount > 0) ? aSpiList[0].Length() : 0; 
       
   564     TUint32 length = KDeleteHeaderLength + (spiCount * spiLength);
       
   565     
       
   566     iPayloadData = HBufC8::NewL(length);
       
   567     TPtr8 payloadDataPtr(iPayloadData->Des());
       
   568     payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength);  
       
   569     payloadDataPtr.FillZ();
       
   570     
       
   571     SetPayloadLength(length);
       
   572 
       
   573     TPtrC8 protocolIdPtr(&aProtocolId, sizeof(aProtocolId));
       
   574     TPtrC8 spiLengthPtr(&spiLength, sizeof(spiLength));
       
   575     
       
   576     BigEndian::Put16(reinterpret_cast<TUint8*>(&spiCount), spiCount);    
       
   577     TPtrC8 spiCountPtr(reinterpret_cast<TUint8*>(&spiCount), sizeof(spiCount));
       
   578     
       
   579     payloadDataPtr.Append(protocolIdPtr);
       
   580     payloadDataPtr.Append(spiLengthPtr);
       
   581     payloadDataPtr.Append(spiCountPtr);
       
   582     
       
   583     for (TInt i = 0; i < aSpiList.Count(); ++i)
       
   584         {
       
   585         const TDesC8& spi = aSpiList[i];
       
   586         __ASSERT_DEBUG(spi.Length() == spiLength, User::Invariant());
       
   587         payloadDataPtr.Append(spi);
       
   588         }
       
   589     
       
   590     __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant());
       
   591     }
       
   592 
       
   593 
       
   594 CIkeV2EapPayload* CIkeV2EapPayload::NewL(const TDesC8& aEapData)
       
   595     {
       
   596     CIkeV2EapPayload* self = new (ELeave) CIkeV2EapPayload;
       
   597     CleanupStack::PushL(self);
       
   598     self->ConstructL(aEapData);
       
   599     CleanupStack::Pop(self);
       
   600     
       
   601     return self;
       
   602     }
       
   603 
       
   604 
       
   605 CIkeV2EapPayload::CIkeV2EapPayload()
       
   606 :CIkeV2Payload(IKEV2_PAYLOAD_EAP)
       
   607     {    
       
   608     }
       
   609 
       
   610 
       
   611 void CIkeV2EapPayload::ConstructL(const TDesC8& aEapData)
       
   612     {       
       
   613     TUint32 length = aEapData.Length() + KEapHeaderLength;
       
   614 
       
   615     iPayloadData = HBufC8::NewL(length);
       
   616     TPtr8 payloadDataPtr(iPayloadData->Des());    
       
   617     payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength);
       
   618     payloadDataPtr.FillZ();
       
   619     SetPayloadLength(length);
       
   620 
       
   621     payloadDataPtr.Append(aEapData);
       
   622     
       
   623     __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant());
       
   624     }
       
   625 
       
   626 
       
   627 
       
   628 CIkeV2TsPayload::CIkeV2TsPayload(TUint aPayloadType)
       
   629 :CIkeV2Payload(aPayloadType)
       
   630     {    
       
   631     }
       
   632 
       
   633 
       
   634 void CIkeV2TsPayload::ConstructL(const CArrayFix<TIkeV2TrafficSelector>& aTsList)
       
   635     {       
       
   636     //selector format: 
       
   637     //                       1                   2                   3
       
   638     //   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       
   639     //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   640     //   !   TS Type     !IP Protocol ID*|       Selector Length         |
       
   641     //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   642     //   |           Start Port*         |           End Port*           |
       
   643     //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   644     //   !                                                               !
       
   645     //   ~                         Starting Address*                     ~
       
   646     //   !                                                               !
       
   647     //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   648     //   !                                                               !
       
   649     //   ~                         Ending Address*                       ~
       
   650     //   !                                                               !
       
   651     //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+        
       
   652     const TUint16 KIpv4SelectorLength = 2*4 + 2*4; //fixed selector header + 2*IPv4 address length
       
   653     const TUint16 KIpv6SelectorLength = 2*4 + 2*16;//fixed selector header + 2*IPv6 address length   
       
   654     
       
   655     TUint8 tsCount = aTsList.Count();
       
   656     __ASSERT_DEBUG(tsCount > 0, User::Invariant());
       
   657 
       
   658     
       
   659     TUint32 length = KTsHeaderLength;
       
   660     
       
   661     TUint i;
       
   662     for (i = 0; i < aTsList.Count(); ++i)
       
   663         {
       
   664         if (aTsList[i].Type() == TS_IPV4_ADDR_RANGE)          
       
   665             {
       
   666             length += KIpv4SelectorLength; //fixed selector header + 2*IPv4 address length
       
   667             }
       
   668         else
       
   669             {
       
   670             __ASSERT_DEBUG(aTsList[i].Type() == TS_IPV6_ADDR_RANGE, User::Invariant());
       
   671             length += KIpv6SelectorLength; //fixed selector header + 2*IPv6 address length       
       
   672             }
       
   673         }
       
   674 
       
   675     iPayloadData = HBufC8::NewL(length);
       
   676     TPtr8 payloadDataPtr(iPayloadData->Des());
       
   677     payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength);  
       
   678     payloadDataPtr.FillZ();
       
   679     
       
   680     SetPayloadLength(length);
       
   681     
       
   682     const TPtrC8 tsCountPtr(&tsCount, sizeof(tsCount));
       
   683     payloadDataPtr.Append(tsCountPtr);
       
   684     
       
   685     _LIT(KReservedField, "\0\0\0");
       
   686     payloadDataPtr.Append(KReservedField);
       
   687     
       
   688     for (i = 0; i < aTsList.Count(); ++i)
       
   689         {
       
   690         TBuf8<KIpv6SelectorLength> selector;
       
   691         selector.Zero();
       
   692         const TIkeV2TrafficSelector& selectorData = aTsList[i]; 
       
   693         TUint8 type = selectorData.Type();
       
   694         selector.Append(&type, sizeof(type));
       
   695         
       
   696         TUint8 protocol = selectorData.ProtocolId();
       
   697         selector.Append(&protocol, sizeof(protocol));
       
   698         
       
   699         TUint16 selectorLength = 0;
       
   700         if (selectorData.Type() == TS_IPV4_ADDR_RANGE)          
       
   701              {
       
   702              BigEndian::Put16(reinterpret_cast<TUint8*>(&selectorLength), KIpv4SelectorLength);
       
   703              }
       
   704          else
       
   705              {
       
   706              BigEndian::Put16(reinterpret_cast<TUint8*>(&selectorLength), KIpv6SelectorLength);
       
   707              }  
       
   708         selector.Append(reinterpret_cast<TUint8*>(&selectorLength), sizeof(selectorLength));
       
   709         
       
   710         TInetAddr startAddress = selectorData.StartingAddress();
       
   711         TInetAddr endAddress = selectorData.EndingAddress();
       
   712         
       
   713         TUint16 startPort = startAddress.Port(); 
       
   714         TUint16 endPort = endAddress.Port();
       
   715         
       
   716         BigEndian::Put16(reinterpret_cast<TUint8*>(&startPort), startPort);
       
   717         BigEndian::Put16(reinterpret_cast<TUint8*>(&endPort), endPort);
       
   718         
       
   719         selector.Append(reinterpret_cast<TUint8*>(&startPort), sizeof(startPort));
       
   720         selector.Append(reinterpret_cast<TUint8*>(&endPort), sizeof(endPort));
       
   721         
       
   722         if (selectorData.Type() == TS_IPV4_ADDR_RANGE)          
       
   723              {
       
   724              TUint32 start = 0;
       
   725              TUint32 end = 0;
       
   726              BigEndian::Put32(reinterpret_cast<TUint8*>(&start), startAddress.Address());
       
   727              BigEndian::Put32(reinterpret_cast<TUint8*>(&end), endAddress.Address());
       
   728              
       
   729              selector.Append(reinterpret_cast<TUint8*>(&start), sizeof(start));
       
   730              selector.Append(reinterpret_cast<TUint8*>(&end), sizeof(end));
       
   731              }
       
   732          else
       
   733              {
       
   734              TPtrC8 start(&startAddress.Ip6Address().u.iAddr8[0], 16);
       
   735              TPtrC8 end(&endAddress.Ip6Address().u.iAddr8[0], 16);
       
   736              selector.Append(start);
       
   737              selector.Append(end);             
       
   738              }   
       
   739         payloadDataPtr.Append(selector);
       
   740         }    
       
   741     
       
   742     __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant());
       
   743     }
       
   744 
       
   745 
       
   746 CIkeV2TsiPayload* CIkeV2TsiPayload::NewL(const CArrayFix<TIkeV2TrafficSelector>& aTsList)
       
   747     {
       
   748     CIkeV2TsiPayload* self = new (ELeave) CIkeV2TsiPayload();
       
   749     CleanupStack::PushL(self);
       
   750     self->ConstructL(aTsList);
       
   751     CleanupStack::Pop(self);
       
   752     
       
   753     return self;
       
   754     }
       
   755 
       
   756 
       
   757 CIkeV2TsiPayload::CIkeV2TsiPayload()
       
   758 :CIkeV2TsPayload(IKEV2_PAYLOAD_TS_I)
       
   759     {
       
   760     
       
   761     }
       
   762 
       
   763 
       
   764 CIkeV2TsrPayload* CIkeV2TsrPayload::NewL(const CArrayFix<TIkeV2TrafficSelector>& aTsList)
       
   765     {
       
   766     CIkeV2TsrPayload* self = new (ELeave) CIkeV2TsrPayload();
       
   767     CleanupStack::PushL(self);
       
   768     self->ConstructL(aTsList);
       
   769     CleanupStack::Pop(self);
       
   770     
       
   771     return self;    
       
   772     }
       
   773 
       
   774 
       
   775 CIkeV2TsrPayload::CIkeV2TsrPayload()
       
   776 :CIkeV2TsPayload(IKEV2_PAYLOAD_TS_R)
       
   777     {    
       
   778     }
       
   779 
       
   780 
       
   781 CIkeV2EncryptedPayload* CIkeV2EncryptedPayload::NewL(TUint aBlockSize)
       
   782     {
       
   783     CIkeV2EncryptedPayload* self = new (ELeave) CIkeV2EncryptedPayload;
       
   784     CleanupStack::PushL(self);
       
   785     self->ConstructL(aBlockSize);
       
   786     CleanupStack::Pop(self);
       
   787     
       
   788     return self;
       
   789     }
       
   790 
       
   791 
       
   792 CIkeV2EncryptedPayload::CIkeV2EncryptedPayload()
       
   793 :CIkeV2TsPayload(IKEV2_PAYLOAD_ENCR)
       
   794     {    
       
   795     }
       
   796 
       
   797 
       
   798 void CIkeV2EncryptedPayload::ConstructL(TUint aBlockSize)
       
   799     {
       
   800     TUint32 length = aBlockSize + KEncryptedHeaderLength;
       
   801 
       
   802     iPayloadData = HBufC8::NewL(length);
       
   803     TPtr8 payloadDataPtr(iPayloadData->Des());
       
   804     payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength);    
       
   805     payloadDataPtr.FillZ();
       
   806     
       
   807     SetPayloadLength(length);
       
   808     payloadDataPtr.SetLength(length);
       
   809     
       
   810     TPtr8 Iv = payloadDataPtr.MidTPtr(KEncryptedHeaderLength);
       
   811     Iv.SetLength(aBlockSize);
       
   812     TRandom::RandomL(Iv);        
       
   813     
       
   814     iBlockSize = aBlockSize;
       
   815     
       
   816     __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant());
       
   817     }
       
   818 
       
   819 TUint CIkeV2EncryptedPayload::BlockSize() const
       
   820     {
       
   821     return iBlockSize;
       
   822     }
       
   823 
       
   824 TPtrC8 CIkeV2EncryptedPayload::InitializationVector() const
       
   825     {
       
   826     return iPayloadData->Right(iBlockSize);
       
   827     }
       
   828 
       
   829 void CIkeV2EncryptedPayload::SetContentLength(TUint16 aLength)
       
   830     {
       
   831     //Set the payload length to be: header + Iv + content
       
   832     SetPayloadLength(aLength + iPayloadData->Length());
       
   833     }
       
   834 
       
   835 static const TUint   KDefaultMessageSize = 4096;
       
   836 static const TUint32 KIkeV2MsgHeaderLength = 28;
       
   837 static const TUint8  KIkeV2Version = 2 << 4;
       
   838 
       
   839 CIkeV2Message* CIkeV2Message::NewL(const TDesC8& aInitiatorSpi,
       
   840                                    const TDesC8& aResponderSpi,
       
   841                                    TUint8 aExchangeType,
       
   842                                    TBool aIntiator,
       
   843                                    TBool aResponse,
       
   844                                    TUint32 aMessageId,
       
   845                                    MIkeDebug& aDebug)
       
   846     {
       
   847     CIkeV2Message* self = new (ELeave)CIkeV2Message(aDebug);
       
   848     CleanupStack::PushL(self);
       
   849     self->ConstructL(aInitiatorSpi,
       
   850                      aResponderSpi,
       
   851                      aExchangeType,
       
   852                      aIntiator,
       
   853                      aResponse,
       
   854                      aMessageId);
       
   855     CleanupStack::Pop(self);
       
   856     
       
   857     return self;
       
   858     }
       
   859 
       
   860 
       
   861 CIkeV2Message::CIkeV2Message(MIkeDebug& aDebug)
       
   862 :iDebug(aDebug), iModified(ETrue)
       
   863     {    
       
   864     }
       
   865 
       
   866 
       
   867 void CIkeV2Message::ConstructL(const TDesC8& aInitiatorSpi,
       
   868                                const TDesC8& aResponderSpi,
       
   869                                TUint8 aExchangeType,   
       
   870                                TBool aIntiator,
       
   871                                TBool aResponse,
       
   872                                TUint32 aMessageId)
       
   873     {
       
   874     __ASSERT_DEBUG(aInitiatorSpi.Length() == 8, User::Invariant());
       
   875     __ASSERT_DEBUG(aResponderSpi.Length() == 8, User::Invariant());
       
   876     
       
   877     iIkeV2MessageHeader = HBufC8::NewL(KDefaultMessageSize);    
       
   878     TPtr8 messageDataPtr = iIkeV2MessageHeader->Des();
       
   879     
       
   880    
       
   881     const TPtrC8 versionPtr(&KIkeV2Version, sizeof(TUint8));    
       
   882     const TPtrC8 exchangeTypePtr(&aExchangeType, sizeof(TUint8));
       
   883     
       
   884     TUint8 flags = (aIntiator) ? IKEV2_INITIATOR : 0;
       
   885     flags |= (aResponse) ? IKEV2_RESPONSE_MSG : 0; 
       
   886     
       
   887     
       
   888     const TPtrC8 flagsPtr(&flags, sizeof(flags));
       
   889     BigEndian::Put32(reinterpret_cast<TUint8*>(&aMessageId), aMessageId);
       
   890     const TPtrC8 messageIdPtr(reinterpret_cast<TUint8*>(&aMessageId), sizeof(TUint32));
       
   891     
       
   892     TUint32 length;
       
   893     BigEndian::Put32(reinterpret_cast<TUint8*>(&length), KIkeV2MsgHeaderLength);
       
   894     const TPtrC8 lengthPtr(reinterpret_cast<TUint8*>(&length), sizeof(TUint32));
       
   895     
       
   896     //Add SPIs
       
   897     messageDataPtr.Append(aInitiatorSpi);
       
   898     messageDataPtr.Append(aResponderSpi);
       
   899     
       
   900     //Left next payload as zero
       
   901     TUint8 nextPayload = 0;
       
   902     TPtrC8 nextPayloadPtr(&nextPayload, sizeof(nextPayload));
       
   903     messageDataPtr.Append(nextPayloadPtr);
       
   904     
       
   905     messageDataPtr.Append(versionPtr);
       
   906     messageDataPtr.Append(exchangeTypePtr);
       
   907     messageDataPtr.Append(flagsPtr);
       
   908     messageDataPtr.Append(messageIdPtr);
       
   909     messageDataPtr.Append(lengthPtr);
       
   910     
       
   911     __ASSERT_DEBUG(iIkeV2MessageHeader->Length() == KIkeV2MsgHeaderLength, User::Invariant());
       
   912     }
       
   913 
       
   914 
       
   915 CIkeV2Message::~CIkeV2Message()
       
   916     {
       
   917     delete iIkeV2Datagram;
       
   918     delete iIkeV2MessageHeader;
       
   919     iPayloads.ResetAndDestroy();
       
   920     iPayloads.Close();
       
   921     }
       
   922 
       
   923 
       
   924 TPtrC8 CIkeV2Message::InitiatorSpi()const
       
   925     {
       
   926     TUint KInitiatorSpiPosition = 0;
       
   927     TUint KSpiLength = 8;
       
   928     
       
   929     return iIkeV2MessageHeader->Mid(KInitiatorSpiPosition, KSpiLength);
       
   930     }
       
   931 
       
   932 
       
   933 TPtrC8 CIkeV2Message::ResponderSpi() const
       
   934     {
       
   935     TUint KResponderSpiPosition = 8;
       
   936     TUint KSpiLength = 8;
       
   937     
       
   938     return iIkeV2MessageHeader->Mid(KResponderSpiPosition, KSpiLength);
       
   939     }
       
   940 
       
   941 
       
   942 TUint8 CIkeV2Message::Flags() const
       
   943     {
       
   944     TUint KFlagsPosition = 19;
       
   945     return (*iIkeV2MessageHeader)[KFlagsPosition];
       
   946     }
       
   947 
       
   948 
       
   949 TUint32 CIkeV2Message::MessageId() const
       
   950     {
       
   951     __ASSERT_DEBUG(iIkeV2MessageHeader->Length() >= KIkeV2MsgHeaderLength, User::Invariant());
       
   952     const TUint8* messageIdPtr = iIkeV2MessageHeader->Ptr() + KMessageIdFieldOffset; 
       
   953     return BigEndian::Get32(messageIdPtr);
       
   954     
       
   955     }
       
   956 
       
   957 
       
   958 void CIkeV2Message::AppendCertReqPayloadL(const CIkeCaList& aCaList)
       
   959     {
       
   960     __ASSERT_DEBUG(aCaList.Count() > 0, User::Invariant());
       
   961 
       
   962     CIkevV2CertReqPayload* certReqPayload = CIkevV2CertReqPayload::NewL(aCaList);
       
   963     AppendPayloadL(certReqPayload);
       
   964     }
       
   965 
       
   966 
       
   967 void CIkeV2Message::AppendCertPayloadL(const TDesC8& aCertificateData)
       
   968     {
       
   969     CIkevV2CertPayload* certPayload = CIkevV2CertPayload::NewL(aCertificateData);
       
   970     AppendPayloadL(certPayload);
       
   971     }
       
   972 
       
   973 
       
   974 void CIkeV2Message::AppendSaPayloadL(const TDesC8& aSaData)
       
   975     {
       
   976     CIkevV2SaPayload* saPayload = CIkevV2SaPayload::NewL(aSaData);
       
   977     AppendPayloadL(saPayload);
       
   978     }
       
   979 
       
   980 
       
   981 void CIkeV2Message::AppendKePayloadL(TUint16 aDHGroup, const TDesC8& aKeData)
       
   982     {
       
   983     CIkevV2KePayload* kePayload = CIkevV2KePayload::NewL(aDHGroup, aKeData);
       
   984     AppendPayloadL(kePayload);
       
   985     }
       
   986 
       
   987 
       
   988 void CIkeV2Message::AppendNoncePayloadL(const TDesC8& aNonceData)
       
   989     {
       
   990     CIkevV2NoncePayload* noncePayload = CIkevV2NoncePayload::NewL(aNonceData);
       
   991     AppendPayloadL(noncePayload);
       
   992     }
       
   993 
       
   994 
       
   995 void CIkeV2Message::AppendIdiPayloadL(const CIkeV2Identity& aIdentity)
       
   996     {
       
   997     CIkevV2IdiPayload* idiPayload = CIkevV2IdiPayload::NewL(aIdentity);  
       
   998     AppendPayloadL(idiPayload);
       
   999     }
       
  1000 
       
  1001 
       
  1002 void CIkeV2Message::AppendIdrPayloadL(const CIkeV2Identity& aIdentity)
       
  1003     {
       
  1004     CIkevV2IdrPayload* idrPayload = CIkevV2IdrPayload::NewL(aIdentity);  
       
  1005     AppendPayloadL(idrPayload);    
       
  1006     }
       
  1007 
       
  1008 void CIkeV2Message::AppendAuthPayloadL(TUint8 aAuthMethod, const TDesC8& aAuthData)
       
  1009     {
       
  1010     CIkeV2AuthPayload* authPayload = CIkeV2AuthPayload::NewL(aAuthMethod, aAuthData);
       
  1011     AppendPayloadL(authPayload);
       
  1012     }
       
  1013 
       
  1014 
       
  1015 void CIkeV2Message::AppendNotifyPayloadL(TUint8 aProtocolId,
       
  1016                                          const TDesC8& aSpi,
       
  1017                                          TUint16 aNotifyType,
       
  1018                                          const TDesC8& aNotifyData)
       
  1019     {
       
  1020     CIkeV2NotifyPayload* notifyPayload = CIkeV2NotifyPayload::NewL(aProtocolId, aSpi,
       
  1021                                                                    aNotifyType, aNotifyData);
       
  1022     AppendPayloadL(notifyPayload);
       
  1023     }
       
  1024 
       
  1025 void CIkeV2Message::PrependCookieNotifyPayloadL(const TDesC8& aCookieData)
       
  1026     {
       
  1027     _LIT8(KZeroDesc, "");
       
  1028     CIkeV2NotifyPayload* notifyPayload = CIkeV2NotifyPayload::NewL(0, KZeroDesc,
       
  1029                                                                    COOKIE, aCookieData);
       
  1030     
       
  1031     delete iIkeV2Datagram;
       
  1032     iIkeV2Datagram = NULL;    
       
  1033     iModified = ETrue;
       
  1034 
       
  1035     if (iPayloads.Count() > 0)
       
  1036         {
       
  1037         notifyPayload->SetNextPayload(iPayloads[0]->PayloadType());
       
  1038         }
       
  1039     
       
  1040     TInt err = iPayloads.Insert(notifyPayload, 0);
       
  1041     if (err != KErrNone)
       
  1042         {
       
  1043         delete notifyPayload;
       
  1044         User::Leave(err);
       
  1045         }
       
  1046     
       
  1047     SetNextPayload(notifyPayload->PayloadType());    
       
  1048     }
       
  1049 
       
  1050 
       
  1051 void CIkeV2Message::AppendConfigurationPayloadL(TUint8 aCfgType, 
       
  1052                                                const TDesC8& aConfigurationData)
       
  1053     {
       
  1054     CIkeV2ConfigurationPayload* configPayload = 
       
  1055                         CIkeV2ConfigurationPayload::NewL(aCfgType, aConfigurationData);
       
  1056     AppendPayloadL(configPayload);
       
  1057     }
       
  1058 
       
  1059 
       
  1060 void CIkeV2Message::AppendVendorIdPayloadL(const TDesC8& aVendorIdData)
       
  1061     {
       
  1062     CIkeV2VendorIdPayload* vendorIdPayload = CIkeV2VendorIdPayload::NewL(aVendorIdData);
       
  1063     AppendPayloadL(vendorIdPayload);
       
  1064     }
       
  1065 
       
  1066 void CIkeV2Message::AppendDeletePayloadL(TUint8 aProtocolId, const CDesC8Array& aSpiList)
       
  1067     {
       
  1068     CIkeV2DeletePayload* deletePayload = CIkeV2DeletePayload::NewL(aProtocolId, aSpiList);
       
  1069     AppendPayloadL(deletePayload);
       
  1070     }
       
  1071 
       
  1072 
       
  1073 void CIkeV2Message::AppendEapPayloadL(const TDesC8& aEapData)
       
  1074     {
       
  1075     CIkeV2EapPayload* eapPayload = CIkeV2EapPayload::NewL(aEapData);
       
  1076     AppendPayloadL(eapPayload);
       
  1077     }
       
  1078 
       
  1079 
       
  1080 void CIkeV2Message::AppendTsiPayloadL(const CArrayFix<TIkeV2TrafficSelector>& aTsList)
       
  1081     {
       
  1082     CIkeV2TsiPayload* tsPayload = CIkeV2TsiPayload::NewL(aTsList);
       
  1083     AppendPayloadL(tsPayload);
       
  1084     }
       
  1085 
       
  1086 
       
  1087 void CIkeV2Message::AppendTsrPayloadL(const CArrayFix<TIkeV2TrafficSelector>& aTsList)
       
  1088     {
       
  1089     CIkeV2TsrPayload* tsPayload = CIkeV2TsrPayload::NewL(aTsList);
       
  1090     AppendPayloadL(tsPayload);    
       
  1091     }
       
  1092 
       
  1093 
       
  1094 void CIkeV2Message::AppendEncryptedPayloadL(TUint aBlockSize)
       
  1095     {
       
  1096     __ASSERT_DEBUG(iPayloads.Count() == 0, User::Invariant());
       
  1097     CIkeV2EncryptedPayload* encryptedPayload = CIkeV2EncryptedPayload::NewL(aBlockSize);
       
  1098     AppendPayloadL(encryptedPayload);
       
  1099     }
       
  1100 
       
  1101 void CIkeV2Message::PrepareIkeMessageDatagramL(TUint16 aEncryptionAlgorith, 
       
  1102                                                const TDesC8& aEncryptionKey,
       
  1103                                                TUint16 aIntegrityAlgorithm,
       
  1104                                                const TDesC8& aIntegrityKey,
       
  1105 #ifdef _DEBUG                                               
       
  1106                                                const TInetAddr& aSourceAddress,
       
  1107 #else
       
  1108                                                const TInetAddr& /*aSourceAddress*/,
       
  1109 #endif                                               
       
  1110                                                const TInetAddr& aDestinationAddress)
       
  1111     {    
       
  1112     __ASSERT_DEBUG(iPayloads.Count() > 0, User::Invariant());
       
  1113     
       
  1114     if (iModified)
       
  1115         {        
       
  1116         __ASSERT_DEBUG(iIkeV2Datagram == NULL, User::Invariant());
       
  1117         
       
  1118         if (iPayloads[0]->PayloadType() == IKEV2_PAYLOAD_ENCR)
       
  1119             {
       
  1120             //Datagram is should be encrypted
       
  1121             //Calculate the length of the padding
       
  1122             CIkeV2EncryptedPayload* encryptedPayload = static_cast<CIkeV2EncryptedPayload*>(iPayloads[0]);
       
  1123             TUint encryptedDataLength = 0;
       
  1124             for(TInt i = 1; i < iPayloads.Count(); ++i)
       
  1125                 {
       
  1126                 encryptedDataLength += iPayloads[i]->PayloadLength();
       
  1127                 }
       
  1128             
       
  1129             //If the data length is multiple of the blocksize, we add full block length
       
  1130             //of padding. Otherwise we just add padding enough to fill the block.
       
  1131             TUint8 paddingLength = encryptedPayload->BlockSize() -
       
  1132                                    encryptedDataLength % encryptedPayload->BlockSize();
       
  1133             //The last octet of the padding tells the length of the padding.
       
  1134             //we just use that value to fill the entire padding.
       
  1135             TInt integrityCheckSumLength = 0;
       
  1136             IkeCrypto::AlgorithmInfo(IKEV2_INTEG, aIntegrityAlgorithm, &integrityCheckSumLength);
       
  1137             
       
  1138             
       
  1139             //The length of the whole datagram:
       
  1140             TUint32 datagramLength = iIkeV2MessageHeader->Length() +
       
  1141                                      encryptedPayload->PayloadLength() +
       
  1142                                      encryptedDataLength + 
       
  1143                                      paddingLength +
       
  1144                                      integrityCheckSumLength;
       
  1145     
       
  1146             //Update header fields
       
  1147             SetLength(datagramLength);
       
  1148             encryptedPayload->SetContentLength((TUint16)(encryptedDataLength + 
       
  1149                                                          paddingLength + 
       
  1150                                                          integrityCheckSumLength));
       
  1151     
       
  1152             //Allocate buffer, which has space for the whole datagram. (+ Non ESP marker)
       
  1153             HBufC8* datagram = HBufC8::NewLC(datagramLength + KNonEspMarker().Length());
       
  1154             TPtr8 datagramPtr = datagram->Des();
       
  1155             
       
  1156             datagramPtr = *iIkeV2MessageHeader;
       
  1157             datagramPtr.Append(encryptedPayload->PayloadData());
       
  1158             
       
  1159             //buffer for data, which is encrypted
       
  1160             HBufC8* encryptionSource = HBufC8::NewLC(encryptedDataLength + 
       
  1161                                                      paddingLength);
       
  1162             TPtr8 encryptionSourcePtr = encryptionSource->Des();
       
  1163             
       
  1164             for (TInt i = 1; i < iPayloads.Count(); ++i)
       
  1165                 {
       
  1166                 const CIkeV2Payload* pl = iPayloads[i];                 
       
  1167                 __ASSERT_DEBUG(pl->PayloadData().Length() == pl->PayloadLength(), User::Invariant());
       
  1168                 
       
  1169                 encryptionSourcePtr.Append(pl->PayloadData());                
       
  1170                 datagramPtr.Append(pl->PayloadData()); //This is because we want to trace the datagram              
       
  1171                 }
       
  1172              
       
  1173             
       
  1174             //Last byte of the padding has to be the length of the padding.
       
  1175             //We fillup the whole padding with this same number
       
  1176             TUint8 paddingValue = paddingLength - 1;
       
  1177             for (TInt i = 0; i < paddingLength; ++i)
       
  1178                 {
       
  1179                 encryptionSourcePtr.Append(&paddingValue, 1);                
       
  1180                 datagramPtr.Append(&paddingValue, 1);
       
  1181                 }
       
  1182             
       
  1183             
       
  1184             datagramPtr.SetLength(datagram->Length() + integrityCheckSumLength);
       
  1185             TRACE_MSG(*datagram, aSourceAddress, aDestinationAddress, 
       
  1186                       (CIkePcapTrace::TEncryptionType)aEncryptionAlgorith);
       
  1187             datagramPtr.SetLength(datagram->Length() - integrityCheckSumLength);
       
  1188             
       
  1189             //Extracts the data, which is encrypted. 
       
  1190             //(Excludes IKE hdr, Encrypted payload hdr and Iv)
       
  1191             TPtr8 encryptionBuffer = datagramPtr.MidTPtr(iIkeV2MessageHeader->Length() + 
       
  1192                                                          KEncryptedHeaderLength + 
       
  1193                                                          encryptedPayload->BlockSize());
       
  1194             __ASSERT_DEBUG(encryptionBuffer.Length() == encryptionSource->Length(), User::Invariant());
       
  1195             encryptionBuffer.SetLength(0);
       
  1196             IkeCrypto::EncryptL(*encryptionSource, encryptionBuffer, 
       
  1197                                 encryptedPayload->InitializationVector(), 
       
  1198                                 aEncryptionKey, aEncryptionAlgorith);
       
  1199             
       
  1200             CleanupStack::PopAndDestroy(encryptionSource);
       
  1201             
       
  1202             //Extracts the space for the checksum from the end of the buffer
       
  1203             TUint lengthWithoutItegrityCheckSum = datagramPtr.Length();
       
  1204             datagramPtr.SetLength(lengthWithoutItegrityCheckSum + integrityCheckSumLength);
       
  1205             TPtr8 checksum = datagramPtr.MidTPtr(lengthWithoutItegrityCheckSum);           
       
  1206             
       
  1207             //Extracts the source for the integrity checksum calculation
       
  1208             TPtrC8 integrityCheckSumSource = datagram->Left(lengthWithoutItegrityCheckSum);            
       
  1209             IkeCrypto::IntegHMACL(integrityCheckSumSource, checksum, aIntegrityKey, aIntegrityAlgorithm);
       
  1210                         
       
  1211             CleanupStack::Pop(datagram);
       
  1212             iIkeV2Datagram = datagram;             
       
  1213             }    
       
  1214         else
       
  1215             {
       
  1216             //calculate the length of unencrypted datagram
       
  1217             TUint datagramLength = iIkeV2MessageHeader->Length();
       
  1218             for (TInt i = 0; i < iPayloads.Count(); ++i)
       
  1219                 {
       
  1220                 datagramLength += iPayloads[i]->PayloadLength();         
       
  1221                 }
       
  1222             SetLength(datagramLength);
       
  1223             
       
  1224             iIkeV2Datagram = HBufC8::NewL(datagramLength + KNonEspMarker().Length());
       
  1225             TPtr8 ikeV2DatargramPtr = iIkeV2Datagram->Des();
       
  1226             ikeV2DatargramPtr.Append(*iIkeV2MessageHeader);
       
  1227             
       
  1228             for (TInt i = 0; i < iPayloads.Count(); ++i)
       
  1229                 {
       
  1230                 ikeV2DatargramPtr.Append(iPayloads[i]->PayloadData());
       
  1231                 }
       
  1232             TRACE_MSG(*iIkeV2Datagram, aSourceAddress, aDestinationAddress, 
       
  1233                       (CIkePcapTrace::TEncryptionType)aEncryptionAlgorith);
       
  1234 
       
  1235             }  
       
  1236         
       
  1237         if (aDestinationAddress.Port() == FLOATED_IKE_PORT)
       
  1238             {
       
  1239             //insert non esp marker
       
  1240             iIkeV2Datagram->Des().Insert(0, KNonEspMarker);
       
  1241             }
       
  1242         iModified = EFalse;
       
  1243         }
       
  1244    
       
  1245     __ASSERT_DEBUG(!iModified && iIkeV2Datagram != NULL, User::Invariant());
       
  1246     }
       
  1247 
       
  1248 
       
  1249 TPtrC8 CIkeV2Message::IkeMessageDatagram() const
       
  1250     {
       
  1251     __ASSERT_DEBUG(!iModified && iIkeV2Datagram != NULL, User::Invariant());
       
  1252     return *iIkeV2Datagram;
       
  1253     }
       
  1254 
       
  1255 
       
  1256 void CIkeV2Message::AppendPayloadL(CIkeV2Payload* aPayload)
       
  1257     {
       
  1258     TInt err = iPayloads.Append(aPayload);    
       
  1259     if (err != KErrNone)
       
  1260         {
       
  1261         delete aPayload;
       
  1262         User::Leave(err);
       
  1263         }
       
  1264     
       
  1265     if (iPayloads.Count() > 1)
       
  1266         {
       
  1267         iPayloads[iPayloads.Count() - 2]->SetNextPayload(aPayload->PayloadType());
       
  1268         }
       
  1269     else
       
  1270         {
       
  1271         SetNextPayload(aPayload->PayloadType());
       
  1272         }    
       
  1273     
       
  1274     delete iIkeV2Datagram;
       
  1275     iIkeV2Datagram = NULL;    
       
  1276     iModified = ETrue;
       
  1277     }
       
  1278 
       
  1279 void CIkeV2Message::SetLength(TUint32 aDatagramLength)
       
  1280     {
       
  1281     static const TUint KLengthFieldPosition = 6*4;
       
  1282     BigEndian::Put32(reinterpret_cast<TUint8*>(&aDatagramLength), aDatagramLength);
       
  1283     TPtr8 lengthField = iIkeV2MessageHeader->Des().MidTPtr(KLengthFieldPosition, sizeof(aDatagramLength));
       
  1284     lengthField = TPtrC8(reinterpret_cast<TUint8*>(&aDatagramLength), sizeof(aDatagramLength));
       
  1285     }
       
  1286 
       
  1287 
       
  1288 void CIkeV2Message::SetNextPayload(TUint8 aNextPayload)
       
  1289     {
       
  1290     const TUint KNextPayloadPosition =  16;
       
  1291     TPtr8 ikeHeaderPtr = iIkeV2MessageHeader->Des();
       
  1292     ikeHeaderPtr[KNextPayloadPosition] = aNextPayload;
       
  1293     }