|
1 How to use OSCP |
|
2 =============== |
|
3 |
|
4 Note: The actual code snippets are indented. |
|
5 |
|
6 Include ocsp.h in your header file. |
|
7 |
|
8 #include <ocsp.h> |
|
9 |
|
10 Link your project with ocsp.lib: add the following string to your project's .mmp |
|
11 file: |
|
12 |
|
13 LIBRARY ocsp.lib |
|
14 |
|
15 Add the following to your class declaration, which should be derived from |
|
16 CActive: |
|
17 |
|
18 COcspClient* iOcspClient; |
|
19 |
|
20 You will need to know revocation server URI. It is possible to get it from |
|
21 installer preferences. Most Software Install components accept the URI as a |
|
22 construction parameter. This is because they are started by the UI which stores |
|
23 preferences in its resource file. If you want to retrieve it yourself, you can |
|
24 use the following code (taken from InstallEngineImpl.cpp): |
|
25 |
|
26 // Open instapp's ini file |
|
27 static CDictionaryStore* OpenIniFileLC(RFs& aFs) |
|
28 { |
|
29 CApaAppFinder* appFinder=CApaScanningAppFinder::NewL(aFs); |
|
30 CleanupStack::PushL(appFinder); |
|
31 TUid instAppUid={KUidInstallAppValue}; |
|
32 TFileName libName=appFinder->FindAppL(KInstallAppName,instAppUid); |
|
33 CleanupStack::PopAndDestroy(appFinder); |
|
34 TParse parser; |
|
35 User::LeaveIfError(parser.SetNoWild(KIniFileExtension,&KInstAppDriveC(), |
|
36 &libName)); |
|
37 aFs.MkDirAll(parser.FullName()); // ignore the error |
|
38 CDictionaryFileStore* dict = CDictionaryFileStore::OpenLC(aFs, |
|
39 parser.FullName(),instAppUid); |
|
40 return dict; |
|
41 } |
|
42 |
|
43 // get preferences from ini file |
|
44 { |
|
45 RFs fs; |
|
46 User::LeaveIfError(fs.Connect()); |
|
47 CleanupClosePushL(fs); |
|
48 CDictionaryStore* iniFile=OpenIniFileLC(fs); // see above |
|
49 User::LeaveIfNull(iniFile); |
|
50 RDictionaryReadStream readStream; |
|
51 readStream.OpenLC(*iniFile,KUidInstallPrefs); |
|
52 TInstallPrefs prefs; // this is what you need |
|
53 TRAPD(ret,readStream >> prefs); // will return KErrEof first time |
|
54 CleanupStack::PopAndDestroy(2); //readStream, iniFile |
|
55 CleanupStack::Pop(); // fs |
|
56 fs.Close(); |
|
57 } |
|
58 |
|
59 If at any time you want to cancel OCSP check, call |
|
60 |
|
61 iOcspClient->CancelCheck(); |
|
62 |
|
63 When ready to perform the check (the certificate chain is built), use the |
|
64 following code as a template (from JavaInstallerSecurityManager.cpp): |
|
65 |
|
66 COCSPParameters* params = COCSPParameters::NewLC(); |
|
67 params->SetURIL(*iOCSPServerURI, ETrue); |
|
68 params->AddCertificatesL(*iCertChain); |
|
69 |
|
70 // Set up authorisation scheme - we've a special UID registered with the |
|
71 // certStore for the appropriate certificates |
|
72 COCSPDirectAuthorisationScheme* scheme = |
|
73 COCSPDirectAuthorisationScheme::NewLC( |
|
74 TUid::Uid(KCertStoreUIDForSWInstallOCSPSigning)); |
|
75 params->AddAuthorisationSchemeL(scheme); |
|
76 CleanupStack::Pop(scheme); |
|
77 |
|
78 // Won't set validation time - this uses the response producedAt time |
|
79 // instead. This avoids us relying on an accurate time in the device. |
|
80 // Caching of old responses avoided by use of the nonce. |
|
81 |
|
82 iOcspClient = COcspClient::NewL(params); |
|
83 CleanupStack::Pop(params); |
|
84 iOcspClient->Check(iStatus); |
|
85 |
|
86 When the request completes and your class's RunL() is called, use the following |
|
87 function template to process the result: |
|
88 |
|
89 TBool accept = ETrue; |
|
90 switch (iStatus.Int()) |
|
91 { |
|
92 case OCSP::KErrNoCertificates: |
|
93 // No certs in OCSP request - no proper cert chain formed. |
|
94 // Covered by check digital sig logic already, so we let it pass. |
|
95 break; |
|
96 case KErrNone: |
|
97 { |
|
98 // Check the outcome of every transaction made |
|
99 for (TInt index = 0; |
|
100 accept && index < iOcspClient->TransactionCount(); |
|
101 ++index) |
|
102 { |
|
103 const TOCSPOutcome& outcome = iOcspClient->Outcome(index); |
|
104 |
|
105 // We have the OCSP response. Interpret it, asking the user |
|
106 // what questions we need to. Return determines whether we |
|
107 // continue the install |
|
108 switch (outcome.iStatus) |
|
109 { |
|
110 case OCSP::ETransportError: |
|
111 case OCSP::EClientInternalError: |
|
112 case OCSP::EMalformedRequest: |
|
113 case OCSP::EServerInternalError: |
|
114 case OCSP::ETryLater: |
|
115 case OCSP::ESignatureRequired: |
|
116 case OCSP::EClientUnauthorised: |
|
117 case OCSP::EUnknownResponseType: |
|
118 // Error: unable to obtain certificate status |
|
119 break; |
|
120 case OCSP::ENoServerSpecified: |
|
121 case OCSP::EInvalidURI: |
|
122 // Error: invalid revocation server URI |
|
123 break; |
|
124 case OCSP::EResponseSignatureValidationFailure: |
|
125 // Error: response signature validation failed |
|
126 break; |
|
127 case OCSP::EThisUpdateTooLate: |
|
128 case OCSP::EThisUpdateTooEarly: |
|
129 case OCSP::ENextUpdateTooEarly: |
|
130 case OCSP::ENonceMismatch: |
|
131 case OCSP::EMalformedResponse: |
|
132 case OCSP::EUnknownCriticalExtension: |
|
133 case OCSP::EMissingCertificates: |
|
134 // Error: invalid server response |
|
135 break; |
|
136 case OCSP::EMissingNonce: |
|
137 // Error: missing nonce |
|
138 break; |
|
139 case OCSP::ECertificateNotValidAtValidationTime: |
|
140 // Error: invalid certificate status information |
|
141 break; |
|
142 case OCSP::EValid: |
|
143 switch(outcome.iResult) |
|
144 { |
|
145 case OCSP::EGood: |
|
146 accept = ETrue; |
|
147 break; |
|
148 case OCSP::EUnknown: |
|
149 // ask user |
|
150 break; |
|
151 case OCSP::ERevoked: |
|
152 // ask user |
|
153 break; |
|
154 default: |
|
155 ASSERT(EFalse); |
|
156 } |
|
157 break; |
|
158 default: |
|
159 ASSERT(EFalse); |
|
160 break; |
|
161 } |
|
162 } |
|
163 break; |
|
164 } |
|
165 default: |
|
166 // Error: cannot obtain certificate status, ask user |
|
167 break; |
|
168 } |
|
169 |
|
170 delete iOcspClient; |
|
171 iOcspClient = NULL; |
|
172 |
|
173 OCSP check can take a long time. Therefore it is a good thing to display a |
|
174 status dialog for the user telling her that OCSP check is in progress and |
|
175 allowing her to cancel it. Both SIS and Java installers delegate this function |
|
176 to their respective UI handlers. |