371 lines
7.0 KiB
C
371 lines
7.0 KiB
C
#include "asn1.h"
|
|
#include "obj_dat.h"
|
|
#include "lhash.h"
|
|
#include "objects.h"
|
|
#include "err.h"
|
|
#include "cryptlib.h"
|
|
#include "limits.h"
|
|
|
|
#define ADDED_NID 3
|
|
#define ADDED_DATA 0
|
|
|
|
//#define OBJerr(f,r) ERR_PUT_error(ERR_LIB_OBJ,(f),(r),__FILE__,__LINE__)
|
|
|
|
typedef struct added_obj_st {
|
|
int type;
|
|
ASN1_OBJECT *obj;
|
|
} ADDED_OBJ;
|
|
|
|
static LHASH *added = NULL;
|
|
|
|
void reset_OBJ_nid2ln_reset(void)
|
|
{
|
|
added = NULL;
|
|
}
|
|
/////////////OBJ_nid2ln/////////////////////////ok
|
|
|
|
const char *OBJ_nid2ln(int n)
|
|
{
|
|
ADDED_OBJ ad, *adp;
|
|
ASN1_OBJECT ob;
|
|
|
|
if ((n >= 0) && (n < NUM_NID)) {
|
|
if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
|
|
return (NULL);
|
|
}
|
|
return (nid_objs[n].ln);
|
|
} else if (added == NULL)
|
|
return (NULL);
|
|
else {
|
|
ad.type = ADDED_NID;
|
|
ad.obj = &ob;
|
|
ob.nid = n;
|
|
adp = (ADDED_OBJ *)lh_retrieve(added, &ad);
|
|
if (adp != NULL)
|
|
return (adp->obj->ln);
|
|
else {
|
|
return (NULL);
|
|
}
|
|
}
|
|
}
|
|
///////////////OBJ_bsearch/////////////////ok
|
|
|
|
const char *OBJ_bsearch(const char *key, const char *base, int num, int size,
|
|
int (*cmp)(const void *, const void *))
|
|
{
|
|
return OBJ_bsearch_ex(key, base, num, size, cmp, 0);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////ok
|
|
|
|
const char *OBJ_bsearch_ex(const char *key, const char *base, int num, int size,
|
|
int (*cmp)(const void *, const void *), int flags)
|
|
{
|
|
int l, h, i = 0, c = 0;
|
|
const char *p = NULL;
|
|
|
|
if (num == 0)
|
|
return (NULL);
|
|
l = 0;
|
|
h = num;
|
|
while (l < h) {
|
|
i = (l + h) / 2;
|
|
p = &(base[i * size]);
|
|
c = (*cmp)(key, p);
|
|
if (c < 0)
|
|
h = i;
|
|
else if (c > 0)
|
|
l = i + 1;
|
|
else
|
|
break;
|
|
}
|
|
//#ifdef CHARSET_EBCDIC //###samyang modity
|
|
/* THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and
|
|
* I don't have perl (yet), we revert to a *LINEAR* search
|
|
* when the object wasn't found in the binary search.
|
|
*/
|
|
if (c != 0) {
|
|
for (i = 0; i < num; ++i) {
|
|
p = &(base[i * size]);
|
|
c = (*cmp)(key, p);
|
|
if (c == 0 ||
|
|
(c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
|
|
return p;
|
|
}
|
|
}
|
|
//#endif ////###samyang modity
|
|
if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))
|
|
p = NULL; //&(base[78*size]);
|
|
else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH)) {
|
|
while (i > 0 && (*cmp)(key, &(base[(i - 1) * size])) == 0)
|
|
i--;
|
|
p = &(base[i * size]);
|
|
}
|
|
return (p);
|
|
}
|
|
|
|
//////////////////obj_cmp//////////////////ok
|
|
|
|
static int obj_cmp(const void *ap, const void *bp)
|
|
{
|
|
int j;
|
|
const ASN1_OBJECT *a = *(ASN1_OBJECT * const *)ap;
|
|
const ASN1_OBJECT *b = *(ASN1_OBJECT * const *)bp;
|
|
|
|
j = (a->length - b->length);
|
|
if (j)
|
|
return (j);
|
|
return (memcmp(a->data, b->data, a->length));
|
|
}
|
|
///////////////////OBJ_obj2nid//////////////////////ok
|
|
|
|
int OBJ_obj2nid(const ASN1_OBJECT *a)
|
|
{
|
|
ASN1_OBJECT **op;
|
|
ADDED_OBJ ad, *adp;
|
|
|
|
if (a == NULL)
|
|
return (NID_undef);
|
|
if (a->nid != 0)
|
|
return (a->nid);
|
|
|
|
if (added != NULL) {
|
|
ad.type = ADDED_DATA;
|
|
ad.obj = (ASN1_OBJECT *)a; /* XXX: ugly but harmless */
|
|
adp = (ADDED_OBJ *)lh_retrieve(added, &ad);
|
|
if (adp != NULL)
|
|
return (adp->obj->nid);
|
|
}
|
|
op = (ASN1_OBJECT **)OBJ_bsearch((const char *)&a,
|
|
(const char *)obj_objs, NUM_OBJ,
|
|
sizeof(ASN1_OBJECT *), obj_cmp);
|
|
if (op == NULL)
|
|
return (NID_undef);
|
|
return ((*op)->nid);
|
|
}
|
|
|
|
///////////////OBJ_nid2obj////////////////////////////////ok
|
|
|
|
ASN1_OBJECT *OBJ_nid2obj(int n)
|
|
{
|
|
ADDED_OBJ ad, *adp;
|
|
ASN1_OBJECT ob;
|
|
|
|
if ((n >= 0) && (n < NUM_NID)) {
|
|
if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
|
|
return (NULL);
|
|
}
|
|
return ((ASN1_OBJECT *)&(nid_objs[n]));
|
|
} else if (added == NULL)
|
|
return (NULL);
|
|
else {
|
|
ad.type = ADDED_NID;
|
|
ad.obj = &ob;
|
|
ob.nid = n;
|
|
adp = (ADDED_OBJ *)lh_retrieve(added, &ad);
|
|
if (adp != NULL)
|
|
return (adp->obj);
|
|
else {
|
|
return (NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
const char *OBJ_nid2sn(int n)
|
|
{
|
|
ADDED_OBJ ad, *adp;
|
|
ASN1_OBJECT ob;
|
|
|
|
if ((n >= 0) && (n < NUM_NID)) {
|
|
if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
|
|
OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID);
|
|
return (NULL);
|
|
}
|
|
return (nid_objs[n].sn);
|
|
} else if (added == NULL)
|
|
return (NULL);
|
|
else {
|
|
ad.type = ADDED_NID;
|
|
ad.obj = &ob;
|
|
ob.nid = n;
|
|
adp = lh_retrieve(added, &ad);
|
|
if (adp != NULL)
|
|
return (adp->obj->sn);
|
|
else {
|
|
return (NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
|
|
{
|
|
// int i,n=0,len,nid, first, use_bn;
|
|
// BIGNUM *bl;
|
|
// unsigned long l;
|
|
// const unsigned char *p;
|
|
// char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2];
|
|
//
|
|
// if ((a == NULL) || (a->data == NULL)) {
|
|
// buf[0]='\0';
|
|
// return(0);
|
|
// }
|
|
//
|
|
// if (!no_name && (nid=OBJ_obj2nid(a)) != NID_undef)
|
|
// {
|
|
// const char *s;
|
|
// s=OBJ_nid2ln(nid);
|
|
// if (s == NULL)
|
|
// s=OBJ_nid2sn(nid);
|
|
// if (s)
|
|
// {
|
|
// if (buf)
|
|
// strncpy(buf,s,buf_len);
|
|
// n=strlen(s);
|
|
// return n;
|
|
// }
|
|
// }
|
|
//
|
|
// len=a->length;
|
|
// p=a->data;
|
|
//
|
|
// first = 1;
|
|
// bl = NULL;
|
|
//
|
|
// while (len > 0)
|
|
// {
|
|
// l=0;
|
|
// use_bn = 0;
|
|
// for (;;)
|
|
// {
|
|
// unsigned char c = *p++;
|
|
// len--;
|
|
// if ((len == 0) && (c & 0x80))
|
|
// goto err;
|
|
// if (use_bn)
|
|
// {
|
|
// if (!BN_add_word(bl, c & 0x7f))
|
|
// goto err;
|
|
// }
|
|
// else
|
|
// l |= c & 0x7f;
|
|
// if (!(c & 0x80))
|
|
// break;
|
|
// if (!use_bn && (l > (ULONG_MAX >> 7L)))
|
|
// {
|
|
// if (!bl && !(bl = BN_new()))
|
|
// goto err;
|
|
// if (!BN_set_word(bl, l))
|
|
// goto err;
|
|
// use_bn = 1;
|
|
// }
|
|
// if (use_bn)
|
|
// {
|
|
// if (!BN_lshift(bl, bl, 7))
|
|
// goto err;
|
|
// }
|
|
// else
|
|
// l<<=7L;
|
|
// }
|
|
//
|
|
// if (first)
|
|
// {
|
|
// first = 0;
|
|
// if (l >= 80)
|
|
// {
|
|
// i = 2;
|
|
// if (use_bn)
|
|
// {
|
|
// if (!BN_sub_word(bl, 80))
|
|
// goto err;
|
|
// }
|
|
// else
|
|
// l -= 80;
|
|
// }
|
|
// else
|
|
// {
|
|
// i=(int)(l/40);
|
|
// l-=(long)(i*40);
|
|
// }
|
|
// if (buf && (buf_len > 0))
|
|
// {
|
|
// *buf++ = i + '0';
|
|
// buf_len--;
|
|
// }
|
|
// n++;
|
|
// }
|
|
//
|
|
// if (use_bn)
|
|
// {
|
|
// char *bndec;
|
|
// bndec = BN_bn2dec(bl);
|
|
// if (!bndec)
|
|
// goto err;
|
|
// i = strlen(bndec);
|
|
// if (buf)
|
|
// {
|
|
// if (buf_len > 0)
|
|
// {
|
|
// *buf++ = '.';
|
|
// buf_len--;
|
|
// }
|
|
// strncpy(buf,bndec,buf_len);
|
|
// if (i > buf_len)
|
|
// {
|
|
// buf += buf_len;
|
|
// buf_len = 0;
|
|
// }
|
|
// else
|
|
// {
|
|
// buf+=i;
|
|
// buf_len-=i;
|
|
// }
|
|
// }
|
|
// n++;
|
|
// n += i;
|
|
// OPENSSL_free(bndec);
|
|
// }
|
|
// else
|
|
// {
|
|
// BIO_snprintf(tbuf,sizeof tbuf,".%lu",l);
|
|
// i=strlen(tbuf);
|
|
// if (buf && (buf_len > 0))
|
|
// {
|
|
// strncpy(buf,tbuf,buf_len);
|
|
// if (i > buf_len)
|
|
// {
|
|
// buf += buf_len;
|
|
// buf_len = 0;
|
|
// }
|
|
// else
|
|
// {
|
|
// buf+=i;
|
|
// buf_len-=i;
|
|
// }
|
|
// }
|
|
// n+=i;
|
|
// l=0;
|
|
// }
|
|
// }
|
|
//
|
|
// if (bl)
|
|
// BN_free(bl);
|
|
// return n;
|
|
//
|
|
// err:
|
|
// if (bl)
|
|
// BN_free(bl);
|
|
return -1;
|
|
}
|
|
|
|
int OBJ_obj2name(char *dst_buf, int buf_len, const ASN1_OBJECT *a)
|
|
{
|
|
if (buf_len < a->length) {
|
|
printf("OBJ_obj2name err: not enough buffer to store name\n");
|
|
|
|
return -1;
|
|
}
|
|
memcpy(dst_buf, a->data, a->length);
|
|
|
|
return a->length;
|
|
}
|