/* asn1_gen.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) 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
	{
	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;
	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_OF_ASN1_TYPE(sk, NULL, i2d_ASN1_TYPE, utype,
					   V_ASN1_UNIVERSAL, is_set);
	der = OPENSSL_malloc(derlen);
	p = der;
	i2d_ASN1_SET_OF_ASN1_TYPE(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_EXP, ASN1_R_ILLEGAL_IMPLICIT_TAG);
		return 0;
		}

	if (arg->exp_count == ASN1_FLAG_EXP_MAX)
		{
		ASN1err(ASN1_F_APPEND_EXP, 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.name = NULL;
		vtmp.section = NULL;
		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;
	}

