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