~ubuntu-branches/ubuntu/quantal/nss/quantal-updates

« back to all changes in this revision

Viewing changes to nss/lib/libpkix/pkix/util/pkix_error.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2013-11-14 14:58:07 UTC
  • mfrom: (1.1.19)
  • Revision ID: package-import@ubuntu.com-20131114145807-vj6v4erz8xj6kwz3
Tags: 3.15.3-0ubuntu0.12.10.1
* SECURITY UPDATE: New upstream release to fix multiple security issues
  and add TLSv1.2 support.
  - CVE-2013-1739
  - CVE-2013-1741
  - CVE-2013-5605
  - CVE-2013-5606
* Adjusted packaging for 3.15.3:
  - debian/patches/*: refreshed.
  - debian/patches/lower-dhe-priority.patch: removed, no longer needed,
    was a workaround for an old version of firefox.
  - debian/libnss3.symbols: added new symbols.
  - debian/rules: updated for new source layout.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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)object;
 
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
}