X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fobjects%2Fobj_dat.c;h=0de0fba6b7be1a79f0bc36a44012b05c52747769;hp=dbff4e075f0ea6e72759d700e627c58199a2c8e2;hb=531308d9299b2a48bfbed64a5e3aa35ce24bef0a;hpb=875a644a9047e96dfcce27af876d30460759805e diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c index dbff4e075f..0de0fba6b7 100644 --- a/crypto/objects/obj_dat.c +++ b/crypto/objects/obj_dat.c @@ -58,6 +58,7 @@ #include #include +#include #include "cryptlib.h" #include #include @@ -115,7 +116,7 @@ static unsigned long add_hash(const void *ca_void) int i; unsigned long ret=0; unsigned char *p; - ADDED_OBJ *ca = (ADDED_OBJ *)ca_void; + const ADDED_OBJ *ca = (const ADDED_OBJ *)ca_void; a=ca->obj; switch (ca->type) @@ -149,8 +150,8 @@ static int add_cmp(const void *ca_void, const void *cb_void) { ASN1_OBJECT *a,*b; int i; - ADDED_OBJ *ca = (ADDED_OBJ *)ca_void; - ADDED_OBJ *cb = (ADDED_OBJ *)cb_void; + const ADDED_OBJ *ca = (const ADDED_OBJ *)ca_void; + const ADDED_OBJ *cb = (const ADDED_OBJ *)cb_void; i=ca->type-cb->type; if (i) return(i); @@ -161,7 +162,7 @@ static int add_cmp(const void *ca_void, const void *cb_void) case ADDED_DATA: i=(a->length - b->length); if (i) return(i); - return(memcmp(a->data,b->data,a->length)); + return(memcmp(a->data,b->data,(size_t)a->length)); case ADDED_SNAME: if (a->sn == NULL) return(-1); else if (b->sn == NULL) return(1); @@ -207,8 +208,26 @@ static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ *) static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ *) static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ *) +/* The purpose of obj_cleanup_defer is to avoid EVP_cleanup() attempting + * to use freed up OIDs. If neccessary the actual freeing up of OIDs is + * delayed. + */ + +int obj_cleanup_defer = 0; + +void check_defer(int nid) + { + if (!obj_cleanup_defer && nid >= NUM_NID) + obj_cleanup_defer = 1; + } + void OBJ_cleanup(void) { + if (obj_cleanup_defer) + { + obj_cleanup_defer = 2; + return ; + } if (added == NULL) return; added->down_load=0; lh_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */ @@ -236,13 +255,13 @@ int OBJ_add_object(const ASN1_OBJECT *obj) if (added == NULL) if (!init_added()) return(0); if ((o=OBJ_dup(obj)) == NULL) goto err; - if (!(ao[ADDED_NID]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err; + if (!(ao[ADDED_NID]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err2; if ((o->length != 0) && (obj->data != NULL)) - ao[ADDED_DATA]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)); + if (!(ao[ADDED_DATA]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err2; if (o->sn != NULL) - ao[ADDED_SNAME]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)); + if (!(ao[ADDED_SNAME]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err2; if (o->ln != NULL) - ao[ADDED_LNAME]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)); + if (!(ao[ADDED_LNAME]=(ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) goto err2; for (i=ADDED_DATA; i<=ADDED_NID; i++) { @@ -260,6 +279,8 @@ int OBJ_add_object(const ASN1_OBJECT *obj) ASN1_OBJECT_FLAG_DYNAMIC_DATA); return(o->nid); +err2: + OBJerr(OBJ_F_OBJ_ADD_OBJECT,ERR_R_MALLOC_FAILURE); err: for (i=ADDED_DATA; i<=ADDED_NID; i++) if (ao[i] != NULL) OPENSSL_free(ao[i]); @@ -380,8 +401,8 @@ int OBJ_obj2nid(const ASN1_OBJECT *a) adp=(ADDED_OBJ *)lh_retrieve(added,&ad); if (adp != NULL) return (adp->obj->nid); } - op=(ASN1_OBJECT **)OBJ_bsearch((char *)&a,(char *)obj_objs,NUM_OBJ, - sizeof(ASN1_OBJECT *),obj_cmp); + 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); @@ -411,8 +432,8 @@ ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name) /* Work out size of content octets */ i=a2d_ASN1_OBJECT(NULL,0,s,-1); if (i <= 0) { - /* Clear the error */ - ERR_get_error(); + /* Don't clear the error */ + /*ERR_clear_error();*/ return NULL; } /* Work out total size */ @@ -434,66 +455,161 @@ ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name) int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) { - int i,idx=0,n=0,len,nid; + int i,n=0,len,nid, first, use_bn; + BIGNUM *bl; unsigned long l; unsigned char *p; - const char *s; char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2]; - if (buf_len <= 0) return(0); - if ((a == NULL) || (a->data == NULL)) { buf[0]='\0'; return(0); } - if (no_name || (nid=OBJ_obj2nid(a)) == NID_undef) { - len=a->length; - p=a->data; - idx=0; - l=0; - while (idx < a->length) { - l|=(p[idx]&0x7f); - if (!(p[idx] & 0x80)) break; - l<<=7L; - idx++; + if (!no_name && (nid=OBJ_obj2nid(a)) != NID_undef) + { + const char *s; + s=OBJ_nid2ln(nid); + if (s == NULL) + s=OBJ_nid2sn(nid); + if (buf) + BUF_strlcpy(buf,s,buf_len); + n=strlen(s); + return n; } - idx++; - i=(int)(l/40); - if (i > 2) i=2; - l-=(long)(i*40); - - BIO_snprintf(tbuf,sizeof tbuf,"%d.%lu",i,l); - i=strlen(tbuf); - BUF_strlcpy(buf,tbuf,buf_len); - buf_len-=i; - buf+=i; - n+=i; + + len=a->length; + p=a->data; + + first = 1; + bl = NULL; + + while (len > 0) + { l=0; - for (; idx (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_strlcpy(buf,tbuf,buf_len); - buf_len-=i; - buf+=i; - n+=i; - l=0; + { + *buf++ = '.'; + buf_len--; + } + BUF_strlcpy(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)) + { + BUF_strlcpy(buf,tbuf,buf_len); + if (i > buf_len) + { + buf += buf_len; + buf_len = 0; + } + else + { + buf+=i; + buf_len-=i; + } + } + n+=i; + l=0; } - l<<=7L; } - } else { - s=OBJ_nid2ln(nid); - if (s == NULL) - s=OBJ_nid2sn(nid); - BUF_strlcpy(buf,s,buf_len); - n=strlen(s); - } - return(n); + + if (bl) + BN_free(bl); + return n; + + err: + if (bl) + BN_free(bl); + return -1; } int OBJ_txt2nid(const char *s) @@ -519,7 +635,7 @@ int OBJ_ln2nid(const char *s) adp=(ADDED_OBJ *)lh_retrieve(added,&ad); if (adp != NULL) return (adp->obj->nid); } - op=(ASN1_OBJECT **)OBJ_bsearch((char *)&oo,(char *)ln_objs,NUM_LN, + op=(ASN1_OBJECT **)OBJ_bsearch((char *)&oo,(char *)ln_objs, NUM_LN, sizeof(ASN1_OBJECT *),ln_cmp); if (op == NULL) return(NID_undef); return((*op)->nid); @@ -547,8 +663,8 @@ int OBJ_sn2nid(const char *s) static int obj_cmp(const void *ap, const void *bp) { int j; - ASN1_OBJECT *a= *(ASN1_OBJECT **)ap; - ASN1_OBJECT *b= *(ASN1_OBJECT **)bp; + 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); @@ -669,7 +785,7 @@ int OBJ_create(const char *oid, const char *sn, const char *ln) if ((buf=(unsigned char *)OPENSSL_malloc(i)) == NULL) { - OBJerr(OBJ_F_OBJ_CREATE,OBJ_R_MALLOC_FAILURE); + OBJerr(OBJ_F_OBJ_CREATE,ERR_R_MALLOC_FAILURE); return(0); } i=a2d_ASN1_OBJECT(buf,i,oid,-1);