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 #if !defined(__STDC_FORMAT_MACROS)
     58 #define __STDC_FORMAT_MACROS
     59 #endif
     60 
     61 #include <openssl/obj.h>
     62 
     63 #include <inttypes.h>
     64 #include <limits.h>
     65 #include <string.h>
     66 
     67 #include <openssl/asn1.h>
     68 #include <openssl/buf.h>
     69 #include <openssl/bytestring.h>
     70 #include <openssl/err.h>
     71 #include <openssl/lhash.h>
     72 #include <openssl/mem.h>
     73 #include <openssl/thread.h>
     74 
     75 #include "obj_dat.h"
     76 #include "../internal.h"
     77 
     78 
     79 static struct CRYPTO_STATIC_MUTEX global_added_lock = CRYPTO_STATIC_MUTEX_INIT;
     80 /* These globals are protected by |global_added_lock|. */
     81 static LHASH_OF(ASN1_OBJECT) *global_added_by_data = NULL;
     82 static LHASH_OF(ASN1_OBJECT) *global_added_by_nid = NULL;
     83 static LHASH_OF(ASN1_OBJECT) *global_added_by_short_name = NULL;
     84 static LHASH_OF(ASN1_OBJECT) *global_added_by_long_name = NULL;
     85 
     86 static struct CRYPTO_STATIC_MUTEX global_next_nid_lock =
     87     CRYPTO_STATIC_MUTEX_INIT;
     88 static unsigned global_next_nid = NUM_NID;
     89 
     90 static int obj_next_nid(void) {
     91   int ret;
     92 
     93   CRYPTO_STATIC_MUTEX_lock_write(&global_next_nid_lock);
     94   ret = global_next_nid++;
     95   CRYPTO_STATIC_MUTEX_unlock_write(&global_next_nid_lock);
     96 
     97   return ret;
     98 }
     99 
    100 ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) {
    101   ASN1_OBJECT *r;
    102   unsigned char *data = NULL;
    103   char *sn = NULL, *ln = NULL;
    104 
    105   if (o == NULL) {
    106     return NULL;
    107   }
    108 
    109   if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
    110     /* TODO(fork): this is a little dangerous. */
    111     return (ASN1_OBJECT *)o;
    112   }
    113 
    114   r = ASN1_OBJECT_new();
    115   if (r == NULL) {
    116     OPENSSL_PUT_ERROR(OBJ, ERR_R_ASN1_LIB);
    117     return NULL;
    118   }
    119   r->ln = r->sn = NULL;
    120 
    121   data = OPENSSL_malloc(o->length);
    122   if (data == NULL) {
    123     goto err;
    124   }
    125   if (o->data != NULL) {
    126     OPENSSL_memcpy(data, o->data, o->length);
    127   }
    128 
    129   /* once data is attached to an object, it remains const */
    130   r->data = data;
    131   r->length = o->length;
    132   r->nid = o->nid;
    133 
    134   if (o->ln != NULL) {
    135     ln = OPENSSL_strdup(o->ln);
    136     if (ln == NULL) {
    137       goto err;
    138     }
    139   }
    140 
    141   if (o->sn != NULL) {
    142     sn = OPENSSL_strdup(o->sn);
    143     if (sn == NULL) {
    144       goto err;
    145     }
    146   }
    147 
    148   r->sn = sn;
    149   r->ln = ln;
    150 
    151   r->flags =
    152       o->flags | (ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
    153                   ASN1_OBJECT_FLAG_DYNAMIC_DATA);
    154   return r;
    155 
    156 err:
    157   OPENSSL_PUT_ERROR(OBJ, ERR_R_MALLOC_FAILURE);
    158   OPENSSL_free(ln);
    159   OPENSSL_free(sn);
    160   OPENSSL_free(data);
    161   OPENSSL_free(r);
    162   return NULL;
    163 }
    164 
    165 int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {
    166   int ret;
    167 
    168   ret = a->length - b->length;
    169   if (ret) {
    170     return ret;
    171   }
    172   return OPENSSL_memcmp(a->data, b->data, a->length);
    173 }
    174 
    175 /* obj_cmp is called to search the kNIDsInOIDOrder array. The |key| argument is
    176  * an |ASN1_OBJECT|* that we're looking for and |element| is a pointer to an
    177  * unsigned int in the array. */
    178 static int obj_cmp(const void *key, const void *element) {
    179   unsigned nid = *((const unsigned*) element);
    180   const ASN1_OBJECT *a = key;
    181   const ASN1_OBJECT *b = &kObjects[nid];
    182 
    183   if (a->length < b->length) {
    184     return -1;
    185   } else if (a->length > b->length) {
    186     return 1;
    187   }
    188   return OPENSSL_memcmp(a->data, b->data, a->length);
    189 }
    190 
    191 int OBJ_obj2nid(const ASN1_OBJECT *obj) {
    192   const unsigned int *nid_ptr;
    193 
    194   if (obj == NULL) {
    195     return NID_undef;
    196   }
    197 
    198   if (obj->nid != 0) {
    199     return obj->nid;
    200   }
    201 
    202   CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock);
    203   if (global_added_by_data != NULL) {
    204     ASN1_OBJECT *match;
    205 
    206     match = lh_ASN1_OBJECT_retrieve(global_added_by_data, obj);
    207     if (match != NULL) {
    208       CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock);
    209       return match->nid;
    210     }
    211   }
    212   CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock);
    213 
    214   nid_ptr = bsearch(obj, kNIDsInOIDOrder, OPENSSL_ARRAY_SIZE(kNIDsInOIDOrder),
    215                     sizeof(kNIDsInOIDOrder[0]), obj_cmp);
    216   if (nid_ptr == NULL) {
    217     return NID_undef;
    218   }
    219 
    220   return kObjects[*nid_ptr].nid;
    221 }
    222 
    223 int OBJ_cbs2nid(const CBS *cbs) {
    224   if (CBS_len(cbs) > INT_MAX) {
    225     return NID_undef;
    226   }
    227 
    228   ASN1_OBJECT obj;
    229   OPENSSL_memset(&obj, 0, sizeof(obj));
    230   obj.data = CBS_data(cbs);
    231   obj.length = (int)CBS_len(cbs);
    232 
    233   return OBJ_obj2nid(&obj);
    234 }
    235 
    236 /* short_name_cmp is called to search the kNIDsInShortNameOrder array. The
    237  * |key| argument is name that we're looking for and |element| is a pointer to
    238  * an unsigned int in the array. */
    239 static int short_name_cmp(const void *key, const void *element) {
    240   const char *name = (const char *) key;
    241   unsigned nid = *((unsigned*) element);
    242 
    243   return strcmp(name, kObjects[nid].sn);
    244 }
    245 
    246 int OBJ_sn2nid(const char *short_name) {
    247   const unsigned int *nid_ptr;
    248 
    249   CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock);
    250   if (global_added_by_short_name != NULL) {
    251     ASN1_OBJECT *match, template;
    252 
    253     template.sn = short_name;
    254     match = lh_ASN1_OBJECT_retrieve(global_added_by_short_name, &template);
    255     if (match != NULL) {
    256       CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock);
    257       return match->nid;
    258     }
    259   }
    260   CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock);
    261 
    262   nid_ptr = bsearch(short_name, kNIDsInShortNameOrder,
    263                     OPENSSL_ARRAY_SIZE(kNIDsInShortNameOrder),
    264                     sizeof(kNIDsInShortNameOrder[0]), short_name_cmp);
    265   if (nid_ptr == NULL) {
    266     return NID_undef;
    267   }
    268 
    269   return kObjects[*nid_ptr].nid;
    270 }
    271 
    272 /* long_name_cmp is called to search the kNIDsInLongNameOrder array. The
    273  * |key| argument is name that we're looking for and |element| is a pointer to
    274  * an unsigned int in the array. */
    275 static int long_name_cmp(const void *key, const void *element) {
    276   const char *name = (const char *) key;
    277   unsigned nid = *((unsigned*) element);
    278 
    279   return strcmp(name, kObjects[nid].ln);
    280 }
    281 
    282 int OBJ_ln2nid(const char *long_name) {
    283   const unsigned int *nid_ptr;
    284 
    285   CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock);
    286   if (global_added_by_long_name != NULL) {
    287     ASN1_OBJECT *match, template;
    288 
    289     template.ln = long_name;
    290     match = lh_ASN1_OBJECT_retrieve(global_added_by_long_name, &template);
    291     if (match != NULL) {
    292       CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock);
    293       return match->nid;
    294     }
    295   }
    296   CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock);
    297 
    298   nid_ptr = bsearch(long_name, kNIDsInLongNameOrder,
    299                     OPENSSL_ARRAY_SIZE(kNIDsInLongNameOrder),
    300                     sizeof(kNIDsInLongNameOrder[0]), long_name_cmp);
    301   if (nid_ptr == NULL) {
    302     return NID_undef;
    303   }
    304 
    305   return kObjects[*nid_ptr].nid;
    306 }
    307 
    308 int OBJ_txt2nid(const char *s) {
    309   ASN1_OBJECT *obj;
    310   int nid;
    311 
    312   obj = OBJ_txt2obj(s, 0 /* search names */);
    313   nid = OBJ_obj2nid(obj);
    314   ASN1_OBJECT_free(obj);
    315   return nid;
    316 }
    317 
    318 OPENSSL_EXPORT int OBJ_nid2cbb(CBB *out, int nid) {
    319   const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
    320   CBB oid;
    321 
    322   if (obj == NULL ||
    323       !CBB_add_asn1(out, &oid, CBS_ASN1_OBJECT) ||
    324       !CBB_add_bytes(&oid, obj->data, obj->length) ||
    325       !CBB_flush(out)) {
    326     return 0;
    327   }
    328 
    329   return 1;
    330 }
    331 
    332 const ASN1_OBJECT *OBJ_nid2obj(int nid) {
    333   if (nid >= 0 && nid < NUM_NID) {
    334     if (nid != NID_undef && kObjects[nid].nid == NID_undef) {
    335       goto err;
    336     }
    337     return &kObjects[nid];
    338   }
    339 
    340   CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock);
    341   if (global_added_by_nid != NULL) {
    342     ASN1_OBJECT *match, template;
    343 
    344     template.nid = nid;
    345     match = lh_ASN1_OBJECT_retrieve(global_added_by_nid, &template);
    346     if (match != NULL) {
    347       CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock);
    348       return match;
    349     }
    350   }
    351   CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock);
    352 
    353 err:
    354   OPENSSL_PUT_ERROR(OBJ, OBJ_R_UNKNOWN_NID);
    355   return NULL;
    356 }
    357 
    358 const char *OBJ_nid2sn(int nid) {
    359   const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
    360   if (obj == NULL) {
    361     return NULL;
    362   }
    363 
    364   return obj->sn;
    365 }
    366 
    367 const char *OBJ_nid2ln(int nid) {
    368   const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
    369   if (obj == NULL) {
    370     return NULL;
    371   }
    372 
    373   return obj->ln;
    374 }
    375 
    376 ASN1_OBJECT *OBJ_txt2obj(const char *s, int dont_search_names) {
    377   int nid = NID_undef;
    378   ASN1_OBJECT *op = NULL;
    379   unsigned char *buf;
    380   unsigned char *p;
    381   const unsigned char *bufp;
    382   int contents_len, total_len;
    383 
    384   if (!dont_search_names) {
    385     nid = OBJ_sn2nid(s);
    386     if (nid == NID_undef) {
    387       nid = OBJ_ln2nid(s);
    388     }
    389 
    390     if (nid != NID_undef) {
    391       return (ASN1_OBJECT*) OBJ_nid2obj(nid);
    392     }
    393   }
    394 
    395   /* Work out size of content octets */
    396   contents_len = a2d_ASN1_OBJECT(NULL, 0, s, -1);
    397   if (contents_len <= 0) {
    398     return NULL;
    399   }
    400   /* Work out total size */
    401   total_len = ASN1_object_size(0, contents_len, V_ASN1_OBJECT);
    402 
    403   buf = OPENSSL_malloc(total_len);
    404   if (buf == NULL) {
    405     OPENSSL_PUT_ERROR(OBJ, ERR_R_MALLOC_FAILURE);
    406     return NULL;
    407   }
    408 
    409   p = buf;
    410   /* Write out tag+length */
    411   ASN1_put_object(&p, 0, contents_len, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
    412   /* Write out contents */
    413   a2d_ASN1_OBJECT(p, contents_len, s, -1);
    414 
    415   bufp = buf;
    416   op = d2i_ASN1_OBJECT(NULL, &bufp, total_len);
    417   OPENSSL_free(buf);
    418 
    419   return op;
    420 }
    421 
    422 static int strlcpy_int(char *dst, const char *src, int dst_size) {
    423   size_t ret = BUF_strlcpy(dst, src, dst_size < 0 ? 0 : (size_t)dst_size);
    424   if (ret > INT_MAX) {
    425     OPENSSL_PUT_ERROR(OBJ, ERR_R_OVERFLOW);
    426     return -1;
    427   }
    428   return (int)ret;
    429 }
    430 
    431 static int parse_oid_component(CBS *cbs, uint64_t *out) {
    432   uint64_t v = 0;
    433   uint8_t b;
    434   do {
    435     if (!CBS_get_u8(cbs, &b)) {
    436       return 0;
    437     }
    438     if ((v >> (64 - 7)) != 0) {
    439       /* The component is too large. */
    440       return 0;
    441     }
    442     if (v == 0 && b == 0x80) {
    443       /* The component must be minimally encoded. */
    444       return 0;
    445     }
    446     v = (v << 7) | (b & 0x7f);
    447 
    448     /* Components end at an octet with the high bit cleared. */
    449   } while (b & 0x80);
    450 
    451   *out = v;
    452   return 1;
    453 }
    454 
    455 static int add_decimal(CBB *out, uint64_t v) {
    456   char buf[DECIMAL_SIZE(uint64_t) + 1];
    457   BIO_snprintf(buf, sizeof(buf), "%" PRIu64, v);
    458   return CBB_add_bytes(out, (const uint8_t *)buf, strlen(buf));
    459 }
    460 
    461 int OBJ_obj2txt(char *out, int out_len, const ASN1_OBJECT *obj,
    462                 int always_return_oid) {
    463   /* Python depends on the empty OID successfully encoding as the empty
    464    * string. */
    465   if (obj == NULL || obj->length == 0) {
    466     return strlcpy_int(out, "", out_len);
    467   }
    468 
    469   if (!always_return_oid) {
    470     int nid = OBJ_obj2nid(obj);
    471     if (nid != NID_undef) {
    472       const char *name = OBJ_nid2ln(nid);
    473       if (name == NULL) {
    474         name = OBJ_nid2sn(nid);
    475       }
    476       if (name != NULL) {
    477         return strlcpy_int(out, name, out_len);
    478       }
    479     }
    480   }
    481 
    482   CBB cbb;
    483   if (!CBB_init(&cbb, 32)) {
    484     goto err;
    485   }
    486 
    487   CBS cbs;
    488   CBS_init(&cbs, obj->data, obj->length);
    489 
    490   /* The first component is 40 * value1 + value2, where value1 is 0, 1, or 2. */
    491   uint64_t v;
    492   if (!parse_oid_component(&cbs, &v)) {
    493     goto err;
    494   }
    495 
    496   if (v >= 80) {
    497     if (!CBB_add_bytes(&cbb, (const uint8_t *)"2.", 2) ||
    498         !add_decimal(&cbb, v - 80)) {
    499       goto err;
    500     }
    501   } else if (!add_decimal(&cbb, v / 40) ||
    502              !CBB_add_u8(&cbb, '.') ||
    503              !add_decimal(&cbb, v % 40)) {
    504     goto err;
    505   }
    506 
    507   while (CBS_len(&cbs) != 0) {
    508     if (!parse_oid_component(&cbs, &v) ||
    509         !CBB_add_u8(&cbb, '.') ||
    510         !add_decimal(&cbb, v)) {
    511       goto err;
    512     }
    513   }
    514 
    515   uint8_t *txt;
    516   size_t txt_len;
    517   if (!CBB_add_u8(&cbb, '\0') ||
    518       !CBB_finish(&cbb, &txt, &txt_len)) {
    519     goto err;
    520   }
    521 
    522   int ret = strlcpy_int(out, (const char *)txt, out_len);
    523   OPENSSL_free(txt);
    524   return ret;
    525 
    526 err:
    527   CBB_cleanup(&cbb);
    528   if (out_len > 0) {
    529     out[0] = '\0';
    530   }
    531   return -1;
    532 }
    533 
    534 static uint32_t hash_nid(const ASN1_OBJECT *obj) {
    535   return obj->nid;
    536 }
    537 
    538 static int cmp_nid(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {
    539   return a->nid - b->nid;
    540 }
    541 
    542 static uint32_t hash_data(const ASN1_OBJECT *obj) {
    543   return OPENSSL_hash32(obj->data, obj->length);
    544 }
    545 
    546 static int cmp_data(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {
    547   int i = a->length - b->length;
    548   if (i) {
    549     return i;
    550   }
    551   return OPENSSL_memcmp(a->data, b->data, a->length);
    552 }
    553 
    554 static uint32_t hash_short_name(const ASN1_OBJECT *obj) {
    555   return lh_strhash(obj->sn);
    556 }
    557 
    558 static int cmp_short_name(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {
    559   return strcmp(a->sn, b->sn);
    560 }
    561 
    562 static uint32_t hash_long_name(const ASN1_OBJECT *obj) {
    563   return lh_strhash(obj->ln);
    564 }
    565 
    566 static int cmp_long_name(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {
    567   return strcmp(a->ln, b->ln);
    568 }
    569 
    570 /* obj_add_object inserts |obj| into the various global hashes for run-time
    571  * added objects. It returns one on success or zero otherwise. */
    572 static int obj_add_object(ASN1_OBJECT *obj) {
    573   int ok;
    574   ASN1_OBJECT *old_object;
    575 
    576   obj->flags &= ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
    577                   ASN1_OBJECT_FLAG_DYNAMIC_DATA);
    578 
    579   CRYPTO_STATIC_MUTEX_lock_write(&global_added_lock);
    580   if (global_added_by_nid == NULL) {
    581     global_added_by_nid = lh_ASN1_OBJECT_new(hash_nid, cmp_nid);
    582     global_added_by_data = lh_ASN1_OBJECT_new(hash_data, cmp_data);
    583     global_added_by_short_name = lh_ASN1_OBJECT_new(hash_short_name, cmp_short_name);
    584     global_added_by_long_name = lh_ASN1_OBJECT_new(hash_long_name, cmp_long_name);
    585   }
    586 
    587   /* We don't pay attention to |old_object| (which contains any previous object
    588    * that was evicted from the hashes) because we don't have a reference count
    589    * on ASN1_OBJECT values. Also, we should never have duplicates nids and so
    590    * should always have objects in |global_added_by_nid|. */
    591 
    592   ok = lh_ASN1_OBJECT_insert(global_added_by_nid, &old_object, obj);
    593   if (obj->length != 0 && obj->data != NULL) {
    594     ok &= lh_ASN1_OBJECT_insert(global_added_by_data, &old_object, obj);
    595   }
    596   if (obj->sn != NULL) {
    597     ok &= lh_ASN1_OBJECT_insert(global_added_by_short_name, &old_object, obj);
    598   }
    599   if (obj->ln != NULL) {
    600     ok &= lh_ASN1_OBJECT_insert(global_added_by_long_name, &old_object, obj);
    601   }
    602   CRYPTO_STATIC_MUTEX_unlock_write(&global_added_lock);
    603 
    604   return ok;
    605 }
    606 
    607 int OBJ_create(const char *oid, const char *short_name, const char *long_name) {
    608   int ret = NID_undef;
    609   ASN1_OBJECT *op = NULL;
    610   unsigned char *buf = NULL;
    611   int len;
    612 
    613   len = a2d_ASN1_OBJECT(NULL, 0, oid, -1);
    614   if (len <= 0) {
    615     goto err;
    616   }
    617 
    618   buf = OPENSSL_malloc(len);
    619   if (buf == NULL) {
    620     OPENSSL_PUT_ERROR(OBJ, ERR_R_MALLOC_FAILURE);
    621     goto err;
    622   }
    623 
    624   len = a2d_ASN1_OBJECT(buf, len, oid, -1);
    625   if (len == 0) {
    626     goto err;
    627   }
    628 
    629   op = (ASN1_OBJECT *)ASN1_OBJECT_create(obj_next_nid(), buf, len, short_name,
    630                                          long_name);
    631   if (op == NULL) {
    632     goto err;
    633   }
    634 
    635   if (obj_add_object(op)) {
    636     ret = op->nid;
    637   }
    638   op = NULL;
    639 
    640 err:
    641   ASN1_OBJECT_free(op);
    642   OPENSSL_free(buf);
    643 
    644   return ret;
    645 }
    646