security/nss/lib/libpkix/pkix/util/pkix_error.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.

     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  */
    11 #include "pkix_error.h"
    13 #undef PKIX_ERRORENTRY
    15 #define PKIX_ERRORENTRY(name,desc,nsserr) #desc
    17 #if defined PKIX_ERROR_DESCRIPTION
    19 const char * const PKIX_ErrorText[] =
    20 {
    21 #include "pkix_errorstrings.h"
    22 };
    24 #else
    26 #include "prprf.h"
    28 #endif /* PKIX_ERROR_DESCRIPTION */
    30 extern const PKIX_Int32 PKIX_PLErrorIndex[];
    32 /* --Private-Functions-------------------------------------------- */
    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;
    55         PKIX_ENTER(ERROR, "pkix_Error_Equals");
    56         PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
    58         unequalFlag = PKIX_FALSE;
    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         }
    69         PKIX_CHECK(pkix_CheckType(firstObject, PKIX_ERROR_TYPE, plContext),
    70                     PKIX_FIRSTOBJECTNOTANERROROBJECT);
    72         PKIX_CHECK(PKIX_PL_Object_GetType
    73                     (secondObject, &secondType, plContext),
    74                     PKIX_ERRORGETTINGSECONDOBJECTTYPE);
    76         /* If types differ, then return false. Result is already set */
    77         if (secondType != PKIX_ERROR_TYPE) goto cleanup;
    79         /* It is safe to cast to PKIX_Error */
    80         firstError = (PKIX_Error *) firstObject;
    81         secondError = (PKIX_Error *) secondObject;
    83         /* Compare error codes */
    84         firstClass = firstError->errClass;
    85         secondClass = secondError->errClass;
    87         /* If codes differ, return false. Result is already set */
    88         if (firstClass != secondClass) goto cleanup;
    90         /* Compare causes */
    91         firstCause = firstError->cause;
    92         secondCause = secondError->cause;
    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;
    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);
   107                 /* Set the unequalFlag so that we return after dec refing */
   108                 if (boolResult == 0) unequalFlag = PKIX_TRUE;
   109         }
   111         /* If the cause errors are not equal, return null */
   112         if (unequalFlag) goto cleanup;
   114         /* Compare info fields */
   115         firstInfo = firstError->info;
   116         secondInfo = secondError->info;
   118         if (firstInfo != secondInfo) goto cleanup;
   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;
   125         if ((firstInfo != NULL) && (secondInfo != NULL)) {
   127                 PKIX_CHECK(PKIX_PL_Object_Equals
   128                             ((PKIX_PL_Object*)firstInfo,
   129                             (PKIX_PL_Object*)secondInfo,
   130                             &boolResult,
   131                             plContext),
   132                             PKIX_ERRORINRECURSIVEEQUALSCALL);
   134                 /* Set the unequalFlag so that we return after dec refing */
   135                 if (boolResult == 0) unequalFlag = PKIX_TRUE;
   136         }
   138         /* If the infos are not equal, return null */
   139         if (unequalFlag) goto cleanup;
   142         /* Compare descs */
   143         if (firstError->errCode != secondError->errCode) {
   144                 unequalFlag = PKIX_TRUE;
   145         }
   147         if (firstError->plErr != secondError->plErr) {
   148                 unequalFlag = PKIX_TRUE;
   149         }
   151         /* If the unequalFlag was set, return false */
   152         if (unequalFlag) goto cleanup;
   154         /* Errors are equal in all fields at this point */
   155         *pResult = PKIX_TRUE;
   157 cleanup:
   159         PKIX_RETURN(ERROR);
   160 }
   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;
   173         PKIX_ENTER(ERROR, "pkix_Error_Destroy");
   174         PKIX_NULLCHECK_ONE(object);
   176         PKIX_CHECK(pkix_CheckType(object, PKIX_ERROR_TYPE, plContext),
   177                 PKIX_OBJECTNOTANERROR);
   179         error = (PKIX_Error *)object;
   181         PKIX_DECREF(error->cause);
   183         PKIX_DECREF(error->info);
   185 cleanup:
   187         PKIX_RETURN(ERROR);
   188 }
   191 /* XXX This is not thread safe */
   192 static PKIX_UInt32 pkix_error_cause_depth = 1;
   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;
   214         PKIX_ENTER(ERROR, "pkix_Error_ToString");
   215         PKIX_NULLCHECK_TWO(object, pString);
   217         PKIX_CHECK(pkix_CheckType(object, PKIX_ERROR_TYPE, plContext),
   218                 PKIX_OBJECTNOTANERROR);
   220         error = (PKIX_Error *)object;
   222         /* Get this error's errClass, description and the string of its cause */
   223         errClass = error->errClass;
   225         /* Get the description string */
   226         PKIX_Error_GetDescription(error, &desc, plContext);
   228         /* Get the cause */
   229         cause = error->cause;
   231         /* Get the causes's description string */
   232         if (cause != NULL) {
   233                 pkix_error_cause_depth++;
   235                 /* Get the cause string */
   236                 PKIX_CHECK(PKIX_PL_Object_ToString
   237                             ((PKIX_PL_Object*)cause, &causeString, plContext),
   238                             PKIX_ERRORGETTINGCAUSESTRING);
   240                 format = "\n*** Cause (%d): %s";
   242                 PKIX_CHECK(PKIX_PL_String_Create
   243                             (PKIX_ESCASCII,
   244                             format,
   245                             0,
   246                             &formatString,
   247                             plContext),
   248                             PKIX_STRINGCREATEFAILED);
   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);
   259                 PKIX_DECREF(formatString);
   261                 pkix_error_cause_depth--;
   262         }
   264         /* Create the Format String */
   265         if (optCauseString != NULL) {
   266                 format = "*** %s Error- %s%s";
   267         } else {
   268                 format = "*** %s Error- %s";
   269         }
   271         /* Ensure that error errClass is known, otherwise default to Object */
   272         if (errClass >= PKIX_NUMERRORCLASSES) {
   273                 errClass = 0;
   274         }
   276         PKIX_CHECK(PKIX_PL_String_Create
   277                     (PKIX_ESCASCII,
   278                     (void *)PKIX_ERRORCLASSNAMES[errClass],
   279                     0,
   280                     &errorNameString,
   281                     plContext),
   282                     PKIX_STRINGCREATEFAILED);
   284         PKIX_CHECK(PKIX_PL_String_Create
   285                     (PKIX_ESCASCII,
   286                     format,
   287                     0,
   288                     &formatString,
   289                     plContext),
   290                     PKIX_STRINGCREATEFAILED);
   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);
   302 cleanup:
   304         PKIX_DECREF(desc);
   305         PKIX_DECREF(causeString);
   306         PKIX_DECREF(formatString);
   307         PKIX_DECREF(optCauseString);
   308         PKIX_DECREF(errorNameString);
   310         PKIX_RETURN(ERROR);
   311 }
   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);
   326         /* XXX Unimplemented */
   327         /* XXX Need to make hashcodes equal when two errors are equal */
   328         *pResult = (PKIX_UInt32)object;
   330         PKIX_RETURN(ERROR);
   331 }
   333 /* --Initializers------------------------------------------------- */
   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
   350 const char *
   351 PKIX_ERRORCLASSNAMES[PKIX_NUMERRORCLASSES] =
   352 {
   353     PKIX_ERRORCLASSES
   354 };
   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;
   373         PKIX_ENTER(ERROR, "pkix_Error_RegisterSelf");
   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;
   385         systemClasses[PKIX_ERROR_TYPE] = entry;
   387         PKIX_RETURN(ERROR);
   388 }
   390 /* --Public-Functions--------------------------------------------- */
   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;
   407         PKIX_ENTER(ERROR, "PKIX_Error_Create");
   409         PKIX_NULLCHECK_ONE(pError);
   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);
   421         if (pkixErrorResult) return (pkixErrorResult);
   423         error->errClass = errClass;
   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         }
   435         PKIX_INCREF(cause);
   436         error->cause = cause;
   438         PKIX_INCREF(info);
   439         error->info = info;
   441         error->errCode = errCode;
   443         error->plErr = PKIX_PLErrorIndex[error->errCode];
   445         *pError = error;
   446         error = NULL;
   448 cleanup:
   449         /* PKIX-XXX Fix for leak during error creation */
   450         PKIX_DECREF(error);
   452         PKIX_RETURN(ERROR);
   453 }
   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);
   467         *pClass = error->errClass;
   469         PKIX_RETURN(ERROR);
   470 }
   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);
   484         *pCode = error->errCode;
   486         PKIX_RETURN(ERROR);
   487 }
   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);
   501         if (error->cause != PKIX_ALLOC_ERROR()){
   502                 PKIX_INCREF(error->cause);
   503         }
   505         *pCause = error->cause;
   507 cleanup:
   508         PKIX_RETURN(ERROR);
   509 }
   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);
   523         PKIX_INCREF(error->info);
   525         *pInfo = error->info;
   527 cleanup:
   528         PKIX_RETURN(ERROR);
   529 }
   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
   545         PKIX_ENTER(ERROR, "PKIX_Error_GetDescription");
   546         PKIX_NULLCHECK_TWO(error, pDesc);
   548 #ifndef PKIX_ERROR_DESCRIPTION
   549         PR_snprintf(errorStr, 32, "Error code: %d", error->errCode);
   550 #endif
   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);
   562         *pDesc = descString;
   564         PKIX_RETURN(ERROR);
   565 }

mercurial