vpnengine/ikev1lib/src/ikev1dialog.cpp
changeset 0 33413c0669b9
child 17 d1a0d37b52a1
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   CIkeDialog class implementation
       
    15 *
       
    16 */
       
    17 
       
    18 #include <random.h>
       
    19 
       
    20 #include "ikev1dialog.h"
       
    21 #include "dhparameters.h"
       
    22 #include "ikedebug.h"
       
    23 #include "ikev1pluginsession.h"
       
    24 #include "ikev1crypto.h"
       
    25 #include "ikev1filesdef.h"
       
    26 
       
    27 
       
    28 CIkev1Dialog::CIkev1Dialog( MIkeDebug& aDebug )
       
    29  : CActive( EPriorityStandard ),
       
    30    iDebug( aDebug )
       
    31 {
       
    32     CActiveScheduler::Add(this);    //Added to the Active Scheduler
       
    33 }
       
    34 
       
    35 CIkev1Dialog::~CIkev1Dialog()
       
    36 {
       
    37     DEBUG_LOG(_L("CIkev1Dialog destructed"));
       
    38 	    		
       
    39     DeQueueDialog(this);
       
    40     
       
    41     if(iTimeout)
       
    42         {
       
    43         iTimeout->Cancel();
       
    44         }
       
    45     Cancel();           // Dialog itself    		
       
    46 
       
    47     delete iTimeout;
       
    48     delete iInputData;
       
    49     
       
    50     iFs.Close();
       
    51 }
       
    52 
       
    53 void CIkev1Dialog::PurgeDialogQueue(CIkev1Dialog* aQueuedDialog)
       
    54 {
       
    55     CIkev1Dialog* NextDialog;
       
    56     while ( aQueuedDialog ) {
       
    57         NextDialog = aQueuedDialog->iNext;
       
    58         delete aQueuedDialog;
       
    59         aQueuedDialog = NextDialog;
       
    60     }   
       
    61 }   
       
    62 
       
    63 void CIkev1Dialog::DoCancel()
       
    64 {
       
    65     iNotifier.CancelNotifier(KUidVpnDialogNotifier);       
       
    66     iNotifier.Close();
       
    67 	DEBUG_LOG(_L("CIkev1Dialog::DoCancel() OK"));				
       
    68 }
       
    69 
       
    70 void CIkev1Dialog::ConstructL(CIkev1PluginSession* aPluginSession, CIkev1Dialog* *aToQueAnchor)
       
    71 {
       
    72     User::LeaveIfError(iFs.Connect());
       
    73     iTimeout = new (ELeave) CDialogTimeout( iDebug );
       
    74     iTimeout->ConstructL(this);
       
    75     iToQueAnchor = aToQueAnchor;
       
    76 	iPluginSession = aPluginSession;
       
    77 }
       
    78 
       
    79 CIkev1Dialog* CIkev1Dialog::NewL( CIkev1PluginSession* aPluginSession,
       
    80                               CIkev1Dialog** aToQueAnchor,
       
    81                               MIkeDebug& aDebug )
       
    82 {
       
    83     CIkev1Dialog* Dialog = new (ELeave) CIkev1Dialog( aDebug );
       
    84     Dialog->ConstructL( aPluginSession, aToQueAnchor );
       
    85      
       
    86     return Dialog;
       
    87 }
       
    88 
       
    89 void CIkev1Dialog::StoreUserNameL(TPtr8 aUserName)
       
    90 {
       
    91 /*--------------------------------------------------------------------
       
    92  *
       
    93  *  Store specified user name into cache file (used as init value in
       
    94  *  the next user name specific dialog).
       
    95  *  User name shall be encrypted (DES) before stored into cache file. 
       
    96  *
       
    97  *---------------------------------------------------------------------*/
       
    98 
       
    99  
       
   100 	if (aUserName.Length() == 0)
       
   101 	    {
       
   102 	    User::Leave(KErrArgument);
       
   103 	    }
       
   104 		
       
   105 	//
       
   106 	// Allocate buffer for file header and encrypted key
       
   107 	//
       
   108 
       
   109 	HBufC8* HeaderBfr = HBufC8::NewLC(aUserName.Length() + sizeof(TUserNameFileHdr) + 32);
       
   110     
       
   111 	TUserNameFileHdr* FileHeader = (TUserNameFileHdr*)HeaderBfr->Ptr();
       
   112 	//
       
   113 	// Get random data values for salt and IV. 
       
   114 	//
       
   115 	TPtr8 ptr((TUint8*)FileHeader, sizeof(TUserNameFileHdr));
       
   116 	ptr.SetLength(sizeof(TUserNameFileHdr));
       
   117 	TRandom::RandomL(ptr);
       
   118 
       
   119 	FileHeader->iFileId = USER_NAME_FILE_ID;	
       
   120 	//
       
   121 	// Build encryption key from just created salt data and fixed
       
   122 	// secret passphrase using MD5 hash
       
   123 	//
       
   124 	TBuf8<16>  EncryptionKey;
       
   125 	TPtr8 SaltPtr((TUint8*)FileHeader->iSalt, 8, 8);
       
   126 	User::LeaveIfError(CIkev1Dialog::BuildEncryptionKey(SaltPtr, EncryptionKey));
       
   127 	   //
       
   128 	   // Encrypt user name data with just created key. 
       
   129 	   // Because DES is used as encryption algorithm, the eight first
       
   130 	   // octets of created encryption octets is used as encryption key.
       
   131 	   //
       
   132 	    TInt EncrLth = 0;
       
   133     EncrLth = SymmetricCipherL((TUint8*)aUserName.Ptr(),
       
   134 					          ((TUint8*)FileHeader + sizeof(TUserNameFileHdr)),
       
   135            					    aUserName.Length(), FileHeader->iIV, (TUint8*)EncryptionKey.Ptr(), ETrue);
       
   136 	if ( EncrLth ) 
       
   137 	    {
       
   138         //
       
   139         // Write encrypted data into user name file
       
   140         //
       
   141 		RFile NameFile;		  
       
   142 
       
   143 		TBuf<128> Ppath;	
       
   144 		User::LeaveIfError(iFs.PrivatePath(Ppath));
       
   145 
       
   146 	    Ppath.Append(USER_NAME_CACHE_FILE);
       
   147 	    TInt err = iFs.CreatePrivatePath(EDriveC);
       
   148 	    if (err != KErrNone &&
       
   149 	        err != KErrAlreadyExists)
       
   150 	        {
       
   151 	        User::Leave(err);
       
   152 	        }
       
   153 	    User::LeaveIfError(NameFile.Replace(iFs, Ppath, EFileShareAny|EFileWrite));
       
   154 
       
   155 		TPtrC8 EncryptedData((TUint8*)FileHeader, sizeof(TUserNameFileHdr) + EncrLth); 
       
   156 
       
   157 		NameFile.Write(EncryptedData);
       
   158 		NameFile.Close();
       
   159 	    }
       
   160 
       
   161     CleanupStack::PopAndDestroy(); // Delete encryption buffer
       
   162 }
       
   163 
       
   164 /*--------------------------------------------------------------------
       
   165  *
       
   166  *  Asynchronous dialog is completed. 
       
   167  *
       
   168  *---------------------------------------------------------------------*/
       
   169 void CIkev1Dialog::RunL()
       
   170 {
       
   171     TInt   delete_obj = 1;
       
   172     HBufC8 *un_bfr    = NULL;
       
   173     HBufC8 *pw_bfr    = NULL;
       
   174     CIkev1Dialog* NextDialog = iNext;
       
   175 
       
   176     iNotifier.CancelNotifier(KUidVpnDialogNotifier);            
       
   177     iNotifier.Close();
       
   178 
       
   179     if ( iStatus.Int() == KErrNone )
       
   180 	{
       
   181        if ( iCallback )
       
   182 	   {
       
   183           TIPSecDialogOutput& resp = iResponseBuf();
       
   184           un_bfr = ConvertPwdToOctetString(resp.iOutBuf);
       
   185 		  pw_bfr = ConvertPwdToOctetString(resp.iOutBuf2);		  
       
   186        }          
       
   187     }
       
   188 
       
   189     if ( iCallback )
       
   190 	{
       
   191 		TInt err;
       
   192 		TRAP(err, delete_obj = iCallback->DialogCompleteL(this, iUserInfo,
       
   193 								                          un_bfr,               //User name
       
   194 			                                              pw_bfr,               //Password
       
   195 			                                              NULL));               //domain
       
   196 	    delete un_bfr; 
       
   197 	    delete pw_bfr;
       
   198 	    if ( err != KErrNone )
       
   199 		  delete_obj = 1;
       
   200     }
       
   201     
       
   202     if ( delete_obj )
       
   203 	{
       
   204        delete this; 
       
   205     }
       
   206     
       
   207     //
       
   208     //  Start a dialog from wait queue if there is some 
       
   209     //
       
   210     if ( NextDialog )
       
   211        NextDialog->StartDialogL();
       
   212 }
       
   213 
       
   214 
       
   215 /*--------------------------------------------------------------------
       
   216  *
       
   217  *  Get user name and password data for Legacy authentication
       
   218  *  This is a synchronous dialog which does NOT convert user name and
       
   219  *  password data into the 8-bit ASCII text 
       
   220  *
       
   221  *---------------------------------------------------------------------*/
       
   222 TInt CIkev1Dialog::GetSyncUNPWDialog(TDes& aUserName, TDes& aPassword)
       
   223 {
       
   224 TIPSecDialogOutput output;
       
   225 
       
   226 
       
   227     TIPSecDialogInfo dialog_input(TKMDDialog::EUserPwd, 0);
       
   228 	
       
   229     TPckgBuf<TIPSecDialogInfo> InfoBuf(dialog_input);//package it in appropriate buf
       
   230 	
       
   231     TPckgBuf<TIPSecDialogOutput> ResponseBuf(output);//create the buf to receive the response
       
   232 
       
   233     TInt status = LauchSyncDialog(InfoBuf, ResponseBuf);
       
   234     if ( status == KErrNone ) {
       
   235        TIPSecDialogOutput& resp = ResponseBuf();
       
   236        aUserName = resp.iOutBuf;
       
   237        aPassword = resp.iOutBuf2;      
       
   238     }   
       
   239 
       
   240     return status;
       
   241 }
       
   242 
       
   243 /*--------------------------------------------------------------------
       
   244  *
       
   245  *  Get user name and password data for Legacy authentication
       
   246  *  This is a synchronous dialog which does NOT convert user name and
       
   247  *  password data into the 8-bit ASCII text
       
   248  *  Uses username cache
       
   249  *
       
   250  *---------------------------------------------------------------------*/
       
   251 TInt CIkev1Dialog::GetSyncUNPWCacheDialog(TDes& aUserName, TDes& aPassword)
       
   252 {
       
   253     TInt status = KErrGeneral;
       
   254     TIPSecDialogOutput output;
       
   255 
       
   256     TIPSecDialogInfo dialog_input(TKMDDialog::EUserPwd, 0);
       
   257     
       
   258     iInputData = CreateDialogInput(dialog_input, ETrue);// TRUE = Use user name cache       
       
   259     
       
   260     TPckgBuf<TIPSecDialogOutput> ResponseBuf(output);//create the buf to receive the response
       
   261 
       
   262     if ( iInputData )
       
   263         status = LauchSyncDialog((TPckgBuf<TIPSecDialogInfo>&)*iInputData, ResponseBuf);
       
   264     
       
   265     if ( status == KErrNone ) {
       
   266         TIPSecDialogOutput& resp = ResponseBuf();
       
   267         aUserName = resp.iOutBuf;
       
   268         aPassword = resp.iOutBuf2;      
       
   269     }
       
   270 
       
   271     return status;
       
   272 }
       
   273 
       
   274 void CIkev1Dialog::ShowErrorDialogL(TInt aDialogText, TAny *aUserInfo, MIkeDialogComplete*  aCallback )
       
   275 {
       
   276     iDialogType = TNoteDialog::EInfo;
       
   277     iUserInfo   = aUserInfo;
       
   278     iCallback   = aCallback; // For asynchronous dialog RunL
       
   279 
       
   280 	TIPSecDialogInfo dialog_input(TNoteDialog::EInfo, aDialogText);		
       
   281 	iInputData = CreateDialogInput(dialog_input, EFalse);// FALSE = Do not use user name cache    
       
   282     if ( iInputData ) 
       
   283        LaunchDialogL();   //launch the dialog 
       
   284 }
       
   285 
       
   286 /*--------------------------------------------------------------------
       
   287  *
       
   288  *  Get user name and password data for Legacy authentication
       
   289  *
       
   290  *---------------------------------------------------------------------*/
       
   291 void CIkev1Dialog::GetAsyncUNPWDialogL(TAny *aUserInfo, MIkeDialogComplete*  aCallback)
       
   292 {
       
   293 	DEBUG_LOG2(_L("CIkev1Dialog::GetAsyncUNPWDialogL(), aUserInfo =  %x, aCallback = %x"), aUserInfo, aCallback);
       
   294 	
       
   295     iDialogType = TKMDDialog::EUserPwd;
       
   296     iUserInfo   = aUserInfo;
       
   297     iCallback   = aCallback; // For asynchronous dialog RunL
       
   298 
       
   299 	TIPSecDialogInfo dialog_input(TKMDDialog::EUserPwd, 0);		
       
   300 	iInputData = CreateDialogInput(dialog_input, ETrue);// TRUE = Use user name cache    	
       
   301     if ( iInputData )
       
   302        LaunchDialogL();   //launch the dialog
       
   303 }
       
   304 
       
   305 /*--------------------------------------------------------------------
       
   306  *
       
   307  *  Get user name and Secure ID pin data for Legacy authentication
       
   308  *
       
   309  *---------------------------------------------------------------------*/
       
   310 void CIkev1Dialog::GetAsyncSecureidDialogL(TAny *aUserInfo, MIkeDialogComplete*  aCallback)
       
   311 {
       
   312 	DEBUG_LOG2(_L("CIkev1Dialog::GetAsyncSecureidDialogL(), aUserInfo =  %x, aCallback = %x"), aUserInfo, aCallback);
       
   313 	
       
   314     iDialogType = TKMDDialog::ESecurIdPin;
       
   315     iUserInfo   = aUserInfo;
       
   316     iCallback   = aCallback; // For asynchronous dialog RunL
       
   317 
       
   318 	TIPSecDialogInfo dialog_input(TKMDDialog::ESecurIdPin, 0);		
       
   319 	iInputData = CreateDialogInput(dialog_input, ETrue);// TRUE = Use user name cache    	
       
   320     if ( iInputData )
       
   321        LaunchDialogL();   //launch the dialog
       
   322 }
       
   323 
       
   324 /*--------------------------------------------------------------------
       
   325  *
       
   326  *  Get user name and Secure ID next pin data for Legacy authentication
       
   327  *
       
   328  *---------------------------------------------------------------------*/
       
   329 void CIkev1Dialog::GetAsyncSecureNextPinDialogL(TAny *aUserInfo,  MIkeDialogComplete* aCallback)
       
   330 {
       
   331 	DEBUG_LOG2(_L("CIkev1Dialog::GetAsyncSecureNextPinDialogL(), aUserInfo =  %x, aCallback = %x"), aUserInfo, aCallback);
       
   332 	
       
   333     iDialogType = TKMDDialog::ESecurIdNextPin;
       
   334     iUserInfo   = aUserInfo;
       
   335     iCallback   = aCallback; // For asynchronous dialog RunL
       
   336     
       
   337 	TIPSecDialogInfo dialog_input(TKMDDialog::ESecurIdNextPin, 0);		
       
   338 	iInputData = CreateDialogInput(dialog_input, ETrue);// TRUE = Use user name cache    	
       
   339     if ( iInputData )
       
   340        LaunchDialogL();   //launch the dialog
       
   341 }
       
   342 
       
   343 
       
   344 /*--------------------------------------------------------------------
       
   345  *
       
   346  * For future use (for challenge/response type  Legacy authentication)
       
   347  *
       
   348  *---------------------------------------------------------------------*/
       
   349 void CIkev1Dialog::GetAsyncUNAMEDialog(TAny* /*aUserInfo*/, MIkeDialogComplete*  /*aCallback*/)
       
   350 {
       
   351 }
       
   352 
       
   353 void CIkev1Dialog::GetAsyncRespDialog(TPtr8 /*aChallenge*/, TAny* /*aUserInfo*/, MIkeDialogComplete* /*aCallback*/)
       
   354 {
       
   355 }
       
   356 
       
   357 
       
   358 ///////////////////////////////////////////////////////////////////////////////
       
   359 //
       
   360 // Private methods
       
   361 //
       
   362 ///////////////////////////////////////////////////////////////////////////////
       
   363 HBufC8* CIkev1Dialog::CreateDialogInput(TIPSecDialogInfo& aDialogInfo, TBool aUserNameCache)
       
   364 {
       
   365 	//
       
   366 	// Create dialog input data buffer. Concatenate cached user name
       
   367 	// string into input data if requested and if cached name exists
       
   368 	//
       
   369 	HBufC8* DialogInput;
       
   370 	HBufC8* UserName = NULL;
       
   371 	TInt    UserNameLth = 0;	
       
   372 	TPckgBuf<TIPSecDialogInfo> infoBuf(aDialogInfo);
       
   373 	
       
   374 	if ( aUserNameCache ) {
       
   375 	   UserName = GetUserNameFromFile();
       
   376 	   if ( UserName )
       
   377 		  UserNameLth = UserName->Length();
       
   378 	}
       
   379 
       
   380 	DialogInput = HBufC8::New(sizeof(TIPSecDialogInfo) + UserNameLth);
       
   381 	if ( DialogInput ) {
       
   382 	   DialogInput->Des().Copy(infoBuf);
       
   383 	   if ( UserName ) {
       
   384 	      DialogInput->Des().Append(UserName->Des());
       
   385 		  delete UserName;
       
   386 	   }	  
       
   387 	}   
       
   388 
       
   389 	return DialogInput;
       
   390 }   
       
   391 
       
   392 void CIkev1Dialog::LaunchDialogL()
       
   393 {
       
   394     //
       
   395     // Launch the dialog if there is no dialog already going 
       
   396     //
       
   397     if ( QueueDialog(this) == 1 ) 
       
   398     {
       
   399         StartDialogL();
       
   400     }      
       
   401 }   
       
   402 
       
   403 void CIkev1Dialog::StartDialogL()
       
   404 {
       
   405     //
       
   406     // Start an asynchronous dialog 
       
   407     //
       
   408     User::LeaveIfError(iNotifier.Connect());
       
   409     iNotifier.StartNotifierAndGetResponse(iStatus,
       
   410                                           KUidVpnDialogNotifier,
       
   411                                          (TPckgBuf<TIPSecDialogInfo>&)(*iInputData),
       
   412                                           iResponseBuf);
       
   413     SetActive();
       
   414 }   
       
   415 
       
   416 
       
   417 TInt CIkev1Dialog::LauchSyncDialog(const TDesC8& aInput, TDes8& aOutput)
       
   418 {
       
   419     RNotifier notifier;
       
   420     TInt err = notifier.Connect();
       
   421     if(err != KErrNone)
       
   422         {
       
   423         return err;
       
   424         }
       
   425     
       
   426     TRequestStatus status;
       
   427     notifier.StartNotifierAndGetResponse(status, KUidVpnDialogNotifier, aInput, aOutput);
       
   428     User::WaitForRequest( status );
       
   429     
       
   430     notifier.CancelNotifier(KUidVpnDialogNotifier);
       
   431     notifier.Close();
       
   432     
       
   433     return status.Int();
       
   434 }
       
   435 
       
   436 TInt CIkev1Dialog::QueueDialog(CIkev1Dialog* aDialog)
       
   437 {
       
   438     TInt DialogCount = 1;
       
   439     aDialog->iNext   = NULL;
       
   440     CIkev1Dialog* QueuedDialog = *aDialog->iToQueAnchor;
       
   441     
       
   442     if ( QueuedDialog  ) 
       
   443     {
       
   444        DialogCount ++;  
       
   445        while ( QueuedDialog->iNext ) {
       
   446            QueuedDialog = QueuedDialog->iNext;
       
   447            DialogCount ++;
       
   448        }
       
   449        QueuedDialog->iNext = aDialog;
       
   450     }    
       
   451     else *aDialog->iToQueAnchor = aDialog;
       
   452     
       
   453     return DialogCount;
       
   454 }
       
   455 
       
   456 void CIkev1Dialog::DeQueueDialog(CIkev1Dialog* aDialog)
       
   457 {
       
   458     CIkev1Dialog* PreviousDialog = NULL;
       
   459     CIkev1Dialog* QueuedDialog   = *aDialog->iToQueAnchor;
       
   460     
       
   461     while ( QueuedDialog ) {
       
   462         if ( QueuedDialog == aDialog ) {
       
   463            if ( PreviousDialog )
       
   464                 PreviousDialog->iNext  = QueuedDialog->iNext;
       
   465            else *aDialog->iToQueAnchor = QueuedDialog->iNext;
       
   466         }
       
   467         PreviousDialog = QueuedDialog;
       
   468         QueuedDialog   = QueuedDialog->iNext;       
       
   469     }    
       
   470 }   
       
   471 
       
   472 HBufC8* CIkev1Dialog::GetUserNameFromFile()
       
   473 {
       
   474 /*--------------------------------------------------------------------
       
   475  *
       
   476  *  Get user name default value from encrypted cache file
       
   477  *
       
   478  *---------------------------------------------------------------------*/
       
   479 	//
       
   480 	// Allocate buffer for file header and encrypted key
       
   481 	//
       
   482 	HBufC8* UserNameBfr = NULL;
       
   483 	RFile UserNameFile;
       
   484 	if ( UserNameFile.Open(iFs, USER_NAME_CACHE_FILE, EFileRead) == KErrNone ) {
       
   485 		TInt FileSize = 0;
       
   486 		UserNameFile.Size(FileSize);
       
   487 		if ( (FileSize > 0) && (FileSize < 256) )  {    
       
   488 			HBufC8* FileData = HBufC8::New(FileSize);
       
   489 			if ( FileData ) {
       
   490                //
       
   491                // Read encrypted file data into the allocated buffer.
       
   492 	           //
       
   493 			   TPtr8 FileDataPtr(FileData->Des());
       
   494 			   if ( UserNameFile.Read(FileDataPtr) == KErrNone )  {
       
   495 				  //
       
   496 				  // Build decryption key and decrypt user name data.
       
   497 				  // Both salt data needed in key generation and IV
       
   498 				  // value required in decryption are found from
       
   499 				  // encrypted file header
       
   500 				  //
       
   501 				  TUserNameFileHdr* FileHeader = (TUserNameFileHdr*)FileData->Ptr();
       
   502 				  if ( FileHeader->iFileId == USER_NAME_FILE_ID ) {
       
   503     			     TBuf8<16>  DecryptionKey;
       
   504 				     TPtr8 SaltPtr((TUint8*)FileHeader->iSalt, 8, 8);				  
       
   505 				     if ( CIkev1Dialog::BuildEncryptionKey(SaltPtr, DecryptionKey) ) {
       
   506 					    TInt EncrLth = FileSize - sizeof(TUserNameFileHdr);
       
   507 					    TUint8* UserNameRawPtr = (TUint8*)FileHeader + sizeof(TUserNameFileHdr); 					 
       
   508 					    TInt err;
       
   509 					    TRAP(err, EncrLth = SymmetricCipherL(UserNameRawPtr, UserNameRawPtr, EncrLth,
       
   510 						                                     FileHeader->iIV, (TUint8*)DecryptionKey.Ptr(), EFalse));
       
   511     				    if ( (err == KErrNone) && EncrLth ) {
       
   512 						   //
       
   513 						   // Allocate a HBufC8 for decrypted user name
       
   514 						   //
       
   515 					       UserNameBfr = HBufC8::New(EncrLth);
       
   516 						   if ( UserNameBfr )
       
   517 						      UserNameBfr->Des().Copy(UserNameRawPtr, EncrLth);
       
   518 						}
       
   519 					 }	 
       
   520 				  }  
       
   521 			   }
       
   522 			   delete FileData;
       
   523 			}
       
   524 		}	
       
   525 	}
       
   526 	
       
   527 	UserNameFile.Close();
       
   528 	return UserNameBfr;
       
   529 }
       
   530 
       
   531 
       
   532 HBufC8 *CIkev1Dialog::ConvertPwdToOctetString(TDesC &aUnicodeBfr)
       
   533 {
       
   534 /*--------------------------------------------------------------------
       
   535  *
       
   536  *  Convert password from Unicode string to 8-bit octet string
       
   537  *
       
   538  *---------------------------------------------------------------------*/
       
   539     HBufC8 *octet_data = HBufC8::New(aUnicodeBfr.Length());
       
   540 	if ( octet_data ) {
       
   541        TPtr8 ptr8(octet_data->Des());
       
   542        ptr8.Copy(aUnicodeBfr);
       
   543     }   
       
   544     return octet_data;
       
   545 }
       
   546 
       
   547 
       
   548 
       
   549 TBool CIkev1Dialog::BuildEncryptionKey(const TDesC8& aSalt, TDes8& aEncryptionKey)
       
   550 {
       
   551 /*--------------------------------------------------------------------
       
   552  *
       
   553  *  Build encryption key for user name data cipher.
       
   554  *  The encryption key is created as follows:
       
   555  *  DH group 5 (MODP 1536) prime is used as passphrase seed so
       
   556  *  that MODP_1536_PRIME_LENGTH/4 octets of seed is taken from prime
       
   557  *  starting from position MODP_1536_PRIME_LENGTH/2.
       
   558  *  The specified salt is concatenated with that data.
       
   559  *  The MD5 hash over that shall be the encryption key (max key then
       
   560  *  128 bits)
       
   561  *
       
   562  *---------------------------------------------------------------------*/
       
   563 	//
       
   564 	// Allocate buffer for key seed data
       
   565 	//
       
   566 	HBufC8* SeedDataBfr = HBufC8::New(aSalt.Length() + MODP_1536_PRIME_LENGTH/4);
       
   567 	if ( !SeedDataBfr )
       
   568 	   return EFalse;
       
   569 	
       
   570 	TPtr8 SeedDataPtr(SeedDataBfr->Des()); 
       
   571 	TPtrC8 PassPhrasePtr((TUint8 *)&MODP_1536_PRIME[MODP_1536_PRIME_LENGTH/2],
       
   572 	                               MODP_1536_PRIME_LENGTH/4);
       
   573 	SeedDataPtr.Copy(PassPhrasePtr);
       
   574 	SeedDataPtr.Append(aSalt);
       
   575 
       
   576 	TInt err;
       
   577 	TRAP(err, MD5HashL(SeedDataPtr, aEncryptionKey));
       
   578 	
       
   579 	delete SeedDataBfr;
       
   580 	
       
   581 	if ( err == KErrNone )
       
   582 		 return ETrue;		
       
   583     else return EFalse;		
       
   584 
       
   585 }
       
   586 
       
   587 
       
   588 
       
   589 /**-------------------------------------------------------
       
   590  *
       
   591  *  CDialogTimeout class
       
   592  *  This timeout class used to check user dialog displayed
       
   593  *  shall be completed in reasonable time (now 90 seconds).
       
   594  *  This class is used the following way:
       
   595  *  -- When a CIkev1Dialog class object is constructed one
       
   596  *     CDialogTimeout object is constructed as well. These
       
   597  *     objects are linked together.
       
   598  *  -- If user dialog completes normally (within 90 seconds)
       
   599  *     CDialogTimeout is cancelled in CIkev1Dialog.RunL().
       
   600  *  -- If timeout expires, CIkev1Dialog is completed via CDialogTimeout.RunL()
       
   601  *
       
   602  *--------------------------------------------------------*/
       
   603 CDialogTimeout::CDialogTimeout( MIkeDebug& aDebug )
       
   604  : CTimer( EPriorityStandard ),
       
   605    iDebug( aDebug )
       
   606 {
       
   607     CActiveScheduler::Add(this);    //Adds itself to the scheduler only the first time
       
   608 }
       
   609 
       
   610 CDialogTimeout::~CDialogTimeout()
       
   611 {
       
   612     DEBUG_LOG(_L("CDialogTimeout destructed"));		
       
   613     if (IsActive())
       
   614         Cancel();
       
   615 }
       
   616 
       
   617 void CDialogTimeout::ConstructL(CIkev1Dialog *aDialog)
       
   618 {
       
   619     CTimer::ConstructL();
       
   620     iDialog = aDialog;
       
   621     After(90*1000000);  //Start dialog timer
       
   622 }
       
   623 
       
   624 void CDialogTimeout::DoCancel()
       
   625 {
       
   626 	DEBUG_LOG(_L("CDialogTimeout cancelled"));		
       
   627     CTimer::DoCancel();
       
   628 }
       
   629 
       
   630 void CDialogTimeout::RunL()
       
   631 {
       
   632 	DEBUG_LOG(_L("CKmdDialog timeout occurred"));
       
   633     TInt delete_dialog    = 1;
       
   634     CIkev1Dialog* NextDialog = iDialog->NextDialog();
       
   635 	MIkeDialogComplete* Callback = iDialog->Callback();
       
   636     
       
   637     if ( Callback ) 
       
   638     {
       
   639 		TInt err;
       
   640 		DEBUG_LOG2(_L("Calling DialogCompleteL(), UserInfo = %x, Callback = %x"), (TUint32)iDialog->UserInfo(), (TUint32)Callback);					
       
   641         TRAP(err, delete_dialog = Callback->DialogCompleteL(iDialog,
       
   642                                                             iDialog->UserInfo(),
       
   643                                                             NULL,               //User name
       
   644                                                             NULL,               //Password
       
   645                                                             NULL));             //domain
       
   646 		DEBUG_LOG2(_L("DialogCompleteL() completed, err = %d, delete_dialog = %d"), err, delete_dialog);			
       
   647 		if ( err != KErrNone )
       
   648 			delete_dialog = 1;
       
   649     }  
       
   650     if ( delete_dialog )
       
   651         {
       
   652         delete iDialog;
       
   653         iDialog = NULL;
       
   654         }
       
   655 
       
   656     //
       
   657     //  Start a dialog from wait queue if there is some 
       
   658     //
       
   659     if ( NextDialog )
       
   660 	{
       
   661 	   DEBUG_LOG(_L("Next dialog started from dialog timer"));	
       
   662        NextDialog->StartDialogL();
       
   663 	}    
       
   664 }
       
   665