security/nss/lib/libpkix/pkix/checker/pkix_policychecker.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rwxr-xr-x

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial