| OLD | NEW |
| (Empty) |
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
| 2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
| 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
| 4 /* | |
| 5 * pkix_pl_crlentry.c | |
| 6 * | |
| 7 * CRLENTRY Function Definitions | |
| 8 * | |
| 9 */ | |
| 10 | |
| 11 #include "pkix_pl_crlentry.h" | |
| 12 | |
| 13 /* --Private-CRLEntry-Functions------------------------------------- */ | |
| 14 | |
| 15 /* | |
| 16 * FUNCTION: pkix_pl_CRLEntry_Destroy | |
| 17 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) | |
| 18 */ | |
| 19 static PKIX_Error * | |
| 20 pkix_pl_CRLEntry_Destroy( | |
| 21 PKIX_PL_Object *object, | |
| 22 void *plContext) | |
| 23 { | |
| 24 PKIX_PL_CRLEntry *crlEntry = NULL; | |
| 25 | |
| 26 PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Destroy"); | |
| 27 PKIX_NULLCHECK_ONE(object); | |
| 28 | |
| 29 PKIX_CHECK(pkix_CheckType(object, PKIX_CRLENTRY_TYPE, plContext), | |
| 30 PKIX_OBJECTNOTCRLENTRY); | |
| 31 | |
| 32 crlEntry = (PKIX_PL_CRLEntry*)object; | |
| 33 | |
| 34 /* crlEntry->nssCrlEntry is freed by NSS when freeing CRL */ | |
| 35 crlEntry->userReasonCode = 0; | |
| 36 crlEntry->userReasonCodeAbsent = PKIX_FALSE; | |
| 37 crlEntry->nssCrlEntry = NULL; | |
| 38 PKIX_DECREF(crlEntry->serialNumber); | |
| 39 PKIX_DECREF(crlEntry->critExtOids); | |
| 40 | |
| 41 cleanup: | |
| 42 | |
| 43 PKIX_RETURN(CRLENTRY); | |
| 44 } | |
| 45 | |
| 46 /* | |
| 47 * FUNCTION: pkix_pl_CRLEntry_ToString_Helper | |
| 48 * | |
| 49 * DESCRIPTION: | |
| 50 * Helper function that creates a string representation of the CRLEntry | |
| 51 * pointed to by "crlEntry" and stores it at "pString". | |
| 52 * | |
| 53 * PARAMETERS | |
| 54 * "crlEntry" | |
| 55 * Address of CRLEntry whose string representation is desired. | |
| 56 * Must be non-NULL. | |
| 57 * "pString" | |
| 58 * Address where object pointer will be stored. Must be non-NULL. | |
| 59 * "plContext" | |
| 60 * Platform-specific context pointer. | |
| 61 * THREAD SAFETY: | |
| 62 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 63 * RETURNS: | |
| 64 * Returns NULL if the function succeeds. | |
| 65 * Returns a CRLEntry Error if the function fails in a non-fatal way. | |
| 66 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
| 67 */ | |
| 68 PKIX_Error * | |
| 69 pkix_pl_CRLEntry_ToString_Helper( | |
| 70 PKIX_PL_CRLEntry *crlEntry, | |
| 71 PKIX_PL_String **pString, | |
| 72 void *plContext) | |
| 73 { | |
| 74 char *asciiFormat = NULL; | |
| 75 PKIX_List *critExtOIDs = NULL; | |
| 76 PKIX_PL_String *crlEntryString = NULL; | |
| 77 PKIX_PL_String *formatString = NULL; | |
| 78 PKIX_PL_String *crlSerialNumberString = NULL; | |
| 79 PKIX_PL_String *crlRevocationDateString = NULL; | |
| 80 PKIX_PL_String *critExtOIDsString = NULL; | |
| 81 PKIX_Int32 reasonCode = 0; | |
| 82 | |
| 83 PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_ToString_Helper"); | |
| 84 PKIX_NULLCHECK_FOUR | |
| 85 (crlEntry, | |
| 86 crlEntry->serialNumber, | |
| 87 crlEntry->nssCrlEntry, | |
| 88 pString); | |
| 89 | |
| 90 asciiFormat = | |
| 91 "\n\t[\n" | |
| 92 "\tSerialNumber: %s\n" | |
| 93 "\tReasonCode: %d\n" | |
| 94 "\tRevocationDate: %s\n" | |
| 95 "\tCritExtOIDs: %s\n" | |
| 96 "\t]\n\t"; | |
| 97 | |
| 98 PKIX_CHECK(PKIX_PL_String_Create | |
| 99 (PKIX_ESCASCII, | |
| 100 asciiFormat, | |
| 101 0, | |
| 102 &formatString, | |
| 103 plContext), | |
| 104 PKIX_STRINGCREATEFAILED); | |
| 105 | |
| 106 /* SerialNumber */ | |
| 107 PKIX_CHECK(PKIX_PL_Object_ToString | |
| 108 ((PKIX_PL_Object *)crlEntry->serialNumber, | |
| 109 &crlSerialNumberString, | |
| 110 plContext), | |
| 111 PKIX_BIGINTTOSTRINGHELPERFAILED); | |
| 112 | |
| 113 /* RevocationDate - No Date object created, use nss data directly */ | |
| 114 PKIX_CHECK(pkix_pl_Date_ToString_Helper | |
| 115 (&(crlEntry->nssCrlEntry->revocationDate), | |
| 116 &crlRevocationDateString, | |
| 117 plContext), | |
| 118 PKIX_DATETOSTRINGHELPERFAILED); | |
| 119 | |
| 120 /* CriticalExtensionOIDs */ | |
| 121 PKIX_CHECK(PKIX_PL_CRLEntry_GetCriticalExtensionOIDs | |
| 122 (crlEntry, &critExtOIDs, plContext), | |
| 123 PKIX_CRLENTRYGETCRITICALEXTENSIONOIDSFAILED); | |
| 124 | |
| 125 PKIX_TOSTRING(critExtOIDs, &critExtOIDsString, plContext, | |
| 126 PKIX_LISTTOSTRINGFAILED); | |
| 127 | |
| 128 /* Revocation Reason Code */ | |
| 129 PKIX_CHECK(PKIX_PL_CRLEntry_GetCRLEntryReasonCode | |
| 130 (crlEntry, &reasonCode, plContext), | |
| 131 PKIX_CRLENTRYGETCRLENTRYREASONCODEFAILED); | |
| 132 | |
| 133 PKIX_CHECK(PKIX_PL_Sprintf | |
| 134 (&crlEntryString, | |
| 135 plContext, | |
| 136 formatString, | |
| 137 crlSerialNumberString, | |
| 138 reasonCode, | |
| 139 crlRevocationDateString, | |
| 140 critExtOIDsString), | |
| 141 PKIX_SPRINTFFAILED); | |
| 142 | |
| 143 *pString = crlEntryString; | |
| 144 | |
| 145 cleanup: | |
| 146 | |
| 147 PKIX_DECREF(critExtOIDs); | |
| 148 PKIX_DECREF(crlSerialNumberString); | |
| 149 PKIX_DECREF(crlRevocationDateString); | |
| 150 PKIX_DECREF(critExtOIDsString); | |
| 151 PKIX_DECREF(formatString); | |
| 152 | |
| 153 PKIX_RETURN(CRLENTRY); | |
| 154 } | |
| 155 | |
| 156 /* | |
| 157 * FUNCTION: pkix_pl_CRLEntry_ToString | |
| 158 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) | |
| 159 */ | |
| 160 static PKIX_Error * | |
| 161 pkix_pl_CRLEntry_ToString( | |
| 162 PKIX_PL_Object *object, | |
| 163 PKIX_PL_String **pString, | |
| 164 void *plContext) | |
| 165 { | |
| 166 PKIX_PL_String *crlEntryString = NULL; | |
| 167 PKIX_PL_CRLEntry *crlEntry = NULL; | |
| 168 | |
| 169 PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_ToString"); | |
| 170 PKIX_NULLCHECK_TWO(object, pString); | |
| 171 | |
| 172 PKIX_CHECK(pkix_CheckType(object, PKIX_CRLENTRY_TYPE, plContext), | |
| 173 PKIX_OBJECTNOTCRLENTRY); | |
| 174 | |
| 175 crlEntry = (PKIX_PL_CRLEntry *) object; | |
| 176 | |
| 177 PKIX_CHECK(pkix_pl_CRLEntry_ToString_Helper | |
| 178 (crlEntry, &crlEntryString, plContext), | |
| 179 PKIX_CRLENTRYTOSTRINGHELPERFAILED); | |
| 180 | |
| 181 *pString = crlEntryString; | |
| 182 | |
| 183 cleanup: | |
| 184 | |
| 185 PKIX_RETURN(CRLENTRY); | |
| 186 } | |
| 187 | |
| 188 /* | |
| 189 * FUNCTION: pkix_pl_CRLEntry_Extensions_Hashcode | |
| 190 * DESCRIPTION: | |
| 191 * | |
| 192 * For each CRL Entry extension stored at NSS structure CERTCertExtension, | |
| 193 * get its derbyte data and do the hash. | |
| 194 * | |
| 195 * PARAMETERS | |
| 196 * "extensions" | |
| 197 * Address of arrray of CERTCertExtension whose hash value is desired. | |
| 198 * Must be non-NULL. | |
| 199 * "pHashValue" | |
| 200 * Address where the final hash value is returned. Must be non-NULL. | |
| 201 * "plContext" | |
| 202 * Platform-specific context pointer. | |
| 203 * THREAD SAFETY: | |
| 204 * Conditional Thread Safe | |
| 205 * Though the value of extensions once created is not supposed to change, | |
| 206 * it may be de-allocated while we are accessing it. But since we are | |
| 207 * validating the object, it is unlikely we or someone is de-allocating | |
| 208 * at the moment. | |
| 209 * RETURNS: | |
| 210 * Returns NULL if the function succeeds. | |
| 211 * Returns an OID Error if the function fails in a non-fatal way. | |
| 212 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
| 213 */ | |
| 214 static PKIX_Error * | |
| 215 pkix_pl_CRLEntry_Extensions_Hashcode( | |
| 216 CERTCertExtension **extensions, | |
| 217 PKIX_UInt32 *pHashValue, | |
| 218 void *plContext) | |
| 219 { | |
| 220 CERTCertExtension *extension = NULL; | |
| 221 PLArenaPool *arena = NULL; | |
| 222 PKIX_UInt32 extHash = 0; | |
| 223 PKIX_UInt32 hashValue = 0; | |
| 224 SECItem *derBytes = NULL; | |
| 225 SECItem *resultSecItem = NULL; | |
| 226 | |
| 227 PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Extensions_Hashcode"); | |
| 228 PKIX_NULLCHECK_TWO(extensions, pHashValue); | |
| 229 | |
| 230 if (extensions) { | |
| 231 | |
| 232 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_NewArena\n"); | |
| 233 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | |
| 234 if (arena == NULL) { | |
| 235 PKIX_ERROR(PKIX_OUTOFMEMORY); | |
| 236 } | |
| 237 | |
| 238 while (*extensions) { | |
| 239 | |
| 240 extension = *extensions++; | |
| 241 | |
| 242 PKIX_NULLCHECK_ONE(extension); | |
| 243 | |
| 244 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_ArenaZNew\n"); | |
| 245 derBytes = PORT_ArenaZNew(arena, SECItem); | |
| 246 if (derBytes == NULL) { | |
| 247 PKIX_ERROR(PKIX_PORTARENAALLOCFAILED); | |
| 248 } | |
| 249 | |
| 250 PKIX_CRLENTRY_DEBUG | |
| 251 ("\t\tCalling SEC_ASN1EncodeItem\n"); | |
| 252 resultSecItem = SEC_ASN1EncodeItem | |
| 253 (arena, | |
| 254 derBytes, | |
| 255 extension, | |
| 256 CERT_CertExtensionTemplate); | |
| 257 | |
| 258 if (resultSecItem == NULL){ | |
| 259 PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED); | |
| 260 } | |
| 261 | |
| 262 PKIX_CHECK(pkix_hash | |
| 263 (derBytes->data, | |
| 264 derBytes->len, | |
| 265 &extHash, | |
| 266 plContext), | |
| 267 PKIX_HASHFAILED); | |
| 268 | |
| 269 hashValue += (extHash << 7); | |
| 270 | |
| 271 } | |
| 272 } | |
| 273 | |
| 274 *pHashValue = hashValue; | |
| 275 | |
| 276 cleanup: | |
| 277 | |
| 278 if (arena){ | |
| 279 /* Note that freeing the arena also frees derBytes */ | |
| 280 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_FreeArena\n"); | |
| 281 PORT_FreeArena(arena, PR_FALSE); | |
| 282 arena = NULL; | |
| 283 } | |
| 284 PKIX_RETURN(CRLENTRY); | |
| 285 } | |
| 286 | |
| 287 /* | |
| 288 * FUNCTION: pkix_pl_CRLEntry_Hashcode | |
| 289 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) | |
| 290 */ | |
| 291 static PKIX_Error * | |
| 292 pkix_pl_CRLEntry_Hashcode( | |
| 293 PKIX_PL_Object *object, | |
| 294 PKIX_UInt32 *pHashcode, | |
| 295 void *plContext) | |
| 296 { | |
| 297 SECItem *nssDate = NULL; | |
| 298 PKIX_PL_CRLEntry *crlEntry = NULL; | |
| 299 PKIX_UInt32 crlEntryHash; | |
| 300 PKIX_UInt32 hashValue; | |
| 301 PKIX_Int32 reasonCode = 0; | |
| 302 | |
| 303 PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Hashcode"); | |
| 304 PKIX_NULLCHECK_TWO(object, pHashcode); | |
| 305 | |
| 306 PKIX_CHECK(pkix_CheckType(object, PKIX_CRLENTRY_TYPE, plContext), | |
| 307 PKIX_OBJECTNOTCRLENTRY); | |
| 308 | |
| 309 crlEntry = (PKIX_PL_CRLEntry *)object; | |
| 310 | |
| 311 PKIX_NULLCHECK_ONE(crlEntry->nssCrlEntry); | |
| 312 nssDate = &(crlEntry->nssCrlEntry->revocationDate); | |
| 313 | |
| 314 PKIX_NULLCHECK_ONE(nssDate->data); | |
| 315 | |
| 316 PKIX_CHECK(pkix_hash | |
| 317 ((const unsigned char *)nssDate->data, | |
| 318 nssDate->len, | |
| 319 &crlEntryHash, | |
| 320 plContext), | |
| 321 PKIX_ERRORGETTINGHASHCODE); | |
| 322 | |
| 323 PKIX_CHECK(PKIX_PL_Object_Hashcode | |
| 324 ((PKIX_PL_Object *)crlEntry->serialNumber, | |
| 325 &hashValue, | |
| 326 plContext), | |
| 327 PKIX_OBJECTHASHCODEFAILED); | |
| 328 | |
| 329 crlEntryHash += (hashValue << 7); | |
| 330 | |
| 331 hashValue = 0; | |
| 332 | |
| 333 if (crlEntry->nssCrlEntry->extensions) { | |
| 334 | |
| 335 PKIX_CHECK(pkix_pl_CRLEntry_Extensions_Hashcode | |
| 336 (crlEntry->nssCrlEntry->extensions, &hashValue, plContext), | |
| 337 PKIX_CRLENTRYEXTENSIONSHASHCODEFAILED); | |
| 338 } | |
| 339 | |
| 340 crlEntryHash += (hashValue << 7); | |
| 341 | |
| 342 PKIX_CHECK(PKIX_PL_CRLEntry_GetCRLEntryReasonCode | |
| 343 (crlEntry, &reasonCode, plContext), | |
| 344 PKIX_CRLENTRYGETCRLENTRYREASONCODEFAILED); | |
| 345 | |
| 346 crlEntryHash += (reasonCode + 777) << 3; | |
| 347 | |
| 348 *pHashcode = crlEntryHash; | |
| 349 | |
| 350 cleanup: | |
| 351 | |
| 352 PKIX_RETURN(CRLENTRY); | |
| 353 } | |
| 354 | |
| 355 /* | |
| 356 * FUNCTION: pkix_pl_CRLENTRY_Extensions_Equals | |
| 357 * DESCRIPTION: | |
| 358 * | |
| 359 * Compare each extension's DERbyte data in "firstExtensions" with extension | |
| 360 * in "secondExtensions" in sequential order and store the result in | |
| 361 * "pResult". | |
| 362 * | |
| 363 * PARAMETERS | |
| 364 * "firstExtensions" | |
| 365 * Address of first NSS structure CERTCertExtension to be compared. | |
| 366 * Must be non-NULL. | |
| 367 * "secondExtensions" | |
| 368 * Address of second NSS structure CERTCertExtension to be compared. | |
| 369 * Must be non-NULL. | |
| 370 * "pResult" | |
| 371 * Address where the comparison result is returned. Must be non-NULL. | |
| 372 * "plContext" | |
| 373 * Platform-specific context pointer. | |
| 374 * THREAD SAFETY: | |
| 375 * Conditionally Thread Safe | |
| 376 * Though the value of extensions once created is not supposed to change, | |
| 377 * it may be de-allocated while we are accessing it. But since we are | |
| 378 * validating the object, it is unlikely we or someone is de-allocating | |
| 379 * at the moment. | |
| 380 * RETURNS: | |
| 381 * Returns NULL if the function succeeds. | |
| 382 * Returns an OID Error if the function fails in a non-fatal way. | |
| 383 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
| 384 */ | |
| 385 static PKIX_Error * | |
| 386 pkix_pl_CRLEntry_Extensions_Equals( | |
| 387 CERTCertExtension **extensions1, | |
| 388 CERTCertExtension **extensions2, | |
| 389 PKIX_Boolean *pResult, | |
| 390 void *plContext) | |
| 391 { | |
| 392 CERTCertExtension **firstExtensions; | |
| 393 CERTCertExtension **secondExtensions; | |
| 394 CERTCertExtension *firstExtension = NULL; | |
| 395 CERTCertExtension *secondExtension = NULL; | |
| 396 PLArenaPool *arena = NULL; | |
| 397 PKIX_Boolean cmpResult = PKIX_FALSE; | |
| 398 SECItem *firstDerBytes = NULL; | |
| 399 SECItem *secondDerBytes = NULL; | |
| 400 SECItem *firstResultSecItem = NULL; | |
| 401 SECItem *secondResultSecItem = NULL; | |
| 402 PKIX_UInt32 firstNumExt = 0; | |
| 403 PKIX_UInt32 secondNumExt = 0; | |
| 404 SECComparison secResult; | |
| 405 | |
| 406 PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Extensions_Equals"); | |
| 407 PKIX_NULLCHECK_THREE(extensions1, extensions2, pResult); | |
| 408 | |
| 409 firstExtensions = extensions1; | |
| 410 secondExtensions = extensions2; | |
| 411 | |
| 412 if (firstExtensions) { | |
| 413 while (*firstExtensions) { | |
| 414 firstExtension = *firstExtensions++; | |
| 415 firstNumExt++; | |
| 416 } | |
| 417 } | |
| 418 | |
| 419 if (secondExtensions) { | |
| 420 while (*secondExtensions) { | |
| 421 secondExtension = *secondExtensions++; | |
| 422 secondNumExt++; | |
| 423 } | |
| 424 } | |
| 425 | |
| 426 if (firstNumExt != secondNumExt) { | |
| 427 *pResult = PKIX_FALSE; | |
| 428 goto cleanup; | |
| 429 } | |
| 430 | |
| 431 if (firstNumExt == 0 && secondNumExt == 0) { | |
| 432 *pResult = PKIX_TRUE; | |
| 433 goto cleanup; | |
| 434 } | |
| 435 | |
| 436 /* now have equal number, but non-zero extension items to compare */ | |
| 437 | |
| 438 firstExtensions = extensions1; | |
| 439 secondExtensions = extensions2; | |
| 440 | |
| 441 cmpResult = PKIX_TRUE; | |
| 442 | |
| 443 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_NewArena\n"); | |
| 444 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE*2); | |
| 445 if (arena == NULL) { | |
| 446 PKIX_ERROR(PKIX_OUTOFMEMORY); | |
| 447 } | |
| 448 | |
| 449 while (firstNumExt--) { | |
| 450 | |
| 451 firstExtension = *firstExtensions++; | |
| 452 secondExtension = *secondExtensions++; | |
| 453 | |
| 454 PKIX_NULLCHECK_TWO(firstExtension, secondExtension); | |
| 455 | |
| 456 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_ArenaZNew\n"); | |
| 457 firstDerBytes = PORT_ArenaZNew(arena, SECItem); | |
| 458 if (firstDerBytes == NULL) { | |
| 459 PKIX_ERROR(PKIX_PORTARENAALLOCFAILED); | |
| 460 } | |
| 461 | |
| 462 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_ArenaZNew\n"); | |
| 463 secondDerBytes = PORT_ArenaZNew(arena, SECItem); | |
| 464 if (secondDerBytes == NULL) { | |
| 465 PKIX_ERROR(PKIX_PORTARENAALLOCFAILED); | |
| 466 } | |
| 467 | |
| 468 PKIX_CRLENTRY_DEBUG | |
| 469 ("\t\tCalling SEC_ASN1EncodeItem\n"); | |
| 470 firstResultSecItem = SEC_ASN1EncodeItem | |
| 471 (arena, | |
| 472 firstDerBytes, | |
| 473 firstExtension, | |
| 474 CERT_CertExtensionTemplate); | |
| 475 | |
| 476 if (firstResultSecItem == NULL){ | |
| 477 PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED); | |
| 478 } | |
| 479 | |
| 480 PKIX_CRLENTRY_DEBUG | |
| 481 ("\t\tCalling SEC_ASN1EncodeItem\n"); | |
| 482 secondResultSecItem = SEC_ASN1EncodeItem | |
| 483 (arena, | |
| 484 secondDerBytes, | |
| 485 secondExtension, | |
| 486 CERT_CertExtensionTemplate); | |
| 487 | |
| 488 if (secondResultSecItem == NULL){ | |
| 489 PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED); | |
| 490 } | |
| 491 | |
| 492 PKIX_CRLENTRY_DEBUG("\t\tCalling SECITEM_CompareItem\n"); | |
| 493 secResult = SECITEM_CompareItem | |
| 494 (firstResultSecItem, secondResultSecItem); | |
| 495 | |
| 496 if (secResult != SECEqual) { | |
| 497 cmpResult = PKIX_FALSE; | |
| 498 break; | |
| 499 } | |
| 500 | |
| 501 } | |
| 502 | |
| 503 *pResult = cmpResult; | |
| 504 | |
| 505 cleanup: | |
| 506 | |
| 507 if (arena){ | |
| 508 /* Note that freeing the arena also frees derBytes */ | |
| 509 PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_FreeArena\n"); | |
| 510 PORT_FreeArena(arena, PR_FALSE); | |
| 511 arena = NULL; | |
| 512 } | |
| 513 | |
| 514 PKIX_RETURN(CRLENTRY); | |
| 515 } | |
| 516 | |
| 517 /* | |
| 518 * FUNCTION: pkix_pl_CRLEntry_Equals | |
| 519 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h) | |
| 520 */ | |
| 521 static PKIX_Error * | |
| 522 pkix_pl_CRLEntry_Equals( | |
| 523 PKIX_PL_Object *firstObject, | |
| 524 PKIX_PL_Object *secondObject, | |
| 525 PKIX_Boolean *pResult, | |
| 526 void *plContext) | |
| 527 { | |
| 528 PKIX_PL_CRLEntry *firstCrlEntry = NULL; | |
| 529 PKIX_PL_CRLEntry *secondCrlEntry = NULL; | |
| 530 PKIX_UInt32 secondType; | |
| 531 PKIX_Boolean cmpResult = PKIX_FALSE; | |
| 532 | |
| 533 PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Equals"); | |
| 534 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult); | |
| 535 | |
| 536 /* test that firstObject is a CRLEntry */ | |
| 537 PKIX_CHECK(pkix_CheckType(firstObject, PKIX_CRLENTRY_TYPE, plContext), | |
| 538 PKIX_FIRSTOBJECTNOTCRLENTRY); | |
| 539 | |
| 540 firstCrlEntry = (PKIX_PL_CRLEntry *)firstObject; | |
| 541 secondCrlEntry = (PKIX_PL_CRLEntry *)secondObject; | |
| 542 | |
| 543 PKIX_NULLCHECK_TWO | |
| 544 (firstCrlEntry->nssCrlEntry, secondCrlEntry->nssCrlEntry); | |
| 545 | |
| 546 /* | |
| 547 * Since we know firstObject is a CRLEntry, if both references are | |
| 548 * identical, they must be equal | |
| 549 */ | |
| 550 if (firstCrlEntry == secondCrlEntry){ | |
| 551 *pResult = PKIX_TRUE; | |
| 552 goto cleanup; | |
| 553 } | |
| 554 | |
| 555 /* | |
| 556 * If secondCrlEntry isn't a CRL Entry, we don't throw an error. | |
| 557 * We simply return a Boolean result of FALSE | |
| 558 */ | |
| 559 *pResult = PKIX_FALSE; | |
| 560 PKIX_CHECK(PKIX_PL_Object_GetType | |
| 561 ((PKIX_PL_Object *)secondCrlEntry, &secondType, plContext), | |
| 562 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT); | |
| 563 if (secondType != PKIX_CRLENTRY_TYPE) goto cleanup; | |
| 564 | |
| 565 /* Compare userSerialNumber */ | |
| 566 PKIX_CRLENTRY_DEBUG("\t\tCalling SECITEM_CompareItem\n"); | |
| 567 if (SECITEM_CompareItem( | |
| 568 &(((PKIX_PL_CRLEntry *)firstCrlEntry)->nssCrlEntry->serialNumber), | |
| 569 &(((PKIX_PL_CRLEntry *)secondCrlEntry)->nssCrlEntry->serialNumber)) | |
| 570 != SECEqual) { | |
| 571 *pResult = PKIX_FALSE; | |
| 572 goto cleanup; | |
| 573 } | |
| 574 | |
| 575 /* Compare revocationDate */ | |
| 576 PKIX_CRLENTRY_DEBUG("\t\tCalling SECITEM_CompareItem\n"); | |
| 577 if (SECITEM_CompareItem | |
| 578 (&(((PKIX_PL_CRLEntry *)firstCrlEntry)->nssCrlEntry-> | |
| 579 revocationDate), | |
| 580 &(((PKIX_PL_CRLEntry *)secondCrlEntry)->nssCrlEntry-> | |
| 581 revocationDate)) | |
| 582 != SECEqual) { | |
| 583 *pResult = PKIX_FALSE; | |
| 584 goto cleanup; | |
| 585 } | |
| 586 | |
| 587 /* Compare Critical Extension List */ | |
| 588 PKIX_CHECK(pkix_pl_CRLEntry_Extensions_Equals | |
| 589 (firstCrlEntry->nssCrlEntry->extensions, | |
| 590 secondCrlEntry->nssCrlEntry->extensions, | |
| 591 &cmpResult, | |
| 592 plContext), | |
| 593 PKIX_CRLENTRYEXTENSIONSEQUALSFAILED); | |
| 594 | |
| 595 if (cmpResult != PKIX_TRUE){ | |
| 596 *pResult = PKIX_FALSE; | |
| 597 goto cleanup; | |
| 598 } | |
| 599 | |
| 600 cmpResult = (firstCrlEntry->userReasonCode == | |
| 601 secondCrlEntry->userReasonCode); | |
| 602 | |
| 603 *pResult = cmpResult; | |
| 604 | |
| 605 cleanup: | |
| 606 | |
| 607 PKIX_RETURN(CRLENTRY); | |
| 608 } | |
| 609 | |
| 610 /* | |
| 611 * FUNCTION: pkix_pl_CRLEntry_RegisterSelf | |
| 612 * DESCRIPTION: | |
| 613 * Registers PKIX_CRLEntry_TYPE and its related functions with systemClasses[] | |
| 614 * THREAD SAFETY: | |
| 615 * Not Thread Safe - for performance and complexity reasons | |
| 616 * | |
| 617 * Since this function is only called by PKIX_PL_Initialize, which should | |
| 618 * only be called once, it is acceptable that this function is not | |
| 619 * thread-safe. | |
| 620 */ | |
| 621 PKIX_Error * | |
| 622 pkix_pl_CRLEntry_RegisterSelf(void *plContext) | |
| 623 { | |
| 624 | |
| 625 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; | |
| 626 pkix_ClassTable_Entry entry; | |
| 627 | |
| 628 PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_RegisterSelf"); | |
| 629 | |
| 630 entry.description = "CRLEntry"; | |
| 631 entry.objCounter = 0; | |
| 632 entry.typeObjectSize = sizeof(PKIX_PL_CRLEntry); | |
| 633 entry.destructor = pkix_pl_CRLEntry_Destroy; | |
| 634 entry.equalsFunction = pkix_pl_CRLEntry_Equals; | |
| 635 entry.hashcodeFunction = pkix_pl_CRLEntry_Hashcode; | |
| 636 entry.toStringFunction = pkix_pl_CRLEntry_ToString; | |
| 637 entry.comparator = NULL; | |
| 638 entry.duplicateFunction = pkix_duplicateImmutable; | |
| 639 | |
| 640 systemClasses[PKIX_CRLENTRY_TYPE] = entry; | |
| 641 | |
| 642 PKIX_RETURN(CRLENTRY); | |
| 643 } | |
| 644 | |
| 645 /* | |
| 646 * FUNCTION: pkix_pl_CRLEntry_CreateEntry | |
| 647 * DESCRIPTION: | |
| 648 * | |
| 649 * Creates a new CRLEntry using the CertCrlEntry pointed to by "nssCrlEntry" | |
| 650 * and stores it at "pCrlEntry". Once created, a CRLEntry is immutable. | |
| 651 * | |
| 652 * revokedCertificates SEQUENCE OF SEQUENCE { | |
| 653 * userCertificate CertificateSerialNumber, | |
| 654 * revocationDate Time, | |
| 655 * crlEntryExtensions Extensions OPTIONAL | |
| 656 * -- if present, MUST be v2 | |
| 657 * | |
| 658 * PARAMETERS: | |
| 659 * "nssCrlEntry" | |
| 660 * Address of CERTCrlEntry representing an NSS CRL entry. | |
| 661 * Must be non-NULL. | |
| 662 * "pCrlEntry" | |
| 663 * Address where object pointer will be stored. Must be non-NULL. | |
| 664 * "plContext" | |
| 665 * Platform-specific context pointer. | |
| 666 * THREAD SAFETY: | |
| 667 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 668 * RETURNS: | |
| 669 * Returns NULL if the function succeeds. | |
| 670 * Returns a CRLEntry Error if the function fails in a non-fatal way. | |
| 671 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
| 672 */ | |
| 673 static PKIX_Error * | |
| 674 pkix_pl_CRLEntry_CreateEntry( | |
| 675 CERTCrlEntry *nssCrlEntry, /* entry data to be created from */ | |
| 676 PKIX_PL_CRLEntry **pCrlEntry, | |
| 677 void *plContext) | |
| 678 { | |
| 679 PKIX_PL_CRLEntry *crlEntry = NULL; | |
| 680 | |
| 681 PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_CreateEntry"); | |
| 682 PKIX_NULLCHECK_TWO(nssCrlEntry, pCrlEntry); | |
| 683 | |
| 684 PKIX_CHECK(PKIX_PL_Object_Alloc | |
| 685 (PKIX_CRLENTRY_TYPE, | |
| 686 sizeof (PKIX_PL_CRLEntry), | |
| 687 (PKIX_PL_Object **)&crlEntry, | |
| 688 plContext), | |
| 689 PKIX_COULDNOTCREATECRLENTRYOBJECT); | |
| 690 | |
| 691 crlEntry->nssCrlEntry = nssCrlEntry; | |
| 692 crlEntry->serialNumber = NULL; | |
| 693 crlEntry->critExtOids = NULL; | |
| 694 crlEntry->userReasonCode = 0; | |
| 695 crlEntry->userReasonCodeAbsent = PKIX_FALSE; | |
| 696 | |
| 697 *pCrlEntry = crlEntry; | |
| 698 | |
| 699 cleanup: | |
| 700 | |
| 701 PKIX_RETURN(CRLENTRY); | |
| 702 } | |
| 703 | |
| 704 /* | |
| 705 * FUNCTION: pkix_pl_CRLEntry_Create | |
| 706 * DESCRIPTION: | |
| 707 * | |
| 708 * Creates a List of CRLEntries using the array of CERTCrlEntries pointed to | |
| 709 * by "nssCrlEntries" and stores it at "pCrlEntryList". If "nssCrlEntries" is | |
| 710 * NULL, this function stores an empty List at "pCrlEntryList". | |
| 711 * } | |
| 712 * PARAMETERS: | |
| 713 * "nssCrlEntries" | |
| 714 * Address of array of CERTCrlEntries representing NSS CRL entries. | |
| 715 * Can be NULL if CRL has no NSS CRL entries. | |
| 716 * "pCrlEntryList" | |
| 717 * Address where object pointer will be stored. Must be non-NULL. | |
| 718 * "plContext" | |
| 719 * Platform-specific context pointer. | |
| 720 * THREAD SAFETY: | |
| 721 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 722 * RETURNS: | |
| 723 * Returns NULL if the function succeeds. | |
| 724 * Returns a CRLEntry Error if the function fails in a non-fatal way. | |
| 725 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
| 726 */ | |
| 727 PKIX_Error * | |
| 728 pkix_pl_CRLEntry_Create( | |
| 729 CERTCrlEntry **nssCrlEntries, /* head of entry list */ | |
| 730 PKIX_List **pCrlEntryList, | |
| 731 void *plContext) | |
| 732 { | |
| 733 PKIX_List *entryList = NULL; | |
| 734 PKIX_PL_CRLEntry *crlEntry = NULL; | |
| 735 CERTCrlEntry **entries = NULL; | |
| 736 SECItem serialNumberItem; | |
| 737 PKIX_PL_BigInt *serialNumber; | |
| 738 char *bytes = NULL; | |
| 739 PKIX_UInt32 length; | |
| 740 | |
| 741 PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Create"); | |
| 742 PKIX_NULLCHECK_ONE(pCrlEntryList); | |
| 743 | |
| 744 entries = nssCrlEntries; | |
| 745 | |
| 746 PKIX_CHECK(PKIX_List_Create(&entryList, plContext), | |
| 747 PKIX_LISTCREATEFAILED); | |
| 748 | |
| 749 if (entries) { | |
| 750 while (*entries){ | |
| 751 PKIX_CHECK(pkix_pl_CRLEntry_CreateEntry | |
| 752 (*entries, &crlEntry, plContext), | |
| 753 PKIX_COULDNOTCREATECRLENTRYOBJECT); | |
| 754 | |
| 755 /* Get Serial Number */ | |
| 756 serialNumberItem = (*entries)->serialNumber; | |
| 757 length = serialNumberItem.len; | |
| 758 bytes = (char *)serialNumberItem.data; | |
| 759 | |
| 760 PKIX_CHECK(pkix_pl_BigInt_CreateWithBytes | |
| 761 (bytes, length, &serialNumber, plContext), | |
| 762 PKIX_BIGINTCREATEWITHBYTESFAILED); | |
| 763 | |
| 764 crlEntry->serialNumber = serialNumber; | |
| 765 crlEntry->nssCrlEntry = *entries; | |
| 766 | |
| 767 PKIX_CHECK(PKIX_List_AppendItem | |
| 768 (entryList, (PKIX_PL_Object *)crlEntry, plContext), | |
| 769 PKIX_LISTAPPENDITEMFAILED); | |
| 770 | |
| 771 PKIX_DECREF(crlEntry); | |
| 772 | |
| 773 entries++; | |
| 774 } | |
| 775 } | |
| 776 | |
| 777 *pCrlEntryList = entryList; | |
| 778 | |
| 779 cleanup: | |
| 780 PKIX_DECREF(crlEntry); | |
| 781 | |
| 782 if (PKIX_ERROR_RECEIVED){ | |
| 783 PKIX_DECREF(entryList); | |
| 784 } | |
| 785 | |
| 786 PKIX_RETURN(CRLENTRY); | |
| 787 } | |
| 788 | |
| 789 /* --Public-CRLENTRY-Functions------------------------------------- */ | |
| 790 | |
| 791 /* | |
| 792 * FUNCTION: PKIX_PL_CRLEntry_GetCRLEntryReasonCode | |
| 793 * (see comments in pkix_pl_pki.h) | |
| 794 */ | |
| 795 PKIX_Error * | |
| 796 PKIX_PL_CRLEntry_GetCRLEntryReasonCode ( | |
| 797 PKIX_PL_CRLEntry *crlEntry, | |
| 798 PKIX_Int32 *pReason, | |
| 799 void *plContext) | |
| 800 { | |
| 801 SECStatus status; | |
| 802 CERTCRLEntryReasonCode nssReasonCode; | |
| 803 | |
| 804 PKIX_ENTER(CRLENTRY, "PKIX_PL_CRLEntry_GetCRLEntryReasonCode"); | |
| 805 PKIX_NULLCHECK_TWO(crlEntry, pReason); | |
| 806 | |
| 807 if (!crlEntry->userReasonCodeAbsent && crlEntry->userReasonCode == 0) { | |
| 808 | |
| 809 PKIX_OBJECT_LOCK(crlEntry); | |
| 810 | |
| 811 if (!crlEntry->userReasonCodeAbsent && | |
| 812 crlEntry->userReasonCode == 0) { | |
| 813 | |
| 814 /* reason code has not been cached in */ | |
| 815 PKIX_CRLENTRY_DEBUG("\t\tCERT_FindCRLEntryReasonExten.\n"); | |
| 816 status = CERT_FindCRLEntryReasonExten | |
| 817 (crlEntry->nssCrlEntry, &nssReasonCode); | |
| 818 | |
| 819 if (status == SECSuccess) { | |
| 820 crlEntry->userReasonCode = (PKIX_Int32) nssReasonCode; | |
| 821 } else { | |
| 822 crlEntry->userReasonCodeAbsent = PKIX_TRUE; | |
| 823 } | |
| 824 } | |
| 825 | |
| 826 PKIX_OBJECT_UNLOCK(crlEntry); | |
| 827 | |
| 828 } | |
| 829 | |
| 830 *pReason = crlEntry->userReasonCode; | |
| 831 | |
| 832 cleanup: | |
| 833 | |
| 834 PKIX_RETURN(CRLENTRY); | |
| 835 } | |
| 836 | |
| 837 /* | |
| 838 * FUNCTION: PKIX_PL_CRLEntry_GetCriticalExtensionOIDs | |
| 839 * (see comments in pkix_pl_pki.h) | |
| 840 */ | |
| 841 PKIX_Error * | |
| 842 PKIX_PL_CRLEntry_GetCriticalExtensionOIDs ( | |
| 843 PKIX_PL_CRLEntry *crlEntry, | |
| 844 PKIX_List **pList, /* list of PKIX_PL_OID */ | |
| 845 void *plContext) | |
| 846 { | |
| 847 PKIX_List *oidsList = NULL; | |
| 848 CERTCertExtension **extensions; | |
| 849 | |
| 850 PKIX_ENTER(CRLENTRY, "PKIX_PL_CRLEntry_GetCriticalExtensionOIDs"); | |
| 851 PKIX_NULLCHECK_THREE(crlEntry, crlEntry->nssCrlEntry, pList); | |
| 852 | |
| 853 /* if we don't have a cached copy from before, we create one */ | |
| 854 if (crlEntry->critExtOids == NULL) { | |
| 855 | |
| 856 PKIX_OBJECT_LOCK(crlEntry); | |
| 857 | |
| 858 if (crlEntry->critExtOids == NULL) { | |
| 859 | |
| 860 extensions = crlEntry->nssCrlEntry->extensions; | |
| 861 | |
| 862 PKIX_CHECK(pkix_pl_OID_GetCriticalExtensionOIDs | |
| 863 (extensions, &oidsList, plContext), | |
| 864 PKIX_GETCRITICALEXTENSIONOIDSFAILED); | |
| 865 | |
| 866 crlEntry->critExtOids = oidsList; | |
| 867 } | |
| 868 | |
| 869 PKIX_OBJECT_UNLOCK(crlEntry); | |
| 870 | |
| 871 } | |
| 872 | |
| 873 /* We should return a copy of the List since this list changes */ | |
| 874 PKIX_DUPLICATE(crlEntry->critExtOids, pList, plContext, | |
| 875 PKIX_OBJECTDUPLICATELISTFAILED); | |
| 876 | |
| 877 cleanup: | |
| 878 | |
| 879 PKIX_RETURN(CRLENTRY); | |
| 880 } | |
| OLD | NEW |