Mercurial > trustbridge > nss-cmake-static
comparison nss/lib/libpkix/pkix/checker/pkix_revocationchecker.c @ 0:1e5118fa0cb1
This is NSS with a Cmake Buildsyste
To compile a static NSS library for Windows we've used the
Chromium-NSS fork and added a Cmake buildsystem to compile
it statically for Windows. See README.chromium for chromium
changes and README.trustbridge for our modifications.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 28 Jul 2014 10:47:06 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e5118fa0cb1 |
---|---|
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 theirs priorities */ | |
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 *pResult = (method1->priority > method2->priority); | |
156 | |
157 PKIX_RETURN(BUILD); | |
158 } | |
159 | |
160 | |
161 /* --Public-Functions--------------------------------------------- */ | |
162 | |
163 | |
164 /* | |
165 * FUNCTION: PKIX_RevocationChecker_Create (see comments in pkix_revchecker.h) | |
166 */ | |
167 PKIX_Error * | |
168 PKIX_RevocationChecker_Create( | |
169 PKIX_UInt32 leafMethodListFlags, | |
170 PKIX_UInt32 chainMethodListFlags, | |
171 PKIX_RevocationChecker **pChecker, | |
172 void *plContext) | |
173 { | |
174 PKIX_RevocationChecker *checker = NULL; | |
175 | |
176 PKIX_ENTER(REVOCATIONCHECKER, "PKIX_RevocationChecker_Create"); | |
177 PKIX_NULLCHECK_ONE(pChecker); | |
178 | |
179 PKIX_CHECK( | |
180 PKIX_PL_Object_Alloc(PKIX_REVOCATIONCHECKER_TYPE, | |
181 sizeof (PKIX_RevocationChecker), | |
182 (PKIX_PL_Object **)&checker, | |
183 plContext), | |
184 PKIX_COULDNOTCREATECERTCHAINCHECKEROBJECT); | |
185 | |
186 checker->leafMethodListFlags = leafMethodListFlags; | |
187 checker->chainMethodListFlags = chainMethodListFlags; | |
188 checker->leafMethodList = NULL; | |
189 checker->chainMethodList = NULL; | |
190 | |
191 *pChecker = checker; | |
192 checker = NULL; | |
193 | |
194 cleanup: | |
195 PKIX_DECREF(checker); | |
196 | |
197 PKIX_RETURN(REVOCATIONCHECKER); | |
198 } | |
199 | |
200 /* | |
201 * FUNCTION: PKIX_RevocationChecker_CreateAndAddMethod | |
202 */ | |
203 PKIX_Error * | |
204 PKIX_RevocationChecker_CreateAndAddMethod( | |
205 PKIX_RevocationChecker *revChecker, | |
206 PKIX_ProcessingParams *params, | |
207 PKIX_RevocationMethodType methodType, | |
208 PKIX_UInt32 flags, | |
209 PKIX_UInt32 priority, | |
210 PKIX_PL_VerifyCallback verificationFn, | |
211 PKIX_Boolean isLeafMethod, | |
212 void *plContext) | |
213 { | |
214 PKIX_List **methodList = NULL; | |
215 PKIX_List *unsortedList = NULL; | |
216 PKIX_List *certStores = NULL; | |
217 pkix_RevocationMethod *method = NULL; | |
218 pkix_LocalRevocationCheckFn *localRevChecker = NULL; | |
219 pkix_ExternalRevocationCheckFn *externRevChecker = NULL; | |
220 PKIX_UInt32 miFlags; | |
221 | |
222 PKIX_ENTER(REVOCATIONCHECKER, "PKIX_RevocationChecker_CreateAndAddMethod"); | |
223 PKIX_NULLCHECK_ONE(revChecker); | |
224 | |
225 /* If the caller has said "Either one is sufficient, then don't let the | |
226 * absence of any one method's info lead to an overall failure. | |
227 */ | |
228 miFlags = isLeafMethod ? revChecker->leafMethodListFlags | |
229 : revChecker->chainMethodListFlags; | |
230 if (miFlags & PKIX_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE) | |
231 flags &= ~PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO; | |
232 | |
233 switch (methodType) { | |
234 case PKIX_RevocationMethod_CRL: | |
235 localRevChecker = pkix_CrlChecker_CheckLocal; | |
236 externRevChecker = pkix_CrlChecker_CheckExternal; | |
237 PKIX_CHECK( | |
238 PKIX_ProcessingParams_GetCertStores(params, &certStores, | |
239 plContext), | |
240 PKIX_PROCESSINGPARAMSGETCERTSTORESFAILED); | |
241 PKIX_CHECK( | |
242 pkix_CrlChecker_Create(methodType, flags, priority, | |
243 localRevChecker, externRevChecker, | |
244 certStores, verificationFn, | |
245 &method, | |
246 plContext), | |
247 PKIX_COULDNOTCREATECRLCHECKEROBJECT); | |
248 break; | |
249 case PKIX_RevocationMethod_OCSP: | |
250 localRevChecker = pkix_OcspChecker_CheckLocal; | |
251 externRevChecker = pkix_OcspChecker_CheckExternal; | |
252 PKIX_CHECK( | |
253 pkix_OcspChecker_Create(methodType, flags, priority, | |
254 localRevChecker, externRevChecker, | |
255 verificationFn, | |
256 &method, | |
257 plContext), | |
258 PKIX_COULDNOTCREATEOCSPCHECKEROBJECT); | |
259 break; | |
260 default: | |
261 PKIX_ERROR(PKIX_INVALIDREVOCATIONMETHOD); | |
262 } | |
263 | |
264 if (isLeafMethod) { | |
265 methodList = &revChecker->leafMethodList; | |
266 } else { | |
267 methodList = &revChecker->chainMethodList; | |
268 } | |
269 | |
270 if (*methodList == NULL) { | |
271 PKIX_CHECK( | |
272 PKIX_List_Create(methodList, plContext), | |
273 PKIX_LISTCREATEFAILED); | |
274 } | |
275 unsortedList = *methodList; | |
276 PKIX_CHECK( | |
277 PKIX_List_AppendItem(unsortedList, (PKIX_PL_Object*)method, plContext), | |
278 PKIX_LISTAPPENDITEMFAILED); | |
279 PKIX_CHECK( | |
280 pkix_List_BubbleSort(unsortedList, | |
281 pkix_RevocationChecker_SortComparator, | |
282 methodList, plContext), | |
283 PKIX_LISTBUBBLESORTFAILED); | |
284 | |
285 cleanup: | |
286 PKIX_DECREF(method); | |
287 PKIX_DECREF(unsortedList); | |
288 PKIX_DECREF(certStores); | |
289 | |
290 PKIX_RETURN(REVOCATIONCHECKER); | |
291 } | |
292 | |
293 /* | |
294 * FUNCTION: PKIX_RevocationChecker_Check | |
295 */ | |
296 PKIX_Error * | |
297 PKIX_RevocationChecker_Check( | |
298 PKIX_PL_Cert *cert, | |
299 PKIX_PL_Cert *issuer, | |
300 PKIX_RevocationChecker *revChecker, | |
301 PKIX_ProcessingParams *procParams, | |
302 PKIX_Boolean chainVerificationState, | |
303 PKIX_Boolean testingLeafCert, | |
304 PKIX_RevocationStatus *pRevStatus, | |
305 PKIX_UInt32 *pReasonCode, | |
306 void **pNbioContext, | |
307 void *plContext) | |
308 { | |
309 PKIX_RevocationStatus overallStatus = PKIX_RevStatus_NoInfo; | |
310 PKIX_RevocationStatus methodStatus[PKIX_RevocationMethod_MAX]; | |
311 PKIX_Boolean onlyUseRemoteMethods = PKIX_FALSE; | |
312 PKIX_UInt32 revFlags = 0; | |
313 PKIX_List *revList = NULL; | |
314 PKIX_PL_Date *date = NULL; | |
315 pkix_RevocationMethod *method = NULL; | |
316 void *nbioContext; | |
317 int tries; | |
318 | |
319 PKIX_ENTER(REVOCATIONCHECKER, "PKIX_RevocationChecker_Check"); | |
320 PKIX_NULLCHECK_TWO(revChecker, procParams); | |
321 | |
322 nbioContext = *pNbioContext; | |
323 *pNbioContext = NULL; | |
324 | |
325 if (testingLeafCert) { | |
326 revList = revChecker->leafMethodList; | |
327 revFlags = revChecker->leafMethodListFlags; | |
328 } else { | |
329 revList = revChecker->chainMethodList; | |
330 revFlags = revChecker->chainMethodListFlags; | |
331 } | |
332 if (!revList) { | |
333 /* Return NoInfo status */ | |
334 goto cleanup; | |
335 } | |
336 | |
337 PORT_Memset(methodStatus, PKIX_RevStatus_NoInfo, | |
338 sizeof(PKIX_RevocationStatus) * PKIX_RevocationMethod_MAX); | |
339 | |
340 date = procParams->date; | |
341 | |
342 /* Need to have two loops if we testing all local info first: | |
343 * first we are going to test all local(cached) info | |
344 * second, all remote info(fetching) */ | |
345 for (tries = 0;tries < 2;tries++) { | |
346 int methodNum = 0; | |
347 for (;methodNum < revList->length;methodNum++) { | |
348 PKIX_UInt32 methodFlags = 0; | |
349 | |
350 PKIX_DECREF(method); | |
351 PKIX_CHECK( | |
352 PKIX_List_GetItem(revList, methodNum, | |
353 (PKIX_PL_Object**)&method, plContext), | |
354 PKIX_LISTGETITEMFAILED); | |
355 methodFlags = method->flags; | |
356 if (!(methodFlags & PKIX_REV_M_TEST_USING_THIS_METHOD)) { | |
357 /* Will not check with this method. Skipping... */ | |
358 continue; | |
359 } | |
360 if (!onlyUseRemoteMethods && | |
361 methodStatus[methodNum] == PKIX_RevStatus_NoInfo) { | |
362 PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo; | |
363 PKIX_CHECK_NO_GOTO( | |
364 (*method->localRevChecker)(cert, issuer, date, | |
365 method, procParams, | |
366 methodFlags, | |
367 chainVerificationState, | |
368 &revStatus, | |
369 pReasonCode, plContext), | |
370 PKIX_REVCHECKERCHECKFAILED); | |
371 methodStatus[methodNum] = revStatus; | |
372 if (revStatus == PKIX_RevStatus_Revoked) { | |
373 /* if error was generated use it as final error. */ | |
374 overallStatus = PKIX_RevStatus_Revoked; | |
375 goto cleanup; | |
376 } | |
377 if (pkixErrorResult) { | |
378 /* Disregard errors. Only returned revStatus matters. */ | |
379 PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixErrorResult, | |
380 plContext); | |
381 pkixErrorResult = NULL; | |
382 } | |
383 } | |
384 if ((!(revFlags & PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST) || | |
385 onlyUseRemoteMethods) && | |
386 chainVerificationState && | |
387 methodStatus[methodNum] == PKIX_RevStatus_NoInfo) { | |
388 if (!(methodFlags & PKIX_REV_M_FORBID_NETWORK_FETCHING)) { | |
389 PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo; | |
390 PKIX_CHECK_NO_GOTO( | |
391 (*method->externalRevChecker)(cert, issuer, date, | |
392 method, | |
393 procParams, methodFlags, | |
394 &revStatus, pReasonCode, | |
395 &nbioContext, plContext), | |
396 PKIX_REVCHECKERCHECKFAILED); | |
397 methodStatus[methodNum] = revStatus; | |
398 if (revStatus == PKIX_RevStatus_Revoked) { | |
399 /* if error was generated use it as final error. */ | |
400 overallStatus = PKIX_RevStatus_Revoked; | |
401 goto cleanup; | |
402 } | |
403 if (pkixErrorResult) { | |
404 /* Disregard errors. Only returned revStatus matters. */ | |
405 PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixErrorResult, | |
406 plContext); | |
407 pkixErrorResult = NULL; | |
408 } | |
409 } else if (methodFlags & | |
410 PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO) { | |
411 /* Info is not in the local cache. Network fetching is not | |
412 * allowed. If need to fail on missing fresh info for the | |
413 * the method, then we should fail right here.*/ | |
414 overallStatus = PKIX_RevStatus_Revoked; | |
415 goto cleanup; | |
416 } | |
417 } | |
418 /* If success and we should not check the next method, then | |
419 * return a success. */ | |
420 if (methodStatus[methodNum] == PKIX_RevStatus_Success && | |
421 !(methodFlags & PKIX_REV_M_CONTINUE_TESTING_ON_FRESH_INFO)) { | |
422 overallStatus = PKIX_RevStatus_Success; | |
423 goto cleanup; | |
424 } | |
425 } /* inner loop */ | |
426 if (!onlyUseRemoteMethods && | |
427 revFlags & PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST && | |
428 chainVerificationState) { | |
429 onlyUseRemoteMethods = PKIX_TRUE; | |
430 continue; | |
431 } | |
432 break; | |
433 } /* outer loop */ | |
434 | |
435 if (overallStatus == PKIX_RevStatus_NoInfo && | |
436 chainVerificationState) { | |
437 /* The following check makes sence only for chain | |
438 * validation step, sinse we do not fetch info while | |
439 * in the process of finding trusted anchor. | |
440 * For chain building step it is enough to know, that | |
441 * the cert was not directly revoked by any of the | |
442 * methods. */ | |
443 | |
444 /* Still have no info. But one of the method could | |
445 * have returned success status(possible if CONTINUE | |
446 * TESTING ON FRESH INFO flag was used). | |
447 * If any of the methods have returned Success status, | |
448 * the overallStatus should be success. */ | |
449 int methodNum = 0; | |
450 for (;methodNum < PKIX_RevocationMethod_MAX;methodNum++) { | |
451 if (methodStatus[methodNum] == PKIX_RevStatus_Success) { | |
452 overallStatus = PKIX_RevStatus_Success; | |
453 goto cleanup; | |
454 } | |
455 } | |
456 if (revFlags & PKIX_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE) { | |
457 overallStatus = PKIX_RevStatus_Revoked; | |
458 } | |
459 } | |
460 | |
461 cleanup: | |
462 *pRevStatus = overallStatus; | |
463 PKIX_DECREF(method); | |
464 | |
465 PKIX_RETURN(REVOCATIONCHECKER); | |
466 } | |
467 |