installationservices/swi/source/sisregistry/server/sisrevocationmanager.cpp
changeset 0 ba25891c3a9e
child 25 98b66e4fb0be
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     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 /**
       
    20  @file 
       
    21  @released
       
    22  @internalTechnology
       
    23 */
       
    24 
       
    25 #include "log.h"
       
    26 
       
    27 #include "securitymanager.h"
       
    28 #include "sistruststatus.h"
       
    29 #include "sisrevocationmanager.h"
       
    30 #include "sisregistryserversession.h"
       
    31 #include "sisinfo.h"
       
    32 #include "sisuid.h"
       
    33 #include "swi/msisuihandlers.h"
       
    34 
       
    35 _LIT(KMyModuleName, "_SISREVOCATION_MANAGER_");
       
    36 
       
    37 using namespace Swi;
       
    38 
       
    39 //
       
    40 // Life Cycle methods
       
    41 //
       
    42 
       
    43 EXPORT_C CSisRevocationManager* CSisRevocationManager::NewL(CSisRegistrySession& aSession)
       
    44 	{
       
    45 	CSisRevocationManager* self = CSisRevocationManager::NewLC(aSession);
       
    46 	CleanupStack::Pop(self);
       
    47 	return self;
       
    48 	}
       
    49  
       
    50 EXPORT_C CSisRevocationManager* CSisRevocationManager::NewLC(CSisRegistrySession& aSession)
       
    51 	{
       
    52 	CSisRevocationManager* self = new(ELeave) CSisRevocationManager(aSession);
       
    53 	CleanupStack::PushL(self);
       
    54 	return self;
       
    55 	}
       
    56 
       
    57 CSisRevocationManager::CSisRevocationManager(CSisRegistrySession& aSession) : 
       
    58     CActive(EPriorityNormal),
       
    59     iSession(&aSession)
       
    60 	{
       
    61 	CActiveScheduler::Add(this);	
       
    62 	}
       
    63 
       
    64 CSisRevocationManager::~CSisRevocationManager()
       
    65 	{
       
    66 	// Remove active object from active scheduler
       
    67 	Deque(); 
       
    68 	Cleanup();
       
    69 	}
       
    70 	
       
    71 //
       
    72 // Active Objects methods
       
    73 //
       
    74 
       
    75 void CSisRevocationManager::RunL()
       
    76 	{
       
    77 	DEBUG_PRINTF2(_L8("Sis Registry Server - CSisrevocationManager::RunL (State: %d.)"), iState);
       
    78 	
       
    79 	if (iStatus.Int() != KErrNone)
       
    80 		{
       
    81 		User::Leave(iStatus.Int());     // Hop into RunError()
       
    82 		}
       
    83 		
       
    84 	switch (iState)
       
    85 		{ 			
       
    86 		case EVerifyChains:
       
    87 			VerifcationRequestL();
       
    88 			break;
       
    89 			
       
    90 		case ERevocationCheck:
       
    91 			{
       
    92 			switch (iSignatureValidationResult)
       
    93 				{
       
    94 				case EValidationSucceeded:
       
    95 					PerformOcspRequestL();	
       
    96 					break;
       
    97 				default:
       
    98 					iState = ERevocationComplete;
       
    99 					// Self complete
       
   100 					TRequestStatus* status  = &iStatus;
       
   101 					User::RequestComplete(status, KErrNone);
       
   102 					SetActive();
       
   103 					break;
       
   104 				}	
       
   105 			}
       
   106 
       
   107 			break;
       
   108 			
       
   109 		case ERevocationComplete:
       
   110 			{
       
   111 			SetTrustStatusL();	
       
   112 			
       
   113 			// Complete the client
       
   114 			iMessage.Complete(KErrNone);	
       
   115             Cleanup();	
       
   116 			}
       
   117 			break;
       
   118 			
       
   119 		default:
       
   120 			{
       
   121 			User::Panic(KMyModuleName, 1); 		
       
   122 			}
       
   123 		}
       
   124 	}
       
   125 
       
   126 void CSisRevocationManager::DoCancel()
       
   127 	{
       
   128 	DEBUG_PRINTF(_L8("Sis Registry Server - Cancelling Revocation Manager"));
       
   129 	
       
   130 	if (iSecurityManager)
       
   131 	    {
       
   132 		iSecurityManager->Cancel();
       
   133 		}
       
   134 	if (iState != EIdle)
       
   135 	    {
       
   136 	    iMessage.Complete(KErrCancel);
       
   137 	    iState = EIdle;	
       
   138 	    }
       
   139 	}
       
   140 
       
   141 TInt CSisRevocationManager::RunError(TInt aError)
       
   142 	{
       
   143 	DEBUG_PRINTF2(_L8("Sis Registry Server - Revocation Manager Failed with error code %d."), aError);
       
   144 	
       
   145 	iMessage.Complete(aError);	
       
   146 	Cleanup();
       
   147 	return KErrNone; 
       
   148 	}
       
   149 
       
   150 //
       
   151 // Business methods
       
   152 //	
       
   153 EXPORT_C void CSisRevocationManager::RevocationStatusRequestL(
       
   154 														HBufC8* aRawController,
       
   155                                                         const Sis::CController* aController,
       
   156                                                         TSisTrustStatus& aTrustStatus,
       
   157                                                         const RArray<TInt>& aCertChainIndices, 
       
   158 													    const TDesC8& aOcspUri,
       
   159 														const RMessage2& aMessage)
       
   160 	{
       
   161 	__ASSERT_ALWAYS(!IsActive(), User::Panic(KMyModuleName, KErrInUse));
       
   162 	ASSERT(EIdle == iState);
       
   163 	
       
   164 	iStatus = KRequestPending;
       
   165 	iRawController = aRawController;
       
   166 	iController = aController;
       
   167 	iChains = aController->SignatureCertificateChains();	
       
   168 	iSecurityManager = CSecurityManager::NewL();	
       
   169 	
       
   170 	// Store caller's request status
       
   171 	iMessage = aMessage;
       
   172 
       
   173 	iState = EVerifyChains;
       
   174 		
       
   175 	iTrustStatus = aTrustStatus;
       
   176 	
       
   177 	iOcspUri = aOcspUri.AllocL();
       
   178 
       
   179 	// Make a copy of the cert chain indicies array
       
   180 	TInt count = aCertChainIndices.Count();
       
   181 	for (TInt index = 0; index < count; ++index)
       
   182 		{
       
   183 		iCertChainIndices.AppendL(aCertChainIndices[index]);
       
   184 		}
       
   185 	
       
   186 	// Self complete
       
   187 	TRequestStatus* status  = &iStatus;
       
   188 	User::RequestComplete(status, KErrNone);
       
   189 
       
   190 	SetActive();
       
   191 	}
       
   192 
       
   193 void CSisRevocationManager::VerifcationRequestL()
       
   194 	{
       
   195 	ASSERT(EVerifyChains == iState);
       
   196 	
       
   197 	// Get current controller data.
       
   198 	TPtrC8 data(iRawController->Mid(iController->DataOffset()));
       
   199 
       
   200 	iSecurityManager->ReverifyControllerL(data,
       
   201 										  *iController,
       
   202 										  iCertChainIndices,
       
   203 										  &iSignatureValidationResult,
       
   204 										  iValidationResultsOut,
       
   205 										  iEndCertificates,
       
   206 										  &iCapabilitySet,
       
   207 										  iAllowUnsigned,
       
   208 										  iStatus);	
       
   209 	
       
   210 	iState = ERevocationCheck;
       
   211 	SetActive();
       
   212 	}
       
   213 
       
   214 void CSisRevocationManager::PerformOcspRequestL()
       
   215 	{
       
   216 	iIap = 0;
       
   217 	iSecurityManager->PerformOcspL(iOcspUri->Des(),
       
   218 								   iIap,
       
   219 								   &iOcspMsg,
       
   220 								   iOcspOutcomeOut,
       
   221 								   iEndCertificates,
       
   222 								   iStatus);
       
   223 	iState = ERevocationComplete;
       
   224 	SetActive();
       
   225 	}
       
   226 	
       
   227 void CSisRevocationManager::SetTrustStatusL()
       
   228 	{		
       
   229 	TBool validated = EFalse;
       
   230 	
       
   231 	TValidationStatus validationStatus = EUnknown;
       
   232 	
       
   233 	switch (iSignatureValidationResult)
       
   234 		{	
       
   235 		case EValidationSucceeded:
       
   236 			validated = ETrue;
       
   237 			validationStatus = EValidatedToAnchor;
       
   238 			break;
       
   239 			
       
   240 		case ESignatureSelfSigned:
       
   241 			validated = ETrue;
       
   242 			validationStatus = EValidated;			
       
   243 			break;		
       
   244 
       
   245 		case ESignatureNotPresent:
       
   246 			validationStatus = EUnsigned;
       
   247 			break;	
       
   248 			
       
   249         case ECertificateValidationError:
       
   250 		case ENoCertificate:
       
   251 		case ENoCodeSigningExtension:
       
   252 		case ENoSupportedPolicyExtension:
       
   253 		case ESignatureCouldNotBeValidated:
       
   254 		case EMandatorySignatureMissing:
       
   255             validationStatus = EInvalid;
       
   256 			break;
       
   257 		default:
       
   258 			// BC break, unknown validation code, abort
       
   259 			User::Leave(KErrNotSupported);
       
   260 			break;			
       
   261 		}
       
   262 		
       
   263 	TRevocationStatus revocationStatus = EUnknown2;
       
   264 		
       
   265 	if (validated)
       
   266 		{
       
   267 	
       
   268 		for (TInt index = 0; index < iOcspOutcomeOut.Count(); index++)
       
   269 			{
       
   270 			if (iOcspOutcomeOut[index]->iResult == OCSP::EUnknown)
       
   271 				{	
       
   272 				switch (iOcspOutcomeOut[index]->iStatus)	
       
   273 					{	
       
   274 					case OCSP::ETransportError:
       
   275 					case OCSP::EInvalidURI:
       
   276 					case OCSP::EServerInternalError:
       
   277 					case OCSP::ETryLater:
       
   278 					case OCSP::EMissingCertificates:
       
   279 					case OCSP::EResponseSignatureValidationFailure:
       
   280 						// Possibly transient error, may retry.
       
   281 						revocationStatus = EOcspTransient;
       
   282 						break;
       
   283 		
       
   284 					case OCSP::EClientInternalError:
       
   285 					case OCSP::ENoServerSpecified:
       
   286 					case OCSP::EMalformedResponse:
       
   287 					case OCSP::EUnknownResponseType:
       
   288 					case OCSP::EUnknownCriticalExtension:
       
   289 					case OCSP::ESignatureRequired:
       
   290 					case OCSP::EClientUnauthorised:
       
   291 					case OCSP::EThisUpdateTooLate:
       
   292 					case OCSP::EThisUpdateTooEarly:
       
   293 					case OCSP::ENextUpdateTooEarly:
       
   294 					case OCSP::ECertificateNotValidAtValidationTime:
       
   295 					case OCSP::ENonceMismatch:	
       
   296 					case OCSP::EMissingNonce:		
       
   297 					case OCSP::EMalformedRequest:
       
   298 						// This is a permanent error, unable to retry.
       
   299 						revocationStatus = EOcspUnknown;
       
   300 						break;
       
   301 		
       
   302 					case OCSP::EValid:
       
   303                         revocationStatus = EOcspUnknown;
       
   304 						break;
       
   305 
       
   306 						// not a valid status for this state
       
   307 					default:
       
   308 						// Unknown value, must be a BC break!
       
   309 						User::Leave(KErrNotSupported);
       
   310 						break;			
       
   311 					}	
       
   312 					
       
   313 				break;
       
   314 				}
       
   315 			else if (iOcspOutcomeOut[index]->iResult == OCSP::ERevoked)
       
   316 				{
       
   317 				revocationStatus = EOcspRevoked;
       
   318 				break;		
       
   319 				}
       
   320 			else 
       
   321 				{
       
   322 				// OCSP of chain is good
       
   323 				revocationStatus = EOcspGood;
       
   324 				}	
       
   325 			}
       
   326 		}
       
   327 	else // not validated
       
   328 		{	
       
   329 		revocationStatus = EOcspNotPerformed;
       
   330 		}	
       
   331 
       
   332 	
       
   333 	// set trust status		
       
   334 	TTime time;
       
   335 	time.UniversalTime();
       
   336 	iTrustStatus.SetLastCheckDate(time);
       
   337 	
       
   338 	iTrustStatus.SetValidationStatus(validationStatus);		
       
   339 	iTrustStatus.SetRevocationStatus(revocationStatus);
       
   340 	if (validated 
       
   341 	    && (revocationStatus == EOcspGood 
       
   342 	        || revocationStatus == EOcspUnknown 
       
   343 	        || revocationStatus == EOcspRevoked ))
       
   344 		{
       
   345 		iTrustStatus.SetResultDate(iTrustStatus.LastCheckDate());
       
   346 		}
       
   347 
       
   348 	iSession->UpdateTrustStatusL(iController->Info().Uid().Uid(),
       
   349 	                            iTrustStatus);
       
   350 	}
       
   351 
       
   352 void CSisRevocationManager::Cleanup()
       
   353 	{
       
   354     iState = EIdle;
       
   355 	
       
   356     delete iController;
       
   357 	iController = 0;
       
   358 	
       
   359     delete iRawController;
       
   360 	iRawController = 0;
       
   361         
       
   362 	iEndCertificates.ResetAndDestroy();			
       
   363     
       
   364     iOcspOutcomeOut.ResetAndDestroy();
       
   365     
       
   366     iValidationResultsOut.ResetAndDestroy();	
       
   367 
       
   368     iCertChainIndices.Close();
       
   369 
       
   370     delete iOcspUri;
       
   371     iOcspUri = 0;
       
   372 
       
   373     delete iSecurityManager;
       
   374 	iSecurityManager = 0;
       
   375 	}