vpnengine/ikev1lib/src/ikev1isakmpstream.cpp
changeset 0 33413c0669b9
child 2 ef893827b4d1
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2007-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:  Stream class implementation for ISAKMP
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "ikev1isakmpstream.h"
       
    20 #include "ikemsgheader.h"
       
    21 #include "ikev1negotiation.h"
       
    22 #include "ikedebug.h"
       
    23 #include "ikev1trans.h"
       
    24 #include "ikecalist.h"
       
    25 #include "ikecaelem.h"
       
    26 #include "ikepolparser.h"
       
    27 #include "ikev1crypto.h"
       
    28 #include "ikev1pkiservice.h"
       
    29 #include "ikev1private.h"
       
    30 #include "ikepkiutils.h"
       
    31 #include "ikev1natdiscovery.h"
       
    32 
       
    33 //
       
    34 //  TIkev1IsakmpStream
       
    35 //
       
    36 
       
    37 TIkev1IsakmpStream::TIkev1IsakmpStream( MIkeDebug& aDebug )
       
    38  : iDebug( aDebug )
       
    39     {    
       
    40     }
       
    41 
       
    42 void TIkev1IsakmpStream::IsakmpInit(CIkev1Negotiation *aSession)
       
    43 {
       
    44     ThdrISAKMP hdr;
       
    45 
       
    46     iError = EFalse;
       
    47     iNegotiation = aSession;    //stores it to avoid passing it for all the functions
       
    48     DEBUG_LOG(_L("[HDR]"));
       
    49     hdr.SetCookieI(iNegotiation->iCookie_I);
       
    50     hdr.SetCookieR(iNegotiation->iCookie_R);
       
    51     hdr.SetPayload(0);  //Is set later through the pointer iNextPayload
       
    52     hdr.SetVersion(0x10);   //MAJOR=1 MINOR=0
       
    53     hdr.SetExchange(iNegotiation->iExchange);
       
    54     hdr.SetFlags(iNegotiation->iFlags);
       
    55     if ((iNegotiation->iExchange == ISAKMP_EXCHANGE_ID) || (iNegotiation->iExchange == ISAKMP_EXCHANGE_AGGR))
       
    56         hdr.SetMessageId(0);
       
    57     else //QUICK mode ,INFORMATIONAL Mode or Transaction exchange
       
    58         hdr.SetMessageId(iNegotiation->iMessageId);
       
    59     
       
    60     iBuf.SetLength(0);  //Set correctly when sending SendL()
       
    61     iBuf.Copy((TUint8 *)&hdr, sizeof(hdr)); //Always called the first so not Append
       
    62     iNextPayload = (TUint8 *)(iBuf.Ptr() + 16); //saves the adress. 
       
    63                                                 //Will be filled by the next called function
       
    64 }
       
    65 
       
    66 
       
    67 void TIkev1IsakmpStream::IsakmpSa()
       
    68 {
       
    69     TSAISAKMP sa;
       
    70     DEBUG_LOG(_L("[SA]"));
       
    71     sa.SetPayload(0);   //Not proposal or transform RFC. After reserved is already 0
       
    72     sa.SetDOI(iNegotiation->iDOI);  //Always the same. Otherwise should be the one contained in CIkev1Negotiation
       
    73     sa.SetSIT(IPSEC_SIT_IDENTITY_ONLY); //That means no Labeled Domain Identifier
       
    74     
       
    75     *iNextPayload = ISAKMP_PAYLOAD_SA;      //Fills the previous payload next field
       
    76     iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address. 
       
    77                                             //Will be filled by the next called function
       
    78 
       
    79     TUint16 pos=(TUint16)iBuf.Length(); //save the position to know the total size later and insert it
       
    80     iBuf.SetLength(pos + sizeof(sa)); //leave room to insert later the proposal
       
    81                                                                     //including the SPI
       
    82     IsakmpProposal();
       
    83     sa.SetLength((TUint16)(iBuf.Length() - pos));
       
    84     TBuf8<sizeof(sa)> aux;
       
    85     aux.Append((TUint8 *)&sa, sizeof(sa));
       
    86     iBuf.Replace(pos,aux.Length(),aux);
       
    87 
       
    88 }
       
    89 
       
    90 //SPI not included yet.
       
    91 //Sends msg stage 2. Should be used for phase 2 as well
       
    92 void TIkev1IsakmpStream::IsakmpProposal()
       
    93 {
       
    94     TProposalISAKMP proposal;
       
    95     TUint16 pos = 0;
       
    96     TUint8  next_payload = ISAKMP_PAYLOAD_T; // default: more than one transform
       
    97 
       
    98     if (iNegotiation->iPhase == PHASE_I)
       
    99     {
       
   100         TProposal *prop;
       
   101         
       
   102         if (iNegotiation->iRole==INITIATOR) 
       
   103         {
       
   104             prop=&iNegotiation->iProposal_I;
       
   105         }
       
   106         else
       
   107         {
       
   108             prop=&iNegotiation->iChosenProposal_I;
       
   109         }
       
   110         proposal.SetPayload(ISAKMP_PAYLOAD_NONE);   //Only one proposal
       
   111         proposal.SetNum(prop->iProposalNum);
       
   112         proposal.SetProtocol(prop->iProtocol);
       
   113         proposal.SetSPISize(0);
       
   114         proposal.SetNumTrans(prop->iNumTransforms);
       
   115         pos=(TUint16)iBuf.Length(); //save the position to insert later
       
   116                                                                     //including the SPI
       
   117         iBuf.SetLength(pos + sizeof(proposal)); //leave room to insert later the proposal
       
   118         TAttrib *attr=prop->iAttrList;
       
   119         for (TInt i=0; i < proposal.GetNumTrans(); i++) //Adds all the transforms
       
   120         {
       
   121             if ( !attr->iNext )
       
   122                next_payload = ISAKMP_PAYLOAD_NONE; // Last trasnform    
       
   123             IsakmpTransform((TUint8 *)attr, next_payload);
       
   124             attr=attr->iNext;
       
   125         }
       
   126         proposal.SetLength((TUint16)(iBuf.Length() - pos));
       
   127         TBuf8<sizeof(proposal) + MAX_SPI_SIZE> aux;
       
   128         aux.Append((TUint8 *)&proposal, sizeof(proposal));
       
   129         //aux.Append(prop->iSPI);   //insert the SPI
       
   130         iBuf.Replace(pos,aux.Length(),aux);
       
   131         return;
       
   132     }
       
   133 
       
   134     //PHASE_II
       
   135     TAttrib_II *attr_II=NULL;
       
   136     CProposal_IIList *propII_List = NULL;
       
   137     CProposal_II *propII = NULL;
       
   138     TBuf8<MAX_SPI_SIZE> SPI;
       
   139     TInt i, index = 0;
       
   140     TUint32 in_spi;
       
   141     TUint8  num_transforms;
       
   142     CArrayFixFlat<TSPINode> *list = iNegotiation->iInboundSPIList;
       
   143     
       
   144     if (iNegotiation->iRole==INITIATOR) 
       
   145         propII_List = iNegotiation->iProposal_IIList;
       
   146     else    //RESPONDER
       
   147     {   
       
   148         for (index = 0; index < list->Count(); index++)
       
   149         {
       
   150             if (list->At(index).iPropNum == iNegotiation->iProposalNum)
       
   151                 break;
       
   152         }
       
   153         propII_List = iNegotiation->iChosenProp_IIList;
       
   154     }
       
   155 
       
   156     TInt count = propII_List->Count();
       
   157 
       
   158     for (i = 0; i < count; i++)
       
   159     {
       
   160         propII = propII_List->At(i);
       
   161         //Choose the correct SPI
       
   162         if (iNegotiation->iRole==INITIATOR) 
       
   163             SPI = propII->iSPI;
       
   164         else    //RESPONDER
       
   165         {
       
   166             in_spi = list->At(index).iSPI;
       
   167             SPI.Copy((TUint8 *)&in_spi, sizeof(TUint32));
       
   168             index++;    
       
   169         }
       
   170 
       
   171         if (i == count - 1) //Last proposal
       
   172             proposal.SetPayload(ISAKMP_PAYLOAD_NONE);
       
   173         else    //There are more
       
   174             proposal.SetPayload(ISAKMP_PAYLOAD_P);
       
   175 
       
   176         num_transforms = propII->iNumTransforms;
       
   177         proposal.SetNum(propII->iProposalNum);
       
   178         proposal.SetProtocol(propII->iProtocol);
       
   179         proposal.SetNumTrans(num_transforms);
       
   180         proposal.SetSPISize((TUint8)SPI.Length());  //The chosen contains the inbound SPI
       
   181         pos=(TUint16)iBuf.Length(); //save the position to insert later
       
   182         iBuf.SetLength(pos + sizeof(proposal) + proposal.GetSPISize()); //leave room to insert later the proposal
       
   183                                                                 //including the SPI
       
   184         for (TInt j = 0; j < num_transforms; j++)   //Adds all the transforms
       
   185         {
       
   186             attr_II = propII->iAttrList->At(j);
       
   187             if ( (num_transforms - j) == 1 )
       
   188                next_payload = ISAKMP_PAYLOAD_NONE; // Last trasnform    
       
   189             IsakmpTransform((TUint8 *)attr_II, next_payload);
       
   190         }
       
   191         proposal.SetLength((TUint16)(iBuf.Length() - pos));
       
   192         TBuf8<sizeof(proposal) + MAX_SPI_SIZE> aux;
       
   193         aux.Append((TUint8 *)&proposal, sizeof(proposal));
       
   194         aux.Append(SPI);    //insert the SPI
       
   195         iBuf.Replace(pos, aux.Length(), aux);
       
   196         
       
   197     }
       
   198 
       
   199 }
       
   200 
       
   201 //Transform data received as TUint8 to allow both TAttrib and TAttrib_II
       
   202 void TIkev1IsakmpStream::IsakmpTransform(TUint8 *aTransform, TUint8 aNextPayload)
       
   203 {
       
   204     TTransformISAKMP transf;
       
   205 
       
   206     //transf.SetNum(1);//SHOULD BE the selected transform but Linux doesn't let it use it!!!
       
   207     if (iNegotiation->iPhase == PHASE_I)
       
   208     {
       
   209         TAttrib *attr=(TAttrib *)aTransform;
       
   210         transf.SetNum(attr->iTransformNum);
       
   211         transf.SetID(attr->iTransformID);
       
   212         transf.SetPayload(aNextPayload);
       
   213     }
       
   214     else    //PHASE_II
       
   215     {
       
   216         TAttrib_II *attr_II=(TAttrib_II *)aTransform;
       
   217         transf.SetNum(attr_II->iTransformNum);
       
   218         transf.SetID(attr_II->iTransformID);
       
   219         transf.SetPayload(aNextPayload);        
       
   220     }
       
   221     
       
   222     TInt pos=iBuf.Length(); //save the position to insert later
       
   223     iBuf.SetLength(pos + sizeof(transf)); //leave room to insert later
       
   224     IsakmpAttrib(aTransform);
       
   225     transf.SetLength((TUint16)(iBuf.Length() - pos));
       
   226     TBuf8<sizeof(transf)> aux;
       
   227     aux.Append((TUint8 *)&transf, sizeof(transf));
       
   228     iBuf.Replace(pos,aux.Length(),aux);
       
   229 }
       
   230 
       
   231 
       
   232 //Creates a data payload with the desired SA attributes. either Phase I or II
       
   233 void TIkev1IsakmpStream::IsakmpAttrib(TUint8 *aTransform)
       
   234 {
       
   235     if (iNegotiation->iPhase == PHASE_I)
       
   236         IsakmpAttrib1((TAttrib *)aTransform);
       
   237     else    //PHASE_II
       
   238         IsakmpAttrib2((TAttrib_II *)aTransform);
       
   239 }
       
   240 
       
   241 //Phase_I attributes
       
   242 void TIkev1IsakmpStream::IsakmpAttrib1(TAttrib *aTransform)
       
   243 {
       
   244     TDataISAKMP attr;
       
   245     TUint length;
       
   246     TUint16 val;
       
   247     TAttrib trans;
       
   248 
       
   249     trans=*aTransform;
       
   250 
       
   251     val=trans.iEncrAlg;
       
   252     if (val != 0)
       
   253     {
       
   254         attr.SetBasic(ETrue);
       
   255         attr.SetType(OAKLEY_ATTR_TYPE_ENCR_ALG);
       
   256         attr.SetValue(val);
       
   257         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   258     }
       
   259 
       
   260     val=trans.iHashAlg;
       
   261     if (val != 0)
       
   262     {
       
   263         attr.SetBasic(ETrue);
       
   264         attr.SetType(OAKLEY_ATTR_TYPE_HASH_ALG);
       
   265         attr.SetValue(val);
       
   266         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   267     }
       
   268 
       
   269     val=CTransNegotiation::GetAuthMethod(trans.iAuthMethod, trans.iXauthUsed, trans.iRole);           
       
   270     if (val != 0)
       
   271     {
       
   272         attr.SetBasic(ETrue);
       
   273         attr.SetType(OAKLEY_ATTR_TYPE_AUTH_METH);
       
   274         attr.SetValue(val);
       
   275         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   276     }
       
   277 
       
   278     val=trans.iGroupDesc;
       
   279     if (val != 0)
       
   280     {
       
   281         attr.SetBasic(ETrue);
       
   282         attr.SetType(OAKLEY_ATTR_TYPE_GROUP_DESC);
       
   283         attr.SetValue(val);
       
   284         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   285     }
       
   286 
       
   287     val=trans.iGroupType;
       
   288     if (val != 0)
       
   289     {
       
   290         attr.SetBasic(ETrue);
       
   291         attr.SetType(OAKLEY_ATTR_TYPE_GROUP_TYPE);
       
   292         attr.SetValue(val);
       
   293         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   294     }
       
   295 
       
   296     length=trans.iGroupPrime.Length();
       
   297     if (length!=0)
       
   298     {
       
   299         attr.SetBasic(EFalse);
       
   300         attr.SetType(OAKLEY_ATTR_TYPE_GROUP_PRIME);
       
   301         attr.SetLength((TUint16)(length));
       
   302         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   303         iBuf.Append(trans.iGroupPrime);
       
   304     }
       
   305 
       
   306     length=trans.iGroupGen1.Length();
       
   307     if (length!=0)
       
   308     {
       
   309         attr.SetBasic(EFalse);
       
   310         attr.SetType(OAKLEY_ATTR_TYPE_GROUP_GEN1);
       
   311         attr.SetLength((TUint16)(length));
       
   312         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   313         iBuf.Append(trans.iGroupGen1);
       
   314     }
       
   315 
       
   316     length=trans.iGroupGen2.Length();
       
   317     if (length!=0)
       
   318     {
       
   319         attr.SetBasic(EFalse);
       
   320         attr.SetType(OAKLEY_ATTR_TYPE_GROUP_GEN2);
       
   321         attr.SetLength((TUint16)(length));
       
   322         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   323         iBuf.Append(trans.iGroupGen2);
       
   324     }
       
   325     
       
   326     length=trans.iGroupCurveA.Length();
       
   327     if (length!=0)
       
   328     {
       
   329         attr.SetBasic(EFalse);
       
   330         attr.SetType(OAKLEY_ATTR_TYPE_GROUP_CRVA);
       
   331         attr.SetLength((TUint16)(length));
       
   332         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   333         iBuf.Append(trans.iGroupCurveA);
       
   334     }
       
   335 
       
   336     length=trans.iGroupCurveB.Length();
       
   337     if (length!=0)
       
   338     {
       
   339         attr.SetBasic(EFalse);
       
   340         attr.SetType(OAKLEY_ATTR_TYPE_GROUP_CRVB);
       
   341         attr.SetLength((TUint16)(length));
       
   342         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   343         iBuf.Append(trans.iGroupCurveB);
       
   344     }
       
   345 
       
   346     length=trans.iLifeDurationSecs.Length();
       
   347     if (length!=0)
       
   348     {
       
   349         attr.SetBasic(ETrue);
       
   350         attr.SetType(OAKLEY_ATTR_TYPE_LIFE_TYPE);
       
   351         attr.SetValue(SECONDS);
       
   352         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   353 
       
   354         attr.SetBasic(EFalse);
       
   355         attr.SetType(OAKLEY_ATTR_TYPE_LIFE_DUR);
       
   356         attr.SetLength((TUint16)(length));
       
   357         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   358         iBuf.Append(trans.iLifeDurationSecs);
       
   359         
       
   360     }
       
   361 
       
   362     length=trans.iLifeDurationKBytes.Length();
       
   363     if (length!=0)
       
   364     {
       
   365         attr.SetBasic(ETrue);
       
   366         attr.SetType(OAKLEY_ATTR_TYPE_LIFE_TYPE);
       
   367         attr.SetValue(KBYTES);
       
   368         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   369 
       
   370         attr.SetBasic(EFalse);
       
   371         attr.SetType(OAKLEY_ATTR_TYPE_LIFE_DUR);
       
   372         attr.SetLength((TUint16)(length));
       
   373         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   374         iBuf.Append(trans.iLifeDurationKBytes);
       
   375         
       
   376     }
       
   377 
       
   378     val=trans.iPRF;
       
   379     if (val != 0)
       
   380     {
       
   381         attr.SetBasic(ETrue);
       
   382         attr.SetType(OAKLEY_ATTR_TYPE_PRF);
       
   383         attr.SetValue(val);
       
   384         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   385     }
       
   386 
       
   387     val=trans.iKeyLength;
       
   388     if (val != 0)
       
   389     {
       
   390         attr.SetBasic(ETrue);
       
   391         attr.SetType(OAKLEY_ATTR_TYPE_KEY_LEN);
       
   392         attr.SetValue(val);
       
   393         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   394     }
       
   395 
       
   396     val=trans.iFieldSize;
       
   397     if (val != 0)
       
   398     {
       
   399         attr.SetBasic(ETrue);
       
   400         attr.SetType(OAKLEY_ATTR_TYPE_FIELD_SIZE);
       
   401         attr.SetValue(val);
       
   402         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   403     }
       
   404 
       
   405     length=trans.iGroupOrder.Length();
       
   406     if (length!=0)
       
   407     {
       
   408         attr.SetBasic(EFalse);
       
   409         attr.SetType(OAKLEY_ATTR_TYPE_GROUP_ORDER);
       
   410         attr.SetLength((TUint16)(sizeof(attr)+length));
       
   411         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   412         iBuf.Append(trans.iGroupOrder);
       
   413     }
       
   414 }
       
   415 
       
   416 
       
   417 //Phase_II attributes
       
   418 void TIkev1IsakmpStream::IsakmpAttrib2(TAttrib_II *aTransform)
       
   419 {
       
   420         TDataISAKMP attr;
       
   421         TUint length;
       
   422         TUint16 val;
       
   423 
       
   424         TAttrib_II trans=*aTransform;
       
   425         length=trans.iLifeDurationSecs.Length();
       
   426         if (length!=0)
       
   427         {
       
   428             attr.SetBasic(ETrue);
       
   429             attr.SetType(DOI_ATTR_TYPE_LIFE_TYPE);
       
   430             attr.SetValue(SECONDS);
       
   431             iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   432 
       
   433             attr.SetBasic(EFalse);
       
   434             attr.SetType(DOI_ATTR_TYPE_LIFE_DUR);
       
   435             attr.SetLength((TUint16)length);
       
   436             iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   437             iBuf.Append(trans.iLifeDurationSecs.Ptr(),trans.iLifeDurationSecs.Length());
       
   438 
       
   439 
       
   440         }   
       
   441 
       
   442         length=trans.iLifeDurationKBytes.Length();
       
   443         if (length!=0)
       
   444         {
       
   445             attr.SetBasic(ETrue);
       
   446             attr.SetType(DOI_ATTR_TYPE_LIFE_TYPE);
       
   447             attr.SetValue(KBYTES);
       
   448             iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   449 
       
   450             attr.SetBasic(EFalse);
       
   451             attr.SetType(DOI_ATTR_TYPE_LIFE_DUR);
       
   452             attr.SetLength((TUint16)length);
       
   453             iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   454             iBuf.Append(trans.iLifeDurationKBytes.Ptr(),trans.iLifeDurationKBytes.Length());
       
   455 
       
   456         }
       
   457 
       
   458         if (iNegotiation->iPFS)
       
   459         {   //Only sent if PFS in use. The same used in Phase I
       
   460             val = trans.iGroupDesc;
       
   461             if (val != 0)
       
   462             {
       
   463                 attr.SetBasic(ETrue);
       
   464                 attr.SetType(DOI_ATTR_TYPE_GROUP_DESC);
       
   465                 attr.SetValue(val);
       
   466                 iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   467             }
       
   468         }
       
   469 
       
   470         val=trans.iEncMode;
       
   471         if (val != 0)
       
   472         {
       
   473             //
       
   474             // If ESP UDP encapsulation required (because of NAT device in between)
       
   475             // modify encapsulation type code values
       
   476             //
       
   477             if ( iNegotiation->iNAT_D_Flags ) {
       
   478                if ( val == DOI_TUNNEL )
       
   479                     val = UDP_ENC_TUNNEL;
       
   480                else val = UDP_ENC_TRANSPORT;
       
   481             }   
       
   482             attr.SetBasic(ETrue);
       
   483             attr.SetType(DOI_ATTR_TYPE_ENC_MODE);
       
   484             attr.SetValue(val);
       
   485             iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   486         }
       
   487 
       
   488         val=trans.iAuthAlg;
       
   489         if (val != 0)
       
   490         {
       
   491             attr.SetBasic(ETrue);
       
   492             attr.SetType(DOI_ATTR_TYPE_AUTH_ALG);
       
   493             attr.SetValue(val);
       
   494             iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   495         }   
       
   496 
       
   497         val=trans.iKeyLength;
       
   498         if (val != 0)
       
   499         {
       
   500             attr.SetBasic(ETrue);
       
   501             attr.SetType(DOI_ATTR_TYPE_KEY_LEN);
       
   502             attr.SetValue(val);
       
   503             iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   504         }   
       
   505 
       
   506         val=trans.iKeyRounds;
       
   507         if (val != 0)
       
   508         {
       
   509             attr.SetBasic(ETrue);
       
   510             attr.SetType(DOI_ATTR_TYPE_KEY_ROUNDS);
       
   511             attr.SetValue(val);
       
   512             iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   513         }   
       
   514             
       
   515         val=trans.iComprDicSize;
       
   516         if (val != 0)
       
   517         {
       
   518             attr.SetBasic(ETrue);
       
   519             attr.SetType(DOI_ATTR_TYPE_COMP_DIC_SIZE);
       
   520             attr.SetValue(val);
       
   521             iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   522         }   
       
   523 
       
   524         length=trans.iComprPrivAlg.Length();
       
   525         if (length!=0)
       
   526         {
       
   527             attr.SetBasic(EFalse);
       
   528             attr.SetType(DOI_ATTR_TYPE_COMP_PRIV_ALG);
       
   529             attr.SetLength((TUint16)(length));
       
   530             iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
   531             iBuf.Append(trans.iComprPrivAlg);
       
   532         }
       
   533 
       
   534 }
       
   535 
       
   536 
       
   537 //Adds the key payload to the buffer
       
   538 void TIkev1IsakmpStream::IsakmpKeyL()
       
   539 {
       
   540     TKeyISAKMP key_payload;
       
   541 
       
   542     if (!iNegotiation->ComputeDHPublicValueL()) //Computes the required key values. Needed to ComputeKeys
       
   543         return; //No key payload generated
       
   544     TPtrC8 key_ptr(iNegotiation->iOwnPublicKey_ptr);
       
   545 	TInt PadLth = 0;
       
   546 	TInt ModLth = iNegotiation->iOwnKeys->ModulusLength();
       
   547 	if ( ModLth > key_ptr.Length() )
       
   548 	{	
       
   549 		PadLth = ModLth - key_ptr.Length();
       
   550 		DEBUG_LOG(_L("[KE(filled)]"));			
       
   551 	}
       
   552 	DEBUG_LOG(_L("[KE]"));	
       
   553     key_payload.SetLength((TUint16)(sizeof(key_payload) + ModLth));
       
   554     *iNextPayload = ISAKMP_PAYLOAD_KE;      //Fills the previous payload next field
       
   555     iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address.
       
   556                                                     //Will be filled by the next called function    
       
   557     iBuf.Append((TUint8 *)&key_payload, sizeof(key_payload));
       
   558     if ( PadLth )
       
   559 	{
       
   560 	   TChar zero(0);	
       
   561 	   iBuf.AppendFill(zero, PadLth);    //Fill prepending zero bits to DH public value
       
   562 	}   
       
   563     iBuf.Append(key_ptr);    //variable size DH public value
       
   564 }
       
   565 
       
   566 void TIkev1IsakmpStream::IsakmpOwnIdentL()
       
   567 {
       
   568     IsakmpIdentL(ETrue);
       
   569 }
       
   570 
       
   571 void TIkev1IsakmpStream::IsakmpPeerIdentL()
       
   572 {
       
   573     IsakmpIdentL(EFalse);
       
   574 }
       
   575 
       
   576 void TIkev1IsakmpStream::IsakmpIdentL(TBool aIsOwn)
       
   577 {
       
   578     TIdentISAKMP id_payload;
       
   579 	
       
   580     TBuf8<256> buf;     //Max size for FQDN or DER ASN1 DN
       
   581                         // (buf should be allocated from heap !!)   
       
   582     TUint32 num;
       
   583     const TUint8 *pnum;
       
   584 
       
   585     //DOI IPSEC
       
   586     if (iNegotiation->iPhase == PHASE_I)
       
   587         id_payload.SetProtocol(KProtocolInetUdp);
       
   588     else
       
   589         id_payload.SetProtocol(iNegotiation->iIDProtocol);  //defined when receiving the acquire (INIT) or when receiveind the ID payload (RESP)
       
   590 
       
   591     if (aIsOwn) //Own ID!
       
   592     {
       
   593         if (iNegotiation->iPhase == PHASE_I)
       
   594         {
       
   595             DEBUG_LOG(_L("[IDi]"));
       
   596 			Isakmp_Phase1_IdL(buf, id_payload);
       
   597         }
       
   598         else //PHASE_II
       
   599         {
       
   600             DEBUG_LOG(_L("[IDci]"));
       
   601             id_payload.SetIDType(iNegotiation->iLocalIDType_II);
       
   602 
       
   603             id_payload.SetPort(iNegotiation->iIDLocalPort); //defined when receiving the acquire (INIT) or when receiveind the ID payload (RESP)
       
   604             
       
   605             switch (iNegotiation->iLocalIDType_II)
       
   606             {
       
   607             case ID_IPV4_ADDR:
       
   608                 id_payload.SetLength((TUint16)(sizeof(id_payload) + sizeof(TUint32)));  //IPV4 addr TInt32
       
   609                 num = ByteOrder::Swap32(iNegotiation->iLocalAddr1_ID_II.Address());//Put in network order
       
   610                 pnum= (TUint8*)&num;
       
   611                 buf.Append(pnum,sizeof(TUint32));
       
   612                 break;
       
   613             case ID_IPV6_ADDR:
       
   614 			   if (iNegotiation->iLocalAddr.IsV4Mapped())
       
   615 				{
       
   616 				id_payload.SetLength((TUint16)(sizeof(id_payload) + sizeof(TUint32)));  //IPV4 addr TInt32
       
   617 				id_payload.SetIDType(ID_IPV4_ADDR);
       
   618 				num = ByteOrder::Swap32(iNegotiation->iLocalAddr.Address());//Put in network order
       
   619 				pnum= (TUint8*)&num;
       
   620 				buf.Append(pnum,sizeof(TUint32));
       
   621 				}
       
   622 			   else 
       
   623 				{
       
   624                 id_payload.SetLength((TUint16)(sizeof(id_payload) + 16));   //IPV6 size is 16
       
   625                 pnum = &iNegotiation->iLocalAddr1_ID_II.Ip6Address().u.iAddr8[0];   //Address in a bytestream
       
   626                 buf.Append(pnum, 16);
       
   627 				}
       
   628                 break;
       
   629             case ID_IPV4_ADDR_SUBNET:
       
   630                 id_payload.SetLength((TUint16)(sizeof(id_payload) + 2*sizeof(TUint32)));    //IPV4 addr TInt32
       
   631                 num = ByteOrder::Swap32(iNegotiation->iLocalAddr1_ID_II.Address());//Put in network order
       
   632                 pnum= (TUint8*)&num;
       
   633                 buf.Append(pnum,sizeof(TUint32));
       
   634                 num = ByteOrder::Swap32(iNegotiation->iLocalAddr2_ID_II.Address());//Put in network order
       
   635                 pnum= (TUint8*)&num;
       
   636                 buf.Append(pnum,sizeof(TUint32));
       
   637                 break;
       
   638             case ID_IPV6_ADDR_SUBNET:
       
   639                 id_payload.SetLength((TUint16)(sizeof(id_payload) + 32));   //one IPV6 addr size is 16
       
   640                 pnum = &iNegotiation->iLocalAddr1_ID_II.Ip6Address().u.iAddr8[0];   //Address in a bytestream
       
   641                 buf.Append(pnum, 16);
       
   642                 pnum = &iNegotiation->iLocalAddr2_ID_II.Ip6Address().u.iAddr8[0];   //Address in a bytestream
       
   643                 buf.Append(pnum, 16);
       
   644                 break;
       
   645             //No need for a default. Must be controlled way before when acquire or IDs received
       
   646             }   
       
   647         }
       
   648     }
       
   649     else //Peer Id.
       
   650     {
       
   651         if (iNegotiation->iPhase == PHASE_I)
       
   652         {
       
   653             DEBUG_LOG(_L("[IDr]"));
       
   654 			Isakmp_Phase1_IdL(buf, id_payload);					
       
   655         }
       
   656         else //PHASE_II
       
   657         {
       
   658             DEBUG_LOG(_L("[IDcr]"));
       
   659             id_payload.SetIDType(iNegotiation->iRemoteIDType_II);
       
   660 
       
   661             id_payload.SetPort(iNegotiation->iIDRemotePort);    //defined when receiving the acquire (INIT) or when receiving the ID payload (RESP)
       
   662             
       
   663             switch (iNegotiation->iRemoteIDType_II)
       
   664             {
       
   665             case ID_IPV4_ADDR:
       
   666                 id_payload.SetLength((TUint16)(sizeof(id_payload) + sizeof(TUint32)));  //IPV4 addr TInt32
       
   667                 num = ByteOrder::Swap32(iNegotiation->iRemoteAddr1_ID_II.Address());//Put in network order
       
   668                 pnum= (TUint8*)&num;
       
   669                 buf.Append(pnum,sizeof(TUint32));
       
   670                 break;
       
   671             case ID_IPV6_ADDR:
       
   672                 id_payload.SetLength((TUint16)(sizeof(id_payload) + 16));   //IPV6 size is 16
       
   673                 pnum = &iNegotiation->iRemoteAddr1_ID_II.Ip6Address().u.iAddr8[0];  //Address in a bytestream
       
   674                 buf.Append(pnum, 16);
       
   675                 break;
       
   676             case ID_IPV4_ADDR_SUBNET:
       
   677                 id_payload.SetLength((TUint16)(sizeof(id_payload) + 2*sizeof(TUint32)));    //IPV4 addr TInt32
       
   678                 num = ByteOrder::Swap32(iNegotiation->iRemoteAddr1_ID_II.Address());//Put in network order
       
   679                 pnum= (TUint8*)&num;
       
   680                 buf.Append(pnum,sizeof(TUint32));
       
   681                 num = ByteOrder::Swap32(iNegotiation->iRemoteAddr2_ID_II.Address());//Put in network order
       
   682                 pnum= (TUint8*)&num;
       
   683                 buf.Append(pnum,sizeof(TUint32));
       
   684                 break;
       
   685             case ID_IPV6_ADDR_SUBNET:
       
   686                 id_payload.SetLength((TUint16)(sizeof(id_payload) + 32));   //one IPV6 addr size is 16
       
   687                 pnum = &iNegotiation->iRemoteAddr1_ID_II.Ip6Address().u.iAddr8[0];  //Address in a bytestream
       
   688                 buf.Append(pnum, 16);
       
   689                 pnum = &iNegotiation->iRemoteAddr2_ID_II.Ip6Address().u.iAddr8[0];  //Address in a bytestream
       
   690                 buf.Append(pnum, 16);
       
   691                 break;
       
   692             default:
       
   693                 DEBUG_LOG(_L("Bad Remote Phase_II ID type"));
       
   694                 iNegotiation->SetFinished();
       
   695                 return;
       
   696             //No need for a default. Must be controlled way before when acquire or IDs received
       
   697             }   
       
   698         }
       
   699     }
       
   700     *iNextPayload = ISAKMP_PAYLOAD_ID;      //Fills the previous payload next field
       
   701     iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the adress.
       
   702                                                     //Will be filled by the next called function
       
   703     iBuf.Append((TUint8 *)&id_payload, sizeof(id_payload));
       
   704     iBuf.Append(buf);   //variable size
       
   705 
       
   706     //stores the payload to be used in HASH_R/I computation (Only for phase I)
       
   707     if ((iNegotiation->iPhase == PHASE_I) && (aIsOwn))
       
   708     {
       
   709         TUint8 *p_ident=iNextPayload+sizeof(TPayloadISAKMP);    //Data field
       
   710 
       
   711         iNegotiation->iOwnIdentPayloadSize=id_payload.GetLength()-sizeof(TPayloadISAKMP);   //without the generic part!
       
   712 
       
   713         if (iNegotiation->iOwnIdentPayload) //in case it contains info
       
   714             {                
       
   715             delete iNegotiation->iOwnIdentPayload;
       
   716             iNegotiation->iOwnIdentPayload = NULL;
       
   717             }
       
   718         iNegotiation->iOwnIdentPayload = new (ELeave) TUint8[iNegotiation->iOwnIdentPayloadSize];   //Generic payload NOT included
       
   719         Mem::Copy(iNegotiation->iOwnIdentPayload,p_ident,iNegotiation->iOwnIdentPayloadSize);
       
   720     }
       
   721 
       
   722 }
       
   723 
       
   724 void TIkev1IsakmpStream::Isakmp_Phase1_IdL(TDes8& aIdData, TIdentISAKMP& aIdPayload)
       
   725 {
       
   726 	if ( iNegotiation->iNAT_D_Flags )
       
   727 		 aIdPayload.SetPort(0);				
       
   728 	else aIdPayload.SetPort(IKE_PORT);
       
   729 
       
   730 	TBool IdOk = EFalse;
       
   731 	TUint8 IdType = iNegotiation->iHostData->iIdType;
       
   732 	if (IdType == ID_USER_FQDN || IdType == ID_DER_ASN1_DN)
       
   733 	{
       
   734 	    if (!iNegotiation->iOwnCert)    //If not yet read
       
   735 	    {
       
   736 	        iNegotiation->ReadOwnCertL();
       
   737 	    }
       
   738 	}
       
   739 	if ( iNegotiation->iOwnCert && iNegotiation->iPkiService )
       
   740 	{
       
   741 		//
       
   742 		// Priority 1 : Use IKE identity based on local certificate
       
   743 		//
       
   744 		TPtrC8 Cert(iNegotiation->iOwnCert->Des());
       
   745 		HBufC8* CertIdBfr = IkePkiUtils::GetIdentityFromCertL(IdType, Cert);
       
   746 		if ( CertIdBfr )
       
   747 		{
       
   748 			if ( CertIdBfr->Des().Length() <= aIdData.MaxLength() )
       
   749 			{
       
   750 			   aIdData.Copy(CertIdBfr->Des());	
       
   751 			   if ( IdType == 0 )
       
   752 				  IdType = ID_DER_ASN1_DN;
       
   753 			   IdOk = ETrue;
       
   754 			} 
       
   755 			delete CertIdBfr; 
       
   756 		}	  
       
   757 	}
       
   758 	
       
   759 	if ( !IdOk )
       
   760 	{
       
   761 		//
       
   762 		// Priority 2 : Use identity defined in policy 
       
   763 		//
       
   764 		TInt DataLength = iNegotiation->iHostData->iFQDN.Length();
       
   765 		IdType = iNegotiation->iHostData->iIdType;                               
       
   766 		if ( ( DataLength > 0 ) && ( DataLength <= aIdData.MaxLength()) )
       
   767 		{
       
   768 			if ( (IdType != ID_KEY_ID) && (IdType != ID_USER_FQDN) && (IdType != ID_FQDN) )
       
   769 				IdType = ID_KEY_ID;
       
   770 			aIdData.Copy(iNegotiation->iHostData->iFQDN);
       
   771 			IdOk = ETrue;
       
   772 		}
       
   773 	}
       
   774 
       
   775 	if ( !IdOk )
       
   776 	{
       
   777 		//
       
   778 		// Priority 3 : Build local id from own IP address
       
   779 		//
       
   780 		TUint32 num;
       
   781 		const TUint8 *pnum;
       
   782 		if ((iNegotiation->iLocalAddr.Family() == KAfInet) || iNegotiation->iLocalAddr.IsV4Mapped() )
       
   783 		{
       
   784 			IdType = ID_IPV4_ADDR;
       
   785 			num  = ByteOrder::Swap32(iNegotiation->iLocalAddr.Address());//Put in network order
       
   786 			pnum = (TUint8*)&num;
       
   787 			aIdData.Copy(pnum, sizeof(TUint32));
       
   788 		}
       
   789 		else 
       
   790 		{
       
   791 			IdType = ID_IPV6_ADDR;			
       
   792 			pnum = &iNegotiation->iLocalAddr.Ip6Address().u.iAddr8[0];  //Address in a bytestream
       
   793 			aIdData.Copy(pnum, 16);
       
   794 		}       
       
   795 	}
       
   796 
       
   797 	aIdPayload.SetLength((TUint16)(sizeof(aIdPayload) + aIdData.Length())); 
       
   798 	aIdPayload.SetIDType(IdType);
       
   799 	
       
   800 }
       
   801 
       
   802 
       
   803 
       
   804 void TIkev1IsakmpStream::IsakmpCertificateL()
       
   805 {
       
   806     TCertificateISAKMP *cert;
       
   807 
       
   808     if (!iNegotiation->iSendCert)   //Set by a received cert request or ourselves if initiator
       
   809         return;
       
   810 
       
   811     if (!iNegotiation->iOwnCert)    //If not yet read
       
   812     {
       
   813         if (!iNegotiation->ReadOwnCertL())
       
   814         {
       
   815             iNegotiation->SetFinished();
       
   816             return;
       
   817         }
       
   818     }   
       
   819     DEBUG_LOG(_L("[CERT]"));
       
   820     *iNextPayload = ISAKMP_PAYLOAD_CERT;        //Fills the previous payload next field
       
   821     cert = (TCertificateISAKMP*)(iBuf.Ptr() + iBuf.Length());
       
   822     iNextPayload = (TUint8 *)cert;//saves the adress.Will be filled by the next called function
       
   823     
       
   824     TPtr8 cert_ptr((TUint8 *)iBuf.Ptr() + iBuf.Length() + TCertificateISAKMP::Size(), 0, iBuf.MaxLength() - iBuf.Length()); //Pointer to the Cert. Data
       
   825 
       
   826     cert_ptr.Copy(iNegotiation->iOwnCert->Des());
       
   827     cert->SetReserved(0);
       
   828     cert->SetLength((TUint16)(TCertificateISAKMP::Size() + cert_ptr.Size()));
       
   829     cert->SetEncoding(iNegotiation->iEncoding); //If responder the same as initiator, otherwise any? (now only X509)    
       
   830     iBuf.SetLength(iBuf.Length() + TCertificateISAKMP::Size() + cert_ptr.Size());   //The new info just added   
       
   831     if ( iNegotiation->iICA2 )
       
   832         {
       
   833         DEBUG_LOG(_L("[Level 2 INTERMEDIATE CERT]"));
       
   834         *iNextPayload = ISAKMP_PAYLOAD_CERT;        //Fills the previous payload next field
       
   835         cert = (TCertificateISAKMP*)(iBuf.Ptr() + iBuf.Length());
       
   836         iNextPayload = (TUint8 *)cert;//saves the adress.Will be filled by the next called function
       
   837          
       
   838         TPtr8 cert_ptr((TUint8 *)iBuf.Ptr() + iBuf.Length() + TCertificateISAKMP::Size(), 0, iBuf.MaxLength() - iBuf.Length()); //Pointer to the Cert. Data
       
   839 
       
   840         cert_ptr.Copy(iNegotiation->iICA2->Des());
       
   841         cert->SetReserved(0);
       
   842         cert->SetLength((TUint16)(TCertificateISAKMP::Size() + cert_ptr.Size()));
       
   843         cert->SetEncoding(iNegotiation->iEncoding); //If responder the same as initiator, otherwise any? (now only X509)    
       
   844         iBuf.SetLength(iBuf.Length() + TCertificateISAKMP::Size() + cert_ptr.Size());   //The new info just added
       
   845         }
       
   846     if ( iNegotiation->iICA1 )
       
   847         {
       
   848         DEBUG_LOG(_L("[Level 1 INTERMEDIATE CERT]"));
       
   849         *iNextPayload = ISAKMP_PAYLOAD_CERT;        //Fills the previous payload next field
       
   850         cert = (TCertificateISAKMP*)(iBuf.Ptr() + iBuf.Length());
       
   851         iNextPayload = (TUint8 *)cert;//saves the adress.Will be filled by the next called function
       
   852              
       
   853         TPtr8 cert_ptr((TUint8 *)iBuf.Ptr() + iBuf.Length() + TCertificateISAKMP::Size(), 0, iBuf.MaxLength() - iBuf.Length()); //Pointer to the Cert. Data
       
   854 
       
   855         cert_ptr.Copy(iNegotiation->iICA1->Des());
       
   856         cert->SetReserved(0);
       
   857         cert->SetLength((TUint16)(TCertificateISAKMP::Size() + cert_ptr.Size()));
       
   858         cert->SetEncoding(iNegotiation->iEncoding); //If responder the same as initiator, otherwise any? (now only X509)    
       
   859         iBuf.SetLength(iBuf.Length() + TCertificateISAKMP::Size() + cert_ptr.Size());   //The new info just added
       
   860         }
       
   861 }
       
   862 
       
   863 
       
   864 void TIkev1IsakmpStream::IsakmpCertificateReqL()
       
   865 {
       
   866     if ( !iNegotiation->iPkiService || !iNegotiation->iPkiService->CaList())
       
   867        return;
       
   868 	CIkeCaList* CaList = iNegotiation->iPkiService->CaList();
       
   869     TCertificateReqISAKMP cert_req;
       
   870     CX509Certificate      *ca_cert;
       
   871     TInt                  count = CaList->Count();
       
   872     TInt                  i     = 0;
       
   873 
       
   874     while ( i < count ) {
       
   875         
       
   876         DEBUG_LOG(_L("[CR]"));
       
   877         ca_cert = CaList->At(i)->Certificate();
       
   878         *iNextPayload = ISAKMP_PAYLOAD_CR;  //Fills the previous payload next field
       
   879         iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address. Will be filled by the next called function
       
   880         TPtr8 certreq_data_ptr((TUint8 *)iBuf.Ptr() + iBuf.Length() + TCertificateReqISAKMP::Size(), 0, iBuf.MaxLength() - iBuf.Length());  //Pointer to the CertReq. Data
       
   881 		IkePkiUtils::GetCertSubjectNameDERL(ca_cert, certreq_data_ptr); 
       
   882         cert_req.SetLength((TUint16)(TCertificateReqISAKMP::Size() + certreq_data_ptr.Size()));
       
   883         cert_req.SetEncoding(iNegotiation->iEncoding);  //If responder the same as initiator, otherwise any? (now only X509)
       
   884         iBuf.Append((TUint8 *)&cert_req, TCertificateReqISAKMP::Size());
       
   885         iBuf.SetLength(iBuf.Length()+ certreq_data_ptr.Size());
       
   886         
       
   887         i ++;
       
   888     }
       
   889     
       
   890     iNegotiation->iCertRequested = ETrue;
       
   891 }
       
   892 
       
   893 
       
   894 void TIkev1IsakmpStream::IsakmpHashL()
       
   895 {
       
   896     DEBUG_LOG(_L("[HASH]"));
       
   897     THashISAKMP hash_payload;
       
   898     TBuf8<ISAKMP_HASH_SIZE> hash;
       
   899     TUint8 exchange = ThdrISAKMP::Ptr(iBuf)->GetExchange();
       
   900     switch (exchange) 
       
   901     {
       
   902     case ISAKMP_EXCHANGE_ID: //Main mode
       
   903     case ISAKMP_EXCHANGE_AGGR: //Main mode
       
   904         *iNextPayload = ISAKMP_PAYLOAD_HASH;        //Fills the previous payload next field
       
   905         iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the adress.
       
   906         
       
   907         if (iNegotiation->iRole==INITIATOR)
       
   908         {
       
   909             DEBUG_LOG(_L("[HASH_I]"));
       
   910             iNegotiation->ComputeHash1L(hash); //Must be done after Isakmp_IDENT to have the correct Id payload
       
   911             hash_payload.SetLength((TUint16)(hash.Length() + sizeof(THashISAKMP)));
       
   912             iBuf.Append((TUint8 *)&hash_payload, sizeof(hash_payload));
       
   913             //iBuf.Append(iNegotiation->iHASH_I,iNegotiation->iHASH_ILen);
       
   914             iBuf.Append(hash);
       
   915             
       
   916         }
       
   917         else    //RESP
       
   918         {
       
   919             DEBUG_LOG(_L("[HASH_R]"));
       
   920             iNegotiation->ComputeHashrL(hash); //Must be done after Isakmp_IDENT to have the correct Id payload
       
   921             hash_payload.SetLength((TUint16)(hash.Length() + sizeof(THashISAKMP)));
       
   922             iBuf.Append((TUint8 *)&hash_payload, sizeof(hash_payload));
       
   923             //iBuf.Append(iNegotiation->iHASH_R,iNegotiation->iHASH_RLen);
       
   924             iBuf.Append(hash);
       
   925         }
       
   926         break;
       
   927 		
       
   928     case IKE_QUICK_MODE:
       
   929         *iNextPayload = ISAKMP_PAYLOAD_HASH;        //Fills the previous payload next field
       
   930         iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the adress.
       
   931         switch (iNegotiation->iStage)
       
   932         {
       
   933         case 1://Require 2-stage hash payload construction
       
   934         case 2:
       
   935         case 4:
       
   936             iHash_pos=iBuf.Length();    //Saves the pos to put the payload later in Isakmp_HASH_cont
       
   937             //Leaves free space for the buffer
       
   938             iBuf.SetLength(iBuf.Length() + sizeof(THashISAKMP) + iNegotiation->HashLength());
       
   939         break;
       
   940         default: //stage 3
       
   941             DEBUG_LOG(_L("[HASH(3)]"));
       
   942             iNegotiation->ComputeHash2L(hash, iNegotiation->iStage);
       
   943             hash_payload.SetLength((TUint16)(hash.Length() + sizeof(THashISAKMP)));
       
   944             iBuf.Append((TUint8 *)&hash_payload, sizeof(hash_payload));
       
   945             iBuf.Append(hash);  //Puts the hash in the correct position. iHashPos fills by Isakmp_HASH()
       
   946         }
       
   947         break;
       
   948 		
       
   949     case ISAKMP_EXCHANGE_INFO:
       
   950     case ISAKMP_EXCHANGE_TRANSACT:
       
   951 		*iNextPayload = ISAKMP_PAYLOAD_HASH;        //Fills the previous payload next field
       
   952 		iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address.		
       
   953 		iHash_pos = iBuf.Length();    //Saves the pos to put the payload later in Isakmp_HASH_cont
       
   954 		//Leaves free space for the buffer
       
   955 		iBuf.SetLength(iBuf.Length() + sizeof(THashISAKMP) + iNegotiation->HashLength());
       
   956         break;
       
   957 		
       
   958     default:
       
   959         DEBUG_LOG(_L("ISAKMP_HASH payload build error"));
       
   960         iNegotiation->SetFinished();
       
   961     }
       
   962 }
       
   963 
       
   964 //Insert the hash in the designed position. Only Phase_II stage 1 or 2
       
   965 void TIkev1IsakmpStream::IsakmpHashContL()
       
   966 {
       
   967     THashISAKMP hash;
       
   968     TBuf8<ISAKMP_HASH_SIZE> tmp_hash;
       
   969 
       
   970     //to put the correct next_payload value we check in the buffer because the next 
       
   971     //payload will have updated the value there
       
   972     THashISAKMP *fake_hdr=(THashISAKMP *)(iBuf.Ptr() + iHash_pos);
       
   973     hash.SetPayload(fake_hdr->GetPayload());
       
   974     TInt hash_len=sizeof(THashISAKMP) + iNegotiation->HashLength();
       
   975     hash.SetLength((TUint16)hash_len);
       
   976     tmp_hash.Copy((TUint8 *)&hash,sizeof(hash));
       
   977     iBuf.Replace(iHash_pos, tmp_hash.Length(),tmp_hash);
       
   978     iHash_pos += tmp_hash.Length();
       
   979     
       
   980     TUint8 *hashMsg=((TUint8 *)iBuf.Ptr() + sizeof(ThdrISAKMP) + hash_len); //Msg to hash
       
   981     TInt hashMsgLen= iBuf.Length()- sizeof(ThdrISAKMP) - hash_len;
       
   982     switch (iNegotiation->iExchange) 
       
   983     {
       
   984     case IKE_QUICK_MODE:
       
   985         if (iNegotiation->iStage != 4)
       
   986             iNegotiation->ComputeHash2L(tmp_hash, iNegotiation->iStage, hashMsg, hashMsgLen);
       
   987         else //Send CONNECT message is informational although in Quick mode
       
   988             iNegotiation->ComputeHashInfL(tmp_hash, hashMsg, hashMsgLen);
       
   989         break;
       
   990     case ISAKMP_EXCHANGE_INFO:
       
   991     case ISAKMP_EXCHANGE_TRANSACT:              
       
   992         iNegotiation->ComputeHashInfL(tmp_hash, hashMsg, hashMsgLen);
       
   993         break;
       
   994     default:
       
   995         DEBUG_LOG(_L("ISAKMP_HASH_contL"));
       
   996         iNegotiation->SetFinished();
       
   997     }
       
   998     iBuf.Replace(iHash_pos,tmp_hash.Length(),tmp_hash); //Puts the hash in the correct position. iHashPos fills by Isakmp_HASH()
       
   999 }
       
  1000 
       
  1001 void TIkev1IsakmpStream::IsakmpSignatureL()
       
  1002 {
       
  1003     TSignatureISAKMP sig;
       
  1004     TBuf8<ISAKMP_HASH_SIZE> hash;
       
  1005 
       
  1006     DEBUG_LOG(_L("[SIG]"));
       
  1007     if ( !iNegotiation->iPkiService )
       
  1008         return;
       
  1009 
       
  1010     //DSS only allows SHA1 as hash
       
  1011     TUint16 tmp = iNegotiation->iChosenProposal_I.iAttrList->iHashAlg;  //save the value to compute the hash with SHA1 if using DSS
       
  1012     
       
  1013     //First computes hash
       
  1014     if (iNegotiation->iRole==INITIATOR)
       
  1015     {
       
  1016         iNegotiation->ComputeHash1L(hash); //Must be done after Isakmp_IDENT to have the correct Id payload
       
  1017     }
       
  1018     else
       
  1019     {
       
  1020         iNegotiation->ComputeHashrL(hash); //Must be done after Isakmp_IDENT to have the correct Id payload
       
  1021     }
       
  1022     iNegotiation->iChosenProposal_I.iAttrList->iHashAlg = tmp;  //Restore the value after computing the hash
       
  1023     
       
  1024     *iNextPayload = ISAKMP_PAYLOAD_SIG;     //Fills the previous payload next field
       
  1025     iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address.
       
  1026                                                     //Will be filled by the next called function
       
  1027     TSignatureISAKMP *p_sig=(TSignatureISAKMP *)(iBuf.Ptr() + iBuf.Length());   //To update the payload size later
       
  1028     iBuf.Append((TUint8 *)&sig, sizeof(sig));
       
  1029     
       
  1030     TPtr8 sig_data_ptr((TUint8 *)(iBuf.Ptr() + iBuf.Length()), iBuf.MaxLength() - iBuf.Length());
       
  1031     
       
  1032     DEBUG_LOG1(_L("sig_data_ptr length=%d"), sig_data_ptr.Length());
       
  1033     if ( iNegotiation->iPkiService->Ikev1SignatureL(iNegotiation->iPeerTrustedCA->Des(),
       
  1034                                                     iNegotiation->iHostData,
       
  1035                                                     hash, sig_data_ptr) == 0 )
       
  1036     {
       
  1037         DEBUG_LOG(_L("Signature Computation failed!"));
       
  1038     }
       
  1039 
       
  1040     DEBUG_LOG(_L("Signature"));
       
  1041     iBuf.SetLength(iBuf.Length() + sig_data_ptr.Length());  //updates the buffer size
       
  1042     p_sig->SetLength((TUint16)(sizeof(sig) + sig_data_ptr.Length()));   //Puts the correct length in the buffer
       
  1043 }
       
  1044 
       
  1045 //Adds the Nonce payload to the buffer
       
  1046 void TIkev1IsakmpStream::IsakmpNonce()
       
  1047 {
       
  1048     TNonceISAKMP nonce_payload;
       
  1049 
       
  1050     //iNegotiation->ComputeNonce();         //Nonce to be sent
       
  1051     nonce_payload.SetLength((TUint16)(sizeof(nonce_payload) + OAKLEY_DEFAULT_NONCE_SIZE));
       
  1052     *iNextPayload = ISAKMP_PAYLOAD_NONCE;       //Fills the previous payload next field
       
  1053     iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address.
       
  1054                                                     //Will be filled by the next called function
       
  1055     iBuf.Append((TUint8 *)&nonce_payload, sizeof(nonce_payload));
       
  1056     if (iNegotiation->iRole==INITIATOR)
       
  1057     {
       
  1058         DEBUG_LOG(_L("[NONCE_I]"));
       
  1059         iBuf.Append(iNegotiation->iNONCE_I);    //variable size
       
  1060     }
       
  1061     else
       
  1062     {
       
  1063         DEBUG_LOG(_L("[NONCE_R]"));
       
  1064         iBuf.Append(iNegotiation->iNONCE_R);    //variable size
       
  1065     }
       
  1066 
       
  1067 }
       
  1068 
       
  1069 //Adds the Notification payload to the buffer
       
  1070 void TIkev1IsakmpStream::IsakmpNotification(TUint16 aType, TUint8 aProtocol, TUint8* aNotifData, TInt aDataLth)
       
  1071 {
       
  1072     TNotificationISAKMP notif;
       
  1073     
       
  1074     TBuf8<2*ISAKMP_COOKIE_SIZE> spi;
       
  1075 
       
  1076     spi.Copy(iNegotiation->iCookie_I);
       
  1077     spi.Append(iNegotiation->iCookie_R);
       
  1078 
       
  1079     DEBUG_LOG(_L("[NOT]"));
       
  1080     *iNextPayload = ISAKMP_PAYLOAD_NOTIF;   //Fills the previous payload next field
       
  1081     iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address.
       
  1082     TUint16 length = (TUint16)(sizeof(notif) + spi.Length() + aDataLth);
       
  1083 
       
  1084     notif.SetLength(length);
       
  1085     notif.SetDOI(iNegotiation->iDOI);
       
  1086     notif.SetProtocol(aProtocol);
       
  1087     notif.SetSPISize((TUint8)spi.Length());
       
  1088     notif.SetMsgType(aType);
       
  1089                                                     //Will be filled by the next called function
       
  1090     iBuf.Append((TUint8 *)&notif, sizeof(notif));   //Header
       
  1091     iBuf.Append(spi);       //insert the SPI
       
  1092 
       
  1093 	if ( aNotifData && aDataLth )
       
  1094 	   iBuf.Append(aNotifData, aDataLth);   //Add Notification data
       
  1095         
       
  1096 }
       
  1097 
       
  1098 //Adds the Notification payload to the buffer
       
  1099 void TIkev1IsakmpStream::IsakmpReplayStatus(TUint8 aProtocol, TUint32 aSPI, TUint8 aReplayWindowLength)
       
  1100 {
       
  1101     TNotificationISAKMP notif;
       
  1102     TUint32 data;
       
  1103     
       
  1104     DEBUG_LOG(_L("[NOT]"));
       
  1105     *iNextPayload = ISAKMP_PAYLOAD_NOTIF;   //Fills the previous payload next field
       
  1106     iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address.
       
  1107     notif.SetLength((TUint16)(sizeof(notif) + sizeof(aSPI) + sizeof(data))); //No Notification Data yet!!!
       
  1108     notif.SetDOI(iNegotiation->iDOI);
       
  1109     notif.SetProtocol(aProtocol);
       
  1110     notif.SetSPISize(sizeof(aSPI)); //No SPI sent
       
  1111     notif.SetMsgType(DOI_REPLAY_STATUS);
       
  1112                                                     //Will be filled by the next called function
       
  1113     iBuf.Append((TUint8 *)&notif, sizeof(notif));   //Header
       
  1114     iBuf.Append((TUint8 *)&aSPI, sizeof(aSPI));     //Insert the SPI
       
  1115 
       
  1116     // Notification Data:   0 if replay detection disabled
       
  1117     //                      1 if replay detection enabled
       
  1118 
       
  1119     if (aReplayWindowLength > 0)
       
  1120         data = ByteOrder::Swap32(1);
       
  1121     else
       
  1122         data = 0;
       
  1123     iBuf.Append((TUint8 *)&data, sizeof(data));
       
  1124 
       
  1125 }
       
  1126 
       
  1127 //Adds the Notification payload to the buffer
       
  1128 void TIkev1IsakmpStream::IsakmpResponderLifetime(TUint8 aProtocol, TUint32 aSPI, const TDesC8 &aLifetime, const TDesC8 &aLifesize)
       
  1129 {
       
  1130     TNotificationISAKMP notif;
       
  1131     TDataISAKMP attr;
       
  1132     
       
  1133     DEBUG_LOG(_L("[NOT]"));
       
  1134     *iNextPayload = ISAKMP_PAYLOAD_NOTIF;   //Fills the previous payload next field
       
  1135     iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address.
       
  1136     
       
  1137     //Notification payload + spi + attribs lifetype and life value
       
  1138     TInt attrlen = 0;
       
  1139     if (aLifetime.Length() > 0)
       
  1140         attrlen = 2*sizeof(attr) + aLifetime.Length();
       
  1141     if (aLifesize.Length() > 0)
       
  1142         attrlen += 2*sizeof(attr) + aLifesize.Length();
       
  1143     if (attrlen == 0)   //No lifevalues to send
       
  1144         return;
       
  1145 
       
  1146     notif.SetLength((TUint16)(sizeof(notif) + sizeof(aSPI) + attrlen));
       
  1147     notif.SetDOI(iNegotiation->iDOI);
       
  1148     notif.SetProtocol(aProtocol);
       
  1149     notif.SetSPISize(sizeof(aSPI)); //No SPI sent
       
  1150     notif.SetMsgType(DOI_RESPONDER_LIFETIME);
       
  1151                                                     //Will be filled by the next called function
       
  1152     iBuf.Append((TUint8 *)&notif, sizeof(notif));   //Header
       
  1153     iBuf.Append((TUint8 *)&aSPI, sizeof(aSPI));     //Insert the SPI
       
  1154     
       
  1155     //Lifetime
       
  1156     if (aLifetime.Length() > 0)
       
  1157     {
       
  1158         //LifeType
       
  1159         attr.SetBasic(ETrue);
       
  1160         attr.SetType(DOI_ATTR_TYPE_LIFE_TYPE);
       
  1161         attr.SetValue(SECONDS);
       
  1162         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
  1163 
       
  1164         //Life Value
       
  1165         attr.SetBasic(EFalse);
       
  1166         attr.SetType(DOI_ATTR_TYPE_LIFE_DUR);
       
  1167         attr.SetLength((TUint16)(aLifetime.Length()));
       
  1168         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
  1169         iBuf.Append(aLifetime);
       
  1170     }
       
  1171 
       
  1172     //Lifesize
       
  1173     if (aLifesize.Length() > 0)
       
  1174     {
       
  1175         //LifeType
       
  1176         attr.SetBasic(ETrue);
       
  1177         attr.SetType(OAKLEY_ATTR_TYPE_LIFE_TYPE);
       
  1178         attr.SetValue(KBYTES);
       
  1179         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
  1180 
       
  1181         //Life Value
       
  1182         attr.SetBasic(EFalse);
       
  1183         attr.SetType(OAKLEY_ATTR_TYPE_LIFE_DUR);
       
  1184         attr.SetLength((TUint16)(aLifesize.Length()));
       
  1185         iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
  1186         iBuf.Append(aLifesize);
       
  1187     }
       
  1188 }
       
  1189 
       
  1190 
       
  1191 //Only send 1 SPI for the ISAKMP SA, AH or ESP
       
  1192 void TIkev1IsakmpStream::IsakmpDelete(TDesC8 &aSPI, TUint8 aProtocol)
       
  1193 {
       
  1194     TDeleteISAKMP delete_payload;
       
  1195 
       
  1196     DEBUG_LOG(_L("[DEL]"));
       
  1197 
       
  1198     *iNextPayload = ISAKMP_PAYLOAD_D;       //Fills the previous payload next field
       
  1199     iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address.
       
  1200     
       
  1201     delete_payload.SetLength((TUint16)(sizeof(delete_payload) + aSPI.Length())); //No Notification Data yet!!!
       
  1202     delete_payload.SetDOI(iNegotiation->iDOI);  
       
  1203     delete_payload.SetProtocol(aProtocol);
       
  1204     delete_payload.SetSPISize((TUint8)aSPI.Length());
       
  1205     delete_payload.SetNumSPI(1);
       
  1206 
       
  1207     iBuf.Append((TUint8 *)&delete_payload, sizeof(delete_payload)); //Header
       
  1208     iBuf.Append(aSPI);  //insert the SPI
       
  1209 }
       
  1210 
       
  1211 //Adds the Vendor ID payload to the buffer
       
  1212 void TIkev1IsakmpStream::IsakmpVendorId(TInt aID_Type,
       
  1213                                    TUint8 *aICOOKIE,
       
  1214                                    TUint8 *aRCOOKIE,
       
  1215                                    TInetAddr &aLocalAddr,
       
  1216                                    TUint8 *aGenericVidData, TInt aGenericVidLth )
       
  1217 {
       
  1218     
       
  1219     *iNextPayload = ISAKMP_PAYLOAD_VID;    //Fills the previous payload next field
       
  1220     iNextPayload  = (TUint8 *)(iBuf.Ptr() + iBuf.Length());
       
  1221 
       
  1222     if ( (aID_Type == IETF_NATT_VENDOR_ID || aID_Type == IETF_RFC_NATT_VENDOR_ID) && aGenericVidData ) {
       
  1223        TVendorISAKMP vendor_payload;
       
  1224        vendor_payload.SetLength((TUint16)(sizeof(vendor_payload) + aGenericVidLth));
       
  1225        iBuf.Append((TUint8 *)&vendor_payload, sizeof(vendor_payload)); //Header
       
  1226        iBuf.Append(aGenericVidData, aGenericVidLth);                   //Data
       
  1227        return;
       
  1228     }   
       
  1229 /*--------------------------------------------------------
       
  1230  *
       
  1231  *  If an expanded Vendor Id required build it, otherwise 
       
  1232  *  use "old" style" short Vendor Id,             
       
  1233  *
       
  1234  *--------------------------------------------------------*/
       
  1235     TBool ExpandedVID;
       
  1236     
       
  1237     if ( aID_Type == EXPANDED_VENDOR_ID )
       
  1238          ExpandedVID = ETrue;       
       
  1239     else ExpandedVID = EFalse;
       
  1240     
       
  1241     TInt payload_lth = ConstructVendorId(ExpandedVID,
       
  1242                                          aICOOKIE,
       
  1243                                          aRCOOKIE,                                   
       
  1244                                          aLocalAddr,
       
  1245                                         (TVendorISAKMP*)iNextPayload);
       
  1246     iBuf.SetLength(iBuf.Length() + payload_lth);   //The new info just added
       
  1247     
       
  1248 }
       
  1249 
       
  1250 
       
  1251 void TIkev1IsakmpStream::IsakmpChre(TUint16 aLAMType, TUint16 aAttr1, HBufC8 *aBfr1,
       
  1252                                 TUint16 aAttr2, HBufC8 *aBfr2, TUint16 aAttr3, HBufC8 *aBfr3)   
       
  1253 {
       
  1254     TCHREISAKMP chre_payload;
       
  1255 
       
  1256     DEBUG_LOG(_L("[CHRE]"));
       
  1257 
       
  1258     *iNextPayload = ISAKMP_PAYLOAD_CHRE;     //Fills the previous payload next field
       
  1259     iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address.
       
  1260     /*----------------------------------------------------
       
  1261      * Fill generic payload header fields (except length)
       
  1262      *----------------------------------------------------*/
       
  1263     chre_payload.SetLAMtype(aLAMType);      
       
  1264     chre_payload.SetCHREReserved();
       
  1265     TInt pos = iBuf.Length(); //save the position to insert later
       
  1266     iBuf.SetLength(pos + sizeof(chre_payload)); //leave room to insert later
       
  1267     
       
  1268     /*----------------------------------------------------
       
  1269      * Store CHRE payload attribute data 
       
  1270      *----------------------------------------------------*/
       
  1271     if ( aAttr1 !=0 )
       
  1272        IsakmpChreAttrib(aAttr1, aBfr1);
       
  1273     if ( aAttr2 !=0 )
       
  1274        IsakmpChreAttrib(aAttr2, aBfr2);   
       
  1275     if ( aAttr3 !=0 )
       
  1276        IsakmpChreAttrib(aAttr3, aBfr3);   
       
  1277     /*----------------------------------------------------
       
  1278      * Store correct payload length 
       
  1279      *----------------------------------------------------*/
       
  1280     chre_payload.SetLength((TUint16)(iBuf.Length() - pos));
       
  1281     TBuf8<sizeof(chre_payload)> aux;
       
  1282     aux.Append((TUint8 *)&chre_payload, sizeof(chre_payload));
       
  1283     iBuf.Replace(pos, aux.Length(), aux);
       
  1284 }
       
  1285 
       
  1286 void TIkev1IsakmpStream::IsakmpChreAttrib(TUint16 aType, HBufC8 *aBfr)
       
  1287 {
       
  1288   /*----------------------------------------------------
       
  1289    * Store CHRE payload attribute data (variable length) 
       
  1290    *----------------------------------------------------*/
       
  1291     TDataISAKMP attr;
       
  1292     TUint       length;
       
  1293     attr.SetBasic(EFalse);
       
  1294     attr.SetType(aType);
       
  1295     if ( aBfr ) 
       
  1296          length = aBfr->Length(); 
       
  1297     else length = 0;
       
  1298     attr.SetLength((TUint16)length);       
       
  1299     iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
  1300     if ( length )
       
  1301        iBuf.Append(aBfr->Ptr(),length);
       
  1302 }   
       
  1303 
       
  1304 
       
  1305 void TIkev1IsakmpStream::IsakmpIntnet(TUint32 aIpv4Addr)
       
  1306 {
       
  1307   /*----------------------------------------------------------
       
  1308    * Build inititor (=client) private Internal Address payload
       
  1309    * Payload contains only PRI_INTERNAL_ADDRESS attribute coded
       
  1310    * as a basic attribute with value 0.
       
  1311    *---------------------------------------------------------*/
       
  1312     TINTNETISAKMP intnet_payload;
       
  1313     TDataISAKMP   attr;
       
  1314 
       
  1315     DEBUG_LOG(_L("[IA]"));
       
  1316 
       
  1317     *iNextPayload = ISAKMP_INT_NETWORK;     //Fills the previous payload next field
       
  1318     iNextPayload  = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address.
       
  1319     
       
  1320     intnet_payload.SetLength((TUint16)(sizeof(intnet_payload) +
       
  1321                                       (2 + 2)));  //basic attribute
       
  1322     iBuf.Append((TUint8 *)&intnet_payload,
       
  1323                           sizeof(intnet_payload));  //Payload Header
       
  1324     attr.SetBasic(ETrue);
       
  1325     attr.SetType(PRI_INTERNAL_ADDRESS);
       
  1326     attr.SetValue((TUint16)aIpv4Addr);  
       
  1327     iBuf.Append((TUint8 *)&attr, sizeof(attr));
       
  1328 
       
  1329 }
       
  1330 
       
  1331 void TIkev1IsakmpStream::IsakmpNatD(TBool aRfcNatt, TDesC8 &aHash)
       
  1332 {
       
  1333   /*------------------------------------------------------------
       
  1334    * Build NAT-D related to NAT discovery.
       
  1335    * Payload data is a hash data defined as follows:
       
  1336    * HASH = HASH(CKY-I | CKY-R | IP | Port)
       
  1337    * using the negotiated HASH algorithm   
       
  1338    *---------------------------------------------------------*/
       
  1339     TNATDISAKMP nat_d_payload;
       
  1340 
       
  1341     DEBUG_LOG(_L("[NAT_D]"));
       
  1342 	
       
  1343 	if ( aRfcNatt )
       
  1344     	*iNextPayload = IETF_RFC_NAT_DISCOVERY;     //Fills the previous payload next field
       
  1345     else
       
  1346     	*iNextPayload = IETF_NAT_DISCOVERY;     //Fills the previous payload next field
       
  1347     iNextPayload  = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address.
       
  1348 
       
  1349     nat_d_payload.SetLength((TUint16)(sizeof(nat_d_payload) + aHash.Length()));
       
  1350     iBuf.Append((TUint8 *)&nat_d_payload, sizeof(nat_d_payload));   //Header
       
  1351     iBuf.Append(aHash);                                             //Data
       
  1352 
       
  1353 }
       
  1354 
       
  1355 void TIkev1IsakmpStream::IsakmpAttributes(TUint8 aMsgType, TUint16 aIdentifier, TDesC8 &aAttributes)
       
  1356 {
       
  1357   /*------------------------------------------------------------
       
  1358    * Build Attributes payload. (used with config-mode and XAUTH)
       
  1359    *---------------------------------------------------------*/
       
  1360     TAttributeISAKMP attr_payload;
       
  1361     attr_payload.SetCfgMsgType(aMsgType);      
       
  1362     attr_payload.SetReservedField();
       
  1363     attr_payload.SetIdentifier(aIdentifier);    
       
  1364 
       
  1365     DEBUG_LOG(_L("[ATTR]"));
       
  1366 
       
  1367     *iNextPayload = ISAKMP_PAYLOAD_ATTRIBUTES;     //Fills the previous payload next field
       
  1368     iNextPayload  = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address.
       
  1369 
       
  1370     attr_payload.SetLength((TUint16)(sizeof(attr_payload) + aAttributes.Length()));
       
  1371     iBuf.Append((TUint8 *)&attr_payload, sizeof(attr_payload));   //Header
       
  1372     iBuf.Append(aAttributes);                                     //Data
       
  1373 }