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