xref: /onnv-gate/usr/src/common/openssl/crypto/objects/obj_dat.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /* crypto/objects/obj_dat.c */
2*0Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3*0Sstevel@tonic-gate  * All rights reserved.
4*0Sstevel@tonic-gate  *
5*0Sstevel@tonic-gate  * This package is an SSL implementation written
6*0Sstevel@tonic-gate  * by Eric Young (eay@cryptsoft.com).
7*0Sstevel@tonic-gate  * The implementation was written so as to conform with Netscapes SSL.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * This library is free for commercial and non-commercial use as long as
10*0Sstevel@tonic-gate  * the following conditions are aheared to.  The following conditions
11*0Sstevel@tonic-gate  * apply to all code found in this distribution, be it the RC4, RSA,
12*0Sstevel@tonic-gate  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13*0Sstevel@tonic-gate  * included with this distribution is covered by the same copyright terms
14*0Sstevel@tonic-gate  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15*0Sstevel@tonic-gate  *
16*0Sstevel@tonic-gate  * Copyright remains Eric Young's, and as such any Copyright notices in
17*0Sstevel@tonic-gate  * the code are not to be removed.
18*0Sstevel@tonic-gate  * If this package is used in a product, Eric Young should be given attribution
19*0Sstevel@tonic-gate  * as the author of the parts of the library used.
20*0Sstevel@tonic-gate  * This can be in the form of a textual message at program startup or
21*0Sstevel@tonic-gate  * in documentation (online or textual) provided with the package.
22*0Sstevel@tonic-gate  *
23*0Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
24*0Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
25*0Sstevel@tonic-gate  * are met:
26*0Sstevel@tonic-gate  * 1. Redistributions of source code must retain the copyright
27*0Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
28*0Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
29*0Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
30*0Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
31*0Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this software
32*0Sstevel@tonic-gate  *    must display the following acknowledgement:
33*0Sstevel@tonic-gate  *    "This product includes cryptographic software written by
34*0Sstevel@tonic-gate  *     Eric Young (eay@cryptsoft.com)"
35*0Sstevel@tonic-gate  *    The word 'cryptographic' can be left out if the rouines from the library
36*0Sstevel@tonic-gate  *    being used are not cryptographic related :-).
37*0Sstevel@tonic-gate  * 4. If you include any Windows specific code (or a derivative thereof) from
38*0Sstevel@tonic-gate  *    the apps directory (application code) you must include an acknowledgement:
39*0Sstevel@tonic-gate  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40*0Sstevel@tonic-gate  *
41*0Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42*0Sstevel@tonic-gate  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43*0Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44*0Sstevel@tonic-gate  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45*0Sstevel@tonic-gate  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46*0Sstevel@tonic-gate  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47*0Sstevel@tonic-gate  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48*0Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49*0Sstevel@tonic-gate  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50*0Sstevel@tonic-gate  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51*0Sstevel@tonic-gate  * SUCH DAMAGE.
52*0Sstevel@tonic-gate  *
53*0Sstevel@tonic-gate  * The licence and distribution terms for any publically available version or
54*0Sstevel@tonic-gate  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55*0Sstevel@tonic-gate  * copied and put under another distribution licence
56*0Sstevel@tonic-gate  * [including the GNU Public Licence.]
57*0Sstevel@tonic-gate  */
58*0Sstevel@tonic-gate 
59*0Sstevel@tonic-gate #include <stdio.h>
60*0Sstevel@tonic-gate #include <ctype.h>
61*0Sstevel@tonic-gate #include "cryptlib.h"
62*0Sstevel@tonic-gate #include <openssl/lhash.h>
63*0Sstevel@tonic-gate #include <openssl/asn1.h>
64*0Sstevel@tonic-gate #include <openssl/objects.h>
65*0Sstevel@tonic-gate 
66*0Sstevel@tonic-gate /* obj_dat.h is generated from objects.h by obj_dat.pl */
67*0Sstevel@tonic-gate #ifndef OPENSSL_NO_OBJECT
68*0Sstevel@tonic-gate #include "obj_dat.h"
69*0Sstevel@tonic-gate #else
70*0Sstevel@tonic-gate /* You will have to load all the objects needed manually in the application */
71*0Sstevel@tonic-gate #define NUM_NID 0
72*0Sstevel@tonic-gate #define NUM_SN 0
73*0Sstevel@tonic-gate #define NUM_LN 0
74*0Sstevel@tonic-gate #define NUM_OBJ 0
75*0Sstevel@tonic-gate static unsigned char lvalues[1];
76*0Sstevel@tonic-gate static ASN1_OBJECT nid_objs[1];
77*0Sstevel@tonic-gate static ASN1_OBJECT *sn_objs[1];
78*0Sstevel@tonic-gate static ASN1_OBJECT *ln_objs[1];
79*0Sstevel@tonic-gate static ASN1_OBJECT *obj_objs[1];
80*0Sstevel@tonic-gate #endif
81*0Sstevel@tonic-gate 
82*0Sstevel@tonic-gate static int sn_cmp(const void *a, const void *b);
83*0Sstevel@tonic-gate static int ln_cmp(const void *a, const void *b);
84*0Sstevel@tonic-gate static int obj_cmp(const void *a, const void *b);
85*0Sstevel@tonic-gate #define ADDED_DATA	0
86*0Sstevel@tonic-gate #define ADDED_SNAME	1
87*0Sstevel@tonic-gate #define ADDED_LNAME	2
88*0Sstevel@tonic-gate #define ADDED_NID	3
89*0Sstevel@tonic-gate 
90*0Sstevel@tonic-gate typedef struct added_obj_st
91*0Sstevel@tonic-gate 	{
92*0Sstevel@tonic-gate 	int type;
93*0Sstevel@tonic-gate 	ASN1_OBJECT *obj;
94*0Sstevel@tonic-gate 	} ADDED_OBJ;
95*0Sstevel@tonic-gate 
96*0Sstevel@tonic-gate static int new_nid=NUM_NID;
97*0Sstevel@tonic-gate static LHASH *added=NULL;
98*0Sstevel@tonic-gate 
99*0Sstevel@tonic-gate static int sn_cmp(const void *a, const void *b)
100*0Sstevel@tonic-gate 	{
101*0Sstevel@tonic-gate 	const ASN1_OBJECT * const *ap = a, * const *bp = b;
102*0Sstevel@tonic-gate 	return(strcmp((*ap)->sn,(*bp)->sn));
103*0Sstevel@tonic-gate 	}
104*0Sstevel@tonic-gate 
105*0Sstevel@tonic-gate static int ln_cmp(const void *a, const void *b)
106*0Sstevel@tonic-gate 	{
107*0Sstevel@tonic-gate 	const ASN1_OBJECT * const *ap = a, * const *bp = b;
108*0Sstevel@tonic-gate 	return(strcmp((*ap)->ln,(*bp)->ln));
109*0Sstevel@tonic-gate 	}
110*0Sstevel@tonic-gate 
111*0Sstevel@tonic-gate /* static unsigned long add_hash(ADDED_OBJ *ca) */
112*0Sstevel@tonic-gate static unsigned long add_hash(const void *ca_void)
113*0Sstevel@tonic-gate 	{
114*0Sstevel@tonic-gate 	const ASN1_OBJECT *a;
115*0Sstevel@tonic-gate 	int i;
116*0Sstevel@tonic-gate 	unsigned long ret=0;
117*0Sstevel@tonic-gate 	unsigned char *p;
118*0Sstevel@tonic-gate 	ADDED_OBJ *ca = (ADDED_OBJ *)ca_void;
119*0Sstevel@tonic-gate 
120*0Sstevel@tonic-gate 	a=ca->obj;
121*0Sstevel@tonic-gate 	switch (ca->type)
122*0Sstevel@tonic-gate 		{
123*0Sstevel@tonic-gate 	case ADDED_DATA:
124*0Sstevel@tonic-gate 		ret=a->length<<20L;
125*0Sstevel@tonic-gate 		p=(unsigned char *)a->data;
126*0Sstevel@tonic-gate 		for (i=0; i<a->length; i++)
127*0Sstevel@tonic-gate 			ret^=p[i]<<((i*3)%24);
128*0Sstevel@tonic-gate 		break;
129*0Sstevel@tonic-gate 	case ADDED_SNAME:
130*0Sstevel@tonic-gate 		ret=lh_strhash(a->sn);
131*0Sstevel@tonic-gate 		break;
132*0Sstevel@tonic-gate 	case ADDED_LNAME:
133*0Sstevel@tonic-gate 		ret=lh_strhash(a->ln);
134*0Sstevel@tonic-gate 		break;
135*0Sstevel@tonic-gate 	case ADDED_NID:
136*0Sstevel@tonic-gate 		ret=a->nid;
137*0Sstevel@tonic-gate 		break;
138*0Sstevel@tonic-gate 	default:
139*0Sstevel@tonic-gate 		/* abort(); */
140*0Sstevel@tonic-gate 		return 0;
141*0Sstevel@tonic-gate 		}
142*0Sstevel@tonic-gate 	ret&=0x3fffffffL;
143*0Sstevel@tonic-gate 	ret|=ca->type<<30L;
144*0Sstevel@tonic-gate 	return(ret);
145*0Sstevel@tonic-gate 	}
146*0Sstevel@tonic-gate 
147*0Sstevel@tonic-gate /* static int add_cmp(ADDED_OBJ *ca, ADDED_OBJ *cb) */
148*0Sstevel@tonic-gate static int add_cmp(const void *ca_void, const void *cb_void)
149*0Sstevel@tonic-gate 	{
150*0Sstevel@tonic-gate 	ASN1_OBJECT *a,*b;
151*0Sstevel@tonic-gate 	int i;
152*0Sstevel@tonic-gate 	ADDED_OBJ *ca = (ADDED_OBJ *)ca_void;
153*0Sstevel@tonic-gate 	ADDED_OBJ *cb = (ADDED_OBJ *)cb_void;
154*0Sstevel@tonic-gate 
155*0Sstevel@tonic-gate 	i=ca->type-cb->type;
156*0Sstevel@tonic-gate 	if (i) return(i);
157*0Sstevel@tonic-gate 	a=ca->obj;
158*0Sstevel@tonic-gate 	b=cb->obj;
159*0Sstevel@tonic-gate 	switch (ca->type)
160*0Sstevel@tonic-gate 		{
161*0Sstevel@tonic-gate 	case ADDED_DATA:
162*0Sstevel@tonic-gate 		i=(a->length - b->length);
163*0Sstevel@tonic-gate 		if (i) return(i);
164*0Sstevel@tonic-gate 		return(memcmp(a->data,b->data,a->length));
165*0Sstevel@tonic-gate 	case ADDED_SNAME:
166*0Sstevel@tonic-gate 		if (a->sn == NULL) return(-1);
167*0Sstevel@tonic-gate 		else if (b->sn == NULL) return(1);
168*0Sstevel@tonic-gate 		else return(strcmp(a->sn,b->sn));
169*0Sstevel@tonic-gate 	case ADDED_LNAME:
170*0Sstevel@tonic-gate 		if (a->ln == NULL) return(-1);
171*0Sstevel@tonic-gate 		else if (b->ln == NULL) return(1);
172*0Sstevel@tonic-gate 		else return(strcmp(a->ln,b->ln));
173*0Sstevel@tonic-gate 	case ADDED_NID:
174*0Sstevel@tonic-gate 		return(a->nid-b->nid);
175*0Sstevel@tonic-gate 	default:
176*0Sstevel@tonic-gate 		/* abort(); */
177*0Sstevel@tonic-gate 		return 0;
178*0Sstevel@tonic-gate 		}
179*0Sstevel@tonic-gate 	}
180*0Sstevel@tonic-gate 
181*0Sstevel@tonic-gate static int init_added(void)
182*0Sstevel@tonic-gate 	{
183*0Sstevel@tonic-gate 	if (added != NULL) return(1);
184*0Sstevel@tonic-gate 	added=lh_new(add_hash,add_cmp);
185*0Sstevel@tonic-gate 	return(added != NULL);
186*0Sstevel@tonic-gate 	}
187*0Sstevel@tonic-gate 
188*0Sstevel@tonic-gate static void cleanup1(ADDED_OBJ *a)
189*0Sstevel@tonic-gate 	{
190*0Sstevel@tonic-gate 	a->obj->nid=0;
191*0Sstevel@tonic-gate 	a->obj->flags|=ASN1_OBJECT_FLAG_DYNAMIC|
192*0Sstevel@tonic-gate 	                ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
193*0Sstevel@tonic-gate 			ASN1_OBJECT_FLAG_DYNAMIC_DATA;
194*0Sstevel@tonic-gate 	}
195*0Sstevel@tonic-gate 
196*0Sstevel@tonic-gate static void cleanup2(ADDED_OBJ *a)
197*0Sstevel@tonic-gate 	{ a->obj->nid++; }
198*0Sstevel@tonic-gate 
199*0Sstevel@tonic-gate static void cleanup3(ADDED_OBJ *a)
200*0Sstevel@tonic-gate 	{
201*0Sstevel@tonic-gate 	if (--a->obj->nid == 0)
202*0Sstevel@tonic-gate 		ASN1_OBJECT_free(a->obj);
203*0Sstevel@tonic-gate 	OPENSSL_free(a);
204*0Sstevel@tonic-gate 	}
205*0Sstevel@tonic-gate 
206*0Sstevel@tonic-gate static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ *)
207*0Sstevel@tonic-gate static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ *)
208*0Sstevel@tonic-gate static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ *)
209*0Sstevel@tonic-gate 
210*0Sstevel@tonic-gate void OBJ_cleanup(void)
211*0Sstevel@tonic-gate 	{
212*0Sstevel@tonic-gate 	if (added == NULL) return;
213*0Sstevel@tonic-gate 	added->down_load=0;
214*0Sstevel@tonic-gate 	lh_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */
215*0Sstevel@tonic-gate 	lh_doall(added,LHASH_DOALL_FN(cleanup2)); /* set counters */
216*0Sstevel@tonic-gate 	lh_doall(added,LHASH_DOALL_FN(cleanup3)); /* free objects */
217*0Sstevel@tonic-gate 	lh_free(added);
218*0Sstevel@tonic-gate 	added=NULL;
219*0Sstevel@tonic-gate 	}
220*0Sstevel@tonic-gate 
221*0Sstevel@tonic-gate int OBJ_new_nid(int num)
222*0Sstevel@tonic-gate 	{
223*0Sstevel@tonic-gate 	int i;
224*0Sstevel@tonic-gate 
225*0Sstevel@tonic-gate 	i=new_nid;
226*0Sstevel@tonic-gate 	new_nid+=num;
227*0Sstevel@tonic-gate 	return(i);
228*0Sstevel@tonic-gate 	}
229*0Sstevel@tonic-gate 
230*0Sstevel@tonic-gate int OBJ_add_object(const ASN1_OBJECT *obj)
231*0Sstevel@tonic-gate 	{
232*0Sstevel@tonic-gate 	ASN1_OBJECT *o;
233*0Sstevel@tonic-gate 	ADDED_OBJ *ao[4]={NULL,NULL,NULL,NULL},*aop;
234*0Sstevel@tonic-gate 	int i;
235*0Sstevel@tonic-gate 
236*0Sstevel@tonic-gate 	if (added == NULL)
237*0Sstevel@tonic-gate 		if (!init_added()) return(0);
238*0Sstevel@tonic-gate 	if ((o=OBJ_dup(obj)) == NULL) goto err;
239*0Sstevel@tonic-gate 	if (!(ao[ADDED_NID]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err;
240*0Sstevel@tonic-gate 	if ((o->length != 0) && (obj->data != NULL))
241*0Sstevel@tonic-gate 		ao[ADDED_DATA]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ));
242*0Sstevel@tonic-gate 	if (o->sn != NULL)
243*0Sstevel@tonic-gate 		ao[ADDED_SNAME]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ));
244*0Sstevel@tonic-gate 	if (o->ln != NULL)
245*0Sstevel@tonic-gate 		ao[ADDED_LNAME]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ));
246*0Sstevel@tonic-gate 
247*0Sstevel@tonic-gate 	for (i=ADDED_DATA; i<=ADDED_NID; i++)
248*0Sstevel@tonic-gate 		{
249*0Sstevel@tonic-gate 		if (ao[i] != NULL)
250*0Sstevel@tonic-gate 			{
251*0Sstevel@tonic-gate 			ao[i]->type=i;
252*0Sstevel@tonic-gate 			ao[i]->obj=o;
253*0Sstevel@tonic-gate 			aop=(ADDED_OBJ *)lh_insert(added,ao[i]);
254*0Sstevel@tonic-gate 			/* memory leak, buit should not normally matter */
255*0Sstevel@tonic-gate 			if (aop != NULL)
256*0Sstevel@tonic-gate 				OPENSSL_free(aop);
257*0Sstevel@tonic-gate 			}
258*0Sstevel@tonic-gate 		}
259*0Sstevel@tonic-gate 	o->flags&= ~(ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
260*0Sstevel@tonic-gate 			ASN1_OBJECT_FLAG_DYNAMIC_DATA);
261*0Sstevel@tonic-gate 
262*0Sstevel@tonic-gate 	return(o->nid);
263*0Sstevel@tonic-gate err:
264*0Sstevel@tonic-gate 	for (i=ADDED_DATA; i<=ADDED_NID; i++)
265*0Sstevel@tonic-gate 		if (ao[i] != NULL) OPENSSL_free(ao[i]);
266*0Sstevel@tonic-gate 	if (o != NULL) OPENSSL_free(o);
267*0Sstevel@tonic-gate 	return(NID_undef);
268*0Sstevel@tonic-gate 	}
269*0Sstevel@tonic-gate 
270*0Sstevel@tonic-gate ASN1_OBJECT *OBJ_nid2obj(int n)
271*0Sstevel@tonic-gate 	{
272*0Sstevel@tonic-gate 	ADDED_OBJ ad,*adp;
273*0Sstevel@tonic-gate 	ASN1_OBJECT ob;
274*0Sstevel@tonic-gate 
275*0Sstevel@tonic-gate 	if ((n >= 0) && (n < NUM_NID))
276*0Sstevel@tonic-gate 		{
277*0Sstevel@tonic-gate 		if ((n != NID_undef) && (nid_objs[n].nid == NID_undef))
278*0Sstevel@tonic-gate 			{
279*0Sstevel@tonic-gate 			OBJerr(OBJ_F_OBJ_NID2OBJ,OBJ_R_UNKNOWN_NID);
280*0Sstevel@tonic-gate 			return(NULL);
281*0Sstevel@tonic-gate 			}
282*0Sstevel@tonic-gate 		return((ASN1_OBJECT *)&(nid_objs[n]));
283*0Sstevel@tonic-gate 		}
284*0Sstevel@tonic-gate 	else if (added == NULL)
285*0Sstevel@tonic-gate 		return(NULL);
286*0Sstevel@tonic-gate 	else
287*0Sstevel@tonic-gate 		{
288*0Sstevel@tonic-gate 		ad.type=ADDED_NID;
289*0Sstevel@tonic-gate 		ad.obj= &ob;
290*0Sstevel@tonic-gate 		ob.nid=n;
291*0Sstevel@tonic-gate 		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
292*0Sstevel@tonic-gate 		if (adp != NULL)
293*0Sstevel@tonic-gate 			return(adp->obj);
294*0Sstevel@tonic-gate 		else
295*0Sstevel@tonic-gate 			{
296*0Sstevel@tonic-gate 			OBJerr(OBJ_F_OBJ_NID2OBJ,OBJ_R_UNKNOWN_NID);
297*0Sstevel@tonic-gate 			return(NULL);
298*0Sstevel@tonic-gate 			}
299*0Sstevel@tonic-gate 		}
300*0Sstevel@tonic-gate 	}
301*0Sstevel@tonic-gate 
302*0Sstevel@tonic-gate const char *OBJ_nid2sn(int n)
303*0Sstevel@tonic-gate 	{
304*0Sstevel@tonic-gate 	ADDED_OBJ ad,*adp;
305*0Sstevel@tonic-gate 	ASN1_OBJECT ob;
306*0Sstevel@tonic-gate 
307*0Sstevel@tonic-gate 	if ((n >= 0) && (n < NUM_NID))
308*0Sstevel@tonic-gate 		{
309*0Sstevel@tonic-gate 		if ((n != NID_undef) && (nid_objs[n].nid == NID_undef))
310*0Sstevel@tonic-gate 			{
311*0Sstevel@tonic-gate 			OBJerr(OBJ_F_OBJ_NID2SN,OBJ_R_UNKNOWN_NID);
312*0Sstevel@tonic-gate 			return(NULL);
313*0Sstevel@tonic-gate 			}
314*0Sstevel@tonic-gate 		return(nid_objs[n].sn);
315*0Sstevel@tonic-gate 		}
316*0Sstevel@tonic-gate 	else if (added == NULL)
317*0Sstevel@tonic-gate 		return(NULL);
318*0Sstevel@tonic-gate 	else
319*0Sstevel@tonic-gate 		{
320*0Sstevel@tonic-gate 		ad.type=ADDED_NID;
321*0Sstevel@tonic-gate 		ad.obj= &ob;
322*0Sstevel@tonic-gate 		ob.nid=n;
323*0Sstevel@tonic-gate 		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
324*0Sstevel@tonic-gate 		if (adp != NULL)
325*0Sstevel@tonic-gate 			return(adp->obj->sn);
326*0Sstevel@tonic-gate 		else
327*0Sstevel@tonic-gate 			{
328*0Sstevel@tonic-gate 			OBJerr(OBJ_F_OBJ_NID2SN,OBJ_R_UNKNOWN_NID);
329*0Sstevel@tonic-gate 			return(NULL);
330*0Sstevel@tonic-gate 			}
331*0Sstevel@tonic-gate 		}
332*0Sstevel@tonic-gate 	}
333*0Sstevel@tonic-gate 
334*0Sstevel@tonic-gate const char *OBJ_nid2ln(int n)
335*0Sstevel@tonic-gate 	{
336*0Sstevel@tonic-gate 	ADDED_OBJ ad,*adp;
337*0Sstevel@tonic-gate 	ASN1_OBJECT ob;
338*0Sstevel@tonic-gate 
339*0Sstevel@tonic-gate 	if ((n >= 0) && (n < NUM_NID))
340*0Sstevel@tonic-gate 		{
341*0Sstevel@tonic-gate 		if ((n != NID_undef) && (nid_objs[n].nid == NID_undef))
342*0Sstevel@tonic-gate 			{
343*0Sstevel@tonic-gate 			OBJerr(OBJ_F_OBJ_NID2LN,OBJ_R_UNKNOWN_NID);
344*0Sstevel@tonic-gate 			return(NULL);
345*0Sstevel@tonic-gate 			}
346*0Sstevel@tonic-gate 		return(nid_objs[n].ln);
347*0Sstevel@tonic-gate 		}
348*0Sstevel@tonic-gate 	else if (added == NULL)
349*0Sstevel@tonic-gate 		return(NULL);
350*0Sstevel@tonic-gate 	else
351*0Sstevel@tonic-gate 		{
352*0Sstevel@tonic-gate 		ad.type=ADDED_NID;
353*0Sstevel@tonic-gate 		ad.obj= &ob;
354*0Sstevel@tonic-gate 		ob.nid=n;
355*0Sstevel@tonic-gate 		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
356*0Sstevel@tonic-gate 		if (adp != NULL)
357*0Sstevel@tonic-gate 			return(adp->obj->ln);
358*0Sstevel@tonic-gate 		else
359*0Sstevel@tonic-gate 			{
360*0Sstevel@tonic-gate 			OBJerr(OBJ_F_OBJ_NID2LN,OBJ_R_UNKNOWN_NID);
361*0Sstevel@tonic-gate 			return(NULL);
362*0Sstevel@tonic-gate 			}
363*0Sstevel@tonic-gate 		}
364*0Sstevel@tonic-gate 	}
365*0Sstevel@tonic-gate 
366*0Sstevel@tonic-gate int OBJ_obj2nid(const ASN1_OBJECT *a)
367*0Sstevel@tonic-gate 	{
368*0Sstevel@tonic-gate 	ASN1_OBJECT **op;
369*0Sstevel@tonic-gate 	ADDED_OBJ ad,*adp;
370*0Sstevel@tonic-gate 
371*0Sstevel@tonic-gate 	if (a == NULL)
372*0Sstevel@tonic-gate 		return(NID_undef);
373*0Sstevel@tonic-gate 	if (a->nid != 0)
374*0Sstevel@tonic-gate 		return(a->nid);
375*0Sstevel@tonic-gate 
376*0Sstevel@tonic-gate 	if (added != NULL)
377*0Sstevel@tonic-gate 		{
378*0Sstevel@tonic-gate 		ad.type=ADDED_DATA;
379*0Sstevel@tonic-gate 		ad.obj=(ASN1_OBJECT *)a; /* XXX: ugly but harmless */
380*0Sstevel@tonic-gate 		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
381*0Sstevel@tonic-gate 		if (adp != NULL) return (adp->obj->nid);
382*0Sstevel@tonic-gate 		}
383*0Sstevel@tonic-gate 	op=(ASN1_OBJECT **)OBJ_bsearch((char *)&a,(char *)obj_objs,NUM_OBJ,
384*0Sstevel@tonic-gate 		sizeof(ASN1_OBJECT *),obj_cmp);
385*0Sstevel@tonic-gate 	if (op == NULL)
386*0Sstevel@tonic-gate 		return(NID_undef);
387*0Sstevel@tonic-gate 	return((*op)->nid);
388*0Sstevel@tonic-gate 	}
389*0Sstevel@tonic-gate 
390*0Sstevel@tonic-gate /* Convert an object name into an ASN1_OBJECT
391*0Sstevel@tonic-gate  * if "noname" is not set then search for short and long names first.
392*0Sstevel@tonic-gate  * This will convert the "dotted" form into an object: unlike OBJ_txt2nid
393*0Sstevel@tonic-gate  * it can be used with any objects, not just registered ones.
394*0Sstevel@tonic-gate  */
395*0Sstevel@tonic-gate 
396*0Sstevel@tonic-gate ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name)
397*0Sstevel@tonic-gate 	{
398*0Sstevel@tonic-gate 	int nid = NID_undef;
399*0Sstevel@tonic-gate 	ASN1_OBJECT *op=NULL;
400*0Sstevel@tonic-gate 	unsigned char *buf,*p;
401*0Sstevel@tonic-gate 	int i, j;
402*0Sstevel@tonic-gate 
403*0Sstevel@tonic-gate 	if(!no_name) {
404*0Sstevel@tonic-gate 		if( ((nid = OBJ_sn2nid(s)) != NID_undef) ||
405*0Sstevel@tonic-gate 			((nid = OBJ_ln2nid(s)) != NID_undef) )
406*0Sstevel@tonic-gate 					return OBJ_nid2obj(nid);
407*0Sstevel@tonic-gate 	}
408*0Sstevel@tonic-gate 
409*0Sstevel@tonic-gate 	/* Work out size of content octets */
410*0Sstevel@tonic-gate 	i=a2d_ASN1_OBJECT(NULL,0,s,-1);
411*0Sstevel@tonic-gate 	if (i <= 0) {
412*0Sstevel@tonic-gate 		/* Clear the error */
413*0Sstevel@tonic-gate 		ERR_get_error();
414*0Sstevel@tonic-gate 		return NULL;
415*0Sstevel@tonic-gate 	}
416*0Sstevel@tonic-gate 	/* Work out total size */
417*0Sstevel@tonic-gate 	j = ASN1_object_size(0,i,V_ASN1_OBJECT);
418*0Sstevel@tonic-gate 
419*0Sstevel@tonic-gate 	if((buf=(unsigned char *)OPENSSL_malloc(j)) == NULL) return NULL;
420*0Sstevel@tonic-gate 
421*0Sstevel@tonic-gate 	p = buf;
422*0Sstevel@tonic-gate 	/* Write out tag+length */
423*0Sstevel@tonic-gate 	ASN1_put_object(&p,0,i,V_ASN1_OBJECT,V_ASN1_UNIVERSAL);
424*0Sstevel@tonic-gate 	/* Write out contents */
425*0Sstevel@tonic-gate 	a2d_ASN1_OBJECT(p,i,s,-1);
426*0Sstevel@tonic-gate 
427*0Sstevel@tonic-gate 	p=buf;
428*0Sstevel@tonic-gate 	op=d2i_ASN1_OBJECT(NULL,&p,j);
429*0Sstevel@tonic-gate 	OPENSSL_free(buf);
430*0Sstevel@tonic-gate 	return op;
431*0Sstevel@tonic-gate 	}
432*0Sstevel@tonic-gate 
433*0Sstevel@tonic-gate int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
434*0Sstevel@tonic-gate {
435*0Sstevel@tonic-gate 	int i,idx=0,n=0,len,nid;
436*0Sstevel@tonic-gate 	unsigned long l;
437*0Sstevel@tonic-gate 	unsigned char *p;
438*0Sstevel@tonic-gate 	const char *s;
439*0Sstevel@tonic-gate 	char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2];
440*0Sstevel@tonic-gate 
441*0Sstevel@tonic-gate 	if (buf_len <= 0) return(0);
442*0Sstevel@tonic-gate 
443*0Sstevel@tonic-gate 	if ((a == NULL) || (a->data == NULL)) {
444*0Sstevel@tonic-gate 		buf[0]='\0';
445*0Sstevel@tonic-gate 		return(0);
446*0Sstevel@tonic-gate 	}
447*0Sstevel@tonic-gate 
448*0Sstevel@tonic-gate 	if (no_name || (nid=OBJ_obj2nid(a)) == NID_undef) {
449*0Sstevel@tonic-gate 		len=a->length;
450*0Sstevel@tonic-gate 		p=a->data;
451*0Sstevel@tonic-gate 
452*0Sstevel@tonic-gate 		idx=0;
453*0Sstevel@tonic-gate 		l=0;
454*0Sstevel@tonic-gate 		while (idx < a->length) {
455*0Sstevel@tonic-gate 			l|=(p[idx]&0x7f);
456*0Sstevel@tonic-gate 			if (!(p[idx] & 0x80)) break;
457*0Sstevel@tonic-gate 			l<<=7L;
458*0Sstevel@tonic-gate 			idx++;
459*0Sstevel@tonic-gate 		}
460*0Sstevel@tonic-gate 		idx++;
461*0Sstevel@tonic-gate 		i=(int)(l/40);
462*0Sstevel@tonic-gate 		if (i > 2) i=2;
463*0Sstevel@tonic-gate 		l-=(long)(i*40);
464*0Sstevel@tonic-gate 
465*0Sstevel@tonic-gate 		BIO_snprintf(tbuf,sizeof tbuf,"%d.%lu",i,l);
466*0Sstevel@tonic-gate 		i=strlen(tbuf);
467*0Sstevel@tonic-gate 		BUF_strlcpy(buf,tbuf,buf_len);
468*0Sstevel@tonic-gate 		buf_len-=i;
469*0Sstevel@tonic-gate 		buf+=i;
470*0Sstevel@tonic-gate 		n+=i;
471*0Sstevel@tonic-gate 
472*0Sstevel@tonic-gate 		l=0;
473*0Sstevel@tonic-gate 		for (; idx<len; idx++) {
474*0Sstevel@tonic-gate 			l|=p[idx]&0x7f;
475*0Sstevel@tonic-gate 			if (!(p[idx] & 0x80)) {
476*0Sstevel@tonic-gate 				BIO_snprintf(tbuf,sizeof tbuf,".%lu",l);
477*0Sstevel@tonic-gate 				i=strlen(tbuf);
478*0Sstevel@tonic-gate 				if (buf_len > 0)
479*0Sstevel@tonic-gate 					BUF_strlcpy(buf,tbuf,buf_len);
480*0Sstevel@tonic-gate 				buf_len-=i;
481*0Sstevel@tonic-gate 				buf+=i;
482*0Sstevel@tonic-gate 				n+=i;
483*0Sstevel@tonic-gate 				l=0;
484*0Sstevel@tonic-gate 			}
485*0Sstevel@tonic-gate 			l<<=7L;
486*0Sstevel@tonic-gate 		}
487*0Sstevel@tonic-gate 	} else {
488*0Sstevel@tonic-gate 		s=OBJ_nid2ln(nid);
489*0Sstevel@tonic-gate 		if (s == NULL)
490*0Sstevel@tonic-gate 			s=OBJ_nid2sn(nid);
491*0Sstevel@tonic-gate 		BUF_strlcpy(buf,s,buf_len);
492*0Sstevel@tonic-gate 		n=strlen(s);
493*0Sstevel@tonic-gate 	}
494*0Sstevel@tonic-gate 	return(n);
495*0Sstevel@tonic-gate }
496*0Sstevel@tonic-gate 
497*0Sstevel@tonic-gate int OBJ_txt2nid(const char *s)
498*0Sstevel@tonic-gate {
499*0Sstevel@tonic-gate 	ASN1_OBJECT *obj;
500*0Sstevel@tonic-gate 	int nid;
501*0Sstevel@tonic-gate 	obj = OBJ_txt2obj(s, 0);
502*0Sstevel@tonic-gate 	nid = OBJ_obj2nid(obj);
503*0Sstevel@tonic-gate 	ASN1_OBJECT_free(obj);
504*0Sstevel@tonic-gate 	return nid;
505*0Sstevel@tonic-gate }
506*0Sstevel@tonic-gate 
507*0Sstevel@tonic-gate int OBJ_ln2nid(const char *s)
508*0Sstevel@tonic-gate 	{
509*0Sstevel@tonic-gate 	ASN1_OBJECT o,*oo= &o,**op;
510*0Sstevel@tonic-gate 	ADDED_OBJ ad,*adp;
511*0Sstevel@tonic-gate 
512*0Sstevel@tonic-gate 	o.ln=s;
513*0Sstevel@tonic-gate 	if (added != NULL)
514*0Sstevel@tonic-gate 		{
515*0Sstevel@tonic-gate 		ad.type=ADDED_LNAME;
516*0Sstevel@tonic-gate 		ad.obj= &o;
517*0Sstevel@tonic-gate 		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
518*0Sstevel@tonic-gate 		if (adp != NULL) return (adp->obj->nid);
519*0Sstevel@tonic-gate 		}
520*0Sstevel@tonic-gate 	op=(ASN1_OBJECT **)OBJ_bsearch((char *)&oo,(char *)ln_objs,NUM_LN,
521*0Sstevel@tonic-gate 		sizeof(ASN1_OBJECT *),ln_cmp);
522*0Sstevel@tonic-gate 	if (op == NULL) return(NID_undef);
523*0Sstevel@tonic-gate 	return((*op)->nid);
524*0Sstevel@tonic-gate 	}
525*0Sstevel@tonic-gate 
526*0Sstevel@tonic-gate int OBJ_sn2nid(const char *s)
527*0Sstevel@tonic-gate 	{
528*0Sstevel@tonic-gate 	ASN1_OBJECT o,*oo= &o,**op;
529*0Sstevel@tonic-gate 	ADDED_OBJ ad,*adp;
530*0Sstevel@tonic-gate 
531*0Sstevel@tonic-gate 	o.sn=s;
532*0Sstevel@tonic-gate 	if (added != NULL)
533*0Sstevel@tonic-gate 		{
534*0Sstevel@tonic-gate 		ad.type=ADDED_SNAME;
535*0Sstevel@tonic-gate 		ad.obj= &o;
536*0Sstevel@tonic-gate 		adp=(ADDED_OBJ *)lh_retrieve(added,&ad);
537*0Sstevel@tonic-gate 		if (adp != NULL) return (adp->obj->nid);
538*0Sstevel@tonic-gate 		}
539*0Sstevel@tonic-gate 	op=(ASN1_OBJECT **)OBJ_bsearch((char *)&oo,(char *)sn_objs,NUM_SN,
540*0Sstevel@tonic-gate 		sizeof(ASN1_OBJECT *),sn_cmp);
541*0Sstevel@tonic-gate 	if (op == NULL) return(NID_undef);
542*0Sstevel@tonic-gate 	return((*op)->nid);
543*0Sstevel@tonic-gate 	}
544*0Sstevel@tonic-gate 
545*0Sstevel@tonic-gate static int obj_cmp(const void *ap, const void *bp)
546*0Sstevel@tonic-gate 	{
547*0Sstevel@tonic-gate 	int j;
548*0Sstevel@tonic-gate 	ASN1_OBJECT *a= *(ASN1_OBJECT **)ap;
549*0Sstevel@tonic-gate 	ASN1_OBJECT *b= *(ASN1_OBJECT **)bp;
550*0Sstevel@tonic-gate 
551*0Sstevel@tonic-gate 	j=(a->length - b->length);
552*0Sstevel@tonic-gate         if (j) return(j);
553*0Sstevel@tonic-gate 	return(memcmp(a->data,b->data,a->length));
554*0Sstevel@tonic-gate         }
555*0Sstevel@tonic-gate 
556*0Sstevel@tonic-gate const char *OBJ_bsearch(const char *key, const char *base, int num, int size,
557*0Sstevel@tonic-gate 	int (*cmp)(const void *, const void *))
558*0Sstevel@tonic-gate 	{
559*0Sstevel@tonic-gate 	int l,h,i,c;
560*0Sstevel@tonic-gate 	const char *p;
561*0Sstevel@tonic-gate 
562*0Sstevel@tonic-gate 	if (num == 0) return(NULL);
563*0Sstevel@tonic-gate 	l=0;
564*0Sstevel@tonic-gate 	h=num;
565*0Sstevel@tonic-gate 	while (l < h)
566*0Sstevel@tonic-gate 		{
567*0Sstevel@tonic-gate 		i=(l+h)/2;
568*0Sstevel@tonic-gate 		p= &(base[i*size]);
569*0Sstevel@tonic-gate 		c=(*cmp)(key,p);
570*0Sstevel@tonic-gate 		if (c < 0)
571*0Sstevel@tonic-gate 			h=i;
572*0Sstevel@tonic-gate 		else if (c > 0)
573*0Sstevel@tonic-gate 			l=i+1;
574*0Sstevel@tonic-gate 		else
575*0Sstevel@tonic-gate 			return(p);
576*0Sstevel@tonic-gate 		}
577*0Sstevel@tonic-gate #ifdef CHARSET_EBCDIC
578*0Sstevel@tonic-gate /* THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and
579*0Sstevel@tonic-gate  * I don't have perl (yet), we revert to a *LINEAR* search
580*0Sstevel@tonic-gate  * when the object wasn't found in the binary search.
581*0Sstevel@tonic-gate  */
582*0Sstevel@tonic-gate 	for (i=0; i<num; ++i) {
583*0Sstevel@tonic-gate 		p= &(base[i*size]);
584*0Sstevel@tonic-gate 		if ((*cmp)(key,p) == 0)
585*0Sstevel@tonic-gate 			return p;
586*0Sstevel@tonic-gate 	}
587*0Sstevel@tonic-gate #endif
588*0Sstevel@tonic-gate 	return(NULL);
589*0Sstevel@tonic-gate 	}
590*0Sstevel@tonic-gate 
591*0Sstevel@tonic-gate int OBJ_create_objects(BIO *in)
592*0Sstevel@tonic-gate 	{
593*0Sstevel@tonic-gate 	MS_STATIC char buf[512];
594*0Sstevel@tonic-gate 	int i,num=0;
595*0Sstevel@tonic-gate 	char *o,*s,*l=NULL;
596*0Sstevel@tonic-gate 
597*0Sstevel@tonic-gate 	for (;;)
598*0Sstevel@tonic-gate 		{
599*0Sstevel@tonic-gate 		s=o=NULL;
600*0Sstevel@tonic-gate 		i=BIO_gets(in,buf,512);
601*0Sstevel@tonic-gate 		if (i <= 0) return(num);
602*0Sstevel@tonic-gate 		buf[i-1]='\0';
603*0Sstevel@tonic-gate 		if (!isalnum((unsigned char)buf[0])) return(num);
604*0Sstevel@tonic-gate 		o=s=buf;
605*0Sstevel@tonic-gate 		while (isdigit((unsigned char)*s) || (*s == '.'))
606*0Sstevel@tonic-gate 			s++;
607*0Sstevel@tonic-gate 		if (*s != '\0')
608*0Sstevel@tonic-gate 			{
609*0Sstevel@tonic-gate 			*(s++)='\0';
610*0Sstevel@tonic-gate 			while (isspace((unsigned char)*s))
611*0Sstevel@tonic-gate 				s++;
612*0Sstevel@tonic-gate 			if (*s == '\0')
613*0Sstevel@tonic-gate 				s=NULL;
614*0Sstevel@tonic-gate 			else
615*0Sstevel@tonic-gate 				{
616*0Sstevel@tonic-gate 				l=s;
617*0Sstevel@tonic-gate 				while ((*l != '\0') && !isspace((unsigned char)*l))
618*0Sstevel@tonic-gate 					l++;
619*0Sstevel@tonic-gate 				if (*l != '\0')
620*0Sstevel@tonic-gate 					{
621*0Sstevel@tonic-gate 					*(l++)='\0';
622*0Sstevel@tonic-gate 					while (isspace((unsigned char)*l))
623*0Sstevel@tonic-gate 						l++;
624*0Sstevel@tonic-gate 					if (*l == '\0') l=NULL;
625*0Sstevel@tonic-gate 					}
626*0Sstevel@tonic-gate 				else
627*0Sstevel@tonic-gate 					l=NULL;
628*0Sstevel@tonic-gate 				}
629*0Sstevel@tonic-gate 			}
630*0Sstevel@tonic-gate 		else
631*0Sstevel@tonic-gate 			s=NULL;
632*0Sstevel@tonic-gate 		if ((o == NULL) || (*o == '\0')) return(num);
633*0Sstevel@tonic-gate 		if (!OBJ_create(o,s,l)) return(num);
634*0Sstevel@tonic-gate 		num++;
635*0Sstevel@tonic-gate 		}
636*0Sstevel@tonic-gate 	/* return(num); */
637*0Sstevel@tonic-gate 	}
638*0Sstevel@tonic-gate 
639*0Sstevel@tonic-gate int OBJ_create(const char *oid, const char *sn, const char *ln)
640*0Sstevel@tonic-gate 	{
641*0Sstevel@tonic-gate 	int ok=0;
642*0Sstevel@tonic-gate 	ASN1_OBJECT *op=NULL;
643*0Sstevel@tonic-gate 	unsigned char *buf;
644*0Sstevel@tonic-gate 	int i;
645*0Sstevel@tonic-gate 
646*0Sstevel@tonic-gate 	i=a2d_ASN1_OBJECT(NULL,0,oid,-1);
647*0Sstevel@tonic-gate 	if (i <= 0) return(0);
648*0Sstevel@tonic-gate 
649*0Sstevel@tonic-gate 	if ((buf=(unsigned char *)OPENSSL_malloc(i)) == NULL)
650*0Sstevel@tonic-gate 		{
651*0Sstevel@tonic-gate 		OBJerr(OBJ_F_OBJ_CREATE,OBJ_R_MALLOC_FAILURE);
652*0Sstevel@tonic-gate 		return(0);
653*0Sstevel@tonic-gate 		}
654*0Sstevel@tonic-gate 	i=a2d_ASN1_OBJECT(buf,i,oid,-1);
655*0Sstevel@tonic-gate 	if (i == 0)
656*0Sstevel@tonic-gate 		goto err;
657*0Sstevel@tonic-gate 	op=(ASN1_OBJECT *)ASN1_OBJECT_create(OBJ_new_nid(1),buf,i,sn,ln);
658*0Sstevel@tonic-gate 	if (op == NULL)
659*0Sstevel@tonic-gate 		goto err;
660*0Sstevel@tonic-gate 	ok=OBJ_add_object(op);
661*0Sstevel@tonic-gate err:
662*0Sstevel@tonic-gate 	ASN1_OBJECT_free(op);
663*0Sstevel@tonic-gate 	OPENSSL_free(buf);
664*0Sstevel@tonic-gate 	return(ok);
665*0Sstevel@tonic-gate 	}
666*0Sstevel@tonic-gate 
667