cellularsrvapitest/datatransferhaitest/esock/src/T_DataVerify.cpp
changeset 0 3553901f7fa8
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     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:
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32base.h>
       
    20 #include <f32file.h>
       
    21 
       
    22 #include <hash.h> // CryptoHW (md5hash)
       
    23 
       
    24 #include "T_DataVerify.h"
       
    25 
       
    26 
       
    27 
       
    28 /*@{*/
       
    29 //Command LIT's
       
    30 _LIT(KCmdVerifyData,	"VerifyData");
       
    31 /*@}*/
       
    32 
       
    33 /*@{*/
       
    34 //LIT's for reading params from ini file
       
    35 _LIT( KDataVerifyType,  "VerifyType" );
       
    36 _LIT( KDataVerifyFile,  "VerifyFile" );
       
    37 _LIT( KChecksum,     	"Checksum" );
       
    38 _LIT( KMD5Type,			"MD5" );        // Use MD5 with data verify
       
    39 /*@}*/
       
    40 
       
    41 
       
    42 namespace DataVerify
       
    43 	{
       
    44 	const TInt KMD5Size = 32;
       
    45     const TInt KMD5length  = 32;
       
    46     const TInt KBufsize    = 512;
       
    47     const TInt KCharlength = 2;
       
    48 	}
       
    49 
       
    50 typedef TBuf8<DataVerify::KMD5length> THashBuf;
       
    51 
       
    52 CT_DataVerify::CT_DataVerify():
       
    53 	iMD5(NULL)
       
    54 	{
       
    55 	}
       
    56 
       
    57 CT_DataVerify* CT_DataVerify::NewL()
       
    58 	{
       
    59 	CT_DataVerify* ret = new (ELeave) CT_DataVerify();
       
    60 	CleanupStack::PushL(ret);
       
    61 	ret->ConstructL();
       
    62 	CleanupStack::Pop(ret);
       
    63 	return ret;
       
    64 	}
       
    65 
       
    66 CT_DataVerify::~CT_DataVerify()
       
    67 	{
       
    68     iFs.Close();
       
    69     if(iMD5)
       
    70     	{
       
    71     	delete iMD5;
       
    72     	iMD5 = NULL;
       
    73     	}
       
    74 	}
       
    75 
       
    76 void CT_DataVerify::ConstructL()
       
    77 	{
       
    78     User::LeaveIfError( iFs.Connect() );
       
    79     iMD5 = CMD5::NewL();
       
    80 	}
       
    81 
       
    82 TAny* CT_DataVerify::GetObject()
       
    83 	{
       
    84 	return NULL;
       
    85 	}
       
    86 
       
    87 TBool CT_DataVerify::DoCommandL(const TTEFFunction& aCommand, const TTEFSectionName& aSection, const TInt /*aAsyncErrorIndex*/)
       
    88 	{
       
    89 	TBool retVal=ETrue;
       
    90 	
       
    91 	if (aCommand==KCmdVerifyData)
       
    92 		{	
       
    93 		DoCmdVerifyData(aSection);	
       
    94 		}
       
    95 	else
       
    96 		{
       
    97 		ERR_PRINTF1(_L("Unknown command"));
       
    98 		retVal=EFalse;
       
    99 		}
       
   100 
       
   101 	return retVal;
       
   102 	}
       
   103 
       
   104 
       
   105 /**
       
   106  * Verifies that the downloaded file is not corrupted by using a previously calculated checksum.
       
   107  * @param aSection - The section in config file to look for the Data Verify Type, the file to verify and the checksum.
       
   108  * @return error - Error code. KErrNone if checksum is equal.
       
   109  */
       
   110 void CT_DataVerify::DoCmdVerifyData(const TTEFSectionName& aSection)
       
   111     {
       
   112     INFO_PRINTF1(_L("*START* CT_TransferData::DoCmdVerifyData"));
       
   113     
       
   114     TBool dataOk =ETrue;
       
   115     TPtrC type;
       
   116     if(!GetStringFromConfig(aSection, KDataVerifyType, type ))
       
   117     	{
       
   118     	ERR_PRINTF2(_L("Error in getting parameter %S from INI file"), &KDataVerifyType);
       
   119     	SetBlockResult(EFail);
       
   120     	dataOk = EFalse;
       
   121     	}
       
   122     
       
   123     TPtrC filename;
       
   124     if(!GetStringFromConfig(aSection, KDataVerifyFile, filename ))
       
   125     	{
       
   126     	ERR_PRINTF2(_L("Error in getting parameter %S from INI file"), &KDataVerifyFile);
       
   127     	SetBlockResult(EFail);
       
   128     	dataOk = EFalse;
       
   129     	}
       
   130     
       
   131     TPtrC checksumParameter;
       
   132     if(!GetStringFromConfig(aSection, KChecksum, checksumParameter ))
       
   133     	{
       
   134     	ERR_PRINTF2(_L("Error in getting parameter %S from INI file"), &KChecksum);
       
   135     	SetBlockResult(EFail);
       
   136     	dataOk = EFalse;
       
   137     	}
       
   138     if(dataOk)
       
   139     	{
       
   140     	TBuf8<DataVerify::KMD5Size> checksum;
       
   141     	checksum.Append(checksumParameter);
       
   142 
       
   143         if (type == KMD5Type)
       
   144             {
       
   145             INFO_PRINTF1(_L("MD5 selected"));
       
   146             TRAPD(error, VerifyChecksumL(checksum, filename));
       
   147             if (error == KErrNone)
       
   148                 {
       
   149                 INFO_PRINTF1(_L("Data verify succeeded"));
       
   150                 }
       
   151             else
       
   152             	{
       
   153                 ERR_PRINTF2(_L("VerifyData failed [%d]"), error);
       
   154                 SetError(error);
       
   155             	}
       
   156             }
       
   157     	}
       
   158 
       
   159     
       
   160     INFO_PRINTF1(_L("*END* CT_TransferData::DoCmdVerifyData"));
       
   161     }
       
   162 
       
   163 
       
   164 /**
       
   165  * Verify Data integrity
       
   166  *
       
   167  * @param aMethod			The verification method
       
   168  * @param aFileName			File to verify
       
   169  * @param aChecksum			Checksum
       
   170  *
       
   171  * @return					N/A
       
   172  *
       
   173  * @leave					System wide error
       
   174  */
       
   175 void CT_DataVerify::VerifyData( const TDataVerifyMethod aMethod, const TFileName& aFileName, const TDesC& aChecksum )
       
   176 	{
       
   177 	TBool dataOk = ETrue;
       
   178 	
       
   179 	if( aFileName.Length() > KMaxFileName)
       
   180 		{
       
   181 		ERR_PRINTF2(_L("Illegal filename: %S"), &aFileName);
       
   182 		SetBlockResult(EFail);
       
   183 		dataOk = EFalse;
       
   184 		}
       
   185 	if(dataOk)
       
   186 		{
       
   187 		THashBuf checksum;
       
   188 		checksum.Append( aChecksum );
       
   189 		
       
   190 		// Use MD5 to verify file
       
   191 		if( aMethod == EDataVerifyMethodMD5 )
       
   192 			{
       
   193 			// MD5 selected
       
   194 			TRAPD(error, VerifyChecksumL( checksum, aFileName ));
       
   195 			if(error == KErrNone)
       
   196 				{
       
   197 				INFO_PRINTF1(_L("Data verify succeeded."));
       
   198 				}
       
   199 			else
       
   200 				{
       
   201 				ERR_PRINTF2(_L("Checksum verification left with error %d"), error);
       
   202 				SetBlockResult(EFail);
       
   203 				}
       
   204 			}
       
   205 		else
       
   206 			{
       
   207 			ERR_PRINTF1(_L("Verification method not supported"));
       
   208 			SetBlockResult(EFail);
       
   209 			}
       
   210 		}
       
   211 	}
       
   212 
       
   213 /**
       
   214  * Verify File integrity
       
   215  *
       
   216  * @param aReferenceFileName	Reference file against to verify integrity
       
   217  * @param aDataFileName			File to verify
       
   218  *
       
   219  * @return						N/A
       
   220  *
       
   221  * @leave						System wide error
       
   222  */
       
   223 void CT_DataVerify::VerifyFileL( const TFileName& aReferenceFileName, const TFileName& aDataFileName )
       
   224 	{
       
   225 	THashBuf refHash;
       
   226 
       
   227 	// hash the first file
       
   228 	HashFileL( aReferenceFileName, refHash );
       
   229 
       
   230 	THashBuf dataHash;
       
   231 	// hash the second file
       
   232 	HashFileL( aDataFileName, dataHash );
       
   233 
       
   234 	// compare hashes together
       
   235 	if( !CompareBuffers( refHash, dataHash ) )
       
   236 		{
       
   237 		// Data was corrupted
       
   238 		User::Leave( KErrCorrupt );
       
   239 		}
       
   240 	}
       
   241 
       
   242 /**
       
   243  * Verify Buffer integrity
       
   244  *
       
   245  * @param aReferenceFileName	Reference file against to verify integrity
       
   246  * @param aData					Buffer to verify
       
   247  *
       
   248  * @return						N/A
       
   249  *
       
   250  * @leave						System wide error
       
   251  */
       
   252 void CT_DataVerify::VerifyBufferL( const TFileName& aReferenceFileName, const TDesC8& aData )
       
   253     {
       
   254 	HBufC8* refdata = 0;
       
   255 	TPtr8 ptr = refdata->Des();
       
   256 	// read file into buffer, file must fit into HBufC8
       
   257 	ReadFileL( aReferenceFileName, ptr );
       
   258 
       
   259 	// compare read file with given buffer
       
   260 	if( !CompareBuffers( refdata->Des(), aData ) )
       
   261 		{
       
   262 		// Data was corrupted
       
   263 		User::Leave( KErrCorrupt );
       
   264 		}
       
   265     }
       
   266 
       
   267 /**
       
   268  * Verify Buffer integrity
       
   269  *
       
   270  * @param aReferenceBuffer		Reference buffer against to verify integrity
       
   271  * @param aData					Buffer to verify
       
   272  *
       
   273  * @return						N/A
       
   274  *
       
   275  * @leave						System wide error
       
   276  */
       
   277 void CT_DataVerify::VerifyBufferL( const TDesC8& aReferenceData, const TDesC8& aData )
       
   278 	{
       
   279 	// Compare buffers
       
   280 	if ( !CompareBuffers( aReferenceData, aData ) )
       
   281 		{
       
   282 		// Data was corrupted
       
   283 		User::Leave( KErrCorrupt );
       
   284 		}
       
   285     }
       
   286 
       
   287 /**
       
   288  * Verify Checksum integrity
       
   289  *
       
   290  * @param aReferenceMD5Checksum		Reference checksum
       
   291  * @param aDataFileName				File to verify
       
   292  *
       
   293  * @return							N/A
       
   294  *
       
   295  * @leave							System wide error
       
   296  */
       
   297 void CT_DataVerify::VerifyChecksumL( const TDesC8& aReferenceMD5Checksum, const TFileName& aDataFileName )
       
   298 	{
       
   299 	// MD5 checksum is always 128 bit (32 char) long
       
   300 	if( aReferenceMD5Checksum.Length() != DataVerify::KMD5length )
       
   301 		{
       
   302 		User::Leave( KErrBadDescriptor );
       
   303 		}
       
   304 
       
   305 	THashBuf hash;
       
   306 	// hash file
       
   307 	HashFileL( aDataFileName, hash );
       
   308 
       
   309 	// converting MD5 checksum to binary is necessary because Hash() function
       
   310 	// returns hash in binary format and reference checksum given in parameter
       
   311 	// is a 32 character long string
       
   312 	THashBuf conversion;
       
   313 	ConvertString2HexL( aReferenceMD5Checksum, conversion );
       
   314 
       
   315 	if( !CompareBuffers( conversion, hash ) )
       
   316 		{
       
   317 		// Data was corrupted
       
   318 		User::Leave( KErrCorrupt );
       
   319 		}
       
   320 	}
       
   321 
       
   322 /**
       
   323  * Verify Checksum integrity
       
   324  *
       
   325  * @param aReferenceMD5Checksum		Reference checksum
       
   326  * @param aData						Data to verify
       
   327  *
       
   328  * @return							N/A
       
   329  *
       
   330  * @leave							System wide error
       
   331  */
       
   332 void CT_DataVerify::VerifyChecksumL( const TDesC8& aReferenceMD5Checksum, const TDesC8& aData )
       
   333     {
       
   334 	// MD5 checksum is always 128 bit (32 char) long
       
   335 	if( aReferenceMD5Checksum.Length() != DataVerify::KMD5length )
       
   336 		{
       
   337 		// MD5 Checksum was not correct length (32 characters)
       
   338 		User::Leave( KErrBadDescriptor );
       
   339 		}
       
   340 
       
   341 	// hash the given buffer
       
   342 	TPtrC8 hash = iMD5->Hash(aData);
       
   343 
       
   344 	// converting MD5 checksum to binary is necessary because Hash() function
       
   345 	// returns hash in binary format and reference checksum given in parameter
       
   346 	// is a 32 character long string
       
   347 	THashBuf conversion;
       
   348 	ConvertString2HexL( aReferenceMD5Checksum, conversion );
       
   349 
       
   350 	// Compare hashs together
       
   351 	if( !CompareBuffers( conversion, hash ) )
       
   352 		{
       
   353 		// Data was corrupted
       
   354 		User::Leave( KErrCorrupt );
       
   355 		}
       
   356 	}
       
   357 
       
   358 /**
       
   359  * Compare Buffers
       
   360  *
       
   361  * @param aReferenceBuffer		Reference buffer
       
   362  * @param aDataBuffer			Buffer to compare
       
   363  *
       
   364  * @return						ETrue if buffer contents match
       
   365  */
       
   366 TBool CT_DataVerify::CompareBuffers( const TDesC8& aReferenceBuffer, const TDesC8& aDataBuffer )
       
   367 	{
       
   368 	TBool res = EFalse;
       
   369 	TInt result = aReferenceBuffer.Compare( aDataBuffer );
       
   370 	
       
   371 	if( result == 0 )
       
   372 		{
       
   373 		// Buffer contents match
       
   374 		res = ETrue;
       
   375 		}
       
   376 	return res;
       
   377 	}
       
   378 
       
   379 /**
       
   380  * Read File
       
   381  *
       
   382  * @param aFileName			File name to read
       
   383  * @param aBuf				Buffer to read file content
       
   384  *
       
   385  * @return					N/A
       
   386  *
       
   387  * @leave					System wide error
       
   388  */
       
   389 void CT_DataVerify::ReadFileL(const TFileName& aFileName, TDes8& aBuf)
       
   390     {
       
   391     RFile file;
       
   392     User::LeaveIfError( file.Open( iFs, aFileName, EFileRead ) );
       
   393     CleanupClosePushL( file );
       
   394 
       
   395     // Get the file size
       
   396     TInt size;
       
   397     User::LeaveIfError( file.Size( size ) );
       
   398 
       
   399     // allocate memory from heap for file content
       
   400     HBufC8* buf = HBufC8::NewLC( size );
       
   401     aBuf = buf->Des();
       
   402 
       
   403     // read file content into buffer, file may be too big for HBufC8
       
   404     User::LeaveIfError( file.Read( aBuf ) );
       
   405 
       
   406     CleanupStack::Pop( buf );
       
   407     CleanupStack::PopAndDestroy( &file ); // file.Close
       
   408     }
       
   409 
       
   410 /**
       
   411  * Hash file in pieces
       
   412  *
       
   413  * @param aFileName			File name to be hashed
       
   414  * @param aDes				Hash value
       
   415  *
       
   416  * @return					N/A
       
   417  *
       
   418  * @leave					System wide error
       
   419  */
       
   420 void CT_DataVerify::HashFileL( const TFileName& aFileName, TDes8& aDes )
       
   421 	{
       
   422 	RFile file;
       
   423 	User::LeaveIfError( file.Open( iFs, aFileName, EFileRead ) );
       
   424 	CleanupClosePushL( file );
       
   425 
       
   426 	TBuf8<DataVerify::KBufsize> buf;
       
   427 
       
   428 	TInt error = KErrNone;
       
   429 	iMD5->Reset();
       
   430 	// File can be hashed in pieces
       
   431 	while( error == KErrNone ) // loop until something goes wrong
       
   432 		{
       
   433 		error = file.Read( buf, DataVerify::KBufsize );
       
   434 		if( buf.Length() != 0 )
       
   435 			{
       
   436 			// MD5 checksum is calculated in pieces
       
   437 			iMD5->Update(buf);
       
   438 			}
       
   439 		else
       
   440 			{
       
   441 			// file ended, end loop
       
   442 			break;
       
   443 			}
       
   444 		}
       
   445 	// Return calculated MD5 checksum
       
   446 	aDes = iMD5->Final();
       
   447 
       
   448 	CleanupStack::PopAndDestroy(&file); // file.Close
       
   449 	}
       
   450 
       
   451 /**
       
   452  * Write File
       
   453  *
       
   454  * @param aFileName			File name
       
   455  * @param aData				Data to be written into file name.
       
   456  *
       
   457  * @return					N/A
       
   458  *
       
   459  * @leave					System wide error
       
   460  */
       
   461 void CT_DataVerify::WriteFileL( const TFileName& aFileName, const TDesC8& aData )
       
   462     {
       
   463     RFile file;
       
   464     // Create file, replace if exists
       
   465     User::LeaveIfError( file.Replace( iFs, aFileName, EFileWrite|EFileStream ) );
       
   466     CleanupClosePushL( file );
       
   467     // Write data into file
       
   468     User::LeaveIfError( file.Write( aData ) );
       
   469     // Commit write
       
   470     User::LeaveIfError( file.Flush() );
       
   471 
       
   472     CleanupStack::PopAndDestroy( &file ); // file.Close
       
   473     }
       
   474 
       
   475 /**
       
   476  * Convert a string to Hexadecimal
       
   477  *
       
   478  * @param aData			String descriptor
       
   479  * @param aDes			Descriptor where Hex value is stored
       
   480  *
       
   481  * @return				N/A
       
   482  *
       
   483  * @leave				System wide error
       
   484  */
       
   485 void CT_DataVerify::ConvertString2HexL( const TDesC8& aData, TDes8& aDes )
       
   486     {
       
   487 	TBuf8<DataVerify::KCharlength> charBuf;
       
   488 
       
   489 	// Check that buffer is even number
       
   490 	if( ( aData.Length() % DataVerify::KCharlength ) != 0 )
       
   491 		{
       
   492 		User::Leave( KErrBadDescriptor );
       
   493 		}
       
   494 
       
   495 	// Go through the data and convert it two characters at a time
       
   496 	// buffer overflow does not occur because buffer is checked to be even number first
       
   497 	for( TInt i = 0, limit = aData.Length()-DataVerify::KCharlength; i <= limit; i+=DataVerify::KCharlength )
       
   498 		{
       
   499 		// Clean char buffer first
       
   500 		charBuf.Delete( 0, charBuf.Length() );
       
   501 		
       
   502 		// Add KCharlength characters into buffer
       
   503 		for ( TInt j = 0; j < DataVerify::KCharlength; j++ )
       
   504 			{
       
   505 			charBuf.Append( aData[i+j] );
       
   506 			}
       
   507 
       
   508 		TUint number;
       
   509 		TLex8 converter = TLex8( charBuf );
       
   510 		// Two characters together represent a hex number in MD5 checksum
       
   511 		User::LeaveIfError( converter.Val( number, EHex ) );
       
   512 
       
   513 		aDes.Append( number );
       
   514 		}
       
   515 	}
       
   516