]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/objects/obj_dat.c
OPENSSL_NO_xxx cleanup: many removals
[thirdparty/openssl.git] / crypto / objects / obj_dat.c
CommitLineData
d02b48c6 1/* crypto/objects/obj_dat.c */
58964a49 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
d02b48c6
RE
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.
0f113f3e 8 *
d02b48c6
RE
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).
0f113f3e 15 *
d02b48c6
RE
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.
0f113f3e 22 *
d02b48c6
RE
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 :-).
0f113f3e 37 * 4. If you include any Windows specific code (or a derivative thereof) from
d02b48c6
RE
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
0f113f3e 40 *
d02b48c6
RE
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.
0f113f3e 52 *
d02b48c6
RE
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>
58964a49 60#include <ctype.h>
452ae49d 61#include <limits.h>
d02b48c6 62#include "cryptlib.h"
ec577822
BM
63#include <openssl/lhash.h>
64#include <openssl/asn1.h>
65#include <openssl/objects.h>
1e26a8ba 66#include <openssl/bn.h>
d02b48c6
RE
67
68/* obj_dat.h is generated from objects.h by obj_dat.pl */
a00ae6c4 69#include "obj_dat.h"
d02b48c6 70
e19106f5
DSH
71DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
72DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
73DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
babb3798 74
0f113f3e
MC
75#define ADDED_DATA 0
76#define ADDED_SNAME 1
77#define ADDED_LNAME 2
78#define ADDED_NID 3
d02b48c6 79
0f113f3e
MC
80typedef struct added_obj_st {
81 int type;
82 ASN1_OBJECT *obj;
83} ADDED_OBJ;
3c1d6bbc 84DECLARE_LHASH_OF(ADDED_OBJ);
d02b48c6 85
0f113f3e
MC
86static int new_nid = NUM_NID;
87static LHASH_OF(ADDED_OBJ) *added = NULL;
d02b48c6 88
0f113f3e
MC
89static int sn_cmp(const ASN1_OBJECT *const *a, const unsigned int *b)
90{
91 return (strcmp((*a)->sn, nid_objs[*b].sn));
92}
d02b48c6 93
e19106f5 94IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
babb3798 95
0f113f3e
MC
96static int ln_cmp(const ASN1_OBJECT *const *a, const unsigned int *b)
97{
98 return (strcmp((*a)->ln, nid_objs[*b].ln));
99}
babb3798 100
e19106f5 101IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
d02b48c6 102
3c1d6bbc 103static unsigned long added_obj_hash(const ADDED_OBJ *ca)
0f113f3e
MC
104{
105 const ASN1_OBJECT *a;
106 int i;
107 unsigned long ret = 0;
108 unsigned char *p;
109
110 a = ca->obj;
111 switch (ca->type) {
112 case ADDED_DATA:
113 ret = a->length << 20L;
114 p = (unsigned char *)a->data;
115 for (i = 0; i < a->length; i++)
116 ret ^= p[i] << ((i * 3) % 24);
117 break;
118 case ADDED_SNAME:
119 ret = lh_strhash(a->sn);
120 break;
121 case ADDED_LNAME:
122 ret = lh_strhash(a->ln);
123 break;
124 case ADDED_NID:
125 ret = a->nid;
126 break;
127 default:
128 /* abort(); */
129 return 0;
130 }
131 ret &= 0x3fffffffL;
132 ret |= ((unsigned long)ca->type) << 30L;
133 return (ret);
134}
135
3c1d6bbc 136static IMPLEMENT_LHASH_HASH_FN(added_obj, ADDED_OBJ)
d02b48c6 137
3c1d6bbc 138static int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb)
0f113f3e
MC
139{
140 ASN1_OBJECT *a, *b;
141 int i;
142
143 i = ca->type - cb->type;
144 if (i)
145 return (i);
146 a = ca->obj;
147 b = cb->obj;
148 switch (ca->type) {
149 case ADDED_DATA:
150 i = (a->length - b->length);
151 if (i)
152 return (i);
153 return (memcmp(a->data, b->data, (size_t)a->length));
154 case ADDED_SNAME:
155 if (a->sn == NULL)
156 return (-1);
157 else if (b->sn == NULL)
158 return (1);
159 else
160 return (strcmp(a->sn, b->sn));
161 case ADDED_LNAME:
162 if (a->ln == NULL)
163 return (-1);
164 else if (b->ln == NULL)
165 return (1);
166 else
167 return (strcmp(a->ln, b->ln));
168 case ADDED_NID:
169 return (a->nid - b->nid);
170 default:
171 /* abort(); */
172 return 0;
173 }
174}
175
3c1d6bbc 176static IMPLEMENT_LHASH_COMP_FN(added_obj, ADDED_OBJ)
d02b48c6 177
6b691a5c 178static int init_added(void)
0f113f3e
MC
179{
180 if (added != NULL)
181 return (1);
182 added = lh_ADDED_OBJ_new();
183 return (added != NULL);
184}
d02b48c6 185
3c1d6bbc 186static void cleanup1_doall(ADDED_OBJ *a)
0f113f3e
MC
187{
188 a->obj->nid = 0;
189 a->obj->flags |= ASN1_OBJECT_FLAG_DYNAMIC |
190 ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA;
191}
d02b48c6 192
3c1d6bbc 193static void cleanup2_doall(ADDED_OBJ *a)
0f113f3e
MC
194{
195 a->obj->nid++;
196}
d02b48c6 197
3c1d6bbc 198static void cleanup3_doall(ADDED_OBJ *a)
0f113f3e
MC
199{
200 if (--a->obj->nid == 0)
201 ASN1_OBJECT_free(a->obj);
202 OPENSSL_free(a);
203}
d02b48c6 204
3c1d6bbc
BL
205static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ)
206static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ)
207static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ)
3c914840 208
0f113f3e
MC
209/*
210 * The purpose of obj_cleanup_defer is to avoid EVP_cleanup() attempting to
211 * use freed up OIDs. If necessary the actual freeing up of OIDs is delayed.
246e0931 212 */
246e0931
DSH
213int obj_cleanup_defer = 0;
214
215void check_defer(int nid)
0f113f3e
MC
216{
217 if (!obj_cleanup_defer && nid >= NUM_NID)
218 obj_cleanup_defer = 1;
219}
246e0931 220
6b691a5c 221void OBJ_cleanup(void)
0f113f3e
MC
222{
223 if (obj_cleanup_defer) {
224 obj_cleanup_defer = 2;
225 return;
226 }
227 if (added == NULL)
228 return;
229 lh_ADDED_OBJ_down_load(added) = 0;
230 lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup1)); /* zero counters */
231 lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup2)); /* set counters */
232 lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup3)); /* free objects */
233 lh_ADDED_OBJ_free(added);
234 added = NULL;
235}
d02b48c6 236
6b691a5c 237int OBJ_new_nid(int num)
0f113f3e
MC
238{
239 int i;
d02b48c6 240
0f113f3e
MC
241 i = new_nid;
242 new_nid += num;
243 return (i);
244}
d02b48c6 245
8d28d5f8 246int OBJ_add_object(const ASN1_OBJECT *obj)
0f113f3e
MC
247{
248 ASN1_OBJECT *o;
249 ADDED_OBJ *ao[4] = { NULL, NULL, NULL, NULL }, *aop;
250 int i;
251
252 if (added == NULL)
253 if (!init_added())
254 return (0);
255 if ((o = OBJ_dup(obj)) == NULL)
256 goto err;
257 if (!(ao[ADDED_NID] = (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ))))
258 goto err2;
259 if ((o->length != 0) && (obj->data != NULL))
260 if (!
261 (ao[ADDED_DATA] = (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ))))
262 goto err2;
263 if (o->sn != NULL)
264 if (!
265 (ao[ADDED_SNAME] =
266 (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ))))
267 goto err2;
268 if (o->ln != NULL)
269 if (!
270 (ao[ADDED_LNAME] =
271 (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ))))
272 goto err2;
273
274 for (i = ADDED_DATA; i <= ADDED_NID; i++) {
275 if (ao[i] != NULL) {
276 ao[i]->type = i;
277 ao[i]->obj = o;
278 aop = lh_ADDED_OBJ_insert(added, ao[i]);
279 /* memory leak, buit should not normally matter */
280 if (aop != NULL)
281 OPENSSL_free(aop);
282 }
283 }
284 o->flags &=
285 ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
286 ASN1_OBJECT_FLAG_DYNAMIC_DATA);
287
288 return (o->nid);
289 err2:
290 OBJerr(OBJ_F_OBJ_ADD_OBJECT, ERR_R_MALLOC_FAILURE);
291 err:
292 for (i = ADDED_DATA; i <= ADDED_NID; i++)
293 if (ao[i] != NULL)
294 OPENSSL_free(ao[i]);
295 if (o != NULL)
296 OPENSSL_free(o);
297 return (NID_undef);
298}
d02b48c6 299
6b691a5c 300ASN1_OBJECT *OBJ_nid2obj(int n)
0f113f3e
MC
301{
302 ADDED_OBJ ad, *adp;
303 ASN1_OBJECT ob;
304
305 if ((n >= 0) && (n < NUM_NID)) {
306 if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
307 OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID);
308 return (NULL);
309 }
310 return ((ASN1_OBJECT *)&(nid_objs[n]));
311 } else if (added == NULL)
312 return (NULL);
313 else {
314 ad.type = ADDED_NID;
315 ad.obj = &ob;
316 ob.nid = n;
317 adp = lh_ADDED_OBJ_retrieve(added, &ad);
318 if (adp != NULL)
319 return (adp->obj);
320 else {
321 OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID);
322 return (NULL);
323 }
324 }
325}
d02b48c6 326
6b691a5c 327const char *OBJ_nid2sn(int n)
0f113f3e
MC
328{
329 ADDED_OBJ ad, *adp;
330 ASN1_OBJECT ob;
331
332 if ((n >= 0) && (n < NUM_NID)) {
333 if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
334 OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID);
335 return (NULL);
336 }
337 return (nid_objs[n].sn);
338 } else if (added == NULL)
339 return (NULL);
340 else {
341 ad.type = ADDED_NID;
342 ad.obj = &ob;
343 ob.nid = n;
344 adp = lh_ADDED_OBJ_retrieve(added, &ad);
345 if (adp != NULL)
346 return (adp->obj->sn);
347 else {
348 OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID);
349 return (NULL);
350 }
351 }
352}
d02b48c6 353
6b691a5c 354const char *OBJ_nid2ln(int n)
0f113f3e
MC
355{
356 ADDED_OBJ ad, *adp;
357 ASN1_OBJECT ob;
358
359 if ((n >= 0) && (n < NUM_NID)) {
360 if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
361 OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID);
362 return (NULL);
363 }
364 return (nid_objs[n].ln);
365 } else if (added == NULL)
366 return (NULL);
367 else {
368 ad.type = ADDED_NID;
369 ad.obj = &ob;
370 ob.nid = n;
371 adp = lh_ADDED_OBJ_retrieve(added, &ad);
372 if (adp != NULL)
373 return (adp->obj->ln);
374 else {
375 OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID);
376 return (NULL);
377 }
378 }
379}
380
381static int obj_cmp(const ASN1_OBJECT *const *ap, const unsigned int *bp)
382{
383 int j;
384 const ASN1_OBJECT *a = *ap;
385 const ASN1_OBJECT *b = &nid_objs[*bp];
386
387 j = (a->length - b->length);
388 if (j)
389 return (j);
390 return (memcmp(a->data, b->data, a->length));
391}
babb3798 392
e19106f5 393IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
babb3798 394
8d28d5f8 395int OBJ_obj2nid(const ASN1_OBJECT *a)
0f113f3e
MC
396{
397 const unsigned int *op;
398 ADDED_OBJ ad, *adp;
399
400 if (a == NULL)
401 return (NID_undef);
402 if (a->nid != 0)
403 return (a->nid);
404
405 if (added != NULL) {
406 ad.type = ADDED_DATA;
407 ad.obj = (ASN1_OBJECT *)a; /* XXX: ugly but harmless */
408 adp = lh_ADDED_OBJ_retrieve(added, &ad);
409 if (adp != NULL)
410 return (adp->obj->nid);
411 }
412 op = OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ);
413 if (op == NULL)
414 return (NID_undef);
415 return (nid_objs[*op].nid);
416}
417
418/*
419 * Convert an object name into an ASN1_OBJECT if "noname" is not set then
420 * search for short and long names first. This will convert the "dotted" form
421 * into an object: unlike OBJ_txt2nid it can be used with any objects, not
422 * just registered ones.
2d723902
DSH
423 */
424
6b691a5c 425ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name)
0f113f3e
MC
426{
427 int nid = NID_undef;
428 ASN1_OBJECT *op = NULL;
429 unsigned char *buf;
430 unsigned char *p;
431 const unsigned char *cp;
432 int i, j;
433
434 if (!no_name) {
435 if (((nid = OBJ_sn2nid(s)) != NID_undef) ||
436 ((nid = OBJ_ln2nid(s)) != NID_undef))
437 return OBJ_nid2obj(nid);
438 }
439
440 /* Work out size of content octets */
441 i = a2d_ASN1_OBJECT(NULL, 0, s, -1);
442 if (i <= 0) {
443 /* Don't clear the error */
444 /*
445 * ERR_clear_error();
446 */
447 return NULL;
448 }
449 /* Work out total size */
450 j = ASN1_object_size(0, i, V_ASN1_OBJECT);
451
452 if ((buf = (unsigned char *)OPENSSL_malloc(j)) == NULL)
453 return NULL;
454
455 p = buf;
456 /* Write out tag+length */
457 ASN1_put_object(&p, 0, i, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
458 /* Write out contents */
459 a2d_ASN1_OBJECT(p, i, s, -1);
460
461 cp = buf;
462 op = d2i_ASN1_OBJECT(NULL, &cp, j);
463 OPENSSL_free(buf);
464 return op;
465}
d02b48c6 466
6343829a 467int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
3e3d2ea2 468{
0f113f3e
MC
469 int i, n = 0, len, nid, first, use_bn;
470 BIGNUM *bl;
471 unsigned long l;
472 const unsigned char *p;
473 char tbuf[DECIMAL_SIZE(i) + DECIMAL_SIZE(l) + 2];
474
475 /* Ensure that, at every state, |buf| is NUL-terminated. */
476 if (buf && buf_len > 0)
477 buf[0] = '\0';
478
479 if ((a == NULL) || (a->data == NULL))
480 return (0);
481
482 if (!no_name && (nid = OBJ_obj2nid(a)) != NID_undef) {
483 const char *s;
484 s = OBJ_nid2ln(nid);
485 if (s == NULL)
486 s = OBJ_nid2sn(nid);
487 if (s) {
488 if (buf)
489 BUF_strlcpy(buf, s, buf_len);
490 n = strlen(s);
491 return n;
492 }
493 }
494
495 len = a->length;
496 p = a->data;
497
498 first = 1;
499 bl = NULL;
500
501 while (len > 0) {
502 l = 0;
503 use_bn = 0;
504 for (;;) {
505 unsigned char c = *p++;
506 len--;
507 if ((len == 0) && (c & 0x80))
508 goto err;
509 if (use_bn) {
510 if (!BN_add_word(bl, c & 0x7f))
511 goto err;
512 } else
513 l |= c & 0x7f;
514 if (!(c & 0x80))
515 break;
516 if (!use_bn && (l > (ULONG_MAX >> 7L))) {
517 if (!bl && !(bl = BN_new()))
518 goto err;
519 if (!BN_set_word(bl, l))
520 goto err;
521 use_bn = 1;
522 }
523 if (use_bn) {
524 if (!BN_lshift(bl, bl, 7))
525 goto err;
526 } else
527 l <<= 7L;
528 }
529
530 if (first) {
531 first = 0;
532 if (l >= 80) {
533 i = 2;
534 if (use_bn) {
535 if (!BN_sub_word(bl, 80))
536 goto err;
537 } else
538 l -= 80;
539 } else {
540 i = (int)(l / 40);
541 l -= (long)(i * 40);
542 }
543 if (buf && (buf_len > 1)) {
544 *buf++ = i + '0';
545 *buf = '\0';
546 buf_len--;
547 }
548 n++;
549 }
550
551 if (use_bn) {
552 char *bndec;
553 bndec = BN_bn2dec(bl);
554 if (!bndec)
555 goto err;
556 i = strlen(bndec);
557 if (buf) {
558 if (buf_len > 1) {
559 *buf++ = '.';
560 *buf = '\0';
561 buf_len--;
562 }
563 BUF_strlcpy(buf, bndec, buf_len);
564 if (i > buf_len) {
565 buf += buf_len;
566 buf_len = 0;
567 } else {
568 buf += i;
569 buf_len -= i;
570 }
571 }
572 n++;
573 n += i;
574 OPENSSL_free(bndec);
575 } else {
576 BIO_snprintf(tbuf, sizeof tbuf, ".%lu", l);
577 i = strlen(tbuf);
578 if (buf && (buf_len > 0)) {
579 BUF_strlcpy(buf, tbuf, buf_len);
580 if (i > buf_len) {
581 buf += buf_len;
582 buf_len = 0;
583 } else {
584 buf += i;
585 buf_len -= i;
586 }
587 }
588 n += i;
589 l = 0;
590 }
591 }
592
593 if (bl)
594 BN_free(bl);
595 return n;
596
597 err:
598 if (bl)
599 BN_free(bl);
600 return -1;
3e3d2ea2
DSH
601}
602
8d28d5f8 603int OBJ_txt2nid(const char *s)
2d723902 604{
0f113f3e
MC
605 ASN1_OBJECT *obj;
606 int nid;
607 obj = OBJ_txt2obj(s, 0);
608 nid = OBJ_obj2nid(obj);
609 ASN1_OBJECT_free(obj);
610 return nid;
2d723902
DSH
611}
612
6b691a5c 613int OBJ_ln2nid(const char *s)
0f113f3e
MC
614{
615 ASN1_OBJECT o;
616 const ASN1_OBJECT *oo = &o;
617 ADDED_OBJ ad, *adp;
618 const unsigned int *op;
619
620 o.ln = s;
621 if (added != NULL) {
622 ad.type = ADDED_LNAME;
623 ad.obj = &o;
624 adp = lh_ADDED_OBJ_retrieve(added, &ad);
625 if (adp != NULL)
626 return (adp->obj->nid);
627 }
628 op = OBJ_bsearch_ln(&oo, ln_objs, NUM_LN);
629 if (op == NULL)
630 return (NID_undef);
631 return (nid_objs[*op].nid);
632}
d02b48c6 633
6b691a5c 634int OBJ_sn2nid(const char *s)
0f113f3e
MC
635{
636 ASN1_OBJECT o;
637 const ASN1_OBJECT *oo = &o;
638 ADDED_OBJ ad, *adp;
639 const unsigned int *op;
640
641 o.sn = s;
642 if (added != NULL) {
643 ad.type = ADDED_SNAME;
644 ad.obj = &o;
645 adp = lh_ADDED_OBJ_retrieve(added, &ad);
646 if (adp != NULL)
647 return (adp->obj->nid);
648 }
649 op = OBJ_bsearch_sn(&oo, sn_objs, NUM_SN);
650 if (op == NULL)
651 return (NID_undef);
652 return (nid_objs[*op].nid);
653}
d02b48c6 654
babb3798 655const void *OBJ_bsearch_(const void *key, const void *base, int num, int size,
0f113f3e
MC
656 int (*cmp) (const void *, const void *))
657{
658 return OBJ_bsearch_ex_(key, base, num, size, cmp, 0);
659}
ea5240a5 660
1ea6472e 661const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num,
0f113f3e
MC
662 int size,
663 int (*cmp) (const void *, const void *),
664 int flags)
665{
666 const char *base = base_;
667 int l, h, i = 0, c = 0;
668 const char *p = NULL;
669
670 if (num == 0)
671 return (NULL);
672 l = 0;
673 h = num;
674 while (l < h) {
675 i = (l + h) / 2;
676 p = &(base[i * size]);
677 c = (*cmp) (key, p);
678 if (c < 0)
679 h = i;
680 else if (c > 0)
681 l = i + 1;
682 else
683 break;
684 }
a53955d8 685#ifdef CHARSET_EBCDIC
0f113f3e
MC
686 /*
687 * THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and I
688 * don't have perl (yet), we revert to a *LINEAR* search when the object
689 * wasn't found in the binary search.
690 */
691 if (c != 0) {
692 for (i = 0; i < num; ++i) {
693 p = &(base[i * size]);
694 c = (*cmp) (key, p);
695 if (c == 0 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
696 return p;
697 }
698 }
a53955d8 699#endif
0f113f3e
MC
700 if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))
701 p = NULL;
702 else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH)) {
703 while (i > 0 && (*cmp) (key, &(base[(i - 1) * size])) == 0)
704 i--;
705 p = &(base[i * size]);
706 }
707 return (p);
708}
d02b48c6 709
6b691a5c 710int OBJ_create_objects(BIO *in)
0f113f3e 711{
68b00c23 712 char buf[512];
0f113f3e
MC
713 int i, num = 0;
714 char *o, *s, *l = NULL;
715
716 for (;;) {
717 s = o = NULL;
718 i = BIO_gets(in, buf, 512);
719 if (i <= 0)
720 return (num);
721 buf[i - 1] = '\0';
722 if (!isalnum((unsigned char)buf[0]))
723 return (num);
724 o = s = buf;
725 while (isdigit((unsigned char)*s) || (*s == '.'))
726 s++;
727 if (*s != '\0') {
728 *(s++) = '\0';
729 while (isspace((unsigned char)*s))
730 s++;
731 if (*s == '\0')
732 s = NULL;
733 else {
734 l = s;
735 while ((*l != '\0') && !isspace((unsigned char)*l))
736 l++;
737 if (*l != '\0') {
738 *(l++) = '\0';
739 while (isspace((unsigned char)*l))
740 l++;
741 if (*l == '\0')
742 l = NULL;
743 } else
744 l = NULL;
745 }
746 } else
747 s = NULL;
748 if ((o == NULL) || (*o == '\0'))
749 return (num);
750 if (!OBJ_create(o, s, l))
751 return (num);
752 num++;
753 }
754 /* return(num); */
755}
58964a49 756
8d28d5f8 757int OBJ_create(const char *oid, const char *sn, const char *ln)
0f113f3e
MC
758{
759 int ok = 0;
760 ASN1_OBJECT *op = NULL;
761 unsigned char *buf;
762 int i;
763
764 i = a2d_ASN1_OBJECT(NULL, 0, oid, -1);
765 if (i <= 0)
766 return (0);
767
768 if ((buf = (unsigned char *)OPENSSL_malloc(i)) == NULL) {
769 OBJerr(OBJ_F_OBJ_CREATE, ERR_R_MALLOC_FAILURE);
770 return (0);
771 }
772 i = a2d_ASN1_OBJECT(buf, i, oid, -1);
773 if (i == 0)
774 goto err;
775 op = (ASN1_OBJECT *)ASN1_OBJECT_create(OBJ_new_nid(1), buf, i, sn, ln);
776 if (op == NULL)
777 goto err;
778 ok = OBJ_add_object(op);
779 err:
780 ASN1_OBJECT_free(op);
781 OPENSSL_free(buf);
782 return (ok);
783}