installationservices/swi/source/securitymanager/securitymanager.cpp
changeset 0 ba25891c3a9e
child 34 741e5bba2bd1
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 1997-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 /**
       
    20  @file 
       
    21  @released
       
    22  @internalTechnology
       
    23 */
       
    24  
       
    25 #include <f32file.h>
       
    26 
       
    27 #include "securitymanager.h"
       
    28 #include "swi/sishash.h"
       
    29 #include "swi/sisdataprovider.h"
       
    30 #include "swi/sissignaturealgorithm.h"
       
    31 #include "swi/sissignaturecertificatechain.h"
       
    32 #include "swi/siscertificatechain.h"
       
    33 #include "swi/sisinfo.h"
       
    34 #include "swi/sissupportedoptions.h"
       
    35 #include "swi/sissupportedlanguages.h"
       
    36 #include "swi/sisprerequisites.h"
       
    37 #include "swi/sislogo.h"
       
    38 #include "swi/sisproperties.h"
       
    39 #include "swi/sisinstallblock.h"
       
    40 #include "swi/sistruststatus.h"
       
    41 #include "hashcontainer.h"
       
    42 #include "certchainconstraints.h"
       
    43 #include "devinfosupportclient.h"
       
    44 
       
    45 #include "log.h"
       
    46 
       
    47 // PKIX dependencies
       
    48 #include <pkixcertchain.h>
       
    49 #include <x509keys.h> 
       
    50 #include <ocsp.h>
       
    51 #include <securitydefsconst.h>
       
    52 
       
    53 #include <ccertattributefilter.h>
       
    54 #include <ct/mcttoken.h>
       
    55 //#include <mctcertstore.h>
       
    56 #include "cfstokentypeclient.h"
       
    57 
       
    58 // Crypto dependencies
       
    59 #include <hash.h>
       
    60 #include <swicertstore.h>
       
    61 
       
    62 // SecMan includes
       
    63 #include "chainvalidator.h"
       
    64 #include "certificateretriever.h"
       
    65 #include "signatureverifier.h"
       
    66 #include "securitypolicy.h"
       
    67 #include "revocationhandler.h"
       
    68 
       
    69 const TInt KFileBufferSize = 1024;  // 1k buffer used to read the data to be hashed
       
    70 _LIT(KSecurityManagerName, "_Security_Manager_");
       
    71 
       
    72 
       
    73 using namespace Swi;
       
    74 
       
    75 //
       
    76 // Life Cycle methods
       
    77 //
       
    78 
       
    79 EXPORT_C CSecurityManager* CSecurityManager::NewL()
       
    80 	{
       
    81 	CSecurityManager* self = CSecurityManager::NewLC();
       
    82 	CleanupStack::Pop(self);
       
    83 	return self;
       
    84 	}
       
    85  
       
    86 EXPORT_C CSecurityManager* CSecurityManager::NewLC()
       
    87 	{
       
    88 	CSecurityManager* self = new(ELeave) CSecurityManager();
       
    89 	CleanupStack::PushL(self);
       
    90 	self->ConstructL();
       
    91 	return self;
       
    92 	}
       
    93 
       
    94 EXPORT_C CSecurityPolicy& CSecurityManager::SecurityPolicy() const
       
    95 	{
       
    96 	return *iSecPolicy;
       
    97 	}
       
    98 
       
    99 CSecurityManager::CSecurityManager() : CActive(EPriorityNormal) 
       
   100 	{
       
   101 	CActiveScheduler::Add(this);	
       
   102 	}
       
   103 
       
   104 CSecurityManager::~CSecurityManager()
       
   105 	{	
       
   106 	Deque();
       
   107 
       
   108 	if (iCurrentPkixChain)
       
   109 		{
       
   110 		delete iCurrentPkixChain;
       
   111 		}
       
   112 
       
   113 	if (iCertStore)
       
   114 		{
       
   115 		iCertStore->Release();
       
   116 		}
       
   117 	
       
   118 	if (iCertificateRetriever)
       
   119 		{
       
   120 		delete iCertificateRetriever;
       
   121 		}
       
   122 		
       
   123 	if (iChainValidator)
       
   124 		{
       
   125 		delete iChainValidator;
       
   126 		}
       
   127 		
       
   128 	if (iRevocationHandler)
       
   129 		{
       
   130 		delete iRevocationHandler;
       
   131 		}
       
   132 		
       
   133 	iValidPkixChains.ResetAndDestroy();
       
   134 	iUntrustedRoots.ResetAndDestroy();
       
   135 	iDeviceIDs.ResetAndDestroy();
       
   136 	TInt count = iTrustedRoots.Count();
       
   137 	// Release certificates from the list
       
   138 	for (TInt i = 0; i < count; ++i)
       
   139 		{
       
   140 		iTrustedRoots[0]->Release(); 
       
   141 		iTrustedRoots.Remove(0);
       
   142 		}
       
   143 	iTrustedRoots.Close();	
       
   144 	iCertMetaInfo.Reset();
       
   145 	iFs.Close();
       
   146 	}
       
   147 
       
   148 
       
   149 void CSecurityManager::ConstructL()
       
   150 	{	
       
   151 	User::LeaveIfError(iFs.Connect());
       
   152 	iSecPolicy = CSecurityPolicy::GetSecurityPolicyL();	
       
   153 	iCertStore=CSWICertStore::NewL(iFs);
       
   154 	}
       
   155 	
       
   156 	
       
   157 //
       
   158 // Active Objects methods
       
   159 //
       
   160 
       
   161 void CSecurityManager::RunL()
       
   162 	{
       
   163 	DEBUG_PRINTF3(_L8("Security Manager - RunL(). State: %d, Status: %d."),
       
   164 		iState, iStatus.Int());
       
   165 	
       
   166 	if (iStatus.Int() != KErrNone)
       
   167 		{
       
   168 		User::Leave(iStatus.Int());     // Hop into RunError()
       
   169 		}
       
   170 		
       
   171 	switch (iState)
       
   172 		{ 			
       
   173 		case ERetrievedTrustedRoots:
       
   174 			{
       
   175 			iCertMetaInfo.Reset();
       
   176 			TInt trustedCertCount = iTrustedRoots.Count();
       
   177 			for (TInt i = 0; i < trustedCertCount; ++i)
       
   178 				{
       
   179 				CCTCertInfo& certInfo=*iTrustedRoots[i];
       
   180 				DEBUG_CODE_SECTION(			
       
   181 					DEBUG_PRINTF2(_L("Security Manager - SWI certstore contains trust anchor certificate '%S'"),
       
   182 						&(certInfo.Label()));
       
   183 						);
       
   184 				TCertMetaInfo metaInfo = iCertStore->CertMetaInfoL(certInfo);
       
   185 				iCertMetaInfo.AppendL(metaInfo);
       
   186 				if (metaInfo.iIsMandatory)		
       
   187 					{
       
   188 					iMandatoryCertDNCount++;
       
   189 					DEBUG_CODE_SECTION(			
       
   190 					DEBUG_PRINTF2(_L("Security Manager - SWI certstore contains mandatory certificate '%S'"),
       
   191 						&(certInfo.Label()));
       
   192 						);
       
   193 					}
       
   194 				if (metaInfo.iIsSystemUpgrade)		
       
   195 					{
       
   196 					DEBUG_CODE_SECTION(			
       
   197 					DEBUG_PRINTF2(_L("Security Manager - SWI certstore contains system upgrade certificate '%S'"),
       
   198 						&(certInfo.Label()));
       
   199 						);
       
   200 					}
       
   201 				}
       
   202 			// After we get here, we have retrieved mandatory certificates
       
   203 			// We may have an unsigned sis file in which case we do not want to verify the block
       
   204 			// since there isn't one, so bail here with the correct error
       
   205 			if (iChains.Count() == 0)
       
   206 					{
       
   207 					if (iMandatoryCertDNCount == 0)
       
   208 						{
       
   209 						*iResult = ESignatureNotPresent; // No mandatory certs, so just say unsigned
       
   210 						}
       
   211 					else
       
   212 						{
       
   213 						*iResult = EMandatorySignatureMissing; // more important error code overrides
       
   214 						}
       
   215 					
       
   216 					User::RequestComplete(iClientStatus, KErrNone);							
       
   217 					break;
       
   218 					}
       
   219 	
       
   220 		
       
   221 			VerifyBlockL(iCurrentChain);			
       
   222 			}
       
   223 			break;
       
   224 			
       
   225 		case EValidatingChain :
       
   226 			{
       
   227 			CPKIXValidationResultBase* result = (*iValidationResultsOut)[iCurrentChain];
       
   228 			::TValidationStatus resultStatus = result->Error(); 	
       
   229 
       
   230 			DEBUG_PRINTF3(_L8("Security Manager - Certificate validation result was %d. (If applicable, error on certificate %d.)"),
       
   231 				resultStatus.iReason, resultStatus.iCert);
       
   232 
       
   233 			iCurrentChain++; // Next chain to validate
       
   234 
       
   235 			if (resultStatus.iReason != EValidatedOK)
       
   236 				{
       
   237 				// we can discard the invalid cert chain
       
   238 				delete iCurrentPkixChain;
       
   239 				iCurrentPkixChain = NULL;
       
   240 				
       
   241 				// ooops
       
   242 				if (iChains.Count() > iCurrentChain)   // This is the ValidateANY policy
       
   243 					{
       
   244 					VerifyBlockL(iCurrentChain);
       
   245 					break;						
       
   246 					}
       
   247 				}
       
   248 			else
       
   249 				{
       
   250 				iHasValidated = ETrue; // At least one chain has been validated! Hurrah!
       
   251 				
       
   252 				// check if a chain has validated that is not self signed
       
   253 				if (*iResult != ESignatureSelfSigned)
       
   254 					{
       
   255 					iHasValidatedTrusted = ETrue;
       
   256 					}
       
   257 				
       
   258 			    // From here on the chain has been validated successfully
       
   259 						
       
   260 			    iTotalCapabilitiesOut->Union(iCurrentCapabilities); // Update the total capabilities
       
   261 			
       
   262 			    // Reduce the count from the list of mandatory certs
       
   263 			    UpdateListOfMissingRequiredCertsL(iCurrentPkixChain->Cert(iCurrentPkixChain->Count()-1));
       
   264 				
       
   265 				// Updage the System Upgrade status of the Certificate
       
   266 				UpdateSystemUpgradeCertStatusL(iCurrentPkixChain->Cert(iCurrentPkixChain->Count()-1));
       
   267 				
       
   268 			    User::LeaveIfError(iValidPkixChains.Append(iCurrentPkixChain));
       
   269 			    // this chain will be used for OCSP checking if required, so record it.
       
   270 			    iController->AddChainIndex(iCurrentChain-1);
       
   271 			    
       
   272 			    iCurrentPkixChain = NULL;
       
   273 				}
       
   274 
       
   275 			if (iCurrentChain == iChains.Count())
       
   276 				{
       
   277 				if (iMandatoryCertDNCount == 0)
       
   278 					{
       
   279 					// Mandatory certs prerequisites met				
       
   280 
       
   281 					if (iHasValidated)
       
   282 						{
       
   283 						//Build the certificate chain constraints
       
   284 						CCertChainConstraints* certChainConstraints(0);
       
   285 						TRAPD(err, certChainConstraints=CCertChainConstraints::NewL(iValidPkixChains));
       
   286 						if (err)
       
   287 							{
       
   288 							*iResult = ECertificateValidationError;
       
   289 							User::RequestComplete(iClientStatus, KErrNone);
       
   290 							return;
       
   291 							}
       
   292 
       
   293 						*iResult = iHasValidatedTrusted ? EValidationSucceeded : ESignatureSelfSigned;
       
   294 						
       
   295 						//Pass the certificate chain constraints ownership to controller
       
   296 						Sis::CController* controller=const_cast<Sis::CController*>(iController);
       
   297 						controller->SetCertChainConstraints(certChainConstraints);
       
   298 
       
   299 						//Set the dev cert found flag if dev cert first time found
       
   300 						if (iDevCertWarningState==ENoDevCerts && 
       
   301 							(certChainConstraints->SIDsAreConstrained() 
       
   302 							||certChainConstraints->VIDsAreConstrained()
       
   303 							||certChainConstraints->DeviceIDsAreConstrained()
       
   304 							||certChainConstraints->CapabilitiesAreConstrained()))
       
   305 							{
       
   306 							DEBUG_PRINTF(_L("Security Manager - At least one certificate chain contains a devcert."));
       
   307 							iDevCertWarningState=EFoundDevCerts;
       
   308 							}
       
   309 
       
   310 						//Check if the device id is contrained and the device Id has been retrieved
       
   311 						if (certChainConstraints->DeviceIDsAreConstrained() && iDeviceIDs.Count()==0)
       
   312 							{
       
   313 				 			//Retrieve and Save the device ID list then complete
       
   314 				 			RDeviceInfo deviceInfo;
       
   315 				 			User::LeaveIfError(deviceInfo.Connect());
       
   316 				 			CleanupClosePushL(deviceInfo);
       
   317  							const RPointerArray<HBufC>& tempbuf=deviceInfo.DeviceIdsL();
       
   318 				 			for (TInt i=0;i<tempbuf.Count();i++)
       
   319 					 			{
       
   320 					 			HBufC* element=tempbuf[i]->AllocLC();
       
   321 				  				iDeviceIDs.AppendL(element);
       
   322 				  				CleanupStack::Pop(element);	 				
       
   323 					 			}
       
   324 					 		CleanupStack::PopAndDestroy(&deviceInfo);					
       
   325 							}						
       
   326 						iState = EChecksDone;
       
   327 						TRequestStatus* status = &iStatus;
       
   328 						User::RequestComplete(status, KErrNone);
       
   329 						SetActive();
       
   330 						return;
       
   331 						}
       
   332 					}
       
   333 
       
   334 				if (iMandatoryCertDNCount != 0)
       
   335 					{
       
   336 					*iResult = EMandatorySignatureMissing;  // We did not meet mandatory cert requirements!
       
   337 					}
       
   338 				else
       
   339 					{
       
   340 					if (!iHasValidated) 
       
   341 						{
       
   342 						*iResult = ECertificateValidationError; // No chain ever validated 
       
   343 						}
       
   344 					}
       
   345 	
       
   346 				User::RequestComplete(iClientStatus, KErrNone);							
       
   347 				}
       
   348 			else
       
   349 				{
       
   350 				VerifyBlockL(iCurrentChain);
       
   351 				return;					
       
   352 				}
       
   353 			}
       
   354 			break;
       
   355 
       
   356 		case ERevalidatingChain:
       
   357 			{
       
   358 			TInt chainIndex = (*iChainListIndices)[iCurrentChain];
       
   359 			
       
   360 			CPKIXValidationResultBase* result = (*iValidationResultsOut)[iCurrentChain];
       
   361 			::TValidationStatus resultStatus = result->Error(); 	
       
   362 
       
   363 			DEBUG_PRINTF3(_L8("Security Manager - Certificate validation result was %d. (If applicable, error on certificate %d.)"),
       
   364 				resultStatus.iReason, resultStatus.iCert);
       
   365 				
       
   366 			iCurrentChain++; // Next chain to validate
       
   367 
       
   368 			if (resultStatus.iReason != EValidatedOK)
       
   369 				{
       
   370 				// We can discard the invalid chain.
       
   371 				delete iCurrentPkixChain;
       
   372 				iCurrentPkixChain = NULL;
       
   373 				
       
   374 				// ooops
       
   375 				if (iChains.Count() > chainIndex)  	
       
   376 					{ // This is the ValidateANY policy
       
   377 					VerifyBlockL(chainIndex);
       
   378 					break;						
       
   379 					}
       
   380 				}
       
   381 			else
       
   382 				{
       
   383 				iHasValidated = ETrue; // At least one chain has been validated! Hurrah!
       
   384 				
       
   385 				// check if a chain has validated that is not self signed
       
   386 				if (*iResult != ESignatureSelfSigned)
       
   387 					{
       
   388 					iHasValidatedTrusted = ETrue;
       
   389 					}
       
   390 				
       
   391 				// From here on the chain has been validated successfully
       
   392 						
       
   393 				iTotalCapabilitiesOut->Union(iCurrentCapabilities); // Update the total capabilities
       
   394 			
       
   395 				// Reduce the count from the list of mandatory certs
       
   396 				UpdateListOfMissingRequiredCertsL(iCurrentPkixChain->Cert(iCurrentPkixChain->Count()-1));
       
   397 			
       
   398 				// Updage the System Upgrade status of the Certificate
       
   399 				UpdateSystemUpgradeCertStatusL(iCurrentPkixChain->Cert(iCurrentPkixChain->Count()-1));
       
   400 				
       
   401 				iValidPkixChains.AppendL(iCurrentPkixChain);
       
   402 					
       
   403 				iCurrentPkixChain = NULL;
       
   404 				}
       
   405 
       
   406 			if (chainIndex == iChains.Count())
       
   407 				{
       
   408 				if (iHasValidated)
       
   409 					{
       
   410 					//Build the certificate chain constraints
       
   411 					CCertChainConstraints* certChainConstraints(0);
       
   412 					TRAPD(err, certChainConstraints=CCertChainConstraints::NewL(iValidPkixChains));
       
   413 					if (err)
       
   414 						{
       
   415 						*iResult = ECertificateValidationError;
       
   416 						User::RequestComplete(iClientStatus, KErrNone);
       
   417 						return;
       
   418 						}
       
   419 					else
       
   420 						{
       
   421 						*iResult = iHasValidatedTrusted ? EValidationSucceeded : ESignatureSelfSigned;								
       
   422 						}
       
   423 
       
   424 					//Pass the certificate chain constraints ownership to controller
       
   425 					Sis::CController* controller=const_cast<Sis::CController*>(iController);
       
   426 					controller->SetCertChainConstraints(certChainConstraints);
       
   427 					
       
   428 					//Check if the device id is contrained and the device Id has been retrieved
       
   429 					if (certChainConstraints->DeviceIDsAreConstrained() && iDeviceIDs.Count()==0)
       
   430 						{
       
   431 				 		//Retrieve and Save the device ID list then complete
       
   432 				 		RDeviceInfo deviceInfo;
       
   433 				 		User::LeaveIfError(deviceInfo.Connect());
       
   434 				 		CleanupClosePushL(deviceInfo);
       
   435  						const RPointerArray<HBufC>& tempbuf=deviceInfo.DeviceIdsL();
       
   436 				 		for (TInt i=0;i<tempbuf.Count();i++)
       
   437 					 		{
       
   438 							HBufC* element=tempbuf[i]->AllocLC();
       
   439 			  				iDeviceIDs.AppendL(element);
       
   440 			  				CleanupStack::Pop(element);	 				
       
   441 					 		}
       
   442 					 	CleanupStack::PopAndDestroy(&deviceInfo);					
       
   443 						}						
       
   444 					iState = EChecksDone;
       
   445 					TRequestStatus* status = &iStatus;
       
   446 					User::RequestComplete(status, KErrNone);
       
   447 					SetActive();
       
   448 					return;
       
   449 					}
       
   450 
       
   451 				else
       
   452 					{
       
   453 					*iResult = ECertificateValidationError; // No chain ever validated 
       
   454 					}
       
   455 
       
   456 				User::RequestComplete(iClientStatus, KErrNone);							
       
   457 				}
       
   458 			else
       
   459 				{
       
   460 				VerifyBlockL(chainIndex);
       
   461 				return;					
       
   462 				}
       
   463 			}
       
   464 			break;
       
   465 
       
   466 		case EOCSPCheck:
       
   467 			{
       
   468 			iState = EChecksDone;
       
   469 			ProcessOcspOutcomesL();
       
   470 			
       
   471 			TRequestStatus* status = &iStatus;
       
   472 			User::RequestComplete(status, KErrNone);
       
   473 			SetActive();			
       
   474 			}
       
   475 			break;
       
   476 			
       
   477 		case EChecksDone:
       
   478 			{
       
   479 			// If the validation is done by certs passed by third party(API user)
       
   480 			// instead of cert-store then even on successful validation
       
   481 			// the result of validation is ESignatureSelfSigned. 
       
   482 			// But if iUntrustedRoots count is not zero then the result is
       
   483 			// really ESignatureSelfSigned.
       
   484 			if (NULL != iRootCerts && iHasValidated)
       
   485 				{
       
   486 				*iResult = EValidationSucceeded;
       
   487 				}
       
   488 			// Complete the client and be happy
       
   489 			User::RequestComplete(iClientStatus, KErrNone);			
       
   490 			}
       
   491 			break;
       
   492 			
       
   493 		default:
       
   494 			{
       
   495 			User::Panic(KSecurityManagerName, 1); 		
       
   496 			}
       
   497 		}
       
   498 	}
       
   499 
       
   500 
       
   501 void CSecurityManager::ProcessOcspOutcomesL() 
       
   502 	{
       
   503 	
       
   504 	 // Identify the worst outcome overall, and the worst in each chain.
       
   505  	// The OCSP outcomes are in the same order as the valid chains and
       
   506  	// certificates within them, with the number of outcomes per chain
       
   507  	// one fewer than the number of certs in the chain.
       
   508  
       
   509 
       
   510 	TInt numOutcomes=iRevocationHandler->TransactionCount();
       
   511 	TInt currentChain = 0;
       
   512  	TInt chainErrorLevel = 0;
       
   513  
       
   514  	// Since the number of outcomes is 1 fewer than the number of certs in the
       
   515  	// PkixChain, the index for the last outcome of the first chain will be
       
   516  	// 2 lower than the number of certs in the chain.
       
   517  	TInt chainLastOutcomeIndex = iValidPkixChains[0]->Count() - 2;
       
   518  	TInt chainWorstOutcome = 0;
       
   519  	
       
   520 	// This variable is used to record the most serious error condition.
       
   521 	TInt errorLevel = 0;
       
   522 
       
   523 	DEBUG_PRINTF2(_L8("Security Manager - OCSP check complete. %d OCSP outcomes."), numOutcomes);
       
   524 
       
   525 	for (TInt i=0; i<numOutcomes; i++)
       
   526 		{
       
   527 		const TOCSPOutcome& outcome=iRevocationHandler->Outcome(i);
       
   528 		
       
   529 		DEBUG_PRINTF4(_L8("Security Manager - OCSP outcome %d; Status: %d, Result: %d."),
       
   530 			i, outcome.iStatus, outcome.iResult);
       
   531 		
       
   532 		if (outcome.iResult == OCSP::ERevoked)
       
   533 			{
       
   534 			// If any certificate is revoked then installation must be aborted
       
   535  			// but we still want to identify the worst case for each chain for
       
   536  			// the purposes of the error dialog.
       
   537 
       
   538 			*iRevocationMessage = ECertificateStatusIsRevoked;
       
   539 			errorLevel = 6;
       
   540  			chainWorstOutcome = i;
       
   541  			
       
   542  			// Skip the rest of the outcomes for this chain.
       
   543  			i = chainLastOutcomeIndex;
       
   544 			}
       
   545 		else if (outcome.iResult != OCSP::EGood)
       
   546 			{			
       
   547 			switch (outcome.iStatus)			
       
   548 				{
       
   549 				// permanent errors, no user interaction is required
       
   550 				case OCSP::ENoServerSpecified:
       
   551 				case OCSP::EClientInternalError:
       
   552 				case OCSP::EMalformedRequest:
       
   553 				case OCSP::EUnknownResponseType:
       
   554 				case OCSP::EClientUnauthorised:
       
   555 				case OCSP::EUnknownCriticalExtension:
       
   556 				case OCSP::EMissingCertificates:
       
   557 				case OCSP::ESignatureRequired:				
       
   558 				case OCSP::EThisUpdateTooLate:
       
   559 				case OCSP::EThisUpdateTooEarly:
       
   560 				case OCSP::ENextUpdateTooEarly:
       
   561 				case OCSP::ECertificateNotValidAtValidationTime:				
       
   562 				case OCSP::ENonceMismatch:
       
   563 					if (errorLevel < 5)
       
   564 						{
       
   565 						errorLevel = 5;
       
   566 						*iRevocationMessage = EInvalidCertificateStatusInformation;
       
   567 						}
       
   568 					if (chainErrorLevel < 5)
       
   569  						{
       
   570  						chainErrorLevel = 5;
       
   571  						chainWorstOutcome = i;
       
   572  						}
       
   573 					break;
       
   574 				case OCSP::EResponseSignatureValidationFailure:
       
   575 					if (errorLevel < 4)
       
   576 						{
       
   577 						errorLevel = 4;
       
   578 						*iRevocationMessage = EResponseSignatureValidationFailure;			
       
   579 						}	
       
   580 					if (chainErrorLevel < 4)
       
   581  						{
       
   582  						chainErrorLevel = 4;
       
   583  						chainWorstOutcome = i;
       
   584 						}
       
   585 					break;
       
   586 				// permanent errors, ask the user	
       
   587 				case OCSP::EValid:
       
   588 					if (errorLevel < 3)
       
   589 						{
       
   590 						errorLevel = 3;
       
   591 						*iRevocationMessage = ECertificateStatusIsUnknown;
       
   592 						}	
       
   593 					if (chainErrorLevel < 3)
       
   594  						{
       
   595  						chainErrorLevel = 3;
       
   596  						chainWorstOutcome = i;
       
   597  						}
       
   598 					break;					
       
   599 				// transient errors - user can retry
       
   600 				case OCSP::EInvalidURI:					
       
   601 					if (errorLevel < 2)
       
   602 						{
       
   603 						errorLevel = 2;
       
   604 						*iRevocationMessage = EInvalidRevocationServerUrl;
       
   605 						}
       
   606 					if (chainErrorLevel < 2)
       
   607  						{
       
   608  						chainErrorLevel = 2;
       
   609  						chainWorstOutcome = i;
       
   610 						}
       
   611 					break;
       
   612 				case OCSP::ETryLater:
       
   613 				case OCSP::ETransportError:
       
   614 				case OCSP::EServerInternalError:
       
   615 				case OCSP::EMissingNonce:
       
   616 					if (errorLevel < 1)
       
   617 						{
       
   618 						errorLevel = 1;
       
   619 						*iRevocationMessage = EUnableToObtainCertificateStatus;
       
   620 						}	
       
   621  					if (chainErrorLevel < 1)
       
   622  						{
       
   623  						chainErrorLevel = 1;
       
   624  						chainWorstOutcome = i;
       
   625  						}
       
   626 
       
   627 					break;	
       
   628 				default:
       
   629 					// All possible OCSP responses should be checked
       
   630 					__ASSERT_ALWAYS(EFalse, User::Leave(KErrArgument));
       
   631 					break;
       
   632 				}	
       
   633 			}
       
   634 
       
   635  		// If this is the end of the chain, store the worst outcome for the
       
   636  		// chain in the output outcome array.
       
   637  		if (i == chainLastOutcomeIndex)
       
   638  			{
       
   639  			TOCSPOutcome* chainOutcome=new(ELeave) TOCSPOutcome(iRevocationHandler->Outcome(chainWorstOutcome));
       
   640  			CleanupStack::PushL(chainOutcome);
       
   641  			iOcspOutcomeOut->AppendL(chainOutcome);
       
   642  			CleanupStack::Pop(chainOutcome);
       
   643  
       
   644  			// If there are more chains to consider, get set to identify the
       
   645  			// worst outcome in the next chain.
       
   646  			if (++currentChain < iValidPkixChains.Count())
       
   647  				{
       
   648  				chainErrorLevel = 0;
       
   649  				chainWorstOutcome = i + 1;
       
   650  				chainLastOutcomeIndex += iValidPkixChains[currentChain]->Count() - 1;
       
   651  				}
       
   652  			}
       
   653 
       
   654 		}
       
   655 	}
       
   656 
       
   657 void CSecurityManager::DoCancel()
       
   658 	{
       
   659 	DEBUG_PRINTF2(_L8("Security Manager - Cancelling in state %d."), iState);
       
   660 	
       
   661 	switch (iState)
       
   662 		{
       
   663 		case ERetrievedTrustedRoots:
       
   664 			{
       
   665 			iCertificateRetriever->Cancel();
       
   666 			}
       
   667 			break;
       
   668 			
       
   669 		case EValidatingChain:
       
   670 		case ERevalidatingChain:
       
   671 			{
       
   672 			iChainValidator->Cancel();		
       
   673 			}
       
   674 			break;
       
   675 			
       
   676 		case EOCSPCheck:
       
   677 			{
       
   678 			iRevocationHandler->Cancel();
       
   679 			}
       
   680 			break;
       
   681 			
       
   682 		case EChecksDone:	
       
   683 		default: 
       
   684 			{
       
   685 			// Do nothing
       
   686 			}
       
   687 		}
       
   688 	if(iClientStatus)
       
   689 		{
       
   690 		User::RequestComplete(iClientStatus,KErrCancel);		
       
   691 		}
       
   692 	}
       
   693 
       
   694 TInt CSecurityManager::RunError(TInt aError)
       
   695 	{
       
   696 	DEBUG_PRINTF2(_L8("Security Manager - RunError(). Error code %d."), aError);
       
   697 	
       
   698 	User::RequestComplete(iClientStatus, aError);			
       
   699 	return KErrNone; 
       
   700 	}
       
   701 
       
   702 
       
   703 //
       
   704 // Business methods
       
   705 //
       
   706 
       
   707 EXPORT_C void CSecurityManager::PerformOcspL(const TDesC8& aOcspUri, 
       
   708 											 TUint32& aIap,
       
   709 											 TRevocationDialogMessage* aRevocationMessageOut, 
       
   710 											 RPointerArray<TOCSPOutcome>& aOcspOutcomeOut, 
       
   711 											 RPointerArray<CX509Certificate>& aCertOut,
       
   712 											 TRequestStatus& aStatus)
       
   713 	{	
       
   714 	Cancel();
       
   715 	
       
   716 	DEBUG_PRINTF2(_L8("Security Manager - Performing OCSP with revocation server at %S."),
       
   717 		&aOcspUri);
       
   718 
       
   719 	// Reset and re-populate certificate list to contain only end certificates
       
   720  	// from valid chains, so that the end cert list can be correlated with the
       
   721  	// list of outcomes.
       
   722  	aCertOut.ResetAndDestroy();
       
   723  	TInt numChains = iValidPkixChains.Count();
       
   724  	for (TInt index = 0; index < numChains; index++)
       
   725  		{
       
   726  		CX509Certificate* certOut = CX509Certificate::NewLC(iValidPkixChains[index]->Cert(0));
       
   727  		aCertOut.AppendL(certOut);
       
   728  		CleanupStack::Pop(certOut);
       
   729  		}
       
   730  		
       
   731  	DEBUG_PRINTF2(_L8("Security Manager - Validating %d certificate chains for this controller."), numChains);
       
   732 
       
   733 	iClientStatus = &aStatus;
       
   734 	*iClientStatus = KRequestPending;
       
   735 
       
   736 	iOcspOutcomeOut = &aOcspOutcomeOut;
       
   737 	iRevocationMessage = aRevocationMessageOut;
       
   738 	
       
   739 	// Make sure to delete earlier object
       
   740 	if (iRevocationHandler)
       
   741 		{
       
   742 		delete iRevocationHandler;
       
   743 		iRevocationHandler = NULL;
       
   744 		}	
       
   745 	iRevocationHandler = CRevocationHandler::NewL(*iCertStore);
       
   746 	iRevocationHandler->SetDefaultURIL(aOcspUri);
       
   747 	iState = EOCSPCheck;
       
   748 	
       
   749 	iRevocationHandler->SendRequestL(iValidPkixChains, aIap, iStatus);
       
   750 	
       
   751 	SetActive();
       
   752 	}
       
   753 
       
   754 EXPORT_C void CSecurityManager::VerifyControllerL(
       
   755 				TDesC8& aRawController,
       
   756 				const Sis::CController& aController, 
       
   757 				TSignatureValidationResult* aResultOut, 
       
   758 				RPointerArray<CPKIXValidationResultBase>& aPkixResultsOut,
       
   759 				RPointerArray<CX509Certificate>& aCertsOut,
       
   760 				TCapabilitySet* aCapabilitySetOut,
       
   761 				TBool& aAllowUnsigned,
       
   762 				TBool& aIsEmbeddedController,
       
   763 				TRequestStatus& aStatus,
       
   764 				TBool aCheckDateAndTime)
       
   765 	{
       
   766 	DEBUG_PRINTF(_L8("Security Manager - Validating Controller"));
       
   767 	
       
   768 	iResult = aResultOut;
       
   769 	iChains = aController.SignatureCertificateChains();	
       
   770 	iController = &aController;
       
   771 	iEndCertificatesOut = &aCertsOut;
       
   772 	iValidationResultsOut = &aPkixResultsOut;
       
   773 	iTotalCapabilitiesOut = aCapabilitySetOut;
       
   774 	iIsEmbeddedController = aIsEmbeddedController;
       
   775 	iCheckDateAndTime = aCheckDateAndTime;
       
   776 	
       
   777 	// Initialy assume that the chain is not validated
       
   778 	iHasValidated = EFalse;
       
   779 	iHasValidatedTrusted = EFalse;
       
   780 	
       
   781 	*iResult = ESignatureNotPresent;
       
   782 	aAllowUnsigned=iSecPolicy->AllowUnsigned();
       
   783 	
       
   784 	
       
   785 	iClientStatus = &aStatus;  // Store caller's request status
       
   786 	*iClientStatus = KRequestPending;
       
   787 		
       
   788 	if (iChains.Count() == 0)
       
   789 		{
       
   790 		User::RequestComplete(iClientStatus, KErrNone);	
       
   791 		return;	
       
   792 		}
       
   793 	
       
   794 	iRawController.Set(aRawController);
       
   795 	iCurrentChain = 0;
       
   796 	
       
   797 	// First retrieve all CA certificates
       
   798 
       
   799 	delete iCertificateRetriever;
       
   800 	iCertificateRetriever = NULL;
       
   801 	iCertificateRetriever = CCertificateRetriever::NewL(*iCertStore);
       
   802 	
       
   803 	delete iChainValidator;
       
   804 	iChainValidator = NULL;
       
   805 	iChainValidator = CChainValidator::NewL(*iCertStore, *iSecPolicy);
       
   806 	
       
   807 	iState = ERetrievedTrustedRoots;
       
   808 	SetActive();
       
   809 
       
   810 	// No need to fetch certificates from the certstore if the root certs
       
   811 	// are already provided by the caller. or
       
   812 	// The root Certificates already fetched from certstore in case of embedded packages
       
   813 
       
   814 	if(NULL == iRootCerts && iTrustedRoots.Count() == 0)
       
   815 		{
       
   816 		iCertificateRetriever->RetrieveCACertificates(
       
   817 			iTrustedRoots, iStatus);
       
   818 		}
       
   819 	else
       
   820 		{
       
   821 		TRequestStatus* tempStatus = &iStatus;
       
   822 		User::RequestComplete(tempStatus, KErrNone);
       
   823 		}
       
   824 	}
       
   825 	
       
   826 EXPORT_C void CSecurityManager::ReverifyControllerL(
       
   827 				TDesC8& aRawController,
       
   828 				const Sis::CController& aController, 
       
   829 				const RArray<TInt>& aChainListIndices,
       
   830 				TSignatureValidationResult* aResultOut, 
       
   831 				RPointerArray<CPKIXValidationResultBase>& aPkixResultsOut,
       
   832 				RPointerArray<CX509Certificate>& aCertsOut,
       
   833 				TCapabilitySet* aCapabilitySetOut,
       
   834 				TBool& aAllowUnsigned,
       
   835 				TRequestStatus& aStatus)
       
   836 	{
       
   837 	DEBUG_PRINTF(_L8("Security Manager - Re-Verifying Controller"));
       
   838 	
       
   839 	iResult = aResultOut;
       
   840 	iChains = aController.SignatureCertificateChains();	
       
   841 	iController = &aController;
       
   842 	iChainListIndices = &aChainListIndices;
       
   843 	iEndCertificatesOut = &aCertsOut;
       
   844 	iValidationResultsOut = &aPkixResultsOut;
       
   845 	iTotalCapabilitiesOut = aCapabilitySetOut;
       
   846 	iIsEmbeddedController = ETrue;
       
   847 	
       
   848 
       
   849 	*iResult = ESignatureNotPresent;
       
   850 	aAllowUnsigned = iSecPolicy->AllowUnsigned();
       
   851 	
       
   852 	iClientStatus = &aStatus;  // Store caller's request status
       
   853 	*iClientStatus = KRequestPending;
       
   854 		
       
   855 	if (iChains.Count() == 0)
       
   856 		{
       
   857 		// This is an unsigned SISX file
       
   858 		User::RequestComplete(iClientStatus, KErrNone);	
       
   859 		return;	
       
   860 		}
       
   861 	
       
   862 	iRawController.Set(aRawController);
       
   863     iCurrentChain = 0;
       
   864     
       
   865     delete iCertificateRetriever;
       
   866     iCertificateRetriever = NULL;
       
   867     iCertificateRetriever = CCertificateRetriever::NewL(*iCertStore);
       
   868     
       
   869     delete iChainValidator;
       
   870     iChainValidator = NULL;
       
   871 	iChainValidator = CChainValidator::NewL(*iCertStore, *iSecPolicy);
       
   872 
       
   873 	// We may have an unsigned sis file in which case we do not want to verify the block
       
   874 	// since there isn't one, so bail here with the correct error
       
   875 	if (iChains.Count() == 0)
       
   876 		{
       
   877 		User::RequestComplete(iClientStatus, KErrNone);							
       
   878 		}
       
   879 	else 
       
   880 		{
       
   881 		TInt currentChain = (*iChainListIndices)[iCurrentChain];
       
   882 		VerifyBlockL(currentChain);		
       
   883 		}	
       
   884 	}
       
   885 		
       
   886 TInt CSecurityManager::SignedSize(TInt iChainsToAdd) const
       
   887 	{
       
   888 	TInt64 size = 0;
       
   889 
       
   890 	const Sis::CInfo& info = iController->Info();	
       
   891 	size += info.Length() + info.HeaderSize() + info.PaddingSize();
       
   892 
       
   893 	const Sis::CSupportedOptions& options = iController->SupportedOptions();
       
   894 	size += options.Length() + options.HeaderSize() + options.PaddingSize();
       
   895 
       
   896 	const Sis::CSupportedLanguages& languages = iController->SupportedLanguages();
       
   897 	size += languages.Length() + languages.HeaderSize() + languages.PaddingSize();
       
   898 
       
   899 	const Sis::CPrerequisites& prerequisites = iController->Prerequisites();
       
   900 	size += prerequisites.Length() + prerequisites.HeaderSize() + prerequisites.PaddingSize();
       
   901 
       
   902 	const Sis::CProperties& props = iController->Properties();
       
   903 	size += props.Length() + props.HeaderSize() + props.PaddingSize();
       
   904 
       
   905 	const Sis::CLogo* logo = iController->Logo();
       
   906 	if (logo != NULL)
       
   907 		{
       
   908 		size += logo->Length() + logo->HeaderSize() + logo->PaddingSize();		
       
   909 		}
       
   910 		
       
   911 	const Sis::CInstallBlock& installblock = iController->InstallBlock();
       
   912 	size += installblock.Length() + installblock.HeaderSize() + installblock.PaddingSize();
       
   913 
       
   914 	for (TInt k = 0; k < iChainsToAdd; k++)
       
   915 		{
       
   916 		size += iChains[k]->Length() + iChains[k]->HeaderSize() + iChains[k]->PaddingSize();
       
   917 		}
       
   918 
       
   919 	return I64INT(size);	
       
   920 	}
       
   921 
       
   922 void CSecurityManager::VerifyBlockL(TInt aChainIndex)
       
   923 	{		
       
   924 	DEBUG_PRINTF2(_L8("Security Manager - Validating certificate chain %d."), aChainIndex);
       
   925 
       
   926 	Sis::CSignatureCertificateChain& chain = *iChains[aChainIndex];	
       
   927 	
       
   928 	// First verify the signature
       
   929 	const RPointerArray<Sis::CSignature> signatures = chain.Signatures();
       
   930 	
       
   931 	// Determine the size of the controller data which was signed
       
   932 	TInt size = SignedSize(aChainIndex);
       
   933 
       
   934 	const Sis::CCertificateChain& certChain = chain.CertificateChain();
       
   935 	const TPtrC8 data = certChain.Data();
       
   936 	
       
   937 	TInt pos = 0;
       
   938 	TInt end = data.Length();
       
   939 	iUntrustedRoots.ResetAndDestroy();
       
   940 	
       
   941 	// Find all the self-signed certificates in the chain as possible root candidates
       
   942 	
       
   943 	while (pos < end)
       
   944 		{
       
   945 		CX509Certificate* decoded = CX509Certificate::NewLC(data, pos);
       
   946 		if (decoded->IsSelfSignedL())
       
   947 			{
       
   948 			// If the root isn't in the trusted list, append it to the untrusted roots
       
   949 			TBool found = EFalse;
       
   950 			if(NULL == iRootCerts)
       
   951 				{
       
   952 				for (TInt i = 0; i < iTrustedRoots.Count(); i++)
       
   953 					{
       
   954 					CCTCertInfo* root = iTrustedRoots[i];
       
   955 					if (root->SubjectKeyId() == decoded->KeyIdentifierL()) 
       
   956 						{
       
   957 						found = ETrue;
       
   958 						break;
       
   959 						}
       
   960 					}
       
   961 				}
       
   962 			else
       
   963 				{
       
   964 				for (TInt i = iRootCerts->Count() - 1; i >= 0; --i)
       
   965 					{
       
   966 					CX509Certificate* root = (*iRootCerts)[i];
       
   967 					if (root->KeyIdentifierL() == decoded->KeyIdentifierL()) 
       
   968 						{
       
   969 						found = ETrue;
       
   970 						break;
       
   971 						}
       
   972 					}
       
   973 				}
       
   974 			
       
   975 			if (!found)
       
   976 				{
       
   977 				iUntrustedRoots.AppendL(decoded);
       
   978 				CleanupStack::Pop(decoded);
       
   979 				}
       
   980 			else
       
   981 				{
       
   982 				CleanupStack::PopAndDestroy(decoded);	
       
   983 				}
       
   984 			}
       
   985 		else
       
   986 			{
       
   987 			CleanupStack::PopAndDestroy(decoded);
       
   988 			}	
       
   989 		}
       
   990 	
       
   991 	DEBUG_PRINTF2(_L8("Security Manager - Found %d non-trusted candidate root certificates"), iUntrustedRoots.Count());
       
   992 		
       
   993 	// If we have self signed roots, don't look in the certstore for a further root
       
   994 	
       
   995 	TBool hasUntrustedRoot = (iUntrustedRoots.Count() > 0);
       
   996 	
       
   997 	if (NULL != iRootCerts)
       
   998 		{
       
   999 		DEBUG_PRINTF(_L8("Security Manager - Validating chain using user provided roots"));
       
  1000 		iCurrentPkixChain = CPKIXCertChainBase::NewL(*iCertStore, data, *iRootCerts);
       
  1001 		hasUntrustedRoot = ETrue; // These root certs are considered untrusted.
       
  1002 		}
       
  1003 	else if(hasUntrustedRoot)
       
  1004 		{
       
  1005 		DEBUG_PRINTF(_L8("Security Manager - Validating chain using untrusted roots"));
       
  1006 		iCurrentPkixChain = CPKIXCertChainBase::NewL(*iCertStore, data, iUntrustedRoots);
       
  1007 		}
       
  1008 	else
       
  1009 		{
       
  1010 		DEBUG_PRINTF(_L8("Security Manager - Validating chain using trusted roots from store"));
       
  1011 		iCurrentPkixChain = CPKIXCertChainBase::NewL(*iCertStore, data, KSwiApplicabilityUid);	
       
  1012 		}
       
  1013 	
       
  1014 
       
  1015 	DEBUG_PRINTF2(_L8("Security Manager - Certificate chain contains %d certificates."), iCurrentPkixChain->Count());
       
  1016 
       
  1017 	const CX509Certificate& clientCert = iCurrentPkixChain->Cert(0); // This is the ee certificate
       
  1018 	CX509Certificate* endCertOut = CX509Certificate::NewLC(clientCert);
       
  1019 	iEndCertificatesOut->AppendL(endCertOut);
       
  1020 	CleanupStack::Pop(endCertOut);
       
  1021 	
       
  1022 	DEBUG_CODE_SECTION(HBufC* issuer = clientCert.IssuerL(); DEBUG_PRINTF2(_L("Security Manager - End Entity Certificate Issuer: '%S'."), issuer); delete issuer;);
       
  1023 	DEBUG_CODE_SECTION(HBufC* subject = clientCert.SubjectL(); DEBUG_PRINTF2(_L("Security Manager - End Entity Certificate Subject: '%S'."), subject); delete subject;);
       
  1024 	
       
  1025 	const CSubjectPublicKeyInfo& publicKey=  clientCert.PublicKey();
       
  1026 	
       
  1027 	DEBUG_PRINTF2(_L8("Security Manager - SIS file signed %d times with this certificate."), signatures.Count());
       
  1028 	
       
  1029 	CSignatureVerifier* verifier = CSignatureVerifier::NewLC();
       
  1030 	TBool result = EFalse;
       
  1031 	for (TInt k = 0; k < signatures.Count(); k++)
       
  1032 		{
       
  1033 		const TDesC& algorithmOID = signatures[k]->Algorithm().AlgorithmIdentifier().Data();
       
  1034 		TRAP_IGNORE(result = verifier->VerifySignatureL(algorithmOID, publicKey, iRawController.Mid((iIsEmbeddedController ? 4 : iController->HeaderSize()), size), signatures[k]->Data()));
       
  1035 		if (result) 
       
  1036  			{
       
  1037 			// We have a verify any policy on signatures (inside a given SISSignatureCertificateChain)
       
  1038 			// Cf. SGL.GT0188.251 Section 4.3
       
  1039 			break;   
       
  1040 			}
       
  1041 		}
       
  1042 
       
  1043 	CleanupStack::PopAndDestroy(verifier);
       
  1044 
       
  1045 	if (!result) // Signature not verified: something is WRONG. Abort.
       
  1046 		{
       
  1047 		DEBUG_PRINTF(_L8("Security Manager - No signature validated."));
       
  1048 		
       
  1049 		*iResult = ESignatureCouldNotBeValidated;
       
  1050 		User::RequestComplete(iClientStatus, KErrNone);	
       
  1051 		return;			
       
  1052 		}
       
  1053 			
       
  1054 	// The signature is good, validate the certificate chain
       
  1055 	
       
  1056 	CPKIXValidationResultBase* validationResult = CPKIXValidationResultBase::NewLC();
       
  1057 	iValidationResultsOut->Append(validationResult);
       
  1058 	CleanupStack::Pop(validationResult);
       
  1059 	
       
  1060 	iState = EValidatingChain;
       
  1061 	iCurrentPkixChain->SetValidityPeriodCheckFatal(iCheckDateAndTime);
       
  1062 	iChainValidator->ValidateChainL(*iCurrentPkixChain, *iResult, *validationResult, 
       
  1063 									iCurrentCapabilities, hasUntrustedRoot, iStatus);
       
  1064 	SetActive();	
       
  1065 	}
       
  1066 
       
  1067 EXPORT_C HBufC8* CSecurityManager::CalculateHashLC(MSisDataProvider& aDataProvider, CMessageDigest::THashId aAlgorithm)
       
  1068 	{
       
  1069 	CMessageDigest* digest = CMessageDigestFactory::NewDigestLC(aAlgorithm);
       
  1070 		
       
  1071 	HBufC8* aBuffer = HBufC8::NewMaxLC(KFileBufferSize); 
       
  1072 	TPtr8 aBufferPtr(aBuffer->Des());
       
  1073 
       
  1074 	User::LeaveIfError(aDataProvider.Read(aBufferPtr));
       
  1075 
       
  1076 	while (aBuffer->Length() != 0)
       
  1077 		{
       
  1078 		digest->Update(*aBuffer);
       
  1079 		User::LeaveIfError(aDataProvider.Read(aBufferPtr));		
       
  1080 		}
       
  1081 	TPtrC8 hash = digest->Final();
       
  1082 	HBufC8* hashBuffer = hash.AllocL();
       
  1083 	CleanupStack::PopAndDestroy(2, digest); // aBuffer, digest
       
  1084 	
       
  1085 	CleanupStack::PushL(hashBuffer);
       
  1086 	return hashBuffer;
       
  1087 	}
       
  1088 
       
  1089 EXPORT_C TBool CSecurityManager::VerifyFileHashL(MSisDataProvider& aDataProvider, const CHashContainer& aDigest)
       
  1090 	{
       
  1091 	HBufC8* hashBuffer = CalculateHashLC(aDataProvider, aDigest.Algorithm());
       
  1092 
       
  1093 	TBool result = EFalse;
       
  1094 
       
  1095 	TPtrC8 hash = hashBuffer->Des();
       
  1096 	if (hash.Compare(aDigest.Data()) == 0)
       
  1097 		{
       
  1098 		result = ETrue;
       
  1099 		}
       
  1100 
       
  1101 	CleanupStack::PopAndDestroy(hashBuffer);
       
  1102 	return result;
       
  1103 	}
       
  1104 	
       
  1105 void CSecurityManager::UpdateListOfMissingRequiredCertsL(const CCertificate& aCertificate) 
       
  1106 	{
       
  1107 	// Find aCertificate in iTrustedRoots and marked as nonmandatory for temporary!
       
  1108 	TInt count = iTrustedRoots.Count();
       
  1109 	for (TInt k = 0; k < count; k++)
       
  1110 		{
       
  1111 		CCTCertInfo* certInfo = iTrustedRoots[k];
       
  1112 		if (iCertMetaInfo[k].iIsMandatory && !certInfo->SubjectKeyId().Compare(aCertificate.KeyIdentifierL()))
       
  1113 			{
       
  1114 			DEBUG_PRINTF2(_L("Security Manager - Mandatory certificate '%S' satisfied."), &(certInfo->Label()));
       
  1115 			// set the Mandatory is false so that next time this certificate won't be compared
       
  1116 			iCertMetaInfo[k].iIsMandatory = 0;
       
  1117 			iMandatoryCertDNCount--;
       
  1118 			break;
       
  1119 			}
       
  1120 		}
       
  1121 	}
       
  1122 
       
  1123 void CSecurityManager::UpdateSystemUpgradeCertStatusL(const CCertificate& aCertificate)
       
  1124 	{	
       
  1125 	// Find aCertificate in iTrustedRoots and update the system upgrade trust status
       
  1126 	TInt count = iTrustedRoots.Count();
       
  1127 	for (TInt k = 0; k < count; k++)
       
  1128 		{
       
  1129 		CCTCertInfo* certInfo = iTrustedRoots[k];
       
  1130 		if (iCertMetaInfo[k].iIsSystemUpgrade && certInfo->SubjectKeyId() == aCertificate.KeyIdentifierL())
       
  1131 			{
       
  1132 			DEBUG_PRINTF2(_L("Security Manager - System upgrade certificate '%S' satisfied."), &(certInfo->Label()));
       
  1133 			// create a modifyable reference to the current controller
       
  1134 			Sis::CController& controller = const_cast <Sis::CController&>(*iController);
       
  1135 			// set the SuCert validation status
       
  1136 			controller.SetSignedBySuCert(ETrue);
       
  1137 			break;
       
  1138 			}
       
  1139 		}
       
  1140 	
       
  1141 	}
       
  1142 
       
  1143 EXPORT_C void CSecurityManager::GetCertificatesFromControllerL(
       
  1144 	const Sis::CController& aController,
       
  1145 	RPointerArray<CX509Certificate>& aCerts)
       
  1146 	{
       
  1147 	// Go through all SIS chains and extract end certificates from them.
       
  1148 	const RPointerArray<Sis::CSignatureCertificateChain>& chains=
       
  1149 		aController.SignatureCertificateChains();
       
  1150 	for (TInt i=0; i<chains.Count(); i++)
       
  1151 		{
       
  1152 		Sis::CSignatureCertificateChain& sigCertChain=*chains[i];
       
  1153 		const Sis::CCertificateChain& certChain=
       
  1154 			sigCertChain.CertificateChain();
       
  1155 		// Construct PKIX cert chain from raw data in the controller.
       
  1156 		CPKIXCertChainBase* pkixChain=CPKIXCertChainBase::NewLC(*iCertStore,
       
  1157 			certChain.Data(), KSwiApplicabilityUid);
       
  1158 		
       
  1159 		// Extract end entity certificate and store it in the member array.
       
  1160 		const CX509Certificate& endCert=pkixChain->Cert(0);
       
  1161 		CX509Certificate* endCertCopy=CX509Certificate::NewLC(endCert);
       
  1162 		User::LeaveIfError(aCerts.Append(endCertCopy));
       
  1163 		CleanupStack::Pop(endCertCopy);
       
  1164 		
       
  1165 		// Cleanup.
       
  1166 		CleanupStack::PopAndDestroy(pkixChain);
       
  1167 		}
       
  1168 	}
       
  1169 
       
  1170 EXPORT_C void CSecurityManager::FillCertInfoArrayL(
       
  1171 	const RPointerArray<CX509Certificate>& aCertificates,
       
  1172 	RPointerArray<CCertificateInfo>& aCertInfos)
       
  1173 	{
       
  1174 	for (TInt i=0; i<aCertificates.Count(); i++)
       
  1175 		{
       
  1176 		CCertificateInfo* certInfo=CCertificateInfo::NewLC(*aCertificates[i]);
       
  1177 		aCertInfos.AppendL(certInfo);
       
  1178 		CleanupStack::Pop(certInfo);
       
  1179 		}
       
  1180 	}
       
  1181 
       
  1182 EXPORT_C const RPointerArray<HBufC>& CSecurityManager::DeviceIDsInfo() const
       
  1183  	{
       
  1184  	return iDeviceIDs;
       
  1185  	}
       
  1186 
       
  1187 EXPORT_C void CSecurityManager::ResetValidCertChains() 
       
  1188 	{
       
  1189 	iValidPkixChains.ResetAndDestroy();
       
  1190 	}
       
  1191 	
       
  1192 EXPORT_C void CSecurityManager::SetDevCertWarningState(TInt aDevCertWarningState)
       
  1193 	{
       
  1194 	iDevCertWarningState=static_cast<TDevCertWarningState>(aDevCertWarningState);	
       
  1195 	}
       
  1196 
       
  1197 EXPORT_C TInt CSecurityManager::GetDevCertWarningState()
       
  1198 	{
       
  1199 	return iDevCertWarningState;
       
  1200 	}
       
  1201 
       
  1202 
       
  1203 EXPORT_C void CSecurityManager::SetRootCerts(RPointerArray<CX509Certificate>* aX509CertArray)
       
  1204 	{
       
  1205 	iRootCerts = aX509CertArray;
       
  1206 	}
       
  1207 
       
  1208 	
       
  1209 	
       
  1210 
       
  1211 
       
  1212