crypto/weakcrypto/test/tpbe/texternpbeparams.cpp
changeset 71 dd83586b62d6
equal deleted inserted replaced
66:8873e6835f7b 71:dd83586b62d6
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "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 <s32mem.h>
       
    20 #include <s32file.h>
       
    21 #include "texternpbeparams.h"
       
    22 
       
    23 
       
    24 CTestAction* CExternPbeParams::NewL(
       
    25 	RFs& aFs, CConsoleBase& aConsole,
       
    26 	Output& aOut, const TTestActionSpec& aTestActionSpec)
       
    27 /**
       
    28 	Factory function allocates new instance of CExternPbeParams and extracts
       
    29 	the element body from the supplied test action spec.
       
    30 
       
    31 	@param	aFs				Used to parse XML script file.
       
    32 	@param	aConsole		Required by CTestAction.
       
    33 	@param	aOut			Required by CTestAction.
       
    34 	@param	aTestActionSpec	Action specification contains type, name, and
       
    35 							XML contents.
       
    36 	@return					New instance of CExternPbeParams, which is owned
       
    37 							by the caller.
       
    38  */
       
    39 	{
       
    40 	CExternPbeParams* self = new(ELeave) CExternPbeParams(aConsole, aOut, aFs);
       
    41 	CleanupStack::PushL(self);
       
    42 	self->ConstructL(aTestActionSpec);
       
    43 	CleanupStack::Pop(self);
       
    44 	return self;
       
    45 	}
       
    46 
       
    47 CExternPbeParams::CExternPbeParams(CConsoleBase& aConsole, Output& aOut, RFs& aFs)
       
    48 /**
       
    49 	This constructor exists to record the file server session and to initialize
       
    50 	the CTestAction superclass.
       
    51 	
       
    52 	@param	aConsole		Required by CTestAction.
       
    53 	@param	aOut			Required by CTestAction.
       
    54 	@param	aFs				Used to read from and write to files in PerformAction,
       
    55 							which stores and restores the externalized params.
       
    56  */
       
    57 :	CTestAction(aConsole, aOut),
       
    58 	iFs(aFs)
       
    59 	{
       
    60 	// empty.
       
    61 	}
       
    62 
       
    63 void CExternPbeParams::ConstructL(const TTestActionSpec& aTestActionSpec)
       
    64 /**
       
    65 	Second phase initialization initializes the superclass and
       
    66 	makes a copy of the test element.
       
    67 	
       
    68 	@param	aTestActionSpec	Action specification contains type, name, and
       
    69 							XML contents.	
       
    70  */
       
    71 	{
       
    72 	CTestAction::ConstructL(aTestActionSpec);
       
    73 	iBody = aTestActionSpec.iActionBody.AllocL();
       
    74 	
       
    75 	// iBody is deconstructed in DoPerformPrerequisite
       
    76 	}
       
    77 
       
    78 CExternPbeParams::~CExternPbeParams()
       
    79 /**
       
    80 	Free resources allocated in ConstructL.  Specifically,
       
    81 	deletes the copy of the element body text.
       
    82  */
       
    83 	{
       
    84 	delete iBody;
       
    85 	}
       
    86 
       
    87 // -------- implement CTestAction --------
       
    88 
       
    89 void CExternPbeParams::DoPerformPrerequisite(TRequestStatus& aStatus)
       
    90 /**
       
    91 	Override CTestAction by deconstructing element body allocated
       
    92 	in ConstructL.
       
    93 	
       
    94 	If this function fails then DoPerformPostrequisite must still
       
    95 	be called.
       
    96 	
       
    97 	@param	aStatus			This status is completed when the prerequisite
       
    98 							has finished.  (This implementation is actually
       
    99 							synchronous so the request will already be completed
       
   100 							when it returns.)
       
   101  */
       
   102 	{
       
   103 	TRAPD(r, DoPerformPrerequisiteL());
       
   104 	
       
   105 	iActionState = CTestAction::EAction;
       
   106 	TRequestStatus* ps = &aStatus;
       
   107 	User::RequestComplete(ps, r);
       
   108 	}
       
   109 
       
   110 void CExternPbeParams::DoPerformPrerequisiteL()
       
   111 /**
       
   112 	Helper function for DoPerformPrerequisite contains resource allocation
       
   113 	functions which can leave.
       
   114 	
       
   115 	Extracts cipher, salt, iv, iter count, and kdf values.
       
   116  */
       
   117 	{
       
   118 	_LIT8(KOrigFileName, "orig-filename");
       
   119 	iOrigFileName = ReadStringLC(*iBody, KOrigFileName);
       
   120 	CleanupStack::Pop(iOrigFileName);
       
   121 	
       
   122 	_LIT8(KExpCipherElemName, "expected-cipher");
       
   123 	iExpCipher = ReadDecStringL(*iBody, KExpCipherElemName);
       
   124 	_LIT8(KExpSaltElemName, "expected-salt");
       
   125 	iExpSalt = ReadHexStringL(*iBody, KExpSaltElemName);
       
   126 	_LIT8(KExpIvElemName, "expected-iv");
       
   127 	iExpIv = ReadHexStringL(*iBody, KExpIvElemName);	
       
   128 	_LIT8(KExpIterCountElemName, "expected-iter-count");
       
   129 	iExpIterCount = ReadDecStringL(*iBody, KExpIterCountElemName);
       
   130 	_LIT8(KExpKdfElemName, "expected-kdf");
       
   131 	iExpKdf = ReadDecStringL(*iBody, KExpKdfElemName);
       
   132 	}
       
   133 
       
   134 void CExternPbeParams::DoPerformPostrequisite(TRequestStatus& aStatus)
       
   135 /**
       
   136 	Implements CTestAction by cleaning up data allocated in DoPerformPrerequisiteL.
       
   137 	
       
   138 	@param	aStatus			This status is completed to indicate the
       
   139 							postrequisite has finished.  (This function
       
   140 							is synchronous so the status is completed before
       
   141 							this function returns.)
       
   142  */
       
   143 	{
       
   144 	delete iExpIv;
       
   145 	iExpIv = 0;
       
   146 	delete iExpSalt;
       
   147 	iExpSalt = 0;
       
   148 	delete iOrigFileName;
       
   149 	iOrigFileName = NULL;
       
   150 	
       
   151 	iFinished = ETrue;
       
   152 	TRequestStatus* ps = &aStatus;
       
   153 	User::RequestComplete(ps, KErrNone);
       
   154 	}
       
   155 
       
   156 void CExternPbeParams::PerformAction(TRequestStatus& aStatus)
       
   157 /**
       
   158 	Implements CTestAction by running the actual tests.  This
       
   159 	consists of:
       
   160 	
       
   161 	Reading an externalized CPBEncryptParms object and testing the
       
   162 	cipher, salt, iv, iteration count, and KDF are as expected.
       
   163 	
       
   164 	Externalizing the object to memory.
       
   165 	
       
   166 	Testing the two externalizations are binary identical.
       
   167 	
       
   168 	Creating an equivalent object from scratch and externalizing it.
       
   169 	
       
   170 	Testing the externalizations are binary identical.
       
   171 	
       
   172 	As well as testing the objects can be stored reliably, this
       
   173 	test also ensures that old (pre-PKCS#12) files can still be
       
   174 	read and, and that objects are stored in the old format if they
       
   175 	do not use any PKCS#12-specific features.  (I.e., they use the
       
   176 	default PKCS#5 KDF.)
       
   177 	
       
   178 	@param	aStatus			This request status is completed when
       
   179 							the action has finished, successfully
       
   180 							or otherwise.  This implementation is
       
   181 							synchronous, and so the status is actually
       
   182 							completed before this function returns.
       
   183  */
       
   184 	{
       
   185 	TFileName fn;
       
   186 	fn.Copy(*iOrigFileName);	// convert from narrow
       
   187 
       
   188 	// ensure reference file matches re-externalized form
       
   189 	
       
   190 	TRAPD(r,
       
   191 		TestDecodeMatchesScriptL(fn);
       
   192 		TestReExternMatchesL(fn);
       
   193 		TestScratchExternL(fn) );
       
   194 		
       
   195 	iResult = (r == KErrNone);
       
   196 	iActionState = CTestAction::EPostrequisite;
       
   197 	TRequestStatus* status = &aStatus;
       
   198 	User::RequestComplete(status, KErrNone);
       
   199 	}
       
   200 
       
   201 CPBEncryptParms* CExternPbeParams::InternalizeEncryptionParamsLC(const TDesC& aFileName)
       
   202 /**
       
   203 	Construct a CPBEncryptParms object from the externalized
       
   204 	form in the named file.
       
   205 	
       
   206 	@param	aFileName		File which contains externalized form.
       
   207 	@return					Internalized encryption parameters object
       
   208 							which is placed on the cleanup stack.
       
   209  */
       
   210 	{
       
   211 	RFileReadStream frs;
       
   212 	TInt r = frs.Open(iFs, aFileName, EFileStream | EFileRead);
       
   213 	User::LeaveIfError(r);
       
   214 	CleanupClosePushL(frs);	
       
   215 	CPBEncryptParms* pbep = CPBEncryptParms::NewL(frs);
       
   216 	CleanupStack::PopAndDestroy(&frs);
       
   217 	CleanupStack::PushL(pbep);
       
   218 	return pbep;
       
   219 	}
       
   220 
       
   221 void CExternPbeParams::TestDecodeMatchesScriptL(const TDesC& aFileName)
       
   222 /**
       
   223 	Test whether the encryption parameters which were externalized
       
   224 	to the supplied file match those specified in the script file.
       
   225 	
       
   226 	@param	aFileName		Name of file which contains externalized form.
       
   227 	@leave KErrGeneral		The internalized form doesn't match the parameters
       
   228 							in the script.
       
   229  */
       
   230 	{
       
   231 	CPBEncryptParms* pbep = InternalizeEncryptionParamsLC(aFileName);
       
   232 	
       
   233 	TBool match =
       
   234 			pbep->Cipher() == iExpCipher
       
   235 		&&	pbep->Salt() == *iExpSalt
       
   236 		&&	pbep->Iterations() == iExpIterCount;
       
   237 	
       
   238 	match = match && pbep->Kdf() == iExpKdf;
       
   239 
       
   240 	if (! match)
       
   241 		User::Leave(KErrGeneral);
       
   242 	
       
   243 	CleanupStack::PopAndDestroy(pbep);	
       
   244 	}
       
   245 
       
   246 void CExternPbeParams::CompareAgainstTestFileL(
       
   247 	const TDesC& aFileName, const CPBEncryptParms& aParams)
       
   248 /**
       
   249 	Externalize the supplied parameters object and ensure it matches the
       
   250 	test file.
       
   251 	
       
   252 	@param	aFileName		File which contains externalized parameters.
       
   253 	@param	aParams			Test object to externalize.
       
   254 	@leave KErrGeneral The externalized forms do not match.
       
   255  */
       
   256 	{
       
   257  	// open a file stream on the externalized form
       
   258 	RFileReadStream frs;
       
   259 	TInt r = frs.Open(iFs, aFileName, EFileStream | EFileRead);
       
   260 	User::LeaveIfError(r);
       
   261 	CleanupClosePushL(frs);
       
   262 	
       
   263 	// externalize the object to memory
       
   264 	const TInt KMaxBufferLen = 128;
       
   265 	HBufC8* reExtBuf = HBufC8::NewLC(KMaxBufferLen);
       
   266 	TPtr8 reDes = reExtBuf->Des();
       
   267 	RDesWriteStream dws(reDes);
       
   268 	CleanupClosePushL(dws);
       
   269 	aParams.ExternalizeL(dws);
       
   270 	dws.CommitL();
       
   271 	
       
   272 	// ensure the externalized forms are equal
       
   273 	RDesReadStream drs(reDes);
       
   274 	TInt fLen = frs.Source()->SizeL();
       
   275 	TInt mLen = drs.Source()->SizeL();
       
   276 	if (fLen != mLen)
       
   277 		User::Leave(KErrGeneral);	
       
   278 
       
   279 	TBuf8<1> fByte;
       
   280 	TBuf8<1> mByte;
       
   281 	for (TInt i = 0; i < fLen; ++i)
       
   282 		{
       
   283 		frs.ReadL(fByte, 1);
       
   284 		drs.ReadL(mByte, 1);
       
   285 		if (fByte != mByte)
       
   286 			User::Leave(KErrGeneral);
       
   287 		}
       
   288 
       
   289 	CleanupStack::PopAndDestroy(3, &frs);	// frs, reExtBuf, dws	
       
   290 	}
       
   291 
       
   292 void CExternPbeParams::TestReExternMatchesL(const TDesC& aFileName)
       
   293 /**
       
   294 	Read the CPBEncryptParms object which is externalized in
       
   295 	the named file, re-externalize it, and check the two
       
   296 	representations are binary equivalent.
       
   297 	
       
   298 	@param	aFileName		Name of file which contains externalized form.
       
   299 	@leave	KErrGeneral		The externalized forms are different.
       
   300  */
       
   301 	{
       
   302  	CPBEncryptParms* pbep = InternalizeEncryptionParamsLC(aFileName);
       
   303  	
       
   304  	CompareAgainstTestFileL(aFileName, *pbep);
       
   305  	
       
   306 	CleanupStack::PopAndDestroy(pbep);
       
   307 	}
       
   308 
       
   309 void CExternPbeParams::TestScratchExternL(const TDesC& aFileName)
       
   310 /**
       
   311 	Construct a CPBEncryptParams object from the parameter values
       
   312 	in the script file.  Test it matches the test file.
       
   313 	
       
   314 	@param	aFileName		Test file which contains externalized parameters.
       
   315  */
       
   316 	{
       
   317 	CPBEncryptParms* pbep = CPBEncryptParms::NewLC(
       
   318 		static_cast<TPBECipher>(iExpCipher),
       
   319 		*iExpSalt,
       
   320 		*iExpIv,
       
   321 		iExpIterCount);
       
   322 	
       
   323 	pbep->SetKdf(static_cast<CPBEncryptParms::TKdf>(iExpKdf));
       
   324 
       
   325 	CompareAgainstTestFileL(aFileName, *pbep);
       
   326 
       
   327 	CleanupStack::PopAndDestroy(pbep);
       
   328 	}
       
   329 
       
   330 void CExternPbeParams::DoReportAction(void)
       
   331 /**
       
   332 	Implements CTestAction but is empty.
       
   333  */
       
   334 	{
       
   335 	// empty.
       
   336 	}
       
   337 
       
   338 void CExternPbeParams::DoCheckResult(TInt /*aError*/)
       
   339 /**
       
   340 	Implements CTestAction but is empty.
       
   341  */
       
   342 	{
       
   343 	// empty.
       
   344 	}
       
   345 
       
   346 
       
   347 // -------- support functions --------
       
   348 
       
   349 
       
   350 HBufC8* CExternPbeParams::ReadHexStringL(const TDesC8& aBody, const TDesC8& aTag)
       
   351 /**
       
   352 	Convert a string in the test script to an 8-bit buffer.  The string
       
   353 	is a sequence of hex digits, e.g. "abcdef01", which is converted to a
       
   354 	descriptor containing the matching bytes {0xab, 0xcd, 0xef, 0x01}.
       
   355 	
       
   356 	@param	aBody			Body of parent element.
       
   357 	@param	aTag			Bare tag name.  This function extracts the text
       
   358 							between "<aTag>" and "</aTag>".
       
   359 	@return					Newly-allocated buffer containing matching bytes.
       
   360 							This is owned by the caller.
       
   361  */
       
   362 	{
       
   363  	HBufC8* scriptString = ReadStringLC(aBody, aTag);
       
   364 
       
   365 	TInt textLen = scriptString->Length();
       
   366 	if ((textLen % 2) != 0)
       
   367 		User::Leave(KErrCorrupt);
       
   368 	TInt byteCount = textLen / 2;
       
   369 	HBufC8* procString = HBufC8::NewMaxLC(byteCount);
       
   370 	TPtr8 procDes = procString->Des();
       
   371 	for (TInt i = 0; i < byteCount; ++i)
       
   372 		{
       
   373 		TUint8 byteVal;
       
   374 		TInt r = TLex8(scriptString->Mid(i * 2, 2)).Val(byteVal, EHex);
       
   375 		User::LeaveIfError(r);
       
   376 		procDes[i] = byteVal;
       
   377 		}
       
   378 	
       
   379 	CleanupStack::Pop(procString);
       
   380 	CleanupStack::PopAndDestroy(scriptString);
       
   381 	return procString;
       
   382 	}
       
   383 
       
   384 TInt CExternPbeParams::ReadDecStringL(const TDesC8& aBody, const TDesC8& aTag)
       
   385 /**
       
   386 	Finds a decimal text string in the script and returns the
       
   387 	integer value which it represents.
       
   388 	
       
   389 	@param	aBody			Body of parent element.
       
   390 	@param	aTag			Bare tag name.  This function extracts the text
       
   391 							between "<aTag>" and "</aTag>".
       
   392 	@return					Integer value encoded in the script file.
       
   393  */
       
   394  	{
       
   395  	HBufC8* scriptString = ReadStringLC(aBody, aTag);
       
   396  	
       
   397  	TInt value;
       
   398 	User::LeaveIfError(TLex8(*scriptString).Val(value));
       
   399 	CleanupStack::PopAndDestroy(scriptString);
       
   400 	return value;
       
   401 	}
       
   402 
       
   403 HBufC8* CExternPbeParams::ReadStringLC(const TDesC8& aBody, const TDesC8& aTag)
       
   404 /**
       
   405 	Extracts a string from the supplied script file.
       
   406 	
       
   407 	@param	aBody			Body of parent element.
       
   408 	@param	aTag			Bare tag name.  This function extracts the text
       
   409 							between "<aTag>" and "</aTag>".
       
   410 	@return					A copy of the string allocated on the heap.  The
       
   411 							string is placed on the cleanup stack.
       
   412  */
       
   413 	{
       
   414 	TBuf8<32> startTag;
       
   415 	startTag.Format(_L8("<%S>"), &aTag);
       
   416 	TBuf8<32> endTag;
       
   417 	endTag.Format(_L8("</%S>"), &aTag);
       
   418 	
       
   419 	TInt pos = 0;
       
   420 	TInt r;
       
   421 	const TPtrC8 contents = Input::ParseElement(
       
   422 		aBody, startTag, endTag, pos, r);
       
   423 	User::LeaveIfError(r);
       
   424 	
       
   425 	return contents.AllocLC();
       
   426 	}
       
   427 
       
   428 /**
       
   429 	This code was originally in PerformAction to create the initial
       
   430 	data files.
       
   431 	
       
   432 	// GENERATE PKCS5 TEST PARAMS FILE
       
   433 	RFileWriteStream fws;
       
   434 	r = fws.Replace(iFs, _L("c:\\tpbe\\pkcs5-orig.dat"), EFileStream | EFileWrite);
       
   435 	User::LeaveIfError(r);
       
   436 	CleanupClosePushL(fws);
       
   437 	
       
   438 	_LIT8(KSalt, "SALT4567");
       
   439 	_LIT8(KIv, "IV23456789abcdef");
       
   440 	const TInt KIterCount = 1234;
       
   441 	CPBEncryptParms* pbep = CPBEncryptParms::NewLC(
       
   442 		ECipherAES_CBC_256, KSalt, KIv, KIterCount);
       
   443 	pbep->ExternalizeL(fws);
       
   444 	fws.CommitL();
       
   445 	CleanupStack::PopAndDestroy(2, &fws);
       
   446 
       
   447 #ifdef SYMBIAN_PKCS12
       
   448 	// GENERATE PKCS12 TEST PARAMS FILE
       
   449 	RFileWriteStream fws;
       
   450 	r = fws.Replace(iFs, _L("c:\\tpbe\\pkcs12-first.dat"), EFileStream | EFileWrite);
       
   451 	User::LeaveIfError(r);
       
   452 	CleanupClosePushL(fws);
       
   453 	
       
   454 	_LIT8(KSalt, "SALT4567");
       
   455 	_LIT8(KIv, "IV23456789abcdef");
       
   456 	const TInt KIterCount = 1234;
       
   457 	CPBEncryptParms* pbep = CPBEncryptParms::NewLC(
       
   458 		ECipherAES_CBC_256, KSalt, KIv, KIterCount);
       
   459 	pbep->SetKdf(CPBEncryptParms::EKdfPkcs12);
       
   460 	pbep->ExternalizeL(fws);
       
   461 	fws.CommitL();
       
   462 	CleanupStack::PopAndDestroy(2, &fws);
       
   463 #endif	// #ifdef SYMBIAN_PKCS12
       
   464 
       
   465  */