/* 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);
	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 */
	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_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)
		{
		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;
	STACK_OF(ASN1_TYPE) *sk = NULL;
	STACK_OF(CONF_VALUE) *sect = NULL;
	unsigned char *der = NULL;
	int derlen;
	int 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)
		{
		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 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()))
		{
		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:
		case V_ASN1_NUMERICSTRING:

		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;
	}

static int mask_cb(const char *elem, int len, void *arg)
	{
	unsigned long *pmask = arg, tmpmask;
	int tag;
	if (len == 3 && !strncmp(elem, "DIR", 3))
		{
		*pmask |= B_ASN1_DIRECTORYSTRING;
		return 1;
		}
	tag = asn1_str2tag(elem, len);
	if (!tag || (tag & ASN1_GEN_FLAG))
		return 0;
	tmpmask = ASN1_tag2bit(tag);
	if (!tmpmask)
		return 0;
	*pmask |= tmpmask;
	return 1;
	}

int ASN1_str2mask(const char *str, unsigned long *pmask)
	{
	*pmask = 0;
	return CONF_parse_list(str, '|', 1, mask_cb, pmask);
	}
