/* 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"

/*
 * 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

/* 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 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);
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_nconf(char *str, CONF *nconf)
{
    X509V3_CTX cnf;

    if (!nconf)
        return ASN1_generate_v3(str, NULL);

    X509V3_set_nconf(&cnf, nconf);
    return ASN1_generate_v3(str, &cnf);
}

ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
{
    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)
        return NULL;

    if ((asn1_tags.utype == V_ASN1_SEQUENCE)
        || (asn1_tags.utype == V_ASN1_SET)) {
        if (!cnf) {
            OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
            return NULL;
        }
        ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
    } 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.
         */
        if (r & 0x1) {
            /* Indefinite length constructed */
            hdr_constructed = 2;
            hdr_len = 0;
        } else
            /* Just retain constructed flag */
            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 0;

    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)
{
    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 =
                ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf);
            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 = string_to_hex((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;
}
