diff -r 000000000000 -r 2c201484c85f cryptomgmtlibs/securitydocs/ocsp.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cryptomgmtlibs/securitydocs/ocsp.txt Wed Jul 08 11:25:26 2009 +0100 @@ -0,0 +1,176 @@ +How to use OSCP +=============== + +Note: The actual code snippets are indented. + +Include ocsp.h in your header file. + + #include + +Link your project with ocsp.lib: add the following string to your project's .mmp +file: + + LIBRARY ocsp.lib + +Add the following to your class declaration, which should be derived from +CActive: + + COcspClient* iOcspClient; + +You will need to know revocation server URI. It is possible to get it from +installer preferences. Most Software Install components accept the URI as a +construction parameter. This is because they are started by the UI which stores +preferences in its resource file. If you want to retrieve it yourself, you can +use the following code (taken from InstallEngineImpl.cpp): + + // Open instapp's ini file + static CDictionaryStore* OpenIniFileLC(RFs& aFs) + { + CApaAppFinder* appFinder=CApaScanningAppFinder::NewL(aFs); + CleanupStack::PushL(appFinder); + TUid instAppUid={KUidInstallAppValue}; + TFileName libName=appFinder->FindAppL(KInstallAppName,instAppUid); + CleanupStack::PopAndDestroy(appFinder); + TParse parser; + User::LeaveIfError(parser.SetNoWild(KIniFileExtension,&KInstAppDriveC(), + &libName)); + aFs.MkDirAll(parser.FullName()); // ignore the error + CDictionaryFileStore* dict = CDictionaryFileStore::OpenLC(aFs, + parser.FullName(),instAppUid); + return dict; + } + + // get preferences from ini file + { + RFs fs; + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + CDictionaryStore* iniFile=OpenIniFileLC(fs); // see above + User::LeaveIfNull(iniFile); + RDictionaryReadStream readStream; + readStream.OpenLC(*iniFile,KUidInstallPrefs); + TInstallPrefs prefs; // this is what you need + TRAPD(ret,readStream >> prefs); // will return KErrEof first time + CleanupStack::PopAndDestroy(2); //readStream, iniFile + CleanupStack::Pop(); // fs + fs.Close(); + } + +If at any time you want to cancel OCSP check, call + + iOcspClient->CancelCheck(); + +When ready to perform the check (the certificate chain is built), use the +following code as a template (from JavaInstallerSecurityManager.cpp): + + COCSPParameters* params = COCSPParameters::NewLC(); + params->SetURIL(*iOCSPServerURI, ETrue); + params->AddCertificatesL(*iCertChain); + + // Set up authorisation scheme - we've a special UID registered with the + // certStore for the appropriate certificates + COCSPDirectAuthorisationScheme* scheme = + COCSPDirectAuthorisationScheme::NewLC( + TUid::Uid(KCertStoreUIDForSWInstallOCSPSigning)); + params->AddAuthorisationSchemeL(scheme); + CleanupStack::Pop(scheme); + + // Won't set validation time - this uses the response producedAt time + // instead. This avoids us relying on an accurate time in the device. + // Caching of old responses avoided by use of the nonce. + + iOcspClient = COcspClient::NewL(params); + CleanupStack::Pop(params); + iOcspClient->Check(iStatus); + +When the request completes and your class's RunL() is called, use the following +function template to process the result: + + TBool accept = ETrue; + switch (iStatus.Int()) + { + case OCSP::KErrNoCertificates: + // No certs in OCSP request - no proper cert chain formed. + // Covered by check digital sig logic already, so we let it pass. + break; + case KErrNone: + { + // Check the outcome of every transaction made + for (TInt index = 0; + accept && index < iOcspClient->TransactionCount(); + ++index) + { + const TOCSPOutcome& outcome = iOcspClient->Outcome(index); + + // We have the OCSP response. Interpret it, asking the user + // what questions we need to. Return determines whether we + // continue the install + switch (outcome.iStatus) + { + case OCSP::ETransportError: + case OCSP::EClientInternalError: + case OCSP::EMalformedRequest: + case OCSP::EServerInternalError: + case OCSP::ETryLater: + case OCSP::ESignatureRequired: + case OCSP::EClientUnauthorised: + case OCSP::EUnknownResponseType: + // Error: unable to obtain certificate status + break; + case OCSP::ENoServerSpecified: + case OCSP::EInvalidURI: + // Error: invalid revocation server URI + break; + case OCSP::EResponseSignatureValidationFailure: + // Error: response signature validation failed + break; + case OCSP::EThisUpdateTooLate: + case OCSP::EThisUpdateTooEarly: + case OCSP::ENextUpdateTooEarly: + case OCSP::ENonceMismatch: + case OCSP::EMalformedResponse: + case OCSP::EUnknownCriticalExtension: + case OCSP::EMissingCertificates: + // Error: invalid server response + break; + case OCSP::EMissingNonce: + // Error: missing nonce + break; + case OCSP::ECertificateNotValidAtValidationTime: + // Error: invalid certificate status information + break; + case OCSP::EValid: + switch(outcome.iResult) + { + case OCSP::EGood: + accept = ETrue; + break; + case OCSP::EUnknown: + // ask user + break; + case OCSP::ERevoked: + // ask user + break; + default: + ASSERT(EFalse); + } + break; + default: + ASSERT(EFalse); + break; + } + } + break; + } + default: + // Error: cannot obtain certificate status, ask user + break; + } + + delete iOcspClient; + iOcspClient = NULL; + +OCSP check can take a long time. Therefore it is a good thing to display a +status dialog for the user telling her that OCSP check is in progress and +allowing her to cancel it. Both SIS and Java installers delegate this function +to their respective UI handlers.