xref: /onnv-gate/usr/src/common/openssl/crypto/objects/obj_dat.c (revision 2139:6243c3338933)
10Sstevel@tonic-gate /* crypto/objects/obj_dat.c */
20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
30Sstevel@tonic-gate  * All rights reserved.
40Sstevel@tonic-gate  *
50Sstevel@tonic-gate  * This package is an SSL implementation written
60Sstevel@tonic-gate  * by Eric Young (eay@cryptsoft.com).
70Sstevel@tonic-gate  * The implementation was written so as to conform with Netscapes SSL.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * This library is free for commercial and non-commercial use as long as
100Sstevel@tonic-gate  * the following conditions are aheared to.  The following conditions
110Sstevel@tonic-gate  * apply to all code found in this distribution, be it the RC4, RSA,
120Sstevel@tonic-gate  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
130Sstevel@tonic-gate  * included with this distribution is covered by the same copyright terms
140Sstevel@tonic-gate  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
150Sstevel@tonic-gate  *
160Sstevel@tonic-gate  * Copyright remains Eric Young's, and as such any Copyright notices in
170Sstevel@tonic-gate  * the code are not to be removed.
180Sstevel@tonic-gate  * If this package is used in a product, Eric Young should be given attribution
190Sstevel@tonic-gate  * as the author of the parts of the library used.
200Sstevel@tonic-gate  * This can be in the form of a textual message at program startup or
210Sstevel@tonic-gate  * in documentation (online or textual) provided with the package.
220Sstevel@tonic-gate  *
230Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
240Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
250Sstevel@tonic-gate  * are met:
260Sstevel@tonic-gate  * 1. Redistributions of source code must retain the copyright
270Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
280Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
290Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
300Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
310Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this software
320Sstevel@tonic-gate  *    must display the following acknowledgement:
330Sstevel@tonic-gate  *    "This product includes cryptographic software written by
340Sstevel@tonic-gate  *     Eric Young (eay@cryptsoft.com)"
350Sstevel@tonic-gate  *    The word 'cryptographic' can be left out if the rouines from the library
360Sstevel@tonic-gate  *    being used are not cryptographic related :-).
370Sstevel@tonic-gate  * 4. If you include any Windows specific code (or a derivative thereof) from
380Sstevel@tonic-gate  *    the apps directory (application code) you must include an acknowledgement:
390Sstevel@tonic-gate  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
400Sstevel@tonic-gate  *
410Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
420Sstevel@tonic-gate  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
440Sstevel@tonic-gate  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
450Sstevel@tonic-gate  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
460Sstevel@tonic-gate  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
470Sstevel@tonic-gate  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
480Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490Sstevel@tonic-gate  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
500Sstevel@tonic-gate  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
510Sstevel@tonic-gate  * SUCH DAMAGE.
520Sstevel@tonic-gate  *
530Sstevel@tonic-gate  * The licence and distribution terms for any publically available version or
540Sstevel@tonic-gate  * derivative of this code cannot be changed.  i.e. this code cannot simply be
550Sstevel@tonic-gate  * copied and put under another distribution licence
560Sstevel@tonic-gate  * [including the GNU Public Licence.]
570Sstevel@tonic-gate  */
580Sstevel@tonic-gate 
590Sstevel@tonic-gate #include <stdio.h>
600Sstevel@tonic-gate #include <ctype.h>
610Sstevel@tonic-gate #include "cryptlib.h"
620Sstevel@tonic-gate #include <openssl/lhash.h>
630Sstevel@tonic-gate #include <openssl/asn1.h>
640Sstevel@tonic-gate #include <openssl/objects.h>
650Sstevel@tonic-gate 
660Sstevel@tonic-gate /* obj_dat.h is generated from objects.h by obj_dat.pl */
670Sstevel@tonic-gate #ifndef OPENSSL_NO_OBJECT
680Sstevel@tonic-gate #include "obj_dat.h"
690Sstevel@tonic-gate #else
700Sstevel@tonic-gate /* You will have to load all the objects needed manually in the application */
710Sstevel@tonic-gate #define NUM_NID 0
720Sstevel@tonic-gate #define NUM_SN 0
730Sstevel@tonic-gate #define NUM_LN 0
740Sstevel@tonic-gate #define NUM_OBJ 0
750Sstevel@tonic-gate static unsigned char lvalues[1];
760Sstevel@tonic-gate static ASN1_OBJECT nid_objs[1];
770Sstevel@tonic-gate static ASN1_OBJECT *sn_objs[1];
780Sstevel@tonic-gate static ASN1_OBJECT *ln_objs[1];
790Sstevel@tonic-gate static ASN1_OBJECT *obj_objs[1];
800Sstevel@tonic-gate #endif
810Sstevel@tonic-gate 
820Sstevel@tonic-gate static int sn_cmp(const void *a, const void *b);
830Sstevel@tonic-gate static int ln_cmp(const void *a, const void *b);
840Sstevel@tonic-gate static int obj_cmp(const void *a, const void *b);
850Sstevel@tonic-gate #define ADDED_DATA	0
860Sstevel@tonic-gate #define ADDED_SNAME	1
870Sstevel@tonic-gate #define ADDED_LNAME	2
880Sstevel@tonic-gate #define ADDED_NID	3
890Sstevel@tonic-gate 
900Sstevel@tonic-gate typedef struct added_obj_st
910Sstevel@tonic-gate 	{
920Sstevel@tonic-gate 	int type;
930Sstevel@tonic-gate 	ASN1_OBJECT *obj;
940Sstevel@tonic-gate 	} ADDED_OBJ;
950Sstevel@tonic-gate 
960Sstevel@tonic-gate static int new_nid=NUM_NID;
970Sstevel@tonic-gate static LHASH *added=NULL;
980Sstevel@tonic-gate 
sn_cmp(const void * a,const void * b)990Sstevel@tonic-gate static int sn_cmp(const void *a, const void *b)
1000Sstevel@tonic-gate 	{
1010Sstevel@tonic-gate 	const ASN1_OBJECT * const *ap = a, * const *bp = b;
1020Sstevel@tonic-gate 	return(strcmp((*ap)->sn,(*bp)->sn));
1030Sstevel@tonic-gate 	}
1040Sstevel@tonic-gate 
ln_cmp(const void * a,const void * b)1050Sstevel@tonic-gate static int ln_cmp(const void *a, const void *b)
1060Sstevel@tonic-gate 	{
1070Sstevel@tonic-gate 	const ASN1_OBJECT * const *ap = a, * const *bp = b;
1080Sstevel@tonic-gate 	return(strcmp((*ap)->ln,(*bp)->ln));
1090Sstevel@tonic-gate 	}
1100Sstevel@tonic-gate 
1110Sstevel@tonic-gate /* static unsigned long add_hash(ADDED_OBJ *ca) */
add_hash(const void * ca_void)1120Sstevel@tonic-gate static unsigned long add_hash(const void *ca_void)
1130Sstevel@tonic-gate 	{
1140Sstevel@tonic-gate 	const ASN1_OBJECT *a;
1150Sstevel@tonic-gate 	int i;
1160Sstevel@tonic-gate 	unsigned long ret=0;
1170Sstevel@tonic-gate 	unsigned char *p;
118*2139Sjp161948 	const ADDED_OBJ *ca = (const ADDED_OBJ *)ca_void;
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate 	a=ca->obj;
1210Sstevel@tonic-gate 	switch (ca->type)
1220Sstevel@tonic-gate 		{
1230Sstevel@tonic-gate 	case ADDED_DATA:
1240Sstevel@tonic-gate 		ret=a->length<<20L;
1250Sstevel@tonic-gate 		p=(unsigned char *)a->data;
1260Sstevel@tonic-gate 		for (i=0; i<a->length; i++)
1270Sstevel@tonic-gate 			ret^=p[i]<<((i*3)%24);
1280Sstevel@tonic-gate 		break;
1290Sstevel@tonic-gate 	case ADDED_SNAME:
1300Sstevel@tonic-gate 		ret=lh_strhash(a->sn);
1310Sstevel@tonic-gate 		break;
1320Sstevel@tonic-gate 	case ADDED_LNAME:
1330Sstevel@tonic-gate 		ret=lh_strhash(a->ln);
1340Sstevel@tonic-gate 		break;
1350Sstevel@tonic-gate 	case ADDED_NID:
1360Sstevel@tonic-gate 		ret=a->nid;
1370Sstevel@tonic-gate 		break;
1380Sstevel@tonic-gate 	default:
1390Sstevel@tonic-gate 		/* abort(); */
1400Sstevel@tonic-gate 		return 0;
1410Sstevel@tonic-gate 		}
1420Sstevel@tonic-gate 	ret&=0x3fffffffL;
1430Sstevel@tonic-gate 	ret|=ca->type<<30L;
1440Sstevel@tonic-gate 	return(ret);
1450Sstevel@tonic-gate 	}
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate /* static int add_cmp(ADDED_OBJ *ca, ADDED_OBJ *cb) */
add_cmp(const void * ca_void,const void * cb_void)1480Sstevel@tonic-gate static int add_cmp(const void *ca_void, const void *cb_void)
1490Sstevel@tonic-gate 	{
1500Sstevel@tonic-gate 	ASN1_OBJECT *a,*b;
1510Sstevel@tonic-gate 	int i;
152*2139Sjp161948 	const ADDED_OBJ *ca = (const ADDED_OBJ *)ca_void;
153*2139Sjp161948 	const ADDED_OBJ *cb = (const ADDED_OBJ *)cb_void;
1540Sstevel@tonic-gate 
1550Sstevel@tonic-gate 	i=ca->type-cb->type;
1560Sstevel@tonic-gate 	if (i) return(i);
1570Sstevel@tonic-gate 	a=ca->obj;
1580Sstevel@tonic-gate 	b=cb->obj;
1590Sstevel@tonic-gate 	switch (ca->type)
1600Sstevel@tonic-gate 		{
1610Sstevel@tonic-gate 	case ADDED_DATA:
1620Sstevel@tonic-gate 		i=(a->length - b->length);
1630Sstevel@tonic-gate 		if (i) return(i);
164*2139Sjp161948 		return(memcmp(a->data,b->data,(size_t)a->length));
1650Sstevel@tonic-gate 	case ADDED_SNAME:
1660Sstevel@tonic-gate 		if (a->sn == NULL) return(-1);
1670Sstevel@tonic-gate 		else if (b->sn == NULL) return(1);
1680Sstevel@tonic-gate 		else return(strcmp(a->sn,b->sn));
1690Sstevel@tonic-gate 	case ADDED_LNAME:
1700Sstevel@tonic-gate 		if (a->ln == NULL) return(-1);
1710Sstevel@tonic-gate 		else if (b->ln == NULL) return(1);
1720Sstevel@tonic-gate 		else return(strcmp(a->ln,b->ln));
1730Sstevel@tonic-gate 	case ADDED_NID:
1740Sstevel@tonic-gate 		return(a->nid-b->nid);
1750Sstevel@tonic-gate 	default:
1760Sstevel@tonic-gate 		/* abort(); */
1770Sstevel@tonic-gate 		return 0;
1780Sstevel@tonic-gate 		}
1790Sstevel@tonic-gate 	}
1800Sstevel@tonic-gate 
init_added(void)1810Sstevel@tonic-gate static int init_added(void)
1820Sstevel@tonic-gate 	{
1830Sstevel@tonic-gate 	if (added != NULL) return(1);
1840Sstevel@tonic-gate 	added=lh_new(add_hash,add_cmp);
1850Sstevel@tonic-gate 	return(added != NULL);
1860Sstevel@tonic-gate 	}
1870Sstevel@tonic-gate 
cleanup1(ADDED_OBJ * a)1880Sstevel@tonic-gate static void cleanup1(ADDED_OBJ *a)
1890Sstevel@tonic-gate 	{
1900Sstevel@tonic-gate 	a->obj->nid=0;
1910Sstevel@tonic-gate 	a->obj->flags|=ASN1_OBJECT_FLAG_DYNAMIC|
1920Sstevel@tonic-gate 	                ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
1930Sstevel@tonic-gate 			ASN1_OBJECT_FLAG_DYNAMIC_DATA;
1940Sstevel@tonic-gate 	}
1950Sstevel@tonic-gate 
cleanup2(ADDED_OBJ * a)1960Sstevel@tonic-gate static void cleanup2(ADDED_OBJ *a)
1970Sstevel@tonic-gate 	{ a->obj->nid++; }
1980Sstevel@tonic-gate 
cleanup3(ADDED_OBJ * a)1990Sstevel@tonic-gate static void cleanup3(ADDED_OBJ *a)
2000Sstevel@tonic-gate 	{
2010Sstevel@tonic-gate 	if (--a->obj->nid == 0)
2020Sstevel@tonic-gate 		ASN1_OBJECT_free(a->obj);
2030Sstevel@tonic-gate 	OPENSSL_free(a);
2040Sstevel@tonic-gate 	}
2050Sstevel@tonic-gate 
IMPLEMENT_LHASH_DOALL_FN(cleanup1,ADDED_OBJ *)2060Sstevel@tonic-gate static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ *)
2070Sstevel@tonic-gate static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ *)
2080Sstevel@tonic-gate static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ *)
2090Sstevel@tonic-gate 
2100Sstevel@tonic-gate void OBJ_cleanup(void)
2110Sstevel@tonic-gate 	{
2120Sstevel@tonic-gate 	if (added == NULL) return;
2130Sstevel@tonic-gate 	added->down_load=0;
2140Sstevel@tonic-gate 	lh_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */
2150Sstevel@tonic-gate 	lh_doall(added,LHASH_DOALL_FN(cleanup2)); /* set counters */
2160Sstevel@tonic-gate 	lh_doall(added,LHASH_DOALL_FN(cleanup3)); /* free objects */
2170Sstevel@tonic-gate 	lh_free(added);
2180Sstevel@tonic-gate 	added=NULL;
2190Sstevel@tonic-gate 	}
2200Sstevel@tonic-gate 
OBJ_new_nid(int num)2210Sstevel@tonic-gate int OBJ_new_nid(int num)
2220Sstevel@tonic-gate 	{
2230Sstevel@tonic-gate 	int i;
2240Sstevel@tonic-gate 
2250Sstevel@tonic-gate 	i=new_nid;
2260Sstevel@tonic-gate 	new_nid+=num;
2270Sstevel@tonic-gate 	return(i);
2280Sstevel@tonic-gate 	}
2290Sstevel@tonic-gate 
OBJ_add_object(const ASN1_OBJECT * obj)2300Sstevel@tonic-gate int OBJ_add_object(const ASN1_OBJECT *obj)
2310Sstevel@tonic-gate 	{
2320Sstevel@tonic-gate 	ASN1_OBJECT *o;
2330Sstevel@tonic-gate 	ADDED_OBJ *ao[4]={NULL,NULL,NULL,NULL},*aop;
2340Sstevel@tonic-gate 	int i;
2350Sstevel@tonic-gate 
2360Sstevel@tonic-gate 	if (added == NULL)
2370Sstevel@tonic-gate 		if (!init_added()) return(0);
2380Sstevel@tonic-gate 	if ((o=OBJ_dup(obj)) == NULL) goto err;
239*2139Sjp161948 	if (!(ao[ADDED_NID]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err2;
2400Sstevel@tonic-gate 	if ((o->length != 0) && (obj->data != NULL))
241*2139Sjp161948 		if (!(ao[ADDED_DATA]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err2;
2420Sstevel@tonic-gate 	if (o->sn != NULL)
243*2139Sjp161948 		if (!(ao[ADDED_SNAME]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err2;
2440Sstevel@tonic-gate 	if (o->ln != NULL)
245*2139Sjp161948 		if (!(ao[ADDED_LNAME]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err2;
2460Sstevel@tonic-gate 
2470Sstevel@tonic-gate 	for (i=ADDED_DATA; i<=ADDED_NID; i++)
2480Sstevel@tonic-gate 		{
2490Sstevel@tonic-gate 		if (ao[i] != NULL)
2500Sstevel@tonic-gate 			{
2510Sstevel@tonic-gate 			ao[i]->type=i;
2520Sstevel@tonic-gate 			ao[i]->obj=o;
2530Sstevel@tonic-gate 			aop=(ADDED_OBJ *)lh_insert(added,ao[i]);
2540Sstevel@tonic-gate 			/* memory leak, buit should not normally matter */
2550Sstevel@tonic-gate 			if (aop != NULL)
2560Sstevel@tonic-gate 				OPENSSL_free(aop);
2570Sstevel@tonic-gate 			}
2580Sstevel@tonic-gate 		}
2590Sstevel@tonic-gate 	o->flags&= ~(ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
2600Sstevel@tonic-gate 			ASN1_OBJECT_FLAG_DYNAMIC_DATA);
2610Sstevel@tonic-gate 
2620Sstevel@tonic-gate 	return(o->nid);
263*2139Sjp161948 err2:
264*2139Sjp161948 	OBJerr(OBJ_F_OBJ_ADD_OBJECT,ERR_R_MALLOC_FAILURE);
2650Sstevel@tonic-gate err:
2660Sstevel@tonic-gate 	for (i=ADDED_DATA; i<=ADDED_NID; i++)
2670Sstevel@tonic-gate 		if (ao[i] != NULL) OPENSSL_free(ao[i]);
2680Sstevel@tonic-gate 	if (o != NULL) OPENSSL_free(o);
2690Sstevel@tonic-gate 	return(NID_undef);
2700Sstevel@tonic-gate 	}
2710Sstevel@tonic-gate 
OBJ_nid2obj(int n)2720Sstevel@tonic-gate ASN1_OBJECT *OBJ_nid2obj(int n)
2730Sstevel@tonic-gate 	{
2740Sstevel@tonic-gate 	ADDED_OBJ ad,*adp;
2750Sstevel@tonic-gate 	ASN1_OBJECT ob;
2760Sstevel@tonic-gate 
2770Sstevel@tonic-gate 	if ((n >= 0) && (n < NUM_NID))
2780Sstevel@tonic-gate 		{
2790Sstevel@tonic-gate 		if ((n != NID_undef) && (nid_objs[n].nid == NID_undef))
2800Sstevel@tonic-gate 			{
2810Sstevel@tonic-gate 			OBJerr(OBJ_F_OBJ_NID2OBJ,OBJ_R_UNKNOWN_NID);
2820Sstevel@tonic-gate 			return(NULL);
2830Sstevel@tonic-gate 			}
2840Sstevel@tonic-gate 		return((ASN1_OBJECT *)&(nid_objs[n]));
2850Sstevel@tonic-gate 		}
2860Sstevel@tonic-gate 	else if (added == NULL)
2870Sstevel@tonic-gate 		return(NULL);
2880Sstevel@tonic-gate 	else
2890Sstevel@tonic-gate 		{
2900Sstevel@tonic-gate 		ad.type=ADDED_NID;
2910Sstevel@tonic-gate 		ad.obj= &ob;
2920Sstevel@tonic-gate 		ob.nid=n;
2930Sstevel@tonic-gate 		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
2940Sstevel@tonic-gate 		if (adp != NULL)
2950Sstevel@tonic-gate 			return(adp->obj);
2960Sstevel@tonic-gate 		else
2970Sstevel@tonic-gate 			{
2980Sstevel@tonic-gate 			OBJerr(OBJ_F_OBJ_NID2OBJ,OBJ_R_UNKNOWN_NID);
2990Sstevel@tonic-gate 			return(NULL);
3000Sstevel@tonic-gate 			}
3010Sstevel@tonic-gate 		}
3020Sstevel@tonic-gate 	}
3030Sstevel@tonic-gate 
OBJ_nid2sn(int n)3040Sstevel@tonic-gate const char *OBJ_nid2sn(int n)
3050Sstevel@tonic-gate 	{
3060Sstevel@tonic-gate 	ADDED_OBJ ad,*adp;
3070Sstevel@tonic-gate 	ASN1_OBJECT ob;
3080Sstevel@tonic-gate 
3090Sstevel@tonic-gate 	if ((n >= 0) && (n < NUM_NID))
3100Sstevel@tonic-gate 		{
3110Sstevel@tonic-gate 		if ((n != NID_undef) && (nid_objs[n].nid == NID_undef))
3120Sstevel@tonic-gate 			{
3130Sstevel@tonic-gate 			OBJerr(OBJ_F_OBJ_NID2SN,OBJ_R_UNKNOWN_NID);
3140Sstevel@tonic-gate 			return(NULL);
3150Sstevel@tonic-gate 			}
3160Sstevel@tonic-gate 		return(nid_objs[n].sn);
3170Sstevel@tonic-gate 		}
3180Sstevel@tonic-gate 	else if (added == NULL)
3190Sstevel@tonic-gate 		return(NULL);
3200Sstevel@tonic-gate 	else
3210Sstevel@tonic-gate 		{
3220Sstevel@tonic-gate 		ad.type=ADDED_NID;
3230Sstevel@tonic-gate 		ad.obj= &ob;
3240Sstevel@tonic-gate 		ob.nid=n;
3250Sstevel@tonic-gate 		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
3260Sstevel@tonic-gate 		if (adp != NULL)
3270Sstevel@tonic-gate 			return(adp->obj->sn);
3280Sstevel@tonic-gate 		else
3290Sstevel@tonic-gate 			{
3300Sstevel@tonic-gate 			OBJerr(OBJ_F_OBJ_NID2SN,OBJ_R_UNKNOWN_NID);
3310Sstevel@tonic-gate 			return(NULL);
3320Sstevel@tonic-gate 			}
3330Sstevel@tonic-gate 		}
3340Sstevel@tonic-gate 	}
3350Sstevel@tonic-gate 
OBJ_nid2ln(int n)3360Sstevel@tonic-gate const char *OBJ_nid2ln(int n)
3370Sstevel@tonic-gate 	{
3380Sstevel@tonic-gate 	ADDED_OBJ ad,*adp;
3390Sstevel@tonic-gate 	ASN1_OBJECT ob;
3400Sstevel@tonic-gate 
3410Sstevel@tonic-gate 	if ((n >= 0) && (n < NUM_NID))
3420Sstevel@tonic-gate 		{
3430Sstevel@tonic-gate 		if ((n != NID_undef) && (nid_objs[n].nid == NID_undef))
3440Sstevel@tonic-gate 			{
3450Sstevel@tonic-gate 			OBJerr(OBJ_F_OBJ_NID2LN,OBJ_R_UNKNOWN_NID);
3460Sstevel@tonic-gate 			return(NULL);
3470Sstevel@tonic-gate 			}
3480Sstevel@tonic-gate 		return(nid_objs[n].ln);
3490Sstevel@tonic-gate 		}
3500Sstevel@tonic-gate 	else if (added == NULL)
3510Sstevel@tonic-gate 		return(NULL);
3520Sstevel@tonic-gate 	else
3530Sstevel@tonic-gate 		{
3540Sstevel@tonic-gate 		ad.type=ADDED_NID;
3550Sstevel@tonic-gate 		ad.obj= &ob;
3560Sstevel@tonic-gate 		ob.nid=n;
3570Sstevel@tonic-gate 		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
3580Sstevel@tonic-gate 		if (adp != NULL)
3590Sstevel@tonic-gate 			return(adp->obj->ln);
3600Sstevel@tonic-gate 		else
3610Sstevel@tonic-gate 			{
3620Sstevel@tonic-gate 			OBJerr(OBJ_F_OBJ_NID2LN,OBJ_R_UNKNOWN_NID);
3630Sstevel@tonic-gate 			return(NULL);
3640Sstevel@tonic-gate 			}
3650Sstevel@tonic-gate 		}
3660Sstevel@tonic-gate 	}
3670Sstevel@tonic-gate 
OBJ_obj2nid(const ASN1_OBJECT * a)3680Sstevel@tonic-gate int OBJ_obj2nid(const ASN1_OBJECT *a)
3690Sstevel@tonic-gate 	{
3700Sstevel@tonic-gate 	ASN1_OBJECT **op;
3710Sstevel@tonic-gate 	ADDED_OBJ ad,*adp;
3720Sstevel@tonic-gate 
3730Sstevel@tonic-gate 	if (a == NULL)
3740Sstevel@tonic-gate 		return(NID_undef);
3750Sstevel@tonic-gate 	if (a->nid != 0)
3760Sstevel@tonic-gate 		return(a->nid);
3770Sstevel@tonic-gate 
3780Sstevel@tonic-gate 	if (added != NULL)
3790Sstevel@tonic-gate 		{
3800Sstevel@tonic-gate 		ad.type=ADDED_DATA;
3810Sstevel@tonic-gate 		ad.obj=(ASN1_OBJECT *)a; /* XXX: ugly but harmless */
3820Sstevel@tonic-gate 		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
3830Sstevel@tonic-gate 		if (adp != NULL) return (adp->obj->nid);
3840Sstevel@tonic-gate 		}
385*2139Sjp161948 	op=(ASN1_OBJECT **)OBJ_bsearch((const char *)&a,(const char *)obj_objs,
386*2139Sjp161948 		NUM_OBJ, sizeof(ASN1_OBJECT *),obj_cmp);
3870Sstevel@tonic-gate 	if (op == NULL)
3880Sstevel@tonic-gate 		return(NID_undef);
3890Sstevel@tonic-gate 	return((*op)->nid);
3900Sstevel@tonic-gate 	}
3910Sstevel@tonic-gate 
3920Sstevel@tonic-gate /* Convert an object name into an ASN1_OBJECT
3930Sstevel@tonic-gate  * if "noname" is not set then search for short and long names first.
3940Sstevel@tonic-gate  * This will convert the "dotted" form into an object: unlike OBJ_txt2nid
3950Sstevel@tonic-gate  * it can be used with any objects, not just registered ones.
3960Sstevel@tonic-gate  */
3970Sstevel@tonic-gate 
OBJ_txt2obj(const char * s,int no_name)3980Sstevel@tonic-gate ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name)
3990Sstevel@tonic-gate 	{
4000Sstevel@tonic-gate 	int nid = NID_undef;
4010Sstevel@tonic-gate 	ASN1_OBJECT *op=NULL;
402*2139Sjp161948 	unsigned char *buf;
403*2139Sjp161948 	unsigned char *p;
404*2139Sjp161948 	const unsigned char *cp;
4050Sstevel@tonic-gate 	int i, j;
4060Sstevel@tonic-gate 
4070Sstevel@tonic-gate 	if(!no_name) {
4080Sstevel@tonic-gate 		if( ((nid = OBJ_sn2nid(s)) != NID_undef) ||
4090Sstevel@tonic-gate 			((nid = OBJ_ln2nid(s)) != NID_undef) )
4100Sstevel@tonic-gate 					return OBJ_nid2obj(nid);
4110Sstevel@tonic-gate 	}
4120Sstevel@tonic-gate 
4130Sstevel@tonic-gate 	/* Work out size of content octets */
4140Sstevel@tonic-gate 	i=a2d_ASN1_OBJECT(NULL,0,s,-1);
4150Sstevel@tonic-gate 	if (i <= 0) {
4160Sstevel@tonic-gate 		/* Clear the error */
417*2139Sjp161948 		ERR_clear_error();
4180Sstevel@tonic-gate 		return NULL;
4190Sstevel@tonic-gate 	}
4200Sstevel@tonic-gate 	/* Work out total size */
4210Sstevel@tonic-gate 	j = ASN1_object_size(0,i,V_ASN1_OBJECT);
4220Sstevel@tonic-gate 
4230Sstevel@tonic-gate 	if((buf=(unsigned char *)OPENSSL_malloc(j)) == NULL) return NULL;
4240Sstevel@tonic-gate 
4250Sstevel@tonic-gate 	p = buf;
4260Sstevel@tonic-gate 	/* Write out tag+length */
4270Sstevel@tonic-gate 	ASN1_put_object(&p,0,i,V_ASN1_OBJECT,V_ASN1_UNIVERSAL);
4280Sstevel@tonic-gate 	/* Write out contents */
4290Sstevel@tonic-gate 	a2d_ASN1_OBJECT(p,i,s,-1);
430*2139Sjp161948 
431*2139Sjp161948 	cp=buf;
432*2139Sjp161948 	op=d2i_ASN1_OBJECT(NULL,&cp,j);
4330Sstevel@tonic-gate 	OPENSSL_free(buf);
4340Sstevel@tonic-gate 	return op;
4350Sstevel@tonic-gate 	}
4360Sstevel@tonic-gate 
OBJ_obj2txt(char * buf,int buf_len,const ASN1_OBJECT * a,int no_name)4370Sstevel@tonic-gate int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
4380Sstevel@tonic-gate {
4390Sstevel@tonic-gate 	int i,idx=0,n=0,len,nid;
4400Sstevel@tonic-gate 	unsigned long l;
4410Sstevel@tonic-gate 	unsigned char *p;
4420Sstevel@tonic-gate 	const char *s;
4430Sstevel@tonic-gate 	char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2];
4440Sstevel@tonic-gate 
4450Sstevel@tonic-gate 	if (buf_len <= 0) return(0);
4460Sstevel@tonic-gate 
4470Sstevel@tonic-gate 	if ((a == NULL) || (a->data == NULL)) {
4480Sstevel@tonic-gate 		buf[0]='\0';
4490Sstevel@tonic-gate 		return(0);
4500Sstevel@tonic-gate 	}
4510Sstevel@tonic-gate 
4520Sstevel@tonic-gate 	if (no_name || (nid=OBJ_obj2nid(a)) == NID_undef) {
4530Sstevel@tonic-gate 		len=a->length;
4540Sstevel@tonic-gate 		p=a->data;
4550Sstevel@tonic-gate 
4560Sstevel@tonic-gate 		idx=0;
4570Sstevel@tonic-gate 		l=0;
4580Sstevel@tonic-gate 		while (idx < a->length) {
4590Sstevel@tonic-gate 			l|=(p[idx]&0x7f);
4600Sstevel@tonic-gate 			if (!(p[idx] & 0x80)) break;
4610Sstevel@tonic-gate 			l<<=7L;
4620Sstevel@tonic-gate 			idx++;
4630Sstevel@tonic-gate 		}
4640Sstevel@tonic-gate 		idx++;
4650Sstevel@tonic-gate 		i=(int)(l/40);
4660Sstevel@tonic-gate 		if (i > 2) i=2;
4670Sstevel@tonic-gate 		l-=(long)(i*40);
4680Sstevel@tonic-gate 
4690Sstevel@tonic-gate 		BIO_snprintf(tbuf,sizeof tbuf,"%d.%lu",i,l);
4700Sstevel@tonic-gate 		i=strlen(tbuf);
4710Sstevel@tonic-gate 		BUF_strlcpy(buf,tbuf,buf_len);
4720Sstevel@tonic-gate 		buf_len-=i;
4730Sstevel@tonic-gate 		buf+=i;
4740Sstevel@tonic-gate 		n+=i;
4750Sstevel@tonic-gate 
4760Sstevel@tonic-gate 		l=0;
4770Sstevel@tonic-gate 		for (; idx<len; idx++) {
4780Sstevel@tonic-gate 			l|=p[idx]&0x7f;
4790Sstevel@tonic-gate 			if (!(p[idx] & 0x80)) {
4800Sstevel@tonic-gate 				BIO_snprintf(tbuf,sizeof tbuf,".%lu",l);
4810Sstevel@tonic-gate 				i=strlen(tbuf);
4820Sstevel@tonic-gate 				if (buf_len > 0)
4830Sstevel@tonic-gate 					BUF_strlcpy(buf,tbuf,buf_len);
4840Sstevel@tonic-gate 				buf_len-=i;
4850Sstevel@tonic-gate 				buf+=i;
4860Sstevel@tonic-gate 				n+=i;
4870Sstevel@tonic-gate 				l=0;
4880Sstevel@tonic-gate 			}
4890Sstevel@tonic-gate 			l<<=7L;
4900Sstevel@tonic-gate 		}
4910Sstevel@tonic-gate 	} else {
4920Sstevel@tonic-gate 		s=OBJ_nid2ln(nid);
4930Sstevel@tonic-gate 		if (s == NULL)
4940Sstevel@tonic-gate 			s=OBJ_nid2sn(nid);
4950Sstevel@tonic-gate 		BUF_strlcpy(buf,s,buf_len);
4960Sstevel@tonic-gate 		n=strlen(s);
4970Sstevel@tonic-gate 	}
4980Sstevel@tonic-gate 	return(n);
4990Sstevel@tonic-gate }
5000Sstevel@tonic-gate 
OBJ_txt2nid(const char * s)5010Sstevel@tonic-gate int OBJ_txt2nid(const char *s)
5020Sstevel@tonic-gate {
5030Sstevel@tonic-gate 	ASN1_OBJECT *obj;
5040Sstevel@tonic-gate 	int nid;
5050Sstevel@tonic-gate 	obj = OBJ_txt2obj(s, 0);
5060Sstevel@tonic-gate 	nid = OBJ_obj2nid(obj);
5070Sstevel@tonic-gate 	ASN1_OBJECT_free(obj);
5080Sstevel@tonic-gate 	return nid;
5090Sstevel@tonic-gate }
5100Sstevel@tonic-gate 
OBJ_ln2nid(const char * s)5110Sstevel@tonic-gate int OBJ_ln2nid(const char *s)
5120Sstevel@tonic-gate 	{
5130Sstevel@tonic-gate 	ASN1_OBJECT o,*oo= &o,**op;
5140Sstevel@tonic-gate 	ADDED_OBJ ad,*adp;
5150Sstevel@tonic-gate 
5160Sstevel@tonic-gate 	o.ln=s;
5170Sstevel@tonic-gate 	if (added != NULL)
5180Sstevel@tonic-gate 		{
5190Sstevel@tonic-gate 		ad.type=ADDED_LNAME;
5200Sstevel@tonic-gate 		ad.obj= &o;
5210Sstevel@tonic-gate 		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
5220Sstevel@tonic-gate 		if (adp != NULL) return (adp->obj->nid);
5230Sstevel@tonic-gate 		}
524*2139Sjp161948 	op=(ASN1_OBJECT **)OBJ_bsearch((char *)&oo,(char *)ln_objs, NUM_LN,
5250Sstevel@tonic-gate 		sizeof(ASN1_OBJECT *),ln_cmp);
5260Sstevel@tonic-gate 	if (op == NULL) return(NID_undef);
5270Sstevel@tonic-gate 	return((*op)->nid);
5280Sstevel@tonic-gate 	}
5290Sstevel@tonic-gate 
OBJ_sn2nid(const char * s)5300Sstevel@tonic-gate int OBJ_sn2nid(const char *s)
5310Sstevel@tonic-gate 	{
5320Sstevel@tonic-gate 	ASN1_OBJECT o,*oo= &o,**op;
5330Sstevel@tonic-gate 	ADDED_OBJ ad,*adp;
5340Sstevel@tonic-gate 
5350Sstevel@tonic-gate 	o.sn=s;
5360Sstevel@tonic-gate 	if (added != NULL)
5370Sstevel@tonic-gate 		{
5380Sstevel@tonic-gate 		ad.type=ADDED_SNAME;
5390Sstevel@tonic-gate 		ad.obj= &o;
5400Sstevel@tonic-gate 		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
5410Sstevel@tonic-gate 		if (adp != NULL) return (adp->obj->nid);
5420Sstevel@tonic-gate 		}
5430Sstevel@tonic-gate 	op=(ASN1_OBJECT **)OBJ_bsearch((char *)&oo,(char *)sn_objs,NUM_SN,
5440Sstevel@tonic-gate 		sizeof(ASN1_OBJECT *),sn_cmp);
5450Sstevel@tonic-gate 	if (op == NULL) return(NID_undef);
5460Sstevel@tonic-gate 	return((*op)->nid);
5470Sstevel@tonic-gate 	}
5480Sstevel@tonic-gate 
obj_cmp(const void * ap,const void * bp)5490Sstevel@tonic-gate static int obj_cmp(const void *ap, const void *bp)
5500Sstevel@tonic-gate 	{
5510Sstevel@tonic-gate 	int j;
552*2139Sjp161948 	const ASN1_OBJECT *a= *(ASN1_OBJECT * const *)ap;
553*2139Sjp161948 	const ASN1_OBJECT *b= *(ASN1_OBJECT * const *)bp;
5540Sstevel@tonic-gate 
5550Sstevel@tonic-gate 	j=(a->length - b->length);
5560Sstevel@tonic-gate         if (j) return(j);
5570Sstevel@tonic-gate 	return(memcmp(a->data,b->data,a->length));
5580Sstevel@tonic-gate         }
5590Sstevel@tonic-gate 
OBJ_bsearch(const char * key,const char * base,int num,int size,int (* cmp)(const void *,const void *))5600Sstevel@tonic-gate const char *OBJ_bsearch(const char *key, const char *base, int num, int size,
5610Sstevel@tonic-gate 	int (*cmp)(const void *, const void *))
5620Sstevel@tonic-gate 	{
563*2139Sjp161948 	return OBJ_bsearch_ex(key, base, num, size, cmp, 0);
564*2139Sjp161948 	}
565*2139Sjp161948 
OBJ_bsearch_ex(const char * key,const char * base,int num,int size,int (* cmp)(const void *,const void *),int flags)566*2139Sjp161948 const char *OBJ_bsearch_ex(const char *key, const char *base, int num,
567*2139Sjp161948 	int size, int (*cmp)(const void *, const void *), int flags)
568*2139Sjp161948 	{
569*2139Sjp161948 	int l,h,i=0,c=0;
570*2139Sjp161948 	const char *p = NULL;
5710Sstevel@tonic-gate 
5720Sstevel@tonic-gate 	if (num == 0) return(NULL);
5730Sstevel@tonic-gate 	l=0;
5740Sstevel@tonic-gate 	h=num;
5750Sstevel@tonic-gate 	while (l < h)
5760Sstevel@tonic-gate 		{
5770Sstevel@tonic-gate 		i=(l+h)/2;
5780Sstevel@tonic-gate 		p= &(base[i*size]);
5790Sstevel@tonic-gate 		c=(*cmp)(key,p);
5800Sstevel@tonic-gate 		if (c < 0)
5810Sstevel@tonic-gate 			h=i;
5820Sstevel@tonic-gate 		else if (c > 0)
5830Sstevel@tonic-gate 			l=i+1;
5840Sstevel@tonic-gate 		else
585*2139Sjp161948 			break;
5860Sstevel@tonic-gate 		}
5870Sstevel@tonic-gate #ifdef CHARSET_EBCDIC
5880Sstevel@tonic-gate /* THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and
5890Sstevel@tonic-gate  * I don't have perl (yet), we revert to a *LINEAR* search
5900Sstevel@tonic-gate  * when the object wasn't found in the binary search.
5910Sstevel@tonic-gate  */
592*2139Sjp161948 	if (c != 0)
593*2139Sjp161948 		{
594*2139Sjp161948 		for (i=0; i<num; ++i)
595*2139Sjp161948 			{
596*2139Sjp161948 			p= &(base[i*size]);
597*2139Sjp161948 			c = (*cmp)(key,p);
598*2139Sjp161948 			if (c == 0 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
599*2139Sjp161948 				return p;
600*2139Sjp161948 			}
601*2139Sjp161948 		}
6020Sstevel@tonic-gate #endif
603*2139Sjp161948 	if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))
604*2139Sjp161948 		p = NULL;
605*2139Sjp161948 	else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH))
606*2139Sjp161948 		{
607*2139Sjp161948 		while(i > 0 && (*cmp)(key,&(base[(i-1)*size])) == 0)
608*2139Sjp161948 			i--;
609*2139Sjp161948 		p = &(base[i*size]);
610*2139Sjp161948 		}
611*2139Sjp161948 	return(p);
6120Sstevel@tonic-gate 	}
6130Sstevel@tonic-gate 
OBJ_create_objects(BIO * in)6140Sstevel@tonic-gate int OBJ_create_objects(BIO *in)
6150Sstevel@tonic-gate 	{
6160Sstevel@tonic-gate 	MS_STATIC char buf[512];
6170Sstevel@tonic-gate 	int i,num=0;
6180Sstevel@tonic-gate 	char *o,*s,*l=NULL;
6190Sstevel@tonic-gate 
6200Sstevel@tonic-gate 	for (;;)
6210Sstevel@tonic-gate 		{
6220Sstevel@tonic-gate 		s=o=NULL;
6230Sstevel@tonic-gate 		i=BIO_gets(in,buf,512);
6240Sstevel@tonic-gate 		if (i <= 0) return(num);
6250Sstevel@tonic-gate 		buf[i-1]='\0';
6260Sstevel@tonic-gate 		if (!isalnum((unsigned char)buf[0])) return(num);
6270Sstevel@tonic-gate 		o=s=buf;
6280Sstevel@tonic-gate 		while (isdigit((unsigned char)*s) || (*s == '.'))
6290Sstevel@tonic-gate 			s++;
6300Sstevel@tonic-gate 		if (*s != '\0')
6310Sstevel@tonic-gate 			{
6320Sstevel@tonic-gate 			*(s++)='\0';
6330Sstevel@tonic-gate 			while (isspace((unsigned char)*s))
6340Sstevel@tonic-gate 				s++;
6350Sstevel@tonic-gate 			if (*s == '\0')
6360Sstevel@tonic-gate 				s=NULL;
6370Sstevel@tonic-gate 			else
6380Sstevel@tonic-gate 				{
6390Sstevel@tonic-gate 				l=s;
6400Sstevel@tonic-gate 				while ((*l != '\0') && !isspace((unsigned char)*l))
6410Sstevel@tonic-gate 					l++;
6420Sstevel@tonic-gate 				if (*l != '\0')
6430Sstevel@tonic-gate 					{
6440Sstevel@tonic-gate 					*(l++)='\0';
6450Sstevel@tonic-gate 					while (isspace((unsigned char)*l))
6460Sstevel@tonic-gate 						l++;
6470Sstevel@tonic-gate 					if (*l == '\0') l=NULL;
6480Sstevel@tonic-gate 					}
6490Sstevel@tonic-gate 				else
6500Sstevel@tonic-gate 					l=NULL;
6510Sstevel@tonic-gate 				}
6520Sstevel@tonic-gate 			}
6530Sstevel@tonic-gate 		else
6540Sstevel@tonic-gate 			s=NULL;
6550Sstevel@tonic-gate 		if ((o == NULL) || (*o == '\0')) return(num);
6560Sstevel@tonic-gate 		if (!OBJ_create(o,s,l)) return(num);
6570Sstevel@tonic-gate 		num++;
6580Sstevel@tonic-gate 		}
6590Sstevel@tonic-gate 	/* return(num); */
6600Sstevel@tonic-gate 	}
6610Sstevel@tonic-gate 
OBJ_create(const char * oid,const char * sn,const char * ln)6620Sstevel@tonic-gate int OBJ_create(const char *oid, const char *sn, const char *ln)
6630Sstevel@tonic-gate 	{
6640Sstevel@tonic-gate 	int ok=0;
6650Sstevel@tonic-gate 	ASN1_OBJECT *op=NULL;
6660Sstevel@tonic-gate 	unsigned char *buf;
6670Sstevel@tonic-gate 	int i;
6680Sstevel@tonic-gate 
6690Sstevel@tonic-gate 	i=a2d_ASN1_OBJECT(NULL,0,oid,-1);
6700Sstevel@tonic-gate 	if (i <= 0) return(0);
6710Sstevel@tonic-gate 
6720Sstevel@tonic-gate 	if ((buf=(unsigned char *)OPENSSL_malloc(i)) == NULL)
6730Sstevel@tonic-gate 		{
674*2139Sjp161948 		OBJerr(OBJ_F_OBJ_CREATE,ERR_R_MALLOC_FAILURE);
6750Sstevel@tonic-gate 		return(0);
6760Sstevel@tonic-gate 		}
6770Sstevel@tonic-gate 	i=a2d_ASN1_OBJECT(buf,i,oid,-1);
6780Sstevel@tonic-gate 	if (i == 0)
6790Sstevel@tonic-gate 		goto err;
6800Sstevel@tonic-gate 	op=(ASN1_OBJECT *)ASN1_OBJECT_create(OBJ_new_nid(1),buf,i,sn,ln);
6810Sstevel@tonic-gate 	if (op == NULL)
6820Sstevel@tonic-gate 		goto err;
6830Sstevel@tonic-gate 	ok=OBJ_add_object(op);
6840Sstevel@tonic-gate err:
6850Sstevel@tonic-gate 	ASN1_OBJECT_free(op);
6860Sstevel@tonic-gate 	OPENSSL_free(buf);
6870Sstevel@tonic-gate 	return(ok);
6880Sstevel@tonic-gate 	}
6890Sstevel@tonic-gate 
690