155714Skris/* crypto/objects/obj_dat.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 8296341Sdelphij * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15296341Sdelphij * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 22296341Sdelphij * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 37296341Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40296341Sdelphij * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 52296341Sdelphij * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 5855714Skris 5955714Skris#include <stdio.h> 6055714Skris#include <ctype.h> 61160814Ssimon#include <limits.h> 6255714Skris#include "cryptlib.h" 6355714Skris#include <openssl/lhash.h> 6455714Skris#include <openssl/asn1.h> 6555714Skris#include <openssl/objects.h> 66194206Ssimon#include <openssl/bn.h> 6755714Skris 6855714Skris/* obj_dat.h is generated from objects.h by obj_dat.pl */ 69109998Smarkm#ifndef OPENSSL_NO_OBJECT 70296341Sdelphij# include "obj_dat.h" 7155714Skris#else 7255714Skris/* You will have to load all the objects needed manually in the application */ 73296341Sdelphij# define NUM_NID 0 74296341Sdelphij# define NUM_SN 0 75296341Sdelphij# define NUM_LN 0 76296341Sdelphij# define NUM_OBJ 0 77238405Sjkimstatic const unsigned char lvalues[1]; 78238405Sjkimstatic const ASN1_OBJECT nid_objs[1]; 79238405Sjkimstatic const unsigned int sn_objs[1]; 80238405Sjkimstatic const unsigned int ln_objs[1]; 81238405Sjkimstatic const unsigned int obj_objs[1]; 8255714Skris#endif 8355714Skris 84238405SjkimDECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn); 85238405SjkimDECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln); 86238405SjkimDECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj); 87238405Sjkim 88296341Sdelphij#define ADDED_DATA 0 89296341Sdelphij#define ADDED_SNAME 1 90296341Sdelphij#define ADDED_LNAME 2 91296341Sdelphij#define ADDED_NID 3 9255714Skris 93296341Sdelphijtypedef struct added_obj_st { 94296341Sdelphij int type; 95296341Sdelphij ASN1_OBJECT *obj; 96296341Sdelphij} ADDED_OBJ; 97238405SjkimDECLARE_LHASH_OF(ADDED_OBJ); 9855714Skris 99296341Sdelphijstatic int new_nid = NUM_NID; 100296341Sdelphijstatic LHASH_OF(ADDED_OBJ) *added = NULL; 10155714Skris 102296341Sdelphijstatic int sn_cmp(const ASN1_OBJECT *const *a, const unsigned int *b) 103296341Sdelphij{ 104296341Sdelphij return (strcmp((*a)->sn, nid_objs[*b].sn)); 105296341Sdelphij} 10655714Skris 107238405SjkimIMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn); 10855714Skris 109296341Sdelphijstatic int ln_cmp(const ASN1_OBJECT *const *a, const unsigned int *b) 110296341Sdelphij{ 111296341Sdelphij return (strcmp((*a)->ln, nid_objs[*b].ln)); 112296341Sdelphij} 113238405Sjkim 114238405SjkimIMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln); 115238405Sjkim 116238405Sjkimstatic unsigned long added_obj_hash(const ADDED_OBJ *ca) 117296341Sdelphij{ 118296341Sdelphij const ASN1_OBJECT *a; 119296341Sdelphij int i; 120296341Sdelphij unsigned long ret = 0; 121296341Sdelphij unsigned char *p; 12255714Skris 123296341Sdelphij a = ca->obj; 124296341Sdelphij switch (ca->type) { 125296341Sdelphij case ADDED_DATA: 126296341Sdelphij ret = a->length << 20L; 127296341Sdelphij p = (unsigned char *)a->data; 128296341Sdelphij for (i = 0; i < a->length; i++) 129296341Sdelphij ret ^= p[i] << ((i * 3) % 24); 130296341Sdelphij break; 131296341Sdelphij case ADDED_SNAME: 132296341Sdelphij ret = lh_strhash(a->sn); 133296341Sdelphij break; 134296341Sdelphij case ADDED_LNAME: 135296341Sdelphij ret = lh_strhash(a->ln); 136296341Sdelphij break; 137296341Sdelphij case ADDED_NID: 138296341Sdelphij ret = a->nid; 139296341Sdelphij break; 140296341Sdelphij default: 141296341Sdelphij /* abort(); */ 142296341Sdelphij return 0; 143296341Sdelphij } 144296341Sdelphij ret &= 0x3fffffffL; 145296341Sdelphij ret |= ((unsigned long)ca->type) << 30L; 146296341Sdelphij return (ret); 147296341Sdelphij} 148296341Sdelphij 149238405Sjkimstatic IMPLEMENT_LHASH_HASH_FN(added_obj, ADDED_OBJ) 15055714Skris 151238405Sjkimstatic int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb) 152296341Sdelphij{ 153296341Sdelphij ASN1_OBJECT *a, *b; 154296341Sdelphij int i; 15555714Skris 156296341Sdelphij i = ca->type - cb->type; 157296341Sdelphij if (i) 158296341Sdelphij return (i); 159296341Sdelphij a = ca->obj; 160296341Sdelphij b = cb->obj; 161296341Sdelphij switch (ca->type) { 162296341Sdelphij case ADDED_DATA: 163296341Sdelphij i = (a->length - b->length); 164296341Sdelphij if (i) 165296341Sdelphij return (i); 166296341Sdelphij return (memcmp(a->data, b->data, (size_t)a->length)); 167296341Sdelphij case ADDED_SNAME: 168296341Sdelphij if (a->sn == NULL) 169296341Sdelphij return (-1); 170296341Sdelphij else if (b->sn == NULL) 171296341Sdelphij return (1); 172296341Sdelphij else 173296341Sdelphij return (strcmp(a->sn, b->sn)); 174296341Sdelphij case ADDED_LNAME: 175296341Sdelphij if (a->ln == NULL) 176296341Sdelphij return (-1); 177296341Sdelphij else if (b->ln == NULL) 178296341Sdelphij return (1); 179296341Sdelphij else 180296341Sdelphij return (strcmp(a->ln, b->ln)); 181296341Sdelphij case ADDED_NID: 182296341Sdelphij return (a->nid - b->nid); 183296341Sdelphij default: 184296341Sdelphij /* abort(); */ 185296341Sdelphij return 0; 186296341Sdelphij } 187296341Sdelphij} 188296341Sdelphij 189238405Sjkimstatic IMPLEMENT_LHASH_COMP_FN(added_obj, ADDED_OBJ) 19055714Skris 19155714Skrisstatic int init_added(void) 192296341Sdelphij{ 193296341Sdelphij if (added != NULL) 194296341Sdelphij return (1); 195296341Sdelphij added = lh_ADDED_OBJ_new(); 196296341Sdelphij return (added != NULL); 197296341Sdelphij} 19855714Skris 199238405Sjkimstatic void cleanup1_doall(ADDED_OBJ *a) 200296341Sdelphij{ 201296341Sdelphij a->obj->nid = 0; 202296341Sdelphij a->obj->flags |= ASN1_OBJECT_FLAG_DYNAMIC | 203296341Sdelphij ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA; 204296341Sdelphij} 20555714Skris 206238405Sjkimstatic void cleanup2_doall(ADDED_OBJ *a) 207296341Sdelphij{ 208296341Sdelphij a->obj->nid++; 209296341Sdelphij} 21055714Skris 211238405Sjkimstatic void cleanup3_doall(ADDED_OBJ *a) 212296341Sdelphij{ 213296341Sdelphij if (--a->obj->nid == 0) 214296341Sdelphij ASN1_OBJECT_free(a->obj); 215296341Sdelphij OPENSSL_free(a); 216296341Sdelphij} 21755714Skris 218238405Sjkimstatic IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ) 219238405Sjkimstatic IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ) 220238405Sjkimstatic IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ) 221109998Smarkm 222296341Sdelphij/* 223296341Sdelphij * The purpose of obj_cleanup_defer is to avoid EVP_cleanup() attempting to 224296341Sdelphij * use freed up OIDs. If neccessary the actual freeing up of OIDs is delayed. 225238405Sjkim */ 226238405Sjkimint obj_cleanup_defer = 0; 227238405Sjkim 228238405Sjkimvoid check_defer(int nid) 229296341Sdelphij{ 230296341Sdelphij if (!obj_cleanup_defer && nid >= NUM_NID) 231296341Sdelphij obj_cleanup_defer = 1; 232296341Sdelphij} 233238405Sjkim 23455714Skrisvoid OBJ_cleanup(void) 235296341Sdelphij{ 236296341Sdelphij if (obj_cleanup_defer) { 237296341Sdelphij obj_cleanup_defer = 2; 238296341Sdelphij return; 239296341Sdelphij } 240296341Sdelphij if (added == NULL) 241296341Sdelphij return; 242296341Sdelphij lh_ADDED_OBJ_down_load(added) = 0; 243296341Sdelphij lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup1)); /* zero counters */ 244296341Sdelphij lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup2)); /* set counters */ 245296341Sdelphij lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup3)); /* free objects */ 246296341Sdelphij lh_ADDED_OBJ_free(added); 247296341Sdelphij added = NULL; 248296341Sdelphij} 24955714Skris 25055714Skrisint OBJ_new_nid(int num) 251296341Sdelphij{ 252296341Sdelphij int i; 25355714Skris 254296341Sdelphij i = new_nid; 255296341Sdelphij new_nid += num; 256296341Sdelphij return (i); 257296341Sdelphij} 25855714Skris 259109998Smarkmint OBJ_add_object(const ASN1_OBJECT *obj) 260296341Sdelphij{ 261296341Sdelphij ASN1_OBJECT *o; 262296341Sdelphij ADDED_OBJ *ao[4] = { NULL, NULL, NULL, NULL }, *aop; 263296341Sdelphij int i; 26455714Skris 265296341Sdelphij if (added == NULL) 266296341Sdelphij if (!init_added()) 267296341Sdelphij return (0); 268296341Sdelphij if ((o = OBJ_dup(obj)) == NULL) 269296341Sdelphij goto err; 270296341Sdelphij if (!(ao[ADDED_NID] = (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) 271296341Sdelphij goto err2; 272296341Sdelphij if ((o->length != 0) && (obj->data != NULL)) 273296341Sdelphij if (! 274296341Sdelphij (ao[ADDED_DATA] = (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) 275296341Sdelphij goto err2; 276296341Sdelphij if (o->sn != NULL) 277296341Sdelphij if (! 278296341Sdelphij (ao[ADDED_SNAME] = 279296341Sdelphij (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) 280296341Sdelphij goto err2; 281296341Sdelphij if (o->ln != NULL) 282296341Sdelphij if (! 283296341Sdelphij (ao[ADDED_LNAME] = 284296341Sdelphij (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) 285296341Sdelphij goto err2; 28655714Skris 287296341Sdelphij for (i = ADDED_DATA; i <= ADDED_NID; i++) { 288296341Sdelphij if (ao[i] != NULL) { 289296341Sdelphij ao[i]->type = i; 290296341Sdelphij ao[i]->obj = o; 291296341Sdelphij aop = lh_ADDED_OBJ_insert(added, ao[i]); 292296341Sdelphij /* memory leak, buit should not normally matter */ 293296341Sdelphij if (aop != NULL) 294296341Sdelphij OPENSSL_free(aop); 295296341Sdelphij } 296296341Sdelphij } 297296341Sdelphij o->flags &= 298296341Sdelphij ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | 299296341Sdelphij ASN1_OBJECT_FLAG_DYNAMIC_DATA); 30055714Skris 301296341Sdelphij return (o->nid); 302296341Sdelphij err2: 303296341Sdelphij OBJerr(OBJ_F_OBJ_ADD_OBJECT, ERR_R_MALLOC_FAILURE); 304296341Sdelphij err: 305296341Sdelphij for (i = ADDED_DATA; i <= ADDED_NID; i++) 306296341Sdelphij if (ao[i] != NULL) 307296341Sdelphij OPENSSL_free(ao[i]); 308296341Sdelphij if (o != NULL) 309296341Sdelphij OPENSSL_free(o); 310296341Sdelphij return (NID_undef); 311296341Sdelphij} 31255714Skris 31355714SkrisASN1_OBJECT *OBJ_nid2obj(int n) 314296341Sdelphij{ 315296341Sdelphij ADDED_OBJ ad, *adp; 316296341Sdelphij ASN1_OBJECT ob; 31755714Skris 318296341Sdelphij if ((n >= 0) && (n < NUM_NID)) { 319296341Sdelphij if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { 320296341Sdelphij OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID); 321296341Sdelphij return (NULL); 322296341Sdelphij } 323296341Sdelphij return ((ASN1_OBJECT *)&(nid_objs[n])); 324296341Sdelphij } else if (added == NULL) 325296341Sdelphij return (NULL); 326296341Sdelphij else { 327296341Sdelphij ad.type = ADDED_NID; 328296341Sdelphij ad.obj = &ob; 329296341Sdelphij ob.nid = n; 330296341Sdelphij adp = lh_ADDED_OBJ_retrieve(added, &ad); 331296341Sdelphij if (adp != NULL) 332296341Sdelphij return (adp->obj); 333296341Sdelphij else { 334296341Sdelphij OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID); 335296341Sdelphij return (NULL); 336296341Sdelphij } 337296341Sdelphij } 338296341Sdelphij} 33955714Skris 34055714Skrisconst char *OBJ_nid2sn(int n) 341296341Sdelphij{ 342296341Sdelphij ADDED_OBJ ad, *adp; 343296341Sdelphij ASN1_OBJECT ob; 34455714Skris 345296341Sdelphij if ((n >= 0) && (n < NUM_NID)) { 346296341Sdelphij if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { 347296341Sdelphij OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID); 348296341Sdelphij return (NULL); 349296341Sdelphij } 350296341Sdelphij return (nid_objs[n].sn); 351296341Sdelphij } else if (added == NULL) 352296341Sdelphij return (NULL); 353296341Sdelphij else { 354296341Sdelphij ad.type = ADDED_NID; 355296341Sdelphij ad.obj = &ob; 356296341Sdelphij ob.nid = n; 357296341Sdelphij adp = lh_ADDED_OBJ_retrieve(added, &ad); 358296341Sdelphij if (adp != NULL) 359296341Sdelphij return (adp->obj->sn); 360296341Sdelphij else { 361296341Sdelphij OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID); 362296341Sdelphij return (NULL); 363296341Sdelphij } 364296341Sdelphij } 365296341Sdelphij} 36655714Skris 36755714Skrisconst char *OBJ_nid2ln(int n) 368296341Sdelphij{ 369296341Sdelphij ADDED_OBJ ad, *adp; 370296341Sdelphij ASN1_OBJECT ob; 37155714Skris 372296341Sdelphij if ((n >= 0) && (n < NUM_NID)) { 373296341Sdelphij if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { 374296341Sdelphij OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID); 375296341Sdelphij return (NULL); 376296341Sdelphij } 377296341Sdelphij return (nid_objs[n].ln); 378296341Sdelphij } else if (added == NULL) 379296341Sdelphij return (NULL); 380296341Sdelphij else { 381296341Sdelphij ad.type = ADDED_NID; 382296341Sdelphij ad.obj = &ob; 383296341Sdelphij ob.nid = n; 384296341Sdelphij adp = lh_ADDED_OBJ_retrieve(added, &ad); 385296341Sdelphij if (adp != NULL) 386296341Sdelphij return (adp->obj->ln); 387296341Sdelphij else { 388296341Sdelphij OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID); 389296341Sdelphij return (NULL); 390296341Sdelphij } 391296341Sdelphij } 392296341Sdelphij} 39355714Skris 394296341Sdelphijstatic int obj_cmp(const ASN1_OBJECT *const *ap, const unsigned int *bp) 395296341Sdelphij{ 396296341Sdelphij int j; 397296341Sdelphij const ASN1_OBJECT *a = *ap; 398296341Sdelphij const ASN1_OBJECT *b = &nid_objs[*bp]; 399238405Sjkim 400296341Sdelphij j = (a->length - b->length); 401296341Sdelphij if (j) 402296341Sdelphij return (j); 403296341Sdelphij if (a->length == 0) 404296341Sdelphij return 0; 405296341Sdelphij return (memcmp(a->data, b->data, a->length)); 406296341Sdelphij} 407238405Sjkim 408238405SjkimIMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj); 409238405Sjkim 410109998Smarkmint OBJ_obj2nid(const ASN1_OBJECT *a) 411296341Sdelphij{ 412296341Sdelphij const unsigned int *op; 413296341Sdelphij ADDED_OBJ ad, *adp; 41455714Skris 415296341Sdelphij if (a == NULL) 416296341Sdelphij return (NID_undef); 417296341Sdelphij if (a->nid != 0) 418296341Sdelphij return (a->nid); 41955714Skris 420296341Sdelphij if (a->length == 0) 421296341Sdelphij return NID_undef; 422284295Sdelphij 423296341Sdelphij if (added != NULL) { 424296341Sdelphij ad.type = ADDED_DATA; 425296341Sdelphij ad.obj = (ASN1_OBJECT *)a; /* XXX: ugly but harmless */ 426296341Sdelphij adp = lh_ADDED_OBJ_retrieve(added, &ad); 427296341Sdelphij if (adp != NULL) 428296341Sdelphij return (adp->obj->nid); 429296341Sdelphij } 430296341Sdelphij op = OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ); 431296341Sdelphij if (op == NULL) 432296341Sdelphij return (NID_undef); 433296341Sdelphij return (nid_objs[*op].nid); 434296341Sdelphij} 43555714Skris 436296341Sdelphij/* 437296341Sdelphij * Convert an object name into an ASN1_OBJECT if "noname" is not set then 438296341Sdelphij * search for short and long names first. This will convert the "dotted" form 439296341Sdelphij * into an object: unlike OBJ_txt2nid it can be used with any objects, not 440296341Sdelphij * just registered ones. 44155714Skris */ 44255714Skris 44355714SkrisASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name) 444296341Sdelphij{ 445296341Sdelphij int nid = NID_undef; 446296341Sdelphij ASN1_OBJECT *op = NULL; 447296341Sdelphij unsigned char *buf; 448296341Sdelphij unsigned char *p; 449296341Sdelphij const unsigned char *cp; 450296341Sdelphij int i, j; 45155714Skris 452296341Sdelphij if (!no_name) { 453296341Sdelphij if (((nid = OBJ_sn2nid(s)) != NID_undef) || 454296341Sdelphij ((nid = OBJ_ln2nid(s)) != NID_undef)) 455296341Sdelphij return OBJ_nid2obj(nid); 456296341Sdelphij } 45755714Skris 458296341Sdelphij /* Work out size of content octets */ 459296341Sdelphij i = a2d_ASN1_OBJECT(NULL, 0, s, -1); 460296341Sdelphij if (i <= 0) { 461296341Sdelphij /* Don't clear the error */ 462296341Sdelphij /* 463296341Sdelphij * ERR_clear_error(); 464296341Sdelphij */ 465296341Sdelphij return NULL; 466296341Sdelphij } 467296341Sdelphij /* Work out total size */ 468296341Sdelphij j = ASN1_object_size(0, i, V_ASN1_OBJECT); 46955714Skris 470296341Sdelphij if ((buf = (unsigned char *)OPENSSL_malloc(j)) == NULL) 471296341Sdelphij return NULL; 47255714Skris 473296341Sdelphij p = buf; 474296341Sdelphij /* Write out tag+length */ 475296341Sdelphij ASN1_put_object(&p, 0, i, V_ASN1_OBJECT, V_ASN1_UNIVERSAL); 476296341Sdelphij /* Write out contents */ 477296341Sdelphij a2d_ASN1_OBJECT(p, i, s, -1); 478160814Ssimon 479296341Sdelphij cp = buf; 480296341Sdelphij op = d2i_ASN1_OBJECT(NULL, &cp, j); 481296341Sdelphij OPENSSL_free(buf); 482296341Sdelphij return op; 483296341Sdelphij} 48455714Skris 485109998Smarkmint OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) 48655714Skris{ 487296341Sdelphij int i, n = 0, len, nid, first, use_bn; 488296341Sdelphij BIGNUM *bl; 489296341Sdelphij unsigned long l; 490296341Sdelphij const unsigned char *p; 491296341Sdelphij char tbuf[DECIMAL_SIZE(i) + DECIMAL_SIZE(l) + 2]; 49255714Skris 493296341Sdelphij /* Ensure that, at every state, |buf| is NUL-terminated. */ 494296341Sdelphij if (buf && buf_len > 0) 495296341Sdelphij buf[0] = '\0'; 496269686Sjkim 497296341Sdelphij if ((a == NULL) || (a->data == NULL)) 498296341Sdelphij return (0); 49955714Skris 500296341Sdelphij if (!no_name && (nid = OBJ_obj2nid(a)) != NID_undef) { 501296341Sdelphij const char *s; 502296341Sdelphij s = OBJ_nid2ln(nid); 503296341Sdelphij if (s == NULL) 504296341Sdelphij s = OBJ_nid2sn(nid); 505296341Sdelphij if (s) { 506296341Sdelphij if (buf) 507296341Sdelphij BUF_strlcpy(buf, s, buf_len); 508296341Sdelphij n = strlen(s); 509296341Sdelphij return n; 510296341Sdelphij } 511296341Sdelphij } 51255714Skris 513296341Sdelphij len = a->length; 514296341Sdelphij p = a->data; 51555714Skris 516296341Sdelphij first = 1; 517296341Sdelphij bl = NULL; 518160814Ssimon 519296341Sdelphij while (len > 0) { 520296341Sdelphij l = 0; 521296341Sdelphij use_bn = 0; 522296341Sdelphij for (;;) { 523296341Sdelphij unsigned char c = *p++; 524296341Sdelphij len--; 525296341Sdelphij if ((len == 0) && (c & 0x80)) 526296341Sdelphij goto err; 527296341Sdelphij if (use_bn) { 528296341Sdelphij if (!BN_add_word(bl, c & 0x7f)) 529296341Sdelphij goto err; 530296341Sdelphij } else 531296341Sdelphij l |= c & 0x7f; 532296341Sdelphij if (!(c & 0x80)) 533296341Sdelphij break; 534296341Sdelphij if (!use_bn && (l > (ULONG_MAX >> 7L))) { 535296341Sdelphij if (!bl && !(bl = BN_new())) 536296341Sdelphij goto err; 537296341Sdelphij if (!BN_set_word(bl, l)) 538296341Sdelphij goto err; 539296341Sdelphij use_bn = 1; 540296341Sdelphij } 541296341Sdelphij if (use_bn) { 542296341Sdelphij if (!BN_lshift(bl, bl, 7)) 543296341Sdelphij goto err; 544296341Sdelphij } else 545296341Sdelphij l <<= 7L; 546296341Sdelphij } 547160814Ssimon 548296341Sdelphij if (first) { 549296341Sdelphij first = 0; 550296341Sdelphij if (l >= 80) { 551296341Sdelphij i = 2; 552296341Sdelphij if (use_bn) { 553296341Sdelphij if (!BN_sub_word(bl, 80)) 554296341Sdelphij goto err; 555296341Sdelphij } else 556296341Sdelphij l -= 80; 557296341Sdelphij } else { 558296341Sdelphij i = (int)(l / 40); 559296341Sdelphij l -= (long)(i * 40); 560296341Sdelphij } 561296341Sdelphij if (buf && (buf_len > 1)) { 562296341Sdelphij *buf++ = i + '0'; 563296341Sdelphij *buf = '\0'; 564296341Sdelphij buf_len--; 565296341Sdelphij } 566296341Sdelphij n++; 567296341Sdelphij } 568160814Ssimon 569296341Sdelphij if (use_bn) { 570296341Sdelphij char *bndec; 571296341Sdelphij bndec = BN_bn2dec(bl); 572296341Sdelphij if (!bndec) 573296341Sdelphij goto err; 574296341Sdelphij i = strlen(bndec); 575296341Sdelphij if (buf) { 576296341Sdelphij if (buf_len > 1) { 577296341Sdelphij *buf++ = '.'; 578296341Sdelphij *buf = '\0'; 579296341Sdelphij buf_len--; 580296341Sdelphij } 581296341Sdelphij BUF_strlcpy(buf, bndec, buf_len); 582296341Sdelphij if (i > buf_len) { 583296341Sdelphij buf += buf_len; 584296341Sdelphij buf_len = 0; 585296341Sdelphij } else { 586296341Sdelphij buf += i; 587296341Sdelphij buf_len -= i; 588296341Sdelphij } 589296341Sdelphij } 590296341Sdelphij n++; 591296341Sdelphij n += i; 592296341Sdelphij OPENSSL_free(bndec); 593296341Sdelphij } else { 594296341Sdelphij BIO_snprintf(tbuf, sizeof tbuf, ".%lu", l); 595296341Sdelphij i = strlen(tbuf); 596296341Sdelphij if (buf && (buf_len > 0)) { 597296341Sdelphij BUF_strlcpy(buf, tbuf, buf_len); 598296341Sdelphij if (i > buf_len) { 599296341Sdelphij buf += buf_len; 600296341Sdelphij buf_len = 0; 601296341Sdelphij } else { 602296341Sdelphij buf += i; 603296341Sdelphij buf_len -= i; 604296341Sdelphij } 605296341Sdelphij } 606296341Sdelphij n += i; 607296341Sdelphij l = 0; 608296341Sdelphij } 609296341Sdelphij } 610160814Ssimon 611296341Sdelphij if (bl) 612296341Sdelphij BN_free(bl); 613296341Sdelphij return n; 614160814Ssimon 615296341Sdelphij err: 616296341Sdelphij if (bl) 617296341Sdelphij BN_free(bl); 618296341Sdelphij return -1; 61955714Skris} 62055714Skris 621109998Smarkmint OBJ_txt2nid(const char *s) 62255714Skris{ 623296341Sdelphij ASN1_OBJECT *obj; 624296341Sdelphij int nid; 625296341Sdelphij obj = OBJ_txt2obj(s, 0); 626296341Sdelphij nid = OBJ_obj2nid(obj); 627296341Sdelphij ASN1_OBJECT_free(obj); 628296341Sdelphij return nid; 62955714Skris} 63055714Skris 63155714Skrisint OBJ_ln2nid(const char *s) 632296341Sdelphij{ 633296341Sdelphij ASN1_OBJECT o; 634296341Sdelphij const ASN1_OBJECT *oo = &o; 635296341Sdelphij ADDED_OBJ ad, *adp; 636296341Sdelphij const unsigned int *op; 63755714Skris 638296341Sdelphij o.ln = s; 639296341Sdelphij if (added != NULL) { 640296341Sdelphij ad.type = ADDED_LNAME; 641296341Sdelphij ad.obj = &o; 642296341Sdelphij adp = lh_ADDED_OBJ_retrieve(added, &ad); 643296341Sdelphij if (adp != NULL) 644296341Sdelphij return (adp->obj->nid); 645296341Sdelphij } 646296341Sdelphij op = OBJ_bsearch_ln(&oo, ln_objs, NUM_LN); 647296341Sdelphij if (op == NULL) 648296341Sdelphij return (NID_undef); 649296341Sdelphij return (nid_objs[*op].nid); 650296341Sdelphij} 65155714Skris 65255714Skrisint OBJ_sn2nid(const char *s) 653296341Sdelphij{ 654296341Sdelphij ASN1_OBJECT o; 655296341Sdelphij const ASN1_OBJECT *oo = &o; 656296341Sdelphij ADDED_OBJ ad, *adp; 657296341Sdelphij const unsigned int *op; 65855714Skris 659296341Sdelphij o.sn = s; 660296341Sdelphij if (added != NULL) { 661296341Sdelphij ad.type = ADDED_SNAME; 662296341Sdelphij ad.obj = &o; 663296341Sdelphij adp = lh_ADDED_OBJ_retrieve(added, &ad); 664296341Sdelphij if (adp != NULL) 665296341Sdelphij return (adp->obj->nid); 666296341Sdelphij } 667296341Sdelphij op = OBJ_bsearch_sn(&oo, sn_objs, NUM_SN); 668296341Sdelphij if (op == NULL) 669296341Sdelphij return (NID_undef); 670296341Sdelphij return (nid_objs[*op].nid); 671296341Sdelphij} 67255714Skris 673238405Sjkimconst void *OBJ_bsearch_(const void *key, const void *base, int num, int size, 674296341Sdelphij int (*cmp) (const void *, const void *)) 675296341Sdelphij{ 676296341Sdelphij return OBJ_bsearch_ex_(key, base, num, size, cmp, 0); 677296341Sdelphij} 67855714Skris 679238405Sjkimconst void *OBJ_bsearch_ex_(const void *key, const void *base_, int num, 680296341Sdelphij int size, 681296341Sdelphij int (*cmp) (const void *, const void *), 682296341Sdelphij int flags) 683296341Sdelphij{ 684296341Sdelphij const char *base = base_; 685296341Sdelphij int l, h, i = 0, c = 0; 686296341Sdelphij const char *p = NULL; 687160814Ssimon 688296341Sdelphij if (num == 0) 689296341Sdelphij return (NULL); 690296341Sdelphij l = 0; 691296341Sdelphij h = num; 692296341Sdelphij while (l < h) { 693296341Sdelphij i = (l + h) / 2; 694296341Sdelphij p = &(base[i * size]); 695296341Sdelphij c = (*cmp) (key, p); 696296341Sdelphij if (c < 0) 697296341Sdelphij h = i; 698296341Sdelphij else if (c > 0) 699296341Sdelphij l = i + 1; 700296341Sdelphij else 701296341Sdelphij break; 702296341Sdelphij } 70355714Skris#ifdef CHARSET_EBCDIC 704296341Sdelphij /* 705296341Sdelphij * THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and I 706296341Sdelphij * don't have perl (yet), we revert to a *LINEAR* search when the object 707296341Sdelphij * wasn't found in the binary search. 708296341Sdelphij */ 709296341Sdelphij if (c != 0) { 710296341Sdelphij for (i = 0; i < num; ++i) { 711296341Sdelphij p = &(base[i * size]); 712296341Sdelphij c = (*cmp) (key, p); 713296341Sdelphij if (c == 0 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))) 714296341Sdelphij return p; 715296341Sdelphij } 716296341Sdelphij } 71755714Skris#endif 718296341Sdelphij if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)) 719296341Sdelphij p = NULL; 720296341Sdelphij else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH)) { 721296341Sdelphij while (i > 0 && (*cmp) (key, &(base[(i - 1) * size])) == 0) 722296341Sdelphij i--; 723296341Sdelphij p = &(base[i * size]); 724296341Sdelphij } 725296341Sdelphij return (p); 726296341Sdelphij} 72755714Skris 72855714Skrisint OBJ_create_objects(BIO *in) 729296341Sdelphij{ 730296341Sdelphij MS_STATIC char buf[512]; 731296341Sdelphij int i, num = 0; 732296341Sdelphij char *o, *s, *l = NULL; 73355714Skris 734296341Sdelphij for (;;) { 735296341Sdelphij s = o = NULL; 736296341Sdelphij i = BIO_gets(in, buf, 512); 737296341Sdelphij if (i <= 0) 738296341Sdelphij return (num); 739296341Sdelphij buf[i - 1] = '\0'; 740296341Sdelphij if (!isalnum((unsigned char)buf[0])) 741296341Sdelphij return (num); 742296341Sdelphij o = s = buf; 743296341Sdelphij while (isdigit((unsigned char)*s) || (*s == '.')) 744296341Sdelphij s++; 745296341Sdelphij if (*s != '\0') { 746296341Sdelphij *(s++) = '\0'; 747296341Sdelphij while (isspace((unsigned char)*s)) 748296341Sdelphij s++; 749296341Sdelphij if (*s == '\0') 750296341Sdelphij s = NULL; 751296341Sdelphij else { 752296341Sdelphij l = s; 753296341Sdelphij while ((*l != '\0') && !isspace((unsigned char)*l)) 754296341Sdelphij l++; 755296341Sdelphij if (*l != '\0') { 756296341Sdelphij *(l++) = '\0'; 757296341Sdelphij while (isspace((unsigned char)*l)) 758296341Sdelphij l++; 759296341Sdelphij if (*l == '\0') 760296341Sdelphij l = NULL; 761296341Sdelphij } else 762296341Sdelphij l = NULL; 763296341Sdelphij } 764296341Sdelphij } else 765296341Sdelphij s = NULL; 766296341Sdelphij if ((o == NULL) || (*o == '\0')) 767296341Sdelphij return (num); 768296341Sdelphij if (!OBJ_create(o, s, l)) 769296341Sdelphij return (num); 770296341Sdelphij num++; 771296341Sdelphij } 772296341Sdelphij /* return(num); */ 773296341Sdelphij} 77455714Skris 775109998Smarkmint OBJ_create(const char *oid, const char *sn, const char *ln) 776296341Sdelphij{ 777296341Sdelphij int ok = 0; 778296341Sdelphij ASN1_OBJECT *op = NULL; 779296341Sdelphij unsigned char *buf; 780296341Sdelphij int i; 78155714Skris 782296341Sdelphij i = a2d_ASN1_OBJECT(NULL, 0, oid, -1); 783296341Sdelphij if (i <= 0) 784296341Sdelphij return (0); 78555714Skris 786296341Sdelphij if ((buf = (unsigned char *)OPENSSL_malloc(i)) == NULL) { 787296341Sdelphij OBJerr(OBJ_F_OBJ_CREATE, ERR_R_MALLOC_FAILURE); 788296341Sdelphij return (0); 789296341Sdelphij } 790296341Sdelphij i = a2d_ASN1_OBJECT(buf, i, oid, -1); 791296341Sdelphij if (i == 0) 792296341Sdelphij goto err; 793296341Sdelphij op = (ASN1_OBJECT *)ASN1_OBJECT_create(OBJ_new_nid(1), buf, i, sn, ln); 794296341Sdelphij if (op == NULL) 795296341Sdelphij goto err; 796296341Sdelphij ok = OBJ_add_object(op); 797296341Sdelphij err: 798296341Sdelphij ASN1_OBJECT_free(op); 799296341Sdelphij OPENSSL_free(buf); 800296341Sdelphij return (ok); 801296341Sdelphij} 802