Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: nss/lib/libpkix/pkix/checker/pkix_ocspchecker.c

Issue 105893015: Update third_party/nss to NSS 3.15.4. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/nss/
Patch Set: Remove SVN property on new file nss/lib/freebl/rsapkcs.c Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* This Source Code Form is subject to the terms of the Mozilla Public 1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 /* 4 /*
5 * pkix_ocspchecker.c 5 * pkix_ocspchecker.c
6 * 6 *
7 * OcspChecker Object Functions 7 * OcspChecker Object Functions
8 * 8 *
9 */ 9 */
10 10
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 193
194 PKIX_RETURN(OCSPCHECKER); 194 PKIX_RETURN(OCSPCHECKER);
195 } 195 }
196 196
197 197
198 /* 198 /*
199 * The OCSPChecker is created in an idle state, and remains in this state until 199 * The OCSPChecker is created in an idle state, and remains in this state until
200 * either (a) the default Responder has been set and enabled, and a Check 200 * either (a) the default Responder has been set and enabled, and a Check
201 * request is received with no responder specified, or (b) a Check request is 201 * request is received with no responder specified, or (b) a Check request is
202 * received with a specified responder. A request message is constructed and 202 * received with a specified responder. A request message is constructed and
203 * given to the HttpClient. If non-blocking I/O is used the client may return 203 * given to the HttpClient. When a response is received it is decoded and the
204 * with WOULDBLOCK, in which case the OCSPChecker returns the WOULDBLOCK 204 * results provided to the caller.
205 * condition to its caller in turn. On a subsequent call the I/O is resumed.
206 * When a response is received it is decoded and the results provided to the
207 * caller.
208 * 205 *
206 * During the most recent enhancement of this function, it has been found that
207 * it doesn't correctly implement non-blocking I/O.
208 *
209 * The nbioContext is used in two places, for "response-obtaining" and
210 * for "response-verification".
211 *
212 * However, if this function gets called to resume, it always
213 * repeats the "request creation" and "response fetching" steps!
214 * As a result, the earlier operation is never resumed.
209 */ 215 */
210 PKIX_Error * 216 PKIX_Error *
211 pkix_OcspChecker_CheckExternal( 217 pkix_OcspChecker_CheckExternal(
212 PKIX_PL_Cert *cert, 218 PKIX_PL_Cert *cert,
213 PKIX_PL_Cert *issuer, 219 PKIX_PL_Cert *issuer,
214 PKIX_PL_Date *date, 220 PKIX_PL_Date *date,
215 pkix_RevocationMethod *checkerObject, 221 pkix_RevocationMethod *checkerObject,
216 PKIX_ProcessingParams *procParams, 222 PKIX_ProcessingParams *procParams,
217 PKIX_UInt32 methodFlags, 223 PKIX_UInt32 methodFlags,
218 PKIX_RevocationStatus *pRevStatus, 224 PKIX_RevocationStatus *pRevStatus,
219 PKIX_UInt32 *pReasonCode, 225 PKIX_UInt32 *pReasonCode,
220 void **pNBIOContext, 226 void **pNBIOContext,
221 void *plContext) 227 void *plContext)
222 { 228 {
223 SECErrorCodes resultCode = SEC_ERROR_REVOKED_CERTIFICATE_OCSP; 229 SECErrorCodes resultCode = SEC_ERROR_REVOKED_CERTIFICATE_OCSP;
224 PKIX_Boolean uriFound = PKIX_FALSE; 230 PKIX_Boolean uriFound = PKIX_FALSE;
225 PKIX_Boolean passed = PKIX_TRUE; 231 PKIX_Boolean passed = PKIX_TRUE;
226 pkix_OcspChecker *checker = NULL; 232 pkix_OcspChecker *checker = NULL;
227 PKIX_PL_OcspCertID *cid = NULL; 233 PKIX_PL_OcspCertID *cid = NULL;
228 PKIX_PL_OcspRequest *request = NULL; 234 PKIX_PL_OcspRequest *request = NULL;
229 PKIX_PL_OcspResponse *response = NULL; 235 PKIX_PL_OcspResponse *response = NULL;
230 PKIX_PL_Date *validity = NULL; 236 PKIX_PL_Date *validity = NULL;
231 PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo; 237 PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo;
232 void *nbioContext = NULL; 238 void *nbioContext = NULL;
239 enum { stageGET, stagePOST } currentStage;
240 PRBool retry = PR_FALSE;
233 241
234 PKIX_ENTER(OCSPCHECKER, "pkix_OcspChecker_CheckExternal"); 242 PKIX_ENTER(OCSPCHECKER, "pkix_OcspChecker_CheckExternal");
235 243
236 PKIX_CHECK( 244 PKIX_CHECK(
237 pkix_CheckType((PKIX_PL_Object*)checkerObject, 245 pkix_CheckType((PKIX_PL_Object*)checkerObject,
238 PKIX_OCSPCHECKER_TYPE, plContext), 246 PKIX_OCSPCHECKER_TYPE, plContext),
239 PKIX_OBJECTNOTOCSPCHECKER); 247 PKIX_OBJECTNOTOCSPCHECKER);
240 248
241 checker = (pkix_OcspChecker *)checkerObject; 249 checker = (pkix_OcspChecker *)checkerObject;
242 250
243 PKIX_CHECK( 251 PKIX_CHECK(
244 PKIX_PL_OcspCertID_Create(cert, NULL, &cid, 252 PKIX_PL_OcspCertID_Create(cert, NULL, &cid,
245 plContext), 253 plContext),
246 PKIX_OCSPCERTIDCREATEFAILED); 254 PKIX_OCSPCERTIDCREATEFAILED);
247 255
248 /* create request */ 256 /* create request */
249 PKIX_CHECK( 257 PKIX_CHECK(
250 pkix_pl_OcspRequest_Create(cert, cid, validity, NULL, 258 pkix_pl_OcspRequest_Create(cert, cid, validity, NULL,
251 methodFlags, &uriFound, &request, 259 methodFlags, &uriFound, &request,
252 plContext), 260 plContext),
253 PKIX_OCSPREQUESTCREATEFAILED); 261 PKIX_OCSPREQUESTCREATEFAILED);
254 262
255 if (uriFound == PKIX_FALSE) { 263 if (uriFound == PKIX_FALSE) {
256 /* no caching for certs lacking URI */ 264 /* no caching for certs lacking URI */
257 resultCode = 0; 265 resultCode = 0;
258 goto cleanup; 266 goto cleanup;
259 } 267 }
260 268
261 /* send request and create a response object */ 269 if (methodFlags & CERT_REV_M_FORCE_POST_METHOD_FOR_OCSP) {
262 PKIX_CHECK( 270 /* Do not try HTTP GET, only HTTP POST */
263 pkix_pl_OcspResponse_Create(request, NULL, 271 currentStage = stagePOST;
264 checker->certVerifyFcn, 272 } else {
265 &nbioContext, 273 /* Try HTTP GET first, falling back to POST */
266 &response, 274 currentStage = stageGET;
267 plContext),
268 PKIX_OCSPRESPONSECREATEFAILED);
269 if (nbioContext != 0) {
270 *pNBIOContext = nbioContext;
271 goto cleanup;
272 }
273
274 PKIX_CHECK(
275 pkix_pl_OcspResponse_Decode(response, &passed,
276 &resultCode, plContext),
277 PKIX_OCSPRESPONSEDECODEFAILED);
278 if (passed == PKIX_FALSE) {
279 goto cleanup;
280 }
281
282 PKIX_CHECK(
283 pkix_pl_OcspResponse_GetStatus(response, &passed,
284 &resultCode, plContext),
285 PKIX_OCSPRESPONSEGETSTATUSRETURNEDANERROR);
286 if (passed == PKIX_FALSE) {
287 goto cleanup;
288 } 275 }
289 276
290 PKIX_CHECK( 277 do {
291 pkix_pl_OcspResponse_VerifySignature(response, cert, 278 const char *method;
292 procParams, &passed, 279 passed = PKIX_TRUE;
293 &nbioContext, plContext),
294 PKIX_OCSPRESPONSEVERIFYSIGNATUREFAILED);
295 »if (nbioContext != 0) {
296 »*pNBIOContext = nbioContext;
297 goto cleanup;
298 }
299 if (passed == PKIX_FALSE) {
300 goto cleanup;
301 }
302 280
303 PKIX_CHECK( 281 retry = PR_FALSE;
304 pkix_pl_OcspResponse_GetStatusForCert(cid, response, date, 282 if (currentStage == stageGET) {
305 &passed, &resultCode, 283 method = "GET";
306 plContext), 284 } else {
307 PKIX_OCSPRESPONSEGETSTATUSFORCERTFAILED); 285 PORT_Assert(currentStage == stagePOST);
308 if (passed == PKIX_FALSE) { 286 method = "POST";
309 revStatus = pkix_OcspChecker_MapResultCodeToRevStatus(resultCode); 287 }
310 } else { 288
311 revStatus = PKIX_RevStatus_Success; 289 /* send request and create a response object */
312 } 290 PKIX_CHECK_NO_GOTO(
291 pkix_pl_OcspResponse_Create(request, method, NULL,
292 checker->certVerifyFcn,
293 &nbioContext,
294 &response,
295 plContext),
296 PKIX_OCSPRESPONSECREATEFAILED);
297
298 if (pkixErrorResult) {
299 passed = PKIX_FALSE;
300 }
301
302 if (passed && nbioContext != 0) {
303 *pNBIOContext = nbioContext;
304 goto cleanup;
305 }
306
307 if (passed){
308 PKIX_CHECK_NO_GOTO(
309 pkix_pl_OcspResponse_Decode(response, &passed,
310 &resultCode, plContext),
311 PKIX_OCSPRESPONSEDECODEFAILED);
312 if (pkixErrorResult) {
313 passed = PKIX_FALSE;
314 }
315 }
316
317 if (passed){
318 PKIX_CHECK_NO_GOTO(
319 pkix_pl_OcspResponse_GetStatus(response, &passed,
320 &resultCode, plContex t),
321 PKIX_OCSPRESPONSEGETSTATUSRETURNEDANERROR);
322 if (pkixErrorResult) {
323 passed = PKIX_FALSE;
324 }
325 }
326
327 if (passed){
328 PKIX_CHECK_NO_GOTO(
329 pkix_pl_OcspResponse_VerifySignature(response, cert,
330 procParams, &pa ssed,
331 &nbioContext, p lContext),
332 PKIX_OCSPRESPONSEVERIFYSIGNATUREFAILED);
333 if (pkixErrorResult) {
334 passed = PKIX_FALSE;
335 } else {
336 if (nbioContext != 0) {
337 *pNBIOContext = nbioContext;
338 goto cleanup;
339 }
340 }
341 }
342
343 if (!passed && currentStage == stagePOST) {
344 /* We won't retry a POST failure, so it's final.
345 * Because the following block with its call to
346 * pkix_pl_OcspResponse_GetStatusForCert
347 * will take care of caching good or bad state,
348 * but we only execute that next block if there hasn't
349 * been a failure yet, we must cache the POST
350 * failure now.
351 */
352
353 if (cid && cid->certID) {
354 /* Caching MIGHT consume the cid. */
355 PKIX_Error *err;
356 err = PKIX_PL_OcspCertID_RememberOCSPProcessingF ailure(
357 cid, plContext);
358 if (err) {
359 PKIX_PL_Object_DecRef((PKIX_PL_Object*)e rr, plContext);
360 }
361 }
362 }
363
364 if (passed){
365 PKIX_Boolean allowCachingOfFailures =
366 (currentStage == stagePOST) ? PKIX_TRUE : PKIX_F ALSE;
367
368 PKIX_CHECK_NO_GOTO(
369 pkix_pl_OcspResponse_GetStatusForCert(cid, response,
370 allowCachingOf Failures,
371 date,
372 &passed, &resu ltCode,
373 plContext),
374 PKIX_OCSPRESPONSEGETSTATUSFORCERTFAILED);
375 if (pkixErrorResult) {
376 passed = PKIX_FALSE;
377 } else if (passed == PKIX_FALSE) {
378 revStatus = pkix_OcspChecker_MapResultCodeToRevS tatus(resultCode);
379 } else {
380 revStatus = PKIX_RevStatus_Success;
381 }
382 }
383
384 if (currentStage == stageGET && revStatus != PKIX_RevStatus_Succ ess &&
385 revStatus != PKIX_RevStatus_Revo ked) {
386 /* we'll retry */
387 PKIX_DECREF(response);
388 retry = PR_TRUE;
389 currentStage = stagePOST;
390 revStatus = PKIX_RevStatus_NoInfo;
391 if (pkixErrorResult) {
392 PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixError Result,
393 plContext);
394 pkixErrorResult = NULL;
395 }
396 }
397 } while (retry);
313 398
314 cleanup: 399 cleanup:
315 if (revStatus == PKIX_RevStatus_NoInfo && (uriFound || 400 if (revStatus == PKIX_RevStatus_NoInfo && (uriFound ||
316 methodFlags & PKIX_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE) && 401 methodFlags & PKIX_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE) &&
317 methodFlags & PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO) { 402 methodFlags & PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO) {
318 revStatus = PKIX_RevStatus_Revoked; 403 revStatus = PKIX_RevStatus_Revoked;
319 } 404 }
320 *pRevStatus = revStatus; 405 *pRevStatus = revStatus;
321 406
322 /* ocsp carries only tree statuses: good, bad, and unknown. 407 /* ocsp carries only three statuses: good, bad, and unknown.
323 * revStatus is used to pass them. reasonCode is always set 408 * revStatus is used to pass them. reasonCode is always set
324 * to be unknown. */ 409 * to be unknown. */
325 *pReasonCode = crlEntryReasonUnspecified; 410 *pReasonCode = crlEntryReasonUnspecified;
326 411
327 if (!passed && cid && cid->certID) {
328 /* We still own the certID object, which means that
329 * it did not get consumed to create a cache entry.
330 * Let's make sure there is one.
331 */
332 PKIX_Error *err;
333 err = PKIX_PL_OcspCertID_RememberOCSPProcessingFailure(
334 cid, plContext);
335 if (err) {
336 PKIX_PL_Object_DecRef((PKIX_PL_Object*)err, plContext);
337 }
338 }
339 PKIX_DECREF(cid); 412 PKIX_DECREF(cid);
340 PKIX_DECREF(request); 413 PKIX_DECREF(request);
341 PKIX_DECREF(response); 414 PKIX_DECREF(response);
342 415
343 PKIX_RETURN(OCSPCHECKER); 416 PKIX_RETURN(OCSPCHECKER);
344 } 417 }
345 418
346 419
OLDNEW
« no previous file with comments | « nss/lib/libpkix/include/pkix_errorstrings.h ('k') | nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698