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