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