~ubuntu-branches/ubuntu/trusty/xulrunner/trusty

« back to all changes in this revision

Viewing changes to security/nss-fips/lib/certdb/secname.c

  • Committer: Bazaar Package Importer
  • Author(s): Devid Antonio Filoni
  • Date: 2008-08-25 13:04:18 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20080825130418-ck1i2ms384tzb9m0
Tags: 1.8.1.16+nobinonly-0ubuntu1
* New upstream release (taken from upstream CVS), LP: #254618.
* Fix MFSA 2008-35, MFSA 2008-34, MFSA 2008-33, MFSA 2008-32, MFSA 2008-31,
  MFSA 2008-30, MFSA 2008-29, MFSA 2008-28, MFSA 2008-27, MFSA 2008-25,
  MFSA 2008-24, MFSA 2008-23, MFSA 2008-22, MFSA 2008-21, MFSA 2008-26 also
  known as CVE-2008-2933, CVE-2008-2785, CVE-2008-2811, CVE-2008-2810,
  CVE-2008-2809, CVE-2008-2808, CVE-2008-2807, CVE-2008-2806, CVE-2008-2805,
  CVE-2008-2803, CVE-2008-2802, CVE-2008-2801, CVE-2008-2800, CVE-2008-2798.
* Drop 89_bz419350_attachment_306066 patch, merged upstream.
* Bump Standards-Version to 3.8.0.

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
 *   John Gardiner Myers <jgmyers@speakeasy.net>
 
23
 *
 
24
 * Alternatively, the contents of this file may be used under the terms of
 
25
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
26
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
27
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
28
 * of those above. If you wish to allow use of your version of this file only
 
29
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
30
 * use your version of this file under the terms of the MPL, indicate your
 
31
 * decision by deleting the provisions above and replace them with the notice
 
32
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
33
 * the provisions above, a recipient may use your version of this file under
 
34
 * the terms of any one of the MPL, the GPL or the LGPL.
 
35
 *
 
36
 * ***** END LICENSE BLOCK ***** */
 
37
 
 
38
#include "cert.h"
 
39
#include "secoid.h"
 
40
#include "secder.h"     /* XXX remove this when remove the DERTemplates */
 
41
#include "secasn1.h"
 
42
#include "secitem.h"
 
43
#include <stdarg.h>
 
44
#include "secerr.h"
 
45
#include "certi.h"
 
46
 
 
47
static const SEC_ASN1Template cert_AVATemplate[] = {
 
48
    { SEC_ASN1_SEQUENCE,
 
49
          0, NULL, sizeof(CERTAVA) },
 
50
    { SEC_ASN1_OBJECT_ID,
 
51
          offsetof(CERTAVA,type), },
 
52
    { SEC_ASN1_ANY,
 
53
          offsetof(CERTAVA,value), },
 
54
    { 0, }
 
55
};
 
56
 
 
57
const SEC_ASN1Template CERT_RDNTemplate[] = {
 
58
    { SEC_ASN1_SET_OF,
 
59
          offsetof(CERTRDN,avas), cert_AVATemplate, sizeof(CERTRDN) }
 
60
};
 
61
 
 
62
 
 
63
static int
 
64
CountArray(void **array)
 
65
{
 
66
    int count = 0;
 
67
    if (array) {
 
68
        while (*array++) {
 
69
            count++;
 
70
        }
 
71
    }
 
72
    return count;
 
73
}
 
74
 
 
75
static void **
 
76
AddToArray(PRArenaPool *arena, void **array, void *element)
 
77
{
 
78
    unsigned count;
 
79
    void **ap;
 
80
 
 
81
    /* Count up number of slots already in use in the array */
 
82
    count = 0;
 
83
    ap = array;
 
84
    if (ap) {
 
85
        while (*ap++) {
 
86
            count++;
 
87
        }
 
88
    }
 
89
 
 
90
    if (array) {
 
91
        array = (void**) PORT_ArenaGrow(arena, array,
 
92
                                        (count + 1) * sizeof(void *),
 
93
                                        (count + 2) * sizeof(void *));
 
94
    } else {
 
95
        array = (void**) PORT_ArenaAlloc(arena, (count + 2) * sizeof(void *));
 
96
    }
 
97
    if (array) {
 
98
        array[count] = element;
 
99
        array[count+1] = 0;
 
100
    }
 
101
    return array;
 
102
}
 
103
 
 
104
 
 
105
SECOidTag
 
106
CERT_GetAVATag(CERTAVA *ava)
 
107
{
 
108
    SECOidData *oid;
 
109
    if (!ava->type.data) return (SECOidTag)-1;
 
110
 
 
111
    oid = SECOID_FindOID(&ava->type);
 
112
    
 
113
    if ( oid ) {
 
114
        return(oid->offset);
 
115
    }
 
116
    return (SECOidTag)-1;
 
117
}
 
118
 
 
119
static SECStatus
 
120
SetupAVAType(PRArenaPool *arena, SECOidTag type, SECItem *it, unsigned *maxLenp)
 
121
{
 
122
    unsigned char *oid;
 
123
    unsigned oidLen;
 
124
    unsigned char *cp;
 
125
    int      maxLen;
 
126
    SECOidData *oidrec;
 
127
 
 
128
    oidrec = SECOID_FindOIDByTag(type);
 
129
    if (oidrec == NULL)
 
130
        return SECFailure;
 
131
 
 
132
    oid = oidrec->oid.data;
 
133
    oidLen = oidrec->oid.len;
 
134
 
 
135
    maxLen = cert_AVAOidTagToMaxLen(type);
 
136
    if (maxLen < 0) {
 
137
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
 
138
        return SECFailure;
 
139
    }
 
140
 
 
141
    it->data = cp = (unsigned char*) PORT_ArenaAlloc(arena, oidLen);
 
142
    if (cp == NULL) {
 
143
        return SECFailure;
 
144
    }
 
145
    it->len = oidLen;
 
146
    PORT_Memcpy(cp, oid, oidLen);
 
147
    *maxLenp = (unsigned)maxLen;
 
148
    return SECSuccess;
 
149
}
 
150
 
 
151
static SECStatus
 
152
SetupAVAValue(PRArenaPool *arena, int valueType, char *value, SECItem *it,
 
153
              unsigned maxLen)
 
154
{
 
155
    unsigned valueLen, valueLenLen, total;
 
156
    unsigned ucs4Len = 0, ucs4MaxLen;
 
157
    unsigned char *cp, *ucs4Val;
 
158
 
 
159
    switch (valueType) {
 
160
      case SEC_ASN1_PRINTABLE_STRING:
 
161
      case SEC_ASN1_IA5_STRING:
 
162
      case SEC_ASN1_T61_STRING:
 
163
      case SEC_ASN1_UTF8_STRING: /* no conversion required */
 
164
        valueLen = PORT_Strlen(value);
 
165
        break;
 
166
      case SEC_ASN1_UNIVERSAL_STRING:
 
167
        valueLen = PORT_Strlen(value);
 
168
        ucs4MaxLen = valueLen * 6;
 
169
        ucs4Val = (unsigned char *)PORT_ArenaZAlloc(arena, ucs4MaxLen);
 
170
        if(!ucs4Val || !PORT_UCS4_UTF8Conversion(PR_TRUE, 
 
171
                                        (unsigned char *)value, valueLen,
 
172
                                        ucs4Val, ucs4MaxLen, &ucs4Len)) {
 
173
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
 
174
            return SECFailure;
 
175
        }
 
176
        value = (char *)ucs4Val;
 
177
        valueLen = ucs4Len;
 
178
        maxLen *= 4;
 
179
        break;
 
180
      default:
 
181
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
 
182
        return SECFailure;
 
183
    }
 
184
 
 
185
    if (valueLen > maxLen) {
 
186
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
 
187
        return SECFailure;
 
188
    } 
 
189
 
 
190
    valueLenLen = DER_LengthLength(valueLen);
 
191
    total = 1 + valueLenLen + valueLen;
 
192
    it->data = cp = (unsigned char*) PORT_ArenaAlloc(arena, total);
 
193
    if (!cp) {
 
194
        return SECFailure;
 
195
    }
 
196
    it->len = total;
 
197
    cp = (unsigned char*) DER_StoreHeader(cp, valueType, valueLen);
 
198
    PORT_Memcpy(cp, value, valueLen);
 
199
    return SECSuccess;
 
200
}
 
201
 
 
202
CERTAVA *
 
203
CERT_CreateAVA(PRArenaPool *arena, SECOidTag kind, int valueType, char *value)
 
204
{
 
205
    CERTAVA *ava;
 
206
    int rv;
 
207
    unsigned maxLen;
 
208
 
 
209
    ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA));
 
210
    if (ava) {
 
211
        rv = SetupAVAType(arena, kind, &ava->type, &maxLen);
 
212
        if (rv) {
 
213
            /* Illegal AVA type */
 
214
            return 0;
 
215
        }
 
216
        rv = SetupAVAValue(arena, valueType, value, &ava->value, maxLen);
 
217
        if (rv) {
 
218
            /* Illegal value type */
 
219
            return 0;
 
220
        }
 
221
    }
 
222
    return ava;
 
223
}
 
224
 
 
225
CERTAVA *
 
226
CERT_CopyAVA(PRArenaPool *arena, CERTAVA *from)
 
227
{
 
228
    CERTAVA *ava;
 
229
    int rv;
 
230
 
 
231
    ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA));
 
232
    if (ava) {
 
233
        rv = SECITEM_CopyItem(arena, &ava->type, &from->type);
 
234
        if (rv) goto loser;
 
235
        rv = SECITEM_CopyItem(arena, &ava->value, &from->value);
 
236
        if (rv) goto loser;
 
237
    }
 
238
    return ava;
 
239
 
 
240
  loser:
 
241
    return 0;
 
242
}
 
243
 
 
244
/************************************************************************/
 
245
/* XXX This template needs to go away in favor of the new SEC_ASN1 version. */
 
246
static const SEC_ASN1Template cert_RDNTemplate[] = {
 
247
    { SEC_ASN1_SET_OF,
 
248
          offsetof(CERTRDN,avas), cert_AVATemplate, sizeof(CERTRDN) }
 
249
};
 
250
 
 
251
 
 
252
CERTRDN *
 
253
CERT_CreateRDN(PRArenaPool *arena, CERTAVA *ava0, ...)
 
254
{
 
255
    CERTAVA *ava;
 
256
    CERTRDN *rdn;
 
257
    va_list ap;
 
258
    unsigned count;
 
259
    CERTAVA **avap;
 
260
 
 
261
    rdn = (CERTRDN*) PORT_ArenaAlloc(arena, sizeof(CERTRDN));
 
262
    if (rdn) {
 
263
        /* Count number of avas going into the rdn */
 
264
        count = 0;
 
265
        if (ava0) {
 
266
            count++;
 
267
            va_start(ap, ava0);
 
268
            while ((ava = va_arg(ap, CERTAVA*)) != 0) {
 
269
                count++;
 
270
            }
 
271
            va_end(ap);
 
272
        }
 
273
 
 
274
        /* Now fill in the pointers */
 
275
        rdn->avas = avap =
 
276
            (CERTAVA**) PORT_ArenaAlloc( arena, (count + 1)*sizeof(CERTAVA*));
 
277
        if (!avap) {
 
278
            return 0;
 
279
        }
 
280
        if (ava0) {
 
281
            *avap++ = ava0;
 
282
            va_start(ap, ava0);
 
283
            while ((ava = va_arg(ap, CERTAVA*)) != 0) {
 
284
                *avap++ = ava;
 
285
            }
 
286
            va_end(ap);
 
287
        }
 
288
        *avap++ = 0;
 
289
    }
 
290
    return rdn;
 
291
}
 
292
 
 
293
SECStatus
 
294
CERT_AddAVA(PRArenaPool *arena, CERTRDN *rdn, CERTAVA *ava)
 
295
{
 
296
    rdn->avas = (CERTAVA**) AddToArray(arena, (void**) rdn->avas, ava);
 
297
    return rdn->avas ? SECSuccess : SECFailure;
 
298
}
 
299
 
 
300
SECStatus
 
301
CERT_CopyRDN(PRArenaPool *arena, CERTRDN *to, CERTRDN *from)
 
302
{
 
303
    CERTAVA **avas, *fava, *tava;
 
304
    SECStatus rv = SECSuccess;
 
305
 
 
306
    /* Copy each ava from from */
 
307
    avas = from->avas;
 
308
    if (avas) {
 
309
        if (avas[0] == NULL) {
 
310
            rv = CERT_AddAVA(arena, to, NULL);
 
311
            return rv;
 
312
        }
 
313
        while ((fava = *avas++) != 0) {
 
314
            tava = CERT_CopyAVA(arena, fava);
 
315
            if (!tava) {
 
316
                rv = SECFailure;
 
317
                break;
 
318
            }
 
319
            rv = CERT_AddAVA(arena, to, tava);
 
320
            if (rv != SECSuccess) 
 
321
                break;
 
322
        }
 
323
    }
 
324
    return rv;
 
325
}
 
326
 
 
327
/************************************************************************/
 
328
 
 
329
const SEC_ASN1Template CERT_NameTemplate[] = {
 
330
    { SEC_ASN1_SEQUENCE_OF,
 
331
          offsetof(CERTName,rdns), CERT_RDNTemplate, sizeof(CERTName) }
 
332
};
 
333
 
 
334
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_NameTemplate)
 
335
 
 
336
CERTName *
 
337
CERT_CreateName(CERTRDN *rdn0, ...)
 
338
{
 
339
    CERTRDN *rdn;
 
340
    CERTName *name;
 
341
    va_list ap;
 
342
    unsigned count;
 
343
    CERTRDN **rdnp;
 
344
    PRArenaPool *arena;
 
345
    
 
346
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
 
347
    if ( !arena ) {
 
348
        return(0);
 
349
    }
 
350
    
 
351
    name = (CERTName*) PORT_ArenaAlloc(arena, sizeof(CERTName));
 
352
    if (name) {
 
353
        name->arena = arena;
 
354
        
 
355
        /* Count number of RDNs going into the Name */
 
356
        if (!rdn0) {
 
357
            count = 0;
 
358
        } else {
 
359
            count = 1;
 
360
            va_start(ap, rdn0);
 
361
            while ((rdn = va_arg(ap, CERTRDN*)) != 0) {
 
362
                count++;
 
363
            }
 
364
            va_end(ap);
 
365
        }
 
366
 
 
367
        /* Allocate space (including space for terminal null ptr) */
 
368
        name->rdns = rdnp =
 
369
            (CERTRDN**) PORT_ArenaAlloc(arena, (count + 1) * sizeof(CERTRDN*));
 
370
        if (!name->rdns) {
 
371
            goto loser;
 
372
        }
 
373
 
 
374
        /* Now fill in the pointers */
 
375
        if (count > 0) {
 
376
            *rdnp++ = rdn0;
 
377
            va_start(ap, rdn0);
 
378
            while ((rdn = va_arg(ap, CERTRDN*)) != 0) {
 
379
                *rdnp++ = rdn;
 
380
            }
 
381
            va_end(ap);
 
382
        }
 
383
 
 
384
        /* null terminate the list */
 
385
        *rdnp++ = 0;
 
386
    }
 
387
    return name;
 
388
 
 
389
loser:
 
390
    PORT_FreeArena(arena, PR_FALSE);
 
391
    return(0);
 
392
}
 
393
 
 
394
void
 
395
CERT_DestroyName(CERTName *name)
 
396
{
 
397
    if (name)
 
398
    {
 
399
        PRArenaPool *arena = name->arena;
 
400
        name->rdns = NULL;
 
401
        name->arena = NULL;
 
402
        if (arena) PORT_FreeArena(arena, PR_FALSE);
 
403
    }
 
404
}
 
405
 
 
406
SECStatus
 
407
CERT_AddRDN(CERTName *name, CERTRDN *rdn)
 
408
{
 
409
    name->rdns = (CERTRDN**) AddToArray(name->arena, (void**) name->rdns, rdn);
 
410
    return name->rdns ? SECSuccess : SECFailure;
 
411
}
 
412
 
 
413
SECStatus
 
414
CERT_CopyName(PRArenaPool *arena, CERTName *to, CERTName *from)
 
415
{
 
416
    CERTRDN **rdns, *frdn, *trdn;
 
417
    SECStatus rv = SECSuccess;
 
418
 
 
419
    if (!to || !from) {
 
420
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
 
421
        return SECFailure;
 
422
    }
 
423
 
 
424
    CERT_DestroyName(to);
 
425
    to->arena = arena;
 
426
 
 
427
    /* Copy each rdn from from */
 
428
    rdns = from->rdns;
 
429
    if (rdns) {
 
430
        if (rdns[0] == NULL) {
 
431
            rv = CERT_AddRDN(to, NULL);
 
432
            return rv;
 
433
        }
 
434
        while ((frdn = *rdns++) != NULL) {
 
435
            trdn = CERT_CreateRDN(arena, 0);
 
436
            if (!trdn) {
 
437
                rv = SECFailure;
 
438
                break;
 
439
            }
 
440
            rv = CERT_CopyRDN(arena, trdn, frdn);
 
441
            if (rv != SECSuccess) 
 
442
                break;
 
443
            rv = CERT_AddRDN(to, trdn);
 
444
            if (rv != SECSuccess) 
 
445
                break;
 
446
        }
 
447
    }
 
448
    return rv;
 
449
}
 
450
 
 
451
/************************************************************************/
 
452
 
 
453
static void
 
454
canonicalize(SECItem * foo)
 
455
{
 
456
    int ch, lastch, len, src, dest;
 
457
 
 
458
    /* strip trailing whitespace. */
 
459
    len = foo->len;
 
460
    while (len > 0 && ((ch = foo->data[len - 1]) == ' ' || 
 
461
           ch == '\t' || ch == '\r' || ch == '\n')) {
 
462
        len--;
 
463
    }
 
464
 
 
465
    src = 0;
 
466
    /* strip leading whitespace. */
 
467
    while (src < len && ((ch = foo->data[src]) == ' ' || 
 
468
           ch == '\t' || ch == '\r' || ch == '\n')) {
 
469
        src++;
 
470
    }
 
471
    dest = 0; lastch = ' ';
 
472
    while (src < len) {
 
473
        ch = foo->data[src++];
 
474
        if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') {
 
475
            ch = ' ';
 
476
            if (ch == lastch)
 
477
                continue;
 
478
        } else if (ch >= 'A' && ch <= 'Z') {
 
479
            ch |= 0x20;  /* downshift */
 
480
        }
 
481
        foo->data[dest++] = lastch = ch;
 
482
    }
 
483
    foo->len = dest;
 
484
}
 
485
 
 
486
/* SECItems a and b contain DER-encoded printable strings. */
 
487
SECComparison
 
488
CERT_CompareDERPrintableStrings(const SECItem *a, const SECItem *b)
 
489
{
 
490
    SECComparison rv = SECLessThan;
 
491
    SECItem * aVal = CERT_DecodeAVAValue(a);
 
492
    SECItem * bVal = CERT_DecodeAVAValue(b);
 
493
 
 
494
    if (aVal && aVal->len && aVal->data &&
 
495
        bVal && bVal->len && bVal->data) {
 
496
        canonicalize(aVal);
 
497
        canonicalize(bVal);
 
498
        rv = SECITEM_CompareItem(aVal, bVal);
 
499
    }
 
500
    SECITEM_FreeItem(aVal, PR_TRUE);
 
501
    SECITEM_FreeItem(bVal, PR_TRUE);
 
502
    return rv;
 
503
}
 
504
 
 
505
SECComparison
 
506
CERT_CompareAVA(const CERTAVA *a, const CERTAVA *b)
 
507
{
 
508
    SECComparison rv;
 
509
 
 
510
    rv = SECITEM_CompareItem(&a->type, &b->type);
 
511
    if (SECEqual != rv)
 
512
        return rv;  /* Attribute types don't match. */
 
513
    /* Let's be optimistic.  Maybe the values will just compare equal. */
 
514
    rv = SECITEM_CompareItem(&a->value, &b->value);
 
515
    if (SECEqual == rv)
 
516
        return rv;  /* values compared exactly. */
 
517
    if (a->value.len && a->value.data && b->value.len && b->value.data) {
 
518
        /* Here, the values did not match.  
 
519
        ** If the values had different encodings, convert them to the same
 
520
        ** encoding and compare that way.
 
521
        */
 
522
        if (a->value.data[0] != b->value.data[0]) {
 
523
            /* encodings differ.  Convert both to UTF-8 and compare. */
 
524
            SECItem * aVal = CERT_DecodeAVAValue(&a->value);
 
525
            SECItem * bVal = CERT_DecodeAVAValue(&b->value);
 
526
            if (aVal && aVal->len && aVal->data &&
 
527
                bVal && bVal->len && bVal->data) {
 
528
                rv = SECITEM_CompareItem(aVal, bVal);
 
529
            }
 
530
            SECITEM_FreeItem(aVal, PR_TRUE);
 
531
            SECITEM_FreeItem(bVal, PR_TRUE);
 
532
        } else if (a->value.data[0] == 0x13) { /* both are printable strings. */
 
533
            /* printable strings */
 
534
            rv = CERT_CompareDERPrintableStrings(&a->value, &b->value);
 
535
        }
 
536
    }
 
537
    return rv;
 
538
}
 
539
 
 
540
SECComparison
 
541
CERT_CompareRDN(CERTRDN *a, CERTRDN *b)
 
542
{
 
543
    CERTAVA **aavas, *aava;
 
544
    CERTAVA **bavas, *bava;
 
545
    int ac, bc;
 
546
    SECComparison rv = SECEqual;
 
547
 
 
548
    aavas = a->avas;
 
549
    bavas = b->avas;
 
550
 
 
551
    /*
 
552
    ** Make sure array of ava's are the same length. If not, then we are
 
553
    ** not equal
 
554
    */
 
555
    ac = CountArray((void**) aavas);
 
556
    bc = CountArray((void**) bavas);
 
557
    if (ac < bc) return SECLessThan;
 
558
    if (ac > bc) return SECGreaterThan;
 
559
 
 
560
    for (;;) {
 
561
        aava = *aavas++;
 
562
        bava = *bavas++;
 
563
        if (!aava) {
 
564
            break;
 
565
        }
 
566
        rv = CERT_CompareAVA(aava, bava);
 
567
        if (rv) return rv;
 
568
    }
 
569
    return rv;
 
570
}
 
571
 
 
572
SECComparison
 
573
CERT_CompareName(CERTName *a, CERTName *b)
 
574
{
 
575
    CERTRDN **ardns, *ardn;
 
576
    CERTRDN **brdns, *brdn;
 
577
    int ac, bc;
 
578
    SECComparison rv = SECEqual;
 
579
 
 
580
    ardns = a->rdns;
 
581
    brdns = b->rdns;
 
582
 
 
583
    /*
 
584
    ** Make sure array of rdn's are the same length. If not, then we are
 
585
    ** not equal
 
586
    */
 
587
    ac = CountArray((void**) ardns);
 
588
    bc = CountArray((void**) brdns);
 
589
    if (ac < bc) return SECLessThan;
 
590
    if (ac > bc) return SECGreaterThan;
 
591
 
 
592
    for (;;) {
 
593
        ardn = *ardns++;
 
594
        brdn = *brdns++;
 
595
        if (!ardn) {
 
596
            break;
 
597
        }
 
598
        rv = CERT_CompareRDN(ardn, brdn);
 
599
        if (rv) return rv;
 
600
    }
 
601
    return rv;
 
602
}
 
603
 
 
604
/* Moved from certhtml.c */
 
605
SECItem *
 
606
CERT_DecodeAVAValue(const SECItem *derAVAValue)
 
607
{
 
608
          SECItem          *retItem; 
 
609
    const SEC_ASN1Template *theTemplate       = NULL;
 
610
          enum { conv_none, conv_ucs4, conv_ucs2, conv_iso88591 } convert = conv_none;
 
611
          SECItem           avaValue          = {siBuffer, 0}; 
 
612
          PLArenaPool      *newarena          = NULL;
 
613
 
 
614
    if (!derAVAValue || !derAVAValue->len || !derAVAValue->data) {
 
615
        return NULL;
 
616
    }
 
617
 
 
618
    switch(derAVAValue->data[0]) {
 
619
        case SEC_ASN1_UNIVERSAL_STRING:
 
620
            convert = conv_ucs4;
 
621
            theTemplate = SEC_UniversalStringTemplate;
 
622
            break;
 
623
        case SEC_ASN1_IA5_STRING:
 
624
            theTemplate = SEC_IA5StringTemplate;
 
625
            break;
 
626
        case SEC_ASN1_PRINTABLE_STRING:
 
627
            theTemplate = SEC_PrintableStringTemplate;
 
628
            break;
 
629
        case SEC_ASN1_T61_STRING:
 
630
            /*
 
631
             * Per common practice, we're not decoding actual T.61, but instead
 
632
             * treating T61-labeled strings as containing ISO-8859-1.
 
633
             */
 
634
            convert = conv_iso88591;
 
635
            theTemplate = SEC_T61StringTemplate;
 
636
            break;
 
637
        case SEC_ASN1_BMP_STRING:
 
638
            convert = conv_ucs2;
 
639
            theTemplate = SEC_BMPStringTemplate;
 
640
            break;
 
641
        case SEC_ASN1_UTF8_STRING:
 
642
            /* No conversion needed ! */
 
643
            theTemplate = SEC_UTF8StringTemplate;
 
644
            break;
 
645
        default:
 
646
            return NULL;
 
647
    }
 
648
 
 
649
    PORT_Memset(&avaValue, 0, sizeof(SECItem));
 
650
    newarena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
 
651
    if (!newarena) {
 
652
        return NULL;
 
653
    }
 
654
    if(SEC_QuickDERDecodeItem(newarena, &avaValue, theTemplate, derAVAValue) 
 
655
                                != SECSuccess) {
 
656
        PORT_FreeArena(newarena, PR_FALSE);
 
657
        return NULL;
 
658
    }
 
659
 
 
660
    if (convert != conv_none) {
 
661
        unsigned int   utf8ValLen = avaValue.len * 3;
 
662
        unsigned char *utf8Val    = (unsigned char*)
 
663
                                    PORT_ArenaZAlloc(newarena, utf8ValLen);
 
664
 
 
665
        switch (convert) {
 
666
        case conv_ucs4:
 
667
           if(avaValue.len % 4 != 0 ||
 
668
              !PORT_UCS4_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len,
 
669
                                        utf8Val, utf8ValLen, &utf8ValLen)) {
 
670
                PORT_FreeArena(newarena, PR_FALSE);
 
671
                PORT_SetError(SEC_ERROR_INVALID_AVA);
 
672
                return NULL;
 
673
           }
 
674
           break;
 
675
        case conv_ucs2:
 
676
           if(avaValue.len % 2 != 0 ||
 
677
              !PORT_UCS2_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len,
 
678
                                        utf8Val, utf8ValLen, &utf8ValLen)) {
 
679
                PORT_FreeArena(newarena, PR_FALSE);
 
680
                PORT_SetError(SEC_ERROR_INVALID_AVA);
 
681
                return NULL;
 
682
           }
 
683
           break;
 
684
        case conv_iso88591:
 
685
           if(!PORT_ISO88591_UTF8Conversion(avaValue.data, avaValue.len,
 
686
                                        utf8Val, utf8ValLen, &utf8ValLen)) {
 
687
                PORT_FreeArena(newarena, PR_FALSE);
 
688
                PORT_SetError(SEC_ERROR_INVALID_AVA);
 
689
                return NULL;
 
690
           }
 
691
           break;
 
692
        case conv_none:
 
693
           PORT_Assert(0); /* not reached */
 
694
           break;
 
695
        }
 
696
          
 
697
        avaValue.data = utf8Val;
 
698
        avaValue.len = utf8ValLen;
 
699
    }
 
700
 
 
701
    retItem = SECITEM_DupItem(&avaValue);
 
702
    PORT_FreeArena(newarena, PR_FALSE);
 
703
    return retItem;
 
704
}