os/security/cryptoservices/certificateandkeymgmt/tpkixcert_tef/src/validateteststep.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.
     1 /*
     2 * Copyright (c) 2008-2010 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 "validateteststep.h"
    20 
    21 
    22 CValidateCertChainStep::CValidateCertChainStep()
    23 	{
    24 	SetTestStepName(KValidateCertChainStep);
    25 	}
    26 
    27 CValidateCertChainStep::~CValidateCertChainStep()
    28 	{
    29 	delete iActiveObject;
    30 	}
    31 
    32 TVerdict CValidateCertChainStep::doTestStepPreambleL()
    33 	{
    34 	CPkixCertStepBase::doTestStepPreambleL();
    35 	GetIntFromConfig(ConfigSection(), KNumberOfCerts, iNumberOfCerts);
    36 	return EPass;
    37 	}
    38 
    39 void CValidateCertChainStep::PerformTestL()
    40 	{
    41 	CPkixCertStepBase::PerformTestL();
    42 	
    43 	iCertChain->SetSupportedCriticalExtensionsL(iProcessedOids);
    44 	
    45 	TTime time;
    46 	time.UniversalTime();
    47 	
    48 	ValidateL(time, ConfigSection());
    49 	
    50 	CleanupStack::PopAndDestroy(iCertChain);
    51 
    52 	}
    53 
    54 
    55 void CValidateCertChainStep::ValidateL(TTime aValidateTime, TDes& aConfigSection)
    56 	{
    57 	
    58 	CPKIXValidationResult* result = CPKIXValidationResult::NewLC();
    59 	
    60 	iActiveObject = new (ELeave) CValidateCertChainHelper(Logger());
    61 	CleanupStack::PushL(iActiveObject);
    62 
    63 	User::LeaveIfError(iActiveObject->PerformTestL(iCertChain, *result, aValidateTime));
    64 
    65 	CleanupStack::PopAndDestroy(iActiveObject);
    66 	iActiveObject = NULL;
    67 
    68 	TInt expectedError;
    69 	GetIntFromConfig(aConfigSection, KError, expectedError);
    70 		
    71 	if ((result->Error()).iReason != expectedError)
    72 		{
    73 		ERR_PRINTF3(_L("ERROR: Error: %d.  Expected error: %d"), (result->Error()).iReason, expectedError);
    74 		User::Leave(KErrGeneral);
    75 		}
    76 			
    77 	if (expectedError != EValidatedOK)
    78 		{
    79 		//we are expected to error
    80 		TInt certIndex;
    81 		GetIntFromConfig(aConfigSection, KErrorIndex, certIndex);	
    82 		if ((result->Error()).iCert != certIndex)
    83 			{			
    84 			ERR_PRINTF3(_L("ERROR: Error certificate index: %d.  Expected index: %d"), (result->Error()).iCert, certIndex);
    85 			User::Leave(KErrGeneral);			
    86 			}
    87 		else{
    88 			CleanupStack::PopAndDestroy(result);
    89 			return; //we have passed
    90 			}
    91 		}
    92 		
    93 	
    94 	const CArrayFixFlat<TValidationStatus>& warns = result->Warnings();
    95 	RArray<TValidationStatus> resultOldWarnings;
    96 	CleanupClosePushL(resultOldWarnings);	
    97 	TInt i;
    98 	for (i=0; i < warns.Count(); ++i)
    99 		{
   100 		resultOldWarnings.AppendL(warns[i]);
   101 		}
   102 
   103 	const RPointerArray<CCertificateValidationWarnings>& certificateWarningsArray = result->ValidationWarnings();	
   104 	
   105 	HBufC* key;
   106 
   107 	RArray<TValidationStatus> processedPolicyQualifiers;
   108 	CleanupClosePushL(processedPolicyQualifiers);		
   109 	
   110 	TInt qualifierWarning = 18;
   111 
   112 	for (i=0; i < iNumberOfCerts; ++i)
   113 		{
   114 		key = HBufC::NewLC(KCert().Length() + KKeyFormat().Length() + KPolicyIndex().Length()); 
   115 		TPtr ptr(key->Des());
   116 		ptr = KCert();
   117 		ptr.AppendFormat(KKeyFormat(), i);
   118 		ptr.Append(KPolicyIndex());	
   119 		
   120 		TInt policyIndex = 0;
   121 		GetIntFromConfig(aConfigSection, *key, policyIndex);
   122 		
   123 		if (policyIndex > 0)
   124 			{
   125 			TValidationError error = (TValidationError) qualifierWarning;
   126 			processedPolicyQualifiers.AppendL(TValidationStatus(error, policyIndex));
   127 			}
   128 
   129 		CleanupStack::PopAndDestroy(key);
   130 		}
   131 	
   132 	//handle 1st part old warnings first - check any warnings we expect are present (later we check no additionals) 
   133 	CheckWarningsPresentAndRemoveL(processedPolicyQualifiers, resultOldWarnings);
   134 	
   135 	RArray<TInt> configOldWarnings;
   136 	CleanupClosePushL(configOldWarnings);
   137 	RArray<TValidationStatus> processedConfigOldWarnings;
   138 	CleanupClosePushL(processedConfigOldWarnings);		
   139 	
   140 	RArray<TValidationStatus> configNewWarnings;
   141 	CleanupClosePushL(configNewWarnings);
   142 	RArray<TPtrC> configCritOids;
   143 	CleanupClosePushL(configCritOids);	
   144 	
   145 	for (TInt cert_index=0; cert_index < iNumberOfCerts; ++cert_index)
   146 		{
   147 		INFO_PRINTF2(_L("Certificate index: %d"), cert_index);
   148 		key = HBufC::NewLC(KCert().Length() + KKeyFormat().Length() + KOldWarnings().Length()); 
   149 		TPtr ptr(key->Des());
   150 		ptr = KCert();
   151 		ptr.AppendFormat(KKeyFormat(), cert_index);
   152 		ptr.Append(KOldWarnings());
   153 		
   154 		GetIntArrayFromConfigL(aConfigSection, *key, configOldWarnings);
   155 		
   156 		processedConfigOldWarnings.Reset();
   157 		for (TInt i=0; i < configOldWarnings.Count(); ++i)
   158 			{
   159 			TValidationError error = (TValidationError) configOldWarnings[i];
   160 			processedConfigOldWarnings.AppendL(TValidationStatus(error, cert_index));
   161 			}
   162 		
   163 		TransferToNewWarningsL(configOldWarnings, configNewWarnings, cert_index);
   164 		
   165 		ptr.Zero();	
   166 		ptr = KCert();
   167 		ptr.AppendFormat(KKeyFormat(), cert_index);
   168 		ptr.Append(KCritOid());
   169 			
   170 		GetStringArrayFromConfigL(aConfigSection, *key, configCritOids);
   171 		
   172 		CleanupStack::PopAndDestroy(key);
   173 		
   174 		//we now have all our arguments from the config file
   175 		
   176 		//handle 1st part old warnings first - check any warnings we expect are present (later we check no additionals) 
   177 		CheckWarningsPresentAndRemoveL(processedConfigOldWarnings, resultOldWarnings);
   178 		
   179 		
   180 		CCertificateValidationWarnings* certWarning = certificateWarningsArray[((iNumberOfCerts - cert_index) - 1)];	//not owned	//warnings returned in reverse order
   181 		
   182 		//check cert and certindex match up correctly		
   183 		if (certWarning->CertIndex() != cert_index)
   184 			{
   185 			ERR_PRINTF3(_L("ERROR: Certificate indexes do not match.  Certificate index: %d.  Expected index: %d"), certWarning->CertIndex(), cert_index);
   186 			User::Leave(KErrGeneral);
   187 			}
   188 		
   189 		key = HBufC::NewLC(KCert().Length() + KKeyFormat().Length() + KPolicyIndex().Length()); 
   190 		TPtr pt(key->Des());
   191 		pt = KCert();
   192 		pt.AppendFormat(KKeyFormat(), cert_index);
   193 		pt.Append(KPolicyIndex());	
   194 			
   195 		TInt policyIndex = 0;
   196 		GetIntFromConfig(aConfigSection, *key, policyIndex);
   197 			
   198 		if (policyIndex > 0)
   199 			{
   200 			TValidationError error = (TValidationError) qualifierWarning;
   201 			configNewWarnings.AppendL(TValidationStatus(error, policyIndex));
   202 			}
   203 
   204 		CleanupStack::PopAndDestroy(key);
   205 			
   206 		//check new warnings behave correctly
   207 		CheckWarningsPresentAndRemoveL(certWarning->Warnings(), configNewWarnings);
   208 		
   209 		if (configNewWarnings.Count() != 0)
   210 			{
   211 			for (TInt err=0; err < configNewWarnings.Count(); ++err)
   212 				{
   213 				ERR_PRINTF2(_L("ERROR: Warning(new API) not reported: %d"), (configNewWarnings[err]).iReason);
   214 				}
   215 			User::Leave(KErrGeneral);
   216 			}
   217 		
   218 		
   219 		//check critoids behave correctly
   220 		CheckCriticalExtsPresentAndRemoveL(certWarning->CriticalExtensionsFound(), configCritOids);
   221 		if (configCritOids.Count() != 0)
   222 			{
   223 			for (TInt err=0; err < configCritOids.Count(); ++err)
   224 				{
   225 				ERR_PRINTF2(_L("ERROR: Critical extension not reported: %S"), &configCritOids[err]);
   226 				}			
   227 			User::Leave(KErrGeneral);
   228 			}
   229 			
   230 		configOldWarnings.Reset();
   231 		configNewWarnings.Reset();
   232 		configCritOids.Reset();		
   233 		}
   234 		
   235 	CleanupStack::PopAndDestroy(5, &processedPolicyQualifiers);	
   236 		
   237 	//check if any warnings in old api we weren't expecting	
   238 	if (resultOldWarnings.Count() != 0)
   239 		{	
   240 		for (TInt warn=0; warn < resultOldWarnings.Count(); ++warn)
   241 			{
   242 			ERR_PRINTF3(_L("ERROR: Warning(old API) not reported: %d.  Index: %d"), (resultOldWarnings[warn]).iReason, (resultOldWarnings[warn]).iCert);
   243 			}		
   244 		User::Leave(KErrGeneral);
   245 		}
   246 	
   247 	CleanupStack::PopAndDestroy(2, result);
   248 	}
   249 
   250 void CValidateCertChainStep::TransferToNewWarningsL(RArray<TInt>& aOldWarnings, RArray<TValidationStatus>& aNewWarnings, TInt aCertIndex)
   251 	{
   252 	for (TInt i=0; i < aOldWarnings.Count(); ++i)
   253 		{
   254 		switch (aOldWarnings[i])
   255 			{
   256 			case ECriticalExtendedKeyUsage:
   257 				break;
   258 			case ECriticalPolicyMapping:
   259 				break;
   260 			case ECriticalDeviceId:
   261 				break;
   262 			case ECriticalSid:
   263 				break;
   264 			case ECriticalVid:
   265 				break;
   266 			case ECriticalCapabilities:
   267 				break;
   268 			case ECriticalCertPoliciesWithQualifiers:	//handled by ini parameter due to overloading by warning of iCert value
   269 				break;
   270 			default:
   271 				TValidationError error = (TValidationError) aOldWarnings[i];
   272 				aNewWarnings.AppendL(TValidationStatus(error, aCertIndex));							
   273 			}
   274 		}
   275 	}
   276 
   277 
   278 
   279 
   280 
   281 void CValidateCertChainStep::CheckWarningsPresentAndRemoveL(const RArray<TValidationStatus>& aWarningsToCheckFor, RArray<TValidationStatus>& aWarningsToCheckIn)
   282 	{
   283 	TBool found;
   284 	for (TInt warnings_index=0; warnings_index < aWarningsToCheckFor.Count(); ++warnings_index)
   285 		{
   286 		found = EFalse;
   287 		for (TInt k=0; k < aWarningsToCheckIn.Count(); ++k)
   288 			{
   289 			if (ValidationStatusEqual(aWarningsToCheckFor[warnings_index], aWarningsToCheckIn[k]))
   290 				{
   291 				found = ETrue;
   292 				aWarningsToCheckIn.Remove(k);
   293 				break;
   294 				}
   295 			}
   296 				
   297 		if (!found)	
   298 			{	
   299 			ERR_PRINTF2(_L("ERROR: Warning not present: %d"), aWarningsToCheckFor[warnings_index].iReason);
   300 			User::Leave(KErrGeneral); 
   301 			}
   302 		}	
   303 	}
   304 
   305 
   306 TBool CValidateCertChainStep::ValidationStatusEqual(const TValidationStatus& aValidationStatus1, const TValidationStatus& aValidationStatus2)
   307 	{
   308 	if (aValidationStatus1.iReason != aValidationStatus2.iReason)
   309 		{
   310 		return EFalse;
   311 		}
   312 	if (aValidationStatus1.iCert != aValidationStatus2.iCert)
   313 		{
   314 		return EFalse;
   315 		}
   316 	return ETrue;	
   317 	}
   318 
   319 
   320 //takes away from aOidsToCheckAgainst
   321 void CValidateCertChainStep::CheckCriticalExtsPresentAndRemoveL(const RPointerArray<TDesC>& aOidsToLookFor, RArray<TPtrC>& aOidsToCheckAgainst)
   322 	{
   323 	TBool found;
   324 	for (TInt oid_index=0; oid_index < aOidsToLookFor.Count(); ++oid_index)
   325 		{
   326 		found = EFalse;
   327 		for (TInt k=0; k < aOidsToCheckAgainst.Count(); ++k)
   328 			{
   329 			if ((*aOidsToLookFor[oid_index])==(aOidsToCheckAgainst[k]))
   330 				{
   331 				found = ETrue;
   332 				aOidsToCheckAgainst.Remove(k);
   333 				break;
   334 				}
   335 			}
   336 				
   337 		if (!found)	
   338 			{
   339 			ERR_PRINTF2(_L("ERROR: Critical extension OID not present: %S"), aOidsToLookFor[oid_index]);
   340 			User::Leave(KErrGeneral);	
   341 			}
   342 		}		
   343 	}
   344 
   345 
   346 
   347 //////////////////////////************
   348 
   349 CValidateCertChainHelper::CValidateCertChainHelper(CTestExecuteLogger& aLogger)
   350 :  CActive(EPriorityStandard), iLogger(aLogger)
   351 	{
   352 	CActiveScheduler::Add(this);
   353 	}
   354 	
   355 	
   356 CValidateCertChainHelper::~CValidateCertChainHelper()
   357 	{
   358 	Cancel();
   359 	}
   360 	
   361 
   362 TInt CValidateCertChainHelper::PerformTestL(CPKIXCertChain* aCertChain, CPKIXValidationResult& aValidResult, TTime aValidateTime)
   363 	{
   364 	iCertChain = aCertChain;
   365 	
   366 	//call async
   367 	aCertChain->ValidateL(aValidResult, aValidateTime, iStatus);
   368 	
   369 	SetActive();
   370    	CActiveScheduler::Start();
   371    	
   372     return iRunError;	
   373 	}
   374 	
   375 	
   376 void CValidateCertChainHelper::DoCancel()
   377 	{
   378 	iCertChain->CancelValidate();
   379 	}
   380 	
   381 	
   382 void CValidateCertChainHelper::RunL()
   383 	{
   384 	iRunError = KErrNone;
   385 	User::LeaveIfError(iStatus.Int());
   386 	
   387 	//processing here
   388 
   389 	
   390 	CActiveScheduler::Stop();	
   391 	}
   392 	
   393 
   394 TInt CValidateCertChainHelper::RunError(TInt aError)
   395 	{
   396 	iRunError = aError;
   397 	//processing here
   398 
   399 	
   400 	CActiveScheduler::Stop();
   401 	return KErrNone;	
   402 	}
   403