~ubuntu-branches/ubuntu/raring/nss/raring-security

« back to all changes in this revision

Viewing changes to mozilla/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_oid.c

  • Committer: Bazaar Package Importer
  • Author(s): Chris Coulson
  • Date: 2010-03-25 13:46:06 UTC
  • mfrom: (1.1.11 upstream)
  • Revision ID: james.westby@ubuntu.com-20100325134606-bl6liuok2w9l7snv
Tags: 3.12.6-0ubuntu1
* New upstream release 3.12.6 RTM (NSS_3_12_6_RTM)
  - fixes CVE-2009-3555 aka US-CERT VU#120541
* Adjust patches to changed upstream code base
  - update debian/patches/38_kbsd.patch
  - update debian/patches/38_mips64_build.patch
  - update debian/patches/85_security_load.patch
* Remove patches that are merged upstream
  - delete debian/patches/91_nonexec_stack.patch
  - update debian/patches/series
* Bump nspr dependency to 4.8
  - update debian/control
* Add new symbols for 3.12.6
  - update debian/libnss3-1d.symbols

Show diffs side-by-side

added added

removed removed

Lines of Context:
45
45
 
46
46
/* --Private-OID-Functions---------------------------------------- */
47
47
 
48
 
/*
 
48
 /*
49
49
 * FUNCTION: pkix_pl_OID_Comparator
50
50
 * (see comments for PKIX_PL_ComparatorCallback in pkix_pl_system.h)
51
51
 */
53
53
pkix_pl_OID_Comparator(
54
54
        PKIX_PL_Object *firstObject,
55
55
        PKIX_PL_Object *secondObject,
56
 
        PKIX_Int32 *pResult,
 
56
        PKIX_Int32 *pRes,
57
57
        void *plContext)
58
58
{
59
59
        PKIX_PL_OID *firstOID = NULL;
60
60
        PKIX_PL_OID *secondOID = NULL;
61
 
        PKIX_UInt32 minLength;
62
61
 
63
62
        PKIX_ENTER(OID, "pkix_pl_OID_Comparator");
64
 
        PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
 
63
        PKIX_NULLCHECK_THREE(firstObject, secondObject, pRes);
65
64
 
66
65
        PKIX_CHECK(pkix_CheckTypes
67
66
                    (firstObject, secondObject, PKIX_OID_TYPE, plContext),
70
69
        firstOID = (PKIX_PL_OID*)firstObject;
71
70
        secondOID = (PKIX_PL_OID*)secondObject;
72
71
 
73
 
        *pResult = 0;
74
 
 
75
 
        minLength = (firstOID->length < secondOID->length)?
76
 
                firstOID->length:
77
 
                secondOID->length;
78
 
 
79
 
        /* Check if both array contents are identical */
80
 
        PKIX_OID_DEBUG("\tCalling PORT_Memcmp).\n");
81
 
        *pResult = PORT_Memcmp
82
 
                (firstOID->components,
83
 
                secondOID->components,
84
 
                minLength * sizeof (PKIX_UInt32));
85
 
 
 
72
        *pRes = (PKIX_Int32)SECITEM_CompareItem(&firstOID->derOid,
 
73
                                                &secondOID->derOid);
86
74
cleanup:
87
75
        PKIX_RETURN(OID);
88
76
}
103
91
 
104
92
        PKIX_CHECK(pkix_CheckType(object, PKIX_OID_TYPE, plContext),
105
93
                    PKIX_OBJECTNOTANOID);
106
 
 
107
94
        oid = (PKIX_PL_OID*)object;
108
 
 
109
 
        PKIX_FREE(oid->components);
110
 
        oid->length = 0;
 
95
        SECITEM_FreeItem(&oid->derOid, PR_FALSE);
111
96
 
112
97
cleanup:
113
 
 
114
98
        PKIX_RETURN(OID);
115
99
}
116
100
 
124
108
        PKIX_UInt32 *pHashcode,
125
109
        void *plContext)
126
110
{
127
 
        PKIX_PL_OID *pkixOID = NULL;
 
111
        PKIX_PL_OID *oid = NULL;
128
112
 
129
113
        PKIX_ENTER(OID, "pkix_pl_OID_HashCode");
130
114
        PKIX_NULLCHECK_TWO(object, pHashcode);
132
116
        PKIX_CHECK(pkix_CheckType(object, PKIX_OID_TYPE, plContext),
133
117
                    PKIX_OBJECTNOTANOID);
134
118
 
135
 
        pkixOID = (PKIX_PL_OID *)object;
 
119
        oid = (PKIX_PL_OID *)object;
136
120
 
137
121
        PKIX_CHECK(pkix_hash
138
 
                    ((unsigned char *)pkixOID->components,
139
 
                    pkixOID->length * sizeof (PKIX_UInt32),
 
122
                    ((unsigned char *)oid->derOid.data,
 
123
                    oid->derOid.len * sizeof (char),
140
124
                    pHashcode,
141
125
                    plContext),
142
126
                    PKIX_HASHFAILED);
157
141
        void *plContext)
158
142
{
159
143
        PKIX_UInt32 secondType;
160
 
        PKIX_Int32 cmpResult;
 
144
        SECComparison cmpResult;
161
145
 
162
146
        PKIX_ENTER(OID, "pkix_pl_OID_Equals");
163
147
        PKIX_NULLCHECK_THREE(first, second, pResult);
174
158
         * Do a quick check that the second object is an OID.
175
159
         * If so, check that their lengths are equal.
176
160
         */
177
 
        if ((secondType != PKIX_OID_TYPE)||
178
 
            (((PKIX_PL_OID*)first)->length !=
179
 
            ((PKIX_PL_OID*)second)->length)) {
 
161
        if (secondType != PKIX_OID_TYPE) {
180
162
                goto cleanup;
181
163
        }
182
164
 
184
166
                    (first, second, &cmpResult, plContext),
185
167
                    PKIX_OIDCOMPARATORFAILED);
186
168
 
187
 
        *pResult = (cmpResult == 0);
188
 
 
 
169
        *pResult = (cmpResult == SECEqual);
189
170
cleanup:
190
171
 
191
172
        PKIX_RETURN(OID);
194
175
/*
195
176
 * FUNCTION: pkix_pl_OID_ToString
196
177
 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
 
178
 * Use this function only for printing OIDs and not to make any
 
179
 * critical security decision.
197
180
 */
198
181
static PKIX_Error *
199
182
pkix_pl_OID_ToString(
201
184
        PKIX_PL_String **pString,
202
185
        void *plContext)
203
186
{
204
 
        PKIX_UInt32 *components = NULL;
205
 
        PKIX_UInt32 length;
206
 
        char *ascii = NULL;
 
187
        PKIX_PL_OID *oid = NULL;
 
188
        char *oidString = NULL;
207
189
 
208
190
        PKIX_ENTER(OID, "pkix_pl_OID_toString");
209
191
        PKIX_NULLCHECK_TWO(object, pString);
210
192
 
211
193
        PKIX_CHECK(pkix_CheckType(object, PKIX_OID_TYPE, plContext),
212
194
                    PKIX_OBJECTNOTANOID);
213
 
 
214
 
        components = ((PKIX_PL_OID*)object)->components;
215
 
        length = ((PKIX_PL_OID*)object)->length;
216
 
 
217
 
        PKIX_CHECK(pkix_pl_helperBytes2Ascii
218
 
                    (components, length, &ascii, plContext),
219
 
                    PKIX_HELPERBYTES2ASCIIFAILED);
220
 
 
 
195
        oid = (PKIX_PL_OID*)object;
 
196
        oidString = CERT_GetOidString(&oid->derOid);
 
197
        
221
198
        PKIX_CHECK(PKIX_PL_String_Create
222
 
                (PKIX_ESCASCII, ascii, 0, pString, plContext),
 
199
                (PKIX_ESCASCII, oidString , 0, pString, plContext),
223
200
                PKIX_STRINGCREATEFAILED);
224
 
 
225
201
cleanup:
226
 
 
227
 
        PKIX_FREE(ascii);
228
 
 
 
202
        PR_smprintf_free(oidString);
 
203
        
229
204
        PKIX_RETURN(OID);
230
205
}
231
206
 
244
219
pkix_pl_OID_RegisterSelf(
245
220
        void *plContext)
246
221
{
247
 
 
248
222
        extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
249
 
        pkix_ClassTable_Entry entry;
 
223
        pkix_ClassTable_Entry *entry = &systemClasses[PKIX_OID_TYPE];
250
224
 
251
225
        PKIX_ENTER(OID, "pkix_pl_OID_RegisterSelf");
252
226
 
253
 
        entry.description = "OID";
254
 
        entry.objCounter = 0;
255
 
        entry.typeObjectSize = sizeof(PKIX_PL_OID);
256
 
        entry.destructor = pkix_pl_OID_Destroy;
257
 
        entry.equalsFunction = pkix_pl_OID_Equals;
258
 
        entry.hashcodeFunction = pkix_pl_OID_Hashcode;
259
 
        entry.toStringFunction = pkix_pl_OID_ToString;
260
 
        entry.comparator = pkix_pl_OID_Comparator;
261
 
        entry.duplicateFunction = pkix_duplicateImmutable;
262
 
 
263
 
        systemClasses[PKIX_OID_TYPE] = entry;
264
 
 
265
 
        PKIX_RETURN(OID);
266
 
}
267
 
 
268
 
/*
269
 
 * FUNCTION: pkix_pl_OID_GetNextToken
270
 
 * DESCRIPTION:
271
 
 *
272
 
 *  This function is essentially a thread safe version of strtok, except
273
 
 *  that we always use '.' (dot) for the token separator.
274
 
 *
275
 
 *  Searches for tokens in the string pointed to by "input", using '.' (dot)
276
 
 *  as the token separator. If "input" contains multiple tokens, the first
277
 
 *  token is stored at "pToken", the character immediately follow the first
278
 
 *  token is replaced by a null character, and the rekmainder of "input" is
279
 
 *  stored at "pRem". If no additional tokens are available, this function
280
 
 *  stores NULL at "pToken".
281
 
 *
282
 
 * PARAMETERS
283
 
 *  "input"
284
 
 *      Address of string to be tokenized. May be NULL.
285
 
 *  "pToken"
286
 
 *      Destination for OID token. Must be non-NULL.
287
 
 *  "pRem"
288
 
 *      Destination for pointer to remainder of string. Must be non-NULL.
289
 
 *  "plContext"
290
 
 *      Platform-specific context pointer.
291
 
 * THREAD SAFETY:
292
 
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
293
 
 * RETURNS:
294
 
 *  Returns NULL if the function succeeds.
295
 
 *  Returns an OID Error if the function fails in a non-fatal way.
296
 
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
297
 
 */
298
 
static PKIX_Error *
299
 
pkix_pl_OID_GetNextToken(
300
 
        char *input,
301
 
        char **pToken,
302
 
        char **pRem,
303
 
        void *plContext)
304
 
{
305
 
        char *token = input;
306
 
 
307
 
        PKIX_ENTER(OID, "pkix_pl_OID_GetNextToken");
308
 
        PKIX_NULLCHECK_TWO(pToken, pRem);
309
 
 
310
 
        if (token == NULL){
311
 
                *pToken = token;
312
 
                goto cleanup;
313
 
        }
314
 
 
315
 
        while (*input != '.' && *input != '\0'){
316
 
                input++;
317
 
        }
318
 
 
319
 
        if (*input == '.'){
320
 
                *input = 0;
321
 
                *pRem = input + 1;
322
 
        } else { /* NULL case */
323
 
                *pRem = NULL;
324
 
        }
325
 
 
326
 
        *pToken = token;
327
 
 
328
 
cleanup:
 
227
        entry->description = "OID";
 
228
        entry->typeObjectSize = sizeof(PKIX_PL_OID);
 
229
        entry->destructor = pkix_pl_OID_Destroy;
 
230
        entry->equalsFunction = pkix_pl_OID_Equals;
 
231
        entry->hashcodeFunction = pkix_pl_OID_Hashcode;
 
232
        entry->toStringFunction = pkix_pl_OID_ToString;
 
233
        entry->comparator = pkix_pl_OID_Comparator;
 
234
        entry->duplicateFunction = pkix_duplicateImmutable;
329
235
 
330
236
        PKIX_RETURN(OID);
331
237
}
357
263
        void *plContext)
358
264
{
359
265
        PKIX_List *oidsList = NULL;
360
 
        CERTCertExtension *extension = NULL;
361
266
        PKIX_PL_OID *pkixOID = NULL;
362
 
        SECItem critical;
363
 
        SECItem oid;
364
 
        char *oidAscii = NULL;
365
267
 
366
268
        PKIX_ENTER(OID, "pkix_pl_OID_GetCriticalExtensionOIDs");
367
269
        PKIX_NULLCHECK_ONE(pOidsList);
369
271
        PKIX_CHECK(PKIX_List_Create(&oidsList, plContext),
370
272
                    PKIX_LISTCREATEFAILED);
371
273
 
372
 
        if (extensions){
373
 
 
374
 
                while (*extensions){
375
 
                        extension = *extensions++;
376
 
 
377
 
                    PKIX_NULLCHECK_ONE(extension);
378
 
 
379
 
                    /* extension is critical */
380
 
                    critical = extension->critical;
381
 
 
382
 
                    if (critical.len != 0){
383
 
 
384
 
                            if (critical.data[0] == 0xff) {
385
 
                            oid = extension->id;
386
 
 
387
 
                            PKIX_CHECK(pkix_pl_oidBytes2Ascii
388
 
                                    (&oid, &oidAscii, plContext),
389
 
                                    PKIX_OIDBYTES2ASCIIFAILED);
390
 
 
391
 
                            PKIX_CHECK(PKIX_PL_OID_Create
392
 
                                    (oidAscii, &pkixOID, plContext),
393
 
                                    PKIX_OIDCREATEFAILED);
394
 
 
395
 
                            PKIX_CHECK(PKIX_List_AppendItem
396
 
                                    (oidsList,
397
 
                                    (PKIX_PL_Object *)pkixOID,
398
 
                                    plContext),
399
 
                                    PKIX_LISTAPPENDITEMFAILED);
400
 
                            }
401
 
                    }
402
 
 
403
 
                    PKIX_FREE(oidAscii);
404
 
                    PKIX_DECREF(pkixOID);
 
274
        if (extensions) {
 
275
            while (*extensions) {
 
276
                CERTCertExtension *extension = NULL;
 
277
                SECItem *critical = NULL;
 
278
                SECItem *oid = NULL;
 
279
 
 
280
                extension = *extensions++;
 
281
                /* extension is critical ? */
 
282
                critical = &extension->critical;
 
283
                if (critical->len == 0 || critical->data[0] == 0) {
 
284
                    continue;
405
285
                }
 
286
                oid = &extension->id;
 
287
                PKIX_CHECK(
 
288
                    PKIX_PL_OID_CreateBySECItem(oid, &pkixOID, plContext),
 
289
                    PKIX_OIDCREATEFAILED);
 
290
                PKIX_CHECK(
 
291
                    PKIX_List_AppendItem(oidsList, (PKIX_PL_Object *)pkixOID,
 
292
                                         plContext),
 
293
                    PKIX_LISTAPPENDITEMFAILED);
 
294
                PKIX_DECREF(pkixOID);
 
295
            }
406
296
        }
407
297
 
408
298
        *pOidsList = oidsList;
410
300
        
411
301
cleanup:
412
302
        PKIX_DECREF(oidsList);
413
 
        PKIX_FREE(oidAscii);
414
303
        PKIX_DECREF(pkixOID);
415
304
        PKIX_RETURN(OID);
416
305
}
418
307
/* --Public-Functions------------------------------------------------------- */
419
308
 
420
309
/*
421
 
 * FUNCTION: PKIX_PL_OID_Create (see comments in pkix_pl_system.h)
 
310
 * FUNCTION: PKIX_PL_OID_CreateBySECItem (see comments in pkix_pl_system.h)
422
311
 */
423
312
PKIX_Error *
424
 
PKIX_PL_OID_Create(
425
 
        char *stringRep,
 
313
PKIX_PL_OID_CreateBySECItem(
 
314
        SECItem *derOid,
426
315
        PKIX_PL_OID **pOID,
427
316
        void *plContext)
428
317
{
429
318
        PKIX_PL_OID *oid = NULL;
430
 
        char *strCpy1 = NULL;
431
 
        char *strCpy2 = NULL;
432
 
        char *token = NULL;
433
 
        PKIX_UInt32 numTokens, i, length;
434
 
        PKIX_UInt32 value;
435
 
        PKIX_Boolean firstFieldTwo;
436
 
        PKIX_UInt32 *components = NULL;
437
 
        char *rem = NULL;
438
 
 
439
 
        PKIX_ENTER(OID, "PKIX_PL_OID_Create");
440
 
        PKIX_NULLCHECK_TWO(pOID, stringRep);
441
 
 
442
 
        PKIX_OID_DEBUG("\tCalling PL_strlen).\n");
443
 
        length = PL_strlen(stringRep);
444
 
 
445
 
        if (length < 3) {
446
 
                PKIX_ERROR(PKIX_OIDLENGTHTOOSHORT);
447
 
        }
448
 
 
449
 
        for (i = 0; i < length; i++) {
450
 
                if ((!PKIX_ISDIGIT(stringRep[i]))&&(stringRep[i] != '.')) {
451
 
                        PKIX_ERROR(PKIX_ILLEGALCHARACTERINOID);
452
 
                }
453
 
        }
454
 
 
455
 
        /* Check that string doesn't have extra dots */
456
 
        if ((stringRep[0] == '.') ||
457
 
            (stringRep[length-1] == '.')||
458
 
            (PL_strstr(stringRep, "..") != NULL)) {
459
 
                PKIX_ERROR(PKIX_ILLEGALDOTINOID);
460
 
        }
461
 
 
462
 
        PKIX_OID_DEBUG("\tCalling PL_strdup).\n");
463
 
 
464
 
        strCpy1 = PL_strdup(stringRep);
465
 
        strCpy2 = PL_strdup(stringRep);
466
 
 
467
 
        /* Validate and tally the number of tokens */
468
 
 
469
 
        PKIX_CHECK(pkix_pl_OID_GetNextToken
470
 
                    (strCpy1, &token, &rem, plContext),
471
 
                    PKIX_OIDGETNEXTTOKENFAILED);
472
 
 
473
 
        for (numTokens = 0; token != NULL; numTokens++){
474
 
                if (numTokens == 0) {
475
 
                        /* We know the string is all digits */
476
 
                        PKIX_OID_DEBUG("\tCalling PORT_Atoi).\n");
477
 
                        value = PORT_Atoi(token);
478
 
                        if (value > 2) {
479
 
                                PKIX_ERROR(PKIX_FIRSTFIELDMUSTBEBETWEEN02);
480
 
                        }
481
 
 
482
 
                        /* Set a flag if the first field is 2 */
483
 
                        firstFieldTwo = (value == 2);
484
 
                } else if (numTokens == 1) {
485
 
                        PKIX_OID_DEBUG("\tCalling PORT_Atoi).\n");
486
 
                        value = PORT_Atoi(token);
487
 
                        if ((!firstFieldTwo)&&(value > 39)) {
488
 
                                PKIX_ERROR
489
 
                                        (PKIX_SECONDFIELDMUSTBEBETWEEN039);
490
 
                        }
491
 
                }
492
 
 
493
 
                /* Check for 32-bit overflow */
494
 
                if (pkix_pl_UInt32_Overflows(token)){
495
 
                        PKIX_ERROR(PKIX_OIDCOMPONENTTOOBIG);
496
 
                }
497
 
 
498
 
                PKIX_CHECK(pkix_pl_OID_GetNextToken
499
 
                            (rem, &token, &rem, plContext),
500
 
                            PKIX_OIDGETNEXTTOKENFAILED);
501
 
        }
502
 
 
503
 
        if (numTokens < 2) {
504
 
                PKIX_ERROR(PKIX_OIDNEEDS2ORMOREFIELDS);
505
 
        }
506
 
 
507
 
        PKIX_CHECK(PKIX_PL_Malloc
508
 
                    (numTokens * sizeof (PKIX_UInt32),
509
 
                    (void **)&components, plContext),
510
 
                    PKIX_MALLOCFAILED);
511
 
 
512
 
        PKIX_CHECK(pkix_pl_OID_GetNextToken
513
 
                    (strCpy2, &token, &rem, plContext),
514
 
                    PKIX_OIDGETNEXTTOKENFAILED);
515
 
 
516
 
        for (i = 0; token != NULL; i++){
517
 
                PKIX_OID_DEBUG("\tCalling PORT_Atoi).\n");
518
 
                components[i] = PORT_Atoi(token);
519
 
 
520
 
                PKIX_CHECK(pkix_pl_OID_GetNextToken
521
 
                            (rem, &token, &rem, plContext),
522
 
                            PKIX_OIDGETNEXTTOKENFAILED);
523
 
        }
 
319
        SECStatus rv;
 
320
        
 
321
        PKIX_ENTER(OID, "PKIX_PL_OID_CreateBySECItem");
 
322
        PKIX_NULLCHECK_TWO(pOID, derOid);
524
323
 
525
324
        PKIX_CHECK(PKIX_PL_Object_Alloc
526
 
                    (PKIX_OID_TYPE,
 
325
                   (PKIX_OID_TYPE,
527
326
                    sizeof (PKIX_PL_OID),
528
327
                    (PKIX_PL_Object **)&oid,
529
328
                    plContext),
530
329
                    PKIX_COULDNOTCREATEOBJECT);
531
 
 
532
 
        oid->length = numTokens;
533
 
        oid->components = components;
534
 
 
535
 
        *pOID = oid;
536
 
 
537
 
cleanup:
538
 
 
539
 
        if (strCpy1){
540
 
                PKIX_OID_DEBUG("\tCalling PL_strfree).\n");
541
 
                PL_strfree(strCpy1);
542
 
        }
543
 
 
544
 
        if (strCpy2){
545
 
                PKIX_OID_DEBUG("\tCalling PL_strfree).\n");
546
 
                PL_strfree(strCpy2);
547
 
        }
548
 
 
549
 
        if (PKIX_ERROR_RECEIVED){
550
 
                PKIX_FREE(components);
551
 
        }
552
 
 
 
330
        rv = SECITEM_CopyItem(NULL, &oid->derOid, derOid);
 
331
        if (rv != SECFailure) {
 
332
            *pOID = oid;
 
333
            oid = NULL;
 
334
        }
 
335
        
 
336
cleanup:
 
337
        PKIX_DECREF(oid);
 
338
        
 
339
        PKIX_RETURN(OID);
 
340
}
 
341
 
 
342
/*
 
343
 * FUNCTION: PKIX_PL_OID_Create (see comments in pkix_pl_system.h)
 
344
 */
 
345
PKIX_Error *
 
346
PKIX_PL_OID_Create(
 
347
        SECOidTag idtag,
 
348
        PKIX_PL_OID **pOID,
 
349
        void *plContext)
 
350
{
 
351
        SECOidData *oidData = NULL;
 
352
    
 
353
        PKIX_ENTER(OID, "PKIX_PL_OID_Create");
 
354
        PKIX_NULLCHECK_ONE(pOID);
 
355
 
 
356
        oidData = SECOID_FindOIDByTag((SECOidTag)idtag);
 
357
        if (!oidData) {
 
358
            PKIX_ERROR(PKIX_SECOIDFINDOIDTAGDESCRIPTIONFAILED);
 
359
        }
 
360
        
 
361
        pkixErrorResult = 
 
362
            PKIX_PL_OID_CreateBySECItem(&oidData->oid, pOID, plContext);
 
363
cleanup:
553
364
        PKIX_RETURN(OID);
554
365
}