/* 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/x509.h>

#include <string.h>

#include <openssl/asn1.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/x509v3.h>

#include "../internal.h"
#include "../x509v3/internal.h"
#include "internal.h"

/*
 * Although this file is in crypto/x509 for layering purposes, it emits
 * errors from the ASN.1 module for OpenSSL compatibility.
 */

#define ASN1_GEN_FLAG 0x10000
#define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG | 1)
#define ASN1_GEN_FLAG_EXP (ASN1_GEN_FLAG | 2)
#define ASN1_GEN_FLAG_TAG (ASN1_GEN_FLAG | 3)
#define ASN1_GEN_FLAG_BITWRAP (ASN1_GEN_FLAG | 4)
#define ASN1_GEN_FLAG_OCTWRAP (ASN1_GEN_FLAG | 5)
#define ASN1_GEN_FLAG_SEQWRAP (ASN1_GEN_FLAG | 6)
#define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG | 7)
#define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG | 8)

#define ASN1_GEN_STR(str, val) \
  { str, sizeof(str) - 1, val }

#define ASN1_FLAG_EXP_MAX 20
/* Maximum number of nested sequences */
#define ASN1_GEN_SEQ_MAX_DEPTH 50

/* Input formats */

/* ASCII: default */
#define ASN1_GEN_FORMAT_ASCII 1
/* UTF8 */
#define ASN1_GEN_FORMAT_UTF8 2
/* Hex */
#define ASN1_GEN_FORMAT_HEX 3
/* List of bits */
#define ASN1_GEN_FORMAT_BITLIST 4

struct tag_name_st {
  const char *strnam;
  int len;
  int tag;
};

typedef struct {
  int exp_tag;
  int exp_class;
  int exp_constructed;
  int exp_pad;
  long exp_len;
} tag_exp_type;

typedef struct {
  int imp_tag;
  int imp_class;
  int utype;
  int format;
  const char *str;
  tag_exp_type exp_list[ASN1_FLAG_EXP_MAX];
  int exp_count;
} tag_exp_arg;

static ASN1_TYPE *generate_v3(const char *str, X509V3_CTX *cnf, int depth,
                              int *perr);
static int bitstr_cb(const char *elem, int len, void *bitstr);
static int asn1_cb(const char *elem, int len, void *bitstr);
static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class,
                      int exp_constructed, int exp_pad, int imp_ok);
static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass);
static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf,
                             int depth, int *perr);
static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype);
static int asn1_str2tag(const char *tagstr, int len);

ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf) {
  int err = 0;
  ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err);
  if (err) {
    OPENSSL_PUT_ERROR(ASN1, err);
  }
  return ret;
}

static ASN1_TYPE *generate_v3(const char *str, X509V3_CTX *cnf, int depth,
                              int *perr) {
  ASN1_TYPE *ret;
  tag_exp_arg asn1_tags;
  tag_exp_type *etmp;

  int i, len;

  unsigned char *orig_der = NULL, *new_der = NULL;
  const unsigned char *cpy_start;
  unsigned char *p;
  const unsigned char *cp;
  int cpy_len;
  long hdr_len = 0;
  int hdr_constructed = 0, hdr_tag, hdr_class;
  int r;

  asn1_tags.imp_tag = -1;
  asn1_tags.imp_class = -1;
  asn1_tags.format = ASN1_GEN_FORMAT_ASCII;
  asn1_tags.exp_count = 0;
  if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) {
    *perr = ASN1_R_UNKNOWN_TAG;
    return NULL;
  }

  if ((asn1_tags.utype == V_ASN1_SEQUENCE) || (asn1_tags.utype == V_ASN1_SET)) {
    if (!cnf) {
      *perr = ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG;
      return NULL;
    }
    if (depth >= ASN1_GEN_SEQ_MAX_DEPTH) {
      *perr = ASN1_R_ILLEGAL_NESTED_TAGGING;
      return NULL;
    }
    ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf, depth, perr);
  } else {
    ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);
  }

  if (!ret) {
    return NULL;
  }

  /* If no tagging return base type */
  if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0)) {
    return ret;
  }

  /* Generate the encoding */
  cpy_len = i2d_ASN1_TYPE(ret, &orig_der);
  ASN1_TYPE_free(ret);
  ret = NULL;
  /* Set point to start copying for modified encoding */
  cpy_start = orig_der;

  /* Do we need IMPLICIT tagging? */
  if (asn1_tags.imp_tag != -1) {
    /* If IMPLICIT we will replace the underlying tag */
    /* Skip existing tag+len */
    r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, cpy_len);
    if (r & 0x80) {
      goto err;
    }
    /* Update copy length */
    cpy_len -= cpy_start - orig_der;
    /*
     * For IMPLICIT tagging the length should match the original length
     * and constructed flag should be consistent.
     */
    hdr_constructed = r & V_ASN1_CONSTRUCTED;
    /*
     * Work out new length with IMPLICIT tag: ignore constructed because
     * it will mess up if indefinite length
     */
    len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag);
  } else {
    len = cpy_len;
  }

  /* Work out length in any EXPLICIT, starting from end */

  for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1;
       i < asn1_tags.exp_count; i++, etmp--) {
    /* Content length: number of content octets + any padding */
    len += etmp->exp_pad;
    etmp->exp_len = len;
    /* Total object length: length including new header */
    len = ASN1_object_size(0, len, etmp->exp_tag);
  }

  /* Allocate buffer for new encoding */

  new_der = OPENSSL_malloc(len);
  if (!new_der) {
    goto err;
  }

  /* Generate tagged encoding */

  p = new_der;

  /* Output explicit tags first */

  for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; i++, etmp++) {
    ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len, etmp->exp_tag,
                    etmp->exp_class);
    if (etmp->exp_pad) {
      *p++ = 0;
    }
  }

  /* If IMPLICIT, output tag */

  if (asn1_tags.imp_tag != -1) {
    if (asn1_tags.imp_class == V_ASN1_UNIVERSAL &&
        (asn1_tags.imp_tag == V_ASN1_SEQUENCE ||
         asn1_tags.imp_tag == V_ASN1_SET)) {
      hdr_constructed = V_ASN1_CONSTRUCTED;
    }
    ASN1_put_object(&p, hdr_constructed, hdr_len, asn1_tags.imp_tag,
                    asn1_tags.imp_class);
  }

  /* Copy across original encoding */
  OPENSSL_memcpy(p, cpy_start, cpy_len);

  cp = new_der;

  /* Obtain new ASN1_TYPE structure */
  ret = d2i_ASN1_TYPE(NULL, &cp, len);

err:
  if (orig_der) {
    OPENSSL_free(orig_der);
  }
  if (new_der) {
    OPENSSL_free(new_der);
  }

  return ret;
}

static int asn1_cb(const char *elem, int len, void *bitstr) {
  tag_exp_arg *arg = bitstr;
  int i;
  int utype;
  int vlen = 0;
  const char *p, *vstart = NULL;

  int tmp_tag, tmp_class;

  if (elem == NULL) {
    return -1;
  }

  for (i = 0, p = elem; i < len; p++, i++) {
    /* Look for the ':' in name value pairs */
    if (*p == ':') {
      vstart = p + 1;
      vlen = len - (vstart - elem);
      len = p - elem;
      break;
    }
  }

  utype = asn1_str2tag(elem, len);

  if (utype == -1) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_TAG);
    ERR_add_error_data(2, "tag=", elem);
    return -1;
  }

  /* If this is not a modifier mark end of string and exit */
  if (!(utype & ASN1_GEN_FLAG)) {
    arg->utype = utype;
    arg->str = vstart;
    /* If no value and not end of string, error */
    if (!vstart && elem[len]) {
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE);
      return -1;
    }
    return 0;
  }

  switch (utype) {
    case ASN1_GEN_FLAG_IMP:
      /* Check for illegal multiple IMPLICIT tagging */
      if (arg->imp_tag != -1) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING);
        return -1;
      }
      if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class)) {
        return -1;
      }
      break;

    case ASN1_GEN_FLAG_EXP:

      if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class)) {
        return -1;
      }
      if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0)) {
        return -1;
      }
      break;

    case ASN1_GEN_FLAG_SEQWRAP:
      if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1)) {
        return -1;
      }
      break;

    case ASN1_GEN_FLAG_SETWRAP:
      if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1)) {
        return -1;
      }
      break;

    case ASN1_GEN_FLAG_BITWRAP:
      if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1)) {
        return -1;
      }
      break;

    case ASN1_GEN_FLAG_OCTWRAP:
      if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1)) {
        return -1;
      }
      break;

    case ASN1_GEN_FLAG_FORMAT:
      if (!vstart) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
        return -1;
      }
      if (!strncmp(vstart, "ASCII", 5)) {
        arg->format = ASN1_GEN_FORMAT_ASCII;
      } else if (!strncmp(vstart, "UTF8", 4)) {
        arg->format = ASN1_GEN_FORMAT_UTF8;
      } else if (!strncmp(vstart, "HEX", 3)) {
        arg->format = ASN1_GEN_FORMAT_HEX;
      } else if (!strncmp(vstart, "BITLIST", 7)) {
        arg->format = ASN1_GEN_FORMAT_BITLIST;
      } else {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
        return -1;
      }
      break;
  }

  return 1;
}

static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) {
  char erch[2];
  long tag_num;
  char *eptr;
  if (!vstart) {
    return 0;
  }
  tag_num = strtoul(vstart, &eptr, 10);
  /* Check we haven't gone past max length: should be impossible */
  if (eptr && *eptr && (eptr > vstart + vlen)) {
    return 0;
  }
  if (tag_num < 0) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER);
    return 0;
  }
  *ptag = tag_num;
  /* If we have non numeric characters, parse them */
  if (eptr) {
    vlen -= eptr - vstart;
  } else {
    vlen = 0;
  }
  if (vlen) {
    switch (*eptr) {
      case 'U':
        *pclass = V_ASN1_UNIVERSAL;
        break;

      case 'A':
        *pclass = V_ASN1_APPLICATION;
        break;

      case 'P':
        *pclass = V_ASN1_PRIVATE;
        break;

      case 'C':
        *pclass = V_ASN1_CONTEXT_SPECIFIC;
        break;

      default:
        erch[0] = *eptr;
        erch[1] = 0;
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_MODIFIER);
        ERR_add_error_data(2, "Char=", erch);
        return 0;
        break;
    }
  } else {
    *pclass = V_ASN1_CONTEXT_SPECIFIC;
  }

  return 1;
}

/* Handle multiple types: SET and SEQUENCE */

static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf,
                             int depth, int *perr) {
  ASN1_TYPE *ret = NULL;
  STACK_OF(ASN1_TYPE) *sk = NULL;
  STACK_OF(CONF_VALUE) *sect = NULL;
  unsigned char *der = NULL;
  int derlen;
  size_t i;
  sk = sk_ASN1_TYPE_new_null();
  if (!sk) {
    goto bad;
  }
  if (section) {
    if (!cnf) {
      goto bad;
    }
    sect = X509V3_get_section(cnf, (char *)section);
    if (!sect) {
      goto bad;
    }
    for (i = 0; i < sk_CONF_VALUE_num(sect); i++) {
      ASN1_TYPE *typ = generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf,
                                   depth + 1, perr);
      if (!typ) {
        goto bad;
      }
      if (!sk_ASN1_TYPE_push(sk, typ)) {
        goto bad;
      }
    }
  }

  /*
   * Now we has a STACK of the components, convert to the correct form
   */

  if (utype == V_ASN1_SET) {
    derlen = i2d_ASN1_SET_ANY(sk, &der);
  } else {
    derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);
  }

  if (derlen < 0) {
    goto bad;
  }

  if (!(ret = ASN1_TYPE_new())) {
    goto bad;
  }

  if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype))) {
    goto bad;
  }

  ret->type = utype;

  ret->value.asn1_string->data = der;
  ret->value.asn1_string->length = derlen;

  der = NULL;

bad:

  if (der) {
    OPENSSL_free(der);
  }

  if (sk) {
    sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
  }
  if (sect) {
    X509V3_section_free(cnf, sect);
  }

  return ret;
}

static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class,
                      int exp_constructed, int exp_pad, int imp_ok) {
  tag_exp_type *exp_tmp;
  /* Can only have IMPLICIT if permitted */
  if ((arg->imp_tag != -1) && !imp_ok) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_IMPLICIT_TAG);
    return 0;
  }

  if (arg->exp_count == ASN1_FLAG_EXP_MAX) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_DEPTH_EXCEEDED);
    return 0;
  }

  exp_tmp = &arg->exp_list[arg->exp_count++];

  /*
   * If IMPLICIT set tag to implicit value then reset implicit tag since it
   * has been used.
   */
  if (arg->imp_tag != -1) {
    exp_tmp->exp_tag = arg->imp_tag;
    exp_tmp->exp_class = arg->imp_class;
    arg->imp_tag = -1;
    arg->imp_class = -1;
  } else {
    exp_tmp->exp_tag = exp_tag;
    exp_tmp->exp_class = exp_class;
  }
  exp_tmp->exp_constructed = exp_constructed;
  exp_tmp->exp_pad = exp_pad;

  return 1;
}

static int asn1_str2tag(const char *tagstr, int len) {
  unsigned int i;
  static const struct tag_name_st *tntmp,
      tnst[] = {
          ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN),
          ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN),
          ASN1_GEN_STR("NULL", V_ASN1_NULL),
          ASN1_GEN_STR("INT", V_ASN1_INTEGER),
          ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER),
          ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED),
          ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED),
          ASN1_GEN_STR("OID", V_ASN1_OBJECT),
          ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT),
          ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME),
          ASN1_GEN_STR("UTC", V_ASN1_UTCTIME),
          ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME),
          ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME),
          ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING),
          ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING),
          ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING),
          ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING),
          ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING),
          ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING),
          ASN1_GEN_STR("IA5", V_ASN1_IA5STRING),
          ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING),
          ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING),
          ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING),
          ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING),
          ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING),
          ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING),
          ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING),
          ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING),
          ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING),
          ASN1_GEN_STR("T61", V_ASN1_T61STRING),
          ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING),
          ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING),
          ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING),
          ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING),
          ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING),
          ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING),

          /* Special cases */
          ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE),
          ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE),
          ASN1_GEN_STR("SET", V_ASN1_SET),
          /* type modifiers */
          /* Explicit tag */
          ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP),
          ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP),
          /* Implicit tag */
          ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP),
          ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP),
          /* OCTET STRING wrapper */
          ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP),
          /* SEQUENCE wrapper */
          ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP),
          /* SET wrapper */
          ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP),
          /* BIT STRING wrapper */
          ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP),
          ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT),
          ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT),
      };

  if (len == -1) {
    len = strlen(tagstr);
  }

  tntmp = tnst;
  for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++) {
    if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len)) {
      return tntmp->tag;
    }
  }

  return -1;
}

static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) {
  ASN1_TYPE *atmp = NULL;

  CONF_VALUE vtmp;

  unsigned char *rdata;
  long rdlen;

  int no_unused = 1;

  if (!(atmp = ASN1_TYPE_new())) {
    OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
    return NULL;
  }

  if (!str) {
    str = "";
  }

  switch (utype) {
    case V_ASN1_NULL:
      if (str && *str) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL_VALUE);
        goto bad_form;
      }
      break;

    case V_ASN1_BOOLEAN:
      if (format != ASN1_GEN_FORMAT_ASCII) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ASCII_FORMAT);
        goto bad_form;
      }
      vtmp.name = NULL;
      vtmp.section = NULL;
      vtmp.value = (char *)str;
      if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BOOLEAN);
        goto bad_str;
      }
      break;

    case V_ASN1_INTEGER:
    case V_ASN1_ENUMERATED:
      if (format != ASN1_GEN_FORMAT_ASCII) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
        goto bad_form;
      }
      if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_INTEGER);
        goto bad_str;
      }
      break;

    case V_ASN1_OBJECT:
      if (format != ASN1_GEN_FORMAT_ASCII) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
        goto bad_form;
      }
      if (!(atmp->value.object = OBJ_txt2obj(str, 0))) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT);
        goto bad_str;
      }
      break;

    case V_ASN1_UTCTIME:
    case V_ASN1_GENERALIZEDTIME:
      if (format != ASN1_GEN_FORMAT_ASCII) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_TIME_NOT_ASCII_FORMAT);
        goto bad_form;
      }
      if (!(atmp->value.asn1_string = ASN1_STRING_new())) {
        OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
        goto bad_str;
      }
      if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) {
        OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
        goto bad_str;
      }
      atmp->value.asn1_string->type = utype;
      if (!ASN1_TIME_check(atmp->value.asn1_string)) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TIME_VALUE);
        goto bad_str;
      }

      break;

    case V_ASN1_BMPSTRING:
    case V_ASN1_PRINTABLESTRING:
    case V_ASN1_IA5STRING:
    case V_ASN1_T61STRING:
    case V_ASN1_UTF8STRING:
    case V_ASN1_VISIBLESTRING:
    case V_ASN1_UNIVERSALSTRING:
    case V_ASN1_GENERALSTRING:
    case V_ASN1_NUMERICSTRING:

      if (format == ASN1_GEN_FORMAT_ASCII) {
        format = MBSTRING_ASC;
      } else if (format == ASN1_GEN_FORMAT_UTF8) {
        format = MBSTRING_UTF8;
      } else {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_FORMAT);
        goto bad_form;
      }

      if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str, -1,
                             format, ASN1_tag2bit(utype)) <= 0) {
        OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
        goto bad_str;
      }

      break;

    case V_ASN1_BIT_STRING:

    case V_ASN1_OCTET_STRING:

      if (!(atmp->value.asn1_string = ASN1_STRING_new())) {
        OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
        goto bad_form;
      }

      if (format == ASN1_GEN_FORMAT_HEX) {
        if (!(rdata = x509v3_hex_to_bytes((char *)str, &rdlen))) {
          OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_HEX);
          goto bad_str;
        }

        atmp->value.asn1_string->data = rdata;
        atmp->value.asn1_string->length = rdlen;
        atmp->value.asn1_string->type = utype;

      } else if (format == ASN1_GEN_FORMAT_ASCII) {
        ASN1_STRING_set(atmp->value.asn1_string, str, -1);
      } else if ((format == ASN1_GEN_FORMAT_BITLIST) &&
                 (utype == V_ASN1_BIT_STRING)) {
        if (!CONF_parse_list(str, ',', 1, bitstr_cb, atmp->value.bit_string)) {
          OPENSSL_PUT_ERROR(ASN1, ASN1_R_LIST_ERROR);
          goto bad_str;
        }
        no_unused = 0;

      } else {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
        goto bad_form;
      }

      if ((utype == V_ASN1_BIT_STRING) && no_unused) {
        atmp->value.asn1_string->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
        atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT;
      }

      break;

    default:
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_TYPE);
      goto bad_str;
      break;
  }

  atmp->type = utype;
  return atmp;

bad_str:
  ERR_add_error_data(2, "string=", str);
bad_form:

  ASN1_TYPE_free(atmp);
  return NULL;
}

static int bitstr_cb(const char *elem, int len, void *bitstr) {
  long bitnum;
  char *eptr;
  if (!elem) {
    return 0;
  }
  bitnum = strtoul(elem, &eptr, 10);
  if (eptr && *eptr && (eptr != elem + len)) {
    return 0;
  }
  if (bitnum < 0) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER);
    return 0;
  }
  if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) {
    OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
    return 0;
  }
  return 1;
}
