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