os/ossrv/ssl/libcrypto/src/crypto/objects/obj_dat.c
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/ssl/libcrypto/src/crypto/objects/obj_dat.c	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,811 @@
     1.4 +/* crypto/objects/obj_dat.c */
     1.5 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
     1.6 + * All rights reserved.
     1.7 + *
     1.8 + * This package is an SSL implementation written
     1.9 + * by Eric Young (eay@cryptsoft.com).
    1.10 + * The implementation was written so as to conform with Netscapes SSL.
    1.11 + * 
    1.12 + * This library is free for commercial and non-commercial use as long as
    1.13 + * the following conditions are aheared to.  The following conditions
    1.14 + * apply to all code found in this distribution, be it the RC4, RSA,
    1.15 + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
    1.16 + * included with this distribution is covered by the same copyright terms
    1.17 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
    1.18 + * 
    1.19 + * Copyright remains Eric Young's, and as such any Copyright notices in
    1.20 + * the code are not to be removed.
    1.21 + * If this package is used in a product, Eric Young should be given attribution
    1.22 + * as the author of the parts of the library used.
    1.23 + * This can be in the form of a textual message at program startup or
    1.24 + * in documentation (online or textual) provided with the package.
    1.25 + * 
    1.26 + * Redistribution and use in source and binary forms, with or without
    1.27 + * modification, are permitted provided that the following conditions
    1.28 + * are met:
    1.29 + * 1. Redistributions of source code must retain the copyright
    1.30 + *    notice, this list of conditions and the following disclaimer.
    1.31 + * 2. Redistributions in binary form must reproduce the above copyright
    1.32 + *    notice, this list of conditions and the following disclaimer in the
    1.33 + *    documentation and/or other materials provided with the distribution.
    1.34 + * 3. All advertising materials mentioning features or use of this software
    1.35 + *    must display the following acknowledgement:
    1.36 + *    "This product includes cryptographic software written by
    1.37 + *     Eric Young (eay@cryptsoft.com)"
    1.38 + *    The word 'cryptographic' can be left out if the rouines from the library
    1.39 + *    being used are not cryptographic related :-).
    1.40 + * 4. If you include any Windows specific code (or a derivative thereof) from 
    1.41 + *    the apps directory (application code) you must include an acknowledgement:
    1.42 + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
    1.43 + * 
    1.44 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
    1.45 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.46 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    1.47 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
    1.48 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    1.49 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    1.50 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    1.52 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    1.53 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    1.54 + * SUCH DAMAGE.
    1.55 + * 
    1.56 + * The licence and distribution terms for any publically available version or
    1.57 + * derivative of this code cannot be changed.  i.e. this code cannot simply be
    1.58 + * copied and put under another distribution licence
    1.59 + * [including the GNU Public Licence.]
    1.60 + */
    1.61 + /*
    1.62 + © Portions copyright (c) 2006 Nokia Corporation.  All rights reserved.
    1.63 + */
    1.64 +
    1.65 +
    1.66 +
    1.67 +#include <stdio.h>
    1.68 +#include <ctype.h>
    1.69 +#include <limits.h>
    1.70 +#include "cryptlib.h"
    1.71 +#include <openssl/lhash.h>
    1.72 +#include <openssl/asn1.h>
    1.73 +#include <openssl/objects.h>
    1.74 +#include <openssl/bn.h>
    1.75 +#if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
    1.76 +#include "libcrypto_wsd_macros.h"
    1.77 +#include "libcrypto_wsd.h"
    1.78 +#endif
    1.79 +
    1.80 +
    1.81 +/* obj_dat.h is generated from objects.h by obj_dat.pl */
    1.82 +#ifndef OPENSSL_NO_OBJECT
    1.83 +#include "obj_dat.h"
    1.84 +#else
    1.85 +/* You will have to load all the objects needed manually in the application */
    1.86 +#define NUM_NID 0
    1.87 +#define NUM_SN 0
    1.88 +#define NUM_LN 0
    1.89 +#define NUM_OBJ 0
    1.90 +#ifndef EMULATOR
    1.91 +static unsigned char lvalues[1];
    1.92 +static ASN1_OBJECT nid_objs[1];
    1.93 +static ASN1_OBJECT *sn_objs[1];
    1.94 +static ASN1_OBJECT *ln_objs[1];
    1.95 +static ASN1_OBJECT *obj_objs[1];
    1.96 +#else //EMULATOR
    1.97 +static const unsigned char lvalues[1];
    1.98 +static const ASN1_OBJECT nid_objs[1];
    1.99 +static const ASN1_OBJECT *sn_objs[1];
   1.100 +static const ASN1_OBJECT *ln_objs[1];
   1.101 +static const ASN1_OBJECT *obj_objs[1];
   1.102 +#endif //EMULATOR
   1.103 +#endif
   1.104 +
   1.105 +static int sn_cmp(const void *a, const void *b);
   1.106 +static int ln_cmp(const void *a, const void *b);
   1.107 +static int obj_cmp(const void *a, const void *b);
   1.108 +#define ADDED_DATA	0
   1.109 +#define ADDED_SNAME	1
   1.110 +#define ADDED_LNAME	2
   1.111 +#define ADDED_NID	3
   1.112 +
   1.113 +typedef struct added_obj_st
   1.114 +	{
   1.115 +	int type;
   1.116 +	ASN1_OBJECT *obj;
   1.117 +	} ADDED_OBJ;
   1.118 +
   1.119 +#ifndef EMULATOR
   1.120 +static int new_nid=NUM_NID;
   1.121 +static LHASH *added=NULL;
   1.122 +#else
   1.123 +GET_STATIC_VAR_FROM_TLS(new_nid,obj_dat,int)
   1.124 +#define new_nid (*GET_WSD_VAR_NAME(new_nid,obj_dat, s)())
   1.125 +GET_STATIC_VAR_FROM_TLS(added,obj_dat,LHASH *)
   1.126 +#define added (*GET_WSD_VAR_NAME(added,obj_dat, s)())
   1.127 +#endif
   1.128 +
   1.129 +static int sn_cmp(const void *a, const void *b)
   1.130 +	{
   1.131 +	const ASN1_OBJECT * const *ap = a, * const *bp = b;
   1.132 +	return(strcmp((*ap)->sn,(*bp)->sn));
   1.133 +	}
   1.134 +
   1.135 +static int ln_cmp(const void *a, const void *b)
   1.136 +	{ 
   1.137 +	const ASN1_OBJECT * const *ap = a, * const *bp = b;
   1.138 +	return(strcmp((*ap)->ln,(*bp)->ln));
   1.139 +	}
   1.140 +
   1.141 +/* static unsigned long add_hash(ADDED_OBJ *ca) */
   1.142 +static unsigned long add_hash(const void *ca_void)
   1.143 +	{
   1.144 +	const ASN1_OBJECT *a;
   1.145 +	int i;
   1.146 +	unsigned long ret=0;
   1.147 +	unsigned char *p;
   1.148 +	const ADDED_OBJ *ca = (const ADDED_OBJ *)ca_void;
   1.149 +
   1.150 +	a=ca->obj;
   1.151 +	switch (ca->type)
   1.152 +		{
   1.153 +	case ADDED_DATA:
   1.154 +		ret=a->length<<20L;
   1.155 +		p=(unsigned char *)a->data;
   1.156 +		for (i=0; i<a->length; i++)
   1.157 +			ret^=p[i]<<((i*3)%24);
   1.158 +		break;
   1.159 +	case ADDED_SNAME:
   1.160 +		ret=lh_strhash(a->sn);
   1.161 +		break;
   1.162 +	case ADDED_LNAME:
   1.163 +		ret=lh_strhash(a->ln);
   1.164 +		break;
   1.165 +	case ADDED_NID:
   1.166 +		ret=a->nid;
   1.167 +		break;
   1.168 +	default:
   1.169 +		/* abort(); */
   1.170 +		return 0;
   1.171 +		}
   1.172 +	ret&=0x3fffffffL;
   1.173 +	ret|=ca->type<<30L;
   1.174 +	return(ret);
   1.175 +	}
   1.176 +
   1.177 +/* static int add_cmp(ADDED_OBJ *ca, ADDED_OBJ *cb) */
   1.178 +static int add_cmp(const void *ca_void, const void *cb_void)
   1.179 +	{
   1.180 +	ASN1_OBJECT *a,*b;
   1.181 +	int i;
   1.182 +	const ADDED_OBJ *ca = (const ADDED_OBJ *)ca_void;
   1.183 +	const ADDED_OBJ *cb = (const ADDED_OBJ *)cb_void;
   1.184 +
   1.185 +	i=ca->type-cb->type;
   1.186 +	if (i) return(i);
   1.187 +	a=ca->obj;
   1.188 +	b=cb->obj;
   1.189 +	switch (ca->type)
   1.190 +		{
   1.191 +	case ADDED_DATA:
   1.192 +		i=(a->length - b->length);
   1.193 +		if (i) return(i);
   1.194 +		return(memcmp(a->data,b->data,(size_t)a->length));
   1.195 +	case ADDED_SNAME:
   1.196 +		if (a->sn == NULL) return(-1);
   1.197 +		else if (b->sn == NULL) return(1);
   1.198 +		else return(strcmp(a->sn,b->sn));
   1.199 +	case ADDED_LNAME:
   1.200 +		if (a->ln == NULL) return(-1);
   1.201 +		else if (b->ln == NULL) return(1);
   1.202 +		else return(strcmp(a->ln,b->ln));
   1.203 +	case ADDED_NID:
   1.204 +		return(a->nid-b->nid);
   1.205 +	default:
   1.206 +		/* abort(); */
   1.207 +		return 0;
   1.208 +		}
   1.209 +	}
   1.210 +
   1.211 +static int init_added(void)
   1.212 +	{
   1.213 +	if (added != NULL) return(1);
   1.214 +	added=lh_new(add_hash,add_cmp);
   1.215 +	return(added != NULL);
   1.216 +	}
   1.217 +
   1.218 +static void cleanup1(ADDED_OBJ *a)
   1.219 +	{
   1.220 +	a->obj->nid=0;
   1.221 +	a->obj->flags|=ASN1_OBJECT_FLAG_DYNAMIC|
   1.222 +	                ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
   1.223 +			ASN1_OBJECT_FLAG_DYNAMIC_DATA;
   1.224 +	}
   1.225 +
   1.226 +static void cleanup2(ADDED_OBJ *a)
   1.227 +	{ a->obj->nid++; }
   1.228 +
   1.229 +static void cleanup3(ADDED_OBJ *a)
   1.230 +	{
   1.231 +	if (--a->obj->nid == 0)
   1.232 +		ASN1_OBJECT_free(a->obj);
   1.233 +	OPENSSL_free(a);
   1.234 +	}
   1.235 +
   1.236 +static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ *)
   1.237 +static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ *)
   1.238 +static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ *)
   1.239 +
   1.240 +EXPORT_C void OBJ_cleanup(void)
   1.241 +	{
   1.242 +	if (added == NULL) return;
   1.243 +	added->down_load=0;
   1.244 +	lh_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */
   1.245 +	lh_doall(added,LHASH_DOALL_FN(cleanup2)); /* set counters */
   1.246 +	lh_doall(added,LHASH_DOALL_FN(cleanup3)); /* free objects */
   1.247 +	lh_free(added);
   1.248 +	added=NULL;
   1.249 +	}
   1.250 +
   1.251 +EXPORT_C int OBJ_new_nid(int num)
   1.252 +	{
   1.253 +	int i;
   1.254 +
   1.255 +	i=new_nid;
   1.256 +	new_nid+=num;
   1.257 +	return(i);
   1.258 +	}
   1.259 +
   1.260 +EXPORT_C int OBJ_add_object(const ASN1_OBJECT *obj)
   1.261 +	{
   1.262 +	ASN1_OBJECT *o;
   1.263 +	ADDED_OBJ *ao[4]={NULL,NULL,NULL,NULL},*aop;
   1.264 +	int i;
   1.265 +
   1.266 +	if (added == NULL)
   1.267 +		if (!init_added()) return(0);
   1.268 +	if ((o=OBJ_dup(obj)) == NULL) goto err;
   1.269 +	if (!(ao[ADDED_NID]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err2;
   1.270 +	if ((o->length != 0) && (obj->data != NULL))
   1.271 +		if (!(ao[ADDED_DATA]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err2;
   1.272 +	if (o->sn != NULL)
   1.273 +		if (!(ao[ADDED_SNAME]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err2;
   1.274 +	if (o->ln != NULL)
   1.275 +		if (!(ao[ADDED_LNAME]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err2;
   1.276 +
   1.277 +	for (i=ADDED_DATA; i<=ADDED_NID; i++)
   1.278 +		{
   1.279 +		if (ao[i] != NULL)
   1.280 +			{
   1.281 +			ao[i]->type=i;
   1.282 +			ao[i]->obj=o;
   1.283 +			aop=(ADDED_OBJ *)lh_insert(added,ao[i]);
   1.284 +			/* memory leak, buit should not normally matter */
   1.285 +			if (aop != NULL)
   1.286 +				OPENSSL_free(aop);
   1.287 +			}
   1.288 +		}
   1.289 +	o->flags&= ~(ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
   1.290 +			ASN1_OBJECT_FLAG_DYNAMIC_DATA);
   1.291 +
   1.292 +	return(o->nid);
   1.293 +err2:
   1.294 +	OBJerr(OBJ_F_OBJ_ADD_OBJECT,ERR_R_MALLOC_FAILURE);
   1.295 +err:
   1.296 +	for (i=ADDED_DATA; i<=ADDED_NID; i++)
   1.297 +		if (ao[i] != NULL) OPENSSL_free(ao[i]);
   1.298 +	if (o != NULL) OPENSSL_free(o);
   1.299 +	return(NID_undef);
   1.300 +	}
   1.301 +
   1.302 +EXPORT_C ASN1_OBJECT *OBJ_nid2obj(int n)
   1.303 +	{
   1.304 +	ADDED_OBJ ad,*adp;
   1.305 +	ASN1_OBJECT ob;
   1.306 +
   1.307 +	if ((n >= 0) && (n < NUM_NID))
   1.308 +		{
   1.309 +		if ((n != NID_undef) && (nid_objs[n].nid == NID_undef))
   1.310 +			{
   1.311 +			OBJerr(OBJ_F_OBJ_NID2OBJ,OBJ_R_UNKNOWN_NID);
   1.312 +			return(NULL);
   1.313 +			}
   1.314 +		return((ASN1_OBJECT *)&(nid_objs[n]));
   1.315 +		}
   1.316 +	else if (added == NULL)
   1.317 +		return(NULL);
   1.318 +	else
   1.319 +		{
   1.320 +		ad.type=ADDED_NID;
   1.321 +		ad.obj= &ob;
   1.322 +		ob.nid=n;
   1.323 +		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
   1.324 +		if (adp != NULL)
   1.325 +			return(adp->obj);
   1.326 +		else
   1.327 +			{
   1.328 +			OBJerr(OBJ_F_OBJ_NID2OBJ,OBJ_R_UNKNOWN_NID);
   1.329 +			return(NULL);
   1.330 +			}
   1.331 +		}
   1.332 +	}
   1.333 +
   1.334 +EXPORT_C const char *OBJ_nid2sn(int n)
   1.335 +	{
   1.336 +	ADDED_OBJ ad,*adp;
   1.337 +	ASN1_OBJECT ob;
   1.338 +
   1.339 +	if ((n >= 0) && (n < NUM_NID))
   1.340 +		{
   1.341 +		if ((n != NID_undef) && (nid_objs[n].nid == NID_undef))
   1.342 +			{
   1.343 +			OBJerr(OBJ_F_OBJ_NID2SN,OBJ_R_UNKNOWN_NID);
   1.344 +			return(NULL);
   1.345 +			}
   1.346 +		return(nid_objs[n].sn);
   1.347 +		}
   1.348 +	else if (added == NULL)
   1.349 +		return(NULL);
   1.350 +	else
   1.351 +		{
   1.352 +		ad.type=ADDED_NID;
   1.353 +		ad.obj= &ob;
   1.354 +		ob.nid=n;
   1.355 +		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
   1.356 +		if (adp != NULL)
   1.357 +			return(adp->obj->sn);
   1.358 +		else
   1.359 +			{
   1.360 +			OBJerr(OBJ_F_OBJ_NID2SN,OBJ_R_UNKNOWN_NID);
   1.361 +			return(NULL);
   1.362 +			}
   1.363 +		}
   1.364 +	}
   1.365 +
   1.366 +EXPORT_C const char *OBJ_nid2ln(int n)
   1.367 +	{
   1.368 +	ADDED_OBJ ad,*adp;
   1.369 +	ASN1_OBJECT ob;
   1.370 +
   1.371 +	if ((n >= 0) && (n < NUM_NID))
   1.372 +		{
   1.373 +		if ((n != NID_undef) && (nid_objs[n].nid == NID_undef))
   1.374 +			{
   1.375 +			OBJerr(OBJ_F_OBJ_NID2LN,OBJ_R_UNKNOWN_NID);
   1.376 +			return(NULL);
   1.377 +			}
   1.378 +		return(nid_objs[n].ln);
   1.379 +		}
   1.380 +	else if (added == NULL)
   1.381 +		return(NULL);
   1.382 +	else
   1.383 +		{
   1.384 +		ad.type=ADDED_NID;
   1.385 +		ad.obj= &ob;
   1.386 +		ob.nid=n;
   1.387 +		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
   1.388 +		if (adp != NULL)
   1.389 +			return(adp->obj->ln);
   1.390 +		else
   1.391 +			{
   1.392 +			OBJerr(OBJ_F_OBJ_NID2LN,OBJ_R_UNKNOWN_NID);
   1.393 +			return(NULL);
   1.394 +			}
   1.395 +		}
   1.396 +	}
   1.397 +
   1.398 +EXPORT_C int OBJ_obj2nid(const ASN1_OBJECT *a)
   1.399 +	{
   1.400 +	ASN1_OBJECT **op;
   1.401 +	ADDED_OBJ ad,*adp;
   1.402 +
   1.403 +	if (a == NULL)
   1.404 +		return(NID_undef);
   1.405 +	if (a->nid != 0)
   1.406 +		return(a->nid);
   1.407 +
   1.408 +	if (added != NULL)
   1.409 +		{
   1.410 +		ad.type=ADDED_DATA;
   1.411 +		ad.obj=(ASN1_OBJECT *)a; /* XXX: ugly but harmless */
   1.412 +		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
   1.413 +		if (adp != NULL) return (adp->obj->nid);
   1.414 +		}
   1.415 +	op=(ASN1_OBJECT **)OBJ_bsearch((const char *)&a,(const char *)obj_objs,
   1.416 +		NUM_OBJ, sizeof(ASN1_OBJECT *),obj_cmp);
   1.417 +	if (op == NULL)
   1.418 +		return(NID_undef);
   1.419 +	return((*op)->nid);
   1.420 +	}
   1.421 +
   1.422 +/* Convert an object name into an ASN1_OBJECT
   1.423 + * if "noname" is not set then search for short and long names first.
   1.424 + * This will convert the "dotted" form into an object: unlike OBJ_txt2nid
   1.425 + * it can be used with any objects, not just registered ones.
   1.426 + */
   1.427 +
   1.428 +EXPORT_C ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name)
   1.429 +	{
   1.430 +	int nid = NID_undef;
   1.431 +	ASN1_OBJECT *op=NULL;
   1.432 +	unsigned char *buf;
   1.433 +	unsigned char *p;
   1.434 +	const unsigned char *cp;
   1.435 +	int i, j;
   1.436 +
   1.437 +	if(!no_name) {
   1.438 +		if( ((nid = OBJ_sn2nid(s)) != NID_undef) ||
   1.439 +			((nid = OBJ_ln2nid(s)) != NID_undef) ) 
   1.440 +					return OBJ_nid2obj(nid);
   1.441 +	}
   1.442 +
   1.443 +	/* Work out size of content octets */
   1.444 +	i=a2d_ASN1_OBJECT(NULL,0,s,-1);
   1.445 +	if (i <= 0) {
   1.446 +				/* Don't clear the error */
   1.447 +		/*ERR_clear_error();*/
   1.448 +		return NULL;
   1.449 +	}
   1.450 +	/* Work out total size */
   1.451 +	j = ASN1_object_size(0,i,V_ASN1_OBJECT);
   1.452 +
   1.453 +	if((buf=(unsigned char *)OPENSSL_malloc(j)) == NULL) return NULL;
   1.454 +
   1.455 +	p = buf;
   1.456 +	/* Write out tag+length */
   1.457 +	ASN1_put_object(&p,0,i,V_ASN1_OBJECT,V_ASN1_UNIVERSAL);
   1.458 +	/* Write out contents */
   1.459 +	a2d_ASN1_OBJECT(p,i,s,-1);
   1.460 +
   1.461 +	cp=buf;
   1.462 +	op=d2i_ASN1_OBJECT(NULL,&cp,j);
   1.463 +	OPENSSL_free(buf);
   1.464 +	return op;
   1.465 +	}
   1.466 +
   1.467 +EXPORT_C int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
   1.468 +{
   1.469 +		int i,n=0,len,nid, first, use_bn;
   1.470 +	BIGNUM *bl;
   1.471 +	unsigned long l;
   1.472 +	unsigned char *p;
   1.473 +	char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2];
   1.474 +
   1.475 +	if ((a == NULL) || (a->data == NULL)) {
   1.476 +		buf[0]='\0';
   1.477 +		return(0);
   1.478 +	}
   1.479 +
   1.480 +
   1.481 +	if (!no_name && (nid=OBJ_obj2nid(a)) != NID_undef)
   1.482 +		{
   1.483 +		const char *s;
   1.484 +		s=OBJ_nid2ln(nid);
   1.485 +		if (s == NULL)
   1.486 +			s=OBJ_nid2sn(nid);
   1.487 +		if (buf)
   1.488 +			BUF_strlcpy(buf,s,buf_len);
   1.489 +		n=strlen(s);
   1.490 +		return n;
   1.491 +		}
   1.492 +
   1.493 +
   1.494 +	len=a->length;
   1.495 +	p=a->data;
   1.496 +
   1.497 +	first = 1;
   1.498 +	bl = NULL;
   1.499 +
   1.500 +	while (len > 0)
   1.501 +		{
   1.502 +		l=0;
   1.503 +		use_bn = 0;
   1.504 +		for (;;)
   1.505 +			{
   1.506 +			unsigned char c = *p++;
   1.507 +			len--;
   1.508 +			if ((len == 0) && (c & 0x80))
   1.509 +				goto err;
   1.510 +			if (use_bn)
   1.511 +				{
   1.512 +				if (!BN_add_word(bl, c & 0x7f))
   1.513 +					goto err;
   1.514 +				}
   1.515 +			else
   1.516 +				l |= c  & 0x7f;
   1.517 +			if (!(c & 0x80))
   1.518 +				break;
   1.519 +			if (!use_bn && (l > (ULONG_MAX >> 7L)))
   1.520 +				{
   1.521 +				if (!bl && !(bl = BN_new()))
   1.522 +					goto err;
   1.523 +				if (!BN_set_word(bl, l))
   1.524 +					goto err;
   1.525 +				use_bn = 1;
   1.526 +				}
   1.527 +			if (use_bn)
   1.528 +				{
   1.529 +				if (!BN_lshift(bl, bl, 7))
   1.530 +					goto err;
   1.531 +				}
   1.532 +			else
   1.533 +				l<<=7L;
   1.534 +			}
   1.535 +
   1.536 +		if (first)
   1.537 +			{
   1.538 +			first = 0;
   1.539 +			if (l >= 80)
   1.540 +				{
   1.541 +				i = 2;
   1.542 +				if (use_bn)
   1.543 +					{
   1.544 +					if (!BN_sub_word(bl, 80))
   1.545 +						goto err;
   1.546 +					}
   1.547 +				else
   1.548 +					l -= 80;
   1.549 +				}
   1.550 +			else
   1.551 +				{
   1.552 +				i=(int)(l/40);
   1.553 +				l-=(long)(i*40);
   1.554 +				}
   1.555 +			if (buf && (buf_len > 0))
   1.556 +				{
   1.557 +				*buf++ = i + '0';
   1.558 +				buf_len--;
   1.559 +				}
   1.560 +			n++;
   1.561 +			}
   1.562 +
   1.563 +		if (use_bn)
   1.564 +			{
   1.565 +			char *bndec;
   1.566 +			bndec = BN_bn2dec(bl);
   1.567 +			if (!bndec)
   1.568 +				goto err;
   1.569 +			i = strlen(bndec);
   1.570 +			if (buf)
   1.571 +				{
   1.572 +				if (buf_len > 0)
   1.573 +					{
   1.574 +					*buf++ = '.';
   1.575 +					buf_len--;
   1.576 +					}
   1.577 +				BUF_strlcpy(buf,bndec,buf_len);
   1.578 +				if (i > buf_len)
   1.579 +					{
   1.580 +					buf += buf_len;
   1.581 +					buf_len = 0;
   1.582 +					}
   1.583 +				else
   1.584 +					{
   1.585 +					buf+=i;
   1.586 +					buf_len-=i;
   1.587 +					}
   1.588 +				}
   1.589 +			n++;
   1.590 +			n += i;
   1.591 +			OPENSSL_free(bndec);
   1.592 +			}
   1.593 +		else
   1.594 +			{
   1.595 +			BIO_snprintf(tbuf,sizeof tbuf,".%lu",l);
   1.596 +			i=strlen(tbuf);
   1.597 +			if (buf && (buf_len > 0))
   1.598 +				{
   1.599 +				BUF_strlcpy(buf,tbuf,buf_len);
   1.600 +				if (i > buf_len)
   1.601 +					{
   1.602 +					buf += buf_len;
   1.603 +					buf_len = 0;
   1.604 +					}
   1.605 +				else
   1.606 +					{
   1.607 +					buf+=i;
   1.608 +					buf_len-=i;
   1.609 +					}
   1.610 +				}
   1.611 +			n+=i;
   1.612 +			l=0;
   1.613 +			}
   1.614 +		}
   1.615 +
   1.616 +	if (bl)
   1.617 +		BN_free(bl);
   1.618 +	return n;
   1.619 +
   1.620 +	err:
   1.621 +	if (bl)
   1.622 +		BN_free(bl);
   1.623 +	return -1;
   1.624 +}
   1.625 +
   1.626 +EXPORT_C int OBJ_txt2nid(const char *s)
   1.627 +{
   1.628 +	ASN1_OBJECT *obj;
   1.629 +	int nid;
   1.630 +	obj = OBJ_txt2obj(s, 0);
   1.631 +	nid = OBJ_obj2nid(obj);
   1.632 +	ASN1_OBJECT_free(obj);
   1.633 +	return nid;
   1.634 +}
   1.635 +
   1.636 +EXPORT_C int OBJ_ln2nid(const char *s)
   1.637 +	{
   1.638 +	ASN1_OBJECT o,*oo= &o,**op;
   1.639 +	ADDED_OBJ ad,*adp;
   1.640 +
   1.641 +	o.ln=s;
   1.642 +	if (added != NULL)
   1.643 +		{
   1.644 +		ad.type=ADDED_LNAME;
   1.645 +		ad.obj= &o;
   1.646 +		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
   1.647 +		if (adp != NULL) return (adp->obj->nid);
   1.648 +		}
   1.649 +	op=(ASN1_OBJECT **)OBJ_bsearch((char *)&oo,(char *)ln_objs, NUM_LN,
   1.650 +		sizeof(ASN1_OBJECT *),ln_cmp);
   1.651 +	if (op == NULL) return(NID_undef);
   1.652 +	return((*op)->nid);
   1.653 +	}
   1.654 +
   1.655 +EXPORT_C int OBJ_sn2nid(const char *s)
   1.656 +	{
   1.657 +	ASN1_OBJECT o,*oo= &o,**op;
   1.658 +	ADDED_OBJ ad,*adp;
   1.659 +
   1.660 +	o.sn=s;
   1.661 +	if (added != NULL)
   1.662 +		{
   1.663 +		ad.type=ADDED_SNAME;
   1.664 +		ad.obj= &o;
   1.665 +		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
   1.666 +		if (adp != NULL) return (adp->obj->nid);
   1.667 +		}
   1.668 +	op=(ASN1_OBJECT **)OBJ_bsearch((char *)&oo,(char *)sn_objs,NUM_SN,
   1.669 +		sizeof(ASN1_OBJECT *),sn_cmp);
   1.670 +	if (op == NULL) return(NID_undef);
   1.671 +	return((*op)->nid);
   1.672 +	}
   1.673 +
   1.674 +static int obj_cmp(const void *ap, const void *bp)
   1.675 +	{
   1.676 +	int j;
   1.677 +	const ASN1_OBJECT *a= *(ASN1_OBJECT * const *)ap;
   1.678 +	const ASN1_OBJECT *b= *(ASN1_OBJECT * const *)bp;
   1.679 +
   1.680 +	j=(a->length - b->length);
   1.681 +        if (j) return(j);
   1.682 +	return(memcmp(a->data,b->data,a->length));
   1.683 +        }
   1.684 +
   1.685 +EXPORT_C const char *OBJ_bsearch(const char *key, const char *base, int num, int size,
   1.686 +	int (*cmp)(const void *, const void *))
   1.687 +	{
   1.688 +	return OBJ_bsearch_ex(key, base, num, size, cmp, 0);
   1.689 +	}
   1.690 +
   1.691 +EXPORT_C const char *OBJ_bsearch_ex(const char *key, const char *base, int num,
   1.692 +	int size, int (*cmp)(const void *, const void *), int flags)
   1.693 +	{
   1.694 +	int l,h,i=0,c=0;
   1.695 +	const char *p = NULL;
   1.696 +
   1.697 +	if (num == 0) return(NULL);
   1.698 +	l=0;
   1.699 +	h=num;
   1.700 +	while (l < h)
   1.701 +		{
   1.702 +		i=(l+h)/2;
   1.703 +		p= &(base[i*size]);
   1.704 +		c=(*cmp)(key,p);
   1.705 +		if (c < 0)
   1.706 +			h=i;
   1.707 +		else if (c > 0)
   1.708 +			l=i+1;
   1.709 +		else
   1.710 +			break;
   1.711 +		}
   1.712 +#ifdef CHARSET_EBCDIC
   1.713 +/* THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and
   1.714 + * I don't have perl (yet), we revert to a *LINEAR* search
   1.715 + * when the object wasn't found in the binary search.
   1.716 + */
   1.717 +	if (c != 0)
   1.718 +		{
   1.719 +		for (i=0; i<num; ++i)
   1.720 +			{
   1.721 +			p= &(base[i*size]);
   1.722 +			c = (*cmp)(key,p);
   1.723 +			if (c == 0 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
   1.724 +				return p;
   1.725 +			}
   1.726 +		}
   1.727 +#endif
   1.728 +	if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))
   1.729 +		p = NULL;
   1.730 +	else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH))
   1.731 +		{
   1.732 +		while(i > 0 && (*cmp)(key,&(base[(i-1)*size])) == 0)
   1.733 +			i--;
   1.734 +		p = &(base[i*size]);
   1.735 +		}
   1.736 +	return(p);
   1.737 +	}
   1.738 +
   1.739 +EXPORT_C int OBJ_create_objects(BIO *in)
   1.740 +	{
   1.741 +	MS_STATIC char buf[512];
   1.742 +	int i,num=0;
   1.743 +	char *o,*s,*l=NULL;
   1.744 +
   1.745 +	for (;;)
   1.746 +		{
   1.747 +		s=o=NULL;
   1.748 +		i=BIO_gets(in,buf,512);
   1.749 +		if (i <= 0) return(num);
   1.750 +		buf[i-1]='\0';
   1.751 +		if (!isalnum((unsigned char)buf[0])) return(num);
   1.752 +		o=s=buf;
   1.753 +		while (isdigit((unsigned char)*s) || (*s == '.'))
   1.754 +			s++;
   1.755 +		if (*s != '\0')
   1.756 +			{
   1.757 +			*(s++)='\0';
   1.758 +			while (isspace((unsigned char)*s))
   1.759 +				s++;
   1.760 +			if (*s == '\0')
   1.761 +				s=NULL;
   1.762 +			else
   1.763 +				{
   1.764 +				l=s;
   1.765 +				while ((*l != '\0') && !isspace((unsigned char)*l))
   1.766 +					l++;
   1.767 +				if (*l != '\0')
   1.768 +					{
   1.769 +					*(l++)='\0';
   1.770 +					while (isspace((unsigned char)*l))
   1.771 +						l++;
   1.772 +					if (*l == '\0') l=NULL;
   1.773 +					}
   1.774 +				else
   1.775 +					l=NULL;
   1.776 +				}
   1.777 +			}
   1.778 +		else
   1.779 +			s=NULL;
   1.780 +		if ((o == NULL) || (*o == '\0')) return(num);
   1.781 +		if (!OBJ_create(o,s,l)) return(num);
   1.782 +		num++;
   1.783 +		}
   1.784 +	/* return(num); */
   1.785 +	}
   1.786 +
   1.787 +EXPORT_C int OBJ_create(const char *oid, const char *sn, const char *ln)
   1.788 +	{
   1.789 +	int ok=0;
   1.790 +	ASN1_OBJECT *op=NULL;
   1.791 +	unsigned char *buf;
   1.792 +	int i;
   1.793 +
   1.794 +	i=a2d_ASN1_OBJECT(NULL,0,oid,-1);
   1.795 +	if (i <= 0) return(0);
   1.796 +
   1.797 +	if ((buf=(unsigned char *)OPENSSL_malloc(i)) == NULL)
   1.798 +		{
   1.799 +		OBJerr(OBJ_F_OBJ_CREATE,ERR_R_MALLOC_FAILURE);
   1.800 +		return(0);
   1.801 +		}
   1.802 +	i=a2d_ASN1_OBJECT(buf,i,oid,-1);
   1.803 +	if (i == 0)
   1.804 +		goto err;
   1.805 +	op=(ASN1_OBJECT *)ASN1_OBJECT_create(OBJ_new_nid(1),buf,i,sn,ln);
   1.806 +	if (op == NULL) 
   1.807 +		goto err;
   1.808 +	ok=OBJ_add_object(op);
   1.809 +err:
   1.810 +	ASN1_OBJECT_free(op);
   1.811 +	OPENSSL_free(buf);
   1.812 +	return(ok);
   1.813 +	}
   1.814 +