/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.] */

#include <openssl/obj.h>

#include <limits.h>
#include <string.h>

#include <openssl/asn1.h>
#include <openssl/buf.h>
#include <openssl/bytestring.h>
#include <openssl/err.h>
#include <openssl/lhash.h>
#include <openssl/mem.h>
#include <openssl/thread.h>

#include "obj_dat.h"

/* These globals are protected by CRYPTO_LOCK_OBJ. */
static LHASH_OF(ASN1_OBJECT) *global_added_by_data = NULL;
static LHASH_OF(ASN1_OBJECT) *global_added_by_nid = NULL;
static LHASH_OF(ASN1_OBJECT) *global_added_by_short_name = NULL;
static LHASH_OF(ASN1_OBJECT) *global_added_by_long_name = NULL;

static unsigned global_next_nid = NUM_NID;

static int obj_next_nid(void) {
  int ret;

  CRYPTO_w_lock(CRYPTO_LOCK_OBJ);
  ret = global_next_nid++;
  CRYPTO_w_unlock(CRYPTO_LOCK_OBJ);

  return ret;
}

ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) {
  ASN1_OBJECT *r;
  unsigned char *data = NULL;
  char *sn = NULL, *ln = NULL;

  if (o == NULL) {
    return NULL;
  }

  if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
    /* TODO(fork): this is a little dangerous. */
    return (ASN1_OBJECT *)o;
  }

  r = ASN1_OBJECT_new();
  if (r == NULL) {
    OPENSSL_PUT_ERROR(OBJ, OBJ_dup, ERR_R_ASN1_LIB);
    return NULL;
  }
  r->ln = r->sn = NULL;

  data = OPENSSL_malloc(o->length);
  if (data == NULL) {
    goto err;
  }
  if (o->data != NULL) {
    memcpy(data, o->data, o->length);
  }

  /* once data is attached to an object, it remains const */
  r->data = data;
  r->length = o->length;
  r->nid = o->nid;

  if (o->ln != NULL) {
    ln = OPENSSL_strdup(o->ln);
    if (ln == NULL) {
      goto err;
    }
  }

  if (o->sn != NULL) {
    sn = OPENSSL_strdup(o->sn);
    if (sn) {
      goto err;
    }
  }

  r->sn = sn;
  r->ln = ln;

  r->flags =
      o->flags | (ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
                  ASN1_OBJECT_FLAG_DYNAMIC_DATA);
  return r;

err:
  OPENSSL_PUT_ERROR(OBJ, OBJ_dup, ERR_R_MALLOC_FAILURE);
  if (ln != NULL) {
    OPENSSL_free(ln);
  }
  if (sn != NULL) {
    OPENSSL_free(sn);
  }
  if (data != NULL) {
    OPENSSL_free(data);
  }
  OPENSSL_free(r);
  return NULL;
}

int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {
  int ret;

  ret = a->length - b->length;
  if (ret) {
    return ret;
  }
  return memcmp(a->data, b->data, a->length);
}

/* nids_cmp is called to search the kNIDsInOIDOrder array. The |key| argument
 * is an |ASN1_OBJECT|* that we're looking for and |element| is a pointer to an
 * unsigned int in the array. */
static int obj_cmp(const void *key, const void *element) {
  int j;
  unsigned nid = *((unsigned*) element);
  const ASN1_OBJECT *a = key;
  const ASN1_OBJECT *b = &kObjects[nid];

  j = a->length - b->length;
  if (j) {
    return j;
  }
  return memcmp(a->data, b->data, a->length);
}

int OBJ_obj2nid(const ASN1_OBJECT *obj) {
  const unsigned int *nid_ptr;

  if (obj == NULL) {
    return NID_undef;
  }

  if (obj->nid != 0) {
    return obj->nid;
  }

  CRYPTO_r_lock(CRYPTO_LOCK_OBJ);
  if (global_added_by_data != NULL) {
    ASN1_OBJECT *match;

    match = lh_ASN1_OBJECT_retrieve(global_added_by_data, obj);
    if (match != NULL) {
      CRYPTO_r_unlock(CRYPTO_LOCK_OBJ);
      return match->nid;
    }
  }
  CRYPTO_r_unlock(CRYPTO_LOCK_OBJ);

  nid_ptr = bsearch(obj, kNIDsInOIDOrder, NUM_OBJ, sizeof(unsigned), obj_cmp);
  if (nid_ptr == NULL) {
    return NID_undef;
  }

  return kObjects[*nid_ptr].nid;
}

int OBJ_cbs2nid(const CBS *cbs) {
  ASN1_OBJECT obj;
  memset(&obj, 0, sizeof(obj));
  obj.data = CBS_data(cbs);
  obj.length = CBS_len(cbs);

  return OBJ_obj2nid(&obj);
}

/* short_name_cmp is called to search the kNIDsInShortNameOrder array. The
 * |key| argument is name that we're looking for and |element| is a pointer to
 * an unsigned int in the array. */
static int short_name_cmp(const void *key, const void *element) {
  const char *name = (const char *) key;
  unsigned nid = *((unsigned*) element);

  return strcmp(name, kObjects[nid].sn);
}

int OBJ_sn2nid(const char *short_name) {
  const unsigned int *nid_ptr;

  CRYPTO_r_lock(CRYPTO_LOCK_OBJ);
  if (global_added_by_short_name != NULL) {
    ASN1_OBJECT *match, template;

    template.sn = short_name;
    match = lh_ASN1_OBJECT_retrieve(global_added_by_short_name, &template);
    if (match != NULL) {
      CRYPTO_r_unlock(CRYPTO_LOCK_OBJ);
      return match->nid;
    }
  }
  CRYPTO_r_unlock(CRYPTO_LOCK_OBJ);

  nid_ptr = bsearch(short_name, kNIDsInShortNameOrder, NUM_SN, sizeof(unsigned), short_name_cmp);
  if (nid_ptr == NULL) {
    return NID_undef;
  }

  return kObjects[*nid_ptr].nid;
}

/* long_name_cmp is called to search the kNIDsInLongNameOrder array. The
 * |key| argument is name that we're looking for and |element| is a pointer to
 * an unsigned int in the array. */
static int long_name_cmp(const void *key, const void *element) {
  const char *name = (const char *) key;
  unsigned nid = *((unsigned*) element);

  return strcmp(name, kObjects[nid].ln);
}

int OBJ_ln2nid(const char *long_name) {
  const unsigned int *nid_ptr;

  CRYPTO_r_lock(CRYPTO_LOCK_OBJ);
  if (global_added_by_long_name != NULL) {
    ASN1_OBJECT *match, template;

    template.ln = long_name;
    match = lh_ASN1_OBJECT_retrieve(global_added_by_long_name, &template);
    if (match != NULL) {
      CRYPTO_r_unlock(CRYPTO_LOCK_OBJ);
      return match->nid;
    }
  }
  CRYPTO_r_unlock(CRYPTO_LOCK_OBJ);

  nid_ptr = bsearch(long_name, kNIDsInLongNameOrder, NUM_LN, sizeof(unsigned), long_name_cmp);
  if (nid_ptr == NULL) {
    return NID_undef;
  }

  return kObjects[*nid_ptr].nid;
}

int OBJ_txt2nid(const char *s) {
  ASN1_OBJECT *obj;
  int nid;

  obj = OBJ_txt2obj(s, 0 /* search names */);
  nid = OBJ_obj2nid(obj);
  ASN1_OBJECT_free(obj);
  return nid;
}

OPENSSL_EXPORT int OBJ_nid2cbb(CBB *out, int nid) {
  const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
  CBB oid;

  if (obj == NULL ||
      !CBB_add_asn1(out, &oid, CBS_ASN1_OBJECT) ||
      !CBB_add_bytes(&oid, obj->data, obj->length) ||
      !CBB_flush(out)) {
    return 0;
  }

  return 1;
}

const ASN1_OBJECT *OBJ_nid2obj(int nid) {
  if (nid >= 0 && nid < NUM_NID) {
    if (nid != NID_undef && kObjects[nid].nid == NID_undef) {
      goto err;
    }
    return &kObjects[nid];
  }

  CRYPTO_r_lock(CRYPTO_LOCK_OBJ);
  if (global_added_by_nid != NULL) {
    ASN1_OBJECT *match, template;

    template.nid = nid;
    match = lh_ASN1_OBJECT_retrieve(global_added_by_nid, &template);
    if (match != NULL) {
      CRYPTO_r_unlock(CRYPTO_LOCK_OBJ);
      return match;
    }
  }
  CRYPTO_r_unlock(CRYPTO_LOCK_OBJ);

err:
  OPENSSL_PUT_ERROR(OBJ, OBJ_nid2obj, OBJ_R_UNKNOWN_NID);
  return NULL;
}

const char *OBJ_nid2sn(int nid) {
  const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
  if (obj == NULL) {
    return NULL;
  }

  return obj->sn;
}

const char *OBJ_nid2ln(int nid) {
  const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
  if (obj == NULL) {
    return NULL;
  }

  return obj->ln;
}

ASN1_OBJECT *OBJ_txt2obj(const char *s, int dont_search_names) {
  int nid = NID_undef;
  ASN1_OBJECT *op = NULL;
  unsigned char *buf;
  unsigned char *p;
  const unsigned char *bufp;
  int contents_len, total_len;

  if (!dont_search_names) {
    nid = OBJ_sn2nid(s);
    if (nid == NID_undef) {
      nid = OBJ_ln2nid(s);
    }

    if (nid != NID_undef) {
      return (ASN1_OBJECT*) OBJ_nid2obj(nid);
    }
  }

  /* Work out size of content octets */
  contents_len = a2d_ASN1_OBJECT(NULL, 0, s, -1);
  if (contents_len <= 0) {
    return NULL;
  }
  /* Work out total size */
  total_len = ASN1_object_size(0, contents_len, V_ASN1_OBJECT);

  buf = OPENSSL_malloc(total_len);
  if (buf == NULL) {
    OPENSSL_PUT_ERROR(OBJ, OBJ_txt2obj, ERR_R_MALLOC_FAILURE);
    return NULL;
  }

  p = buf;
  /* Write out tag+length */
  ASN1_put_object(&p, 0, contents_len, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
  /* Write out contents */
  a2d_ASN1_OBJECT(p, contents_len, s, -1);

  bufp = buf;
  op = d2i_ASN1_OBJECT(NULL, &bufp, total_len);
  OPENSSL_free(buf);

  return op;
}

int OBJ_obj2txt(char *out, int out_len, const ASN1_OBJECT *obj, int dont_return_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 (out && out_len > 0) {
    out[0] = 0;
  }

  if (obj == NULL || obj->data == NULL) {
    return 0;
  }

  if (!dont_return_name && (nid = OBJ_obj2nid(obj)) != NID_undef) {
    const char *s;
    s = OBJ_nid2ln(nid);
    if (s == NULL) {
      s = OBJ_nid2sn(nid);
    }
    if (s) {
      if (out) {
        BUF_strlcpy(out, s, out_len);
      }
      return strlen(s);
    }
  }

  len = obj->length;
  p = obj->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 (out && out_len > 1) {
        *out++ = i + '0';
        *out = '0';
        out_len--;
      }
      n++;
    }

    if (use_bn) {
      char *bndec;
      bndec = BN_bn2dec(bl);
      if (!bndec) {
        goto err;
      }
      i = strlen(bndec);
      if (out) {
        if (out_len > 1) {
          *out++ = '.';
          *out = 0;
          out_len--;
        }
        BUF_strlcpy(out, bndec, out_len);
        if (i > out_len) {
          out += out_len;
          out_len = 0;
        } else {
          out += i;
          out_len -= i;
        }
      }
      n++;
      n += i;
      OPENSSL_free(bndec);
    } else {
      BIO_snprintf(tbuf, sizeof(tbuf), ".%lu", l);
      i = strlen(tbuf);
      if (out && out_len > 0) {
        BUF_strlcpy(out, tbuf, out_len);
        if (i > out_len) {
          out += out_len;
          out_len = 0;
        } else {
          out += i;
          out_len -= i;
        }
      }
      n += i;
    }
  }

  if (bl) {
    BN_free(bl);
  }
  return n;

err:
  if (bl) {
    BN_free(bl);
  }
  return -1;
}

static uint32_t hash_nid(const ASN1_OBJECT *obj) {
  return obj->nid;
}

static int cmp_nid(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {
  return a->nid - b->nid;
}

static uint32_t hash_data(const ASN1_OBJECT *obj) {
  return OPENSSL_hash32(obj->data, obj->length);
}

static int cmp_data(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {
  int i = a->length - b->length;
  if (i) {
    return i;
  }
  return memcmp(a->data, b->data, a->length);
}

static uint32_t hash_short_name(const ASN1_OBJECT *obj) {
  return lh_strhash(obj->sn);
}

static int cmp_short_name(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {
  return strcmp(a->sn, b->sn);
}

static uint32_t hash_long_name(const ASN1_OBJECT *obj) {
  return lh_strhash(obj->ln);
}

static int cmp_long_name(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {
  return strcmp(a->ln, b->ln);
}

/* obj_add_object inserts |obj| into the various global hashes for run-time
 * added objects. It returns one on success or zero otherwise. */
static int obj_add_object(ASN1_OBJECT *obj) {
  int ok;
  ASN1_OBJECT *old_object;

  obj->flags &= ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
                  ASN1_OBJECT_FLAG_DYNAMIC_DATA);

  CRYPTO_w_lock(CRYPTO_LOCK_OBJ);
  if (global_added_by_nid == NULL) {
    global_added_by_nid = lh_ASN1_OBJECT_new(hash_nid, cmp_nid);
    global_added_by_data = lh_ASN1_OBJECT_new(hash_data, cmp_data);
    global_added_by_short_name = lh_ASN1_OBJECT_new(hash_short_name, cmp_short_name);
    global_added_by_long_name = lh_ASN1_OBJECT_new(hash_long_name, cmp_long_name);
  }

  /* We don't pay attention to |old_object| (which contains any previous object
   * that was evicted from the hashes) because we don't have a reference count
   * on ASN1_OBJECT values. Also, we should never have duplicates nids and so
   * should always have objects in |global_added_by_nid|. */

  ok = lh_ASN1_OBJECT_insert(global_added_by_nid, &old_object, obj);
  if (obj->length != 0 && obj->data != NULL) {
    ok &= lh_ASN1_OBJECT_insert(global_added_by_data, &old_object, obj);
  }
  if (obj->sn != NULL) {
    ok &= lh_ASN1_OBJECT_insert(global_added_by_short_name, &old_object, obj);
  }
  if (obj->ln != NULL) {
    ok &= lh_ASN1_OBJECT_insert(global_added_by_long_name, &old_object, obj);
  }
  CRYPTO_w_unlock(CRYPTO_LOCK_OBJ);

  return ok;
}

int OBJ_create(const char *oid, const char *short_name, const char *long_name) {
  int ret = NID_undef;
  ASN1_OBJECT *op = NULL;
  unsigned char *buf = NULL;
  int len;

  len = a2d_ASN1_OBJECT(NULL, 0, oid, -1);
  if (len <= 0) {
    goto err;
  }

  buf = OPENSSL_malloc(len);
  if (buf == NULL) {
    OPENSSL_PUT_ERROR(OBJ, OBJ_create, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  len = a2d_ASN1_OBJECT(buf, len, oid, -1);
  if (len == 0) {
    goto err;
  }

  op = (ASN1_OBJECT *)ASN1_OBJECT_create(obj_next_nid(), buf, len, short_name,
                                         long_name);
  if (op == NULL) {
    goto err;
  }

  if (obj_add_object(op)) {
    ret = op->nid;
  }
  op = NULL;

err:
  if (op != NULL) {
    ASN1_OBJECT_free(op);
  }
  if (buf != NULL) {
    OPENSSL_free(buf);
  }

  return ret;
}
