security/nss/lib/libpkix/pkix/certsel/pkix_certselector.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rwxr-xr-x

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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_certselector.c
michael@0 6 *
michael@0 7 * CertSelector Object Functions
michael@0 8 *
michael@0 9 */
michael@0 10
michael@0 11 #include "pkix_certselector.h"
michael@0 12
michael@0 13 /* --Private-Functions-------------------------------------------- */
michael@0 14
michael@0 15 /*
michael@0 16 * FUNCTION: pkix_CertSelector_Destroy
michael@0 17 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
michael@0 18 */
michael@0 19 static PKIX_Error *
michael@0 20 pkix_CertSelector_Destroy(
michael@0 21 PKIX_PL_Object *object,
michael@0 22 void *plContext)
michael@0 23 {
michael@0 24 PKIX_CertSelector *selector = NULL;
michael@0 25
michael@0 26 PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Destroy");
michael@0 27 PKIX_NULLCHECK_ONE(object);
michael@0 28
michael@0 29 /* Check that this object is a cert selector */
michael@0 30 PKIX_CHECK(pkix_CheckType(object, PKIX_CERTSELECTOR_TYPE, plContext),
michael@0 31 PKIX_OBJECTNOTCERTSELECTOR);
michael@0 32
michael@0 33 selector = (PKIX_CertSelector *)object;
michael@0 34 PKIX_DECREF(selector->params);
michael@0 35 PKIX_DECREF(selector->context);
michael@0 36
michael@0 37 cleanup:
michael@0 38
michael@0 39 PKIX_RETURN(CERTSELECTOR);
michael@0 40 }
michael@0 41
michael@0 42 /*
michael@0 43 * FUNCTION: pkix_CertSelector_Duplicate
michael@0 44 * (see comments for PKIX_PL_DuplicateCallback in pkix_pl_system.h)
michael@0 45 */
michael@0 46 static PKIX_Error *
michael@0 47 pkix_CertSelector_Duplicate(
michael@0 48 PKIX_PL_Object *object,
michael@0 49 PKIX_PL_Object **pNewObject,
michael@0 50 void *plContext)
michael@0 51 {
michael@0 52 PKIX_CertSelector *certSelector = NULL;
michael@0 53 PKIX_CertSelector *certSelectorDuplicate = NULL;
michael@0 54
michael@0 55 PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Duplicate");
michael@0 56 PKIX_NULLCHECK_TWO(object, pNewObject);
michael@0 57
michael@0 58 PKIX_CHECK(pkix_CheckType(object, PKIX_CERTSELECTOR_TYPE, plContext),
michael@0 59 PKIX_OBJECTNOTCERTSELECTOR);
michael@0 60
michael@0 61 certSelector = (PKIX_CertSelector *)object;
michael@0 62
michael@0 63 PKIX_CHECK(PKIX_CertSelector_Create
michael@0 64 (certSelector->matchCallback,
michael@0 65 certSelector->context,
michael@0 66 &certSelectorDuplicate,
michael@0 67 plContext),
michael@0 68 PKIX_CERTSELECTORCREATEFAILED);
michael@0 69
michael@0 70 PKIX_CHECK(PKIX_PL_Object_Duplicate
michael@0 71 ((PKIX_PL_Object *)certSelector->params,
michael@0 72 (PKIX_PL_Object **)&certSelectorDuplicate->params,
michael@0 73 plContext),
michael@0 74 PKIX_OBJECTDUPLICATEFAILED);
michael@0 75
michael@0 76 *pNewObject = (PKIX_PL_Object *)certSelectorDuplicate;
michael@0 77
michael@0 78 cleanup:
michael@0 79
michael@0 80 if (PKIX_ERROR_RECEIVED){
michael@0 81 PKIX_DECREF(certSelectorDuplicate);
michael@0 82 }
michael@0 83
michael@0 84 PKIX_RETURN(CERTSELECTOR);
michael@0 85 }
michael@0 86
michael@0 87 /*
michael@0 88 * FUNCTION: pkix_CertSelector_Match_BasicConstraint
michael@0 89 * DESCRIPTION:
michael@0 90 *
michael@0 91 * Determines whether the Cert pointed to by "cert" matches the basic
michael@0 92 * constraints criterion using the basic constraints field of the
michael@0 93 * ComCertSelParams pointed to by "params". If the basic constraints field is
michael@0 94 * -1, no basic constraints check is done and the Cert is considered to match
michael@0 95 * the basic constraints criterion. If the Cert does not match the basic
michael@0 96 * constraints criterion, an Error pointer is returned.
michael@0 97 *
michael@0 98 * In order to match against this criterion, there are several possibilities.
michael@0 99 *
michael@0 100 * 1) If the criterion's minimum path length is greater than or equal to zero,
michael@0 101 * a certificate must include a BasicConstraints extension with a pathLen of
michael@0 102 * at least this value.
michael@0 103 *
michael@0 104 * 2) If the criterion's minimum path length is -2, a certificate must be an
michael@0 105 * end-entity certificate.
michael@0 106 *
michael@0 107 * 3) If the criterion's minimum path length is -1, no basic constraints check
michael@0 108 * is done and all certificates are considered to match this criterion.
michael@0 109 *
michael@0 110 * PARAMETERS:
michael@0 111 * "params"
michael@0 112 * Address of ComCertSelParams whose basic constraints field is used.
michael@0 113 * Must be non-NULL.
michael@0 114 * "cert"
michael@0 115 * Address of Cert that is to be matched. Must be non-NULL.
michael@0 116 * "pResult"
michael@0 117 * Address of PKIX_Boolean that returns the match result.
michael@0 118 * "plContext"
michael@0 119 * Platform-specific context pointer.
michael@0 120 * OUTPUT PARAMETERS ON FAILURE:
michael@0 121 * If the function returns a failure,
michael@0 122 * the output parameters of this function are undefined.
michael@0 123 * THREAD SAFETY:
michael@0 124 * Conditionally Thread Safe
michael@0 125 * (see Thread Safety Definitions in Programmer's Guide)
michael@0 126 * RETURNS:
michael@0 127 * Returns NULL if the function succeeds.
michael@0 128 * Returns a CertSelector Error if the function fails in a non-fatal way.
michael@0 129 * Returns a Fatal Error if the function fails in an unrecoverable way.
michael@0 130 */
michael@0 131 static PKIX_Error *
michael@0 132 pkix_CertSelector_Match_BasicConstraint(
michael@0 133 PKIX_ComCertSelParams *params,
michael@0 134 PKIX_PL_Cert *cert,
michael@0 135 PKIX_Boolean *pResult,
michael@0 136 void *plContext)
michael@0 137 {
michael@0 138 PKIX_PL_CertBasicConstraints *basicConstraints = NULL;
michael@0 139 PKIX_Boolean caFlag = PKIX_FALSE; /* EE Cert by default */
michael@0 140 PKIX_Int32 pathLength = 0;
michael@0 141 PKIX_Int32 minPathLength = 0;
michael@0 142
michael@0 143 PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_BasicConstraint");
michael@0 144 PKIX_NULLCHECK_THREE(params, cert, pResult);
michael@0 145 *pResult = PKIX_TRUE;
michael@0 146
michael@0 147 PKIX_CHECK(PKIX_ComCertSelParams_GetBasicConstraints
michael@0 148 (params, &minPathLength, plContext),
michael@0 149 PKIX_COMCERTSELPARAMSGETBASICCONSTRAINTSFAILED);
michael@0 150
michael@0 151 /* If the minPathLength is unlimited (-1), no checking */
michael@0 152 if (minPathLength == PKIX_CERTSEL_ALL_MATCH_MIN_PATHLENGTH) {
michael@0 153 goto cleanup;
michael@0 154 }
michael@0 155
michael@0 156 PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints
michael@0 157 (cert, &basicConstraints, plContext),
michael@0 158 PKIX_CERTGETBASICCONSTRAINTSFAILED);
michael@0 159
michael@0 160 if (basicConstraints != NULL) {
michael@0 161 PKIX_CHECK(PKIX_PL_BasicConstraints_GetCAFlag
michael@0 162 (basicConstraints, &caFlag, plContext),
michael@0 163 PKIX_BASICCONSTRAINTSGETCAFLAGFAILED);
michael@0 164
michael@0 165 PKIX_CHECK(PKIX_PL_BasicConstraints_GetPathLenConstraint
michael@0 166 (basicConstraints, &pathLength, plContext),
michael@0 167 PKIX_BASICCONSTRAINTSGETPATHLENCONSTRAINTFAILED);
michael@0 168 }
michael@0 169
michael@0 170 /*
michael@0 171 * if minPathLength >= 0, the cert must have a BasicConstraints ext and
michael@0 172 * the pathLength in this cert
michael@0 173 * BasicConstraints needs to be >= minPathLength.
michael@0 174 */
michael@0 175 if (minPathLength >= 0){
michael@0 176 if ((!basicConstraints) || (caFlag == PKIX_FALSE)){
michael@0 177 PKIX_ERROR(PKIX_CERTNOTALLOWEDTOSIGNCERTIFICATES);
michael@0 178 } else if ((pathLength != PKIX_UNLIMITED_PATH_CONSTRAINT) &&
michael@0 179 (pathLength < minPathLength)){
michael@0 180 PKIX_CERTSELECTOR_DEBUG
michael@0 181 ("Basic Constraints path length match failed\n");
michael@0 182 *pResult = PKIX_FALSE;
michael@0 183 PKIX_ERROR(PKIX_PATHLENCONSTRAINTINVALID);
michael@0 184 }
michael@0 185 }
michael@0 186
michael@0 187 /* if the minPathLength is -2, this cert must be an end-entity cert. */
michael@0 188 if (minPathLength == PKIX_CERTSEL_ENDENTITY_MIN_PATHLENGTH) {
michael@0 189 if (caFlag == PKIX_TRUE) {
michael@0 190 PKIX_CERTSELECTOR_DEBUG
michael@0 191 ("Basic Constraints end-entity match failed\n");
michael@0 192 *pResult = PKIX_FALSE;
michael@0 193 PKIX_ERROR(PKIX_PATHLENCONSTRAINTINVALID);
michael@0 194 }
michael@0 195 }
michael@0 196
michael@0 197 cleanup:
michael@0 198
michael@0 199 PKIX_DECREF(basicConstraints);
michael@0 200 PKIX_RETURN(CERTSELECTOR);
michael@0 201 }
michael@0 202
michael@0 203 /*
michael@0 204 * FUNCTION: pkix_CertSelector_Match_Policies
michael@0 205 * DESCRIPTION:
michael@0 206 *
michael@0 207 * Determines whether the Cert pointed to by "cert" matches the policy
michael@0 208 * constraints specified in the ComCertsSelParams given by "params".
michael@0 209 * If "params" specifies a policy constraint of NULL, all certificates
michael@0 210 * match. If "params" specifies an empty list, "cert" must have at least
michael@0 211 * some policy. Otherwise "cert" must include at least one of the
michael@0 212 * policies in the list. See the description of PKIX_CertSelector in
michael@0 213 * pkix_certsel.h for more.
michael@0 214 *
michael@0 215 * PARAMETERS:
michael@0 216 * "params"
michael@0 217 * Address of ComCertSelParams whose policy criterion (if any) is used.
michael@0 218 * Must be non-NULL.
michael@0 219 * "cert"
michael@0 220 * Address of Cert that is to be matched. Must be non-NULL.
michael@0 221 * "pResult"
michael@0 222 * Address of PKIX_Boolean that returns the match result.
michael@0 223 * "plContext"
michael@0 224 * Platform-specific context pointer.
michael@0 225 * THREAD SAFETY:
michael@0 226 * Conditionally Thread Safe
michael@0 227 * (see Thread Safety Definitions in Programmer's Guide)
michael@0 228 * RETURNS:
michael@0 229 * Returns NULL if the function succeeds.
michael@0 230 * Returns a CertSelector Error if the function fails in a non-fatal way.
michael@0 231 * Returns a Fatal Error if the function fails in an unrecoverable way.
michael@0 232 */
michael@0 233 static PKIX_Error *
michael@0 234 pkix_CertSelector_Match_Policies(
michael@0 235 PKIX_ComCertSelParams *params,
michael@0 236 PKIX_PL_Cert *cert,
michael@0 237 PKIX_Boolean *pResult,
michael@0 238 void *plContext)
michael@0 239 {
michael@0 240 PKIX_UInt32 numConstraintPolicies = 0;
michael@0 241 PKIX_UInt32 numCertPolicies = 0;
michael@0 242 PKIX_UInt32 certPolicyIndex = 0;
michael@0 243 PKIX_Boolean result = PKIX_FALSE;
michael@0 244 PKIX_List *constraintPolicies = NULL; /* List of PKIX_PL_OID */
michael@0 245 PKIX_List *certPolicyInfos = NULL; /* List of PKIX_PL_CertPolicyInfo */
michael@0 246 PKIX_PL_CertPolicyInfo *policyInfo = NULL;
michael@0 247 PKIX_PL_OID *polOID = NULL;
michael@0 248
michael@0 249 PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_Policies");
michael@0 250 PKIX_NULLCHECK_THREE(params, cert, pResult);
michael@0 251
michael@0 252 PKIX_CHECK(PKIX_ComCertSelParams_GetPolicy
michael@0 253 (params, &constraintPolicies, plContext),
michael@0 254 PKIX_COMCERTSELPARAMSGETPOLICYFAILED);
michael@0 255
michael@0 256 /* If constraintPolicies is NULL, all certificates "match" */
michael@0 257 if (constraintPolicies) {
michael@0 258 PKIX_CHECK(PKIX_PL_Cert_GetPolicyInformation
michael@0 259 (cert, &certPolicyInfos, plContext),
michael@0 260 PKIX_CERTGETPOLICYINFORMATIONFAILED);
michael@0 261
michael@0 262 /* No hope of a match if cert has no policies */
michael@0 263 if (!certPolicyInfos) {
michael@0 264 PKIX_CERTSELECTOR_DEBUG("Certificate has no policies\n");
michael@0 265 *pResult = PKIX_FALSE;
michael@0 266 PKIX_ERROR(PKIX_CERTSELECTORMATCHPOLICIESFAILED);
michael@0 267 }
michael@0 268
michael@0 269 PKIX_CHECK(PKIX_List_GetLength
michael@0 270 (constraintPolicies, &numConstraintPolicies, plContext),
michael@0 271 PKIX_LISTGETLENGTHFAILED);
michael@0 272
michael@0 273 if (numConstraintPolicies > 0) {
michael@0 274
michael@0 275 PKIX_CHECK(PKIX_List_GetLength
michael@0 276 (certPolicyInfos, &numCertPolicies, plContext),
michael@0 277 PKIX_LISTGETLENGTHFAILED);
michael@0 278
michael@0 279 for (certPolicyIndex = 0;
michael@0 280 ((!result) && (certPolicyIndex < numCertPolicies));
michael@0 281 certPolicyIndex++) {
michael@0 282
michael@0 283 PKIX_CHECK(PKIX_List_GetItem
michael@0 284 (certPolicyInfos,
michael@0 285 certPolicyIndex,
michael@0 286 (PKIX_PL_Object **)&policyInfo,
michael@0 287 plContext),
michael@0 288 PKIX_LISTGETELEMENTFAILED);
michael@0 289 PKIX_CHECK(PKIX_PL_CertPolicyInfo_GetPolicyId
michael@0 290 (policyInfo, &polOID, plContext),
michael@0 291 PKIX_CERTPOLICYINFOGETPOLICYIDFAILED);
michael@0 292
michael@0 293 PKIX_CHECK(pkix_List_Contains
michael@0 294 (constraintPolicies,
michael@0 295 (PKIX_PL_Object *)polOID,
michael@0 296 &result,
michael@0 297 plContext),
michael@0 298 PKIX_LISTCONTAINSFAILED);
michael@0 299 PKIX_DECREF(policyInfo);
michael@0 300 PKIX_DECREF(polOID);
michael@0 301 }
michael@0 302 if (!result) {
michael@0 303 *pResult = PKIX_FALSE;
michael@0 304 PKIX_ERROR(PKIX_CERTSELECTORMATCHPOLICIESFAILED);
michael@0 305 }
michael@0 306 }
michael@0 307 }
michael@0 308
michael@0 309 cleanup:
michael@0 310
michael@0 311 PKIX_DECREF(constraintPolicies);
michael@0 312 PKIX_DECREF(certPolicyInfos);
michael@0 313 PKIX_DECREF(policyInfo);
michael@0 314 PKIX_DECREF(polOID);
michael@0 315
michael@0 316 PKIX_RETURN(CERTSELECTOR);
michael@0 317
michael@0 318 }
michael@0 319
michael@0 320 /*
michael@0 321 * FUNCTION: pkix_CertSelector_Match_CertificateValid
michael@0 322 * DESCRIPTION:
michael@0 323 *
michael@0 324 * Determines whether the Cert pointed to by "cert" matches the certificate
michael@0 325 * validity criterion using the CertificateValid field of the
michael@0 326 * ComCertSelParams pointed to by "params". If the CertificateValid field is
michael@0 327 * NULL, no validity check is done and the Cert is considered to match
michael@0 328 * the CertificateValid criterion. If the CertificateValid field specifies a
michael@0 329 * Date prior to the notBefore field in the Cert, or greater than the notAfter
michael@0 330 * field in the Cert, an Error is returned.
michael@0 331 *
michael@0 332 * PARAMETERS:
michael@0 333 * "params"
michael@0 334 * Address of ComCertSelParams whose certValid field is used.
michael@0 335 * Must be non-NULL.
michael@0 336 * "cert"
michael@0 337 * Address of Cert that is to be matched. Must be non-NULL.
michael@0 338 * "pResult"
michael@0 339 * Address of PKIX_Boolean that returns the match result.
michael@0 340 * "plContext"
michael@0 341 * Platform-specific context pointer.
michael@0 342 * THREAD SAFETY:
michael@0 343 * Conditionally Thread Safe
michael@0 344 * (see Thread Safety Definitions in Programmer's Guide)
michael@0 345 * RETURNS:
michael@0 346 * Returns NULL if the function succeeds.
michael@0 347 * Returns a CertSelector Error if the function fails in a non-fatal way.
michael@0 348 * Returns a Fatal Error if the function fails in an unrecoverable way.
michael@0 349 */
michael@0 350 static PKIX_Error *
michael@0 351 pkix_CertSelector_Match_CertificateValid(
michael@0 352 PKIX_ComCertSelParams *params,
michael@0 353 PKIX_PL_Cert *cert,
michael@0 354 PKIX_Boolean *pResult,
michael@0 355 void *plContext)
michael@0 356 {
michael@0 357 PKIX_PL_Date *validityTime = NULL;
michael@0 358
michael@0 359 PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_CertificateValid");
michael@0 360 PKIX_NULLCHECK_THREE(params, cert, pResult);
michael@0 361
michael@0 362 PKIX_CHECK(PKIX_ComCertSelParams_GetCertificateValid
michael@0 363 (params, &validityTime, plContext),
michael@0 364 PKIX_COMCERTSELPARAMSGETCERTIFICATEVALIDFAILED);
michael@0 365
michael@0 366 /* If the validityTime is not set, all certificates are acceptable */
michael@0 367 if (validityTime) {
michael@0 368 PKIX_CHECK(PKIX_PL_Cert_CheckValidity
michael@0 369 (cert, validityTime, plContext),
michael@0 370 PKIX_CERTCHECKVALIDITYFAILED);
michael@0 371 }
michael@0 372
michael@0 373 cleanup:
michael@0 374 if (PKIX_ERROR_RECEIVED) {
michael@0 375 *pResult = PKIX_FALSE;
michael@0 376 }
michael@0 377 PKIX_DECREF(validityTime);
michael@0 378
michael@0 379 PKIX_RETURN(CERTSELECTOR);
michael@0 380 }
michael@0 381
michael@0 382 /*
michael@0 383 * FUNCTION: pkix_CertSelector_Match_NameConstraints
michael@0 384 * DESCRIPTION:
michael@0 385 *
michael@0 386 * Determines whether the Cert pointed to by "cert" matches the name
michael@0 387 * constraints criterion specified in the ComCertSelParams pointed to by
michael@0 388 * "params". If the name constraints field is NULL, no name constraints check
michael@0 389 * is done and the Cert is considered to match the name constraints criterion.
michael@0 390 * If the Cert does not match the name constraints criterion, an Error pointer
michael@0 391 * is returned.
michael@0 392 *
michael@0 393 * PARAMETERS:
michael@0 394 * "params"
michael@0 395 * Address of ComCertSelParams whose name constraints field is used.
michael@0 396 * Must be non-NULL.
michael@0 397 * "cert"
michael@0 398 * Address of Cert that is to be matched. Must be non-NULL.
michael@0 399 * "pResult"
michael@0 400 * Address of PKIX_Boolean that returns the match result.
michael@0 401 * "plContext"
michael@0 402 * Platform-specific context pointer.
michael@0 403 * THREAD SAFETY:
michael@0 404 * Conditionally Thread Safe
michael@0 405 * (see Thread Safety Definitions in Programmer's Guide)
michael@0 406 * RETURNS:
michael@0 407 * Returns NULL if the function succeeds.
michael@0 408 * Returns a CertSelector Error if the function fails in a non-fatal way.
michael@0 409 * Returns a Fatal Error if the function fails in an unrecoverable way.
michael@0 410 */
michael@0 411 static PKIX_Error *
michael@0 412 pkix_CertSelector_Match_NameConstraints(
michael@0 413 PKIX_ComCertSelParams *params,
michael@0 414 PKIX_PL_Cert *cert,
michael@0 415 PKIX_Boolean *pResult,
michael@0 416 void *plContext)
michael@0 417 {
michael@0 418 PKIX_PL_CertNameConstraints *nameConstraints = NULL;
michael@0 419
michael@0 420 PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_NameConstraints");
michael@0 421 PKIX_NULLCHECK_THREE(params, cert, pResult);
michael@0 422
michael@0 423 PKIX_CHECK(PKIX_ComCertSelParams_GetNameConstraints
michael@0 424 (params, &nameConstraints, plContext),
michael@0 425 PKIX_COMCERTSELPARAMSGETNAMECONSTRAINTSFAILED);
michael@0 426
michael@0 427 if (nameConstraints != NULL) {
michael@0 428 /* As only the end-entity certificate should have
michael@0 429 * the common name constrained as if it was a dNSName,
michael@0 430 * do not constrain the common name when building a
michael@0 431 * forward path.
michael@0 432 */
michael@0 433 PKIX_CHECK(PKIX_PL_Cert_CheckNameConstraints
michael@0 434 (cert, nameConstraints, PKIX_FALSE, plContext),
michael@0 435 PKIX_CERTCHECKNAMECONSTRAINTSFAILED);
michael@0 436 }
michael@0 437
michael@0 438 cleanup:
michael@0 439 if (PKIX_ERROR_RECEIVED) {
michael@0 440 *pResult = PKIX_FALSE;
michael@0 441 }
michael@0 442
michael@0 443 PKIX_DECREF(nameConstraints);
michael@0 444 PKIX_RETURN(CERTSELECTOR);
michael@0 445 }
michael@0 446
michael@0 447 /*
michael@0 448 * FUNCTION: pkix_CertSelector_Match_PathToNames
michael@0 449 * DESCRIPTION:
michael@0 450 *
michael@0 451 * Determines whether the names at pathToNames in "params" complies with the
michael@0 452 * NameConstraints pointed to by "cert". If the pathToNames field is NULL
michael@0 453 * or there is no name constraints for this "cert", no checking is done
michael@0 454 * and the Cert is considered to match the name constraints criterion.
michael@0 455 * If the Cert does not match the name constraints criterion, an Error
michael@0 456 * pointer is returned.
michael@0 457 *
michael@0 458 * PARAMETERS:
michael@0 459 * "params"
michael@0 460 * Address of ComCertSelParams whose PathToNames field is used.
michael@0 461 * Must be non-NULL.
michael@0 462 * "cert"
michael@0 463 * Address of Cert that is to be matched. Must be non-NULL.
michael@0 464 * "pResult"
michael@0 465 * Address of PKIX_Boolean that returns the match result.
michael@0 466 * "plContext"
michael@0 467 * Platform-specific context pointer.
michael@0 468 * THREAD SAFETY:
michael@0 469 * Conditionally Thread Safe
michael@0 470 * (see Thread Safety Definitions in Programmer's Guide)
michael@0 471 * RETURNS:
michael@0 472 * Returns NULL if the function succeeds.
michael@0 473 * Returns a CertSelector Error if the function fails in a non-fatal way.
michael@0 474 * Returns a Fatal Error if the function fails in an unrecoverable way.
michael@0 475 */
michael@0 476 static PKIX_Error *
michael@0 477 pkix_CertSelector_Match_PathToNames(
michael@0 478 PKIX_ComCertSelParams *params,
michael@0 479 PKIX_PL_Cert *cert,
michael@0 480 PKIX_Boolean *pResult,
michael@0 481 void *plContext)
michael@0 482 {
michael@0 483 PKIX_List *pathToNamesList = NULL;
michael@0 484 PKIX_Boolean passed = PKIX_FALSE;
michael@0 485 PKIX_PL_CertNameConstraints *nameConstraints = NULL;
michael@0 486
michael@0 487 PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_PathToNames");
michael@0 488 PKIX_NULLCHECK_THREE(params, cert, pResult);
michael@0 489
michael@0 490 PKIX_CHECK(PKIX_ComCertSelParams_GetPathToNames
michael@0 491 (params, &pathToNamesList, plContext),
michael@0 492 PKIX_COMCERTSELPARAMSGETPATHTONAMESFAILED);
michael@0 493
michael@0 494 if (pathToNamesList != NULL) {
michael@0 495
michael@0 496 PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints
michael@0 497 (cert, &nameConstraints, plContext),
michael@0 498 PKIX_CERTGETNAMECONSTRAINTSFAILED);
michael@0 499
michael@0 500 if (nameConstraints != NULL) {
michael@0 501
michael@0 502 PKIX_CHECK(PKIX_PL_CertNameConstraints_CheckNamesInNameSpace
michael@0 503 (pathToNamesList, nameConstraints, &passed, plContext),
michael@0 504 PKIX_CERTNAMECONSTRAINTSCHECKNAMESINNAMESPACEFAILED);
michael@0 505
michael@0 506 if (passed != PKIX_TRUE) {
michael@0 507 *pResult = PKIX_FALSE;
michael@0 508 PKIX_ERROR(PKIX_CERTSELECTORMATCHPATHTONAMESFAILED);
michael@0 509 }
michael@0 510 }
michael@0 511
michael@0 512 }
michael@0 513
michael@0 514 cleanup:
michael@0 515
michael@0 516 PKIX_DECREF(nameConstraints);
michael@0 517 PKIX_DECREF(pathToNamesList);
michael@0 518
michael@0 519 PKIX_RETURN(CERTSELECTOR);
michael@0 520 }
michael@0 521
michael@0 522 /*
michael@0 523 * FUNCTION: pkix_CertSelector_Match_SubjAltNames
michael@0 524 * DESCRIPTION:
michael@0 525 *
michael@0 526 * Determines whether the names at subjAltNames in "params" match with the
michael@0 527 * SubjAltNames pointed to by "cert". If the subjAltNames field is NULL,
michael@0 528 * no name checking is done and the Cert is considered to match the
michael@0 529 * criterion. If the Cert does not match the criterion, an Error pointer
michael@0 530 * is returned.
michael@0 531 *
michael@0 532 * PARAMETERS:
michael@0 533 * "params"
michael@0 534 * Address of ComCertSelParams whose SubjAltNames field is used.
michael@0 535 * Must be non-NULL.
michael@0 536 * "cert"
michael@0 537 * Address of Cert that is to be matched. Must be non-NULL.
michael@0 538 * "pResult"
michael@0 539 * Address of PKIX_Boolean that returns the match result.
michael@0 540 * "plContext"
michael@0 541 * Platform-specific context pointer.
michael@0 542 * THREAD SAFETY:
michael@0 543 * Conditionally Thread Safe
michael@0 544 * (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 CertSelector 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 static PKIX_Error *
michael@0 551 pkix_CertSelector_Match_SubjAltNames(
michael@0 552 PKIX_ComCertSelParams *params,
michael@0 553 PKIX_PL_Cert *cert,
michael@0 554 PKIX_Boolean *pResult,
michael@0 555 void *plContext)
michael@0 556 {
michael@0 557 PKIX_List *subjAltNamesList = NULL;
michael@0 558 PKIX_List *certSubjAltNames = NULL;
michael@0 559 PKIX_PL_GeneralName *name = NULL;
michael@0 560 PKIX_Boolean checkPassed = PKIX_FALSE;
michael@0 561 PKIX_Boolean matchAll = PKIX_TRUE;
michael@0 562 PKIX_UInt32 i, numItems;
michael@0 563 PKIX_UInt32 matchCount = 0;
michael@0 564
michael@0 565 PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_SubjAltNames");
michael@0 566 PKIX_NULLCHECK_THREE(params, cert, pResult);
michael@0 567
michael@0 568 PKIX_CHECK(PKIX_ComCertSelParams_GetMatchAllSubjAltNames
michael@0 569 (params, &matchAll, plContext),
michael@0 570 PKIX_COMCERTSELPARAMSGETMATCHALLSUBJALTNAMESFAILED);
michael@0 571
michael@0 572 PKIX_CHECK(PKIX_ComCertSelParams_GetSubjAltNames
michael@0 573 (params, &subjAltNamesList, plContext),
michael@0 574 PKIX_COMCERTSELPARAMSGETSUBJALTNAMESFAILED);
michael@0 575
michael@0 576 if (subjAltNamesList != NULL) {
michael@0 577
michael@0 578 PKIX_CHECK(PKIX_PL_Cert_GetSubjectAltNames
michael@0 579 (cert, &certSubjAltNames, plContext),
michael@0 580 PKIX_CERTGETSUBJALTNAMESFAILED);
michael@0 581
michael@0 582 if (certSubjAltNames == NULL) {
michael@0 583 *pResult = PKIX_FALSE;
michael@0 584 PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJALTNAMESFAILED);
michael@0 585 }
michael@0 586
michael@0 587 PKIX_CHECK(PKIX_List_GetLength
michael@0 588 (subjAltNamesList, &numItems, plContext),
michael@0 589 PKIX_LISTGETLENGTHFAILED);
michael@0 590
michael@0 591 for (i = 0; i < numItems; i++) {
michael@0 592
michael@0 593 PKIX_CHECK(PKIX_List_GetItem
michael@0 594 (subjAltNamesList,
michael@0 595 i,
michael@0 596 (PKIX_PL_Object **) &name,
michael@0 597 plContext),
michael@0 598 PKIX_LISTGETITEMFAILED);
michael@0 599
michael@0 600 PKIX_CHECK(pkix_List_Contains
michael@0 601 (certSubjAltNames,
michael@0 602 (PKIX_PL_Object *) name,
michael@0 603 &checkPassed,
michael@0 604 plContext),
michael@0 605 PKIX_LISTCONTAINSFAILED);
michael@0 606
michael@0 607 PKIX_DECREF(name);
michael@0 608
michael@0 609 if (checkPassed == PKIX_TRUE) {
michael@0 610
michael@0 611 if (matchAll == PKIX_FALSE) {
michael@0 612 /* one match is good enough */
michael@0 613 matchCount = numItems;
michael@0 614 break;
michael@0 615 } else {
michael@0 616 /* else continue checking next */
michael@0 617 matchCount++;
michael@0 618 }
michael@0 619
michael@0 620 }
michael@0 621
michael@0 622 }
michael@0 623
michael@0 624 if (matchCount != numItems) {
michael@0 625 *pResult = PKIX_FALSE;
michael@0 626 PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJALTNAMESFAILED);
michael@0 627 }
michael@0 628 }
michael@0 629
michael@0 630 cleanup:
michael@0 631
michael@0 632 PKIX_DECREF(name);
michael@0 633 PKIX_DECREF(certSubjAltNames);
michael@0 634 PKIX_DECREF(subjAltNamesList);
michael@0 635
michael@0 636 PKIX_RETURN(CERTSELECTOR);
michael@0 637 }
michael@0 638
michael@0 639 /*
michael@0 640 * FUNCTION: pkix_CertSelector_Match_ExtendedKeyUsage
michael@0 641 * DESCRIPTION:
michael@0 642 *
michael@0 643 * Determines whether the names at ExtKeyUsage in "params" matches with the
michael@0 644 * ExtKeyUsage pointed to by "cert". If the ExtKeyUsage criterion or
michael@0 645 * ExtKeyUsage in "cert" is NULL, no checking is done and the Cert is
michael@0 646 * considered a match. If the Cert does not match, an Error pointer is
michael@0 647 * returned.
michael@0 648 *
michael@0 649 * PARAMETERS:
michael@0 650 * "params"
michael@0 651 * Address of ComCertSelParams whose ExtKeyUsage field is used.
michael@0 652 * Must be non-NULL.
michael@0 653 * "cert"
michael@0 654 * Address of Cert that is to be matched. Must be non-NULL.
michael@0 655 * "pResult"
michael@0 656 * Address of PKIX_Boolean that returns the match result.
michael@0 657 * "plContext"
michael@0 658 * Platform-specific context pointer.
michael@0 659 * THREAD SAFETY:
michael@0 660 * Conditionally Thread Safe
michael@0 661 * (see Thread Safety Definitions in Programmer's Guide)
michael@0 662 * RETURNS:
michael@0 663 * Returns NULL if the function succeeds.
michael@0 664 * Returns a CertSelector Error if the function fails in a non-fatal way.
michael@0 665 * Returns a Fatal Error if the function fails in an unrecoverable way.
michael@0 666 */
michael@0 667 static PKIX_Error *
michael@0 668 pkix_CertSelector_Match_ExtendedKeyUsage(
michael@0 669 PKIX_ComCertSelParams *params,
michael@0 670 PKIX_PL_Cert *cert,
michael@0 671 PKIX_Boolean *pResult,
michael@0 672 void *plContext)
michael@0 673 {
michael@0 674 PKIX_List *extKeyUsageList = NULL;
michael@0 675 PKIX_List *certExtKeyUsageList = NULL;
michael@0 676 PKIX_PL_OID *ekuOid = NULL;
michael@0 677 PKIX_Boolean isContained = PKIX_FALSE;
michael@0 678 PKIX_UInt32 numItems = 0;
michael@0 679 PKIX_UInt32 i;
michael@0 680
michael@0 681 PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_ExtendedKeyUsage");
michael@0 682 PKIX_NULLCHECK_THREE(params, cert, pResult);
michael@0 683
michael@0 684 PKIX_CHECK(PKIX_ComCertSelParams_GetExtendedKeyUsage
michael@0 685 (params, &extKeyUsageList, plContext),
michael@0 686 PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED);
michael@0 687
michael@0 688 if (extKeyUsageList == NULL) {
michael@0 689 goto cleanup;
michael@0 690 }
michael@0 691
michael@0 692 PKIX_CHECK(PKIX_PL_Cert_GetExtendedKeyUsage
michael@0 693 (cert, &certExtKeyUsageList, plContext),
michael@0 694 PKIX_CERTGETEXTENDEDKEYUSAGEFAILED);
michael@0 695
michael@0 696 if (certExtKeyUsageList != NULL) {
michael@0 697
michael@0 698 PKIX_CHECK(PKIX_List_GetLength
michael@0 699 (extKeyUsageList, &numItems, plContext),
michael@0 700 PKIX_LISTGETLENGTHFAILED);
michael@0 701
michael@0 702 for (i = 0; i < numItems; i++) {
michael@0 703
michael@0 704 PKIX_CHECK(PKIX_List_GetItem
michael@0 705 (extKeyUsageList, i, (PKIX_PL_Object **)&ekuOid, plContext),
michael@0 706 PKIX_LISTGETITEMFAILED);
michael@0 707
michael@0 708 PKIX_CHECK(pkix_List_Contains
michael@0 709 (certExtKeyUsageList,
michael@0 710 (PKIX_PL_Object *)ekuOid,
michael@0 711 &isContained,
michael@0 712 plContext),
michael@0 713 PKIX_LISTCONTAINSFAILED);
michael@0 714
michael@0 715 PKIX_DECREF(ekuOid);
michael@0 716
michael@0 717 if (isContained != PKIX_TRUE) {
michael@0 718 *pResult = PKIX_FALSE;
michael@0 719 PKIX_ERROR(PKIX_CERTSELECTORMATCHEXTENDEDKEYUSAGEFAILED);
michael@0 720 }
michael@0 721 }
michael@0 722 }
michael@0 723
michael@0 724 cleanup:
michael@0 725
michael@0 726 PKIX_DECREF(ekuOid);
michael@0 727 PKIX_DECREF(extKeyUsageList);
michael@0 728 PKIX_DECREF(certExtKeyUsageList);
michael@0 729
michael@0 730 PKIX_RETURN(CERTSELECTOR);
michael@0 731 }
michael@0 732
michael@0 733 /*
michael@0 734 * FUNCTION: pkix_CertSelector_Match_KeyUsage
michael@0 735 * DESCRIPTION:
michael@0 736 *
michael@0 737 * Determines whether the bits at KeyUsage in "params" matches with the
michael@0 738 * KeyUsage pointed to by "cert". If the KeyUsage in params is 0
michael@0 739 * no checking is done and the Cert is considered a match. If the Cert does
michael@0 740 * not match, an Error pointer is returned.
michael@0 741 *
michael@0 742 * PARAMETERS:
michael@0 743 * "params"
michael@0 744 * Address of ComCertSelParams whose ExtKeyUsage field is used.
michael@0 745 * Must be non-NULL.
michael@0 746 * "cert"
michael@0 747 * Address of Cert that is to be matched. Must be non-NULL.
michael@0 748 * "pResult"
michael@0 749 * Address of PKIX_Boolean that returns the match result.
michael@0 750 * "plContext"
michael@0 751 * Platform-specific context pointer.
michael@0 752 * THREAD SAFETY:
michael@0 753 * Conditionally Thread Safe
michael@0 754 * (see Thread Safety Definitions in Programmer's Guide)
michael@0 755 * RETURNS:
michael@0 756 * Returns NULL if the function succeeds.
michael@0 757 * Returns a CertSelector Error if the function fails in a non-fatal way.
michael@0 758 * Returns a Fatal Error if the function fails in an unrecoverable way.
michael@0 759 */
michael@0 760 static PKIX_Error *
michael@0 761 pkix_CertSelector_Match_KeyUsage(
michael@0 762 PKIX_ComCertSelParams *params,
michael@0 763 PKIX_PL_Cert *cert,
michael@0 764 PKIX_Boolean *pResult,
michael@0 765 void *plContext)
michael@0 766 {
michael@0 767 PKIX_UInt32 keyUsage = 0;
michael@0 768
michael@0 769 PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_KeyUsage");
michael@0 770 PKIX_NULLCHECK_THREE(params, cert, pResult);
michael@0 771
michael@0 772 PKIX_CHECK(PKIX_ComCertSelParams_GetKeyUsage
michael@0 773 (params, &keyUsage, plContext),
michael@0 774 PKIX_COMCERTSELPARAMSGETKEYUSAGEFAILED);
michael@0 775
michael@0 776 if (keyUsage != 0) {
michael@0 777
michael@0 778 PKIX_CHECK(PKIX_PL_Cert_VerifyKeyUsage
michael@0 779 (cert, keyUsage, plContext),
michael@0 780 PKIX_CERTVERIFYKEYUSAGEFAILED);
michael@0 781
michael@0 782 }
michael@0 783
michael@0 784 cleanup:
michael@0 785 if (PKIX_ERROR_RECEIVED) {
michael@0 786 *pResult = PKIX_FALSE;
michael@0 787 }
michael@0 788
michael@0 789 PKIX_RETURN(CERTSELECTOR);
michael@0 790 }
michael@0 791
michael@0 792 /*
michael@0 793 * FUNCTION: pkix_CertSelector_Match_SubjKeyId
michael@0 794 * DESCRIPTION:
michael@0 795 *
michael@0 796 * Determines whether the bytes at subjKeyId in "params" matches with the
michael@0 797 * Subject Key Identifier pointed to by "cert". If the subjKeyId in params is
michael@0 798 * set to NULL or the Cert doesn't have a Subject Key Identifier, no checking
michael@0 799 * is done and the Cert is considered a match. If the Cert does not match, an
michael@0 800 * Error pointer is returned.
michael@0 801 *
michael@0 802 * PARAMETERS:
michael@0 803 * "params"
michael@0 804 * Address of ComCertSelParams whose subjKeyId field is used.
michael@0 805 * Must be non-NULL.
michael@0 806 * "cert"
michael@0 807 * Address of Cert that is to be matched. Must be non-NULL.
michael@0 808 * "pResult"
michael@0 809 * Address of PKIX_Boolean that returns the match result.
michael@0 810 * "plContext"
michael@0 811 * Platform-specific context pointer.
michael@0 812 * THREAD SAFETY:
michael@0 813 * Conditionally Thread Safe
michael@0 814 * (see Thread Safety Definitions in Programmer's Guide)
michael@0 815 * RETURNS:
michael@0 816 * Returns NULL if the function succeeds.
michael@0 817 * Returns a CertSelector Error if the function fails in a non-fatal way.
michael@0 818 * Returns a Fatal Error if the function fails in an unrecoverable way.
michael@0 819 */
michael@0 820 static PKIX_Error *
michael@0 821 pkix_CertSelector_Match_SubjKeyId(
michael@0 822 PKIX_ComCertSelParams *params,
michael@0 823 PKIX_PL_Cert *cert,
michael@0 824 PKIX_Boolean *pResult,
michael@0 825 void *plContext)
michael@0 826 {
michael@0 827 PKIX_PL_ByteArray *selSubjKeyId = NULL;
michael@0 828 PKIX_PL_ByteArray *certSubjKeyId = NULL;
michael@0 829 PKIX_Boolean equals = PKIX_FALSE;
michael@0 830
michael@0 831 PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_SubjKeyId");
michael@0 832 PKIX_NULLCHECK_THREE(params, cert, pResult);
michael@0 833
michael@0 834 PKIX_CHECK(PKIX_ComCertSelParams_GetSubjKeyIdentifier
michael@0 835 (params, &selSubjKeyId, plContext),
michael@0 836 PKIX_COMCERTSELPARAMSGETSUBJKEYIDENTIFIERFAILED);
michael@0 837
michael@0 838 if (selSubjKeyId != NULL) {
michael@0 839
michael@0 840 PKIX_CHECK(PKIX_PL_Cert_GetSubjectKeyIdentifier
michael@0 841 (cert, &certSubjKeyId, plContext),
michael@0 842 PKIX_CERTGETSUBJECTKEYIDENTIFIERFAILED);
michael@0 843
michael@0 844 if (certSubjKeyId == NULL) {
michael@0 845 goto cleanup;
michael@0 846 }
michael@0 847
michael@0 848 PKIX_CHECK(PKIX_PL_Object_Equals
michael@0 849 ((PKIX_PL_Object *)selSubjKeyId,
michael@0 850 (PKIX_PL_Object *)certSubjKeyId,
michael@0 851 &equals,
michael@0 852 plContext),
michael@0 853 PKIX_OBJECTEQUALSFAILED);
michael@0 854
michael@0 855 if (equals == PKIX_FALSE) {
michael@0 856 *pResult = PKIX_FALSE;
michael@0 857 PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJKEYIDFAILED);
michael@0 858 }
michael@0 859 }
michael@0 860
michael@0 861 cleanup:
michael@0 862
michael@0 863 PKIX_DECREF(selSubjKeyId);
michael@0 864 PKIX_DECREF(certSubjKeyId);
michael@0 865
michael@0 866 PKIX_RETURN(CERTSELECTOR);
michael@0 867 }
michael@0 868
michael@0 869 /*
michael@0 870 * FUNCTION: pkix_CertSelector_Match_AuthKeyId
michael@0 871 * DESCRIPTION:
michael@0 872 *
michael@0 873 * Determines whether the bytes at authKeyId in "params" matches with the
michael@0 874 * Authority Key Identifier pointed to by "cert". If the authKeyId in params
michael@0 875 * is set to NULL, no checking is done and the Cert is considered a match. If
michael@0 876 * the Cert does not match, an Error pointer is returned.
michael@0 877 *
michael@0 878 * PARAMETERS:
michael@0 879 * "params"
michael@0 880 * Address of ComCertSelParams whose authKeyId field is used.
michael@0 881 * Must be non-NULL.
michael@0 882 * "cert"
michael@0 883 * Address of Cert that is to be matched. Must be non-NULL.
michael@0 884 * "pResult"
michael@0 885 * Address of PKIX_Boolean that returns the match result.
michael@0 886 * "plContext"
michael@0 887 * Platform-specific context pointer.
michael@0 888 * THREAD SAFETY:
michael@0 889 * Conditionally Thread Safe
michael@0 890 * (see Thread Safety Definitions in Programmer's Guide)
michael@0 891 * RETURNS:
michael@0 892 * Returns NULL if the function succeeds.
michael@0 893 * Returns a CertSelector Error if the function fails in a non-fatal way.
michael@0 894 * Returns a Fatal Error if the function fails in an unrecoverable way.
michael@0 895 */
michael@0 896 static PKIX_Error *
michael@0 897 pkix_CertSelector_Match_AuthKeyId(
michael@0 898 PKIX_ComCertSelParams *params,
michael@0 899 PKIX_PL_Cert *cert,
michael@0 900 PKIX_Boolean *pResult,
michael@0 901 void *plContext)
michael@0 902 {
michael@0 903 PKIX_PL_ByteArray *selAuthKeyId = NULL;
michael@0 904 PKIX_PL_ByteArray *certAuthKeyId = NULL;
michael@0 905 PKIX_Boolean equals = PKIX_FALSE;
michael@0 906
michael@0 907 PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_AuthKeyId");
michael@0 908 PKIX_NULLCHECK_THREE(params, cert, pResult);
michael@0 909
michael@0 910 PKIX_CHECK(PKIX_ComCertSelParams_GetAuthorityKeyIdentifier
michael@0 911 (params, &selAuthKeyId, plContext),
michael@0 912 PKIX_COMCERTSELPARAMSGETAUTHORITYKEYIDENTIFIERFAILED);
michael@0 913
michael@0 914 if (selAuthKeyId != NULL) {
michael@0 915
michael@0 916 PKIX_CHECK(PKIX_PL_Cert_GetAuthorityKeyIdentifier
michael@0 917 (cert, &certAuthKeyId, plContext),
michael@0 918 PKIX_CERTGETAUTHORITYKEYIDENTIFIERFAILED);
michael@0 919
michael@0 920 if (certAuthKeyId == NULL) {
michael@0 921 *pResult = PKIX_FALSE;
michael@0 922 PKIX_ERROR(PKIX_CERTSELECTORMATCHAUTHKEYIDFAILED);
michael@0 923 }
michael@0 924 PKIX_CHECK(PKIX_PL_Object_Equals
michael@0 925 ((PKIX_PL_Object *)selAuthKeyId,
michael@0 926 (PKIX_PL_Object *)certAuthKeyId,
michael@0 927 &equals,
michael@0 928 plContext),
michael@0 929 PKIX_OBJECTEQUALSFAILED);
michael@0 930
michael@0 931 if (equals != PKIX_TRUE) {
michael@0 932 *pResult = PKIX_FALSE;
michael@0 933 PKIX_ERROR(PKIX_CERTSELECTORMATCHAUTHKEYIDFAILED);
michael@0 934 }
michael@0 935 }
michael@0 936
michael@0 937 cleanup:
michael@0 938
michael@0 939 PKIX_DECREF(selAuthKeyId);
michael@0 940 PKIX_DECREF(certAuthKeyId);
michael@0 941
michael@0 942 PKIX_RETURN(CERTSELECTOR);
michael@0 943 }
michael@0 944
michael@0 945 /*
michael@0 946 * FUNCTION: pkix_CertSelector_Match_SubjPKAlgId
michael@0 947 * DESCRIPTION:
michael@0 948 *
michael@0 949 * Determines whether the OID at subjPKAlgId in "params" matches with the
michael@0 950 * Subject Public Key Alg Id pointed to by "cert". If the subjPKAlgId in params
michael@0 951 * is set to NULL, no checking is done and the Cert is considered a match. If
michael@0 952 * the Cert does not match, an Error pointer is returned.
michael@0 953 *
michael@0 954 * PARAMETERS:
michael@0 955 * "params"
michael@0 956 * Address of ComCertSelParams whose subjPKAlgId field is used.
michael@0 957 * Must be non-NULL.
michael@0 958 * "cert"
michael@0 959 * Address of Cert that is to be matched. Must be non-NULL.
michael@0 960 * "pResult"
michael@0 961 * Address of PKIX_Boolean that returns the match result.
michael@0 962 * "plContext"
michael@0 963 * Platform-specific context pointer.
michael@0 964 * THREAD SAFETY:
michael@0 965 * Conditionally Thread Safe
michael@0 966 * (see Thread Safety Definitions in Programmer's Guide)
michael@0 967 * RETURNS:
michael@0 968 * Returns NULL if the function succeeds.
michael@0 969 * Returns a CertSelector Error if the function fails in a non-fatal way.
michael@0 970 * Returns a Fatal Error if the function fails in an unrecoverable way.
michael@0 971 */
michael@0 972 static PKIX_Error *
michael@0 973 pkix_CertSelector_Match_SubjPKAlgId(
michael@0 974 PKIX_ComCertSelParams *params,
michael@0 975 PKIX_PL_Cert *cert,
michael@0 976 PKIX_Boolean *pResult,
michael@0 977 void *plContext)
michael@0 978 {
michael@0 979 PKIX_PL_OID *selPKAlgId = NULL;
michael@0 980 PKIX_PL_OID *certPKAlgId = NULL;
michael@0 981 PKIX_Boolean equals = PKIX_FALSE;
michael@0 982
michael@0 983 PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_SubjPKAlgId");
michael@0 984 PKIX_NULLCHECK_THREE(params, cert, pResult);
michael@0 985
michael@0 986 PKIX_CHECK(PKIX_ComCertSelParams_GetSubjPKAlgId
michael@0 987 (params, &selPKAlgId, plContext),
michael@0 988 PKIX_COMCERTSELPARAMSGETSUBJPKALGIDFAILED);
michael@0 989
michael@0 990 if (selPKAlgId != NULL) {
michael@0 991
michael@0 992 PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKeyAlgId
michael@0 993 (cert, &certPKAlgId, plContext),
michael@0 994 PKIX_CERTGETSUBJECTPUBLICKEYALGIDFAILED);
michael@0 995
michael@0 996 if (certPKAlgId != NULL) {
michael@0 997 *pResult = PKIX_FALSE;
michael@0 998 PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJPKALGIDFAILED);
michael@0 999 }
michael@0 1000 PKIX_CHECK(PKIX_PL_Object_Equals
michael@0 1001 ((PKIX_PL_Object *)selPKAlgId,
michael@0 1002 (PKIX_PL_Object *)certPKAlgId,
michael@0 1003 &equals,
michael@0 1004 plContext),
michael@0 1005 PKIX_OBJECTEQUALSFAILED);
michael@0 1006
michael@0 1007 if (equals != PKIX_TRUE) {
michael@0 1008 *pResult = PKIX_FALSE;
michael@0 1009 PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJPKALGIDFAILED);
michael@0 1010 }
michael@0 1011 }
michael@0 1012
michael@0 1013 cleanup:
michael@0 1014
michael@0 1015 PKIX_DECREF(selPKAlgId);
michael@0 1016 PKIX_DECREF(certPKAlgId);
michael@0 1017
michael@0 1018 PKIX_RETURN(CERTSELECTOR);
michael@0 1019 }
michael@0 1020
michael@0 1021 /*
michael@0 1022 * FUNCTION: pkix_CertSelector_Match_SubjPubKey
michael@0 1023 * DESCRIPTION:
michael@0 1024 *
michael@0 1025 * Determines whether the key at subjPubKey in "params" matches with the
michael@0 1026 * Subject Public Key pointed to by "cert". If the subjPubKey in params
michael@0 1027 * is set to NULL, no checking is done and the Cert is considered a match. If
michael@0 1028 * the Cert does not match, an Error pointer is returned.
michael@0 1029 *
michael@0 1030 * PARAMETERS:
michael@0 1031 * "params"
michael@0 1032 * Address of ComCertSelParams whose subPubKey field is used.
michael@0 1033 * Must be non-NULL.
michael@0 1034 * "cert"
michael@0 1035 * Address of Cert that is to be matched. Must be non-NULL.
michael@0 1036 * "pResult"
michael@0 1037 * Address of PKIX_Boolean that returns the match result.
michael@0 1038 * "plContext"
michael@0 1039 * Platform-specific context pointer.
michael@0 1040 * THREAD SAFETY:
michael@0 1041 * Conditionally Thread Safe
michael@0 1042 * (see Thread Safety Definitions in Programmer's Guide)
michael@0 1043 * RETURNS:
michael@0 1044 * Returns NULL if the function succeeds.
michael@0 1045 * Returns a CertSelector Error if the function fails in a non-fatal way.
michael@0 1046 * Returns a Fatal Error if the function fails in an unrecoverable way.
michael@0 1047 */
michael@0 1048 static PKIX_Error *
michael@0 1049 pkix_CertSelector_Match_SubjPubKey(
michael@0 1050 PKIX_ComCertSelParams *params,
michael@0 1051 PKIX_PL_Cert *cert,
michael@0 1052 PKIX_Boolean *pResult,
michael@0 1053 void *plContext)
michael@0 1054 {
michael@0 1055 PKIX_PL_PublicKey *selPK = NULL;
michael@0 1056 PKIX_PL_PublicKey *certPK = NULL;
michael@0 1057 PKIX_Boolean equals = PKIX_FALSE;
michael@0 1058
michael@0 1059 PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_SubjPubKey");
michael@0 1060 PKIX_NULLCHECK_THREE(params, cert, pResult);
michael@0 1061
michael@0 1062 PKIX_CHECK(PKIX_ComCertSelParams_GetSubjPubKey
michael@0 1063 (params, &selPK, plContext),
michael@0 1064 PKIX_COMCERTSELPARAMSGETSUBJPUBKEYFAILED);
michael@0 1065
michael@0 1066 if (selPK != NULL) {
michael@0 1067
michael@0 1068 PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
michael@0 1069 (cert, &certPK, plContext),
michael@0 1070 PKIX_CERTGETSUBJECTPUBLICKEYFAILED);
michael@0 1071
michael@0 1072 if (certPK == NULL) {
michael@0 1073 *pResult = PKIX_FALSE;
michael@0 1074 PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJPUBKEYFAILED);
michael@0 1075 }
michael@0 1076 PKIX_CHECK(PKIX_PL_Object_Equals
michael@0 1077 ((PKIX_PL_Object *)selPK,
michael@0 1078 (PKIX_PL_Object *)certPK,
michael@0 1079 &equals,
michael@0 1080 plContext),
michael@0 1081 PKIX_OBJECTEQUALSFAILED);
michael@0 1082
michael@0 1083 if (equals != PKIX_TRUE) {
michael@0 1084 *pResult = PKIX_FALSE;
michael@0 1085 PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJPUBKEYFAILED);
michael@0 1086 }
michael@0 1087 }
michael@0 1088
michael@0 1089 cleanup:
michael@0 1090
michael@0 1091 PKIX_DECREF(selPK);
michael@0 1092 PKIX_DECREF(certPK);
michael@0 1093
michael@0 1094 PKIX_RETURN(CERTSELECTOR);
michael@0 1095 }
michael@0 1096
michael@0 1097 /*
michael@0 1098 * FUNCTION: pkix_CertSelector_DefaultMatch
michael@0 1099 * DESCRIPTION:
michael@0 1100 *
michael@0 1101 * This default match function determines whether the specified Cert pointed
michael@0 1102 * to by "cert" matches the criteria of the CertSelector pointed to by
michael@0 1103 * "selector". If the Cert does not match the CertSelector's
michael@0 1104 * criteria, an error will be thrown.
michael@0 1105 *
michael@0 1106 * This default match function understands how to process the most common
michael@0 1107 * parameters. Any common parameter that is not set is assumed to be disabled,
michael@0 1108 * which means this function will select all certificates without regard to
michael@0 1109 * that particular disabled parameter. For example, if the SerialNumber
michael@0 1110 * parameter is not set, this function will not filter out any certificate
michael@0 1111 * based on its serial number. As such, if no parameters are set, all are
michael@0 1112 * disabled and any certificate will match. If a parameter is disabled, its
michael@0 1113 * associated PKIX_ComCertSelParams_Get* function returns a default value.
michael@0 1114 * That value is -1 for PKIX_ComCertSelParams_GetBasicConstraints and
michael@0 1115 * PKIX_ComCertSelParams_GetVersion, 0 for PKIX_ComCertSelParams_GetKeyUsage,
michael@0 1116 * and NULL for all other Get functions.
michael@0 1117 *
michael@0 1118 * PARAMETERS:
michael@0 1119 * "selector"
michael@0 1120 * Address of CertSelector whose MatchCallback logic and parameters are
michael@0 1121 * to be used. Must be non-NULL.
michael@0 1122 * "cert"
michael@0 1123 * Address of Cert that is to be matched using "selector".
michael@0 1124 * Must be non-NULL.
michael@0 1125 * "plContext"
michael@0 1126 * Platform-specific context pointer.
michael@0 1127 * THREAD SAFETY:
michael@0 1128 * Conditionally Thread Safe
michael@0 1129 * (see Thread Safety Definitions in Programmer's Guide)
michael@0 1130 * RETURNS:
michael@0 1131 * Returns NULL if the function succeeds.
michael@0 1132 * Returns a CertSelector Error if the function fails in a non-fatal way.
michael@0 1133 * Returns a Fatal Error if the function fails in an unrecoverable way.
michael@0 1134 */
michael@0 1135 static PKIX_Error *
michael@0 1136 pkix_CertSelector_DefaultMatch(
michael@0 1137 PKIX_CertSelector *selector,
michael@0 1138 PKIX_PL_Cert *cert,
michael@0 1139 void *plContext)
michael@0 1140 {
michael@0 1141 PKIX_ComCertSelParams *params = NULL;
michael@0 1142 PKIX_PL_X500Name *certSubject = NULL;
michael@0 1143 PKIX_PL_X500Name *selSubject = NULL;
michael@0 1144 PKIX_PL_X500Name *certIssuer = NULL;
michael@0 1145 PKIX_PL_X500Name *selIssuer = NULL;
michael@0 1146 PKIX_PL_BigInt *certSerialNumber = NULL;
michael@0 1147 PKIX_PL_BigInt *selSerialNumber = NULL;
michael@0 1148 PKIX_PL_Cert *selCert = NULL;
michael@0 1149 PKIX_PL_Date *selDate = NULL;
michael@0 1150 PKIX_UInt32 selVersion = 0xFFFFFFFF;
michael@0 1151 PKIX_UInt32 certVersion = 0;
michael@0 1152 PKIX_Boolean result = PKIX_TRUE;
michael@0 1153 PKIX_Boolean isLeafCert = PKIX_TRUE;
michael@0 1154
michael@0 1155 #ifdef PKIX_BUILDDEBUG
michael@0 1156 PKIX_PL_String *certString = NULL;
michael@0 1157 void *certAscii = NULL;
michael@0 1158 PKIX_UInt32 certAsciiLen;
michael@0 1159 #endif
michael@0 1160
michael@0 1161 PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_DefaultMatch");
michael@0 1162 PKIX_NULLCHECK_TWO(selector, cert);
michael@0 1163
michael@0 1164 PKIX_INCREF(selector->params);
michael@0 1165 params = selector->params;
michael@0 1166
michael@0 1167 /* Are we looking for CAs? */
michael@0 1168 PKIX_CHECK(PKIX_ComCertSelParams_GetLeafCertFlag
michael@0 1169 (params, &isLeafCert, plContext),
michael@0 1170 PKIX_COMCERTSELPARAMSGETLEAFCERTFLAGFAILED);
michael@0 1171
michael@0 1172 if (params == NULL){
michael@0 1173 goto cleanup;
michael@0 1174 }
michael@0 1175
michael@0 1176 PKIX_CHECK(PKIX_ComCertSelParams_GetVersion
michael@0 1177 (params, &selVersion, plContext),
michael@0 1178 PKIX_COMCERTSELPARAMSGETVERSIONFAILED);
michael@0 1179
michael@0 1180 if (selVersion != 0xFFFFFFFF){
michael@0 1181 PKIX_CHECK(PKIX_PL_Cert_GetVersion
michael@0 1182 (cert, &certVersion, plContext),
michael@0 1183 PKIX_CERTGETVERSIONFAILED);
michael@0 1184
michael@0 1185 if (selVersion != certVersion) {
michael@0 1186 PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTVERSIONFAILED);
michael@0 1187 }
michael@0 1188 }
michael@0 1189
michael@0 1190 PKIX_CHECK(PKIX_ComCertSelParams_GetSubject
michael@0 1191 (params, &selSubject, plContext),
michael@0 1192 PKIX_COMCERTSELPARAMSGETSUBJECTFAILED);
michael@0 1193
michael@0 1194 if (selSubject){
michael@0 1195 PKIX_CHECK(PKIX_PL_Cert_GetSubject
michael@0 1196 (cert, &certSubject, plContext),
michael@0 1197 PKIX_CERTGETSUBJECTFAILED);
michael@0 1198
michael@0 1199 if (certSubject){
michael@0 1200 PKIX_CHECK(PKIX_PL_X500Name_Match
michael@0 1201 (selSubject, certSubject, &result, plContext),
michael@0 1202 PKIX_X500NAMEMATCHFAILED);
michael@0 1203
michael@0 1204 if (result == PKIX_FALSE){
michael@0 1205 PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTSUBJECTFAILED);
michael@0 1206 }
michael@0 1207 } else { /* cert has no subject */
michael@0 1208 PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTSUBJECTFAILED);
michael@0 1209 }
michael@0 1210 }
michael@0 1211
michael@0 1212 PKIX_CHECK(PKIX_ComCertSelParams_GetIssuer
michael@0 1213 (params, &selIssuer, plContext),
michael@0 1214 PKIX_COMCERTSELPARAMSGETISSUERFAILED);
michael@0 1215
michael@0 1216 if (selIssuer){
michael@0 1217 PKIX_CHECK(PKIX_PL_Cert_GetIssuer
michael@0 1218 (cert, &certIssuer, plContext),
michael@0 1219 PKIX_CERTGETISSUERFAILED);
michael@0 1220
michael@0 1221 PKIX_CHECK(PKIX_PL_X500Name_Match
michael@0 1222 (selIssuer, certIssuer, &result, plContext),
michael@0 1223 PKIX_X500NAMEMATCHFAILED);
michael@0 1224
michael@0 1225 if (result == PKIX_FALSE){
michael@0 1226 PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTISSUERFAILED);
michael@0 1227 }
michael@0 1228 }
michael@0 1229
michael@0 1230 PKIX_CHECK(PKIX_ComCertSelParams_GetSerialNumber
michael@0 1231 (params, &selSerialNumber, plContext),
michael@0 1232 PKIX_COMCERTSELPARAMSGETSERIALNUMBERFAILED);
michael@0 1233
michael@0 1234 if (selSerialNumber){
michael@0 1235 PKIX_CHECK(PKIX_PL_Cert_GetSerialNumber
michael@0 1236 (cert, &certSerialNumber, plContext),
michael@0 1237 PKIX_CERTGETSERIALNUMBERFAILED);
michael@0 1238
michael@0 1239 PKIX_CHECK(PKIX_PL_Object_Equals
michael@0 1240 ((PKIX_PL_Object *)selSerialNumber,
michael@0 1241 (PKIX_PL_Object *)certSerialNumber,
michael@0 1242 &result,
michael@0 1243 plContext),
michael@0 1244 PKIX_OBJECTEQUALSFAILED);
michael@0 1245
michael@0 1246 if (result == PKIX_FALSE){
michael@0 1247 PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTSERIALNUMFAILED);
michael@0 1248 }
michael@0 1249 }
michael@0 1250
michael@0 1251 PKIX_CHECK(PKIX_ComCertSelParams_GetCertificate
michael@0 1252 (params, &selCert, plContext),
michael@0 1253 PKIX_COMCERTSELPARAMSGETCERTIFICATEFAILED);
michael@0 1254
michael@0 1255 if (selCert){
michael@0 1256 PKIX_CHECK(PKIX_PL_Object_Equals
michael@0 1257 ((PKIX_PL_Object *) selCert,
michael@0 1258 (PKIX_PL_Object *) cert,
michael@0 1259 &result,
michael@0 1260 plContext),
michael@0 1261 PKIX_OBJECTEQUALSFAILED);
michael@0 1262
michael@0 1263 if (result == PKIX_FALSE){
michael@0 1264 PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTOBJECTFAILED);
michael@0 1265 }
michael@0 1266 }
michael@0 1267
michael@0 1268 PKIX_CHECK(PKIX_ComCertSelParams_GetCertificateValid
michael@0 1269 (params, &selDate, plContext),
michael@0 1270 PKIX_COMCERTSELPARAMSGETCERTIFICATEVALIDFAILED);
michael@0 1271
michael@0 1272 if (selDate){
michael@0 1273 PKIX_CHECK(PKIX_PL_Cert_CheckValidity
michael@0 1274 (cert, selDate, plContext),
michael@0 1275 PKIX_CERTCHECKVALIDITYFAILED);
michael@0 1276 }
michael@0 1277
michael@0 1278 PKIX_CHECK(pkix_CertSelector_Match_BasicConstraint
michael@0 1279 (params, cert, &result, plContext),
michael@0 1280 PKIX_CERTSELECTORMATCHBASICCONSTRAINTFAILED);
michael@0 1281
michael@0 1282 PKIX_CHECK(pkix_CertSelector_Match_Policies
michael@0 1283 (params, cert, &result, plContext),
michael@0 1284 PKIX_CERTSELECTORMATCHPOLICIESFAILED);
michael@0 1285
michael@0 1286 PKIX_CHECK(pkix_CertSelector_Match_CertificateValid
michael@0 1287 (params, cert, &result, plContext),
michael@0 1288 PKIX_CERTSELECTORMATCHCERTIFICATEVALIDFAILED);
michael@0 1289
michael@0 1290 PKIX_CHECK(pkix_CertSelector_Match_NameConstraints
michael@0 1291 (params, cert, &result, plContext),
michael@0 1292 PKIX_CERTSELECTORMATCHNAMECONSTRAINTSFAILED);
michael@0 1293
michael@0 1294 PKIX_CHECK(pkix_CertSelector_Match_PathToNames
michael@0 1295 (params, cert, &result, plContext),
michael@0 1296 PKIX_CERTSELECTORMATCHPATHTONAMESFAILED);
michael@0 1297
michael@0 1298 PKIX_CHECK(pkix_CertSelector_Match_SubjAltNames
michael@0 1299 (params, cert, &result, plContext),
michael@0 1300 PKIX_CERTSELECTORMATCHSUBJALTNAMESFAILED);
michael@0 1301
michael@0 1302 /* Check key usage and cert type based on certificate usage. */
michael@0 1303 PKIX_CHECK(PKIX_PL_Cert_VerifyCertAndKeyType(cert, !isLeafCert,
michael@0 1304 plContext),
michael@0 1305 PKIX_CERTVERIFYCERTTYPEFAILED);
michael@0 1306
michael@0 1307 /* Next two check are for user supplied additional KU and EKU. */
michael@0 1308 PKIX_CHECK(pkix_CertSelector_Match_ExtendedKeyUsage
michael@0 1309 (params, cert, &result, plContext),
michael@0 1310 PKIX_CERTSELECTORMATCHEXTENDEDKEYUSAGEFAILED);
michael@0 1311
michael@0 1312 PKIX_CHECK(pkix_CertSelector_Match_KeyUsage
michael@0 1313 (params, cert, &result, plContext),
michael@0 1314 PKIX_CERTSELECTORMATCHKEYUSAGEFAILED);
michael@0 1315
michael@0 1316 PKIX_CHECK(pkix_CertSelector_Match_SubjKeyId
michael@0 1317 (params, cert, &result, plContext),
michael@0 1318 PKIX_CERTSELECTORMATCHSUBJKEYIDFAILED);
michael@0 1319
michael@0 1320 PKIX_CHECK(pkix_CertSelector_Match_AuthKeyId
michael@0 1321 (params, cert, &result, plContext),
michael@0 1322 PKIX_CERTSELECTORMATCHAUTHKEYIDFAILED);
michael@0 1323
michael@0 1324 PKIX_CHECK(pkix_CertSelector_Match_SubjPKAlgId
michael@0 1325 (params, cert, &result, plContext),
michael@0 1326 PKIX_CERTSELECTORMATCHSUBJPKALGIDFAILED);
michael@0 1327
michael@0 1328 PKIX_CHECK(pkix_CertSelector_Match_SubjPubKey
michael@0 1329 (params, cert, &result, plContext),
michael@0 1330 PKIX_CERTSELECTORMATCHSUBJPUBKEYFAILED);
michael@0 1331
michael@0 1332 /* if we reach here, the cert has successfully matched criteria */
michael@0 1333
michael@0 1334
michael@0 1335 #ifdef PKIX_BUILDDEBUG
michael@0 1336
michael@0 1337 PKIX_CHECK(pkix_pl_Cert_ToString_Helper
michael@0 1338 (cert, PKIX_TRUE, &certString, plContext),
michael@0 1339 PKIX_CERTTOSTRINGHELPERFAILED);
michael@0 1340
michael@0 1341 PKIX_CHECK(PKIX_PL_String_GetEncoded
michael@0 1342 (certString,
michael@0 1343 PKIX_ESCASCII,
michael@0 1344 &certAscii,
michael@0 1345 &certAsciiLen,
michael@0 1346 plContext),
michael@0 1347 PKIX_STRINGGETENCODEDFAILED);
michael@0 1348
michael@0 1349 PKIX_CERTSELECTOR_DEBUG_ARG("Cert Selected:\n%s\n", certAscii);
michael@0 1350
michael@0 1351 #endif
michael@0 1352
michael@0 1353 cleanup:
michael@0 1354
michael@0 1355 #ifdef PKIX_BUILDDEBUG
michael@0 1356 PKIX_DECREF(certString);
michael@0 1357 PKIX_FREE(certAscii);
michael@0 1358 #endif
michael@0 1359
michael@0 1360 PKIX_DECREF(certSubject);
michael@0 1361 PKIX_DECREF(selSubject);
michael@0 1362 PKIX_DECREF(certIssuer);
michael@0 1363 PKIX_DECREF(selIssuer);
michael@0 1364 PKIX_DECREF(certSerialNumber);
michael@0 1365 PKIX_DECREF(selSerialNumber);
michael@0 1366 PKIX_DECREF(selCert);
michael@0 1367 PKIX_DECREF(selDate);
michael@0 1368 PKIX_DECREF(params);
michael@0 1369 PKIX_RETURN(CERTSELECTOR);
michael@0 1370 }
michael@0 1371
michael@0 1372 /*
michael@0 1373 * FUNCTION: pkix_CertSelector_RegisterSelf
michael@0 1374 * DESCRIPTION:
michael@0 1375 * Registers PKIX_CERTSELECTOR_TYPE and its related functions with
michael@0 1376 * systemClasses[]
michael@0 1377 * THREAD SAFETY:
michael@0 1378 * Not Thread Safe - for performance and complexity reasons
michael@0 1379 *
michael@0 1380 * Since this function is only called by PKIX_PL_Initialize, which should
michael@0 1381 * only be called once, it is acceptable that this function is not
michael@0 1382 * thread-safe.
michael@0 1383 */
michael@0 1384 PKIX_Error *
michael@0 1385 pkix_CertSelector_RegisterSelf(void *plContext)
michael@0 1386 {
michael@0 1387 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
michael@0 1388 pkix_ClassTable_Entry entry;
michael@0 1389
michael@0 1390 PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_RegisterSelf");
michael@0 1391
michael@0 1392 entry.description = "CertSelector";
michael@0 1393 entry.objCounter = 0;
michael@0 1394 entry.typeObjectSize = sizeof(PKIX_CertSelector);
michael@0 1395 entry.destructor = pkix_CertSelector_Destroy;
michael@0 1396 entry.equalsFunction = NULL;
michael@0 1397 entry.hashcodeFunction = NULL;
michael@0 1398 entry.toStringFunction = NULL;
michael@0 1399 entry.comparator = NULL;
michael@0 1400 entry.duplicateFunction = pkix_CertSelector_Duplicate;
michael@0 1401
michael@0 1402 systemClasses[PKIX_CERTSELECTOR_TYPE] = entry;
michael@0 1403
michael@0 1404 PKIX_RETURN(CERTSELECTOR);
michael@0 1405 }
michael@0 1406
michael@0 1407 /* --Public-Functions--------------------------------------------- */
michael@0 1408
michael@0 1409
michael@0 1410 /*
michael@0 1411 * FUNCTION: PKIX_CertSelector_Create (see comments in pkix_certsel.h)
michael@0 1412 */
michael@0 1413 PKIX_Error *
michael@0 1414 PKIX_CertSelector_Create(
michael@0 1415 PKIX_CertSelector_MatchCallback callback,
michael@0 1416 PKIX_PL_Object *certSelectorContext,
michael@0 1417 PKIX_CertSelector **pSelector,
michael@0 1418 void *plContext)
michael@0 1419 {
michael@0 1420 PKIX_CertSelector *selector = NULL;
michael@0 1421
michael@0 1422 PKIX_ENTER(CERTSELECTOR, "PKIX_CertSelector_Create");
michael@0 1423 PKIX_NULLCHECK_ONE(pSelector);
michael@0 1424
michael@0 1425 PKIX_CHECK(PKIX_PL_Object_Alloc
michael@0 1426 (PKIX_CERTSELECTOR_TYPE,
michael@0 1427 sizeof (PKIX_CertSelector),
michael@0 1428 (PKIX_PL_Object **)&selector,
michael@0 1429 plContext),
michael@0 1430 PKIX_COULDNOTCREATECERTSELECTOROBJECT);
michael@0 1431
michael@0 1432 /*
michael@0 1433 * if user specified a particular match callback, we use that one.
michael@0 1434 * otherwise, we use the default match implementation which
michael@0 1435 * understands how to process PKIX_ComCertSelParams
michael@0 1436 */
michael@0 1437
michael@0 1438 if (callback){
michael@0 1439 selector->matchCallback = callback;
michael@0 1440 } else {
michael@0 1441 selector->matchCallback = pkix_CertSelector_DefaultMatch;
michael@0 1442 }
michael@0 1443
michael@0 1444 /* initialize other fields */
michael@0 1445 selector->params = NULL;
michael@0 1446
michael@0 1447 PKIX_INCREF(certSelectorContext);
michael@0 1448 selector->context = certSelectorContext;
michael@0 1449
michael@0 1450 *pSelector = selector;
michael@0 1451
michael@0 1452 cleanup:
michael@0 1453
michael@0 1454 PKIX_RETURN(CERTSELECTOR);
michael@0 1455
michael@0 1456 }
michael@0 1457
michael@0 1458 /*
michael@0 1459 * FUNCTION: PKIX_CertSelector_GetMatchCallback
michael@0 1460 * (see comments in pkix_certsel.h)
michael@0 1461 */
michael@0 1462 PKIX_Error *
michael@0 1463 PKIX_CertSelector_GetMatchCallback(
michael@0 1464 PKIX_CertSelector *selector,
michael@0 1465 PKIX_CertSelector_MatchCallback *pCallback,
michael@0 1466 void *plContext)
michael@0 1467 {
michael@0 1468 PKIX_ENTER(CERTSELECTOR, "PKIX_CertSelector_GetMatchCallback");
michael@0 1469 PKIX_NULLCHECK_TWO(selector, pCallback);
michael@0 1470
michael@0 1471 *pCallback = selector->matchCallback;
michael@0 1472
michael@0 1473 PKIX_RETURN(CERTSELECTOR);
michael@0 1474 }
michael@0 1475
michael@0 1476 /*
michael@0 1477 * FUNCTION: PKIX_CertSelector_GetCertSelectorContext
michael@0 1478 * (see comments in pkix_certsel.h)
michael@0 1479 */
michael@0 1480 PKIX_Error *
michael@0 1481 PKIX_CertSelector_GetCertSelectorContext(
michael@0 1482 PKIX_CertSelector *selector,
michael@0 1483 PKIX_PL_Object **pCertSelectorContext,
michael@0 1484 void *plContext)
michael@0 1485 {
michael@0 1486 PKIX_ENTER(CERTSELECTOR, "PKIX_CertSelector_GetCertSelectorContext");
michael@0 1487 PKIX_NULLCHECK_TWO(selector, pCertSelectorContext);
michael@0 1488
michael@0 1489 PKIX_INCREF(selector->context);
michael@0 1490
michael@0 1491 *pCertSelectorContext = selector->context;
michael@0 1492
michael@0 1493 cleanup:
michael@0 1494 PKIX_RETURN(CERTSELECTOR);
michael@0 1495 }
michael@0 1496
michael@0 1497 /*
michael@0 1498 * FUNCTION: PKIX_CertSelector_GetCommonCertSelectorParams
michael@0 1499 * (see comments in pkix_certsel.h)
michael@0 1500 */
michael@0 1501 PKIX_Error *
michael@0 1502 PKIX_CertSelector_GetCommonCertSelectorParams(
michael@0 1503 PKIX_CertSelector *selector,
michael@0 1504 PKIX_ComCertSelParams **pParams,
michael@0 1505 void *plContext)
michael@0 1506 {
michael@0 1507 PKIX_ENTER(CERTSELECTOR,
michael@0 1508 "PKIX_CertSelector_GetCommonCertSelectorParams");
michael@0 1509
michael@0 1510 PKIX_NULLCHECK_TWO(selector, pParams);
michael@0 1511
michael@0 1512 PKIX_INCREF(selector->params);
michael@0 1513 *pParams = selector->params;
michael@0 1514
michael@0 1515 cleanup:
michael@0 1516 PKIX_RETURN(CERTSELECTOR);
michael@0 1517
michael@0 1518 }
michael@0 1519
michael@0 1520 /*
michael@0 1521 * FUNCTION: PKIX_CertSelector_SetCommonCertSelectorParams
michael@0 1522 * (see comments in pkix_certsel.h)
michael@0 1523 */
michael@0 1524 PKIX_Error *
michael@0 1525 PKIX_CertSelector_SetCommonCertSelectorParams(
michael@0 1526 PKIX_CertSelector *selector,
michael@0 1527 PKIX_ComCertSelParams *params,
michael@0 1528 void *plContext)
michael@0 1529 {
michael@0 1530 PKIX_ENTER(CERTSELECTOR,
michael@0 1531 "PKIX_CertSelector_SetCommonCertSelectorParams");
michael@0 1532
michael@0 1533 PKIX_NULLCHECK_ONE(selector);
michael@0 1534
michael@0 1535 PKIX_DECREF(selector->params);
michael@0 1536 PKIX_INCREF(params);
michael@0 1537 selector->params = params;
michael@0 1538
michael@0 1539 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
michael@0 1540 ((PKIX_PL_Object *)selector, plContext),
michael@0 1541 PKIX_OBJECTINVALIDATECACHEFAILED);
michael@0 1542
michael@0 1543 cleanup:
michael@0 1544
michael@0 1545 PKIX_RETURN(CERTSELECTOR);
michael@0 1546
michael@0 1547 }
michael@0 1548
michael@0 1549 /*
michael@0 1550 * FUNCTION: pkix_CertSelector_Select
michael@0 1551 * DESCRIPTION:
michael@0 1552 *
michael@0 1553 * This function applies the selector pointed to by "selector" to each Cert,
michael@0 1554 * in turn, in the List pointed to by "before", and creates a List containing
michael@0 1555 * all the Certs that matched, or passed the selection process, storing that
michael@0 1556 * List at "pAfter". If no Certs match, an empty List is stored at "pAfter".
michael@0 1557 *
michael@0 1558 * The List returned in "pAfter" is immutable.
michael@0 1559 *
michael@0 1560 * PARAMETERS:
michael@0 1561 * "selector"
michael@0 1562 * Address of CertSelelector to be applied to the List. Must be non-NULL.
michael@0 1563 * "before"
michael@0 1564 * Address of List that is to be filtered. Must be non-NULL.
michael@0 1565 * "pAfter"
michael@0 1566 * Address at which resulting List, possibly empty, is stored. Must be
michael@0 1567 * non-NULL.
michael@0 1568 * "plContext"
michael@0 1569 * Platform-specific context pointer.
michael@0 1570 * THREAD SAFETY:
michael@0 1571 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
michael@0 1572 * RETURNS:
michael@0 1573 * Returns NULL if the function succeeds.
michael@0 1574 * Returns a CertSelector Error if the function fails in a non-fatal way.
michael@0 1575 * Returns a Fatal Error if the function fails in an unrecoverable way.
michael@0 1576 */
michael@0 1577 PKIX_Error *
michael@0 1578 pkix_CertSelector_Select(
michael@0 1579 PKIX_CertSelector *selector,
michael@0 1580 PKIX_List *before,
michael@0 1581 PKIX_List **pAfter,
michael@0 1582 void *plContext)
michael@0 1583 {
michael@0 1584 PKIX_UInt32 numBefore = 0;
michael@0 1585 PKIX_UInt32 i = 0;
michael@0 1586 PKIX_List *filtered = NULL;
michael@0 1587 PKIX_PL_Cert *candidate = NULL;
michael@0 1588
michael@0 1589 PKIX_ENTER(CERTSELECTOR, "PKIX_CertSelector_Select");
michael@0 1590 PKIX_NULLCHECK_THREE(selector, before, pAfter);
michael@0 1591
michael@0 1592 PKIX_CHECK(PKIX_List_Create(&filtered, plContext),
michael@0 1593 PKIX_LISTCREATEFAILED);
michael@0 1594
michael@0 1595 PKIX_CHECK(PKIX_List_GetLength(before, &numBefore, plContext),
michael@0 1596 PKIX_LISTGETLENGTHFAILED);
michael@0 1597
michael@0 1598 for (i = 0; i < numBefore; i++) {
michael@0 1599
michael@0 1600 PKIX_CHECK(PKIX_List_GetItem
michael@0 1601 (before, i, (PKIX_PL_Object **)&candidate, plContext),
michael@0 1602 PKIX_LISTGETITEMFAILED);
michael@0 1603
michael@0 1604 PKIX_CHECK_ONLY_FATAL(selector->matchCallback
michael@0 1605 (selector, candidate, plContext),
michael@0 1606 PKIX_CERTSELECTORMATCHCALLBACKFAILED);
michael@0 1607
michael@0 1608 if (!(PKIX_ERROR_RECEIVED)) {
michael@0 1609
michael@0 1610 PKIX_CHECK_ONLY_FATAL(PKIX_List_AppendItem
michael@0 1611 (filtered,
michael@0 1612 (PKIX_PL_Object *)candidate,
michael@0 1613 plContext),
michael@0 1614 PKIX_LISTAPPENDITEMFAILED);
michael@0 1615 }
michael@0 1616
michael@0 1617 pkixTempErrorReceived = PKIX_FALSE;
michael@0 1618 PKIX_DECREF(candidate);
michael@0 1619 }
michael@0 1620
michael@0 1621 PKIX_CHECK(PKIX_List_SetImmutable(filtered, plContext),
michael@0 1622 PKIX_LISTSETIMMUTABLEFAILED);
michael@0 1623
michael@0 1624 /* Don't throw away the list if one Cert was bad! */
michael@0 1625 pkixTempErrorReceived = PKIX_FALSE;
michael@0 1626
michael@0 1627 *pAfter = filtered;
michael@0 1628 filtered = NULL;
michael@0 1629
michael@0 1630 cleanup:
michael@0 1631
michael@0 1632 PKIX_DECREF(filtered);
michael@0 1633 PKIX_DECREF(candidate);
michael@0 1634
michael@0 1635 PKIX_RETURN(CERTSELECTOR);
michael@0 1636
michael@0 1637 }

mercurial