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