Coverage Report

Created: 2022-11-30 06:20

/src/openssl/crypto/objects/obj_dat.c
Line
Count
Source (jump to first uncovered line)
1
/* crypto/objects/obj_dat.c */
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 *
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 *
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 *
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 *
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 *
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
#include <stdio.h>
60
#include <ctype.h>
61
#include <limits.h>
62
#include "cryptlib.h"
63
#include <openssl/lhash.h>
64
#include <openssl/asn1.h>
65
#include <openssl/objects.h>
66
#include <openssl/bn.h>
67
68
/* obj_dat.h is generated from objects.h by obj_dat.pl */
69
#ifndef OPENSSL_NO_OBJECT
70
# include "obj_dat.h"
71
#else
72
/* You will have to load all the objects needed manually in the application */
73
# define NUM_NID 0
74
# define NUM_SN 0
75
# define NUM_LN 0
76
# define NUM_OBJ 0
77
static const unsigned char lvalues[1];
78
static const ASN1_OBJECT nid_objs[1];
79
static const unsigned int sn_objs[1];
80
static const unsigned int ln_objs[1];
81
static const unsigned int obj_objs[1];
82
#endif
83
84
DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
85
DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
86
DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
87
88
0
#define ADDED_DATA      0
89
0
#define ADDED_SNAME     1
90
0
#define ADDED_LNAME     2
91
0
#define ADDED_NID       3
92
93
typedef struct added_obj_st {
94
    int type;
95
    ASN1_OBJECT *obj;
96
} ADDED_OBJ;
97
DECLARE_LHASH_OF(ADDED_OBJ);
98
99
static int new_nid = NUM_NID;
100
static LHASH_OF(ADDED_OBJ) *added = NULL;
101
102
static int sn_cmp(const ASN1_OBJECT *const *a, const unsigned int *b)
103
0
{
104
0
    return (strcmp((*a)->sn, nid_objs[*b].sn));
105
0
}
106
107
IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
108
109
static int ln_cmp(const ASN1_OBJECT *const *a, const unsigned int *b)
110
0
{
111
0
    return (strcmp((*a)->ln, nid_objs[*b].ln));
112
0
}
113
114
IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
115
116
static unsigned long added_obj_hash(const ADDED_OBJ *ca)
117
0
{
118
0
    const ASN1_OBJECT *a;
119
0
    int i;
120
0
    unsigned long ret = 0;
121
0
    unsigned char *p;
122
123
0
    a = ca->obj;
124
0
    switch (ca->type) {
125
0
    case ADDED_DATA:
126
0
        ret = a->length << 20L;
127
0
        p = (unsigned char *)a->data;
128
0
        for (i = 0; i < a->length; i++)
129
0
            ret ^= p[i] << ((i * 3) % 24);
130
0
        break;
131
0
    case ADDED_SNAME:
132
0
        ret = lh_strhash(a->sn);
133
0
        break;
134
0
    case ADDED_LNAME:
135
0
        ret = lh_strhash(a->ln);
136
0
        break;
137
0
    case ADDED_NID:
138
0
        ret = a->nid;
139
0
        break;
140
0
    default:
141
        /* abort(); */
142
0
        return 0;
143
0
    }
144
0
    ret &= 0x3fffffffL;
145
0
    ret |= ((unsigned long)ca->type) << 30L;
146
0
    return (ret);
147
0
}
148
149
static IMPLEMENT_LHASH_HASH_FN(added_obj, ADDED_OBJ)
150
151
static int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb)
152
0
{
153
0
    ASN1_OBJECT *a, *b;
154
0
    int i;
155
156
0
    i = ca->type - cb->type;
157
0
    if (i)
158
0
        return (i);
159
0
    a = ca->obj;
160
0
    b = cb->obj;
161
0
    switch (ca->type) {
162
0
    case ADDED_DATA:
163
0
        i = (a->length - b->length);
164
0
        if (i)
165
0
            return (i);
166
0
        return (memcmp(a->data, b->data, (size_t)a->length));
167
0
    case ADDED_SNAME:
168
0
        if (a->sn == NULL)
169
0
            return (-1);
170
0
        else if (b->sn == NULL)
171
0
            return (1);
172
0
        else
173
0
            return (strcmp(a->sn, b->sn));
174
0
    case ADDED_LNAME:
175
0
        if (a->ln == NULL)
176
0
            return (-1);
177
0
        else if (b->ln == NULL)
178
0
            return (1);
179
0
        else
180
0
            return (strcmp(a->ln, b->ln));
181
0
    case ADDED_NID:
182
0
        return (a->nid - b->nid);
183
0
    default:
184
        /* abort(); */
185
0
        return 0;
186
0
    }
187
0
}
188
189
static IMPLEMENT_LHASH_COMP_FN(added_obj, ADDED_OBJ)
190
191
static int init_added(void)
192
0
{
193
0
    if (added != NULL)
194
0
        return (1);
195
0
    added = lh_ADDED_OBJ_new();
196
0
    return (added != NULL);
197
0
}
198
199
static void cleanup1_doall(ADDED_OBJ *a)
200
0
{
201
0
    a->obj->nid = 0;
202
0
    a->obj->flags |= ASN1_OBJECT_FLAG_DYNAMIC |
203
0
        ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA;
204
0
}
205
206
static void cleanup2_doall(ADDED_OBJ *a)
207
0
{
208
0
    a->obj->nid++;
209
0
}
210
211
static void cleanup3_doall(ADDED_OBJ *a)
212
0
{
213
0
    if (--a->obj->nid == 0)
214
0
        ASN1_OBJECT_free(a->obj);
215
0
    OPENSSL_free(a);
216
0
}
217
218
static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ)
219
static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ)
220
static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ)
221
222
/*
223
 * The purpose of obj_cleanup_defer is to avoid EVP_cleanup() attempting to
224
 * use freed up OIDs. If neccessary the actual freeing up of OIDs is delayed.
225
 */
226
int obj_cleanup_defer = 0;
227
228
void check_defer(int nid)
229
3.04k
{
230
3.04k
    if (!obj_cleanup_defer && nid >= NUM_NID)
231
0
        obj_cleanup_defer = 1;
232
3.04k
}
233
234
void OBJ_cleanup(void)
235
0
{
236
0
    if (obj_cleanup_defer) {
237
0
        obj_cleanup_defer = 2;
238
0
        return;
239
0
    }
240
0
    if (added == NULL)
241
0
        return;
242
0
    lh_ADDED_OBJ_down_load(added) = 0;
243
0
    lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup1)); /* zero counters */
244
0
    lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup2)); /* set counters */
245
0
    lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup3)); /* free objects */
246
0
    lh_ADDED_OBJ_free(added);
247
0
    added = NULL;
248
0
}
249
250
int OBJ_new_nid(int num)
251
0
{
252
0
    int i;
253
254
0
    i = new_nid;
255
0
    new_nid += num;
256
0
    return (i);
257
0
}
258
259
int OBJ_add_object(const ASN1_OBJECT *obj)
260
0
{
261
0
    ASN1_OBJECT *o;
262
0
    ADDED_OBJ *ao[4] = { NULL, NULL, NULL, NULL }, *aop;
263
0
    int i;
264
265
0
    if (added == NULL)
266
0
        if (!init_added())
267
0
            return (0);
268
0
    if ((o = OBJ_dup(obj)) == NULL)
269
0
        goto err;
270
0
    if (!(ao[ADDED_NID] = (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ))))
271
0
        goto err2;
272
0
    if ((o->length != 0) && (obj->data != NULL))
273
0
        if (!
274
0
            (ao[ADDED_DATA] = (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ))))
275
0
            goto err2;
276
0
    if (o->sn != NULL)
277
0
        if (!
278
0
            (ao[ADDED_SNAME] =
279
0
             (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ))))
280
0
            goto err2;
281
0
    if (o->ln != NULL)
282
0
        if (!
283
0
            (ao[ADDED_LNAME] =
284
0
             (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ))))
285
0
            goto err2;
286
287
0
    for (i = ADDED_DATA; i <= ADDED_NID; i++) {
288
0
        if (ao[i] != NULL) {
289
0
            ao[i]->type = i;
290
0
            ao[i]->obj = o;
291
0
            aop = lh_ADDED_OBJ_insert(added, ao[i]);
292
            /* memory leak, buit should not normally matter */
293
0
            if (aop != NULL)
294
0
                OPENSSL_free(aop);
295
0
        }
296
0
    }
297
0
    o->flags &=
298
0
        ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
299
0
          ASN1_OBJECT_FLAG_DYNAMIC_DATA);
300
301
0
    return (o->nid);
302
0
 err2:
303
0
    OBJerr(OBJ_F_OBJ_ADD_OBJECT, ERR_R_MALLOC_FAILURE);
304
0
 err:
305
0
    for (i = ADDED_DATA; i <= ADDED_NID; i++)
306
0
        if (ao[i] != NULL)
307
0
            OPENSSL_free(ao[i]);
308
0
    if (o != NULL)
309
0
        OPENSSL_free(o);
310
0
    return (NID_undef);
311
0
}
312
313
ASN1_OBJECT *OBJ_nid2obj(int n)
314
3.40M
{
315
3.40M
    ADDED_OBJ ad, *adp;
316
3.40M
    ASN1_OBJECT ob;
317
318
3.40M
    if ((n >= 0) && (n < NUM_NID)) {
319
3.40M
        if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
320
0
            OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID);
321
0
            return (NULL);
322
0
        }
323
3.40M
        return ((ASN1_OBJECT *)&(nid_objs[n]));
324
3.40M
    } else if (added == NULL)
325
0
        return (NULL);
326
0
    else {
327
0
        ad.type = ADDED_NID;
328
0
        ad.obj = &ob;
329
0
        ob.nid = n;
330
0
        adp = lh_ADDED_OBJ_retrieve(added, &ad);
331
0
        if (adp != NULL)
332
0
            return (adp->obj);
333
0
        else {
334
0
            OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID);
335
0
            return (NULL);
336
0
        }
337
0
    }
338
3.40M
}
339
340
const char *OBJ_nid2sn(int n)
341
594k
{
342
594k
    ADDED_OBJ ad, *adp;
343
594k
    ASN1_OBJECT ob;
344
345
594k
    if ((n >= 0) && (n < NUM_NID)) {
346
594k
        if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
347
0
            OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID);
348
0
            return (NULL);
349
0
        }
350
594k
        return (nid_objs[n].sn);
351
594k
    } else if (added == NULL)
352
0
        return (NULL);
353
0
    else {
354
0
        ad.type = ADDED_NID;
355
0
        ad.obj = &ob;
356
0
        ob.nid = n;
357
0
        adp = lh_ADDED_OBJ_retrieve(added, &ad);
358
0
        if (adp != NULL)
359
0
            return (adp->obj->sn);
360
0
        else {
361
0
            OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID);
362
0
            return (NULL);
363
0
        }
364
0
    }
365
594k
}
366
367
const char *OBJ_nid2ln(int n)
368
3.04k
{
369
3.04k
    ADDED_OBJ ad, *adp;
370
3.04k
    ASN1_OBJECT ob;
371
372
3.04k
    if ((n >= 0) && (n < NUM_NID)) {
373
3.04k
        if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
374
0
            OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID);
375
0
            return (NULL);
376
0
        }
377
3.04k
        return (nid_objs[n].ln);
378
3.04k
    } else if (added == NULL)
379
0
        return (NULL);
380
0
    else {
381
0
        ad.type = ADDED_NID;
382
0
        ad.obj = &ob;
383
0
        ob.nid = n;
384
0
        adp = lh_ADDED_OBJ_retrieve(added, &ad);
385
0
        if (adp != NULL)
386
0
            return (adp->obj->ln);
387
0
        else {
388
0
            OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID);
389
0
            return (NULL);
390
0
        }
391
0
    }
392
3.04k
}
393
394
static int obj_cmp(const ASN1_OBJECT *const *ap, const unsigned int *bp)
395
5.48M
{
396
5.48M
    int j;
397
5.48M
    const ASN1_OBJECT *a = *ap;
398
5.48M
    const ASN1_OBJECT *b = &nid_objs[*bp];
399
400
5.48M
    j = (a->length - b->length);
401
5.48M
    if (j)
402
2.08M
        return (j);
403
3.39M
    if (a->length == 0)
404
0
        return 0;
405
3.39M
    return (memcmp(a->data, b->data, a->length));
406
3.39M
}
407
408
IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
409
410
int OBJ_obj2nid(const ASN1_OBJECT *a)
411
596k
{
412
596k
    const unsigned int *op;
413
596k
    ADDED_OBJ ad, *adp;
414
415
596k
    if (a == NULL)
416
0
        return (NID_undef);
417
596k
    if (a->nid != 0)
418
0
        return (a->nid);
419
420
596k
    if (a->length == 0)
421
0
        return NID_undef;
422
423
596k
    if (added != NULL) {
424
0
        ad.type = ADDED_DATA;
425
0
        ad.obj = (ASN1_OBJECT *)a; /* XXX: ugly but harmless */
426
0
        adp = lh_ADDED_OBJ_retrieve(added, &ad);
427
0
        if (adp != NULL)
428
0
            return (adp->obj->nid);
429
0
    }
430
596k
    op = OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ);
431
596k
    if (op == NULL)
432
4.97k
        return (NID_undef);
433
591k
    return (nid_objs[*op].nid);
434
596k
}
435
436
/*
437
 * Convert an object name into an ASN1_OBJECT if "noname" is not set then
438
 * search for short and long names first. This will convert the "dotted" form
439
 * into an object: unlike OBJ_txt2nid it can be used with any objects, not
440
 * just registered ones.
441
 */
442
443
ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name)
444
0
{
445
0
    int nid = NID_undef;
446
0
    ASN1_OBJECT *op = NULL;
447
0
    unsigned char *buf;
448
0
    unsigned char *p;
449
0
    const unsigned char *cp;
450
0
    int i, j;
451
452
0
    if (!no_name) {
453
0
        if (((nid = OBJ_sn2nid(s)) != NID_undef) ||
454
0
            ((nid = OBJ_ln2nid(s)) != NID_undef))
455
0
            return OBJ_nid2obj(nid);
456
0
    }
457
458
    /* Work out size of content octets */
459
0
    i = a2d_ASN1_OBJECT(NULL, 0, s, -1);
460
0
    if (i <= 0) {
461
        /* Don't clear the error */
462
        /*
463
         * ERR_clear_error();
464
         */
465
0
        return NULL;
466
0
    }
467
    /* Work out total size */
468
0
    j = ASN1_object_size(0, i, V_ASN1_OBJECT);
469
470
0
    if ((buf = (unsigned char *)OPENSSL_malloc(j)) == NULL)
471
0
        return NULL;
472
473
0
    p = buf;
474
    /* Write out tag+length */
475
0
    ASN1_put_object(&p, 0, i, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
476
    /* Write out contents */
477
0
    a2d_ASN1_OBJECT(p, i, s, -1);
478
479
0
    cp = buf;
480
0
    op = d2i_ASN1_OBJECT(NULL, &cp, j);
481
0
    OPENSSL_free(buf);
482
0
    return op;
483
0
}
484
485
int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
486
2.48k
{
487
2.48k
    int i, n = 0, len, nid, first, use_bn;
488
2.48k
    BIGNUM *bl;
489
2.48k
    unsigned long l;
490
2.48k
    const unsigned char *p;
491
2.48k
    char tbuf[DECIMAL_SIZE(i) + DECIMAL_SIZE(l) + 2];
492
493
    /* Ensure that, at every state, |buf| is NUL-terminated. */
494
2.48k
    if (buf && buf_len > 0)
495
2.48k
        buf[0] = '\0';
496
497
2.48k
    if ((a == NULL) || (a->data == NULL))
498
0
        return (0);
499
500
2.48k
    if (!no_name && (nid = OBJ_obj2nid(a)) != NID_undef) {
501
0
        const char *s;
502
0
        s = OBJ_nid2ln(nid);
503
0
        if (s == NULL)
504
0
            s = OBJ_nid2sn(nid);
505
0
        if (s) {
506
0
            if (buf)
507
0
                BUF_strlcpy(buf, s, buf_len);
508
0
            n = strlen(s);
509
0
            return n;
510
0
        }
511
0
    }
512
513
2.48k
    len = a->length;
514
2.48k
    p = a->data;
515
516
2.48k
    first = 1;
517
2.48k
    bl = NULL;
518
519
9.94k
    while (len > 0) {
520
7.45k
        l = 0;
521
7.45k
        use_bn = 0;
522
7.45k
        for (;;) {
523
7.45k
            unsigned char c = *p++;
524
7.45k
            len--;
525
7.45k
            if ((len == 0) && (c & 0x80))
526
0
                goto err;
527
7.45k
            if (use_bn) {
528
0
                if (!BN_add_word(bl, c & 0x7f))
529
0
                    goto err;
530
0
            } else
531
7.45k
                l |= c & 0x7f;
532
7.45k
            if (!(c & 0x80))
533
7.45k
                break;
534
0
            if (!use_bn && (l > (ULONG_MAX >> 7L))) {
535
0
                if (!bl && !(bl = BN_new()))
536
0
                    goto err;
537
0
                if (!BN_set_word(bl, l))
538
0
                    goto err;
539
0
                use_bn = 1;
540
0
            }
541
0
            if (use_bn) {
542
0
                if (!BN_lshift(bl, bl, 7))
543
0
                    goto err;
544
0
            } else
545
0
                l <<= 7L;
546
0
        }
547
548
7.45k
        if (first) {
549
2.48k
            first = 0;
550
2.48k
            if (l >= 80) {
551
2.48k
                i = 2;
552
2.48k
                if (use_bn) {
553
0
                    if (!BN_sub_word(bl, 80))
554
0
                        goto err;
555
0
                } else
556
2.48k
                    l -= 80;
557
2.48k
            } else {
558
0
                i = (int)(l / 40);
559
0
                l -= (long)(i * 40);
560
0
            }
561
2.48k
            if (buf && (buf_len > 1)) {
562
2.48k
                *buf++ = i + '0';
563
2.48k
                *buf = '\0';
564
2.48k
                buf_len--;
565
2.48k
            }
566
2.48k
            n++;
567
2.48k
        }
568
569
7.45k
        if (use_bn) {
570
0
            char *bndec;
571
0
            bndec = BN_bn2dec(bl);
572
0
            if (!bndec)
573
0
                goto err;
574
0
            i = strlen(bndec);
575
0
            if (buf) {
576
0
                if (buf_len > 1) {
577
0
                    *buf++ = '.';
578
0
                    *buf = '\0';
579
0
                    buf_len--;
580
0
                }
581
0
                BUF_strlcpy(buf, bndec, buf_len);
582
0
                if (i > buf_len) {
583
0
                    buf += buf_len;
584
0
                    buf_len = 0;
585
0
                } else {
586
0
                    buf += i;
587
0
                    buf_len -= i;
588
0
                }
589
0
            }
590
0
            n++;
591
0
            n += i;
592
0
            OPENSSL_free(bndec);
593
7.45k
        } else {
594
7.45k
            BIO_snprintf(tbuf, sizeof tbuf, ".%lu", l);
595
7.45k
            i = strlen(tbuf);
596
7.45k
            if (buf && (buf_len > 0)) {
597
7.45k
                BUF_strlcpy(buf, tbuf, buf_len);
598
7.45k
                if (i > buf_len) {
599
0
                    buf += buf_len;
600
0
                    buf_len = 0;
601
7.45k
                } else {
602
7.45k
                    buf += i;
603
7.45k
                    buf_len -= i;
604
7.45k
                }
605
7.45k
            }
606
7.45k
            n += i;
607
7.45k
            l = 0;
608
7.45k
        }
609
7.45k
    }
610
611
2.48k
    if (bl)
612
0
        BN_free(bl);
613
2.48k
    return n;
614
615
0
 err:
616
0
    if (bl)
617
0
        BN_free(bl);
618
0
    return -1;
619
2.48k
}
620
621
int OBJ_txt2nid(const char *s)
622
0
{
623
0
    ASN1_OBJECT *obj;
624
0
    int nid;
625
0
    obj = OBJ_txt2obj(s, 0);
626
0
    nid = OBJ_obj2nid(obj);
627
0
    ASN1_OBJECT_free(obj);
628
0
    return nid;
629
0
}
630
631
int OBJ_ln2nid(const char *s)
632
0
{
633
0
    ASN1_OBJECT o;
634
0
    const ASN1_OBJECT *oo = &o;
635
0
    ADDED_OBJ ad, *adp;
636
0
    const unsigned int *op;
637
638
0
    o.ln = s;
639
0
    if (added != NULL) {
640
0
        ad.type = ADDED_LNAME;
641
0
        ad.obj = &o;
642
0
        adp = lh_ADDED_OBJ_retrieve(added, &ad);
643
0
        if (adp != NULL)
644
0
            return (adp->obj->nid);
645
0
    }
646
0
    op = OBJ_bsearch_ln(&oo, ln_objs, NUM_LN);
647
0
    if (op == NULL)
648
0
        return (NID_undef);
649
0
    return (nid_objs[*op].nid);
650
0
}
651
652
int OBJ_sn2nid(const char *s)
653
0
{
654
0
    ASN1_OBJECT o;
655
0
    const ASN1_OBJECT *oo = &o;
656
0
    ADDED_OBJ ad, *adp;
657
0
    const unsigned int *op;
658
659
0
    o.sn = s;
660
0
    if (added != NULL) {
661
0
        ad.type = ADDED_SNAME;
662
0
        ad.obj = &o;
663
0
        adp = lh_ADDED_OBJ_retrieve(added, &ad);
664
0
        if (adp != NULL)
665
0
            return (adp->obj->nid);
666
0
    }
667
0
    op = OBJ_bsearch_sn(&oo, sn_objs, NUM_SN);
668
0
    if (op == NULL)
669
0
        return (NID_undef);
670
0
    return (nid_objs[*op].nid);
671
0
}
672
673
const void *OBJ_bsearch_(const void *key, const void *base, int num, int size,
674
                         int (*cmp) (const void *, const void *))
675
596k
{
676
596k
    return OBJ_bsearch_ex_(key, base, num, size, cmp, 0);
677
596k
}
678
679
const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num,
680
                            int size,
681
                            int (*cmp) (const void *, const void *),
682
                            int flags)
683
754k
{
684
754k
    const char *base = base_;
685
754k
    int l, h, i = 0, c = 0;
686
754k
    const char *p = NULL;
687
688
754k
    if (num == 0)
689
1.24k
        return (NULL);
690
753k
    l = 0;
691
753k
    h = num;
692
6.53M
    while (l < h) {
693
6.37M
        i = (l + h) / 2;
694
6.37M
        p = &(base[i * size]);
695
6.37M
        c = (*cmp) (key, p);
696
6.37M
        if (c < 0)
697
4.01M
            h = i;
698
2.35M
        else if (c > 0)
699
1.76M
            l = i + 1;
700
591k
        else
701
591k
            break;
702
6.37M
    }
703
#ifdef CHARSET_EBCDIC
704
    /*
705
     * THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and I
706
     * don't have perl (yet), we revert to a *LINEAR* search when the object
707
     * wasn't found in the binary search.
708
     */
709
    if (c != 0) {
710
        for (i = 0; i < num; ++i) {
711
            p = &(base[i * size]);
712
            c = (*cmp) (key, p);
713
            if (c == 0 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
714
                return p;
715
        }
716
    }
717
#endif
718
753k
    if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))
719
161k
        p = NULL;
720
591k
    else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH)) {
721
0
        while (i > 0 && (*cmp) (key, &(base[(i - 1) * size])) == 0)
722
0
            i--;
723
0
        p = &(base[i * size]);
724
0
    }
725
753k
    return (p);
726
754k
}
727
728
int OBJ_create_objects(BIO *in)
729
0
{
730
0
    MS_STATIC char buf[512];
731
0
    int i, num = 0;
732
0
    char *o, *s, *l = NULL;
733
734
0
    for (;;) {
735
0
        s = o = NULL;
736
0
        i = BIO_gets(in, buf, 512);
737
0
        if (i <= 0)
738
0
            return (num);
739
0
        buf[i - 1] = '\0';
740
0
        if (!isalnum((unsigned char)buf[0]))
741
0
            return (num);
742
0
        o = s = buf;
743
0
        while (isdigit((unsigned char)*s) || (*s == '.'))
744
0
            s++;
745
0
        if (*s != '\0') {
746
0
            *(s++) = '\0';
747
0
            while (isspace((unsigned char)*s))
748
0
                s++;
749
0
            if (*s == '\0')
750
0
                s = NULL;
751
0
            else {
752
0
                l = s;
753
0
                while ((*l != '\0') && !isspace((unsigned char)*l))
754
0
                    l++;
755
0
                if (*l != '\0') {
756
0
                    *(l++) = '\0';
757
0
                    while (isspace((unsigned char)*l))
758
0
                        l++;
759
0
                    if (*l == '\0')
760
0
                        l = NULL;
761
0
                } else
762
0
                    l = NULL;
763
0
            }
764
0
        } else
765
0
            s = NULL;
766
0
        if ((o == NULL) || (*o == '\0'))
767
0
            return (num);
768
0
        if (!OBJ_create(o, s, l))
769
0
            return (num);
770
0
        num++;
771
0
    }
772
    /* return(num); */
773
0
}
774
775
int OBJ_create(const char *oid, const char *sn, const char *ln)
776
0
{
777
0
    int ok = 0;
778
0
    ASN1_OBJECT *op = NULL;
779
0
    unsigned char *buf;
780
0
    int i;
781
782
0
    i = a2d_ASN1_OBJECT(NULL, 0, oid, -1);
783
0
    if (i <= 0)
784
0
        return (0);
785
786
0
    if ((buf = (unsigned char *)OPENSSL_malloc(i)) == NULL) {
787
0
        OBJerr(OBJ_F_OBJ_CREATE, ERR_R_MALLOC_FAILURE);
788
0
        return (0);
789
0
    }
790
0
    i = a2d_ASN1_OBJECT(buf, i, oid, -1);
791
0
    if (i == 0)
792
0
        goto err;
793
0
    op = (ASN1_OBJECT *)ASN1_OBJECT_create(OBJ_new_nid(1), buf, i, sn, ln);
794
0
    if (op == NULL)
795
0
        goto err;
796
0
    ok = OBJ_add_object(op);
797
0
 err:
798
0
    ASN1_OBJECT_free(op);
799
0
    OPENSSL_free(buf);
800
0
    return (ok);
801
0
}