~ubuntu-branches/ubuntu/intrepid/xulrunner-1.9/intrepid

« back to all changes in this revision

Viewing changes to mozilla/security/nss/lib/certdb/certxutl.c

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Sack, Alexander Sack, Fabien Tassin
  • Date: 2008-02-13 11:47:21 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20080213114721-7om0mgzngvuk9czv
Tags: 1.9~b3+nobinonly-0ubuntu1
* release FIREFOX_3_0b3_RELEASE

[ Alexander Sack ]
* submit patch that ships xpcshell to bugzilla
  - rename debian/patches/ship_xpcshell.patch =>
           debian/patches/bz410617_att295212_ship_xpcshell.patch
  - update debian/patches/series
* fix tooltip in epiphany: previously displayed out of screen bounds
  (LP: #37507)
  - add debian/patches/bz233371_att297343_fix_outofscreen_embed_tooltip.patch
  - update debian/patches/series
* use default upstream gcc tweaks for improved performance - especially of the
  javascript engine
  - update debian/rules
* update global extension/plugin patch to apply cleanly against latest code
  - update debian/patches/bzXXX_gre_extension_plugin_support.patch
* fix pyxpcom build failure introduced by recent commit
  - add debian/patches/bzXXX_fix_pyxpcom_build_failure.patch
  - update debian/patches/series
* add distro independent global install locations for extensions,
  /usr/lib/mozilla/extensions and /usr/share/mozilla/extensions
  - update debian/xulrunner-1.9.dirs
* support embedded tarball layout when either there is a *.tar.bz2 in orig tarball
  or if DEBIAN_MOZCLIENT_EMBEDDED is not unset (you will need this to produce embedded
  tarballs during |get-orig-source|
  - update debian/rules
* bump minimum libnss3-dev build requirements to >= 3.12.0~1.9b3
  - update debian/control
* bump minimum libnspr4-dev build requirements to >= 4.7.0~1.9b3
  - update debian/control

[ Fabien Tassin ]
* Drop patches applied upstream
  - drop debian/patches/bz410617_att295212_ship_xpcshell.patch
  - drop debian/patches/bz404634_att294921.patch
  - drop debian/patches/bz386610_python2.5_ftbfs_amd64.patch
  - drop debian/patches/bz373918_att295042.patch
  - drop debian/patches/bz408062_unstable_pc.patch
  - drop debian/patches/bz384304_fix_recursive_symlinks.patch
  - update debian/patches/series
* Refresh diverged patches:
  - update debian/patches/bzXXX_pc_honour_system_nspr_nss.patch
  - update debian/patches/rename_venkman_addon.patch
  - update debian/patches/bz344818_cairo_xrender.patch
* Install links for all .so libs in the -dev package
  - update debian/patches/dont_install_so_in_dev.patch
* Bump gtk requirement to 2.12 as per Mozilla bug 412432
  - update debian/control
* Add #DEBHELPER# token to postinst/prerm scripts
  - update debian/xulrunner-1.9.{postinst,prerm}
* Install previously missed libdbusservice.so
  - update debian/xulrunner-1.9.install
* Update venkman patch to also rename locales
  - update debian/patches/rename_venkman_addon.patch
* Bump requirement for system cairo to >= 1.5.8 as we now need
  the newly added cairo_path_extents()
  - update debian/rules
* Include mozilla-devscripts file using -include so ifneq could be omitted
  - update debian/rules
* Fix missing .so symlinks regression
  - update debian/patches/dont_install_so_in_dev.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* ***** BEGIN LICENSE BLOCK *****
2
 
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3
 
 *
4
 
 * The contents of this file are subject to the Mozilla Public License Version
5
 
 * 1.1 (the "License"); you may not use this file except in compliance with
6
 
 * the License. You may obtain a copy of the License at
7
 
 * http://www.mozilla.org/MPL/
8
 
 *
9
 
 * Software distributed under the License is distributed on an "AS IS" basis,
10
 
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
 
 * for the specific language governing rights and limitations under the
12
 
 * License.
13
 
 *
14
 
 * The Original Code is the Netscape security libraries.
15
 
 *
16
 
 * The Initial Developer of the Original Code is
17
 
 * Netscape Communications Corporation.
18
 
 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19
 
 * the Initial Developer. All Rights Reserved.
20
 
 *
21
 
 * Contributor(s):
22
 
 *
23
 
 * Alternatively, the contents of this file may be used under the terms of
24
 
 * either the GNU General Public License Version 2 or later (the "GPL"), or
25
 
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26
 
 * in which case the provisions of the GPL or the LGPL are applicable instead
27
 
 * of those above. If you wish to allow use of your version of this file only
28
 
 * under the terms of either the GPL or the LGPL, and not to allow others to
29
 
 * use your version of this file under the terms of the MPL, indicate your
30
 
 * decision by deleting the provisions above and replace them with the notice
31
 
 * and other provisions required by the GPL or the LGPL. If you do not delete
32
 
 * the provisions above, a recipient may use your version of this file under
33
 
 * the terms of any one of the MPL, the GPL or the LGPL.
34
 
 *
35
 
 * ***** END LICENSE BLOCK ***** */
36
 
 
37
 
/*
38
 
 * Certificate Extensions handling code
39
 
 *
40
 
 */
41
 
 
42
 
#include "cert.h"
43
 
#include "secitem.h"
44
 
#include "secoid.h"
45
 
#include "secder.h"
46
 
#include "secasn1.h"
47
 
#include "certxutl.h"
48
 
#include "secerr.h"
49
 
 
50
 
#ifdef OLD
51
 
#include "ocspti.h"     /* XXX a better extensions interface would not
52
 
                         * require knowledge of data structures of callers */
53
 
#endif
54
 
 
55
 
static CERTCertExtension *
56
 
GetExtension (CERTCertExtension **extensions, SECItem *oid)
57
 
{
58
 
    CERTCertExtension **exts;
59
 
    CERTCertExtension *ext = NULL;
60
 
    SECComparison comp;
61
 
 
62
 
    exts = extensions;
63
 
    
64
 
    if (exts) {
65
 
        while ( *exts ) {
66
 
            ext = *exts;
67
 
            comp = SECITEM_CompareItem(oid, &ext->id);
68
 
            if ( comp == SECEqual ) 
69
 
                break;
70
 
 
71
 
            exts++;
72
 
        }
73
 
        return (*exts ? ext : NULL);
74
 
    }
75
 
    return (NULL);
76
 
}
77
 
 
78
 
SECStatus
79
 
cert_FindExtensionByOID (CERTCertExtension **extensions, SECItem *oid, SECItem *value)
80
 
{
81
 
    CERTCertExtension *ext;
82
 
    SECStatus rv = SECSuccess;
83
 
    
84
 
    ext = GetExtension (extensions, oid);
85
 
    if (ext == NULL) {
86
 
        PORT_SetError (SEC_ERROR_EXTENSION_NOT_FOUND);
87
 
        return (SECFailure);
88
 
    }
89
 
    if (value)
90
 
        rv = SECITEM_CopyItem(NULL, value, &ext->value);
91
 
    return (rv);
92
 
}
93
 
    
94
 
 
95
 
SECStatus
96
 
CERT_GetExtenCriticality (CERTCertExtension **extensions, int tag, PRBool *isCritical)
97
 
{
98
 
    CERTCertExtension *ext;
99
 
    SECOidData *oid;
100
 
 
101
 
    if (!isCritical)
102
 
        return (SECSuccess);
103
 
    
104
 
    /* find the extension in the extensions list */
105
 
    oid = SECOID_FindOIDByTag((SECOidTag)tag);
106
 
    if ( !oid ) {
107
 
        return(SECFailure);
108
 
    }
109
 
    ext = GetExtension (extensions, &oid->oid);
110
 
    if (ext == NULL) {
111
 
        PORT_SetError (SEC_ERROR_EXTENSION_NOT_FOUND);
112
 
        return (SECFailure);
113
 
    }
114
 
 
115
 
    /* If the criticality is omitted, then it is false by default.
116
 
       ex->critical.data is NULL */
117
 
    if (ext->critical.data == NULL)
118
 
        *isCritical = PR_FALSE;
119
 
    else
120
 
        *isCritical = (ext->critical.data[0] == 0xff) ? PR_TRUE : PR_FALSE;
121
 
    return (SECSuccess);    
122
 
}
123
 
 
124
 
SECStatus
125
 
cert_FindExtension(CERTCertExtension **extensions, int tag, SECItem *value)
126
 
{
127
 
    SECOidData *oid;
128
 
    
129
 
    oid = SECOID_FindOIDByTag((SECOidTag)tag);
130
 
    if ( !oid ) {
131
 
        return(SECFailure);
132
 
    }
133
 
 
134
 
    return(cert_FindExtensionByOID(extensions, &oid->oid, value));
135
 
}
136
 
 
137
 
 
138
 
typedef struct _extNode {
139
 
    struct _extNode *next;
140
 
    CERTCertExtension *ext;
141
 
} extNode;
142
 
 
143
 
typedef struct {
144
 
    void (*setExts)(void *object, CERTCertExtension **exts);
145
 
    void *object;
146
 
    PRArenaPool *ownerArena;
147
 
    PRArenaPool *arena;
148
 
    extNode *head;
149
 
    int count;
150
 
}extRec;
151
 
 
152
 
/*
153
 
 * cert_StartExtensions
154
 
 *
155
 
 * NOTE: This interface changed significantly to remove knowledge
156
 
 *   about callers data structures (owner objects)
157
 
 */
158
 
void *
159
 
cert_StartExtensions(void *owner, PRArenaPool *ownerArena,
160
 
   void (*setExts)(void *object, CERTCertExtension **exts))
161
 
{
162
 
    PRArenaPool *arena;
163
 
    extRec *handle;
164
 
 
165
 
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
166
 
    if ( !arena ) {
167
 
        return(0);
168
 
    }
169
 
 
170
 
    handle = (extRec *)PORT_ArenaAlloc(arena, sizeof(extRec));
171
 
    if ( !handle ) {
172
 
        PORT_FreeArena(arena, PR_FALSE);
173
 
        return(0);
174
 
    }
175
 
 
176
 
    handle->object = owner;
177
 
    handle->ownerArena = ownerArena;
178
 
    handle->setExts = setExts;
179
 
 
180
 
    handle->arena = arena;
181
 
    handle->head = 0;
182
 
    handle->count = 0;
183
 
    
184
 
    return(handle);
185
 
}
186
 
 
187
 
static unsigned char hextrue = 0xff;
188
 
 
189
 
/*
190
 
 * Note - assumes that data pointed to by oid->data will not move
191
 
 */
192
 
SECStatus
193
 
CERT_AddExtensionByOID (void *exthandle, SECItem *oid, SECItem *value,
194
 
                        PRBool critical, PRBool copyData)
195
 
{
196
 
    CERTCertExtension *ext;
197
 
    SECStatus rv;
198
 
    extNode *node;
199
 
    extRec *handle;
200
 
    
201
 
    handle = (extRec *)exthandle;
202
 
 
203
 
    /* allocate space for extension and list node */
204
 
    ext = (CERTCertExtension*)PORT_ArenaZAlloc(handle->ownerArena,
205
 
                                               sizeof(CERTCertExtension));
206
 
    if ( !ext ) {
207
 
        return(SECFailure);
208
 
    }
209
 
 
210
 
    node = (extNode*)PORT_ArenaAlloc(handle->arena, sizeof(extNode));
211
 
    if ( !node ) {
212
 
        return(SECFailure);
213
 
    }
214
 
 
215
 
    /* add to list */
216
 
    node->next = handle->head;
217
 
    handle->head = node;
218
 
   
219
 
    /* point to ext struct */
220
 
    node->ext = ext;
221
 
    
222
 
    /* the object ID of the extension */
223
 
    ext->id = *oid;
224
 
    
225
 
    /* set critical field */
226
 
    if ( critical ) {
227
 
        ext->critical.data = (unsigned char*)&hextrue;
228
 
        ext->critical.len = 1;
229
 
    }
230
 
 
231
 
    /* set the value */
232
 
    if ( copyData ) {
233
 
        rv = SECITEM_CopyItem(handle->ownerArena, &ext->value, value);
234
 
        if ( rv ) {
235
 
            return(SECFailure);
236
 
        }
237
 
    } else {
238
 
        ext->value = *value;
239
 
    }
240
 
    
241
 
    handle->count++;
242
 
    
243
 
    return(SECSuccess);
244
 
 
245
 
}
246
 
 
247
 
SECStatus
248
 
CERT_AddExtension(void *exthandle, int idtag, SECItem *value,
249
 
                     PRBool critical, PRBool copyData)
250
 
{
251
 
    SECOidData *oid;
252
 
    
253
 
    oid = SECOID_FindOIDByTag((SECOidTag)idtag);
254
 
    if ( !oid ) {
255
 
        return(SECFailure);
256
 
    }
257
 
 
258
 
    return(CERT_AddExtensionByOID(exthandle, &oid->oid, value, critical, copyData));
259
 
}
260
 
 
261
 
SECStatus
262
 
CERT_EncodeAndAddExtension(void *exthandle, int idtag, void *value,
263
 
                           PRBool critical, const SEC_ASN1Template *atemplate)
264
 
{
265
 
    extRec *handle;
266
 
    SECItem *encitem;
267
 
 
268
 
    handle = (extRec *)exthandle;
269
 
 
270
 
    encitem = SEC_ASN1EncodeItem(handle->ownerArena, NULL, value, atemplate);
271
 
    if ( encitem == NULL ) {
272
 
        return(SECFailure);
273
 
    }
274
 
 
275
 
    return CERT_AddExtension(exthandle, idtag, encitem, critical, PR_FALSE);
276
 
}
277
 
 
278
 
void
279
 
PrepareBitStringForEncoding (SECItem *bitsmap, SECItem *value)
280
 
{
281
 
  unsigned char onebyte;
282
 
  unsigned int i, len = 0;
283
 
 
284
 
  /* to prevent warning on some platform at compile time */ 
285
 
  onebyte = '\0';   
286
 
  /* Get the position of the right-most turn-on bit */ 
287
 
  for (i = 0; i < (value->len ) * 8; ++i) {
288
 
      if (i % 8 == 0)
289
 
          onebyte = value->data[i/8];
290
 
      if (onebyte & 0x80)
291
 
          len = i;            
292
 
      onebyte <<= 1;
293
 
      
294
 
  }
295
 
  bitsmap->data = value->data;
296
 
  /* Add one here since we work with base 1 */ 
297
 
  bitsmap->len = len + 1;
298
 
}
299
 
 
300
 
SECStatus
301
 
CERT_EncodeAndAddBitStrExtension (void *exthandle, int idtag,
302
 
                                  SECItem *value, PRBool critical)
303
 
{
304
 
  SECItem bitsmap;
305
 
  
306
 
  PrepareBitStringForEncoding (&bitsmap, value);
307
 
  return (CERT_EncodeAndAddExtension
308
 
          (exthandle, idtag, &bitsmap, critical, SEC_BitStringTemplate));
309
 
}
310
 
 
311
 
SECStatus
312
 
CERT_FinishExtensions(void *exthandle)
313
 
{
314
 
    extRec *handle;
315
 
    extNode *node;
316
 
    CERTCertExtension **exts;
317
 
    SECStatus rv = SECFailure;
318
 
    
319
 
    handle = (extRec *)exthandle;
320
 
 
321
 
    /* allocate space for extensions array */
322
 
    exts = PORT_ArenaNewArray(handle->ownerArena, CERTCertExtension *,
323
 
                              handle->count + 1);
324
 
    if (exts == NULL) {
325
 
        goto loser;
326
 
    }
327
 
 
328
 
    /* put extensions in owner object and update its version number */
329
 
 
330
 
#ifdef OLD
331
 
    switch (handle->type) {
332
 
      case CertificateExtensions:
333
 
        handle->owner.cert->extensions = exts;
334
 
        DER_SetUInteger (ownerArena, &(handle->owner.cert->version),
335
 
                         SEC_CERTIFICATE_VERSION_3);
336
 
        break;
337
 
      case CrlExtensions:
338
 
        handle->owner.crl->extensions = exts;
339
 
        DER_SetUInteger (ownerArena, &(handle->owner.crl->version),
340
 
                         SEC_CRL_VERSION_2);
341
 
        break;
342
 
      case OCSPRequestExtensions:
343
 
        handle->owner.request->tbsRequest->requestExtensions = exts;
344
 
        break;
345
 
      case OCSPSingleRequestExtensions:
346
 
        handle->owner.singleRequest->singleRequestExtensions = exts;    
347
 
        break;
348
 
      case OCSPResponseSingleExtensions:
349
 
        handle->owner.singleResponse->singleExtensions = exts;  
350
 
        break;
351
 
    }
352
 
#endif
353
 
 
354
 
    handle->setExts(handle->object, exts);
355
 
        
356
 
    /* update the version number */
357
 
 
358
 
    /* copy each extension pointer */
359
 
    node = handle->head;
360
 
    while ( node ) {
361
 
        *exts = node->ext;
362
 
        
363
 
        node = node->next;
364
 
        exts++;
365
 
    }
366
 
 
367
 
    /* terminate the array of extensions */
368
 
    *exts = 0;
369
 
 
370
 
    rv = SECSuccess;
371
 
 
372
 
loser:
373
 
    /* free working arena */
374
 
    PORT_FreeArena(handle->arena, PR_FALSE);
375
 
    return rv;
376
 
}
377
 
 
378
 
SECStatus
379
 
CERT_MergeExtensions(void *exthandle, CERTCertExtension **extensions)
380
 
{
381
 
    CERTCertExtension *ext;
382
 
    SECStatus rv = SECSuccess;
383
 
    SECOidTag tag;
384
 
    extNode *node;
385
 
    extRec *handle = exthandle;
386
 
    
387
 
    if (!exthandle || !extensions) {
388
 
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
389
 
        return SECFailure;
390
 
    }
391
 
    while ((ext = *extensions++) != NULL) {
392
 
        tag = SECOID_FindOIDTag(&ext->id);
393
 
        for (node=handle->head; node != NULL; node=node->next) {
394
 
            if (tag == 0) {
395
 
                if (SECITEM_ItemsAreEqual(&ext->id, &node->ext->id))
396
 
                    break;
397
 
            }
398
 
            else {
399
 
                if (SECOID_FindOIDTag(&node->ext->id) == tag) {
400
 
                    break;
401
 
                }
402
 
            }
403
 
        }
404
 
        if (node == NULL) {
405
 
            PRBool critical = (ext->critical.len != 0 &&
406
 
                            ext->critical.data[ext->critical.len - 1] != 0);
407
 
            if (critical && tag == SEC_OID_UNKNOWN) {
408
 
               PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION);
409
 
               rv = SECFailure;
410
 
               break;
411
 
            }
412
 
            /* add to list */
413
 
            rv = CERT_AddExtensionByOID (exthandle, &ext->id, &ext->value,
414
 
                                         critical, PR_TRUE);
415
 
            if (rv != SECSuccess)
416
 
                break;
417
 
        }
418
 
    }
419
 
    return rv;
420
 
}
421
 
 
422
 
/*
423
 
 * get the value of the Netscape Certificate Type Extension
424
 
 */
425
 
SECStatus
426
 
CERT_FindBitStringExtension (CERTCertExtension **extensions, int tag,
427
 
                             SECItem *retItem)
428
 
{
429
 
    SECItem wrapperItem, tmpItem = {siBuffer,0};
430
 
    SECStatus rv;
431
 
    PRArenaPool *arena = NULL;
432
 
    
433
 
    wrapperItem.data = NULL;
434
 
    tmpItem.data = NULL;
435
 
    
436
 
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
437
 
    
438
 
    if ( ! arena ) {
439
 
        return(SECFailure);
440
 
    }
441
 
    
442
 
    rv = cert_FindExtension(extensions, tag, &wrapperItem);
443
 
    if ( rv != SECSuccess ) {
444
 
        goto loser;
445
 
    }
446
 
 
447
 
    rv = SEC_QuickDERDecodeItem(arena, &tmpItem, SEC_BitStringTemplate, 
448
 
                            &wrapperItem);
449
 
 
450
 
    if ( rv != SECSuccess ) {
451
 
        goto loser;
452
 
    }
453
 
 
454
 
    retItem->data = (unsigned char *)PORT_Alloc( ( tmpItem.len + 7 ) >> 3 );
455
 
    if ( retItem->data == NULL ) {
456
 
        goto loser;
457
 
    }
458
 
    
459
 
    PORT_Memcpy(retItem->data, tmpItem.data, ( tmpItem.len + 7 ) >> 3);
460
 
    retItem->len = tmpItem.len;
461
 
    
462
 
    rv = SECSuccess;
463
 
    goto done;
464
 
    
465
 
loser:
466
 
    rv = SECFailure;
467
 
 
468
 
done:
469
 
    if ( arena ) {
470
 
        PORT_FreeArena(arena, PR_FALSE);
471
 
    }
472
 
    
473
 
    if ( wrapperItem.data ) {
474
 
        PORT_Free(wrapperItem.data);
475
 
    }
476
 
 
477
 
    return(rv);
478
 
}
479
 
 
480
 
PRBool
481
 
cert_HasCriticalExtension (CERTCertExtension **extensions)
482
 
{
483
 
    CERTCertExtension **exts;
484
 
    CERTCertExtension *ext = NULL;
485
 
    PRBool hasCriticalExten = PR_FALSE;
486
 
    
487
 
    exts = extensions;
488
 
    
489
 
    if (exts) {
490
 
        while ( *exts ) {
491
 
            ext = *exts;
492
 
            /* If the criticality is omitted, it's non-critical */
493
 
            if (ext->critical.data && ext->critical.data[0] == 0xff) {
494
 
                hasCriticalExten = PR_TRUE;
495
 
                break;
496
 
            }
497
 
            exts++;
498
 
        }
499
 
    }
500
 
    return (hasCriticalExten);
501
 
}
502
 
 
503
 
PRBool
504
 
cert_HasUnknownCriticalExten (CERTCertExtension **extensions)
505
 
{
506
 
    CERTCertExtension **exts;
507
 
    CERTCertExtension *ext = NULL;
508
 
    PRBool hasUnknownCriticalExten = PR_FALSE;
509
 
    
510
 
    exts = extensions;
511
 
    
512
 
    if (exts) {
513
 
        while ( *exts ) {
514
 
            ext = *exts;
515
 
            /* If the criticality is omitted, it's non-critical.
516
 
               If an extension is critical, make sure that we know
517
 
               how to process the extension.
518
 
             */
519
 
            if (ext->critical.data && ext->critical.data[0] == 0xff) {
520
 
                if (SECOID_KnownCertExtenOID (&ext->id) == PR_FALSE) {
521
 
                    hasUnknownCriticalExten = PR_TRUE;
522
 
                    break;
523
 
                }
524
 
            }
525
 
            exts++;
526
 
        }
527
 
    }
528
 
    return (hasUnknownCriticalExten);
529
 
}