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