~ubuntu-branches/ubuntu/jaunty/heimdal/jaunty

« back to all changes in this revision

Viewing changes to lib/hx509/name.c

  • Committer: Bazaar Package Importer
  • Author(s): Nick Ellery
  • Date: 2008-11-17 22:25:58 UTC
  • mfrom: (1.1.5 upstream) (2.1.2 lenny)
  • Revision ID: james.westby@ubuntu.com-20081117222558-jd1aj1jth6ycdb0x
Tags: 1.2.dfsg.1-2.1ubuntu1
* Merge from debian unstable, remaining changes (LP: #299345):
  - Change libdb4.2-dev to libdb4.6-dev in build-deps
  - Add netbase to heimdal-kdc depends.
  - Set CPPFLAGS=-DLDAP_DEPRECATED to fix build with OpenLDAP 2.4 on
    64-bit architectures.
* Remove dependency on update-inetd to heimdal-servers and heimdal-kdc,
  as packages should rely on the inet-superserver to provide the
  update-inetd command.
* Drop the addition of -1 to the version of comerr-dev in build depends.

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
 */
33
33
 
34
34
#include "hx_locl.h"
35
 
RCSID("$Id: name.c 22432 2008-01-13 14:08:03Z lha $");
 
35
#include <wind.h>
 
36
RCSID("$Id: name.c 22677 2008-03-13 17:35:49Z lha $");
36
37
 
37
38
/**
38
39
 * @page page_name PKIX/X.509 Names
63
64
static const struct {
64
65
    const char *n;
65
66
    const heim_oid *(*o)(void);
 
67
    wind_profile_flags flags;
66
68
} no[] = {
67
69
    { "C", oid_id_at_countryName },
68
70
    { "CN", oid_id_at_commonName },
279
281
    return 0;
280
282
}
281
283
 
282
 
/*
283
 
 * XXX this function is broken, it needs to compare code points, not
284
 
 * bytes.
285
 
 */
286
 
 
287
 
static void
288
 
prune_space(const unsigned char **s)
289
 
{
290
 
    while (**s == ' ')
291
 
        (*s)++;
292
 
}
293
 
 
294
 
int
295
 
_hx509_name_ds_cmp(const DirectoryString *ds1, const DirectoryString *ds2)
296
 
{
297
 
    int c;
298
 
 
299
 
    c = ds1->element - ds2->element;
300
 
    if (c)
301
 
        return c;
302
 
 
303
 
    switch(ds1->element) {
 
284
#define COPYCHARARRAY(_ds,_el,_l,_n)            \
 
285
        (_l) = strlen(_ds->u._el);              \
 
286
        (_n) = malloc((_l) * sizeof((_n)[0]));  \
 
287
        if ((_n) == NULL)                       \
 
288
            return ENOMEM;                      \
 
289
        for (i = 0; i < (_l); i++)              \
 
290
            (_n)[i] = _ds->u._el[i]
 
291
 
 
292
 
 
293
#define COPYVALARRAY(_ds,_el,_l,_n)             \
 
294
        (_l) = _ds->u._el.length;               \
 
295
        (_n) = malloc((_l) * sizeof((_n)[0]));  \
 
296
        if ((_n) == NULL)                       \
 
297
            return ENOMEM;                      \
 
298
        for (i = 0; i < (_l); i++)              \
 
299
            (_n)[i] = _ds->u._el.data[i]
 
300
 
 
301
#define COPYVOIDARRAY(_ds,_el,_l,_n)            \
 
302
        (_l) = _ds->u._el.length;               \
 
303
        (_n) = malloc((_l) * sizeof((_n)[0]));  \
 
304
        if ((_n) == NULL)                       \
 
305
            return ENOMEM;                      \
 
306
        for (i = 0; i < (_l); i++)              \
 
307
            (_n)[i] = ((unsigned char *)_ds->u._el.data)[i]
 
308
 
 
309
 
 
310
 
 
311
static int
 
312
dsstringprep(const DirectoryString *ds, uint32_t **rname, size_t *rlen)
 
313
{
 
314
    wind_profile_flags flags = 0;
 
315
    size_t i, len;
 
316
    int ret;
 
317
    uint32_t *name;
 
318
 
 
319
    *rname = NULL;
 
320
    *rlen = 0;
 
321
 
 
322
    switch(ds->element) {
304
323
    case choice_DirectoryString_ia5String:
305
 
        c = strcmp(ds1->u.ia5String, ds2->u.ia5String);
 
324
        COPYCHARARRAY(ds, ia5String, len, name);
 
325
        break;
 
326
    case choice_DirectoryString_printableString:
 
327
        flags = WIND_PROFILE_LDAP_CASE_EXACT_ATTRIBUTE;
 
328
        COPYCHARARRAY(ds, printableString, len, name);
306
329
        break;
307
330
    case choice_DirectoryString_teletexString:
308
 
        c = der_heim_octet_string_cmp(&ds1->u.teletexString,
309
 
                                  &ds2->u.teletexString);
310
 
        break;
311
 
    case choice_DirectoryString_printableString: {
312
 
        const unsigned char *s1 = (unsigned char*)ds1->u.printableString;
313
 
        const unsigned char *s2 = (unsigned char*)ds2->u.printableString;
314
 
        prune_space(&s1); prune_space(&s2);
315
 
        while (*s1 && *s2) {
316
 
            if (toupper(*s1) != toupper(*s2)) {
317
 
                c = toupper(*s1) - toupper(*s2);
318
 
                break;
319
 
            }
320
 
            if (*s1 == ' ') { prune_space(&s1); prune_space(&s2); }
321
 
            else { s1++; s2++; }
322
 
        }           
323
 
        prune_space(&s1); prune_space(&s2);
324
 
        c = *s1 - *s2;
325
 
        break;
326
 
    }
 
331
        COPYVOIDARRAY(ds, teletexString, len, name);
 
332
        break;
 
333
    case choice_DirectoryString_bmpString:
 
334
        COPYVALARRAY(ds, bmpString, len, name);
 
335
        break;
 
336
    case choice_DirectoryString_universalString:
 
337
        COPYVALARRAY(ds, universalString, len, name);
 
338
        break;
327
339
    case choice_DirectoryString_utf8String:
328
 
        c = strcmp(ds1->u.utf8String, ds2->u.utf8String);
329
 
        break;
330
 
    case choice_DirectoryString_universalString:
331
 
        c = der_heim_universal_string_cmp(&ds1->u.universalString,
332
 
                                          &ds2->u.universalString);
333
 
        break;
334
 
    case choice_DirectoryString_bmpString:
335
 
        c = der_heim_bmp_string_cmp(&ds1->u.bmpString,
336
 
                                    &ds2->u.bmpString);
 
340
        ret = wind_utf8ucs4_length(ds->u.utf8String, &len);
 
341
        if (ret)
 
342
            return ret;
 
343
        name = malloc(len * sizeof(name[0]));
 
344
        if (name == NULL)
 
345
            return ENOMEM;
 
346
        ret = wind_utf8ucs4(ds->u.utf8String, name, &len);
 
347
        if (ret)
 
348
            return ret;
337
349
        break;
338
350
    default:
339
 
        c = 1;
340
 
        break;
341
 
    }
342
 
    return c;
343
 
}
344
 
 
345
 
int
346
 
_hx509_name_cmp(const Name *n1, const Name *n2)
347
 
{
348
 
    int i, j, c;
349
 
 
350
 
    c = n1->u.rdnSequence.len - n2->u.rdnSequence.len;
351
 
    if (c)
352
 
        return c;
 
351
        _hx509_abort("unknown directory type: %d", ds->element);
 
352
    }
 
353
 
 
354
    *rlen = len;
 
355
    /* try a couple of times to get the length right, XXX gross */
 
356
    for (i = 0; i < 4; i++) {
 
357
        *rlen = *rlen * 2;
 
358
        *rname = malloc(*rlen * sizeof((*rname)[0]));
 
359
 
 
360
        ret = wind_stringprep(name, len, *rname, rlen,
 
361
                              WIND_PROFILE_LDAP|flags);
 
362
        if (ret == WIND_ERR_OVERRUN) {
 
363
            free(*rname);
 
364
            *rname = NULL;
 
365
            continue;
 
366
        } else
 
367
            break;
 
368
    }
 
369
    free(name);
 
370
    if (ret) {
 
371
        if (*rname)
 
372
            free(*rname);
 
373
        *rname = NULL;
 
374
        *rlen = 0;
 
375
        return ret;
 
376
    }
 
377
 
 
378
    return 0;
 
379
}
 
380
 
 
381
int
 
382
_hx509_name_ds_cmp(const DirectoryString *ds1,
 
383
                   const DirectoryString *ds2,
 
384
                   int *diff)
 
385
{
 
386
    uint32_t *ds1lp, *ds2lp;
 
387
    size_t ds1len, ds2len;
 
388
    int ret;
 
389
 
 
390
    ret = dsstringprep(ds1, &ds1lp, &ds1len);
 
391
    if (ret)
 
392
        return ret;
 
393
    ret = dsstringprep(ds2, &ds2lp, &ds2len);
 
394
    if (ret) {
 
395
        free(ds1lp);
 
396
        return ret;
 
397
    }
 
398
 
 
399
    if (ds1len != ds2len)
 
400
        *diff = ds1len - ds2len;
 
401
    else
 
402
        *diff = memcmp(ds1lp, ds2lp, ds1len * sizeof(ds1lp[0]));
 
403
 
 
404
    free(ds1lp);
 
405
    free(ds2lp);
 
406
 
 
407
    return 0;
 
408
}
 
409
 
 
410
int
 
411
_hx509_name_cmp(const Name *n1, const Name *n2, int *c)
 
412
{
 
413
    int ret, i, j;
 
414
 
 
415
    *c = n1->u.rdnSequence.len - n2->u.rdnSequence.len;
 
416
    if (*c)
 
417
        return 0;
353
418
 
354
419
    for (i = 0 ; i < n1->u.rdnSequence.len; i++) {
355
 
        c = n1->u.rdnSequence.val[i].len - n2->u.rdnSequence.val[i].len;
356
 
        if (c)
357
 
            return c;
 
420
        *c = n1->u.rdnSequence.val[i].len - n2->u.rdnSequence.val[i].len;
 
421
        if (*c)
 
422
            return 0;
358
423
 
359
424
        for (j = 0; j < n1->u.rdnSequence.val[i].len; j++) {
360
 
            c = der_heim_oid_cmp(&n1->u.rdnSequence.val[i].val[j].type,
361
 
                                 &n1->u.rdnSequence.val[i].val[j].type);
362
 
            if (c)
363
 
                return c;
 
425
            *c = der_heim_oid_cmp(&n1->u.rdnSequence.val[i].val[j].type,
 
426
                                  &n1->u.rdnSequence.val[i].val[j].type);
 
427
            if (*c)
 
428
                return 0;
364
429
                             
365
 
            c = _hx509_name_ds_cmp(&n1->u.rdnSequence.val[i].val[j].value,
366
 
                                   &n2->u.rdnSequence.val[i].val[j].value);
367
 
            if (c)
368
 
                return c;
 
430
            ret = _hx509_name_ds_cmp(&n1->u.rdnSequence.val[i].val[j].value,
 
431
                                     &n2->u.rdnSequence.val[i].val[j].value,
 
432
                                     c);
 
433
            if (ret)
 
434
                return ret;
 
435
            if (*c)
 
436
                return 0;
369
437
        }
370
438
    }
 
439
    *c = 0;
371
440
    return 0;
372
441
}
373
442
 
386
455
int
387
456
hx509_name_cmp(hx509_name n1, hx509_name n2)
388
457
{
389
 
    return _hx509_name_cmp(&n1->der_name, &n2->der_name);
 
458
    int ret, diff;
 
459
    ret = _hx509_name_cmp(&n1->der_name, &n2->der_name, &diff);
 
460
    if (ret)
 
461
        return ret;
 
462
    return diff;
390
463
}
391
464
 
392
465
 
824
897
 * @param name the name to print
825
898
 * @param str an allocated string returns the name in string form
826
899
 *
827
 
 * @return An hx509 error code, see krb5_get_error_string().
 
900
 * @return An hx509 error code, see hx509_get_error_string().
828
901
 *
829
902
 * @ingroup hx509_name
830
903
 */