os/security/cryptoservices/certificateandkeymgmt/tx509/extensiontest.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2005-2010 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 "x509constraintext.h"
sl@0
    20
#include "extensiontest.h"
sl@0
    21
#include "t_input.h"
sl@0
    22
sl@0
    23
_LIT(KFileNameStart, "<filename>");
sl@0
    24
_LIT(KExpectedDeviceIdList, "<device_id_list>");
sl@0
    25
_LIT(KExpectedDevice, "<device_id>");
sl@0
    26
_LIT(KExpectedSidList, "<sid_list>");
sl@0
    27
_LIT(KExpectedSid, "<sid>");
sl@0
    28
_LIT(KExpectedVidList, "<vid_list>");
sl@0
    29
_LIT(KExpectedVid, "<vid>");
sl@0
    30
_LIT(KExpectedCapabilities, "<capabilities>");
sl@0
    31
_LIT(KCorrupt, "<corrupt>");
sl@0
    32
_LIT(KMatch, "<match>");
sl@0
    33
sl@0
    34
CTestAction* CExtensionTest::NewL(RFs& aFs, CConsoleBase& aConsole, 
sl@0
    35
	Output& aOut, const TTestActionSpec& aTestActionSpec)
sl@0
    36
	{
sl@0
    37
	CTestAction* self = CExtensionTest::NewLC(aFs, aConsole, aOut, aTestActionSpec);
sl@0
    38
	CleanupStack::Pop(self);
sl@0
    39
	return self;
sl@0
    40
	}
sl@0
    41
sl@0
    42
CTestAction* CExtensionTest::NewLC(RFs& aFs, CConsoleBase& aConsole, 
sl@0
    43
	Output& aOut, const TTestActionSpec& aTestActionSpec)
sl@0
    44
	{
sl@0
    45
	CExtensionTest* self = new(ELeave) CExtensionTest(aFs, aConsole, aOut);
sl@0
    46
	CleanupStack::PushL(self);
sl@0
    47
	self->ConstructL(aTestActionSpec);
sl@0
    48
	return self;
sl@0
    49
	}
sl@0
    50
sl@0
    51
CExtensionTest::CExtensionTest(RFs& aFs, CConsoleBase& aConsole, Output& aOut)
sl@0
    52
	: CTestAction(aConsole, aOut), 
sl@0
    53
	iFs(aFs)
sl@0
    54
	{
sl@0
    55
	}
sl@0
    56
sl@0
    57
CExtensionTest::~CExtensionTest()
sl@0
    58
	{	
sl@0
    59
	iExpectedDeviceIdList.ResetAndDestroy();
sl@0
    60
	iExpectedDeviceIdList.Close();		
sl@0
    61
	iExpectedSidList.Close();
sl@0
    62
	iExpectedVidList.Close();
sl@0
    63
	}	
sl@0
    64
sl@0
    65
void CExtensionTest::ConstructL(const TTestActionSpec& aTestActionSpec)
sl@0
    66
	{
sl@0
    67
	CTestAction::ConstructL(aTestActionSpec);
sl@0
    68
	TInt startPos = 0;
sl@0
    69
	TInt err = 0;
sl@0
    70
	
sl@0
    71
	HBufC* aBody = HBufC::NewLC(aTestActionSpec.iActionBody.Length());	
sl@0
    72
	aBody->Des().Copy(aTestActionSpec.iActionBody);
sl@0
    73
	
sl@0
    74
	// Filename of the certificate file
sl@0
    75
	TPtrC fileNameStart = Input::ParseElement(*aBody, KFileNameStart);
sl@0
    76
	iCertFileName.Copy(fileNameStart);
sl@0
    77
sl@0
    78
	// Whether we expect at least on of the extensions to be corrupt
sl@0
    79
	TPtrC corruptStart = Input::ParseElement(*aBody, KCorrupt);	
sl@0
    80
	if (corruptStart.CompareF(_L("True")) == 0)
sl@0
    81
		{
sl@0
    82
		iExpectedCorrupt = ETrue;
sl@0
    83
		}				
sl@0
    84
		
sl@0
    85
	// We expect the certificate to match the constraints
sl@0
    86
	TPtrC matchStart = Input::ParseElement(*aBody, KMatch);	
sl@0
    87
	if (matchStart.CompareF(_L("True")) == 0)
sl@0
    88
		{
sl@0
    89
		iExpectedMatch = ETrue;
sl@0
    90
		}						
sl@0
    91
sl@0
    92
	// Extract the lists of constraints that are expected to be present 		
sl@0
    93
	startPos = 0;
sl@0
    94
	TPtrC deviceListStart = Input::ParseElement(*aBody, KExpectedDeviceIdList, startPos, err);
sl@0
    95
	if (err >= 0)
sl@0
    96
		{
sl@0
    97
		BuildStringListL(iExpectedDeviceIdList, deviceListStart, KExpectedDevice);
sl@0
    98
		iDeviceIdsPresent = ETrue;		
sl@0
    99
		}
sl@0
   100
sl@0
   101
	startPos = 0;
sl@0
   102
	TPtrC sidListStart = Input::ParseElement(*aBody, KExpectedSidList, startPos, err);
sl@0
   103
	if (err >= 0)
sl@0
   104
		{
sl@0
   105
		BuildIntList(iExpectedSidList, sidListStart, KExpectedSid);
sl@0
   106
		iSidsPresent = ETrue;
sl@0
   107
		}	
sl@0
   108
sl@0
   109
	startPos = 0;
sl@0
   110
	TPtrC vidListStart = Input::ParseElement(*aBody, KExpectedVidList, startPos, err);
sl@0
   111
	if (err >= 0)
sl@0
   112
		{
sl@0
   113
		BuildIntList(iExpectedVidList, vidListStart, KExpectedVid);
sl@0
   114
		iVidsPresent = ETrue;
sl@0
   115
		}	
sl@0
   116
		
sl@0
   117
	startPos = 0;
sl@0
   118
	TPtrC capabilities = Input::ParseElement(*aBody, KExpectedCapabilities, startPos, err);
sl@0
   119
	if (err >= 0)
sl@0
   120
		{
sl@0
   121
		BuildCapabilitySet(iExpectedCapabilities, capabilities);
sl@0
   122
		iCapabilitiesPresent = ETrue;
sl@0
   123
		}	
sl@0
   124
	
sl@0
   125
	CleanupStack::PopAndDestroy(aBody);
sl@0
   126
	}	
sl@0
   127
sl@0
   128
void CExtensionTest::BuildStringListL(RPointerArray<HBufC>& aStrings, const TDesC& aBuf, const TDesC& aTag)
sl@0
   129
	{
sl@0
   130
	TInt pos = 0;
sl@0
   131
	TInt err = 0;	
sl@0
   132
	do
sl@0
   133
		{			
sl@0
   134
		// Find next value for the specified tag and add it to the string array
sl@0
   135
		// if it exists.
sl@0
   136
		TPtrC str = Input::ParseElement(aBuf, aTag, pos, err);
sl@0
   137
		if (err >= 0)
sl@0
   138
			{
sl@0
   139
			HBufC* string = str.AllocLC();			
sl@0
   140
			aStrings.AppendL(string);
sl@0
   141
			CleanupStack::Pop(string);
sl@0
   142
			}								
sl@0
   143
		}
sl@0
   144
	while (err >= 0);	
sl@0
   145
	}
sl@0
   146
sl@0
   147
void CExtensionTest::BuildIntList(RArray<TInt>& aInts, const TDesC& aBuf, const TDesC& aTag)
sl@0
   148
	{	
sl@0
   149
	TInt pos = 0;
sl@0
   150
	TInt err = 0;	
sl@0
   151
	do
sl@0
   152
		{			
sl@0
   153
		// Attempt to convert the contents of val to an int and store in  
sl@0
   154
		// the aInts array if it is a valid integer.
sl@0
   155
		TInt n = Input::ParseIntElement(aBuf, aTag, pos, err);
sl@0
   156
		if (err >= 0)
sl@0
   157
			{
sl@0
   158
			// This append should not fail as the parsing went fine. 
sl@0
   159
			// So, ignoring the leave just to satisfy non leaving method convention.
sl@0
   160
			TRAP_IGNORE(aInts.AppendL(n));
sl@0
   161
			}								
sl@0
   162
		}
sl@0
   163
	while (err >= 0);
sl@0
   164
	}
sl@0
   165
sl@0
   166
void CExtensionTest::BuildCapabilitySet(TCapabilitySet& aCapabilitySet, const TDesC& aBuf)	
sl@0
   167
	{
sl@0
   168
	aCapabilitySet.SetEmpty();
sl@0
   169
	TUint length = aBuf.Length();
sl@0
   170
	for (TUint i = 0; i < length && i < ECapability_Limit; i++) 
sl@0
   171
		{
sl@0
   172
		if (aBuf[i] == '1')
sl@0
   173
			{
sl@0
   174
			aCapabilitySet.AddCapability(static_cast<TCapability>(i));
sl@0
   175
			}			
sl@0
   176
		}
sl@0
   177
	}
sl@0
   178
			
sl@0
   179
void CExtensionTest::PerformAction(TRequestStatus& aStatus)
sl@0
   180
	{
sl@0
   181
	HBufC8* buf = NULL;
sl@0
   182
	TInt err = KErrNone;
sl@0
   183
	
sl@0
   184
	TRAP(err, buf = Input::ReadFileL(iCertFileName, iFs));
sl@0
   185
	if (err == KErrNotFound)
sl@0
   186
		{
sl@0
   187
		iResult = EFalse;
sl@0
   188
		iFinished = ETrue;
sl@0
   189
		SetScriptError(EFileNotFound, iCertFileName);
sl@0
   190
		TRequestStatus* status = &aStatus;
sl@0
   191
		iActionState = EPostrequisite;
sl@0
   192
		User::RequestComplete(status, KErrNone);
sl@0
   193
		return;
sl@0
   194
		}
sl@0
   195
	else if (err != KErrNone)
sl@0
   196
		{
sl@0
   197
		User::Leave(err);
sl@0
   198
		}
sl@0
   199
		
sl@0
   200
	CleanupStack::PushL(buf);
sl@0
   201
	CX509Certificate* cert = CX509Certificate::NewLC(buf->Des());
sl@0
   202
sl@0
   203
	Print(_L("Checking certificate extensions in file "));
sl@0
   204
	PrintLine(iCertFileName);
sl@0
   205
	
sl@0
   206
	TBool match = EFalse;
sl@0
   207
	TBool corrupt = EFalse;
sl@0
   208
	CheckExtensionsL(*cert, match, corrupt);
sl@0
   209
	if (corrupt)
sl@0
   210
		{
sl@0
   211
		iResult = iExpectedCorrupt;
sl@0
   212
		if (!iResult)
sl@0
   213
			{
sl@0
   214
			Print(_L("Found unexpected corrupt extension."));
sl@0
   215
			}
sl@0
   216
		}
sl@0
   217
	else 
sl@0
   218
		{
sl@0
   219
		// no error. test whether the certificate matched the
sl@0
   220
		// test script.
sl@0
   221
		iResult = (match == iExpectedMatch);
sl@0
   222
		}
sl@0
   223
	CleanupStack::PopAndDestroy(2, buf); // cert, buf	
sl@0
   224
sl@0
   225
	TRequestStatus* status = &aStatus;
sl@0
   226
	iActionState = EPostrequisite;
sl@0
   227
	User::RequestComplete(status, KErrNone);
sl@0
   228
	}	
sl@0
   229
	
sl@0
   230
void CExtensionTest::CheckExtensionsL(const CX509Certificate& cert, 
sl@0
   231
	TBool& match, TBool& corrupt)
sl@0
   232
	{
sl@0
   233
	TInt err = KErrNone;
sl@0
   234
	
sl@0
   235
	match = ETrue;
sl@0
   236
	corrupt = EFalse;
sl@0
   237
sl@0
   238
	TRAP(err, match &= CheckDeviceIdListL(cert));
sl@0
   239
	if (err == KErrArgument)
sl@0
   240
		{		
sl@0
   241
		PrintLine(_L("The device id constraint is corrupt."));
sl@0
   242
		corrupt = ETrue;
sl@0
   243
		}
sl@0
   244
	else if (err != KErrNone) 
sl@0
   245
		{
sl@0
   246
		User::Leave(err);
sl@0
   247
		}	
sl@0
   248
				
sl@0
   249
	TRAP(err, match &= CheckSidListL(cert));
sl@0
   250
	if (err == KErrArgument)
sl@0
   251
		{		
sl@0
   252
		PrintLine(_L("The secure id constraint is corrupt."));
sl@0
   253
		corrupt = ETrue;
sl@0
   254
		}
sl@0
   255
	else if (err != KErrNone) 
sl@0
   256
		{
sl@0
   257
		User::Leave(err);
sl@0
   258
		}
sl@0
   259
		
sl@0
   260
	TRAP(err, match &= CheckVidListL(cert));
sl@0
   261
	if (err == KErrArgument)
sl@0
   262
		{		
sl@0
   263
		PrintLine(_L("The vendor id constraint is corrupt."));
sl@0
   264
		corrupt = ETrue;
sl@0
   265
		}
sl@0
   266
	else if (err != KErrNone) 
sl@0
   267
		{
sl@0
   268
		User::Leave(err);
sl@0
   269
		}		
sl@0
   270
		
sl@0
   271
	TRAP(err, match &= CheckCapabilitiesL(cert));
sl@0
   272
	if (err == KErrArgument)
sl@0
   273
		{		
sl@0
   274
		PrintLine(_L("The capabilities constraint is corrupt."));
sl@0
   275
		corrupt = ETrue;
sl@0
   276
		}
sl@0
   277
	else if (err != KErrNone) 
sl@0
   278
		{
sl@0
   279
		User::Leave(err);
sl@0
   280
		}				
sl@0
   281
	}
sl@0
   282
	
sl@0
   283
TBool CExtensionTest::CheckDeviceIdListL(const CX509Certificate& cert) 
sl@0
   284
	{
sl@0
   285
	TBool match = ETrue;
sl@0
   286
	const CX509CertExtension* ext = cert.Extension(KDeviceIdListConstraint);	
sl@0
   287
	if (ext)
sl@0
   288
		{
sl@0
   289
		// use NewL because this covers NewLC as well
sl@0
   290
		CX509Utf8StringListExt* stringListExt = CX509Utf8StringListExt::NewL(ext->Data());	
sl@0
   291
		CleanupStack::PushL(stringListExt);
sl@0
   292
		if (! IsEqual(stringListExt->StringArray(), iExpectedDeviceIdList))
sl@0
   293
			{
sl@0
   294
			PrintLine(_L("Device Id list is different."));
sl@0
   295
			match = EFalse;
sl@0
   296
			}
sl@0
   297
		CleanupStack::PopAndDestroy(stringListExt);		
sl@0
   298
		}	
sl@0
   299
	else if (iDeviceIdsPresent) 
sl@0
   300
		{
sl@0
   301
		PrintLine(_L("Device Id constraint is missing."));
sl@0
   302
		match = EFalse;
sl@0
   303
		}	
sl@0
   304
	return match;
sl@0
   305
	}
sl@0
   306
	
sl@0
   307
TBool CExtensionTest::CheckSidListL(const CX509Certificate& cert) 
sl@0
   308
	{
sl@0
   309
	const CX509CertExtension* ext = cert.Extension(KSidListConstraint);
sl@0
   310
	TBool match = ETrue;
sl@0
   311
	if (ext)
sl@0
   312
		{				
sl@0
   313
		// use NewL because this covers NewLC as well
sl@0
   314
		CX509IntListExt* intListExt = CX509IntListExt::NewL(ext->Data());
sl@0
   315
		CleanupStack::PushL(intListExt);
sl@0
   316
		if (! IsEqual(intListExt->IntArray(), iExpectedSidList))
sl@0
   317
			{
sl@0
   318
			PrintLine(_L("SID list is different"));
sl@0
   319
			match = EFalse;
sl@0
   320
			}
sl@0
   321
		CleanupStack::PopAndDestroy(intListExt);		
sl@0
   322
		}	
sl@0
   323
	else if (iSidsPresent) 
sl@0
   324
		{
sl@0
   325
			PrintLine(_L("SID constraint is missing."));
sl@0
   326
			match = EFalse;
sl@0
   327
		}
sl@0
   328
	return match;	
sl@0
   329
	}
sl@0
   330
	
sl@0
   331
TBool CExtensionTest::CheckVidListL(const CX509Certificate& cert) 
sl@0
   332
	{
sl@0
   333
	const CX509CertExtension* ext = cert.Extension(KVidListConstraint);
sl@0
   334
	TBool match = ETrue;
sl@0
   335
	if (ext)
sl@0
   336
		{
sl@0
   337
		// use NewL because this covers NewLC as well
sl@0
   338
		CX509IntListExt* intListExt = CX509IntListExt::NewL(ext->Data());
sl@0
   339
		CleanupStack::PushL(intListExt);
sl@0
   340
								
sl@0
   341
		if (! IsEqual(intListExt->IntArray(), iExpectedVidList))
sl@0
   342
			{
sl@0
   343
			PrintLine(_L("VID list is different"));
sl@0
   344
			match = EFalse;
sl@0
   345
			}
sl@0
   346
		CleanupStack::PopAndDestroy(intListExt);		
sl@0
   347
		}	
sl@0
   348
	else if (iVidsPresent) 
sl@0
   349
		{
sl@0
   350
		PrintLine(_L("VID constraint is missing."));
sl@0
   351
		match = EFalse;
sl@0
   352
		}	
sl@0
   353
	return match;
sl@0
   354
	}	
sl@0
   355
	
sl@0
   356
TBool CExtensionTest::CheckCapabilitiesL(const CX509Certificate& cert) 
sl@0
   357
	{
sl@0
   358
	const CX509CertExtension* ext = cert.Extension(KCapabilitiesConstraint);
sl@0
   359
	TBool match = ETrue;
sl@0
   360
	if (ext)
sl@0
   361
		{		
sl@0
   362
		// use NewL because this covers NewLC as well
sl@0
   363
		CX509CapabilitySetExt* capabilitySetExt = CX509CapabilitySetExt::NewL(ext->Data());		
sl@0
   364
		CleanupStack::PushL(capabilitySetExt);
sl@0
   365
		
sl@0
   366
		const TCapabilitySet& capabilitySet = capabilitySetExt->CapabilitySet();		
sl@0
   367
sl@0
   368
		if (! (capabilitySet.HasCapabilities(iExpectedCapabilities)
sl@0
   369
			&& iExpectedCapabilities.HasCapabilities(capabilitySet)))
sl@0
   370
			{
sl@0
   371
			PrintLine(_L("Capability constraints are different."));
sl@0
   372
			match = EFalse;
sl@0
   373
			}
sl@0
   374
		CleanupStack::PopAndDestroy(capabilitySetExt);		
sl@0
   375
		}	
sl@0
   376
	else if (iCapabilitiesPresent) 
sl@0
   377
		{
sl@0
   378
		PrintLine(_L("Capability constraint is missing."));
sl@0
   379
		match = EFalse;
sl@0
   380
		}	
sl@0
   381
	return match;		
sl@0
   382
	}
sl@0
   383
sl@0
   384
TBool CExtensionTest::IsEqual(const RArray<TInt>& aArray1, const RArray<TInt>& aArray2) 
sl@0
   385
	{			
sl@0
   386
	if (aArray1.Count() == aArray2.Count())
sl@0
   387
		{
sl@0
   388
		TInt count = aArray1.Count();				
sl@0
   389
		for (TInt i = 0; i < count; i++)
sl@0
   390
			{
sl@0
   391
			if (aArray1[i] != aArray2[i])
sl@0
   392
				{
sl@0
   393
				return EFalse;
sl@0
   394
				}
sl@0
   395
			}
sl@0
   396
		return ETrue;
sl@0
   397
		}	
sl@0
   398
	return EFalse;
sl@0
   399
	}
sl@0
   400
sl@0
   401
TBool CExtensionTest::IsEqual(const RPointerArray<HBufC>& aArray1, const RPointerArray<HBufC>& aArray2) 
sl@0
   402
	{			
sl@0
   403
	if (aArray1.Count() == aArray2.Count())
sl@0
   404
		{
sl@0
   405
		TInt count = aArray1.Count();				
sl@0
   406
		for (TInt i = 0; i < count; i++)
sl@0
   407
			{
sl@0
   408
			if (aArray1[i]->Compare(*aArray2[i]) != 0)
sl@0
   409
				{
sl@0
   410
				return EFalse;
sl@0
   411
				}
sl@0
   412
			}
sl@0
   413
		return ETrue;
sl@0
   414
		}	
sl@0
   415
	return EFalse;
sl@0
   416
	}
sl@0
   417
	
sl@0
   418
void CExtensionTest::DoReportAction() 
sl@0
   419
	{	
sl@0
   420
	}
sl@0
   421
	
sl@0
   422
void CExtensionTest::DoCheckResult(TInt /*aError*/)
sl@0
   423
	{
sl@0
   424
	}
sl@0
   425
sl@0
   426
void CExtensionTest::Print(const TDesC& aText)
sl@0
   427
	{
sl@0
   428
	iConsole.Printf(aText);
sl@0
   429
	iOut.writeString(aText);			
sl@0
   430
	}
sl@0
   431
void CExtensionTest::PrintLine(const TDesC& aText)
sl@0
   432
	{
sl@0
   433
	iConsole.Printf(aText);
sl@0
   434
	iConsole.Printf(_L("\n"));
sl@0
   435
	
sl@0
   436
	iOut.writeString(aText);			
sl@0
   437
	iOut.writeNewLine();					
sl@0
   438
	}