cryptoservices/certificateandkeymgmt/tpkixcert/Tactionvalidate.cpp
changeset 0 2c201484c85f
child 8 35751d3474b7
equal deleted inserted replaced
-1:000000000000 0:2c201484c85f
       
     1 /*
       
     2 * Copyright (c) 1998-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 "tactionvalidate.h"
       
    20 #include "t_inputextra.h"
       
    21 
       
    22 _LIT(KChainStart, "<chain>");
       
    23 _LIT(KChainEnd, "</chain>");
       
    24 _LIT(KIOStart, "<io>");
       
    25 _LIT(KIOEnd, "</io>");
       
    26 _LIT(KCertPath, "\\pkixtestdata\\");
       
    27 
       
    28 CActionValidate::~CActionValidate()
       
    29 	{
       
    30 	if (iPolicies)
       
    31 		{
       
    32 		iPolicies->ResetAndDestroy();
       
    33 		delete iPolicies;
       
    34 		iPolicies = 0;
       
    35 		}
       
    36 
       
    37 	delete iValidationResult;
       
    38 	delete iChain;
       
    39 
       
    40 	delete iCertUtils;
       
    41 
       
    42 	delete iTestChain;
       
    43 	delete iTestIO;
       
    44 	}
       
    45 
       
    46 CActionValidate::CActionValidate(RFs& aFs, 
       
    47 								 CConsoleBase& aConsole,
       
    48 								 Output& aOut)
       
    49 : CTestAction(aConsole, aOut), iFs(aFs)
       
    50 	{
       
    51 	}
       
    52 
       
    53 
       
    54 void CActionValidate::ConstructL(const TTestActionSpec& aTestActionSpec)
       
    55 	{
       
    56 	CTestAction::ConstructL(aTestActionSpec);
       
    57 	HBufC* aBody = HBufC::NewLC(aTestActionSpec.iActionBody.Length());
       
    58 	aBody->Des().Copy(aTestActionSpec.iActionBody);
       
    59 	TInt pos = 0;
       
    60 	TInt err = KErrNone;
       
    61 	TPtrC chainBuf = Input::ParseElement(*aBody, KChainStart, KChainEnd, pos, err);
       
    62 	iTestChain = CTestChain::NewL(chainBuf);
       
    63 	if (!AddParametersL(*aBody, pos))
       
    64 		{
       
    65 		// There must be at least one IO thing
       
    66 		User::Leave(KErrNotFound);
       
    67 		}
       
    68 	while(AddParametersL(*aBody, pos))
       
    69 		{
       
    70 		}
       
    71 
       
    72 	iValidationResult = CPKIXValidationResult::NewL();
       
    73 	TDriveUnit sysDrive (RFs::GetSystemDrive());
       
    74 	TDriveName driveName(sysDrive.Name());
       
    75 	iCertPath.Copy(driveName);
       
    76 	iCertPath.Append(KCertPath);
       
    77 
       
    78 	CleanupStack::PopAndDestroy(aBody);
       
    79 	}
       
    80 
       
    81 void CActionValidate::PerformAction(TRequestStatus& aStatus)
       
    82 	{
       
    83 	switch (iState)
       
    84 		{
       
    85 		case EDoValidateTestStart:
       
    86 			{
       
    87 			__ASSERT_DEBUG(!iChain, User::Panic(_L("CPKIXCertTest"), 1));
       
    88 			TRAPD(err, CreateChainL());
       
    89 			iState = EDoValidateTestValidate;
       
    90 			TRequestStatus* status = &aStatus;
       
    91 			User::RequestComplete(status, err);
       
    92 			break;
       
    93 			}
       
    94 
       
    95 		case EDoValidateTestValidate:
       
    96 			{
       
    97 			// 1) write the overall result we expect
       
    98 			iOut.writeSpaces(4);
       
    99 			iOut.writeString(_L("Expected result = "));
       
   100 			iOut.writeString(iTestIO->iError);
       
   101 			iOut.writeNewLine();
       
   102 
       
   103 			// 2) now do the validation
       
   104 
       
   105 			iTime.UniversalTime();
       
   106 	
       
   107 			if (iTestIO->iPolicyInput->Count() > 0)
       
   108 				{
       
   109 				__ASSERT_DEBUG(!iPolicies, User::Panic(_L("CPKIXCertTest"), 1));
       
   110 				__ASSERT_DEBUG(iChain, User::Panic(_L("CPKIXCertTest"), 1));
       
   111 
       
   112 				iPolicies = new (ELeave) CArrayPtrFlat<HBufC> (1);
       
   113 				TInt count = iTestIO->iPolicyInput->Count();
       
   114 				for (TInt i = 0; i < count; i++)
       
   115 					{
       
   116 					TPtrC policy = iTestIO->iPolicyInput->MdcaPoint(i);
       
   117 					HBufC* pBuf = policy.AllocL();
       
   118 					CleanupStack::PushL(pBuf);
       
   119 					iPolicies->AppendL(pBuf);
       
   120 					CleanupStack::Pop();
       
   121 					}
       
   122 					
       
   123 				iChain->ValidateL(*iValidationResult, iTime, *iPolicies, aStatus);	
       
   124 				}
       
   125 			else
       
   126 				{
       
   127 				iChain->ValidateL(*iValidationResult, iTime, aStatus);
       
   128 				}
       
   129 			iState = EDoValidateTestValidated;
       
   130 			}
       
   131 			break;
       
   132 
       
   133 		case EDoValidateTestValidated:
       
   134 			{
       
   135 			// 3) write the overall result
       
   136 			iOut.writeSpaces(4);
       
   137 			iOut.writeString(_L("Actual result = "));
       
   138 			CCertUtils::WriteError(iValidationResult->Error().iReason, iOut);
       
   139 			TBuf<128> iActualResult = CCertUtils::MapError(iValidationResult->Error().iReason);
       
   140 			iOut.writeNewLine();
       
   141 			iOut.writeNewLine();
       
   142 
       
   143 			// 4) write the policy info
       
   144 			TBool checkingPolicies = 
       
   145 				((iTestIO->iIPoliciesSet) || (iTestIO->iOPoliciesSet));
       
   146 			if (checkingPolicies)
       
   147 				{
       
   148 				if (iTestIO->iIPoliciesSet)
       
   149 					{
       
   150 					// 4.1) policies we supplied
       
   151 					iOut.writeSpaces(4);
       
   152 					iOut.writeString(_L("Supplied policy set: "));
       
   153 					iOut.writeNewLine();
       
   154 					WritePolicies(*(iTestIO->iPolicyInput));
       
   155 					}
       
   156 				if (iTestIO->iOPoliciesSet)
       
   157 					{
       
   158 					// 4.2) policies we expect
       
   159 					iOut.writeSpaces(4);
       
   160 					iOut.writeString(_L("Expected user-constrained policy set: "));
       
   161 					iOut.writeNewLine();
       
   162 					WritePolicies(*(iTestIO->iExpectedPolicyOutput));
       
   163 					}
       
   164 
       
   165 				// 4.3) policies we collected
       
   166 				iOut.writeSpaces(4);
       
   167 				iOut.writeString(_L("Actual user-constrained policy set: "));
       
   168 				iOut.writeNewLine();
       
   169 				const CArrayPtrFlat<CX509CertPolicyInfo>& policies = iValidationResult->Policies();
       
   170 				TInt actualPolicyCount = policies.Count();
       
   171 				for (TInt j = 0; j < actualPolicyCount; j++)
       
   172 					{
       
   173 					iOut.writeSpaces(8);
       
   174 					iOut.writeString(policies.At(j)->Id());
       
   175 					iOut.writeNewLine();	
       
   176 					}
       
   177 				iOut.writeNewLine();	
       
   178 
       
   179 			//check expected user-constrained policy set == actual user-constrained policy set
       
   180 				TBool policyOutputCorrect = ETrue;
       
   181 				CDesCArray* expectedPolicies = iTestIO->iExpectedPolicyOutput;
       
   182 				TInt expectedPolicyCount = expectedPolicies->MdcaCount();
       
   183 				if (expectedPolicyCount == actualPolicyCount)
       
   184 					{
       
   185 					for (TInt k = 0; k < expectedPolicyCount; k++)
       
   186 						{
       
   187 						TPtrC expectedPolicy = expectedPolicies->MdcaPoint(k);
       
   188 						TBool policyFound = EFalse;
       
   189 						for (TInt l = 0; l < actualPolicyCount; l++)
       
   190 							{
       
   191 							TPtrC actualPolicy = policies.At(l)->Id();
       
   192 							if (actualPolicy == expectedPolicy)
       
   193 								{
       
   194 								policyFound = ETrue;
       
   195 								break;
       
   196 								}
       
   197 							}
       
   198 						if (!policyFound)
       
   199 							{
       
   200 							policyOutputCorrect = EFalse;
       
   201 							}	
       
   202 						}
       
   203 					}
       
   204 				else
       
   205 					{
       
   206 					policyOutputCorrect = EFalse;
       
   207 					}
       
   208 				iResult = (iTestIO->iError == iActualResult) && (policyOutputCorrect);
       
   209 				}
       
   210 			else	//! checking policies 
       
   211 				{
       
   212 				iResult = (iTestIO->iError == iActualResult);
       
   213 				}
       
   214 			iState = EDoValidateTestFinished;
       
   215 			if (iPolicies)
       
   216 				{
       
   217 				iPolicies->ResetAndDestroy();
       
   218 				delete iPolicies;
       
   219 				iPolicies = 0;
       
   220 				}
       
   221 			TRequestStatus* status = &aStatus;
       
   222 			User::RequestComplete(status, KErrNone);
       
   223 			}
       
   224 			break;
       
   225 
       
   226 		case EDoValidateTestFinished:
       
   227 			{
       
   228 			__ASSERT_DEBUG(!iPolicies, User::Panic(_L("CPKIXCertTest"), 1));
       
   229 			delete iChain;
       
   230 			iChain = 0;
       
   231 			iState = ERemoveCertsAfterTest;
       
   232 			iActionState = EPostrequisite;
       
   233 			TRequestStatus* status = &aStatus;
       
   234 			User::RequestComplete(status, KErrNone);
       
   235 			}
       
   236 			break;
       
   237 		default:
       
   238 			break;
       
   239 		}
       
   240 	}
       
   241 
       
   242 TBool CActionValidate::TestResult(TInt /*aError*/)
       
   243 	{
       
   244 	return 0;
       
   245 	}
       
   246 	
       
   247 void CActionValidate::PerformCancel()
       
   248 	{
       
   249 	delete iChain;
       
   250 	iChain = 0;
       
   251 	}
       
   252 
       
   253 void CActionValidate::AfterOOMFailure()
       
   254 	{
       
   255 	if (iPolicies)
       
   256 		{
       
   257 		iPolicies->ResetAndDestroy();
       
   258 		delete iPolicies;
       
   259 		iPolicies = 0;
       
   260 		}
       
   261 	}
       
   262 	
       
   263 void CActionValidate::Reset()
       
   264 	{
       
   265 	iState = EDoValidateTestStart;
       
   266 	if (iPolicies)
       
   267 		{
       
   268 		iPolicies->ResetAndDestroy();
       
   269 		delete iPolicies;
       
   270 		iPolicies = 0;
       
   271 		}
       
   272 	delete iChain;
       
   273 	iChain = 0;
       
   274 	}
       
   275 
       
   276 void CActionValidate::DoReportAction()
       
   277 	{
       
   278 	iConsole.Printf(_L("u"));
       
   279 	}
       
   280 
       
   281 void CActionValidate::DoCheckResult(TInt /*aError*/)
       
   282 	{
       
   283 	}
       
   284 
       
   285 TBool CActionValidate::AddParametersL(const TDesC& aBuf, TInt& aPos)
       
   286 	{
       
   287 	TPtrC ioBuf = Input::ParseElement(aBuf, KIOStart, KIOEnd, aPos);
       
   288 	if (ioBuf != KNullDesC)
       
   289 		{
       
   290 		iTestIO = CTestParameters::NewL(ioBuf);
       
   291 		return ETrue;
       
   292 		}
       
   293 	return EFalse;
       
   294 	}
       
   295 
       
   296 void CActionValidate::WritePolicies(const CDesCArray& aPolicySet)
       
   297 	{
       
   298 	TInt count = aPolicySet.Count();
       
   299 	for (TInt i = 0; i < count; i++)
       
   300 		{
       
   301 		iOut.writeSpaces(8);
       
   302 		iOut.writeString(aPolicySet.MdcaPoint(i));
       
   303 		iOut.writeNewLine();
       
   304 		}
       
   305 	}
       
   306 
       
   307 /*
       
   308 validate using the cert store as a source of root certificates
       
   309 */
       
   310 
       
   311 CTestAction* CActionValidateWithStore::NewL(RFs& aFs, CConsoleBase& aConsole,
       
   312 		Output& aOut, const TTestActionSpec& aTestActionSpec)
       
   313 	{
       
   314 	CTestAction* self = CActionValidateWithStore::NewLC(aFs, aConsole,
       
   315 		aOut, aTestActionSpec);
       
   316 	CleanupStack::Pop(self);
       
   317 	return self;
       
   318 	}
       
   319 
       
   320 CTestAction* CActionValidateWithStore::NewLC(RFs& aFs, CConsoleBase& aConsole,
       
   321 		Output& aOut, const TTestActionSpec& aTestActionSpec)
       
   322 	{
       
   323 	CActionValidateWithStore* self = new(ELeave) CActionValidateWithStore(aFs, aConsole, aOut);
       
   324 	CleanupStack::PushL(self);
       
   325 	self->ConstructL(aTestActionSpec);
       
   326 	return self;
       
   327 	}
       
   328 
       
   329 CActionValidateWithStore::CActionValidateWithStore(RFs& aFs, CConsoleBase& aConsole,Output& aOut)
       
   330 	:CActionValidate(aFs, aConsole, aOut)
       
   331 	{
       
   332 	}
       
   333 
       
   334 void CActionValidateWithStore::DoPerformPrerequisite(TRequestStatus& aStatus)
       
   335 	{
       
   336 	switch (iState)
       
   337 		{
       
   338 		case ERemoveCertsBeforeTest:
       
   339 			__ASSERT_DEBUG(!iCertUtils, User::Panic(_L("CPKIXCertTest"), 1));
       
   340 			iCertUtils = CCertUtils::NewL(iFs);
       
   341 			iCertUtils->RemoveCertsL(aStatus);
       
   342 			iState = EAddRoot;
       
   343 			break;
       
   344 
       
   345 		case EAddRoot:
       
   346 			{
       
   347 			TUid uid = { 1 };
       
   348 			TRAPD(err, iCertUtils->RemoveApplicationL(uid));
       
   349 			iCertUtils->AddApplicationL(_L("testpkix"), uid);
       
   350 			TUid uid2 = { 2 };
       
   351 			TRAP(err, iCertUtils->RemoveApplicationL(uid2));
       
   352 			iCertUtils->AddApplicationL(_L("testpkix"), uid2);
       
   353 			iCertUtils->AddCertL(iTestChain->iRootCertLabel,
       
   354 				EX509Certificate, ECACertificate, 1, iCertPath,
       
   355 				iTestChain->iRootCertFileName, 
       
   356 				aStatus);	// 1 is trusted for our use
       
   357 			iState = EAddIntermediateCerts;
       
   358 			break;
       
   359 			}
       
   360 
       
   361 		case EAddIntermediateCerts:
       
   362 			{
       
   363 			iCertUtils->AddCACertsL(*(iTestChain->iIntermediateCertsFileName), 
       
   364 				*(iTestChain->iIntermediateCertsLabel),
       
   365 				EX509Certificate, 2, iCertPath, 
       
   366 				aStatus);	//2 not trusted for our use
       
   367 			iState = EDoValidateTestStart;
       
   368 			iActionState = EAction;
       
   369 			break;
       
   370 			}
       
   371 		default:
       
   372 			break;
       
   373 		}
       
   374 	}
       
   375 
       
   376 void CActionValidateWithStore::DoPerformPostrequisite(TRequestStatus& aStatus)
       
   377 	{
       
   378 	switch (iState)
       
   379 		{
       
   380 		case ERemoveCertsAfterTest:
       
   381 			iCertUtils->RemoveCertsL(aStatus);
       
   382 			iState = EEnd;
       
   383 			break;
       
   384 
       
   385 		case EEnd:
       
   386 			{
       
   387 			delete iCertUtils;
       
   388 			iCertUtils = 0;
       
   389 			TRequestStatus* status = &aStatus;
       
   390 			iFinished = ETrue;
       
   391 			User::RequestComplete(status, KErrNone);
       
   392 			}
       
   393 			break;
       
   394 		default:
       
   395 			break;
       
   396 		}
       
   397 	}
       
   398 
       
   399 
       
   400 void CActionValidateWithStore::CreateChainL()
       
   401 	{
       
   402 	HBufC8* eeCert = 0;
       
   403 			
       
   404 	TRAPD(err, 
       
   405 		eeCert = Input::ReadFileL(iTestChain->iEECertFileName,
       
   406 		iCertPath, iFs));
       
   407 	if (err != KErrNone)
       
   408 		{
       
   409 		iConsole.Printf(_L("Error : couldn't open file "));
       
   410 		iConsole.Printf(iTestChain->iEECertFileName);
       
   411 		iConsole.Printf(_L("\n"));
       
   412 		iOut.writeString(_L("Error : couldn't open file "));
       
   413 		iOut.writeString(iTestChain->iEECertFileName);
       
   414 		iOut.writeNewLine();
       
   415 		User::Leave(err);
       
   416 		}
       
   417 	CleanupStack::PushL(eeCert);
       
   418 	TUid testUid = TUid::Uid(1);
       
   419 	iChain = CPKIXCertChain::NewL(iFs, *eeCert, testUid);
       
   420 	CleanupStack::PopAndDestroy(eeCert); 
       
   421 	}
       
   422 
       
   423 /*
       
   424 validate using a set of candidates root certs supplied by the client
       
   425 */
       
   426 CTestAction* CActionValidateWithSuppliedCerts::NewL(RFs& aFs, CConsoleBase& aConsole,
       
   427 		Output& aOut, const TTestActionSpec& aTestActionSpec)
       
   428 	{
       
   429 	CTestAction* self = CActionValidateWithSuppliedCerts::NewLC(aFs, aConsole,
       
   430 		aOut, aTestActionSpec);
       
   431 	CleanupStack::Pop(self);
       
   432 	return self;	
       
   433 	}
       
   434 
       
   435 CTestAction* CActionValidateWithSuppliedCerts::NewLC(RFs& aFs, CConsoleBase& aConsole,
       
   436 		Output& aOut, const TTestActionSpec& aTestActionSpec)
       
   437 	{
       
   438 	CActionValidateWithSuppliedCerts* self = new(ELeave) CActionValidateWithSuppliedCerts(aFs, aConsole, aOut);
       
   439 	CleanupStack::PushL(self);
       
   440 	self->ConstructL(aTestActionSpec);
       
   441 	return self;
       
   442 	}
       
   443 
       
   444 CActionValidateWithSuppliedCerts::CActionValidateWithSuppliedCerts(RFs& aFs, CConsoleBase& aConsole,Output& aOut)
       
   445 	:CActionValidate(aFs, aConsole, aOut)
       
   446 	{
       
   447 	}
       
   448 
       
   449 void CActionValidateWithSuppliedCerts::ConstructL(const TTestActionSpec& aTestActionSpec)
       
   450 	{
       
   451 	CActionValidate::ConstructL(aTestActionSpec);
       
   452 	iRootCerts = new(ELeave) RPointerArray<CX509Certificate>;
       
   453 	}
       
   454 
       
   455 CActionValidateWithSuppliedCerts::~CActionValidateWithSuppliedCerts()
       
   456 	{
       
   457 	if (iRootCerts)
       
   458 		{
       
   459 		iRootCerts->ResetAndDestroy();
       
   460 		delete iRootCerts;
       
   461 		}
       
   462 	delete iEndEntityAndIntermediateCerts;
       
   463 	}
       
   464 
       
   465 void CActionValidateWithSuppliedCerts::DoPerformPrerequisite(TRequestStatus& aStatus)
       
   466 	{
       
   467 //initialise the big descriptor containing ee cert followed by all intermediate certs
       
   468 //and the array of candidate root certs
       
   469 
       
   470 	HBufC8* eeCert = Input::ReadFileLC(iTestChain->iEECertFileName, iCertPath, iFs);
       
   471 	HBufC8* inter = InputExtra::ReadFilesLC(*(iTestChain->iIntermediateCertsFileName), iCertPath, iFs);
       
   472 	TInt totalSize = (eeCert->Size()) + (inter->Size());
       
   473 	iEndEntityAndIntermediateCerts = HBufC8::NewL(totalSize);
       
   474 	TPtr8 pRes = iEndEntityAndIntermediateCerts->Des();
       
   475 	pRes.Append(*eeCert);
       
   476 	pRes.Append(*inter);
       
   477 	CleanupStack::PopAndDestroy(2);//eeCert, inter
       
   478 
       
   479 	HBufC8* rootBuf = Input::ReadFileLC(iTestChain->iRootCertFileName, iCertPath, iFs);
       
   480 	CX509Certificate* root = CX509Certificate::NewL(*rootBuf);
       
   481 	CleanupStack::PopAndDestroy(rootBuf);
       
   482 	CleanupStack::PushL(root);
       
   483 	
       
   484 	User::LeaveIfError(iRootCerts->Append(root));
       
   485 	CleanupStack::Pop(root);//
       
   486 
       
   487 	TRequestStatus* status = &aStatus;
       
   488 	User::RequestComplete(status, KErrNone);
       
   489 	iState = EDoValidateTestStart;
       
   490 	iActionState = EAction;
       
   491 	}
       
   492 
       
   493 void CActionValidateWithSuppliedCerts::DoPerformPostrequisite(TRequestStatus& aStatus)
       
   494 	{
       
   495 	delete iCertUtils;
       
   496 	iCertUtils = NULL;
       
   497 	TRequestStatus* status = &aStatus;
       
   498 	iFinished = ETrue;
       
   499 	User::RequestComplete(status, KErrNone);
       
   500 	}
       
   501 
       
   502 void CActionValidateWithSuppliedCerts::CreateChainL()
       
   503 	{
       
   504 //create chain object
       
   505 	iChain = CPKIXCertChain::NewL(iFs, *iEndEntityAndIntermediateCerts, *iRootCerts);
       
   506 	}