Mercurial > trustbridge > nss-cmake-static
comparison nss/lib/libpkix/pkix/checker/pkix_policychecker.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_policychecker.c | |
6 * | |
7 * Functions for Policy Checker | |
8 * | |
9 */ | |
10 #include "pkix_policychecker.h" | |
11 | |
12 /* --Forward declarations----------------------------------------------- */ | |
13 | |
14 static PKIX_Error * | |
15 pkix_PolicyChecker_MakeSingleton( | |
16 PKIX_PL_Object *listItem, | |
17 PKIX_Boolean immutability, | |
18 PKIX_List **pList, | |
19 void *plContext); | |
20 | |
21 /* --Private-PolicyCheckerState-Functions---------------------------------- */ | |
22 | |
23 /* | |
24 * FUNCTION:pkix_PolicyCheckerState_Destroy | |
25 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) | |
26 */ | |
27 static PKIX_Error * | |
28 pkix_PolicyCheckerState_Destroy( | |
29 PKIX_PL_Object *object, | |
30 void *plContext) | |
31 { | |
32 PKIX_PolicyCheckerState *checkerState = NULL; | |
33 | |
34 PKIX_ENTER(CERTPOLICYCHECKERSTATE, "pkix_PolicyCheckerState_Destroy"); | |
35 PKIX_NULLCHECK_ONE(object); | |
36 | |
37 PKIX_CHECK(pkix_CheckType | |
38 (object, PKIX_CERTPOLICYCHECKERSTATE_TYPE, plContext), | |
39 PKIX_OBJECTNOTPOLICYCHECKERSTATE); | |
40 | |
41 checkerState = (PKIX_PolicyCheckerState *)object; | |
42 | |
43 PKIX_DECREF(checkerState->certPoliciesExtension); | |
44 PKIX_DECREF(checkerState->policyMappingsExtension); | |
45 PKIX_DECREF(checkerState->policyConstraintsExtension); | |
46 PKIX_DECREF(checkerState->inhibitAnyPolicyExtension); | |
47 PKIX_DECREF(checkerState->anyPolicyOID); | |
48 PKIX_DECREF(checkerState->validPolicyTree); | |
49 PKIX_DECREF(checkerState->userInitialPolicySet); | |
50 PKIX_DECREF(checkerState->mappedUserInitialPolicySet); | |
51 | |
52 checkerState->policyQualifiersRejected = PKIX_FALSE; | |
53 checkerState->explicitPolicy = 0; | |
54 checkerState->inhibitAnyPolicy = 0; | |
55 checkerState->policyMapping = 0; | |
56 checkerState->numCerts = 0; | |
57 checkerState->certsProcessed = 0; | |
58 checkerState->certPoliciesCritical = PKIX_FALSE; | |
59 | |
60 PKIX_DECREF(checkerState->anyPolicyNodeAtBottom); | |
61 PKIX_DECREF(checkerState->newAnyPolicyNode); | |
62 PKIX_DECREF(checkerState->mappedPolicyOIDs); | |
63 | |
64 cleanup: | |
65 | |
66 PKIX_RETURN(CERTPOLICYCHECKERSTATE); | |
67 } | |
68 | |
69 /* | |
70 * FUNCTION: pkix_PolicyCheckerState_ToString | |
71 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) | |
72 */ | |
73 static PKIX_Error * | |
74 pkix_PolicyCheckerState_ToString( | |
75 PKIX_PL_Object *object, | |
76 PKIX_PL_String **pCheckerStateString, | |
77 void *plContext) | |
78 { | |
79 PKIX_PolicyCheckerState *state = NULL; | |
80 PKIX_PL_String *resultString = NULL; | |
81 PKIX_PL_String *policiesExtOIDString = NULL; | |
82 PKIX_PL_String *policyMapOIDString = NULL; | |
83 PKIX_PL_String *policyConstrOIDString = NULL; | |
84 PKIX_PL_String *inhAnyPolOIDString = NULL; | |
85 PKIX_PL_String *anyPolicyOIDString = NULL; | |
86 PKIX_PL_String *validPolicyTreeString = NULL; | |
87 PKIX_PL_String *userInitialPolicySetString = NULL; | |
88 PKIX_PL_String *mappedUserPolicySetString = NULL; | |
89 PKIX_PL_String *mappedPolicyOIDsString = NULL; | |
90 PKIX_PL_String *anyAtBottomString = NULL; | |
91 PKIX_PL_String *newAnyPolicyString = NULL; | |
92 PKIX_PL_String *formatString = NULL; | |
93 PKIX_PL_String *trueString = NULL; | |
94 PKIX_PL_String *falseString = NULL; | |
95 PKIX_PL_String *nullString = NULL; | |
96 PKIX_Boolean initialPolicyMappingInhibit = PKIX_FALSE; | |
97 PKIX_Boolean initialExplicitPolicy = PKIX_FALSE; | |
98 PKIX_Boolean initialAnyPolicyInhibit = PKIX_FALSE; | |
99 PKIX_Boolean initialIsAnyPolicy = PKIX_FALSE; | |
100 PKIX_Boolean policyQualifiersRejected = PKIX_FALSE; | |
101 PKIX_Boolean certPoliciesCritical = PKIX_FALSE; | |
102 char *asciiFormat = | |
103 "{\n" | |
104 "\tcertPoliciesExtension: \t%s\n" | |
105 "\tpolicyMappingsExtension: \t%s\n" | |
106 "\tpolicyConstraintsExtension:\t%s\n" | |
107 "\tinhibitAnyPolicyExtension:\t%s\n" | |
108 "\tanyPolicyOID: \t%s\n" | |
109 "\tinitialIsAnyPolicy: \t%s\n" | |
110 "\tvalidPolicyTree: \t%s\n" | |
111 "\tuserInitialPolicySet: \t%s\n" | |
112 "\tmappedUserPolicySet: \t%s\n" | |
113 "\tpolicyQualifiersRejected: \t%s\n" | |
114 "\tinitialPolMappingInhibit: \t%s\n" | |
115 "\tinitialExplicitPolicy: \t%s\n" | |
116 "\tinitialAnyPolicyInhibit: \t%s\n" | |
117 "\texplicitPolicy: \t%d\n" | |
118 "\tinhibitAnyPolicy: \t%d\n" | |
119 "\tpolicyMapping: \t%d\n" | |
120 "\tnumCerts: \t%d\n" | |
121 "\tcertsProcessed: \t%d\n" | |
122 "\tanyPolicyNodeAtBottom: \t%s\n" | |
123 "\tnewAnyPolicyNode: \t%s\n" | |
124 "\tcertPoliciesCritical: \t%s\n" | |
125 "\tmappedPolicyOIDs: \t%s\n" | |
126 "}"; | |
127 | |
128 PKIX_ENTER(CERTPOLICYCHECKERSTATE, "pkix_PolicyCheckerState_ToString"); | |
129 | |
130 PKIX_NULLCHECK_TWO(object, pCheckerStateString); | |
131 | |
132 PKIX_CHECK(pkix_CheckType | |
133 (object, PKIX_CERTPOLICYCHECKERSTATE_TYPE, plContext), | |
134 PKIX_OBJECTNOTPOLICYCHECKERSTATE); | |
135 | |
136 state = (PKIX_PolicyCheckerState *)object; | |
137 PKIX_NULLCHECK_THREE | |
138 (state->certPoliciesExtension, | |
139 state->policyMappingsExtension, | |
140 state->policyConstraintsExtension); | |
141 PKIX_NULLCHECK_THREE | |
142 (state->inhibitAnyPolicyExtension, | |
143 state->anyPolicyOID, | |
144 state->userInitialPolicySet); | |
145 | |
146 PKIX_CHECK(PKIX_PL_String_Create | |
147 (PKIX_ESCASCII, asciiFormat, 0, &formatString, plContext), | |
148 PKIX_STRINGCREATEFAILED); | |
149 /* | |
150 * Create TRUE, FALSE, and "NULL" PKIX_PL_Strings. But creating a | |
151 * PKIX_PL_String is complicated enough, it's worth checking, for | |
152 * each, to make sure the string is needed. | |
153 */ | |
154 initialPolicyMappingInhibit = state->initialPolicyMappingInhibit; | |
155 initialExplicitPolicy = state->initialExplicitPolicy; | |
156 initialAnyPolicyInhibit = state->initialAnyPolicyInhibit; | |
157 initialIsAnyPolicy = state->initialIsAnyPolicy; | |
158 policyQualifiersRejected = state->policyQualifiersRejected; | |
159 certPoliciesCritical = state->certPoliciesCritical; | |
160 | |
161 if (initialPolicyMappingInhibit || initialExplicitPolicy || | |
162 initialAnyPolicyInhibit || initialIsAnyPolicy || | |
163 policyQualifiersRejected || certPoliciesCritical) { | |
164 PKIX_CHECK(PKIX_PL_String_Create | |
165 (PKIX_ESCASCII, "TRUE", 0, &trueString, plContext), | |
166 PKIX_STRINGCREATEFAILED); | |
167 } | |
168 if (!initialPolicyMappingInhibit || !initialExplicitPolicy || | |
169 !initialAnyPolicyInhibit || !initialIsAnyPolicy || | |
170 !policyQualifiersRejected || !certPoliciesCritical) { | |
171 PKIX_CHECK(PKIX_PL_String_Create | |
172 (PKIX_ESCASCII, "FALSE", 0, &falseString, plContext), | |
173 PKIX_STRINGCREATEFAILED); | |
174 } | |
175 if (!(state->anyPolicyNodeAtBottom) || !(state->newAnyPolicyNode)) { | |
176 PKIX_CHECK(PKIX_PL_String_Create | |
177 (PKIX_ESCASCII, "(null)", 0, &nullString, plContext), | |
178 PKIX_STRINGCREATEFAILED); | |
179 } | |
180 | |
181 PKIX_TOSTRING | |
182 (state->certPoliciesExtension, &policiesExtOIDString, plContext, | |
183 PKIX_OBJECTTOSTRINGFAILED); | |
184 | |
185 PKIX_TOSTRING | |
186 (state->policyMappingsExtension, | |
187 &policyMapOIDString, | |
188 plContext, | |
189 PKIX_OBJECTTOSTRINGFAILED); | |
190 | |
191 PKIX_TOSTRING | |
192 (state->policyConstraintsExtension, | |
193 &policyConstrOIDString, | |
194 plContext, | |
195 PKIX_OBJECTTOSTRINGFAILED); | |
196 | |
197 PKIX_TOSTRING | |
198 (state->inhibitAnyPolicyExtension, | |
199 &inhAnyPolOIDString, | |
200 plContext, | |
201 PKIX_OBJECTTOSTRINGFAILED); | |
202 | |
203 PKIX_TOSTRING(state->anyPolicyOID, &anyPolicyOIDString, plContext, | |
204 PKIX_OBJECTTOSTRINGFAILED); | |
205 | |
206 PKIX_TOSTRING(state->validPolicyTree, &validPolicyTreeString, plContext, | |
207 PKIX_OBJECTTOSTRINGFAILED); | |
208 | |
209 PKIX_TOSTRING | |
210 (state->userInitialPolicySet, | |
211 &userInitialPolicySetString, | |
212 plContext, | |
213 PKIX_OBJECTTOSTRINGFAILED); | |
214 | |
215 PKIX_TOSTRING | |
216 (state->mappedUserInitialPolicySet, | |
217 &mappedUserPolicySetString, | |
218 plContext, | |
219 PKIX_OBJECTTOSTRINGFAILED); | |
220 | |
221 if (state->anyPolicyNodeAtBottom) { | |
222 PKIX_CHECK(pkix_SinglePolicyNode_ToString | |
223 (state->anyPolicyNodeAtBottom, | |
224 &anyAtBottomString, | |
225 plContext), | |
226 PKIX_SINGLEPOLICYNODETOSTRINGFAILED); | |
227 } else { | |
228 PKIX_INCREF(nullString); | |
229 anyAtBottomString = nullString; | |
230 } | |
231 | |
232 if (state->newAnyPolicyNode) { | |
233 PKIX_CHECK(pkix_SinglePolicyNode_ToString | |
234 (state->newAnyPolicyNode, | |
235 &newAnyPolicyString, | |
236 plContext), | |
237 PKIX_SINGLEPOLICYNODETOSTRINGFAILED); | |
238 } else { | |
239 PKIX_INCREF(nullString); | |
240 newAnyPolicyString = nullString; | |
241 } | |
242 | |
243 PKIX_TOSTRING | |
244 (state->mappedPolicyOIDs, | |
245 &mappedPolicyOIDsString, | |
246 plContext, | |
247 PKIX_OBJECTTOSTRINGFAILED); | |
248 | |
249 PKIX_CHECK(PKIX_PL_Sprintf | |
250 (&resultString, | |
251 plContext, | |
252 formatString, | |
253 policiesExtOIDString, | |
254 policyMapOIDString, | |
255 policyConstrOIDString, | |
256 inhAnyPolOIDString, | |
257 anyPolicyOIDString, | |
258 initialIsAnyPolicy?trueString:falseString, | |
259 validPolicyTreeString, | |
260 userInitialPolicySetString, | |
261 mappedUserPolicySetString, | |
262 policyQualifiersRejected?trueString:falseString, | |
263 initialPolicyMappingInhibit?trueString:falseString, | |
264 initialExplicitPolicy?trueString:falseString, | |
265 initialAnyPolicyInhibit?trueString:falseString, | |
266 state->explicitPolicy, | |
267 state->inhibitAnyPolicy, | |
268 state->policyMapping, | |
269 state->numCerts, | |
270 state->certsProcessed, | |
271 anyAtBottomString, | |
272 newAnyPolicyString, | |
273 certPoliciesCritical?trueString:falseString, | |
274 mappedPolicyOIDsString), | |
275 PKIX_SPRINTFFAILED); | |
276 | |
277 *pCheckerStateString = resultString; | |
278 | |
279 cleanup: | |
280 PKIX_DECREF(policiesExtOIDString); | |
281 PKIX_DECREF(policyMapOIDString); | |
282 PKIX_DECREF(policyConstrOIDString); | |
283 PKIX_DECREF(inhAnyPolOIDString); | |
284 PKIX_DECREF(anyPolicyOIDString); | |
285 PKIX_DECREF(validPolicyTreeString); | |
286 PKIX_DECREF(userInitialPolicySetString); | |
287 PKIX_DECREF(mappedUserPolicySetString); | |
288 PKIX_DECREF(anyAtBottomString); | |
289 PKIX_DECREF(newAnyPolicyString); | |
290 PKIX_DECREF(mappedPolicyOIDsString); | |
291 PKIX_DECREF(formatString); | |
292 PKIX_DECREF(trueString); | |
293 PKIX_DECREF(falseString); | |
294 PKIX_DECREF(nullString); | |
295 | |
296 PKIX_RETURN(CERTPOLICYCHECKERSTATE); | |
297 } | |
298 | |
299 /* | |
300 * FUNCTION: pkix_PolicyCheckerState_RegisterSelf | |
301 * DESCRIPTION: | |
302 * | |
303 * Registers PKIX_POLICYCHECKERSTATE_TYPE and its related functions | |
304 * with systemClasses[] | |
305 * | |
306 * PARAMETERS: | |
307 * "plContext" | |
308 * Platform-specific context pointer. | |
309 * THREAD SAFETY: | |
310 * Not Thread Safe - for performance and complexity reasons | |
311 * | |
312 * Since this function is only called by PKIX_PL_Initialize, which should | |
313 * only be called once, it is acceptable that this function is not | |
314 * thread-safe. | |
315 */ | |
316 PKIX_Error * | |
317 pkix_PolicyCheckerState_RegisterSelf(void *plContext) | |
318 { | |
319 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; | |
320 pkix_ClassTable_Entry entry; | |
321 | |
322 PKIX_ENTER | |
323 (CERTPOLICYCHECKERSTATE, | |
324 "pkix_PolicyCheckerState_RegisterSelf"); | |
325 | |
326 entry.description = "PolicyCheckerState"; | |
327 entry.objCounter = 0; | |
328 entry.typeObjectSize = sizeof(PKIX_PolicyCheckerState); | |
329 entry.destructor = pkix_PolicyCheckerState_Destroy; | |
330 entry.equalsFunction = NULL; | |
331 entry.hashcodeFunction = NULL; | |
332 entry.toStringFunction = pkix_PolicyCheckerState_ToString; | |
333 entry.comparator = NULL; | |
334 entry.duplicateFunction = NULL; | |
335 | |
336 systemClasses[PKIX_CERTPOLICYCHECKERSTATE_TYPE] = entry; | |
337 | |
338 PKIX_RETURN(CERTPOLICYCHECKERSTATE); | |
339 } | |
340 | |
341 /* | |
342 * FUNCTION:pkix_PolicyCheckerState_Create | |
343 * DESCRIPTION: | |
344 * | |
345 * Creates a PolicyCheckerState Object, using the List pointed to | |
346 * by "initialPolicies" for the user-initial-policy-set, the Boolean value | |
347 * of "policyQualifiersRejected" for the policyQualifiersRejected parameter, | |
348 * the Boolean value of "initialPolicyMappingInhibit" for the | |
349 * inhibitPolicyMappings parameter, the Boolean value of | |
350 * "initialExplicitPolicy" for the initialExplicitPolicy parameter, the | |
351 * Boolean value of "initialAnyPolicyInhibit" for the inhibitAnyPolicy | |
352 * parameter, and the UInt32 value of "numCerts" as the number of | |
353 * certificates in the chain; and stores the Object at "pCheckerState". | |
354 * | |
355 * PARAMETERS: | |
356 * "initialPolicies" | |
357 * Address of List of OIDs comprising the user-initial-policy-set; the List | |
358 * may be empty, but must be non-NULL | |
359 * "policyQualifiersRejected" | |
360 * Boolean value of the policyQualifiersRejected parameter | |
361 * "initialPolicyMappingInhibit" | |
362 * Boolean value of the inhibitPolicyMappings parameter | |
363 * "initialExplicitPolicy" | |
364 * Boolean value of the initialExplicitPolicy parameter | |
365 * "initialAnyPolicyInhibit" | |
366 * Boolean value of the inhibitAnyPolicy parameter | |
367 * "numCerts" | |
368 * Number of certificates in the chain to be validated | |
369 * "pCheckerState" | |
370 * Address where PolicyCheckerState will be stored. Must be non-NULL. | |
371 * "plContext" | |
372 * Platform-specific context pointer. | |
373 * THREAD SAFETY: | |
374 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
375 * RETURNS: | |
376 * Returns NULL if the function succeeds | |
377 * Returns a CertPolicyCheckerState Error if the functions fails in a | |
378 * non-fatal way | |
379 * Returns a Fatal Error if the function fails in an unrecoverable way | |
380 */ | |
381 static PKIX_Error * | |
382 pkix_PolicyCheckerState_Create( | |
383 PKIX_List *initialPolicies, | |
384 PKIX_Boolean policyQualifiersRejected, | |
385 PKIX_Boolean initialPolicyMappingInhibit, | |
386 PKIX_Boolean initialExplicitPolicy, | |
387 PKIX_Boolean initialAnyPolicyInhibit, | |
388 PKIX_UInt32 numCerts, | |
389 PKIX_PolicyCheckerState **pCheckerState, | |
390 void *plContext) | |
391 { | |
392 PKIX_PolicyCheckerState *checkerState = NULL; | |
393 PKIX_PolicyNode *policyNode = NULL; | |
394 PKIX_List *anyPolicyList = NULL; | |
395 PKIX_Boolean initialPoliciesIsEmpty = PKIX_FALSE; | |
396 | |
397 PKIX_ENTER(CERTPOLICYCHECKERSTATE, "pkix_PolicyCheckerState_Create"); | |
398 PKIX_NULLCHECK_TWO(initialPolicies, pCheckerState); | |
399 | |
400 PKIX_CHECK(PKIX_PL_Object_Alloc | |
401 (PKIX_CERTPOLICYCHECKERSTATE_TYPE, | |
402 sizeof (PKIX_PolicyCheckerState), | |
403 (PKIX_PL_Object **)&checkerState, | |
404 plContext), | |
405 PKIX_COULDNOTCREATEPOLICYCHECKERSTATEOBJECT); | |
406 | |
407 /* Create constant PKIX_PL_OIDs: */ | |
408 | |
409 PKIX_CHECK(PKIX_PL_OID_Create | |
410 (PKIX_CERTIFICATEPOLICIES_OID, | |
411 &(checkerState->certPoliciesExtension), | |
412 plContext), | |
413 PKIX_OIDCREATEFAILED); | |
414 | |
415 PKIX_CHECK(PKIX_PL_OID_Create | |
416 (PKIX_POLICYMAPPINGS_OID, | |
417 &(checkerState->policyMappingsExtension), | |
418 plContext), | |
419 PKIX_OIDCREATEFAILED); | |
420 | |
421 PKIX_CHECK(PKIX_PL_OID_Create | |
422 (PKIX_POLICYCONSTRAINTS_OID, | |
423 &(checkerState->policyConstraintsExtension), | |
424 plContext), | |
425 PKIX_OIDCREATEFAILED); | |
426 | |
427 PKIX_CHECK(PKIX_PL_OID_Create | |
428 (PKIX_INHIBITANYPOLICY_OID, | |
429 &(checkerState->inhibitAnyPolicyExtension), | |
430 plContext), | |
431 PKIX_OIDCREATEFAILED); | |
432 | |
433 PKIX_CHECK(PKIX_PL_OID_Create | |
434 (PKIX_CERTIFICATEPOLICIES_ANYPOLICY_OID, | |
435 &(checkerState->anyPolicyOID), | |
436 plContext), | |
437 PKIX_OIDCREATEFAILED); | |
438 | |
439 /* Create an initial policy set from argument supplied */ | |
440 PKIX_INCREF(initialPolicies); | |
441 checkerState->userInitialPolicySet = initialPolicies; | |
442 PKIX_INCREF(initialPolicies); | |
443 checkerState->mappedUserInitialPolicySet = initialPolicies; | |
444 | |
445 PKIX_CHECK(PKIX_List_IsEmpty | |
446 (initialPolicies, | |
447 &initialPoliciesIsEmpty, | |
448 plContext), | |
449 PKIX_LISTISEMPTYFAILED); | |
450 if (initialPoliciesIsEmpty) { | |
451 checkerState->initialIsAnyPolicy = PKIX_TRUE; | |
452 } else { | |
453 PKIX_CHECK(pkix_List_Contains | |
454 (initialPolicies, | |
455 (PKIX_PL_Object *)(checkerState->anyPolicyOID), | |
456 &(checkerState->initialIsAnyPolicy), | |
457 plContext), | |
458 PKIX_LISTCONTAINSFAILED); | |
459 } | |
460 | |
461 checkerState->policyQualifiersRejected = | |
462 policyQualifiersRejected; | |
463 checkerState->initialExplicitPolicy = initialExplicitPolicy; | |
464 checkerState->explicitPolicy = | |
465 (initialExplicitPolicy? 0: numCerts + 1); | |
466 checkerState->initialAnyPolicyInhibit = initialAnyPolicyInhibit; | |
467 checkerState->inhibitAnyPolicy = | |
468 (initialAnyPolicyInhibit? 0: numCerts + 1); | |
469 checkerState->initialPolicyMappingInhibit = initialPolicyMappingInhibit; | |
470 checkerState->policyMapping = | |
471 (initialPolicyMappingInhibit? 0: numCerts + 1); | |
472 ; | |
473 checkerState->numCerts = numCerts; | |
474 checkerState->certsProcessed = 0; | |
475 checkerState->certPoliciesCritical = PKIX_FALSE; | |
476 | |
477 /* Create a valid_policy_tree as in RFC3280 6.1.2(a) */ | |
478 PKIX_CHECK(pkix_PolicyChecker_MakeSingleton | |
479 ((PKIX_PL_Object *)(checkerState->anyPolicyOID), | |
480 PKIX_TRUE, | |
481 &anyPolicyList, | |
482 plContext), | |
483 PKIX_POLICYCHECKERMAKESINGLETONFAILED); | |
484 | |
485 PKIX_CHECK(pkix_PolicyNode_Create | |
486 (checkerState->anyPolicyOID, /* validPolicy */ | |
487 NULL, /* qualifier set */ | |
488 PKIX_FALSE, /* criticality */ | |
489 anyPolicyList, /* expectedPolicySet */ | |
490 &policyNode, | |
491 plContext), | |
492 PKIX_POLICYNODECREATEFAILED); | |
493 checkerState->validPolicyTree = policyNode; | |
494 | |
495 /* | |
496 * Since the initial validPolicyTree specifies | |
497 * ANY_POLICY, begin with a pointer to the root node. | |
498 */ | |
499 PKIX_INCREF(policyNode); | |
500 checkerState->anyPolicyNodeAtBottom = policyNode; | |
501 | |
502 checkerState->newAnyPolicyNode = NULL; | |
503 | |
504 checkerState->mappedPolicyOIDs = NULL; | |
505 | |
506 *pCheckerState = checkerState; | |
507 checkerState = NULL; | |
508 | |
509 cleanup: | |
510 | |
511 PKIX_DECREF(checkerState); | |
512 | |
513 PKIX_DECREF(anyPolicyList); | |
514 | |
515 PKIX_RETURN(CERTPOLICYCHECKERSTATE); | |
516 } | |
517 | |
518 /* --Private-PolicyChecker-Functions--------------------------------------- */ | |
519 | |
520 /* | |
521 * FUNCTION: pkix_PolicyChecker_MapContains | |
522 * DESCRIPTION: | |
523 * | |
524 * Checks the List of CertPolicyMaps pointed to by "certPolicyMaps", to | |
525 * determine whether the OID pointed to by "policy" is among the | |
526 * issuerDomainPolicies or subjectDomainPolicies of "certPolicyMaps", and | |
527 * stores the result in "pFound". | |
528 * | |
529 * This function is intended to allow an efficient check that the proscription | |
530 * against anyPolicy being mapped, described in RFC3280 Section 6.1.4(a), is | |
531 * not violated. | |
532 * | |
533 * PARAMETERS: | |
534 * "certPolicyMaps" | |
535 * Address of List of CertPolicyMaps to be searched. May be empty, but | |
536 * must be non-NULL | |
537 * "policy" | |
538 * Address of OID to be checked for. Must be non-NULL | |
539 * "pFound" | |
540 * Address where the result of the search will be stored. Must be non-NULL. | |
541 * "plContext" | |
542 * platform-specific context pointer | |
543 * THREAD SAFETY: | |
544 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
545 * RETURNS: | |
546 * Returns NULL if the function succeeds | |
547 * Returns a CertChainChecker Error if the function fails in a non-fatal way. | |
548 * Returns a Fatal Error if the function fails in an unrecoverable way | |
549 */ | |
550 PKIX_Error * | |
551 pkix_PolicyChecker_MapContains( | |
552 PKIX_List *certPolicyMaps, | |
553 PKIX_PL_OID *policy, | |
554 PKIX_Boolean *pFound, | |
555 void *plContext) | |
556 { | |
557 PKIX_PL_CertPolicyMap *map = NULL; | |
558 PKIX_UInt32 numEntries = 0; | |
559 PKIX_UInt32 index = 0; | |
560 PKIX_Boolean match = PKIX_FALSE; | |
561 PKIX_PL_OID *issuerDomainPolicy = NULL; | |
562 PKIX_PL_OID *subjectDomainPolicy = NULL; | |
563 | |
564 PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_MapContains"); | |
565 PKIX_NULLCHECK_THREE(certPolicyMaps, policy, pFound); | |
566 | |
567 PKIX_CHECK(PKIX_List_GetLength(certPolicyMaps, &numEntries, plContext), | |
568 PKIX_LISTGETLENGTHFAILED); | |
569 | |
570 for (index = 0; (!match) && (index < numEntries); index++) { | |
571 PKIX_CHECK(PKIX_List_GetItem | |
572 (certPolicyMaps, index, (PKIX_PL_Object **)&map, plContext), | |
573 PKIX_LISTGETITEMFAILED); | |
574 | |
575 PKIX_NULLCHECK_ONE(map); | |
576 | |
577 PKIX_CHECK(PKIX_PL_CertPolicyMap_GetIssuerDomainPolicy | |
578 (map, &issuerDomainPolicy, plContext), | |
579 PKIX_CERTPOLICYMAPGETISSUERDOMAINPOLICYFAILED); | |
580 | |
581 PKIX_EQUALS | |
582 (policy, issuerDomainPolicy, &match, plContext, | |
583 PKIX_OBJECTEQUALSFAILED); | |
584 | |
585 if (!match) { | |
586 PKIX_CHECK(PKIX_PL_CertPolicyMap_GetSubjectDomainPolicy | |
587 (map, &subjectDomainPolicy, plContext), | |
588 PKIX_CERTPOLICYMAPGETSUBJECTDOMAINPOLICYFAILED); | |
589 | |
590 PKIX_EQUALS | |
591 (policy, subjectDomainPolicy, &match, plContext, | |
592 PKIX_OBJECTEQUALSFAILED); | |
593 } | |
594 | |
595 PKIX_DECREF(map); | |
596 PKIX_DECREF(issuerDomainPolicy); | |
597 PKIX_DECREF(subjectDomainPolicy); | |
598 } | |
599 | |
600 *pFound = match; | |
601 | |
602 cleanup: | |
603 | |
604 PKIX_DECREF(map); | |
605 PKIX_DECREF(issuerDomainPolicy); | |
606 PKIX_DECREF(subjectDomainPolicy); | |
607 PKIX_RETURN(CERTCHAINCHECKER); | |
608 } | |
609 | |
610 /* | |
611 * FUNCTION: pkix_PolicyChecker_MapGetSubjectDomainPolicies | |
612 * DESCRIPTION: | |
613 * | |
614 * Checks the List of CertPolicyMaps pointed to by "certPolicyMaps", to create | |
615 * a list of all SubjectDomainPolicies for which the IssuerDomainPolicy is the | |
616 * policy pointed to by "policy", and stores the result in | |
617 * "pSubjectDomainPolicies". | |
618 * | |
619 * If the List of CertPolicyMaps provided in "certPolicyMaps" is NULL, the | |
620 * resulting List will be NULL. If there are CertPolicyMaps, but none that | |
621 * include "policy" as an IssuerDomainPolicy, the returned List pointer will | |
622 * be NULL. Otherwise, the returned List will contain the SubjectDomainPolicies | |
623 * of all CertPolicyMaps for which "policy" is the IssuerDomainPolicy. If a | |
624 * List is returned it will be immutable. | |
625 * | |
626 * PARAMETERS: | |
627 * "certPolicyMaps" | |
628 * Address of List of CertPolicyMaps to be searched. May be empty or NULL. | |
629 * "policy" | |
630 * Address of OID to be checked for. Must be non-NULL | |
631 * "pSubjectDomainPolicies" | |
632 * Address where the result of the search will be stored. Must be non-NULL. | |
633 * "plContext" | |
634 * platform-specific context pointer | |
635 * THREAD SAFETY: | |
636 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
637 * RETURNS: | |
638 * Returns NULL if the function succeeds | |
639 * Returns a CertChainChecker Error if the function fails in a non-fatal way. | |
640 * Returns a Fatal Error if the function fails in an unrecoverable way | |
641 */ | |
642 PKIX_Error * | |
643 pkix_PolicyChecker_MapGetSubjectDomainPolicies( | |
644 PKIX_List *certPolicyMaps, | |
645 PKIX_PL_OID *policy, | |
646 PKIX_List **pSubjectDomainPolicies, | |
647 void *plContext) | |
648 { | |
649 PKIX_PL_CertPolicyMap *map = NULL; | |
650 PKIX_List *subjectList = NULL; | |
651 PKIX_UInt32 numEntries = 0; | |
652 PKIX_UInt32 index = 0; | |
653 PKIX_Boolean match = PKIX_FALSE; | |
654 PKIX_PL_OID *issuerDomainPolicy = NULL; | |
655 PKIX_PL_OID *subjectDomainPolicy = NULL; | |
656 | |
657 PKIX_ENTER | |
658 (CERTCHAINCHECKER, | |
659 "pkix_PolicyChecker_MapGetSubjectDomainPolicies"); | |
660 PKIX_NULLCHECK_TWO(policy, pSubjectDomainPolicies); | |
661 | |
662 if (certPolicyMaps) { | |
663 PKIX_CHECK(PKIX_List_GetLength | |
664 (certPolicyMaps, | |
665 &numEntries, | |
666 plContext), | |
667 PKIX_LISTGETLENGTHFAILED); | |
668 } | |
669 | |
670 for (index = 0; index < numEntries; index++) { | |
671 PKIX_CHECK(PKIX_List_GetItem | |
672 (certPolicyMaps, index, (PKIX_PL_Object **)&map, plContext), | |
673 PKIX_LISTGETITEMFAILED); | |
674 | |
675 PKIX_NULLCHECK_ONE(map); | |
676 | |
677 PKIX_CHECK(PKIX_PL_CertPolicyMap_GetIssuerDomainPolicy | |
678 (map, &issuerDomainPolicy, plContext), | |
679 PKIX_CERTPOLICYMAPGETISSUERDOMAINPOLICYFAILED); | |
680 | |
681 PKIX_EQUALS | |
682 (policy, issuerDomainPolicy, &match, plContext, | |
683 PKIX_OBJECTEQUALSFAILED); | |
684 | |
685 if (match) { | |
686 if (!subjectList) { | |
687 PKIX_CHECK(PKIX_List_Create(&subjectList, plContext), | |
688 PKIX_LISTCREATEFAILED); | |
689 } | |
690 | |
691 PKIX_CHECK(PKIX_PL_CertPolicyMap_GetSubjectDomainPolicy | |
692 (map, &subjectDomainPolicy, plContext), | |
693 PKIX_CERTPOLICYMAPGETSUBJECTDOMAINPOLICYFAILED); | |
694 | |
695 PKIX_CHECK(PKIX_List_AppendItem | |
696 (subjectList, | |
697 (PKIX_PL_Object *)subjectDomainPolicy, | |
698 plContext), | |
699 PKIX_LISTAPPENDITEMFAILED); | |
700 } | |
701 | |
702 PKIX_DECREF(map); | |
703 PKIX_DECREF(issuerDomainPolicy); | |
704 PKIX_DECREF(subjectDomainPolicy); | |
705 } | |
706 | |
707 if (subjectList) { | |
708 PKIX_CHECK(PKIX_List_SetImmutable(subjectList, plContext), | |
709 PKIX_LISTSETIMMUTABLEFAILED); | |
710 } | |
711 | |
712 *pSubjectDomainPolicies = subjectList; | |
713 | |
714 cleanup: | |
715 | |
716 if (PKIX_ERROR_RECEIVED) { | |
717 PKIX_DECREF(subjectList); | |
718 } | |
719 | |
720 PKIX_DECREF(map); | |
721 PKIX_DECREF(issuerDomainPolicy); | |
722 PKIX_DECREF(subjectDomainPolicy); | |
723 | |
724 PKIX_RETURN(CERTCHAINCHECKER); | |
725 } | |
726 | |
727 /* | |
728 * FUNCTION: pkix_PolicyChecker_MapGetMappedPolicies | |
729 * DESCRIPTION: | |
730 * | |
731 * Checks the List of CertPolicyMaps pointed to by "certPolicyMaps" to create a | |
732 * List of all IssuerDomainPolicies, and stores the result in | |
733 * "pMappedPolicies". | |
734 * | |
735 * The caller may not rely on the IssuerDomainPolicies to be in any particular | |
736 * order. IssuerDomainPolicies that appear in more than one CertPolicyMap will | |
737 * only appear once in "pMappedPolicies". If "certPolicyMaps" is empty the | |
738 * result will be an empty List. The created List is mutable. | |
739 * | |
740 * PARAMETERS: | |
741 * "certPolicyMaps" | |
742 * Address of List of CertPolicyMaps to be searched. May be empty, but | |
743 * must be non-NULL. | |
744 * "pMappedPolicies" | |
745 * Address where the result will be stored. Must be non-NULL. | |
746 * "plContext" | |
747 * platform-specific context pointer | |
748 * THREAD SAFETY: | |
749 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
750 * RETURNS: | |
751 * Returns NULL if the function succeeds | |
752 * Returns a CertChainChecker Error if the functions fails in a non-fatal way | |
753 * Returns a Fatal Error if the function fails in an unrecoverable way | |
754 */ | |
755 PKIX_Error * | |
756 pkix_PolicyChecker_MapGetMappedPolicies( | |
757 PKIX_List *certPolicyMaps, | |
758 PKIX_List **pMappedPolicies, | |
759 void *plContext) | |
760 { | |
761 PKIX_PL_CertPolicyMap *map = NULL; | |
762 PKIX_List *mappedList = NULL; | |
763 PKIX_UInt32 numEntries = 0; | |
764 PKIX_UInt32 index = 0; | |
765 PKIX_Boolean isContained = PKIX_FALSE; | |
766 PKIX_PL_OID *issuerDomainPolicy = NULL; | |
767 | |
768 PKIX_ENTER | |
769 (CERTCHAINCHECKER, "pkix_PolicyChecker_MapGetMappedPolicies"); | |
770 PKIX_NULLCHECK_TWO(certPolicyMaps, pMappedPolicies); | |
771 | |
772 PKIX_CHECK(PKIX_List_Create(&mappedList, plContext), | |
773 PKIX_LISTCREATEFAILED); | |
774 | |
775 PKIX_CHECK(PKIX_List_GetLength(certPolicyMaps, &numEntries, plContext), | |
776 PKIX_LISTGETLENGTHFAILED); | |
777 | |
778 for (index = 0; index < numEntries; index++) { | |
779 PKIX_CHECK(PKIX_List_GetItem | |
780 (certPolicyMaps, index, (PKIX_PL_Object **)&map, plContext), | |
781 PKIX_LISTGETITEMFAILED); | |
782 | |
783 PKIX_NULLCHECK_ONE(map); | |
784 | |
785 PKIX_CHECK(PKIX_PL_CertPolicyMap_GetIssuerDomainPolicy | |
786 (map, &issuerDomainPolicy, plContext), | |
787 PKIX_CERTPOLICYMAPGETISSUERDOMAINPOLICYFAILED); | |
788 | |
789 PKIX_CHECK(pkix_List_Contains | |
790 (mappedList, | |
791 (PKIX_PL_Object *)issuerDomainPolicy, | |
792 &isContained, | |
793 plContext), | |
794 PKIX_LISTCONTAINSFAILED); | |
795 | |
796 if (isContained == PKIX_FALSE) { | |
797 PKIX_CHECK(PKIX_List_AppendItem | |
798 (mappedList, | |
799 (PKIX_PL_Object *)issuerDomainPolicy, | |
800 plContext), | |
801 PKIX_LISTAPPENDITEMFAILED); | |
802 } | |
803 | |
804 PKIX_DECREF(map); | |
805 PKIX_DECREF(issuerDomainPolicy); | |
806 } | |
807 | |
808 *pMappedPolicies = mappedList; | |
809 | |
810 cleanup: | |
811 | |
812 if (PKIX_ERROR_RECEIVED) { | |
813 PKIX_DECREF(mappedList); | |
814 } | |
815 | |
816 PKIX_DECREF(map); | |
817 PKIX_DECREF(issuerDomainPolicy); | |
818 | |
819 PKIX_RETURN(CERTCHAINCHECKER); | |
820 } | |
821 | |
822 /* | |
823 * FUNCTION: pkix_PolicyChecker_MakeMutableCopy | |
824 * DESCRIPTION: | |
825 * | |
826 * Creates a mutable copy of the List pointed to by "list", which may or may | |
827 * not be immutable, and stores the address at "pMutableCopy". | |
828 * | |
829 * PARAMETERS: | |
830 * "list" | |
831 * Address of List to be copied. Must be non-NULL. | |
832 * "pMutableCopy" | |
833 * Address where mutable copy will be stored. Must be non-NULL. | |
834 * "plContext" | |
835 * Platform-specific context pointer. | |
836 * THREAD SAFETY: | |
837 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
838 * RETURNS: | |
839 * Returns NULL if the function succeeds | |
840 * Returns a CertChainChecker Error if the functions fails in a non-fatal way | |
841 * Returns a Fatal Error if the function fails in an unrecoverable way | |
842 */ | |
843 static PKIX_Error * | |
844 pkix_PolicyChecker_MakeMutableCopy( | |
845 PKIX_List *list, | |
846 PKIX_List **pMutableCopy, | |
847 void *plContext) | |
848 { | |
849 PKIX_List *newList = NULL; | |
850 PKIX_UInt32 listLen = 0; | |
851 PKIX_UInt32 listIx = 0; | |
852 PKIX_PL_Object *object = NULL; | |
853 | |
854 PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_MakeMutableCopy"); | |
855 PKIX_NULLCHECK_TWO(list, pMutableCopy); | |
856 | |
857 PKIX_CHECK(PKIX_List_Create(&newList, plContext), | |
858 PKIX_LISTCREATEFAILED); | |
859 | |
860 PKIX_CHECK(PKIX_List_GetLength(list, &listLen, plContext), | |
861 PKIX_LISTGETLENGTHFAILED); | |
862 | |
863 for (listIx = 0; listIx < listLen; listIx++) { | |
864 | |
865 PKIX_CHECK(PKIX_List_GetItem(list, listIx, &object, plContext), | |
866 PKIX_LISTGETITEMFAILED); | |
867 | |
868 PKIX_CHECK(PKIX_List_AppendItem(newList, object, plContext), | |
869 PKIX_LISTAPPENDITEMFAILED); | |
870 | |
871 PKIX_DECREF(object); | |
872 } | |
873 | |
874 *pMutableCopy = newList; | |
875 newList = NULL; | |
876 | |
877 cleanup: | |
878 PKIX_DECREF(newList); | |
879 PKIX_DECREF(object); | |
880 | |
881 PKIX_RETURN(CERTCHAINCHECKER); | |
882 } | |
883 | |
884 /* | |
885 * FUNCTION: pkix_PolicyChecker_MakeSingleton | |
886 * DESCRIPTION: | |
887 * | |
888 * Creates a new List containing the Object pointed to by "listItem", using | |
889 * the Boolean value of "immutability" to determine whether to set the List | |
890 * immutable, and stores the address at "pList". | |
891 * | |
892 * PARAMETERS: | |
893 * "listItem" | |
894 * Address of Object to be inserted into the new List. Must be non-NULL. | |
895 * "immutability" | |
896 * Boolean value indicating whether new List is to be immutable | |
897 * "pList" | |
898 * Address where List will be stored. Must be non-NULL. | |
899 * "plContext" | |
900 * Platform-specific context pointer. | |
901 * THREAD SAFETY: | |
902 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
903 * RETURNS: | |
904 * Returns NULL if the function succeeds | |
905 * Returns a CertChainChecker Error if the functions fails in a non-fatal way | |
906 * Returns a Fatal Error if the function fails in an unrecoverable way | |
907 */ | |
908 static PKIX_Error * | |
909 pkix_PolicyChecker_MakeSingleton( | |
910 PKIX_PL_Object *listItem, | |
911 PKIX_Boolean immutability, | |
912 PKIX_List **pList, | |
913 void *plContext) | |
914 { | |
915 PKIX_List *newList = NULL; | |
916 | |
917 PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_MakeSingleton"); | |
918 PKIX_NULLCHECK_TWO(listItem, pList); | |
919 | |
920 PKIX_CHECK(PKIX_List_Create(&newList, plContext), | |
921 PKIX_LISTCREATEFAILED); | |
922 | |
923 PKIX_CHECK(PKIX_List_AppendItem | |
924 (newList, (PKIX_PL_Object *)listItem, plContext), | |
925 PKIX_LISTAPPENDITEMFAILED); | |
926 | |
927 if (immutability) { | |
928 PKIX_CHECK(PKIX_List_SetImmutable(newList, plContext), | |
929 PKIX_LISTSETIMMUTABLEFAILED); | |
930 } | |
931 | |
932 *pList = newList; | |
933 | |
934 cleanup: | |
935 if (PKIX_ERROR_RECEIVED) { | |
936 PKIX_DECREF(newList); | |
937 } | |
938 | |
939 PKIX_RETURN(CERTCHAINCHECKER); | |
940 } | |
941 | |
942 /* | |
943 * FUNCTION: pkix_PolicyChecker_Spawn | |
944 * DESCRIPTION: | |
945 * | |
946 * Creates a new childNode for the parent pointed to by "parent", using | |
947 * the OID pointed to by "policyOID", the List of CertPolicyQualifiers | |
948 * pointed to by "qualifiers", the List of OIDs pointed to by | |
949 * "subjectDomainPolicies", and the PolicyCheckerState pointed to by | |
950 * "state". The new node will be added to "parent". | |
951 * | |
952 * The validPolicy of the new node is set from the OID pointed to by | |
953 * "policyOID". The policy qualifiers for the new node is set from the | |
954 * List of qualifiers pointed to by "qualifiers", and may be NULL or | |
955 * empty if the argument provided was NULL or empty. The criticality is | |
956 * set according to the criticality obtained from the PolicyCheckerState. | |
957 * If "subjectDomainPolicies" is NULL, the expectedPolicySet of the | |
958 * child is set to contain the same policy as the validPolicy. If | |
959 * "subjectDomainPolicies" is not NULL, it is used as the value for | |
960 * the expectedPolicySet. | |
961 * | |
962 * The PolicyCheckerState also contains a constant, anyPolicy, which is | |
963 * compared to "policyOID". If they match, the address of the childNode | |
964 * is saved in the state's newAnyPolicyNode. | |
965 * | |
966 * PARAMETERS: | |
967 * "parent" | |
968 * Address of PolicyNode to which the child will be linked. Must be | |
969 * non-NULL. | |
970 * "policyOID" | |
971 * Address of OID of the new child's validPolicy and also, if | |
972 * subjectDomainPolicies is NULL, of the new child's expectedPolicySet. | |
973 * Must be non-NULL. | |
974 * "qualifiers" | |
975 * Address of List of CertPolicyQualifiers. May be NULL or empty. | |
976 * "subjectDomainPolicies" | |
977 * Address of List of OIDs indicating the policies to which "policy" is | |
978 * mapped. May be empty or NULL. | |
979 * "state" | |
980 * Address of the current PKIX_PolicyCheckerState. Must be non-NULL.. | |
981 * "plContext" | |
982 * Platform-specific context pointer. | |
983 * THREAD SAFETY: | |
984 * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
985 * RETURNS: | |
986 * Returns NULL if the function succeeds | |
987 * Returns a CertChainChecker Error if the functions fails in a non-fatal way | |
988 * Returns a Fatal Error if the function fails in an unrecoverable way | |
989 */ | |
990 static PKIX_Error * | |
991 pkix_PolicyChecker_Spawn( | |
992 PKIX_PolicyNode *parent, | |
993 PKIX_PL_OID *policyOID, | |
994 PKIX_List *qualifiers, /* CertPolicyQualifiers */ | |
995 PKIX_List *subjectDomainPolicies, | |
996 PKIX_PolicyCheckerState *state, | |
997 void *plContext) | |
998 { | |
999 PKIX_List *expectedSet = NULL; /* OIDs */ | |
1000 PKIX_PolicyNode *childNode = NULL; | |
1001 PKIX_Boolean match = PKIX_FALSE; | |
1002 | |
1003 PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_Spawn"); | |
1004 PKIX_NULLCHECK_THREE(policyOID, parent, state); | |
1005 | |
1006 if (subjectDomainPolicies) { | |
1007 | |
1008 PKIX_INCREF(subjectDomainPolicies); | |
1009 expectedSet = subjectDomainPolicies; | |
1010 | |
1011 } else { | |
1012 /* Create the child's ExpectedPolicy Set */ | |
1013 PKIX_CHECK(pkix_PolicyChecker_MakeSingleton | |
1014 ((PKIX_PL_Object *)policyOID, | |
1015 PKIX_TRUE, /* make expectedPolicySet immutable */ | |
1016 &expectedSet, | |
1017 plContext), | |
1018 PKIX_POLICYCHECKERMAKESINGLETONFAILED); | |
1019 } | |
1020 | |
1021 PKIX_CHECK(pkix_PolicyNode_Create | |
1022 (policyOID, | |
1023 qualifiers, | |
1024 state->certPoliciesCritical, | |
1025 expectedSet, | |
1026 &childNode, | |
1027 plContext), | |
1028 PKIX_POLICYNODECREATEFAILED); | |
1029 | |
1030 /* | |
1031 * If we had a non-empty mapping, we know the new node could not | |
1032 * have been created with a validPolicy of anyPolicy. Otherwise, | |
1033 * check whether we just created a new node with anyPolicy, because | |
1034 * in that case we want to save the child pointer in newAnyPolicyNode. | |
1035 */ | |
1036 if (!subjectDomainPolicies) { | |
1037 PKIX_EQUALS(policyOID, state->anyPolicyOID, &match, plContext, | |
1038 PKIX_OBJECTEQUALSFAILED); | |
1039 | |
1040 if (match) { | |
1041 PKIX_DECREF(state->newAnyPolicyNode); | |
1042 PKIX_INCREF(childNode); | |
1043 state->newAnyPolicyNode = childNode; | |
1044 } | |
1045 } | |
1046 | |
1047 PKIX_CHECK(pkix_PolicyNode_AddToParent(parent, childNode, plContext), | |
1048 PKIX_POLICYNODEADDTOPARENTFAILED); | |
1049 | |
1050 PKIX_CHECK(PKIX_PL_Object_InvalidateCache | |
1051 ((PKIX_PL_Object *)state, plContext), | |
1052 PKIX_OBJECTINVALIDATECACHEFAILED); | |
1053 | |
1054 cleanup: | |
1055 PKIX_DECREF(childNode); | |
1056 PKIX_DECREF(expectedSet); | |
1057 PKIX_RETURN(CERTCHAINCHECKER); | |
1058 } | |
1059 | |
1060 /* | |
1061 * FUNCTION: pkix_PolicyChecker_CheckPolicyRecursive | |
1062 * DESCRIPTION: | |
1063 * | |
1064 * Performs policy processing for the policy whose OID is pointed to by | |
1065 * "policyOID" and whose List of CertPolicyQualifiers is pointed to by | |
1066 * "policyQualifiers", using the List of policy OIDs pointed to by | |
1067 * "subjectDomainPolicies" and the PolicyNode pointed to by "currentNode", | |
1068 * in accordance with the current PolicyCheckerState pointed to by "state", | |
1069 * and setting "pChildNodeCreated" to TRUE if a new childNode is created. | |
1070 * Note: "pChildNodeCreated" is not set to FALSE if no childNode is created. | |
1071 * The intent of the design is that the caller can set a variable to FALSE | |
1072 * initially, prior to a recursive set of calls. At the end, the variable | |
1073 * can be tested to see whether *any* of the calls created a child node. | |
1074 * | |
1075 * If the currentNode is not at the bottom of the tree, this function | |
1076 * calls itself recursively for each child of currentNode. At the bottom of | |
1077 * the tree, it creates new child nodes as appropriate. This function will | |
1078 * never be called with policy = anyPolicy. | |
1079 * | |
1080 * This function implements the processing described in RFC3280 | |
1081 * Section 6.1.3(d)(1)(i). | |
1082 * | |
1083 * PARAMETERS: | |
1084 * "policyOID" | |
1085 * Address of OID of the policy to be checked for. Must be non-NULL. | |
1086 * "policyQualifiers" | |
1087 * Address of List of CertPolicyQualifiers of the policy to be checked for. | |
1088 * May be empty or NULL. | |
1089 * "subjectDomainPolicies" | |
1090 * Address of List of OIDs indicating the policies to which "policy" is | |
1091 * mapped. May be empty or NULL. | |
1092 * "currentNode" | |
1093 * Address of PolicyNode whose descendants will be checked, if not at the | |
1094 * bottom of the tree; or whose expectedPolicySet will be compared to | |
1095 * "policy", if at the bottom. Must be non-NULL. | |
1096 * "state" | |
1097 * Address of PolicyCheckerState of the current PolicyChecker. Must be | |
1098 * non-NULL. | |
1099 * "pChildNodeCreated" | |
1100 * Address of the Boolean that will be set TRUE if this function | |
1101 * creates a child node. Must be non-NULL. | |
1102 * "plContext" | |
1103 * Platform-specific context pointer. | |
1104 * THREAD SAFETY: | |
1105 * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
1106 * RETURNS: | |
1107 * Returns NULL if the function succeeds | |
1108 * Returns a CertChainChecker Error if the functions fails in a non-fatal way | |
1109 * Returns a Fatal Error if the function fails in an unrecoverable way | |
1110 */ | |
1111 static PKIX_Error * | |
1112 pkix_PolicyChecker_CheckPolicyRecursive( | |
1113 PKIX_PL_OID *policyOID, | |
1114 PKIX_List *policyQualifiers, | |
1115 PKIX_List *subjectDomainPolicies, | |
1116 PKIX_PolicyNode *currentNode, | |
1117 PKIX_PolicyCheckerState *state, | |
1118 PKIX_Boolean *pChildNodeCreated, | |
1119 void *plContext) | |
1120 { | |
1121 PKIX_UInt32 depth = 0; | |
1122 PKIX_UInt32 numChildren = 0; | |
1123 PKIX_UInt32 childIx = 0; | |
1124 PKIX_Boolean isIncluded = PKIX_FALSE; | |
1125 PKIX_List *children = NULL; /* PolicyNodes */ | |
1126 PKIX_PolicyNode *childNode = NULL; | |
1127 PKIX_List *expectedPolicies = NULL; /* OIDs */ | |
1128 | |
1129 PKIX_ENTER | |
1130 (CERTCHAINCHECKER, | |
1131 "pkix_PolicyChecker_CheckPolicyRecursive"); | |
1132 PKIX_NULLCHECK_FOUR(policyOID, currentNode, state, pChildNodeCreated); | |
1133 | |
1134 /* if not at the bottom of the tree */ | |
1135 PKIX_CHECK(PKIX_PolicyNode_GetDepth | |
1136 (currentNode, &depth, plContext), | |
1137 PKIX_POLICYNODEGETDEPTHFAILED); | |
1138 | |
1139 if (depth < (state->certsProcessed)) { | |
1140 PKIX_CHECK(pkix_PolicyNode_GetChildrenMutable | |
1141 (currentNode, &children, plContext), | |
1142 PKIX_POLICYNODEGETCHILDRENMUTABLEFAILED); | |
1143 | |
1144 if (children) { | |
1145 PKIX_CHECK(PKIX_List_GetLength | |
1146 (children, &numChildren, plContext), | |
1147 PKIX_LISTGETLENGTHFAILED); | |
1148 } | |
1149 | |
1150 for (childIx = 0; childIx < numChildren; childIx++) { | |
1151 | |
1152 PKIX_CHECK(PKIX_List_GetItem | |
1153 (children, | |
1154 childIx, | |
1155 (PKIX_PL_Object **)&childNode, | |
1156 plContext), | |
1157 PKIX_LISTGETITEMFAILED); | |
1158 | |
1159 PKIX_CHECK(pkix_PolicyChecker_CheckPolicyRecursive | |
1160 (policyOID, | |
1161 policyQualifiers, | |
1162 subjectDomainPolicies, | |
1163 childNode, | |
1164 state, | |
1165 pChildNodeCreated, | |
1166 plContext), | |
1167 PKIX_POLICYCHECKERCHECKPOLICYRECURSIVEFAILED); | |
1168 | |
1169 PKIX_DECREF(childNode); | |
1170 } | |
1171 } else { /* if at the bottom of the tree */ | |
1172 | |
1173 /* Check whether policy is in this node's expectedPolicySet */ | |
1174 PKIX_CHECK(PKIX_PolicyNode_GetExpectedPolicies | |
1175 (currentNode, &expectedPolicies, plContext), | |
1176 PKIX_POLICYNODEGETEXPECTEDPOLICIESFAILED); | |
1177 | |
1178 PKIX_NULLCHECK_ONE(expectedPolicies); | |
1179 | |
1180 PKIX_CHECK(pkix_List_Contains | |
1181 (expectedPolicies, | |
1182 (PKIX_PL_Object *)policyOID, | |
1183 &isIncluded, | |
1184 plContext), | |
1185 PKIX_LISTCONTAINSFAILED); | |
1186 | |
1187 if (isIncluded) { | |
1188 PKIX_CHECK(pkix_PolicyChecker_Spawn | |
1189 (currentNode, | |
1190 policyOID, | |
1191 policyQualifiers, | |
1192 subjectDomainPolicies, | |
1193 state, | |
1194 plContext), | |
1195 PKIX_POLICYCHECKERSPAWNFAILED); | |
1196 | |
1197 *pChildNodeCreated = PKIX_TRUE; | |
1198 } | |
1199 } | |
1200 | |
1201 cleanup: | |
1202 | |
1203 PKIX_DECREF(children); | |
1204 PKIX_DECREF(childNode); | |
1205 PKIX_DECREF(expectedPolicies); | |
1206 | |
1207 PKIX_RETURN(CERTCHAINCHECKER); | |
1208 } | |
1209 | |
1210 /* | |
1211 * FUNCTION: pkix_PolicyChecker_CheckPolicy | |
1212 * DESCRIPTION: | |
1213 * | |
1214 * Performs the non-recursive portion of the policy processing for the policy | |
1215 * whose OID is pointed to by "policyOID" and whose List of | |
1216 * CertPolicyQualifiers is pointed to by "policyQualifiers", for the | |
1217 * Certificate pointed to by "cert" with the List of CertPolicyMaps pointed | |
1218 * to by "maps", in accordance with the current PolicyCheckerState pointed | |
1219 * to by "state". | |
1220 * | |
1221 * This function implements the processing described in RFC3280 | |
1222 * Section 6.1.3(d)(1)(i). | |
1223 * | |
1224 * PARAMETERS: | |
1225 * "policyOID" | |
1226 * Address of OID of the policy to be checked for. Must be non-NULL. | |
1227 * "policyQualifiers" | |
1228 * Address of List of CertPolicyQualifiers of the policy to be checked for. | |
1229 * May be empty or NULL. | |
1230 * "cert" | |
1231 * Address of the current certificate. Must be non-NULL. | |
1232 * "maps" | |
1233 * Address of List of CertPolicyMaps for the current certificate | |
1234 * "state" | |
1235 * Address of PolicyCheckerState of the current PolicyChecker. Must be | |
1236 * non-NULL. | |
1237 * "plContext" | |
1238 * Platform-specific context pointer. | |
1239 * THREAD SAFETY: | |
1240 * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
1241 * RETURNS: | |
1242 * Returns NULL if the function succeeds | |
1243 * Returns a CertChainChecker Error if the functions fails in a non-fatal way | |
1244 * Returns a Fatal Error if the function fails in an unrecoverable way | |
1245 */ | |
1246 static PKIX_Error * | |
1247 pkix_PolicyChecker_CheckPolicy( | |
1248 PKIX_PL_OID *policyOID, | |
1249 PKIX_List *policyQualifiers, | |
1250 PKIX_PL_Cert *cert, | |
1251 PKIX_List *maps, | |
1252 PKIX_PolicyCheckerState *state, | |
1253 void *plContext) | |
1254 { | |
1255 PKIX_Boolean childNodeCreated = PKIX_FALSE; | |
1256 PKIX_Boolean okToSpawn = PKIX_FALSE; | |
1257 PKIX_Boolean found = PKIX_FALSE; | |
1258 PKIX_List *subjectDomainPolicies = NULL; | |
1259 | |
1260 PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_CheckPolicy"); | |
1261 PKIX_NULLCHECK_THREE(policyOID, cert, state); | |
1262 | |
1263 /* | |
1264 * If this is not the last certificate, get the set of | |
1265 * subjectDomainPolicies that "policy" maps to, according to the | |
1266 * current cert's policy mapping extension. That set will be NULL | |
1267 * if the current cert does not have a policy mapping extension, | |
1268 * or if the current policy is not mapped. | |
1269 */ | |
1270 if (state->certsProcessed != (state->numCerts - 1)) { | |
1271 PKIX_CHECK(pkix_PolicyChecker_MapGetSubjectDomainPolicies | |
1272 (maps, policyOID, &subjectDomainPolicies, plContext), | |
1273 PKIX_POLICYCHECKERMAPGETSUBJECTDOMAINPOLICIESFAILED); | |
1274 } | |
1275 | |
1276 /* | |
1277 * Section 6.1.4(b)(2) tells us that if policyMapping is zero, we | |
1278 * will have to delete any nodes created with validPolicies equal to | |
1279 * policies that appear as issuerDomainPolicies in a policy mapping | |
1280 * extension. Let's avoid creating any such nodes. | |
1281 */ | |
1282 if ((state->policyMapping) == 0) { | |
1283 if (subjectDomainPolicies) { | |
1284 goto cleanup; | |
1285 } | |
1286 } | |
1287 | |
1288 PKIX_CHECK(pkix_PolicyChecker_CheckPolicyRecursive | |
1289 (policyOID, | |
1290 policyQualifiers, | |
1291 subjectDomainPolicies, | |
1292 state->validPolicyTree, | |
1293 state, | |
1294 &childNodeCreated, | |
1295 plContext), | |
1296 PKIX_POLICYCHECKERCHECKPOLICYRECURSIVEFAILED); | |
1297 | |
1298 if (!childNodeCreated) { | |
1299 /* | |
1300 * Section 6.1.3(d)(1)(ii) | |
1301 * There was no match. If there was a node at | |
1302 * depth i-1 with valid policy anyPolicy, | |
1303 * generate a node subordinate to that. | |
1304 * | |
1305 * But that means this created node would be in | |
1306 * the valid-policy-node-set, and will be | |
1307 * pruned in 6.1.5(g)(iii)(2) unless it is in | |
1308 * the user-initial-policy-set or the user- | |
1309 * initial-policy-set is {anyPolicy}. So check, | |
1310 * and don't create it if it will be pruned. | |
1311 */ | |
1312 if (state->anyPolicyNodeAtBottom) { | |
1313 if (state->initialIsAnyPolicy) { | |
1314 okToSpawn = PKIX_TRUE; | |
1315 } else { | |
1316 PKIX_CHECK(pkix_List_Contains | |
1317 (state->mappedUserInitialPolicySet, | |
1318 (PKIX_PL_Object *)policyOID, | |
1319 &okToSpawn, | |
1320 plContext), | |
1321 PKIX_LISTCONTAINSFAILED); | |
1322 } | |
1323 if (okToSpawn) { | |
1324 PKIX_CHECK(pkix_PolicyChecker_Spawn | |
1325 (state->anyPolicyNodeAtBottom, | |
1326 policyOID, | |
1327 policyQualifiers, | |
1328 subjectDomainPolicies, | |
1329 state, | |
1330 plContext), | |
1331 PKIX_POLICYCHECKERSPAWNFAILED); | |
1332 childNodeCreated = PKIX_TRUE; | |
1333 } | |
1334 } | |
1335 } | |
1336 | |
1337 if (childNodeCreated) { | |
1338 /* | |
1339 * If this policy had qualifiers, and the certificate policies | |
1340 * extension was marked critical, and the user cannot deal with | |
1341 * policy qualifiers, throw an error. | |
1342 */ | |
1343 if (policyQualifiers && | |
1344 state->certPoliciesCritical && | |
1345 state->policyQualifiersRejected) { | |
1346 PKIX_ERROR | |
1347 (PKIX_QUALIFIERSINCRITICALCERTIFICATEPOLICYEXTENSION); | |
1348 } | |
1349 /* | |
1350 * If the policy we just propagated was in the list of mapped | |
1351 * policies, remove it from the list. That list is used, at the | |
1352 * end, to determine policies that have not been propagated. | |
1353 */ | |
1354 if (state->mappedPolicyOIDs) { | |
1355 PKIX_CHECK(pkix_List_Contains | |
1356 (state->mappedPolicyOIDs, | |
1357 (PKIX_PL_Object *)policyOID, | |
1358 &found, | |
1359 plContext), | |
1360 PKIX_LISTCONTAINSFAILED); | |
1361 if (found) { | |
1362 PKIX_CHECK(pkix_List_Remove | |
1363 (state->mappedPolicyOIDs, | |
1364 (PKIX_PL_Object *)policyOID, | |
1365 plContext), | |
1366 PKIX_LISTREMOVEFAILED); | |
1367 } | |
1368 } | |
1369 } | |
1370 | |
1371 cleanup: | |
1372 | |
1373 PKIX_DECREF(subjectDomainPolicies); | |
1374 | |
1375 PKIX_RETURN(CERTCHAINCHECKER); | |
1376 } | |
1377 | |
1378 /* | |
1379 * FUNCTION: pkix_PolicyChecker_CheckAny | |
1380 * DESCRIPTION: | |
1381 * Performs the creation of PolicyNodes, for the PolicyNode pointed to by | |
1382 * "currentNode" and PolicyNodes subordinate to it, using the List of | |
1383 * qualifiers pointed to by "qualsOfAny", in accordance with the current | |
1384 * certificate's PolicyMaps pointed to by "policyMaps" and the current | |
1385 * PolicyCheckerState pointed to by "state". | |
1386 * | |
1387 * If the currentNode is not just above the bottom of the validPolicyTree, this | |
1388 * function calls itself recursively for each child of currentNode. At the | |
1389 * level just above the bottom, for each policy in the currentNode's | |
1390 * expectedPolicySet not already present in a child node, it creates a new | |
1391 * child node. The validPolicy of the child created, and its expectedPolicySet, | |
1392 * will be the policy from the currentNode's expectedPolicySet. The policy | |
1393 * qualifiers will be the qualifiers from the current certificate's anyPolicy, | |
1394 * the "qualsOfAny" parameter. If the currentNode's expectedSet includes | |
1395 * anyPolicy, a childNode will be created with a policy of anyPolicy. This is | |
1396 * the only way such a node can be created. | |
1397 * | |
1398 * This function is called only when anyPolicy is one of the current | |
1399 * certificate's policies. This function implements the processing described | |
1400 * in RFC3280 Section 6.1.3(d)(2). | |
1401 * | |
1402 * PARAMETERS: | |
1403 * "currentNode" | |
1404 * Address of PolicyNode whose descendants will be checked, if not at the | |
1405 * bottom of the tree; or whose expectedPolicySet will be compared to those | |
1406 * in "alreadyPresent", if at the bottom. Must be non-NULL. | |
1407 * "qualsOfAny" | |
1408 * Address of List of qualifiers of the anyPolicy in the current | |
1409 * certificate. May be empty or NULL. | |
1410 * "policyMaps" | |
1411 * Address of the List of PolicyMaps of the current certificate. May be | |
1412 * empty or NULL. | |
1413 * "state" | |
1414 * Address of the current state of the PKIX_PolicyChecker. | |
1415 * Must be non-NULL. | |
1416 * "plContext" | |
1417 * Platform-specific context pointer. | |
1418 * THREAD SAFETY: | |
1419 * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
1420 * RETURNS: | |
1421 * Returns NULL if the function succeeds | |
1422 * Returns a CertChainChecker Error if the functions fails in a non-fatal way | |
1423 * Returns a Fatal Error if the function fails in an unrecoverable way | |
1424 */ | |
1425 static PKIX_Error * | |
1426 pkix_PolicyChecker_CheckAny( | |
1427 PKIX_PolicyNode *currentNode, | |
1428 PKIX_List *qualsOfAny, /* CertPolicyQualifiers */ | |
1429 PKIX_List *policyMaps, /* CertPolicyMaps */ | |
1430 PKIX_PolicyCheckerState *state, | |
1431 void *plContext) | |
1432 { | |
1433 PKIX_UInt32 depth = 0; | |
1434 PKIX_UInt32 numChildren = 0; | |
1435 PKIX_UInt32 childIx = 0; | |
1436 PKIX_UInt32 numPolicies = 0; | |
1437 PKIX_UInt32 polx = 0; | |
1438 PKIX_Boolean isIncluded = PKIX_FALSE; | |
1439 PKIX_List *children = NULL; /* PolicyNodes */ | |
1440 PKIX_PolicyNode *childNode = NULL; | |
1441 PKIX_List *expectedPolicies = NULL; /* OIDs */ | |
1442 PKIX_PL_OID *policyOID = NULL; | |
1443 PKIX_PL_OID *childPolicy = NULL; | |
1444 PKIX_List *subjectDomainPolicies = NULL; /* OIDs */ | |
1445 | |
1446 PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_CheckAny"); | |
1447 PKIX_NULLCHECK_TWO(currentNode, state); | |
1448 | |
1449 PKIX_CHECK(PKIX_PolicyNode_GetDepth | |
1450 (currentNode, &depth, plContext), | |
1451 PKIX_POLICYNODEGETDEPTHFAILED); | |
1452 | |
1453 PKIX_CHECK(pkix_PolicyNode_GetChildrenMutable | |
1454 (currentNode, &children, plContext), | |
1455 PKIX_POLICYNODEGETCHILDRENMUTABLEFAILED); | |
1456 | |
1457 if (children) { | |
1458 PKIX_CHECK(PKIX_List_GetLength | |
1459 (children, &numChildren, plContext), | |
1460 PKIX_LISTGETLENGTHFAILED); | |
1461 } | |
1462 | |
1463 if (depth < (state->certsProcessed)) { | |
1464 for (childIx = 0; childIx < numChildren; childIx++) { | |
1465 | |
1466 PKIX_CHECK(PKIX_List_GetItem | |
1467 (children, | |
1468 childIx, | |
1469 (PKIX_PL_Object **)&childNode, | |
1470 plContext), | |
1471 PKIX_LISTGETITEMFAILED); | |
1472 | |
1473 PKIX_NULLCHECK_ONE(childNode); | |
1474 PKIX_CHECK(pkix_PolicyChecker_CheckAny | |
1475 (childNode, | |
1476 qualsOfAny, | |
1477 policyMaps, | |
1478 state, | |
1479 plContext), | |
1480 PKIX_POLICYCHECKERCHECKANYFAILED); | |
1481 | |
1482 PKIX_DECREF(childNode); | |
1483 } | |
1484 } else { /* if at the bottom of the tree */ | |
1485 | |
1486 PKIX_CHECK(PKIX_PolicyNode_GetExpectedPolicies | |
1487 (currentNode, &expectedPolicies, plContext), | |
1488 PKIX_POLICYNODEGETEXPECTEDPOLICIESFAILED); | |
1489 | |
1490 /* Expected Policy Set is not allowed to be NULL */ | |
1491 PKIX_NULLCHECK_ONE(expectedPolicies); | |
1492 | |
1493 PKIX_CHECK(PKIX_List_GetLength | |
1494 (expectedPolicies, &numPolicies, plContext), | |
1495 PKIX_LISTGETLENGTHFAILED); | |
1496 | |
1497 for (polx = 0; polx < numPolicies; polx++) { | |
1498 PKIX_CHECK(PKIX_List_GetItem | |
1499 (expectedPolicies, | |
1500 polx, | |
1501 (PKIX_PL_Object **)&policyOID, | |
1502 plContext), | |
1503 PKIX_LISTGETITEMFAILED); | |
1504 | |
1505 PKIX_NULLCHECK_ONE(policyOID); | |
1506 | |
1507 isIncluded = PKIX_FALSE; | |
1508 | |
1509 for (childIx = 0; | |
1510 (!isIncluded && (childIx < numChildren)); | |
1511 childIx++) { | |
1512 | |
1513 PKIX_CHECK(PKIX_List_GetItem | |
1514 (children, | |
1515 childIx, | |
1516 (PKIX_PL_Object **)&childNode, | |
1517 plContext), | |
1518 PKIX_LISTGETITEMFAILED); | |
1519 | |
1520 PKIX_NULLCHECK_ONE(childNode); | |
1521 | |
1522 PKIX_CHECK(PKIX_PolicyNode_GetValidPolicy | |
1523 (childNode, &childPolicy, plContext), | |
1524 PKIX_POLICYNODEGETVALIDPOLICYFAILED); | |
1525 | |
1526 PKIX_NULLCHECK_ONE(childPolicy); | |
1527 | |
1528 PKIX_EQUALS(policyOID, childPolicy, &isIncluded, plContext, | |
1529 PKIX_OBJECTEQUALSFAILED); | |
1530 | |
1531 PKIX_DECREF(childNode); | |
1532 PKIX_DECREF(childPolicy); | |
1533 } | |
1534 | |
1535 if (!isIncluded) { | |
1536 if (policyMaps) { | |
1537 PKIX_CHECK | |
1538 (pkix_PolicyChecker_MapGetSubjectDomainPolicies | |
1539 (policyMaps, | |
1540 policyOID, | |
1541 &subjectDomainPolicies, | |
1542 plContext), | |
1543 PKIX_POLICYCHECKERMAPGETSUBJECTDOMAINPOLICIESFAILED); | |
1544 } | |
1545 PKIX_CHECK(pkix_PolicyChecker_Spawn | |
1546 (currentNode, | |
1547 policyOID, | |
1548 qualsOfAny, | |
1549 subjectDomainPolicies, | |
1550 state, | |
1551 plContext), | |
1552 PKIX_POLICYCHECKERSPAWNFAILED); | |
1553 PKIX_DECREF(subjectDomainPolicies); | |
1554 } | |
1555 | |
1556 PKIX_DECREF(policyOID); | |
1557 } | |
1558 } | |
1559 | |
1560 cleanup: | |
1561 | |
1562 PKIX_DECREF(children); | |
1563 PKIX_DECREF(childNode); | |
1564 PKIX_DECREF(expectedPolicies); | |
1565 PKIX_DECREF(policyOID); | |
1566 PKIX_DECREF(childPolicy); | |
1567 PKIX_DECREF(subjectDomainPolicies); | |
1568 | |
1569 PKIX_RETURN(CERTCHAINCHECKER); | |
1570 | |
1571 } | |
1572 | |
1573 /* | |
1574 * FUNCTION: pkix_PolicyChecker_CalculateIntersection | |
1575 * DESCRIPTION: | |
1576 * | |
1577 * Processes the PolicyNode pointed to by "currentNode", and its descendants, | |
1578 * using the PolicyCheckerState pointed to by "state", using the List at | |
1579 * the address pointed to by "nominees" the OIDs of policies that are in the | |
1580 * user-initial-policy-set but are not represented among the nodes at the | |
1581 * bottom of the tree, and storing at "pShouldBePruned" the value TRUE if | |
1582 * currentNode is childless at the end of this processing, FALSE if it has | |
1583 * children or is at the bottom of the tree. | |
1584 * | |
1585 * When this function is called at the top level, "nominees" should be the List | |
1586 * of all policies in the user-initial-policy-set. Policies that are | |
1587 * represented in the valid-policy-node-set are removed from this List. As a | |
1588 * result when nodes are created according to 6.1.5.(g)(iii)(3)(b), a node will | |
1589 * be created for each policy remaining in this List. | |
1590 * | |
1591 * This function implements the calculation of the intersection of the | |
1592 * validPolicyTree with the user-initial-policy-set, as described in | |
1593 * RFC 3280 6.1.5(g)(iii). | |
1594 * | |
1595 * PARAMETERS: | |
1596 * "currentNode" | |
1597 * Address of PolicyNode whose descendants will be processed as described. | |
1598 * Must be non-NULL. | |
1599 * "state" | |
1600 * Address of the current state of the PKIX_PolicyChecker. Must be non-NULL | |
1601 * "nominees" | |
1602 * Address of List of the OIDs for which nodes should be created to replace | |
1603 * anyPolicy nodes. Must be non-NULL but may be empty. | |
1604 * "pShouldBePruned" | |
1605 * Address where Boolean return value, set to TRUE if this PolicyNode | |
1606 * should be deleted, is stored. Must be non-NULL. | |
1607 * "plContext" | |
1608 * Platform-specific context pointer. | |
1609 * THREAD SAFETY: | |
1610 * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
1611 * RETURNS: | |
1612 * Returns NULL if the function succeeds | |
1613 * Returns a CertChainChecker Error if the functions fails in a non-fatal way | |
1614 * Returns a Fatal Error if the function fails in an unrecoverable way | |
1615 */ | |
1616 static PKIX_Error * | |
1617 pkix_PolicyChecker_CalculateIntersection( | |
1618 PKIX_PolicyNode *currentNode, | |
1619 PKIX_PolicyCheckerState *state, | |
1620 PKIX_List *nominees, /* OIDs */ | |
1621 PKIX_Boolean *pShouldBePruned, | |
1622 void *plContext) | |
1623 { | |
1624 PKIX_Boolean currentPolicyIsAny = PKIX_FALSE; | |
1625 PKIX_Boolean parentPolicyIsAny = PKIX_FALSE; | |
1626 PKIX_Boolean currentPolicyIsValid = PKIX_FALSE; | |
1627 PKIX_Boolean shouldBePruned = PKIX_FALSE; | |
1628 PKIX_Boolean priorCriticality = PKIX_FALSE; | |
1629 PKIX_UInt32 depth = 0; | |
1630 PKIX_UInt32 numChildren = 0; | |
1631 PKIX_UInt32 childIndex = 0; | |
1632 PKIX_UInt32 numNominees = 0; | |
1633 PKIX_UInt32 polIx = 0; | |
1634 PKIX_PL_OID *currentPolicy = NULL; | |
1635 PKIX_PL_OID *parentPolicy = NULL; | |
1636 PKIX_PL_OID *substPolicy = NULL; | |
1637 PKIX_PolicyNode *parent = NULL; | |
1638 PKIX_PolicyNode *child = NULL; | |
1639 PKIX_List *children = NULL; /* PolicyNodes */ | |
1640 PKIX_List *policyQualifiers = NULL; | |
1641 | |
1642 PKIX_ENTER | |
1643 (CERTCHAINCHECKER, | |
1644 "pkix_PolicyChecker_CalculateIntersection"); | |
1645 | |
1646 /* | |
1647 * We call this function if the valid_policy_tree is not NULL and | |
1648 * the user-initial-policy-set is not any-policy. | |
1649 */ | |
1650 if (!state->validPolicyTree || state->initialIsAnyPolicy) { | |
1651 PKIX_ERROR(PKIX_PRECONDITIONFAILED); | |
1652 } | |
1653 | |
1654 PKIX_NULLCHECK_FOUR(currentNode, state, nominees, pShouldBePruned); | |
1655 | |
1656 PKIX_CHECK(PKIX_PolicyNode_GetValidPolicy | |
1657 (currentNode, ¤tPolicy, plContext), | |
1658 PKIX_POLICYNODEGETVALIDPOLICYFAILED); | |
1659 | |
1660 PKIX_NULLCHECK_TWO(state->anyPolicyOID, currentPolicy); | |
1661 | |
1662 PKIX_EQUALS | |
1663 (state->anyPolicyOID, | |
1664 currentPolicy, | |
1665 ¤tPolicyIsAny, | |
1666 plContext, | |
1667 PKIX_OBJECTEQUALSFAILED); | |
1668 | |
1669 PKIX_CHECK(PKIX_PolicyNode_GetParent(currentNode, &parent, plContext), | |
1670 PKIX_POLICYNODEGETPARENTFAILED); | |
1671 | |
1672 if (currentPolicyIsAny == PKIX_FALSE) { | |
1673 | |
1674 /* | |
1675 * If we are at the top of the tree, or if our | |
1676 * parent's validPolicy is anyPolicy, we are in | |
1677 * the valid policy node set. | |
1678 */ | |
1679 if (parent) { | |
1680 PKIX_CHECK(PKIX_PolicyNode_GetValidPolicy | |
1681 (parent, &parentPolicy, plContext), | |
1682 PKIX_POLICYNODEGETVALIDPOLICYFAILED); | |
1683 | |
1684 PKIX_NULLCHECK_ONE(parentPolicy); | |
1685 | |
1686 PKIX_EQUALS | |
1687 (state->anyPolicyOID, | |
1688 parentPolicy, | |
1689 &parentPolicyIsAny, | |
1690 plContext, | |
1691 PKIX_OBJECTEQUALSFAILED); | |
1692 } | |
1693 | |
1694 /* | |
1695 * Section 6.1.5(g)(iii)(2) | |
1696 * If this node's policy is not in the user-initial-policy-set, | |
1697 * it is not in the intersection. Prune it. | |
1698 */ | |
1699 if (!parent || parentPolicyIsAny) { | |
1700 PKIX_CHECK(pkix_List_Contains | |
1701 (state->userInitialPolicySet, | |
1702 (PKIX_PL_Object *)currentPolicy, | |
1703 ¤tPolicyIsValid, | |
1704 plContext), | |
1705 PKIX_LISTCONTAINSFAILED); | |
1706 if (!currentPolicyIsValid) { | |
1707 *pShouldBePruned = PKIX_TRUE; | |
1708 goto cleanup; | |
1709 } | |
1710 | |
1711 /* | |
1712 * If this node's policy is in the user-initial-policy- | |
1713 * set, it will propagate that policy into the next | |
1714 * level of the tree. Remove the policy from the list | |
1715 * of policies that an anyPolicy will spawn. | |
1716 */ | |
1717 PKIX_CHECK(pkix_List_Remove | |
1718 (nominees, | |
1719 (PKIX_PL_Object *)currentPolicy, | |
1720 plContext), | |
1721 PKIX_LISTREMOVEFAILED); | |
1722 } | |
1723 } | |
1724 | |
1725 | |
1726 /* Are we at the bottom of the tree? */ | |
1727 | |
1728 PKIX_CHECK(PKIX_PolicyNode_GetDepth | |
1729 (currentNode, &depth, plContext), | |
1730 PKIX_POLICYNODEGETDEPTHFAILED); | |
1731 | |
1732 if (depth == (state->numCerts)) { | |
1733 /* | |
1734 * Section 6.1.5(g)(iii)(3) | |
1735 * Replace anyPolicy nodes... | |
1736 */ | |
1737 if (currentPolicyIsAny == PKIX_TRUE) { | |
1738 | |
1739 /* replace this node */ | |
1740 | |
1741 PKIX_CHECK(PKIX_List_GetLength | |
1742 (nominees, &numNominees, plContext), | |
1743 PKIX_LISTGETLENGTHFAILED); | |
1744 | |
1745 if (numNominees) { | |
1746 | |
1747 PKIX_CHECK(PKIX_PolicyNode_GetPolicyQualifiers | |
1748 (currentNode, | |
1749 &policyQualifiers, | |
1750 plContext), | |
1751 PKIX_POLICYNODEGETPOLICYQUALIFIERSFAILED); | |
1752 | |
1753 PKIX_CHECK(PKIX_PolicyNode_IsCritical | |
1754 (currentNode, &priorCriticality, plContext), | |
1755 PKIX_POLICYNODEISCRITICALFAILED); | |
1756 } | |
1757 | |
1758 PKIX_NULLCHECK_ONE(parent); | |
1759 | |
1760 for (polIx = 0; polIx < numNominees; polIx++) { | |
1761 | |
1762 PKIX_CHECK(PKIX_List_GetItem | |
1763 (nominees, | |
1764 polIx, | |
1765 (PKIX_PL_Object **)&substPolicy, | |
1766 plContext), | |
1767 PKIX_LISTGETITEMFAILED); | |
1768 | |
1769 PKIX_CHECK(pkix_PolicyChecker_Spawn | |
1770 (parent, | |
1771 substPolicy, | |
1772 policyQualifiers, | |
1773 NULL, | |
1774 state, | |
1775 plContext), | |
1776 PKIX_POLICYCHECKERSPAWNFAILED); | |
1777 | |
1778 PKIX_DECREF(substPolicy); | |
1779 | |
1780 } | |
1781 /* remove currentNode from parent */ | |
1782 *pShouldBePruned = PKIX_TRUE; | |
1783 /* | |
1784 * We can get away with augmenting the parent's List | |
1785 * of children because we started at the end and went | |
1786 * toward the beginning. New nodes are added at the end. | |
1787 */ | |
1788 } | |
1789 } else { | |
1790 /* | |
1791 * Section 6.1.5(g)(iii)(4) | |
1792 * Prune any childless nodes above the bottom level | |
1793 */ | |
1794 PKIX_CHECK(pkix_PolicyNode_GetChildrenMutable | |
1795 (currentNode, &children, plContext), | |
1796 PKIX_POLICYNODEGETCHILDRENMUTABLEFAILED); | |
1797 | |
1798 /* CurrentNode should have been pruned if childless. */ | |
1799 PKIX_NULLCHECK_ONE(children); | |
1800 | |
1801 PKIX_CHECK(PKIX_List_GetLength | |
1802 (children, &numChildren, plContext), | |
1803 PKIX_LISTGETLENGTHFAILED); | |
1804 | |
1805 for (childIndex = numChildren; childIndex > 0; childIndex--) { | |
1806 | |
1807 PKIX_CHECK(PKIX_List_GetItem | |
1808 (children, | |
1809 childIndex - 1, | |
1810 (PKIX_PL_Object **)&child, | |
1811 plContext), | |
1812 PKIX_LISTGETITEMFAILED); | |
1813 | |
1814 PKIX_CHECK(pkix_PolicyChecker_CalculateIntersection | |
1815 (child, state, nominees, &shouldBePruned, plContext), | |
1816 PKIX_POLICYCHECKERCALCULATEINTERSECTIONFAILED); | |
1817 | |
1818 if (PKIX_TRUE == shouldBePruned) { | |
1819 | |
1820 PKIX_CHECK(PKIX_List_DeleteItem | |
1821 (children, childIndex - 1, plContext), | |
1822 PKIX_LISTDELETEITEMFAILED); | |
1823 PKIX_CHECK(PKIX_PL_Object_InvalidateCache | |
1824 ((PKIX_PL_Object *)state, plContext), | |
1825 PKIX_OBJECTINVALIDATECACHEFAILED); | |
1826 } | |
1827 | |
1828 PKIX_DECREF(child); | |
1829 } | |
1830 | |
1831 PKIX_CHECK(PKIX_List_GetLength | |
1832 (children, &numChildren, plContext), | |
1833 PKIX_LISTGETLENGTHFAILED); | |
1834 | |
1835 if (numChildren == 0) { | |
1836 *pShouldBePruned = PKIX_TRUE; | |
1837 } | |
1838 } | |
1839 cleanup: | |
1840 PKIX_DECREF(currentPolicy); | |
1841 PKIX_DECREF(parentPolicy); | |
1842 PKIX_DECREF(substPolicy); | |
1843 PKIX_DECREF(parent); | |
1844 PKIX_DECREF(child); | |
1845 PKIX_DECREF(children); | |
1846 PKIX_DECREF(policyQualifiers); | |
1847 | |
1848 PKIX_RETURN(CERTCHAINCHECKER); | |
1849 | |
1850 } | |
1851 | |
1852 /* | |
1853 * FUNCTION: pkix_PolicyChecker_PolicyMapProcessing | |
1854 * DESCRIPTION: | |
1855 * | |
1856 * Performs the processing of Policies in the List of CertPolicyMaps pointed | |
1857 * to by "policyMaps", using and updating the PolicyCheckerState pointed to by | |
1858 * "state". | |
1859 * | |
1860 * This function implements the policyMap processing described in RFC3280 | |
1861 * Section 6.1.4(b)(1), after certificate i has been processed, in preparation | |
1862 * for certificate i+1. Section references are to that document. | |
1863 * | |
1864 * PARAMETERS: | |
1865 * "policyMaps" | |
1866 * Address of the List of CertPolicyMaps presented by certificate i. | |
1867 * Must be non-NULL. | |
1868 * "certPoliciesIncludeAny" | |
1869 * Boolean value which is PKIX_TRUE if the current certificate asserts | |
1870 * anyPolicy, PKIX_FALSE otherwise. | |
1871 * "qualsOfAny" | |
1872 * Address of List of qualifiers of the anyPolicy in the current | |
1873 * certificate. May be empty or NULL. | |
1874 * "state" | |
1875 * Address of the current state of the PKIX_PolicyChecker. | |
1876 * Must be non-NULL. | |
1877 * "plContext" | |
1878 * Platform-specific context pointer. | |
1879 * THREAD SAFETY: | |
1880 * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
1881 * RETURNS: | |
1882 * Returns NULL if the function succeeds | |
1883 * Returns a CertChainChecker Error if the functions fails in a non-fatal way | |
1884 * Returns a Fatal Error if the function fails in an unrecoverable way | |
1885 */ | |
1886 static PKIX_Error * | |
1887 pkix_PolicyChecker_PolicyMapProcessing( | |
1888 PKIX_List *policyMaps, /* CertPolicyMaps */ | |
1889 PKIX_Boolean certPoliciesIncludeAny, | |
1890 PKIX_List *qualsOfAny, | |
1891 PKIX_PolicyCheckerState *state, | |
1892 void *plContext) | |
1893 { | |
1894 PKIX_UInt32 numPolicies = 0; | |
1895 PKIX_UInt32 polX = 0; | |
1896 PKIX_PL_OID *policyOID = NULL; | |
1897 PKIX_List *newMappedPolicies = NULL; /* OIDs */ | |
1898 PKIX_List *subjectDomainPolicies = NULL; /* OIDs */ | |
1899 | |
1900 PKIX_ENTER | |
1901 (CERTCHAINCHECKER, | |
1902 "pkix_PolicyChecker_PolicyMapProcessing"); | |
1903 PKIX_NULLCHECK_THREE | |
1904 (policyMaps, | |
1905 state, | |
1906 state->mappedUserInitialPolicySet); | |
1907 | |
1908 /* | |
1909 * For each policy in mappedUserInitialPolicySet, if it is not mapped, | |
1910 * append it to new policySet; if it is mapped, append its | |
1911 * subjectDomainPolicies to new policySet. When done, this new | |
1912 * policySet will replace mappedUserInitialPolicySet. | |
1913 */ | |
1914 PKIX_CHECK(PKIX_List_Create | |
1915 (&newMappedPolicies, plContext), | |
1916 PKIX_LISTCREATEFAILED); | |
1917 | |
1918 PKIX_CHECK(PKIX_List_GetLength | |
1919 (state->mappedUserInitialPolicySet, | |
1920 &numPolicies, | |
1921 plContext), | |
1922 PKIX_LISTGETLENGTHFAILED); | |
1923 | |
1924 for (polX = 0; polX < numPolicies; polX++) { | |
1925 | |
1926 PKIX_CHECK(PKIX_List_GetItem | |
1927 (state->mappedUserInitialPolicySet, | |
1928 polX, | |
1929 (PKIX_PL_Object **)&policyOID, | |
1930 plContext), | |
1931 PKIX_LISTGETITEMFAILED); | |
1932 | |
1933 PKIX_CHECK(pkix_PolicyChecker_MapGetSubjectDomainPolicies | |
1934 (policyMaps, | |
1935 policyOID, | |
1936 &subjectDomainPolicies, | |
1937 plContext), | |
1938 PKIX_POLICYCHECKERMAPGETSUBJECTDOMAINPOLICIESFAILED); | |
1939 | |
1940 if (subjectDomainPolicies) { | |
1941 | |
1942 PKIX_CHECK(pkix_List_AppendUnique | |
1943 (newMappedPolicies, | |
1944 subjectDomainPolicies, | |
1945 plContext), | |
1946 PKIX_LISTAPPENDUNIQUEFAILED); | |
1947 | |
1948 PKIX_DECREF(subjectDomainPolicies); | |
1949 | |
1950 } else { | |
1951 PKIX_CHECK(PKIX_List_AppendItem | |
1952 (newMappedPolicies, | |
1953 (PKIX_PL_Object *)policyOID, | |
1954 plContext), | |
1955 PKIX_LISTAPPENDITEMFAILED); | |
1956 } | |
1957 PKIX_DECREF(policyOID); | |
1958 } | |
1959 | |
1960 /* | |
1961 * For each policy ID-P remaining in mappedPolicyOIDs, it has not been | |
1962 * propagated to the bottom of the tree (depth i). If policyMapping | |
1963 * is greater than zero and this cert contains anyPolicy and the tree | |
1964 * contains an anyPolicy node at depth i-1, then we must create a node | |
1965 * with validPolicy ID-P, the policy qualifiers of anyPolicy in | |
1966 * this certificate, and expectedPolicySet the subjectDomainPolicies | |
1967 * that ID-P maps to. We also then add those subjectDomainPolicies to | |
1968 * the list of policies that will be accepted in the next certificate, | |
1969 * the mappedUserInitialPolicySet. | |
1970 */ | |
1971 | |
1972 if ((state->policyMapping > 0) && (certPoliciesIncludeAny) && | |
1973 (state->anyPolicyNodeAtBottom) && (state->mappedPolicyOIDs)) { | |
1974 | |
1975 PKIX_CHECK(PKIX_List_GetLength | |
1976 (state->mappedPolicyOIDs, | |
1977 &numPolicies, | |
1978 plContext), | |
1979 PKIX_LISTGETLENGTHFAILED); | |
1980 | |
1981 for (polX = 0; polX < numPolicies; polX++) { | |
1982 | |
1983 PKIX_CHECK(PKIX_List_GetItem | |
1984 (state->mappedPolicyOIDs, | |
1985 polX, | |
1986 (PKIX_PL_Object **)&policyOID, | |
1987 plContext), | |
1988 PKIX_LISTGETITEMFAILED); | |
1989 | |
1990 PKIX_CHECK(pkix_PolicyChecker_MapGetSubjectDomainPolicies | |
1991 (policyMaps, | |
1992 policyOID, | |
1993 &subjectDomainPolicies, | |
1994 plContext), | |
1995 PKIX_POLICYCHECKERMAPGETSUBJECTDOMAINPOLICIESFAILED); | |
1996 | |
1997 PKIX_CHECK(pkix_PolicyChecker_Spawn | |
1998 (state->anyPolicyNodeAtBottom, | |
1999 policyOID, | |
2000 qualsOfAny, | |
2001 subjectDomainPolicies, | |
2002 state, | |
2003 plContext), | |
2004 PKIX_POLICYCHECKERSPAWNFAILED); | |
2005 | |
2006 PKIX_CHECK(pkix_List_AppendUnique | |
2007 (newMappedPolicies, | |
2008 subjectDomainPolicies, | |
2009 plContext), | |
2010 PKIX_LISTAPPENDUNIQUEFAILED); | |
2011 | |
2012 PKIX_DECREF(subjectDomainPolicies); | |
2013 PKIX_DECREF(policyOID); | |
2014 } | |
2015 } | |
2016 | |
2017 PKIX_CHECK(PKIX_List_SetImmutable(newMappedPolicies, plContext), | |
2018 PKIX_LISTSETIMMUTABLEFAILED); | |
2019 | |
2020 PKIX_DECREF(state->mappedUserInitialPolicySet); | |
2021 PKIX_INCREF(newMappedPolicies); | |
2022 | |
2023 state->mappedUserInitialPolicySet = newMappedPolicies; | |
2024 | |
2025 cleanup: | |
2026 | |
2027 PKIX_DECREF(policyOID); | |
2028 PKIX_DECREF(newMappedPolicies); | |
2029 PKIX_DECREF(subjectDomainPolicies); | |
2030 | |
2031 PKIX_RETURN(CERTCHAINCHECKER); | |
2032 } | |
2033 | |
2034 /* | |
2035 * FUNCTION: pkix_PolicyChecker_WrapUpProcessing | |
2036 * DESCRIPTION: | |
2037 * | |
2038 * Performs the wrap-up processing for the Cert pointed to by "cert", | |
2039 * using and updating the PolicyCheckerState pointed to by "state". | |
2040 * | |
2041 * This function implements the wrap-up processing described in RFC3280 | |
2042 * Section 6.1.5, after the final certificate has been processed. Section | |
2043 * references in the comments are to that document. | |
2044 * | |
2045 * PARAMETERS: | |
2046 * "cert" | |
2047 * Address of the current (presumably the end entity) certificate. | |
2048 * Must be non-NULL. | |
2049 * "state" | |
2050 * Address of the current state of the PKIX_PolicyChecker. | |
2051 * Must be non-NULL. | |
2052 * "plContext" | |
2053 * Platform-specific context pointer. | |
2054 * THREAD SAFETY: | |
2055 * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
2056 * RETURNS: | |
2057 * Returns NULL if the function succeeds | |
2058 * Returns a CertChainChecker Error if the functions fails in a non-fatal way | |
2059 * Returns a Fatal Error if the function fails in an unrecoverable way | |
2060 */ | |
2061 static PKIX_Error * | |
2062 pkix_PolicyChecker_WrapUpProcessing( | |
2063 PKIX_PL_Cert *cert, | |
2064 PKIX_PolicyCheckerState *state, | |
2065 void *plContext) | |
2066 { | |
2067 PKIX_Int32 explicitPolicySkipCerts = 0; | |
2068 PKIX_Boolean isSelfIssued = PKIX_FALSE; | |
2069 PKIX_Boolean shouldBePruned = PKIX_FALSE; | |
2070 PKIX_List *nominees = NULL; /* OIDs */ | |
2071 #if PKIX_CERTPOLICYCHECKERSTATEDEBUG | |
2072 PKIX_PL_String *stateString = NULL; | |
2073 char *stateAscii = NULL; | |
2074 PKIX_UInt32 length; | |
2075 #endif | |
2076 | |
2077 PKIX_ENTER | |
2078 (CERTCHAINCHECKER, | |
2079 "pkix_PolicyChecker_WrapUpProcessing"); | |
2080 PKIX_NULLCHECK_THREE(cert, state, state->userInitialPolicySet); | |
2081 | |
2082 #if PKIX_CERTPOLICYCHECKERSTATEDEBUG | |
2083 PKIX_CHECK(PKIX_PL_Object_ToString | |
2084 ((PKIX_PL_Object*)state, &stateString, plContext), | |
2085 PKIX_OBJECTTOSTRINGFAILED); | |
2086 | |
2087 PKIX_CHECK(PKIX_PL_String_GetEncoded | |
2088 (stateString, | |
2089 PKIX_ESCASCII, | |
2090 (void **)&stateAscii, | |
2091 &length, | |
2092 plContext), | |
2093 PKIX_STRINGGETENCODEDFAILED); | |
2094 | |
2095 PKIX_DEBUG_ARG("%s\n", stateAscii); | |
2096 | |
2097 PKIX_FREE(stateAscii); | |
2098 PKIX_DECREF(stateString); | |
2099 #endif | |
2100 | |
2101 /* Section 6.1.5(a) ... */ | |
2102 PKIX_CHECK(pkix_IsCertSelfIssued | |
2103 (cert, &isSelfIssued, plContext), | |
2104 PKIX_ISCERTSELFISSUEDFAILED); | |
2105 | |
2106 if (!isSelfIssued) { | |
2107 if (state->explicitPolicy > 0) { | |
2108 | |
2109 state->explicitPolicy--; | |
2110 | |
2111 PKIX_CHECK(PKIX_PL_Object_InvalidateCache | |
2112 ((PKIX_PL_Object *)state, plContext), | |
2113 PKIX_OBJECTINVALIDATECACHEFAILED); | |
2114 } | |
2115 } | |
2116 | |
2117 /* Section 6.1.5(b) ... */ | |
2118 PKIX_CHECK(PKIX_PL_Cert_GetRequireExplicitPolicy | |
2119 (cert, &explicitPolicySkipCerts, plContext), | |
2120 PKIX_CERTGETREQUIREEXPLICITPOLICYFAILED); | |
2121 | |
2122 if (explicitPolicySkipCerts == 0) { | |
2123 state->explicitPolicy = 0; | |
2124 } | |
2125 | |
2126 /* Section 6.1.5(g)(i) ... */ | |
2127 | |
2128 if (!(state->validPolicyTree)) { | |
2129 goto cleanup; | |
2130 } | |
2131 | |
2132 /* Section 6.1.5(g)(ii) ... */ | |
2133 | |
2134 if (state->initialIsAnyPolicy) { | |
2135 goto cleanup; | |
2136 } | |
2137 | |
2138 /* | |
2139 * Section 6.1.5(g)(iii) ... | |
2140 * Create a list of policies which could be substituted for anyPolicy. | |
2141 * Start with a (mutable) copy of user-initial-policy-set. | |
2142 */ | |
2143 PKIX_CHECK(pkix_PolicyChecker_MakeMutableCopy | |
2144 (state->userInitialPolicySet, &nominees, plContext), | |
2145 PKIX_POLICYCHECKERMAKEMUTABLECOPYFAILED); | |
2146 | |
2147 PKIX_CHECK(pkix_PolicyChecker_CalculateIntersection | |
2148 (state->validPolicyTree, /* node at top of tree */ | |
2149 state, | |
2150 nominees, | |
2151 &shouldBePruned, | |
2152 plContext), | |
2153 PKIX_POLICYCHECKERCALCULATEINTERSECTIONFAILED); | |
2154 | |
2155 if (PKIX_TRUE == shouldBePruned) { | |
2156 PKIX_DECREF(state->validPolicyTree); | |
2157 } | |
2158 | |
2159 if (state->validPolicyTree) { | |
2160 PKIX_CHECK(PKIX_PL_Object_InvalidateCache | |
2161 ((PKIX_PL_Object *)state->validPolicyTree, plContext), | |
2162 PKIX_OBJECTINVALIDATECACHEFAILED); | |
2163 } | |
2164 | |
2165 PKIX_CHECK(PKIX_PL_Object_InvalidateCache | |
2166 ((PKIX_PL_Object *)state, plContext), | |
2167 PKIX_OBJECTINVALIDATECACHEFAILED); | |
2168 | |
2169 #if PKIX_CERTPOLICYCHECKERSTATEDEBUG | |
2170 if (state->validPolicyTree) { | |
2171 PKIX_CHECK(PKIX_PL_Object_ToString | |
2172 ((PKIX_PL_Object*)state, &stateString, plContext), | |
2173 PKIX_OBJECTTOSTRINGFAILED); | |
2174 | |
2175 PKIX_CHECK(PKIX_PL_String_GetEncoded | |
2176 (stateString, | |
2177 PKIX_ESCASCII, | |
2178 (void **)&stateAscii, | |
2179 &length, | |
2180 plContext), | |
2181 PKIX_STRINGGETENCODEDFAILED); | |
2182 | |
2183 PKIX_DEBUG_ARG | |
2184 ("After CalculateIntersection:\n%s\n", stateAscii); | |
2185 | |
2186 PKIX_FREE(stateAscii); | |
2187 PKIX_DECREF(stateString); | |
2188 } else { | |
2189 PKIX_DEBUG("validPolicyTree is NULL\n"); | |
2190 } | |
2191 #endif | |
2192 | |
2193 /* Section 6.1.5(g)(iii)(4) ... */ | |
2194 | |
2195 if (state->validPolicyTree) { | |
2196 | |
2197 PKIX_CHECK(pkix_PolicyNode_Prune | |
2198 (state->validPolicyTree, | |
2199 state->numCerts, | |
2200 &shouldBePruned, | |
2201 plContext), | |
2202 PKIX_POLICYNODEPRUNEFAILED); | |
2203 | |
2204 if (shouldBePruned) { | |
2205 PKIX_DECREF(state->validPolicyTree); | |
2206 } | |
2207 } | |
2208 | |
2209 if (state->validPolicyTree) { | |
2210 PKIX_CHECK(PKIX_PL_Object_InvalidateCache | |
2211 ((PKIX_PL_Object *)state->validPolicyTree, plContext), | |
2212 PKIX_OBJECTINVALIDATECACHEFAILED); | |
2213 } | |
2214 | |
2215 PKIX_CHECK(PKIX_PL_Object_InvalidateCache | |
2216 ((PKIX_PL_Object *)state, plContext), | |
2217 PKIX_OBJECTINVALIDATECACHEFAILED); | |
2218 | |
2219 #if PKIX_CERTPOLICYCHECKERSTATEDEBUG | |
2220 PKIX_CHECK(PKIX_PL_Object_ToString | |
2221 ((PKIX_PL_Object*)state, &stateString, plContext), | |
2222 PKIX_OBJECTTOSTRINGFAILED); | |
2223 PKIX_CHECK(PKIX_PL_String_GetEncoded | |
2224 (stateString, | |
2225 PKIX_ESCASCII, | |
2226 (void **)&stateAscii, | |
2227 &length, | |
2228 plContext), | |
2229 PKIX_STRINGGETENCODEDFAILED); | |
2230 PKIX_DEBUG_ARG("%s\n", stateAscii); | |
2231 | |
2232 PKIX_FREE(stateAscii); | |
2233 PKIX_DECREF(stateString); | |
2234 #endif | |
2235 | |
2236 cleanup: | |
2237 | |
2238 PKIX_DECREF(nominees); | |
2239 | |
2240 PKIX_RETURN(CERTCHAINCHECKER); | |
2241 } | |
2242 | |
2243 | |
2244 /* | |
2245 * FUNCTION: pkix_PolicyChecker_Check | |
2246 * (see comments in pkix_checker.h for PKIX_CertChainChecker_CheckCallback) | |
2247 * | |
2248 * Labels referring to sections, such as "Section 6.1.3(d)", refer to | |
2249 * sections of RFC3280, Section 6.1.3 Basic Certificate Processing. | |
2250 * | |
2251 * If a non-fatal error occurs, it is unlikely that policy processing can | |
2252 * continue. But it is still possible that chain validation could succeed if | |
2253 * policy processing is non-critical. So if this function receives a non-fatal | |
2254 * error from a lower level routine, it aborts policy processing by setting | |
2255 * the validPolicyTree to NULL and tries to continue. | |
2256 * | |
2257 */ | |
2258 static PKIX_Error * | |
2259 pkix_PolicyChecker_Check( | |
2260 PKIX_CertChainChecker *checker, | |
2261 PKIX_PL_Cert *cert, | |
2262 PKIX_List *unresolvedCriticals, /* OIDs */ | |
2263 void **pNBIOContext, | |
2264 void *plContext) | |
2265 { | |
2266 PKIX_UInt32 numPolicies = 0; | |
2267 PKIX_UInt32 polX = 0; | |
2268 PKIX_Boolean result = PKIX_FALSE; | |
2269 PKIX_Int32 inhibitMappingSkipCerts = 0; | |
2270 PKIX_Int32 explicitPolicySkipCerts = 0; | |
2271 PKIX_Int32 inhibitAnyPolicySkipCerts = 0; | |
2272 PKIX_Boolean shouldBePruned = PKIX_FALSE; | |
2273 PKIX_Boolean isSelfIssued = PKIX_FALSE; | |
2274 PKIX_Boolean certPoliciesIncludeAny = PKIX_FALSE; | |
2275 PKIX_Boolean doAnyPolicyProcessing = PKIX_FALSE; | |
2276 | |
2277 PKIX_PolicyCheckerState *state = NULL; | |
2278 PKIX_List *certPolicyInfos = NULL; /* CertPolicyInfos */ | |
2279 PKIX_PL_CertPolicyInfo *policy = NULL; | |
2280 PKIX_PL_OID *policyOID = NULL; | |
2281 PKIX_List *qualsOfAny = NULL; /* CertPolicyQualifiers */ | |
2282 PKIX_List *policyQualifiers = NULL; /* CertPolicyQualifiers */ | |
2283 PKIX_List *policyMaps = NULL; /* CertPolicyMaps */ | |
2284 PKIX_List *mappedPolicies = NULL; /* OIDs */ | |
2285 PKIX_Error *subroutineErr = NULL; | |
2286 #if PKIX_CERTPOLICYCHECKERSTATEDEBUG | |
2287 PKIX_PL_String *stateString = NULL; | |
2288 char *stateAscii = NULL; | |
2289 PKIX_PL_String *certString = NULL; | |
2290 char *certAscii = NULL; | |
2291 PKIX_UInt32 length; | |
2292 #endif | |
2293 | |
2294 PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_Check"); | |
2295 PKIX_NULLCHECK_FOUR(checker, cert, unresolvedCriticals, pNBIOContext); | |
2296 | |
2297 *pNBIOContext = NULL; /* we never block on pending I/O */ | |
2298 | |
2299 PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState | |
2300 (checker, (PKIX_PL_Object **)&state, plContext), | |
2301 PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED); | |
2302 | |
2303 PKIX_NULLCHECK_TWO(state, state->certPoliciesExtension); | |
2304 | |
2305 #if PKIX_CERTPOLICYCHECKERSTATEDEBUG | |
2306 PKIX_CHECK(PKIX_PL_Object_ToString | |
2307 ((PKIX_PL_Object*)state, &stateString, plContext), | |
2308 PKIX_OBJECTTOSTRINGFAILED); | |
2309 PKIX_CHECK(PKIX_PL_String_GetEncoded | |
2310 (stateString, | |
2311 PKIX_ESCASCII, | |
2312 (void **)&stateAscii, | |
2313 &length, | |
2314 plContext), | |
2315 PKIX_STRINGGETENCODEDFAILED); | |
2316 PKIX_DEBUG_ARG("On entry %s\n", stateAscii); | |
2317 PKIX_FREE(stateAscii); | |
2318 PKIX_DECREF(stateString); | |
2319 #endif | |
2320 | |
2321 /* | |
2322 * Section 6.1.4(a) | |
2323 * If this is not the last certificate, and if | |
2324 * policyMapping extension is present, check that no | |
2325 * issuerDomainPolicy or subjectDomainPolicy is equal to the | |
2326 * special policy anyPolicy. | |
2327 */ | |
2328 if (state->certsProcessed != (state->numCerts - 1)) { | |
2329 PKIX_CHECK(PKIX_PL_Cert_GetPolicyMappings | |
2330 (cert, &policyMaps, plContext), | |
2331 PKIX_CERTGETPOLICYMAPPINGSFAILED); | |
2332 } | |
2333 | |
2334 if (policyMaps) { | |
2335 | |
2336 PKIX_CHECK(pkix_PolicyChecker_MapContains | |
2337 (policyMaps, state->anyPolicyOID, &result, plContext), | |
2338 PKIX_POLICYCHECKERMAPCONTAINSFAILED); | |
2339 | |
2340 if (result) { | |
2341 PKIX_ERROR(PKIX_INVALIDPOLICYMAPPINGINCLUDESANYPOLICY); | |
2342 } | |
2343 | |
2344 PKIX_CHECK(pkix_PolicyChecker_MapGetMappedPolicies | |
2345 (policyMaps, &mappedPolicies, plContext), | |
2346 PKIX_POLICYCHECKERMAPGETMAPPEDPOLICIESFAILED); | |
2347 | |
2348 PKIX_DECREF(state->mappedPolicyOIDs); | |
2349 PKIX_INCREF(mappedPolicies); | |
2350 state->mappedPolicyOIDs = mappedPolicies; | |
2351 } | |
2352 | |
2353 /* Section 6.1.3(d) */ | |
2354 if (state->validPolicyTree) { | |
2355 | |
2356 PKIX_CHECK(PKIX_PL_Cert_GetPolicyInformation | |
2357 (cert, &certPolicyInfos, plContext), | |
2358 PKIX_CERTGETPOLICYINFORMATIONFAILED); | |
2359 | |
2360 if (certPolicyInfos) { | |
2361 PKIX_CHECK(PKIX_List_GetLength | |
2362 (certPolicyInfos, &numPolicies, plContext), | |
2363 PKIX_LISTGETLENGTHFAILED); | |
2364 } | |
2365 | |
2366 if (numPolicies > 0) { | |
2367 | |
2368 PKIX_CHECK(PKIX_PL_Cert_AreCertPoliciesCritical | |
2369 (cert, &(state->certPoliciesCritical), plContext), | |
2370 PKIX_CERTARECERTPOLICIESCRITICALFAILED); | |
2371 | |
2372 /* Section 6.1.3(d)(1) For each policy not equal to anyPolicy */ | |
2373 for (polX = 0; polX < numPolicies; polX++) { | |
2374 | |
2375 PKIX_CHECK(PKIX_List_GetItem | |
2376 (certPolicyInfos, | |
2377 polX, | |
2378 (PKIX_PL_Object **)&policy, | |
2379 plContext), | |
2380 PKIX_LISTGETITEMFAILED); | |
2381 | |
2382 PKIX_CHECK(PKIX_PL_CertPolicyInfo_GetPolicyId | |
2383 (policy, &policyOID, plContext), | |
2384 PKIX_CERTPOLICYINFOGETPOLICYIDFAILED); | |
2385 | |
2386 PKIX_CHECK(PKIX_PL_CertPolicyInfo_GetPolQualifiers | |
2387 (policy, &policyQualifiers, plContext), | |
2388 PKIX_CERTPOLICYINFOGETPOLQUALIFIERSFAILED); | |
2389 | |
2390 PKIX_EQUALS | |
2391 (state->anyPolicyOID, | |
2392 policyOID, | |
2393 &result, | |
2394 plContext, | |
2395 PKIX_OIDEQUALFAILED); | |
2396 | |
2397 if (result == PKIX_FALSE) { | |
2398 | |
2399 /* Section 6.1.3(d)(1)(i) */ | |
2400 subroutineErr = pkix_PolicyChecker_CheckPolicy | |
2401 (policyOID, | |
2402 policyQualifiers, | |
2403 cert, | |
2404 policyMaps, | |
2405 state, | |
2406 plContext); | |
2407 if (subroutineErr) { | |
2408 goto subrErrorCleanup; | |
2409 } | |
2410 | |
2411 } else { | |
2412 /* | |
2413 * No descent (yet) for anyPolicy, but we will need | |
2414 * the policyQualifiers for anyPolicy in 6.1.3(d)(2) | |
2415 */ | |
2416 PKIX_DECREF(qualsOfAny); | |
2417 PKIX_INCREF(policyQualifiers); | |
2418 qualsOfAny = policyQualifiers; | |
2419 certPoliciesIncludeAny = PKIX_TRUE; | |
2420 } | |
2421 PKIX_DECREF(policy); | |
2422 PKIX_DECREF(policyOID); | |
2423 PKIX_DECREF(policyQualifiers); | |
2424 } | |
2425 | |
2426 /* Section 6.1.3(d)(2) */ | |
2427 if (certPoliciesIncludeAny == PKIX_TRUE) { | |
2428 if (state->inhibitAnyPolicy > 0) { | |
2429 doAnyPolicyProcessing = PKIX_TRUE; | |
2430 } else { | |
2431 /* We haven't yet counted the current cert */ | |
2432 if (((state->certsProcessed) + 1) < | |
2433 (state->numCerts)) { | |
2434 | |
2435 PKIX_CHECK(pkix_IsCertSelfIssued | |
2436 (cert, | |
2437 &doAnyPolicyProcessing, | |
2438 plContext), | |
2439 PKIX_ISCERTSELFISSUEDFAILED); | |
2440 } | |
2441 } | |
2442 if (doAnyPolicyProcessing) { | |
2443 subroutineErr = pkix_PolicyChecker_CheckAny | |
2444 (state->validPolicyTree, | |
2445 qualsOfAny, | |
2446 policyMaps, | |
2447 state, | |
2448 plContext); | |
2449 if (subroutineErr) { | |
2450 goto subrErrorCleanup; | |
2451 } | |
2452 } | |
2453 } | |
2454 | |
2455 /* Section 6.1.3(d)(3) */ | |
2456 if (state->validPolicyTree) { | |
2457 subroutineErr = pkix_PolicyNode_Prune | |
2458 (state->validPolicyTree, | |
2459 state->certsProcessed + 1, | |
2460 &shouldBePruned, | |
2461 plContext); | |
2462 if (subroutineErr) { | |
2463 goto subrErrorCleanup; | |
2464 } | |
2465 if (shouldBePruned) { | |
2466 PKIX_DECREF(state->validPolicyTree); | |
2467 PKIX_DECREF(state->anyPolicyNodeAtBottom); | |
2468 } | |
2469 } | |
2470 | |
2471 PKIX_CHECK(PKIX_PL_Object_InvalidateCache | |
2472 ((PKIX_PL_Object *)state, plContext), | |
2473 PKIX_OBJECTINVALIDATECACHEFAILED); | |
2474 | |
2475 } else { | |
2476 /* Section 6.1.3(e) */ | |
2477 PKIX_DECREF(state->validPolicyTree); | |
2478 PKIX_DECREF(state->anyPolicyNodeAtBottom); | |
2479 PKIX_DECREF(state->newAnyPolicyNode); | |
2480 | |
2481 PKIX_CHECK(PKIX_PL_Object_InvalidateCache | |
2482 ((PKIX_PL_Object *)state, plContext), | |
2483 PKIX_OBJECTINVALIDATECACHEFAILED); | |
2484 } | |
2485 } | |
2486 | |
2487 /* Section 6.1.3(f) */ | |
2488 if ((0 == state->explicitPolicy) && (!state->validPolicyTree)) { | |
2489 PKIX_ERROR(PKIX_CERTCHAINFAILSCERTIFICATEPOLICYVALIDATION); | |
2490 } | |
2491 | |
2492 /* | |
2493 * Remove Policy OIDs from list of unresolved critical | |
2494 * extensions, if present. | |
2495 */ | |
2496 PKIX_CHECK(pkix_List_Remove | |
2497 (unresolvedCriticals, | |
2498 (PKIX_PL_Object *)state->certPoliciesExtension, | |
2499 plContext), | |
2500 PKIX_LISTREMOVEFAILED); | |
2501 | |
2502 PKIX_CHECK(pkix_List_Remove | |
2503 (unresolvedCriticals, | |
2504 (PKIX_PL_Object *)state->policyMappingsExtension, | |
2505 plContext), | |
2506 PKIX_LISTREMOVEFAILED); | |
2507 | |
2508 PKIX_CHECK(pkix_List_Remove | |
2509 (unresolvedCriticals, | |
2510 (PKIX_PL_Object *)state->policyConstraintsExtension, | |
2511 plContext), | |
2512 PKIX_LISTREMOVEFAILED); | |
2513 | |
2514 PKIX_CHECK(pkix_List_Remove | |
2515 (unresolvedCriticals, | |
2516 (PKIX_PL_Object *)state->inhibitAnyPolicyExtension, | |
2517 plContext), | |
2518 PKIX_LISTREMOVEFAILED); | |
2519 | |
2520 state->certsProcessed++; | |
2521 | |
2522 /* If this was not the last certificate, do next-cert preparation */ | |
2523 if (state->certsProcessed != state->numCerts) { | |
2524 | |
2525 if (policyMaps) { | |
2526 subroutineErr = pkix_PolicyChecker_PolicyMapProcessing | |
2527 (policyMaps, | |
2528 certPoliciesIncludeAny, | |
2529 qualsOfAny, | |
2530 state, | |
2531 plContext); | |
2532 if (subroutineErr) { | |
2533 goto subrErrorCleanup; | |
2534 } | |
2535 } | |
2536 | |
2537 /* update anyPolicyNodeAtBottom pointer */ | |
2538 PKIX_DECREF(state->anyPolicyNodeAtBottom); | |
2539 state->anyPolicyNodeAtBottom = state->newAnyPolicyNode; | |
2540 state->newAnyPolicyNode = NULL; | |
2541 | |
2542 /* Section 6.1.4(h) */ | |
2543 PKIX_CHECK(pkix_IsCertSelfIssued | |
2544 (cert, &isSelfIssued, plContext), | |
2545 PKIX_ISCERTSELFISSUEDFAILED); | |
2546 | |
2547 if (!isSelfIssued) { | |
2548 if (state->explicitPolicy > 0) { | |
2549 state->explicitPolicy--; | |
2550 } | |
2551 if (state->policyMapping > 0) { | |
2552 state->policyMapping--; | |
2553 } | |
2554 if (state->inhibitAnyPolicy > 0) { | |
2555 state->inhibitAnyPolicy--; | |
2556 } | |
2557 } | |
2558 | |
2559 /* Section 6.1.4(i) */ | |
2560 PKIX_CHECK(PKIX_PL_Cert_GetRequireExplicitPolicy | |
2561 (cert, &explicitPolicySkipCerts, plContext), | |
2562 PKIX_CERTGETREQUIREEXPLICITPOLICYFAILED); | |
2563 | |
2564 if (explicitPolicySkipCerts != -1) { | |
2565 if (((PKIX_UInt32)explicitPolicySkipCerts) < | |
2566 (state->explicitPolicy)) { | |
2567 state->explicitPolicy = | |
2568 ((PKIX_UInt32) explicitPolicySkipCerts); | |
2569 } | |
2570 } | |
2571 | |
2572 PKIX_CHECK(PKIX_PL_Cert_GetPolicyMappingInhibited | |
2573 (cert, &inhibitMappingSkipCerts, plContext), | |
2574 PKIX_CERTGETPOLICYMAPPINGINHIBITEDFAILED); | |
2575 | |
2576 if (inhibitMappingSkipCerts != -1) { | |
2577 if (((PKIX_UInt32)inhibitMappingSkipCerts) < | |
2578 (state->policyMapping)) { | |
2579 state->policyMapping = | |
2580 ((PKIX_UInt32)inhibitMappingSkipCerts); | |
2581 } | |
2582 } | |
2583 | |
2584 PKIX_CHECK(PKIX_PL_Cert_GetInhibitAnyPolicy | |
2585 (cert, &inhibitAnyPolicySkipCerts, plContext), | |
2586 PKIX_CERTGETINHIBITANYPOLICYFAILED); | |
2587 | |
2588 if (inhibitAnyPolicySkipCerts != -1) { | |
2589 if (((PKIX_UInt32)inhibitAnyPolicySkipCerts) < | |
2590 (state->inhibitAnyPolicy)) { | |
2591 state->inhibitAnyPolicy = | |
2592 ((PKIX_UInt32)inhibitAnyPolicySkipCerts); | |
2593 } | |
2594 } | |
2595 | |
2596 PKIX_CHECK(PKIX_PL_Object_InvalidateCache | |
2597 ((PKIX_PL_Object *)state, plContext), | |
2598 PKIX_OBJECTINVALIDATECACHEFAILED); | |
2599 | |
2600 } else { /* If this was the last certificate, do wrap-up processing */ | |
2601 | |
2602 /* Section 6.1.5 */ | |
2603 subroutineErr = pkix_PolicyChecker_WrapUpProcessing | |
2604 (cert, state, plContext); | |
2605 if (subroutineErr) { | |
2606 goto subrErrorCleanup; | |
2607 } | |
2608 | |
2609 if ((0 == state->explicitPolicy) && (!state->validPolicyTree)) { | |
2610 PKIX_ERROR(PKIX_CERTCHAINFAILSCERTIFICATEPOLICYVALIDATION); | |
2611 } | |
2612 | |
2613 PKIX_DECREF(state->anyPolicyNodeAtBottom); | |
2614 PKIX_DECREF(state->newAnyPolicyNode); | |
2615 } | |
2616 | |
2617 | |
2618 if (subroutineErr) { | |
2619 | |
2620 subrErrorCleanup: | |
2621 /* We had an error. Was it a fatal error? */ | |
2622 pkixErrorClass = subroutineErr->errClass; | |
2623 if (pkixErrorClass == PKIX_FATAL_ERROR) { | |
2624 pkixErrorResult = subroutineErr; | |
2625 subroutineErr = NULL; | |
2626 goto cleanup; | |
2627 } | |
2628 /* | |
2629 * Abort policy processing, and then determine whether | |
2630 * we can continue without policy processing. | |
2631 */ | |
2632 PKIX_DECREF(state->validPolicyTree); | |
2633 PKIX_DECREF(state->anyPolicyNodeAtBottom); | |
2634 PKIX_DECREF(state->newAnyPolicyNode); | |
2635 if (state->explicitPolicy == 0) { | |
2636 PKIX_ERROR | |
2637 (PKIX_CERTCHAINFAILSCERTIFICATEPOLICYVALIDATION); | |
2638 } | |
2639 } | |
2640 | |
2641 /* Checking is complete. Save state for the next certificate. */ | |
2642 PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState | |
2643 (checker, (PKIX_PL_Object *)state, plContext), | |
2644 PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED); | |
2645 | |
2646 cleanup: | |
2647 | |
2648 #if PKIX_CERTPOLICYCHECKERSTATEDEBUG | |
2649 if (cert) { | |
2650 PKIX_CHECK(PKIX_PL_Object_ToString | |
2651 ((PKIX_PL_Object*)cert, &certString, plContext), | |
2652 PKIX_OBJECTTOSTRINGFAILED); | |
2653 PKIX_CHECK(PKIX_PL_String_GetEncoded | |
2654 (certString, | |
2655 PKIX_ESCASCII, | |
2656 (void **)&certAscii, | |
2657 &length, | |
2658 plContext), | |
2659 PKIX_STRINGGETENCODEDFAILED); | |
2660 PKIX_DEBUG_ARG("Cert was %s\n", certAscii); | |
2661 PKIX_FREE(certAscii); | |
2662 PKIX_DECREF(certString); | |
2663 } | |
2664 if (state) { | |
2665 PKIX_CHECK(PKIX_PL_Object_ToString | |
2666 ((PKIX_PL_Object*)state, &stateString, plContext), | |
2667 PKIX_OBJECTTOSTRINGFAILED); | |
2668 PKIX_CHECK(PKIX_PL_String_GetEncoded | |
2669 (stateString, | |
2670 PKIX_ESCASCII, | |
2671 (void **)&stateAscii, | |
2672 &length, | |
2673 plContext), | |
2674 PKIX_STRINGGETENCODEDFAILED); | |
2675 PKIX_DEBUG_ARG("On exit %s\n", stateAscii); | |
2676 PKIX_FREE(stateAscii); | |
2677 PKIX_DECREF(stateString); | |
2678 } | |
2679 #endif | |
2680 | |
2681 PKIX_DECREF(state); | |
2682 PKIX_DECREF(certPolicyInfos); | |
2683 PKIX_DECREF(policy); | |
2684 PKIX_DECREF(qualsOfAny); | |
2685 PKIX_DECREF(policyQualifiers); | |
2686 PKIX_DECREF(policyOID); | |
2687 PKIX_DECREF(subroutineErr); | |
2688 PKIX_DECREF(policyMaps); | |
2689 PKIX_DECREF(mappedPolicies); | |
2690 | |
2691 PKIX_RETURN(CERTCHAINCHECKER); | |
2692 } | |
2693 | |
2694 /* | |
2695 * FUNCTION: pkix_PolicyChecker_Initialize | |
2696 * DESCRIPTION: | |
2697 * | |
2698 * Creates and initializes a PolicyChecker, using the List pointed to | |
2699 * by "initialPolicies" for the user-initial-policy-set, the Boolean value | |
2700 * of "policyQualifiersRejected" for the policyQualifiersRejected parameter, | |
2701 * the Boolean value of "initialPolicyMappingInhibit" for the | |
2702 * inhibitPolicyMappings parameter, the Boolean value of | |
2703 * "initialExplicitPolicy" for the initialExplicitPolicy parameter, the | |
2704 * Boolean value of "initialAnyPolicyInhibit" for the inhibitAnyPolicy | |
2705 * parameter, and the UInt32 value of "numCerts" as the number of | |
2706 * certificates in the chain; and stores the Checker at "pChecker". | |
2707 * | |
2708 * PARAMETERS: | |
2709 * "initialPolicies" | |
2710 * Address of List of OIDs comprising the user-initial-policy-set; the List | |
2711 * may be empty or NULL | |
2712 * "policyQualifiersRejected" | |
2713 * Boolean value of the policyQualifiersRejected parameter | |
2714 * "initialPolicyMappingInhibit" | |
2715 * Boolean value of the inhibitPolicyMappings parameter | |
2716 * "initialExplicitPolicy" | |
2717 * Boolean value of the initialExplicitPolicy parameter | |
2718 * "initialAnyPolicyInhibit" | |
2719 * Boolean value of the inhibitAnyPolicy parameter | |
2720 * "numCerts" | |
2721 * Number of certificates in the chain to be validated | |
2722 * "pChecker" | |
2723 * Address to store the created PolicyChecker. Must be non-NULL. | |
2724 * "plContext" | |
2725 * Platform-specific context pointer. | |
2726 * THREAD SAFETY: | |
2727 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
2728 * RETURNS: | |
2729 * Returns NULL if the function succeeds | |
2730 * Returns a CertChainChecker Error if the functions fails in a non-fatal way | |
2731 * Returns a Fatal Error if the function fails in an unrecoverable way | |
2732 */ | |
2733 PKIX_Error * | |
2734 pkix_PolicyChecker_Initialize( | |
2735 PKIX_List *initialPolicies, | |
2736 PKIX_Boolean policyQualifiersRejected, | |
2737 PKIX_Boolean initialPolicyMappingInhibit, | |
2738 PKIX_Boolean initialExplicitPolicy, | |
2739 PKIX_Boolean initialAnyPolicyInhibit, | |
2740 PKIX_UInt32 numCerts, | |
2741 PKIX_CertChainChecker **pChecker, | |
2742 void *plContext) | |
2743 { | |
2744 PKIX_PolicyCheckerState *polCheckerState = NULL; | |
2745 PKIX_List *policyExtensions = NULL; /* OIDs */ | |
2746 PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_Initialize"); | |
2747 PKIX_NULLCHECK_ONE(pChecker); | |
2748 | |
2749 PKIX_CHECK(pkix_PolicyCheckerState_Create | |
2750 (initialPolicies, | |
2751 policyQualifiersRejected, | |
2752 initialPolicyMappingInhibit, | |
2753 initialExplicitPolicy, | |
2754 initialAnyPolicyInhibit, | |
2755 numCerts, | |
2756 &polCheckerState, | |
2757 plContext), | |
2758 PKIX_POLICYCHECKERSTATECREATEFAILED); | |
2759 | |
2760 /* Create the list of extensions that we handle */ | |
2761 PKIX_CHECK(pkix_PolicyChecker_MakeSingleton | |
2762 ((PKIX_PL_Object *)(polCheckerState->certPoliciesExtension), | |
2763 PKIX_TRUE, | |
2764 &policyExtensions, | |
2765 plContext), | |
2766 PKIX_POLICYCHECKERMAKESINGLETONFAILED); | |
2767 | |
2768 PKIX_CHECK(PKIX_CertChainChecker_Create | |
2769 (pkix_PolicyChecker_Check, | |
2770 PKIX_FALSE, /* forwardCheckingSupported */ | |
2771 PKIX_FALSE, | |
2772 policyExtensions, | |
2773 (PKIX_PL_Object *)polCheckerState, | |
2774 pChecker, | |
2775 plContext), | |
2776 PKIX_CERTCHAINCHECKERCREATEFAILED); | |
2777 | |
2778 cleanup: | |
2779 PKIX_DECREF(polCheckerState); | |
2780 PKIX_DECREF(policyExtensions); | |
2781 PKIX_RETURN(CERTCHAINCHECKER); | |
2782 | |
2783 } |