/* asn1_gen.c */
/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
 * project 2002.
 */
/* ====================================================================
 * Copyright (c) 2002 The OpenSSL Project.  All rights reserved.
 *
 * 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 above 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 acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED 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 OpenSSL PROJECT OR
 * ITS 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.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/x509v3.h>

#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
	{
	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;
	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)
			{
			ASN1err(ASN1_F_ASN1_GENERATE_V3, 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);

	/* 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)
		ASN1_put_object(&p, hdr_constructed, hdr_len,
					asn1_tags.imp_tag, asn1_tags.imp_class);

	/* Copy across original encoding */
	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;

	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)
		{
		ASN1err(ASN1_F_ASN1_CB, 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])
			{
			ASN1err(ASN1_F_ASN1_CB, 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)
			{
			ASN1err(ASN1_F_ASN1_CB, 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 (!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", 3))
			arg->format = ASN1_GEN_FORMAT_BITLIST;
		else
			{
			ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKOWN_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)
		{
		ASN1err(ASN1_F_PARSE_TAGGING, 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;
			ASN1err(ASN1_F_PARSE_TAGGING, 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, *typ = NULL;
	STACK_OF(ASN1_TYPE) *sk = NULL;
	STACK_OF(CONF_VALUE) *sect = NULL;
	unsigned char *der = NULL, *p;
	int derlen;
	int i, is_set;
	sk = sk_ASN1_TYPE_new_null();
	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++)
			{
			typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf);
			if (!typ)
				goto bad;
			sk_ASN1_TYPE_push(sk, typ);
			typ = NULL;
			}
		}

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

	if (utype == V_ASN1_SET)
		is_set = 1;
	else
		is_set = 0;


	derlen = i2d_ASN1_SET((STACK *)sk, NULL, i2d_ASN1_TYPE, utype, V_ASN1_UNIVERSAL, is_set);
	der = OPENSSL_malloc(derlen);
	p = der;
	i2d_ASN1_SET((STACK *)sk, &p, i2d_ASN1_TYPE, utype, V_ASN1_UNIVERSAL, is_set);

	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 (typ)
		ASN1_TYPE_free(typ);
	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)
		{
		ASN1err(ASN1_F_APPEND_TAG, ASN1_R_ILLEGAL_IMPLICIT_TAG);
		return 0;
		}

	if (arg->exp_count == ASN1_FLAG_EXP_MAX)
		{
		ASN1err(ASN1_F_APPEND_TAG, 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 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),

		/* 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()))
		{
		ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
		return NULL;
		}

	if (!str)
		str = "";

	switch(utype)
		{

		case V_ASN1_NULL:
		if (str && *str)
			{
			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE);
			goto bad_form;
			}
		break;
		
		case V_ASN1_BOOLEAN:
		if (format != ASN1_GEN_FORMAT_ASCII)
			{
			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT);
			goto bad_form;
			}
		vtmp.value = (char *)str;
		if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean))
			{
			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN);
			goto bad_str;
			}
		break;

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

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

		case V_ASN1_UTCTIME:
		case V_ASN1_GENERALIZEDTIME:
		if (format != ASN1_GEN_FORMAT_ASCII)
			{
			ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT);
			goto bad_form;
			}
		if (!(atmp->value.asn1_string = ASN1_STRING_new()))
			{
			ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
			goto bad_str;
			}
		if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1))
			{
			ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
			goto bad_str;
			}
		atmp->value.asn1_string->type = utype;
		if (!ASN1_TIME_check(atmp->value.asn1_string))
			{
			ASN1err(ASN1_F_ASN1_STR2TYPE, 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:

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


		if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str,
						-1, format, ASN1_tag2bit(utype)) <= 0)
			{
			ASN1err(ASN1_F_ASN1_STR2TYPE, 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()))
			{
			ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
			goto bad_form;
			}

		if (format == ASN1_GEN_FORMAT_HEX)
			{

			if (!(rdata = string_to_hex((char *)str, &rdlen)))
				{
				ASN1err(ASN1_F_ASN1_STR2TYPE, 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))
				{
				ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR);
				goto bad_str;
				}
			no_unused = 0;
			
			}
		else 
			{
			ASN1err(ASN1_F_ASN1_STR2TYPE, 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:
		ASN1err(ASN1_F_ASN1_STR2TYPE, 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)
		{
		ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER);
		return 0;
		}
	if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1))
		{
		ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE);
		return 0;
		}
	return 1;
	}

