Home | History | Annotate | Download | only in obj
      1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      2  * All rights reserved.
      3  *
      4  * This package is an SSL implementation written
      5  * by Eric Young (eay (at) cryptsoft.com).
      6  * The implementation was written so as to conform with Netscapes SSL.
      7  *
      8  * This library is free for commercial and non-commercial use as long as
      9  * the following conditions are aheared to.  The following conditions
     10  * apply to all code found in this distribution, be it the RC4, RSA,
     11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
     12  * included with this distribution is covered by the same copyright terms
     13  * except that the holder is Tim Hudson (tjh (at) cryptsoft.com).
     14  *
     15  * Copyright remains Eric Young's, and as such any Copyright notices in
     16  * the code are not to be removed.
     17  * If this package is used in a product, Eric Young should be given attribution
     18  * as the author of the parts of the library used.
     19  * This can be in the form of a textual message at program startup or
     20  * in documentation (online or textual) provided with the package.
     21  *
     22  * Redistribution and use in source and binary forms, with or without
     23  * modification, are permitted provided that the following conditions
     24  * are met:
     25  * 1. Redistributions of source code must retain the copyright
     26  *    notice, this list of conditions and the following disclaimer.
     27  * 2. Redistributions in binary form must reproduce the above copyright
     28  *    notice, this list of conditions and the following disclaimer in the
     29  *    documentation and/or other materials provided with the distribution.
     30  * 3. All advertising materials mentioning features or use of this software
     31  *    must display the following acknowledgement:
     32  *    "This product includes cryptographic software written by
     33  *     Eric Young (eay (at) cryptsoft.com)"
     34  *    The word 'cryptographic' can be left out if the rouines from the library
     35  *    being used are not cryptographic related :-).
     36  * 4. If you include any Windows specific code (or a derivative thereof) from
     37  *    the apps directory (application code) you must include an acknowledgement:
     38  *    "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)"
     39  *
     40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
     41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     50  * SUCH DAMAGE.
     51  *
     52  * The licence and distribution terms for any publically available version or
     53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
     54  * copied and put under another distribution licence
     55  * [including the GNU Public Licence.] */
     56 
     57 #include <openssl/obj.h>
     58 
     59 #include <limits.h>
     60 #include <string.h>
     61 
     62 #include <openssl/asn1.h>
     63 #include <openssl/buf.h>
     64 #include <openssl/bytestring.h>
     65 #include <openssl/err.h>
     66 #include <openssl/lhash.h>
     67 #include <openssl/mem.h>
     68 #include <openssl/thread.h>
     69 
     70 #include "obj_dat.h"
     71 #include "../internal.h"
     72 
     73 
     74 static struct CRYPTO_STATIC_MUTEX global_added_lock = CRYPTO_STATIC_MUTEX_INIT;
     75 /* These globals are protected by |global_added_lock|. */
     76 static LHASH_OF(ASN1_OBJECT) *global_added_by_data = NULL;
     77 static LHASH_OF(ASN1_OBJECT) *global_added_by_nid = NULL;
     78 static LHASH_OF(ASN1_OBJECT) *global_added_by_short_name = NULL;
     79 static LHASH_OF(ASN1_OBJECT) *global_added_by_long_name = NULL;
     80 
     81 static struct CRYPTO_STATIC_MUTEX global_next_nid_lock =
     82     CRYPTO_STATIC_MUTEX_INIT;
     83 static unsigned global_next_nid = NUM_NID;
     84 
     85 static int obj_next_nid(void) {
     86   int ret;
     87 
     88   CRYPTO_STATIC_MUTEX_lock_write(&global_next_nid_lock);
     89   ret = global_next_nid++;
     90   CRYPTO_STATIC_MUTEX_unlock(&global_next_nid_lock);
     91 
     92   return ret;
     93 }
     94 
     95 ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) {
     96   ASN1_OBJECT *r;
     97   unsigned char *data = NULL;
     98   char *sn = NULL, *ln = NULL;
     99 
    100   if (o == NULL) {
    101     return NULL;
    102   }
    103 
    104   if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
    105     /* TODO(fork): this is a little dangerous. */
    106     return (ASN1_OBJECT *)o;
    107   }
    108 
    109   r = ASN1_OBJECT_new();
    110   if (r == NULL) {
    111     OPENSSL_PUT_ERROR(OBJ, ERR_R_ASN1_LIB);
    112     return NULL;
    113   }
    114   r->ln = r->sn = NULL;
    115 
    116   data = OPENSSL_malloc(o->length);
    117   if (data == NULL) {
    118     goto err;
    119   }
    120   if (o->data != NULL) {
    121     memcpy(data, o->data, o->length);
    122   }
    123 
    124   /* once data is attached to an object, it remains const */
    125   r->data = data;
    126   r->length = o->length;
    127   r->nid = o->nid;
    128 
    129   if (o->ln != NULL) {
    130     ln = OPENSSL_strdup(o->ln);
    131     if (ln == NULL) {
    132       goto err;
    133     }
    134   }
    135 
    136   if (o->sn != NULL) {
    137     sn = OPENSSL_strdup(o->sn);
    138     if (sn == NULL) {
    139       goto err;
    140     }
    141   }
    142 
    143   r->sn = sn;
    144   r->ln = ln;
    145 
    146   r->flags =
    147       o->flags | (ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
    148                   ASN1_OBJECT_FLAG_DYNAMIC_DATA);
    149   return r;
    150 
    151 err:
    152   OPENSSL_PUT_ERROR(OBJ, ERR_R_MALLOC_FAILURE);
    153   OPENSSL_free(ln);
    154   OPENSSL_free(sn);
    155   OPENSSL_free(data);
    156   OPENSSL_free(r);
    157   return NULL;
    158 }
    159 
    160 int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {
    161   int ret;
    162 
    163   ret = a->length - b->length;
    164   if (ret) {
    165     return ret;
    166   }
    167   return memcmp(a->data, b->data, a->length);
    168 }
    169 
    170 /* obj_cmp is called to search the kNIDsInOIDOrder array. The |key| argument is
    171  * an |ASN1_OBJECT|* that we're looking for and |element| is a pointer to an
    172  * unsigned int in the array. */
    173 static int obj_cmp(const void *key, const void *element) {
    174   unsigned nid = *((const unsigned*) element);
    175   const ASN1_OBJECT *a = key;
    176   const ASN1_OBJECT *b = &kObjects[nid];
    177 
    178   if (a->length < b->length) {
    179     return -1;
    180   } else if (a->length > b->length) {
    181     return 1;
    182   }
    183   return memcmp(a->data, b->data, a->length);
    184 }
    185 
    186 int OBJ_obj2nid(const ASN1_OBJECT *obj) {
    187   const unsigned int *nid_ptr;
    188 
    189   if (obj == NULL) {
    190     return NID_undef;
    191   }
    192 
    193   if (obj->nid != 0) {
    194     return obj->nid;
    195   }
    196 
    197   CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock);
    198   if (global_added_by_data != NULL) {
    199     ASN1_OBJECT *match;
    200 
    201     match = lh_ASN1_OBJECT_retrieve(global_added_by_data, obj);
    202     if (match != NULL) {
    203       CRYPTO_STATIC_MUTEX_unlock(&global_added_lock);
    204       return match->nid;
    205     }
    206   }
    207   CRYPTO_STATIC_MUTEX_unlock(&global_added_lock);
    208 
    209   nid_ptr = bsearch(obj, kNIDsInOIDOrder, NUM_OBJ, sizeof(unsigned), obj_cmp);
    210   if (nid_ptr == NULL) {
    211     return NID_undef;
    212   }
    213 
    214   return kObjects[*nid_ptr].nid;
    215 }
    216 
    217 int OBJ_cbs2nid(const CBS *cbs) {
    218   ASN1_OBJECT obj;
    219   memset(&obj, 0, sizeof(obj));
    220   obj.data = CBS_data(cbs);
    221   obj.length = CBS_len(cbs);
    222 
    223   return OBJ_obj2nid(&obj);
    224 }
    225 
    226 /* short_name_cmp is called to search the kNIDsInShortNameOrder array. The
    227  * |key| argument is name that we're looking for and |element| is a pointer to
    228  * an unsigned int in the array. */
    229 static int short_name_cmp(const void *key, const void *element) {
    230   const char *name = (const char *) key;
    231   unsigned nid = *((unsigned*) element);
    232 
    233   return strcmp(name, kObjects[nid].sn);
    234 }
    235 
    236 int OBJ_sn2nid(const char *short_name) {
    237   const unsigned int *nid_ptr;
    238 
    239   CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock);
    240   if (global_added_by_short_name != NULL) {
    241     ASN1_OBJECT *match, template;
    242 
    243     template.sn = short_name;
    244     match = lh_ASN1_OBJECT_retrieve(global_added_by_short_name, &template);
    245     if (match != NULL) {
    246       CRYPTO_STATIC_MUTEX_unlock(&global_added_lock);
    247       return match->nid;
    248     }
    249   }
    250   CRYPTO_STATIC_MUTEX_unlock(&global_added_lock);
    251 
    252   nid_ptr = bsearch(short_name, kNIDsInShortNameOrder, NUM_SN, sizeof(unsigned), short_name_cmp);
    253   if (nid_ptr == NULL) {
    254     return NID_undef;
    255   }
    256 
    257   return kObjects[*nid_ptr].nid;
    258 }
    259 
    260 /* long_name_cmp is called to search the kNIDsInLongNameOrder array. The
    261  * |key| argument is name that we're looking for and |element| is a pointer to
    262  * an unsigned int in the array. */
    263 static int long_name_cmp(const void *key, const void *element) {
    264   const char *name = (const char *) key;
    265   unsigned nid = *((unsigned*) element);
    266 
    267   return strcmp(name, kObjects[nid].ln);
    268 }
    269 
    270 int OBJ_ln2nid(const char *long_name) {
    271   const unsigned int *nid_ptr;
    272 
    273   CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock);
    274   if (global_added_by_long_name != NULL) {
    275     ASN1_OBJECT *match, template;
    276 
    277     template.ln = long_name;
    278     match = lh_ASN1_OBJECT_retrieve(global_added_by_long_name, &template);
    279     if (match != NULL) {
    280       CRYPTO_STATIC_MUTEX_unlock(&global_added_lock);
    281       return match->nid;
    282     }
    283   }
    284   CRYPTO_STATIC_MUTEX_unlock(&global_added_lock);
    285 
    286   nid_ptr = bsearch(long_name, kNIDsInLongNameOrder, NUM_LN, sizeof(unsigned), long_name_cmp);
    287   if (nid_ptr == NULL) {
    288     return NID_undef;
    289   }
    290 
    291   return kObjects[*nid_ptr].nid;
    292 }
    293 
    294 int OBJ_txt2nid(const char *s) {
    295   ASN1_OBJECT *obj;
    296   int nid;
    297 
    298   obj = OBJ_txt2obj(s, 0 /* search names */);
    299   nid = OBJ_obj2nid(obj);
    300   ASN1_OBJECT_free(obj);
    301   return nid;
    302 }
    303 
    304 OPENSSL_EXPORT int OBJ_nid2cbb(CBB *out, int nid) {
    305   const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
    306   CBB oid;
    307 
    308   if (obj == NULL ||
    309       !CBB_add_asn1(out, &oid, CBS_ASN1_OBJECT) ||
    310       !CBB_add_bytes(&oid, obj->data, obj->length) ||
    311       !CBB_flush(out)) {
    312     return 0;
    313   }
    314 
    315   return 1;
    316 }
    317 
    318 const ASN1_OBJECT *OBJ_nid2obj(int nid) {
    319   if (nid >= 0 && nid < NUM_NID) {
    320     if (nid != NID_undef && kObjects[nid].nid == NID_undef) {
    321       goto err;
    322     }
    323     return &kObjects[nid];
    324   }
    325 
    326   CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock);
    327   if (global_added_by_nid != NULL) {
    328     ASN1_OBJECT *match, template;
    329 
    330     template.nid = nid;
    331     match = lh_ASN1_OBJECT_retrieve(global_added_by_nid, &template);
    332     if (match != NULL) {
    333       CRYPTO_STATIC_MUTEX_unlock(&global_added_lock);
    334       return match;
    335     }
    336   }
    337   CRYPTO_STATIC_MUTEX_unlock(&global_added_lock);
    338 
    339 err:
    340   OPENSSL_PUT_ERROR(OBJ, OBJ_R_UNKNOWN_NID);
    341   return NULL;
    342 }
    343 
    344 const char *OBJ_nid2sn(int nid) {
    345   const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
    346   if (obj == NULL) {
    347     return NULL;
    348   }
    349 
    350   return obj->sn;
    351 }
    352 
    353 const char *OBJ_nid2ln(int nid) {
    354   const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
    355   if (obj == NULL) {
    356     return NULL;
    357   }
    358 
    359   return obj->ln;
    360 }
    361 
    362 ASN1_OBJECT *OBJ_txt2obj(const char *s, int dont_search_names) {
    363   int nid = NID_undef;
    364   ASN1_OBJECT *op = NULL;
    365   unsigned char *buf;
    366   unsigned char *p;
    367   const unsigned char *bufp;
    368   int contents_len, total_len;
    369 
    370   if (!dont_search_names) {
    371     nid = OBJ_sn2nid(s);
    372     if (nid == NID_undef) {
    373       nid = OBJ_ln2nid(s);
    374     }
    375 
    376     if (nid != NID_undef) {
    377       return (ASN1_OBJECT*) OBJ_nid2obj(nid);
    378     }
    379   }
    380 
    381   /* Work out size of content octets */
    382   contents_len = a2d_ASN1_OBJECT(NULL, 0, s, -1);
    383   if (contents_len <= 0) {
    384     return NULL;
    385   }
    386   /* Work out total size */
    387   total_len = ASN1_object_size(0, contents_len, V_ASN1_OBJECT);
    388 
    389   buf = OPENSSL_malloc(total_len);
    390   if (buf == NULL) {
    391     OPENSSL_PUT_ERROR(OBJ, ERR_R_MALLOC_FAILURE);
    392     return NULL;
    393   }
    394 
    395   p = buf;
    396   /* Write out tag+length */
    397   ASN1_put_object(&p, 0, contents_len, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
    398   /* Write out contents */
    399   a2d_ASN1_OBJECT(p, contents_len, s, -1);
    400 
    401   bufp = buf;
    402   op = d2i_ASN1_OBJECT(NULL, &bufp, total_len);
    403   OPENSSL_free(buf);
    404 
    405   return op;
    406 }
    407 
    408 int OBJ_obj2txt(char *out, int out_len, const ASN1_OBJECT *obj, int dont_return_name) {
    409   int i, n = 0, len, nid, first, use_bn;
    410   BIGNUM *bl;
    411   unsigned long l;
    412   const unsigned char *p;
    413   char tbuf[DECIMAL_SIZE(i) + DECIMAL_SIZE(l) + 2];
    414 
    415   if (out && out_len > 0) {
    416     out[0] = 0;
    417   }
    418 
    419   if (obj == NULL || obj->data == NULL) {
    420     return 0;
    421   }
    422 
    423   if (!dont_return_name && (nid = OBJ_obj2nid(obj)) != NID_undef) {
    424     const char *s;
    425     s = OBJ_nid2ln(nid);
    426     if (s == NULL) {
    427       s = OBJ_nid2sn(nid);
    428     }
    429     if (s) {
    430       if (out) {
    431         BUF_strlcpy(out, s, out_len);
    432       }
    433       return strlen(s);
    434     }
    435   }
    436 
    437   len = obj->length;
    438   p = obj->data;
    439 
    440   first = 1;
    441   bl = NULL;
    442 
    443   while (len > 0) {
    444     l = 0;
    445     use_bn = 0;
    446     for (;;) {
    447       unsigned char c = *p++;
    448       len--;
    449       if (len == 0 && (c & 0x80)) {
    450         goto err;
    451       }
    452       if (use_bn) {
    453         if (!BN_add_word(bl, c & 0x7f)) {
    454           goto err;
    455         }
    456       } else {
    457         l |= c & 0x7f;
    458       }
    459       if (!(c & 0x80)) {
    460         break;
    461       }
    462       if (!use_bn && (l > (ULONG_MAX >> 7L))) {
    463         if (!bl && !(bl = BN_new())) {
    464           goto err;
    465         }
    466         if (!BN_set_word(bl, l)) {
    467           goto err;
    468         }
    469         use_bn = 1;
    470       }
    471       if (use_bn) {
    472         if (!BN_lshift(bl, bl, 7)) {
    473           goto err;
    474         }
    475       } else {
    476         l <<= 7L;
    477       }
    478     }
    479 
    480     if (first) {
    481       first = 0;
    482       if (l >= 80) {
    483         i = 2;
    484         if (use_bn) {
    485           if (!BN_sub_word(bl, 80)) {
    486             goto err;
    487           }
    488         } else {
    489           l -= 80;
    490         }
    491       } else {
    492         i = (int)(l / 40);
    493         l -= (long)(i * 40);
    494       }
    495       if (out && out_len > 1) {
    496         *out++ = i + '0';
    497         *out = '0';
    498         out_len--;
    499       }
    500       n++;
    501     }
    502 
    503     if (use_bn) {
    504       char *bndec;
    505       bndec = BN_bn2dec(bl);
    506       if (!bndec) {
    507         goto err;
    508       }
    509       i = strlen(bndec);
    510       if (out) {
    511         if (out_len > 1) {
    512           *out++ = '.';
    513           *out = 0;
    514           out_len--;
    515         }
    516         BUF_strlcpy(out, bndec, out_len);
    517         if (i > out_len) {
    518           out += out_len;
    519           out_len = 0;
    520         } else {
    521           out += i;
    522           out_len -= i;
    523         }
    524       }
    525       n++;
    526       n += i;
    527       OPENSSL_free(bndec);
    528     } else {
    529       BIO_snprintf(tbuf, sizeof(tbuf), ".%lu", l);
    530       i = strlen(tbuf);
    531       if (out && out_len > 0) {
    532         BUF_strlcpy(out, tbuf, out_len);
    533         if (i > out_len) {
    534           out += out_len;
    535           out_len = 0;
    536         } else {
    537           out += i;
    538           out_len -= i;
    539         }
    540       }
    541       n += i;
    542     }
    543   }
    544 
    545   BN_free(bl);
    546   return n;
    547 
    548 err:
    549   BN_free(bl);
    550   return -1;
    551 }
    552 
    553 static uint32_t hash_nid(const ASN1_OBJECT *obj) {
    554   return obj->nid;
    555 }
    556 
    557 static int cmp_nid(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {
    558   return a->nid - b->nid;
    559 }
    560 
    561 static uint32_t hash_data(const ASN1_OBJECT *obj) {
    562   return OPENSSL_hash32(obj->data, obj->length);
    563 }
    564 
    565 static int cmp_data(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {
    566   int i = a->length - b->length;
    567   if (i) {
    568     return i;
    569   }
    570   return memcmp(a->data, b->data, a->length);
    571 }
    572 
    573 static uint32_t hash_short_name(const ASN1_OBJECT *obj) {
    574   return lh_strhash(obj->sn);
    575 }
    576 
    577 static int cmp_short_name(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {
    578   return strcmp(a->sn, b->sn);
    579 }
    580 
    581 static uint32_t hash_long_name(const ASN1_OBJECT *obj) {
    582   return lh_strhash(obj->ln);
    583 }
    584 
    585 static int cmp_long_name(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {
    586   return strcmp(a->ln, b->ln);
    587 }
    588 
    589 /* obj_add_object inserts |obj| into the various global hashes for run-time
    590  * added objects. It returns one on success or zero otherwise. */
    591 static int obj_add_object(ASN1_OBJECT *obj) {
    592   int ok;
    593   ASN1_OBJECT *old_object;
    594 
    595   obj->flags &= ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
    596                   ASN1_OBJECT_FLAG_DYNAMIC_DATA);
    597 
    598   CRYPTO_STATIC_MUTEX_lock_write(&global_added_lock);
    599   if (global_added_by_nid == NULL) {
    600     global_added_by_nid = lh_ASN1_OBJECT_new(hash_nid, cmp_nid);
    601     global_added_by_data = lh_ASN1_OBJECT_new(hash_data, cmp_data);
    602     global_added_by_short_name = lh_ASN1_OBJECT_new(hash_short_name, cmp_short_name);
    603     global_added_by_long_name = lh_ASN1_OBJECT_new(hash_long_name, cmp_long_name);
    604   }
    605 
    606   /* We don't pay attention to |old_object| (which contains any previous object
    607    * that was evicted from the hashes) because we don't have a reference count
    608    * on ASN1_OBJECT values. Also, we should never have duplicates nids and so
    609    * should always have objects in |global_added_by_nid|. */
    610 
    611   ok = lh_ASN1_OBJECT_insert(global_added_by_nid, &old_object, obj);
    612   if (obj->length != 0 && obj->data != NULL) {
    613     ok &= lh_ASN1_OBJECT_insert(global_added_by_data, &old_object, obj);
    614   }
    615   if (obj->sn != NULL) {
    616     ok &= lh_ASN1_OBJECT_insert(global_added_by_short_name, &old_object, obj);
    617   }
    618   if (obj->ln != NULL) {
    619     ok &= lh_ASN1_OBJECT_insert(global_added_by_long_name, &old_object, obj);
    620   }
    621   CRYPTO_STATIC_MUTEX_unlock(&global_added_lock);
    622 
    623   return ok;
    624 }
    625 
    626 int OBJ_create(const char *oid, const char *short_name, const char *long_name) {
    627   int ret = NID_undef;
    628   ASN1_OBJECT *op = NULL;
    629   unsigned char *buf = NULL;
    630   int len;
    631 
    632   len = a2d_ASN1_OBJECT(NULL, 0, oid, -1);
    633   if (len <= 0) {
    634     goto err;
    635   }
    636 
    637   buf = OPENSSL_malloc(len);
    638   if (buf == NULL) {
    639     OPENSSL_PUT_ERROR(OBJ, ERR_R_MALLOC_FAILURE);
    640     goto err;
    641   }
    642 
    643   len = a2d_ASN1_OBJECT(buf, len, oid, -1);
    644   if (len == 0) {
    645     goto err;
    646   }
    647 
    648   op = (ASN1_OBJECT *)ASN1_OBJECT_create(obj_next_nid(), buf, len, short_name,
    649                                          long_name);
    650   if (op == NULL) {
    651     goto err;
    652   }
    653 
    654   if (obj_add_object(op)) {
    655     ret = op->nid;
    656   }
    657   op = NULL;
    658 
    659 err:
    660   ASN1_OBJECT_free(op);
    661   OPENSSL_free(buf);
    662 
    663   return ret;
    664 }
    665