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

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

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 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
OLDNEW
(Empty)
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
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 /*
5 * pkix_revocationchecker.c
6 *
7 * RevocationChecker Object Functions
8 *
9 */
10
11 #include "pkix_revocationchecker.h"
12 #include "pkix_tools.h"
13
14 /* --Private-Functions-------------------------------------------- */
15
16 /*
17 * FUNCTION: pkix_RevocationChecker_Destroy
18 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
19 */
20 static PKIX_Error *
21 pkix_RevocationChecker_Destroy(
22 PKIX_PL_Object *object,
23 void *plContext)
24 {
25 PKIX_RevocationChecker *checker = NULL;
26
27 PKIX_ENTER(REVOCATIONCHECKER, "pkix_RevocationChecker_Destroy");
28 PKIX_NULLCHECK_ONE(object);
29
30 /* Check that this object is a revocation checker */
31 PKIX_CHECK(pkix_CheckType
32 (object, PKIX_REVOCATIONCHECKER_TYPE, plContext),
33 PKIX_OBJECTNOTREVOCATIONCHECKER);
34
35 checker = (PKIX_RevocationChecker *)object;
36
37 PKIX_DECREF(checker->leafMethodList);
38 PKIX_DECREF(checker->chainMethodList);
39
40 cleanup:
41
42 PKIX_RETURN(REVOCATIONCHECKER);
43 }
44
45 /*
46 * FUNCTION: pkix_RevocationChecker_Duplicate
47 * (see comments for PKIX_PL_DuplicateCallback in pkix_pl_system.h)
48 */
49 static PKIX_Error *
50 pkix_RevocationChecker_Duplicate(
51 PKIX_PL_Object *object,
52 PKIX_PL_Object **pNewObject,
53 void *plContext)
54 {
55 PKIX_RevocationChecker *checker = NULL;
56 PKIX_RevocationChecker *checkerDuplicate = NULL;
57 PKIX_List *dupLeafList = NULL;
58 PKIX_List *dupChainList = NULL;
59
60 PKIX_ENTER(REVOCATIONCHECKER, "pkix_RevocationChecker_Duplicate");
61 PKIX_NULLCHECK_TWO(object, pNewObject);
62
63 PKIX_CHECK(pkix_CheckType
64 (object, PKIX_REVOCATIONCHECKER_TYPE, plContext),
65 PKIX_OBJECTNOTCERTCHAINCHECKER);
66
67 checker = (PKIX_RevocationChecker *)object;
68
69 if (checker->leafMethodList){
70 PKIX_CHECK(PKIX_PL_Object_Duplicate
71 ((PKIX_PL_Object *)checker->leafMethodList,
72 (PKIX_PL_Object **)&dupLeafList,
73 plContext),
74 PKIX_OBJECTDUPLICATEFAILED);
75 }
76 if (checker->chainMethodList){
77 PKIX_CHECK(PKIX_PL_Object_Duplicate
78 ((PKIX_PL_Object *)checker->chainMethodList,
79 (PKIX_PL_Object **)&dupChainList,
80 plContext),
81 PKIX_OBJECTDUPLICATEFAILED);
82 }
83
84 PKIX_CHECK(
85 PKIX_RevocationChecker_Create(checker->leafMethodListFlags,
86 checker->chainMethodListFlags,
87 &checkerDuplicate,
88 plContext),
89 PKIX_REVOCATIONCHECKERCREATEFAILED);
90
91 checkerDuplicate->leafMethodList = dupLeafList;
92 checkerDuplicate->chainMethodList = dupChainList;
93 dupLeafList = NULL;
94 dupChainList = NULL;
95
96 *pNewObject = (PKIX_PL_Object *)checkerDuplicate;
97
98 cleanup:
99 PKIX_DECREF(dupLeafList);
100 PKIX_DECREF(dupChainList);
101
102 PKIX_RETURN(REVOCATIONCHECKER);
103 }
104
105 /*
106 * FUNCTION: pkix_RevocationChecker_RegisterSelf
107 * DESCRIPTION:
108 * Registers PKIX_REVOCATIONCHECKER_TYPE and its related functions with
109 * systemClasses[]
110 * THREAD SAFETY:
111 * Not Thread Safe - for performance and complexity reasons
112 *
113 * Since this function is only called by PKIX_PL_Initialize, which should
114 * only be called once, it is acceptable that this function is not
115 * thread-safe.
116 */
117 PKIX_Error *
118 pkix_RevocationChecker_RegisterSelf(void *plContext)
119 {
120 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
121 pkix_ClassTable_Entry entry;
122
123 PKIX_ENTER(REVOCATIONCHECKER, "pkix_RevocationChecker_RegisterSelf");
124
125 entry.description = "RevocationChecker";
126 entry.objCounter = 0;
127 entry.typeObjectSize = sizeof(PKIX_RevocationChecker);
128 entry.destructor = pkix_RevocationChecker_Destroy;
129 entry.equalsFunction = NULL;
130 entry.hashcodeFunction = NULL;
131 entry.toStringFunction = NULL;
132 entry.comparator = NULL;
133 entry.duplicateFunction = pkix_RevocationChecker_Duplicate;
134
135 systemClasses[PKIX_REVOCATIONCHECKER_TYPE] = entry;
136
137 PKIX_RETURN(REVOCATIONCHECKER);
138 }
139
140 /* Sort methods by their priorities (lower priority = higher preference) */
141 static PKIX_Error *
142 pkix_RevocationChecker_SortComparator(
143 PKIX_PL_Object *obj1,
144 PKIX_PL_Object *obj2,
145 PKIX_Int32 *pResult,
146 void *plContext)
147 {
148 pkix_RevocationMethod *method1 = NULL, *method2 = NULL;
149
150 PKIX_ENTER(BUILD, "pkix_RevocationChecker_SortComparator");
151
152 method1 = (pkix_RevocationMethod *)obj1;
153 method2 = (pkix_RevocationMethod *)obj2;
154
155 if (method1->priority < method2->priority) {
156 *pResult = -1;
157 } else if (method1->priority > method2->priority) {
158 *pResult = 1;
159 } else {
160 *pResult = 0;
161 }
162
163 PKIX_RETURN(BUILD);
164 }
165
166
167 /* --Public-Functions--------------------------------------------- */
168
169
170 /*
171 * FUNCTION: PKIX_RevocationChecker_Create (see comments in pkix_revchecker.h)
172 */
173 PKIX_Error *
174 PKIX_RevocationChecker_Create(
175 PKIX_UInt32 leafMethodListFlags,
176 PKIX_UInt32 chainMethodListFlags,
177 PKIX_RevocationChecker **pChecker,
178 void *plContext)
179 {
180 PKIX_RevocationChecker *checker = NULL;
181
182 PKIX_ENTER(REVOCATIONCHECKER, "PKIX_RevocationChecker_Create");
183 PKIX_NULLCHECK_ONE(pChecker);
184
185 PKIX_CHECK(
186 PKIX_PL_Object_Alloc(PKIX_REVOCATIONCHECKER_TYPE,
187 sizeof (PKIX_RevocationChecker),
188 (PKIX_PL_Object **)&checker,
189 plContext),
190 PKIX_COULDNOTCREATECERTCHAINCHECKEROBJECT);
191
192 checker->leafMethodListFlags = leafMethodListFlags;
193 checker->chainMethodListFlags = chainMethodListFlags;
194 checker->leafMethodList = NULL;
195 checker->chainMethodList = NULL;
196
197 *pChecker = checker;
198 checker = NULL;
199
200 cleanup:
201 PKIX_DECREF(checker);
202
203 PKIX_RETURN(REVOCATIONCHECKER);
204 }
205
206 /*
207 * FUNCTION: PKIX_RevocationChecker_CreateAndAddMethod
208 */
209 PKIX_Error *
210 PKIX_RevocationChecker_CreateAndAddMethod(
211 PKIX_RevocationChecker *revChecker,
212 PKIX_ProcessingParams *params,
213 PKIX_RevocationMethodType methodType,
214 PKIX_UInt32 flags,
215 PKIX_UInt32 priority,
216 PKIX_PL_VerifyCallback verificationFn,
217 PKIX_Boolean isLeafMethod,
218 void *plContext)
219 {
220 PKIX_List **methodList = NULL;
221 PKIX_List *unsortedList = NULL;
222 PKIX_List *certStores = NULL;
223 pkix_RevocationMethod *method = NULL;
224 pkix_LocalRevocationCheckFn *localRevChecker = NULL;
225 pkix_ExternalRevocationCheckFn *externRevChecker = NULL;
226 PKIX_UInt32 miFlags;
227
228 PKIX_ENTER(REVOCATIONCHECKER, "PKIX_RevocationChecker_CreateAndAddMethod");
229 PKIX_NULLCHECK_ONE(revChecker);
230
231 /* If the caller has said "Either one is sufficient, then don't let the
232 * absence of any one method's info lead to an overall failure.
233 */
234 miFlags = isLeafMethod ? revChecker->leafMethodListFlags
235 : revChecker->chainMethodListFlags;
236 if (miFlags & PKIX_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE)
237 flags &= ~PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO;
238
239 switch (methodType) {
240 case PKIX_RevocationMethod_CRL:
241 localRevChecker = pkix_CrlChecker_CheckLocal;
242 externRevChecker = pkix_CrlChecker_CheckExternal;
243 PKIX_CHECK(
244 PKIX_ProcessingParams_GetCertStores(params, &certStores,
245 plContext),
246 PKIX_PROCESSINGPARAMSGETCERTSTORESFAILED);
247 PKIX_CHECK(
248 pkix_CrlChecker_Create(methodType, flags, priority,
249 localRevChecker, externRevChecker,
250 certStores, verificationFn,
251 &method,
252 plContext),
253 PKIX_COULDNOTCREATECRLCHECKEROBJECT);
254 break;
255 case PKIX_RevocationMethod_OCSP:
256 localRevChecker = pkix_OcspChecker_CheckLocal;
257 externRevChecker = pkix_OcspChecker_CheckExternal;
258 PKIX_CHECK(
259 pkix_OcspChecker_Create(methodType, flags, priority,
260 localRevChecker, externRevChecker,
261 verificationFn,
262 &method,
263 plContext),
264 PKIX_COULDNOTCREATEOCSPCHECKEROBJECT);
265 break;
266 default:
267 PKIX_ERROR(PKIX_INVALIDREVOCATIONMETHOD);
268 }
269
270 if (isLeafMethod) {
271 methodList = &revChecker->leafMethodList;
272 } else {
273 methodList = &revChecker->chainMethodList;
274 }
275
276 if (*methodList == NULL) {
277 PKIX_CHECK(
278 PKIX_List_Create(methodList, plContext),
279 PKIX_LISTCREATEFAILED);
280 }
281 unsortedList = *methodList;
282 PKIX_CHECK(
283 PKIX_List_AppendItem(unsortedList, (PKIX_PL_Object*)method, plContext),
284 PKIX_LISTAPPENDITEMFAILED);
285 PKIX_CHECK(
286 pkix_List_BubbleSort(unsortedList,
287 pkix_RevocationChecker_SortComparator,
288 methodList, plContext),
289 PKIX_LISTBUBBLESORTFAILED);
290
291 cleanup:
292 PKIX_DECREF(method);
293 PKIX_DECREF(unsortedList);
294 PKIX_DECREF(certStores);
295
296 PKIX_RETURN(REVOCATIONCHECKER);
297 }
298
299 /*
300 * FUNCTION: PKIX_RevocationChecker_Check
301 */
302 PKIX_Error *
303 PKIX_RevocationChecker_Check(
304 PKIX_PL_Cert *cert,
305 PKIX_PL_Cert *issuer,
306 PKIX_RevocationChecker *revChecker,
307 PKIX_ProcessingParams *procParams,
308 PKIX_Boolean chainVerificationState,
309 PKIX_Boolean testingLeafCert,
310 PKIX_RevocationStatus *pRevStatus,
311 PKIX_UInt32 *pReasonCode,
312 void **pNbioContext,
313 void *plContext)
314 {
315 PKIX_RevocationStatus overallStatus = PKIX_RevStatus_NoInfo;
316 PKIX_RevocationStatus methodStatus[PKIX_RevocationMethod_MAX];
317 PKIX_Boolean onlyUseRemoteMethods = PKIX_FALSE;
318 PKIX_UInt32 revFlags = 0;
319 PKIX_List *revList = NULL;
320 PKIX_PL_Date *date = NULL;
321 pkix_RevocationMethod *method = NULL;
322 void *nbioContext;
323 int tries;
324
325 PKIX_ENTER(REVOCATIONCHECKER, "PKIX_RevocationChecker_Check");
326 PKIX_NULLCHECK_TWO(revChecker, procParams);
327
328 nbioContext = *pNbioContext;
329 *pNbioContext = NULL;
330
331 if (testingLeafCert) {
332 revList = revChecker->leafMethodList;
333 revFlags = revChecker->leafMethodListFlags;
334 } else {
335 revList = revChecker->chainMethodList;
336 revFlags = revChecker->chainMethodListFlags;
337 }
338 if (!revList) {
339 /* Return NoInfo status */
340 goto cleanup;
341 }
342
343 PORT_Memset(methodStatus, PKIX_RevStatus_NoInfo,
344 sizeof(PKIX_RevocationStatus) * PKIX_RevocationMethod_MAX);
345
346 date = procParams->date;
347
348 /* Need to have two loops if we testing all local info first:
349 * first we are going to test all local(cached) info
350 * second, all remote info(fetching) */
351 for (tries = 0;tries < 2;tries++) {
352 unsigned int methodNum = 0;
353 for (;methodNum < revList->length;methodNum++) {
354 PKIX_UInt32 methodFlags = 0;
355
356 PKIX_DECREF(method);
357 PKIX_CHECK(
358 PKIX_List_GetItem(revList, methodNum,
359 (PKIX_PL_Object**)&method, plContext),
360 PKIX_LISTGETITEMFAILED);
361 methodFlags = method->flags;
362 if (!(methodFlags & PKIX_REV_M_TEST_USING_THIS_METHOD)) {
363 /* Will not check with this method. Skipping... */
364 continue;
365 }
366 if (!onlyUseRemoteMethods &&
367 methodStatus[methodNum] == PKIX_RevStatus_NoInfo) {
368 PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo;
369 PKIX_CHECK_NO_GOTO(
370 (*method->localRevChecker)(cert, issuer, date,
371 method, procParams,
372 methodFlags,
373 chainVerificationState,
374 &revStatus,
375 (CERTCRLEntryReasonCode *)pReason Code,
376 plContext),
377 PKIX_REVCHECKERCHECKFAILED);
378 methodStatus[methodNum] = revStatus;
379 if (revStatus == PKIX_RevStatus_Revoked) {
380 /* if error was generated use it as final error. */
381 overallStatus = PKIX_RevStatus_Revoked;
382 goto cleanup;
383 }
384 if (pkixErrorResult) {
385 /* Disregard errors. Only returned revStatus matters. */
386 PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixErrorResult,
387 plContext);
388 pkixErrorResult = NULL;
389 }
390 }
391 if ((!(revFlags & PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST) ||
392 onlyUseRemoteMethods) &&
393 chainVerificationState &&
394 methodStatus[methodNum] == PKIX_RevStatus_NoInfo) {
395 if (!(methodFlags & PKIX_REV_M_FORBID_NETWORK_FETCHING)) {
396 PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo;
397 PKIX_CHECK_NO_GOTO(
398 (*method->externalRevChecker)(cert, issuer, date,
399 method,
400 procParams, methodFlags,
401 &revStatus,
402 (CERTCRLEntryReasonCode *) pReasonCode,
403 &nbioContext, plContext),
404 PKIX_REVCHECKERCHECKFAILED);
405 methodStatus[methodNum] = revStatus;
406 if (revStatus == PKIX_RevStatus_Revoked) {
407 /* if error was generated use it as final error. */
408 overallStatus = PKIX_RevStatus_Revoked;
409 goto cleanup;
410 }
411 if (pkixErrorResult) {
412 /* Disregard errors. Only returned revStatus matters. */
413 PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixErrorResult,
414 plContext);
415 pkixErrorResult = NULL;
416 }
417 } else if (methodFlags &
418 PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO) {
419 /* Info is not in the local cache. Network fetching is not
420 * allowed. If need to fail on missing fresh info for the
421 * the method, then we should fail right here.*/
422 overallStatus = PKIX_RevStatus_Revoked;
423 goto cleanup;
424 }
425 }
426 /* If success and we should not check the next method, then
427 * return a success. */
428 if (methodStatus[methodNum] == PKIX_RevStatus_Success &&
429 !(methodFlags & PKIX_REV_M_CONTINUE_TESTING_ON_FRESH_INFO)) {
430 overallStatus = PKIX_RevStatus_Success;
431 goto cleanup;
432 }
433 } /* inner loop */
434 if (!onlyUseRemoteMethods &&
435 revFlags & PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST &&
436 chainVerificationState) {
437 onlyUseRemoteMethods = PKIX_TRUE;
438 continue;
439 }
440 break;
441 } /* outer loop */
442
443 if (overallStatus == PKIX_RevStatus_NoInfo &&
444 chainVerificationState) {
445 /* The following check makes sence only for chain
446 * validation step, sinse we do not fetch info while
447 * in the process of finding trusted anchor.
448 * For chain building step it is enough to know, that
449 * the cert was not directly revoked by any of the
450 * methods. */
451
452 /* Still have no info. But one of the method could
453 * have returned success status(possible if CONTINUE
454 * TESTING ON FRESH INFO flag was used).
455 * If any of the methods have returned Success status,
456 * the overallStatus should be success. */
457 int methodNum = 0;
458 for (;methodNum < PKIX_RevocationMethod_MAX;methodNum++) {
459 if (methodStatus[methodNum] == PKIX_RevStatus_Success) {
460 overallStatus = PKIX_RevStatus_Success;
461 goto cleanup;
462 }
463 }
464 if (revFlags & PKIX_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE) {
465 overallStatus = PKIX_RevStatus_Revoked;
466 }
467 }
468
469 cleanup:
470 *pRevStatus = overallStatus;
471 PKIX_DECREF(method);
472
473 PKIX_RETURN(REVOCATIONCHECKER);
474 }
475
OLDNEW
« no previous file with comments | « nss/lib/libpkix/pkix/checker/pkix_revocationchecker.h ('k') | nss/lib/libpkix/pkix/checker/pkix_revocationmethod.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698