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