os/security/crypto/weakcryptospi/test/tpbe/texternpbeparams.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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 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  */