|
1 /* |
|
2 * Copyright (c) 2007-2007 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 "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 "ocspclient.h" |
|
20 |
|
21 using namespace java::security; |
|
22 using namespace std; |
|
23 using namespace java::util; |
|
24 |
|
25 const TInt KCertStoreUIDForSWInstallOCSPSigning = 268478646; |
|
26 |
|
27 OcspClient* OcspClient::createInstance(long iap, const char* defaultUrl) |
|
28 { |
|
29 OcspClient* self = new OcspClient(iap); |
|
30 TRAPD(err, self->ConstructL(defaultUrl)); |
|
31 if (err != KErrNone) |
|
32 { |
|
33 delete self; |
|
34 self = NULL; |
|
35 } |
|
36 return self; |
|
37 } |
|
38 |
|
39 OcspClient::OcspClient(long iap) |
|
40 : CActive(EPriorityNormal), iIap(TUint32(iap)), iDefaultUrl(NULL), iOcspClient(NULL), iCertStore(NULL), iInitialized(false), iOcspResponse(NULL), iCertArray(NULL), iMonitor(NULL) |
|
41 { |
|
42 CActiveScheduler::Add(this); |
|
43 } |
|
44 |
|
45 void OcspClient::ConstructL(const char* defaultUrl) |
|
46 { |
|
47 User::LeaveIfError(iRfs.Connect()); |
|
48 iCertStore = CUnifiedCertStore::NewL(iRfs, false /*aOpenForWrite*/); |
|
49 iOcspResponse = OcspResponse::NewL(); |
|
50 // create the monitor |
|
51 iMonitor = Monitor::createMonitor(); |
|
52 if (defaultUrl) |
|
53 { |
|
54 int len = strlen(defaultUrl); |
|
55 iDefaultUrl = HBufC8::NewL(len); |
|
56 TPtr8 defaultUrlPtr = iDefaultUrl->Des(); |
|
57 TPtr8 ptr((TUint8 *)defaultUrl, len); |
|
58 ptr.SetLength(len); |
|
59 defaultUrlPtr.Copy(ptr); |
|
60 } |
|
61 } |
|
62 |
|
63 void OcspClient::RunL() |
|
64 { |
|
65 switch (iState) |
|
66 { |
|
67 case ESendOcspRequest: |
|
68 SendOcspRequestL(); |
|
69 iState = EProcessOcspResponse; |
|
70 break; |
|
71 case EProcessOcspResponse: |
|
72 ProcessOcspResponse(); |
|
73 iMonitor->notify(); |
|
74 return; |
|
75 } |
|
76 // re-issue a new request |
|
77 SetActive(); |
|
78 } |
|
79 |
|
80 void OcspClient::DoCancel() |
|
81 { |
|
82 if (iCertStore) |
|
83 { |
|
84 iCertStore->CancelInitialize(); |
|
85 } |
|
86 if (iOcspClient) |
|
87 { |
|
88 iOcspClient->CancelCheck(); |
|
89 } |
|
90 } |
|
91 |
|
92 TInt OcspClient::RunError(TInt /*aError*/) |
|
93 { |
|
94 return KErrNone; |
|
95 } |
|
96 |
|
97 OcspClient::~OcspClient() |
|
98 { |
|
99 if (IsActive()) |
|
100 { |
|
101 Cancel(); |
|
102 } |
|
103 if (iCertStore) |
|
104 { |
|
105 delete iCertStore; |
|
106 iCertStore = NULL; |
|
107 } |
|
108 if (iOcspClient) |
|
109 { |
|
110 delete iOcspClient; |
|
111 iOcspClient = NULL; |
|
112 } |
|
113 if (iOcspResponse) |
|
114 { |
|
115 delete iOcspResponse; |
|
116 iOcspResponse = NULL; |
|
117 } |
|
118 if (iCertArray) |
|
119 { |
|
120 iCertArray->ResetAndDestroy(); |
|
121 delete iCertArray; |
|
122 } |
|
123 if (iDefaultUrl) |
|
124 { |
|
125 delete iDefaultUrl; |
|
126 iDefaultUrl = NULL; |
|
127 } |
|
128 if (iMonitor) |
|
129 { |
|
130 delete iMonitor; |
|
131 iMonitor = NULL; |
|
132 } |
|
133 iRfs.Close(); |
|
134 } |
|
135 |
|
136 void OcspClient::startOcspCheck(const char ** aCertChain, int aCertChainLen) |
|
137 { |
|
138 |
|
139 // clear the response |
|
140 iOcspResponse->Clear(); |
|
141 // build up the chain |
|
142 iCertChain = aCertChain; |
|
143 iCertChainLen = aCertChainLen; |
|
144 // kick off the state machine |
|
145 Start(); |
|
146 } |
|
147 |
|
148 OcspResponse OcspClient::getOcspCheckResponse() |
|
149 { |
|
150 // wait for completion |
|
151 iMonitor->wait(); |
|
152 // return the result |
|
153 return *iOcspResponse; |
|
154 } |
|
155 |
|
156 void OcspClient::cancelOcspCheck(bool doCleanup) |
|
157 { |
|
158 // cancel the outstanding request (if any) |
|
159 if (doCleanup) |
|
160 { |
|
161 if (IsActive()) |
|
162 { |
|
163 Cancel(); |
|
164 } |
|
165 } |
|
166 iMonitor->notify(); |
|
167 } |
|
168 |
|
169 void OcspClient::Start() |
|
170 { |
|
171 // cancel the outstanding request (if any) |
|
172 if (IsActive()) |
|
173 { |
|
174 Cancel(); |
|
175 } |
|
176 |
|
177 iState = ESendOcspRequest; |
|
178 SetActive(); |
|
179 if (iInitialized) |
|
180 { |
|
181 // already initialized |
|
182 CompleteRequest(); |
|
183 return; |
|
184 } |
|
185 |
|
186 // do the initialization |
|
187 iCertStore->Initialize(iStatus); |
|
188 iInitialized = true; |
|
189 } |
|
190 |
|
191 void OcspClient::SendOcspRequestL() |
|
192 { |
|
193 InitOcspClientL(); |
|
194 iOcspClient->Check(iStatus); |
|
195 } |
|
196 |
|
197 void OcspClient::ProcessOcspResponse() |
|
198 { |
|
199 int summary = RESPONSE_CANNOT_OBTAIN_CERT_STATUS; |
|
200 if (iStatus.Int() == KErrNone) |
|
201 { |
|
202 // set the summary |
|
203 switch (iOcspClient->SummaryResult()) |
|
204 { |
|
205 case OCSP::EGood: |
|
206 summary = RESPONSE_GOOD; |
|
207 break; |
|
208 case OCSP::EUnknown: |
|
209 summary = RESPONSE_UNKNOWN; |
|
210 break; |
|
211 case OCSP::ERevoked: |
|
212 summary = RESPONSE_REVOKED; |
|
213 break; |
|
214 } |
|
215 // set the individual responses |
|
216 for (TInt index = 0 ; index < iOcspClient->TransactionCount() ; ++index) |
|
217 { |
|
218 const TOCSPOutcome& outcome = iOcspClient->Outcome(index); |
|
219 switch (outcome.iStatus) |
|
220 { |
|
221 case OCSP::ETransportError: |
|
222 case OCSP::EClientInternalError: |
|
223 case OCSP::EMalformedRequest: |
|
224 case OCSP::EServerInternalError: |
|
225 case OCSP::ETryLater: |
|
226 case OCSP::ESignatureRequired: |
|
227 case OCSP::EClientUnauthorised: |
|
228 case OCSP::EUnknownResponseType: |
|
229 iOcspResponse->iIndividualResponses.push_back(RESPONSE_CANNOT_OBTAIN_CERT_STATUS); |
|
230 break; |
|
231 case OCSP::ENoServerSpecified: |
|
232 case OCSP::EInvalidURI: |
|
233 iOcspResponse->iIndividualResponses.push_back(RESPONSE_INVALID_REVOCATION_SERVER_URI); |
|
234 break; |
|
235 case OCSP::EResponseSignatureValidationFailure: |
|
236 iOcspResponse->iIndividualResponses.push_back(RESPONSE_SIGNATURE_VALIDATION_FAILURE); |
|
237 break; |
|
238 case OCSP::EThisUpdateTooLate: |
|
239 case OCSP::EThisUpdateTooEarly: |
|
240 case OCSP::ENextUpdateTooEarly: |
|
241 case OCSP::ENonceMismatch: |
|
242 case OCSP::EMalformedResponse: |
|
243 case OCSP::EUnknownCriticalExtension: |
|
244 case OCSP::EMissingCertificates: |
|
245 iOcspResponse->iIndividualResponses.push_back(RESPONSE_INVALID_REVOCATION_SERVER_RESPONSE); |
|
246 break; |
|
247 case OCSP::EMissingNonce: |
|
248 iOcspResponse->iIndividualResponses.push_back(RESPONSE_MISSING_NONCE); |
|
249 break; |
|
250 case OCSP::ECertificateNotValidAtValidationTime: |
|
251 iOcspResponse->iIndividualResponses.push_back(RESPONSE_INVALID_CERT_STATUS_INFO); |
|
252 break; |
|
253 case OCSP::EValid: |
|
254 switch (outcome.iResult) |
|
255 { |
|
256 case OCSP::EGood: |
|
257 iOcspResponse->iIndividualResponses.push_back(RESPONSE_GOOD); |
|
258 break; |
|
259 case OCSP::EUnknown: |
|
260 iOcspResponse->iIndividualResponses.push_back(RESPONSE_UNKNOWN); |
|
261 break; |
|
262 case OCSP::ERevoked: |
|
263 iOcspResponse->iIndividualResponses.push_back(RESPONSE_REVOKED); |
|
264 break; |
|
265 default: |
|
266 ASSERT(EFalse); |
|
267 } |
|
268 break; |
|
269 default: |
|
270 ASSERT(EFalse); |
|
271 break; |
|
272 } |
|
273 } |
|
274 } |
|
275 iOcspResponse->iSummary = summary; |
|
276 } |
|
277 |
|
278 void OcspClient::CompleteRequest() |
|
279 { |
|
280 TRequestStatus* status = &iStatus; |
|
281 User::RequestComplete(status,KErrNone); |
|
282 } |
|
283 |
|
284 void OcspClient::InitOcspClientL() |
|
285 { |
|
286 if (iOcspClient) |
|
287 { |
|
288 delete iOcspClient; |
|
289 iOcspClient = NULL; |
|
290 } |
|
291 if (iCertArray) |
|
292 { |
|
293 iCertArray->ResetAndDestroy(); |
|
294 delete iCertArray; |
|
295 } |
|
296 COCSPParameters* ocspParams = COCSPParameters::NewL(); |
|
297 if (iDefaultUrl) |
|
298 { |
|
299 ocspParams->SetURIL(*iDefaultUrl, ETrue); |
|
300 } |
|
301 ocspParams->SetTransport(COCSPTransportDefault::NewL(iIap)); |
|
302 ocspParams->AddAllAuthorisationSchemesL( |
|
303 TUid::Uid(KCertStoreUIDForSWInstallOCSPSigning), *iCertStore); |
|
304 // add the certs |
|
305 if (iCertChainLen >= 2) |
|
306 { |
|
307 iCertArray = new(ELeave) CArrayPtrFlat<CX509Certificate>(1); |
|
308 std::string cert = JavaCommonUtils::base64decode(std::string(iCertChain[0], strlen(iCertChain[0]))); |
|
309 TPtr8 ptr8((TUint8 *)(cert.c_str()), cert.size()); |
|
310 ptr8.SetLength(cert.size()); |
|
311 CX509Certificate* issuerCert = CX509Certificate::NewL(ptr8); |
|
312 iCertArray->AppendL(issuerCert); |
|
313 CX509Certificate* subjectCert = NULL; |
|
314 for (int i = 1; i < iCertChainLen; i++) |
|
315 { |
|
316 subjectCert = issuerCert; |
|
317 cert = JavaCommonUtils::base64decode(std::string(iCertChain[i], strlen(iCertChain[i]))); |
|
318 TPtr8 ptr((TUint8 *)(cert.c_str()), cert.size()); |
|
319 ptr.SetLength(cert.size()); |
|
320 issuerCert = CX509Certificate::NewL(ptr); |
|
321 iCertArray->AppendL(issuerCert); |
|
322 ocspParams->AddCertificateL(*subjectCert, *issuerCert); |
|
323 } |
|
324 } |
|
325 iOcspClient = COCSPClient::NewL(ocspParams); |
|
326 } |
|
327 |
|
328 OcspResponse* OcspResponse::NewL() |
|
329 { |
|
330 OcspResponse* self = new(ELeave) OcspResponse(); |
|
331 CleanupStack::PushL(self); |
|
332 self->ConstructL(); |
|
333 CleanupStack::Pop(self); |
|
334 return self; |
|
335 } |
|
336 |
|
337 OcspResponse::OcspResponse() |
|
338 { |
|
339 iIndividualResponses.clear(); |
|
340 iSummary = RESPONSE_CANNOT_OBTAIN_CERT_STATUS; |
|
341 } |
|
342 |
|
343 void OcspResponse::ConstructL() |
|
344 { |
|
345 } |
|
346 |
|
347 OcspResponse::~OcspResponse() |
|
348 { |
|
349 } |
|
350 |
|
351 void OcspResponse::Clear() |
|
352 { |
|
353 iIndividualResponses.clear(); |
|
354 iSummary = RESPONSE_CANNOT_OBTAIN_CERT_STATUS; |
|
355 } |
|
356 |
|
357 OcspResponse& OcspResponse::operator=(const OcspResponse& x) |
|
358 { |
|
359 iSummary = x.iSummary; |
|
360 iIndividualResponses = x.iIndividualResponses; |
|
361 return *this; |
|
362 } |
|
363 |
|
364 OcspResponse::OcspResponse(const OcspResponse& x) |
|
365 { |
|
366 *this = x; |
|
367 } |
|
368 |