| 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_error.c | |
| 6 * | |
| 7 * Error Object Functions | |
| 8 * | |
| 9 */ | |
| 10 | |
| 11 #include "pkix_error.h" | |
| 12 | |
| 13 #undef PKIX_ERRORENTRY | |
| 14 | |
| 15 #define PKIX_ERRORENTRY(name,desc,nsserr) #desc | |
| 16 | |
| 17 #if defined PKIX_ERROR_DESCRIPTION | |
| 18 | |
| 19 const char * const PKIX_ErrorText[] = | |
| 20 { | |
| 21 #include "pkix_errorstrings.h" | |
| 22 }; | |
| 23 | |
| 24 #else | |
| 25 | |
| 26 #include "prprf.h" | |
| 27 | |
| 28 #endif /* PKIX_ERROR_DESCRIPTION */ | |
| 29 | |
| 30 extern const PKIX_Int32 PKIX_PLErrorIndex[]; | |
| 31 | |
| 32 /* --Private-Functions-------------------------------------------- */ | |
| 33 | |
| 34 /* | |
| 35 * FUNCTION: pkix_Error_Equals | |
| 36 * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h) | |
| 37 */ | |
| 38 static PKIX_Error * | |
| 39 pkix_Error_Equals( | |
| 40 PKIX_PL_Object *firstObject, | |
| 41 PKIX_PL_Object *secondObject, | |
| 42 PKIX_Boolean *pResult, | |
| 43 void *plContext) | |
| 44 { | |
| 45 PKIX_Error *firstError = NULL; | |
| 46 PKIX_Error *secondError = NULL; | |
| 47 PKIX_Error *firstCause = NULL; | |
| 48 PKIX_Error *secondCause = NULL; | |
| 49 PKIX_PL_Object *firstInfo = NULL; | |
| 50 PKIX_PL_Object *secondInfo = NULL; | |
| 51 PKIX_ERRORCLASS firstClass, secondClass; | |
| 52 PKIX_UInt32 secondType; | |
| 53 PKIX_Boolean boolResult, unequalFlag; | |
| 54 | |
| 55 PKIX_ENTER(ERROR, "pkix_Error_Equals"); | |
| 56 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult); | |
| 57 | |
| 58 unequalFlag = PKIX_FALSE; | |
| 59 | |
| 60 /* First just compare pointer values to save time */ | |
| 61 if (firstObject == secondObject) { | |
| 62 *pResult = PKIX_TRUE; | |
| 63 goto cleanup; | |
| 64 } else { | |
| 65 /* Result will only be set to true if all tests pass */ | |
| 66 *pResult = PKIX_FALSE; | |
| 67 } | |
| 68 | |
| 69 PKIX_CHECK(pkix_CheckType(firstObject, PKIX_ERROR_TYPE, plContext), | |
| 70 PKIX_FIRSTOBJECTNOTANERROROBJECT); | |
| 71 | |
| 72 PKIX_CHECK(PKIX_PL_Object_GetType | |
| 73 (secondObject, &secondType, plContext), | |
| 74 PKIX_ERRORGETTINGSECONDOBJECTTYPE); | |
| 75 | |
| 76 /* If types differ, then return false. Result is already set */ | |
| 77 if (secondType != PKIX_ERROR_TYPE) goto cleanup; | |
| 78 | |
| 79 /* It is safe to cast to PKIX_Error */ | |
| 80 firstError = (PKIX_Error *) firstObject; | |
| 81 secondError = (PKIX_Error *) secondObject; | |
| 82 | |
| 83 /* Compare error codes */ | |
| 84 firstClass = firstError->errClass; | |
| 85 secondClass = secondError->errClass; | |
| 86 | |
| 87 /* If codes differ, return false. Result is already set */ | |
| 88 if (firstClass != secondClass) goto cleanup; | |
| 89 | |
| 90 /* Compare causes */ | |
| 91 firstCause = firstError->cause; | |
| 92 secondCause = secondError->cause; | |
| 93 | |
| 94 /* Ensure that either both or none of the causes are NULL */ | |
| 95 if (((firstCause != NULL) && (secondCause == NULL))|| | |
| 96 ((firstCause == NULL) && (secondCause != NULL))) | |
| 97 unequalFlag = PKIX_TRUE; | |
| 98 | |
| 99 if ((firstCause != NULL) && (secondCause != NULL)) { | |
| 100 PKIX_CHECK(PKIX_PL_Object_Equals | |
| 101 ((PKIX_PL_Object*)firstCause, | |
| 102 (PKIX_PL_Object*)secondCause, | |
| 103 &boolResult, | |
| 104 plContext), | |
| 105 PKIX_ERRORINRECURSIVEEQUALSCALL); | |
| 106 | |
| 107 /* Set the unequalFlag so that we return after dec refing */ | |
| 108 if (boolResult == 0) unequalFlag = PKIX_TRUE; | |
| 109 } | |
| 110 | |
| 111 /* If the cause errors are not equal, return null */ | |
| 112 if (unequalFlag) goto cleanup; | |
| 113 | |
| 114 /* Compare info fields */ | |
| 115 firstInfo = firstError->info; | |
| 116 secondInfo = secondError->info; | |
| 117 | |
| 118 if (firstInfo != secondInfo) goto cleanup; | |
| 119 | |
| 120 /* Ensure that either both or none of the infos are NULL */ | |
| 121 if (((firstInfo != NULL) && (secondInfo == NULL))|| | |
| 122 ((firstInfo == NULL) && (secondInfo != NULL))) | |
| 123 unequalFlag = PKIX_TRUE; | |
| 124 | |
| 125 if ((firstInfo != NULL) && (secondInfo != NULL)) { | |
| 126 | |
| 127 PKIX_CHECK(PKIX_PL_Object_Equals | |
| 128 ((PKIX_PL_Object*)firstInfo, | |
| 129 (PKIX_PL_Object*)secondInfo, | |
| 130 &boolResult, | |
| 131 plContext), | |
| 132 PKIX_ERRORINRECURSIVEEQUALSCALL); | |
| 133 | |
| 134 /* Set the unequalFlag so that we return after dec refing */ | |
| 135 if (boolResult == 0) unequalFlag = PKIX_TRUE; | |
| 136 } | |
| 137 | |
| 138 /* If the infos are not equal, return null */ | |
| 139 if (unequalFlag) goto cleanup; | |
| 140 | |
| 141 | |
| 142 /* Compare descs */ | |
| 143 if (firstError->errCode != secondError->errCode) { | |
| 144 unequalFlag = PKIX_TRUE; | |
| 145 } | |
| 146 | |
| 147 if (firstError->plErr != secondError->plErr) { | |
| 148 unequalFlag = PKIX_TRUE; | |
| 149 } | |
| 150 | |
| 151 /* If the unequalFlag was set, return false */ | |
| 152 if (unequalFlag) goto cleanup; | |
| 153 | |
| 154 /* Errors are equal in all fields at this point */ | |
| 155 *pResult = PKIX_TRUE; | |
| 156 | |
| 157 cleanup: | |
| 158 | |
| 159 PKIX_RETURN(ERROR); | |
| 160 } | |
| 161 | |
| 162 /* | |
| 163 * FUNCTION: pkix_Error_Destroy | |
| 164 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) | |
| 165 */ | |
| 166 static PKIX_Error * | |
| 167 pkix_Error_Destroy( | |
| 168 PKIX_PL_Object *object, | |
| 169 void *plContext) | |
| 170 { | |
| 171 PKIX_Error *error = NULL; | |
| 172 | |
| 173 PKIX_ENTER(ERROR, "pkix_Error_Destroy"); | |
| 174 PKIX_NULLCHECK_ONE(object); | |
| 175 | |
| 176 PKIX_CHECK(pkix_CheckType(object, PKIX_ERROR_TYPE, plContext), | |
| 177 PKIX_OBJECTNOTANERROR); | |
| 178 | |
| 179 error = (PKIX_Error *)object; | |
| 180 | |
| 181 PKIX_DECREF(error->cause); | |
| 182 | |
| 183 PKIX_DECREF(error->info); | |
| 184 | |
| 185 cleanup: | |
| 186 | |
| 187 PKIX_RETURN(ERROR); | |
| 188 } | |
| 189 | |
| 190 | |
| 191 /* XXX This is not thread safe */ | |
| 192 static PKIX_UInt32 pkix_error_cause_depth = 1; | |
| 193 | |
| 194 /* | |
| 195 * FUNCTION: pkix_Error_ToString | |
| 196 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) | |
| 197 */ | |
| 198 static PKIX_Error * | |
| 199 pkix_Error_ToString( | |
| 200 PKIX_PL_Object *object, | |
| 201 PKIX_PL_String **pString, | |
| 202 void *plContext) | |
| 203 { | |
| 204 PKIX_Error *error = NULL; | |
| 205 PKIX_Error *cause = NULL; | |
| 206 PKIX_PL_String *desc = NULL; | |
| 207 PKIX_PL_String *formatString = NULL; | |
| 208 PKIX_PL_String *causeString = NULL; | |
| 209 PKIX_PL_String *optCauseString = NULL; | |
| 210 PKIX_PL_String *errorNameString = NULL; | |
| 211 char *format = NULL; | |
| 212 PKIX_ERRORCLASS errClass; | |
| 213 | |
| 214 PKIX_ENTER(ERROR, "pkix_Error_ToString"); | |
| 215 PKIX_NULLCHECK_TWO(object, pString); | |
| 216 | |
| 217 PKIX_CHECK(pkix_CheckType(object, PKIX_ERROR_TYPE, plContext), | |
| 218 PKIX_OBJECTNOTANERROR); | |
| 219 | |
| 220 error = (PKIX_Error *)object; | |
| 221 | |
| 222 /* Get this error's errClass, description and the string of its cause */ | |
| 223 errClass = error->errClass; | |
| 224 | |
| 225 /* Get the description string */ | |
| 226 PKIX_Error_GetDescription(error, &desc, plContext); | |
| 227 | |
| 228 /* Get the cause */ | |
| 229 cause = error->cause; | |
| 230 | |
| 231 /* Get the causes's description string */ | |
| 232 if (cause != NULL) { | |
| 233 pkix_error_cause_depth++; | |
| 234 | |
| 235 /* Get the cause string */ | |
| 236 PKIX_CHECK(PKIX_PL_Object_ToString | |
| 237 ((PKIX_PL_Object*)cause, &causeString, plContext), | |
| 238 PKIX_ERRORGETTINGCAUSESTRING); | |
| 239 | |
| 240 format = "\n*** Cause (%d): %s"; | |
| 241 | |
| 242 PKIX_CHECK(PKIX_PL_String_Create | |
| 243 (PKIX_ESCASCII, | |
| 244 format, | |
| 245 0, | |
| 246 &formatString, | |
| 247 plContext), | |
| 248 PKIX_STRINGCREATEFAILED); | |
| 249 | |
| 250 /* Create the optional Cause String */ | |
| 251 PKIX_CHECK(PKIX_PL_Sprintf | |
| 252 (&optCauseString, | |
| 253 plContext, | |
| 254 formatString, | |
| 255 pkix_error_cause_depth, | |
| 256 causeString), | |
| 257 PKIX_SPRINTFFAILED); | |
| 258 | |
| 259 PKIX_DECREF(formatString); | |
| 260 | |
| 261 pkix_error_cause_depth--; | |
| 262 } | |
| 263 | |
| 264 /* Create the Format String */ | |
| 265 if (optCauseString != NULL) { | |
| 266 format = "*** %s Error- %s%s"; | |
| 267 } else { | |
| 268 format = "*** %s Error- %s"; | |
| 269 } | |
| 270 | |
| 271 /* Ensure that error errClass is known, otherwise default to Object */ | |
| 272 if (errClass >= PKIX_NUMERRORCLASSES) { | |
| 273 errClass = 0; | |
| 274 } | |
| 275 | |
| 276 PKIX_CHECK(PKIX_PL_String_Create | |
| 277 (PKIX_ESCASCII, | |
| 278 (void *)PKIX_ERRORCLASSNAMES[errClass], | |
| 279 0, | |
| 280 &errorNameString, | |
| 281 plContext), | |
| 282 PKIX_STRINGCREATEFAILED); | |
| 283 | |
| 284 PKIX_CHECK(PKIX_PL_String_Create | |
| 285 (PKIX_ESCASCII, | |
| 286 format, | |
| 287 0, | |
| 288 &formatString, | |
| 289 plContext), | |
| 290 PKIX_STRINGCREATEFAILED); | |
| 291 | |
| 292 /* Create the output String */ | |
| 293 PKIX_CHECK(PKIX_PL_Sprintf | |
| 294 (pString, | |
| 295 plContext, | |
| 296 formatString, | |
| 297 errorNameString, | |
| 298 desc, | |
| 299 optCauseString), | |
| 300 PKIX_SPRINTFFAILED); | |
| 301 | |
| 302 cleanup: | |
| 303 | |
| 304 PKIX_DECREF(desc); | |
| 305 PKIX_DECREF(causeString); | |
| 306 PKIX_DECREF(formatString); | |
| 307 PKIX_DECREF(optCauseString); | |
| 308 PKIX_DECREF(errorNameString); | |
| 309 | |
| 310 PKIX_RETURN(ERROR); | |
| 311 } | |
| 312 | |
| 313 /* | |
| 314 * FUNCTION: pkix_Error_Hashcode | |
| 315 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) | |
| 316 */ | |
| 317 static PKIX_Error * | |
| 318 pkix_Error_Hashcode( | |
| 319 PKIX_PL_Object *object, | |
| 320 PKIX_UInt32 *pResult, | |
| 321 void *plContext) | |
| 322 { | |
| 323 PKIX_ENTER(ERROR, "pkix_Error_Hashcode"); | |
| 324 PKIX_NULLCHECK_TWO(object, pResult); | |
| 325 | |
| 326 /* XXX Unimplemented */ | |
| 327 /* XXX Need to make hashcodes equal when two errors are equal */ | |
| 328 *pResult = (PKIX_UInt32)((char *)object - (char *)NULL); | |
| 329 | |
| 330 PKIX_RETURN(ERROR); | |
| 331 } | |
| 332 | |
| 333 /* --Initializers------------------------------------------------- */ | |
| 334 | |
| 335 /* | |
| 336 * PKIX_ERRORCLASSNAMES is an array of strings, with each string holding a | |
| 337 * descriptive name for an error errClass. This is used by the default | |
| 338 * PKIX_PL_Error_ToString function. | |
| 339 * | |
| 340 * Note: PKIX_ERRORCLASSES is defined in pkixt.h as a list of error types. | |
| 341 * (More precisely, as a list of invocations of ERRMACRO(type).) The | |
| 342 * macro is expanded in pkixt.h to define error numbers, and here to | |
| 343 * provide corresponding strings. For example, since the fifth ERRMACRO | |
| 344 * entry is MUTEX, then PKIX_MUTEX_ERROR is defined in pkixt.h as 4, and | |
| 345 * PKIX_ERRORCLASSNAMES[4] is initialized here with the value "MUTEX". | |
| 346 */ | |
| 347 #undef ERRMACRO | |
| 348 #define ERRMACRO(type) #type | |
| 349 | |
| 350 const char * | |
| 351 PKIX_ERRORCLASSNAMES[PKIX_NUMERRORCLASSES] = | |
| 352 { | |
| 353 PKIX_ERRORCLASSES | |
| 354 }; | |
| 355 | |
| 356 /* | |
| 357 * FUNCTION: pkix_Error_RegisterSelf | |
| 358 * DESCRIPTION: | |
| 359 * Registers PKIX_ERROR_TYPE and its related functions with systemClasses[] | |
| 360 * THREAD SAFETY: | |
| 361 * Not Thread Safe - for performance and complexity reasons | |
| 362 * | |
| 363 * Since this function is only called by PKIX_PL_Initialize, which should | |
| 364 * only be called once, it is acceptable that this function is not | |
| 365 * thread-safe. | |
| 366 */ | |
| 367 PKIX_Error * | |
| 368 pkix_Error_RegisterSelf(void *plContext) | |
| 369 { | |
| 370 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; | |
| 371 pkix_ClassTable_Entry entry; | |
| 372 | |
| 373 PKIX_ENTER(ERROR, "pkix_Error_RegisterSelf"); | |
| 374 | |
| 375 entry.description = "Error"; | |
| 376 entry.objCounter = 0; | |
| 377 entry.typeObjectSize = sizeof(PKIX_Error); | |
| 378 entry.destructor = pkix_Error_Destroy; | |
| 379 entry.equalsFunction = pkix_Error_Equals; | |
| 380 entry.hashcodeFunction = pkix_Error_Hashcode; | |
| 381 entry.toStringFunction = pkix_Error_ToString; | |
| 382 entry.comparator = NULL; | |
| 383 entry.duplicateFunction = pkix_duplicateImmutable; | |
| 384 | |
| 385 systemClasses[PKIX_ERROR_TYPE] = entry; | |
| 386 | |
| 387 PKIX_RETURN(ERROR); | |
| 388 } | |
| 389 | |
| 390 /* --Public-Functions--------------------------------------------- */ | |
| 391 | |
| 392 /* | |
| 393 * FUNCTION: PKIX_Error_Create (see comments in pkix_util.h) | |
| 394 */ | |
| 395 PKIX_Error * | |
| 396 PKIX_Error_Create( | |
| 397 PKIX_ERRORCLASS errClass, | |
| 398 PKIX_Error *cause, | |
| 399 PKIX_PL_Object *info, | |
| 400 PKIX_ERRORCODE errCode, | |
| 401 PKIX_Error **pError, | |
| 402 void *plContext) | |
| 403 { | |
| 404 PKIX_Error *tempCause = NULL; | |
| 405 PKIX_Error *error = NULL; | |
| 406 | |
| 407 PKIX_ENTER(ERROR, "PKIX_Error_Create"); | |
| 408 | |
| 409 PKIX_NULLCHECK_ONE(pError); | |
| 410 | |
| 411 /* | |
| 412 * when called here, if PKIX_PL_Object_Alloc returns an error, | |
| 413 * it must be a PKIX_ALLOC_ERROR | |
| 414 */ | |
| 415 pkixErrorResult = PKIX_PL_Object_Alloc | |
| 416 (PKIX_ERROR_TYPE, | |
| 417 ((PKIX_UInt32)(sizeof (PKIX_Error))), | |
| 418 (PKIX_PL_Object **)&error, | |
| 419 plContext); | |
| 420 | |
| 421 if (pkixErrorResult) return (pkixErrorResult); | |
| 422 | |
| 423 error->errClass = errClass; | |
| 424 | |
| 425 /* Ensure we don't have a loop. Follow causes until NULL */ | |
| 426 for (tempCause = cause; | |
| 427 tempCause != NULL; | |
| 428 tempCause = tempCause->cause) { | |
| 429 /* If we detect a loop, throw a new error */ | |
| 430 if (tempCause == error) { | |
| 431 PKIX_ERROR(PKIX_LOOPOFERRORCAUSEDETECTED); | |
| 432 } | |
| 433 } | |
| 434 | |
| 435 PKIX_INCREF(cause); | |
| 436 error->cause = cause; | |
| 437 | |
| 438 PKIX_INCREF(info); | |
| 439 error->info = info; | |
| 440 | |
| 441 error->errCode = errCode; | |
| 442 | |
| 443 error->plErr = PKIX_PLErrorIndex[error->errCode]; | |
| 444 | |
| 445 *pError = error; | |
| 446 error = NULL; | |
| 447 | |
| 448 cleanup: | |
| 449 /* PKIX-XXX Fix for leak during error creation */ | |
| 450 PKIX_DECREF(error); | |
| 451 | |
| 452 PKIX_RETURN(ERROR); | |
| 453 } | |
| 454 | |
| 455 /* | |
| 456 * FUNCTION: PKIX_Error_GetErrorClass (see comments in pkix_util.h) | |
| 457 */ | |
| 458 PKIX_Error * | |
| 459 PKIX_Error_GetErrorClass( | |
| 460 PKIX_Error *error, | |
| 461 PKIX_ERRORCLASS *pClass, | |
| 462 void *plContext) | |
| 463 { | |
| 464 PKIX_ENTER(ERROR, "PKIX_Error_GetErrorClass"); | |
| 465 PKIX_NULLCHECK_TWO(error, pClass); | |
| 466 | |
| 467 *pClass = error->errClass; | |
| 468 | |
| 469 PKIX_RETURN(ERROR); | |
| 470 } | |
| 471 | |
| 472 /* | |
| 473 * FUNCTION: PKIX_Error_GetErrorCode (see comments in pkix_util.h) | |
| 474 */ | |
| 475 PKIX_Error * | |
| 476 PKIX_Error_GetErrorCode( | |
| 477 PKIX_Error *error, | |
| 478 PKIX_ERRORCODE *pCode, | |
| 479 void *plContext) | |
| 480 { | |
| 481 PKIX_ENTER(ERROR, "PKIX_Error_GetErrorCode"); | |
| 482 PKIX_NULLCHECK_TWO(error, pCode); | |
| 483 | |
| 484 *pCode = error->errCode; | |
| 485 | |
| 486 PKIX_RETURN(ERROR); | |
| 487 } | |
| 488 | |
| 489 /* | |
| 490 * FUNCTION: PKIX_Error_GetCause (see comments in pkix_util.h) | |
| 491 */ | |
| 492 PKIX_Error * | |
| 493 PKIX_Error_GetCause( | |
| 494 PKIX_Error *error, | |
| 495 PKIX_Error **pCause, | |
| 496 void *plContext) | |
| 497 { | |
| 498 PKIX_ENTER(ERROR, "PKIX_Error_GetCause"); | |
| 499 PKIX_NULLCHECK_TWO(error, pCause); | |
| 500 | |
| 501 if (error->cause != PKIX_ALLOC_ERROR()){ | |
| 502 PKIX_INCREF(error->cause); | |
| 503 } | |
| 504 | |
| 505 *pCause = error->cause; | |
| 506 | |
| 507 cleanup: | |
| 508 PKIX_RETURN(ERROR); | |
| 509 } | |
| 510 | |
| 511 /* | |
| 512 * FUNCTION: PKIX_Error_GetSupplementaryInfo (see comments in pkix_util.h) | |
| 513 */ | |
| 514 PKIX_Error * | |
| 515 PKIX_Error_GetSupplementaryInfo( | |
| 516 PKIX_Error *error, | |
| 517 PKIX_PL_Object **pInfo, | |
| 518 void *plContext) | |
| 519 { | |
| 520 PKIX_ENTER(ERROR, "PKIX_Error_GetSupplementaryInfo"); | |
| 521 PKIX_NULLCHECK_TWO(error, pInfo); | |
| 522 | |
| 523 PKIX_INCREF(error->info); | |
| 524 | |
| 525 *pInfo = error->info; | |
| 526 | |
| 527 cleanup: | |
| 528 PKIX_RETURN(ERROR); | |
| 529 } | |
| 530 | |
| 531 /* | |
| 532 * FUNCTION: PKIX_Error_GetDescription (see comments in pkix_util.h) | |
| 533 */ | |
| 534 PKIX_Error * | |
| 535 PKIX_Error_GetDescription( | |
| 536 PKIX_Error *error, | |
| 537 PKIX_PL_String **pDesc, | |
| 538 void *plContext) | |
| 539 { | |
| 540 PKIX_PL_String *descString = NULL; | |
| 541 #ifndef PKIX_ERROR_DESCRIPTION | |
| 542 char errorStr[32]; | |
| 543 #endif | |
| 544 | |
| 545 PKIX_ENTER(ERROR, "PKIX_Error_GetDescription"); | |
| 546 PKIX_NULLCHECK_TWO(error, pDesc); | |
| 547 | |
| 548 #ifndef PKIX_ERROR_DESCRIPTION | |
| 549 PR_snprintf(errorStr, 32, "Error code: %d", error->errCode); | |
| 550 #endif | |
| 551 | |
| 552 PKIX_PL_String_Create(PKIX_ESCASCII, | |
| 553 #if defined PKIX_ERROR_DESCRIPTION | |
| 554 (void *)PKIX_ErrorText[error->errCode], | |
| 555 #else | |
| 556 errorStr, | |
| 557 #endif | |
| 558 0, | |
| 559 &descString, | |
| 560 plContext); | |
| 561 | |
| 562 *pDesc = descString; | |
| 563 | |
| 564 PKIX_RETURN(ERROR); | |
| 565 } | |
| OLD | NEW |