/* tasn_enc.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
 * project 2000.
 */
/* ====================================================================
 * Copyright (c) 2000-2004 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 <stddef.h>
#include <string.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>

static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
					const ASN1_ITEM *it,
					int tag, int aclass);
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
					int skcontlen, const ASN1_ITEM *item,
					int do_sort, int iclass);
static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
					const ASN1_TEMPLATE *tt,
					int tag, int aclass);
static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
					const ASN1_ITEM *it, int flags);

/* Top level i2d equivalents: the 'ndef' variant instructs the encoder
 * to use indefinite length constructed encoding, where appropriate
 */

int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out,
						const ASN1_ITEM *it)
	{
	return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
	}

int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
	{
	return asn1_item_flags_i2d(val, out, it, 0);
	}

/* Encode an ASN1 item, this is use by the
 * standard 'i2d' function. 'out' points to 
 * a buffer to output the data to.
 *
 * The new i2d has one additional feature. If the output
 * buffer is NULL (i.e. *out == NULL) then a buffer is
 * allocated and populated with the encoding.
 */

static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
					const ASN1_ITEM *it, int flags)
	{
	if (out && !*out)
		{
		unsigned char *p, *buf;
		int len;
		len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
		if (len <= 0)
			return len;
		buf = OPENSSL_malloc(len);
		if (!buf)
			return -1;
		p = buf;
		ASN1_item_ex_i2d(&val, &p, it, -1, flags);
		*out = buf;
		return len;
		}

	return ASN1_item_ex_i2d(&val, out, it, -1, flags);
	}

/* Encode an item, taking care of IMPLICIT tagging (if any).
 * This function performs the normal item handling: it can be
 * used in external types.
 */

int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
			const ASN1_ITEM *it, int tag, int aclass)
	{
	const ASN1_TEMPLATE *tt = NULL;
	unsigned char *p = NULL;
	int i, seqcontlen, seqlen, ndef = 1;
	const ASN1_COMPAT_FUNCS *cf;
	const ASN1_EXTERN_FUNCS *ef;
	const ASN1_AUX *aux = it->funcs;
	ASN1_aux_cb *asn1_cb = 0;

	if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
		return 0;

	if (aux && aux->asn1_cb)
		 asn1_cb = aux->asn1_cb;

	switch(it->itype)
		{

		case ASN1_ITYPE_PRIMITIVE:
		if (it->templates)
			return asn1_template_ex_i2d(pval, out, it->templates,
								tag, aclass);
		return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
		break;

		case ASN1_ITYPE_MSTRING:
		return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);

		case ASN1_ITYPE_CHOICE:
		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
				return 0;
		i = asn1_get_choice_selector(pval, it);
		if ((i >= 0) && (i < it->tcount))
			{
			ASN1_VALUE **pchval;
			const ASN1_TEMPLATE *chtt;
			chtt = it->templates + i;
			pchval = asn1_get_field_ptr(pval, chtt);
			return asn1_template_ex_i2d(pchval, out, chtt,
								-1, aclass);
			}
		/* Fixme: error condition if selector out of range */
		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
				return 0;
		break;

		case ASN1_ITYPE_EXTERN:
		/* If new style i2d it does all the work */
		ef = it->funcs;
		return ef->asn1_ex_i2d(pval, out, it, tag, aclass);

		case ASN1_ITYPE_COMPAT:
		/* old style hackery... */
		cf = it->funcs;
		if (out)
			p = *out;
		i = cf->asn1_i2d(*pval, out);
		/* Fixup for IMPLICIT tag: note this messes up for tags > 30,
		 * but so did the old code. Tags > 30 are very rare anyway.
		 */
		if (out && (tag != -1))
			*p = aclass | tag | (*p & V_ASN1_CONSTRUCTED);
		return i;
		
		case ASN1_ITYPE_NDEF_SEQUENCE:
		/* Use indefinite length constructed if requested */
		if (aclass & ASN1_TFLG_NDEF) ndef = 2;
		/* fall through */

		case ASN1_ITYPE_SEQUENCE:
		i = asn1_enc_restore(&seqcontlen, out, pval, it);
		/* An error occurred */
		if (i < 0)
			return 0;
		/* We have a valid cached encoding... */
		if (i > 0)
			return seqcontlen;
		/* Otherwise carry on */
		seqcontlen = 0;
		/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
		if (tag == -1)
			{
			tag = V_ASN1_SEQUENCE;
			/* Retain any other flags in aclass */
			aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
					| V_ASN1_UNIVERSAL;
			}
		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
				return 0;
		/* First work out sequence content length */
		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
			{
			const ASN1_TEMPLATE *seqtt;
			ASN1_VALUE **pseqval;
			seqtt = asn1_do_adb(pval, tt, 1);
			if (!seqtt)
				return 0;
			pseqval = asn1_get_field_ptr(pval, seqtt);
			/* FIXME: check for errors in enhanced version */
			seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,
								-1, aclass);
			}

		seqlen = ASN1_object_size(ndef, seqcontlen, tag);
		if (!out)
			return seqlen;
		/* Output SEQUENCE header */
		ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
			{
			const ASN1_TEMPLATE *seqtt;
			ASN1_VALUE **pseqval;
			seqtt = asn1_do_adb(pval, tt, 1);
			if (!seqtt)
				return 0;
			pseqval = asn1_get_field_ptr(pval, seqtt);
			/* FIXME: check for errors in enhanced version */
			asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
			}
		if (ndef == 2)
			ASN1_put_eoc(out);
		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
				return 0;
		return seqlen;

		default:
		return 0;

		}
	return 0;
	}

int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out,
							const ASN1_TEMPLATE *tt)
	{
	return asn1_template_ex_i2d(pval, out, tt, -1, 0);
	}

static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
				const ASN1_TEMPLATE *tt, int tag, int iclass)
	{
	int i, ret, flags, ttag, tclass, ndef;
	flags = tt->flags;
	/* Work out tag and class to use: tagging may come
	 * either from the template or the arguments, not both
	 * because this would create ambiguity. Additionally
	 * the iclass argument may contain some additional flags
	 * which should be noted and passed down to other levels.
	 */
	if (flags & ASN1_TFLG_TAG_MASK)
		{
		/* Error if argument and template tagging */
		if (tag != -1)
			/* FIXME: error code here */
			return -1;
		/* Get tagging from template */
		ttag = tt->tag;
		tclass = flags & ASN1_TFLG_TAG_CLASS;
		}
	else if (tag != -1)
		{
		/* No template tagging, get from arguments */
		ttag = tag;
		tclass = iclass & ASN1_TFLG_TAG_CLASS;
		}
	else
		{
		ttag = -1;
		tclass = 0;
		}
	/* 
	 * Remove any class mask from iflag.
	 */
	iclass &= ~ASN1_TFLG_TAG_CLASS;

	/* At this point 'ttag' contains the outer tag to use,
	 * 'tclass' is the class and iclass is any flags passed
	 * to this function.
	 */

	/* if template and arguments require ndef, use it */
	if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))
		ndef = 2;
	else ndef = 1;

	if (flags & ASN1_TFLG_SK_MASK)
		{
		/* SET OF, SEQUENCE OF */
		STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
		int isset, sktag, skaclass;
		int skcontlen, sklen;
		ASN1_VALUE *skitem;

		if (!*pval)
			return 0;

		if (flags & ASN1_TFLG_SET_OF)
			{
			isset = 1;
			/* 2 means we reorder */
			if (flags & ASN1_TFLG_SEQUENCE_OF)
				isset = 2;
			}
		else isset = 0;

		/* Work out inner tag value: if EXPLICIT
		 * or no tagging use underlying type.
		 */
		if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG))
			{
			sktag = ttag;
			skaclass = tclass;
			}
		else
			{
			skaclass = V_ASN1_UNIVERSAL;
			if (isset)
				sktag = V_ASN1_SET;
			else sktag = V_ASN1_SEQUENCE;
			}

		/* Determine total length of items */
		skcontlen = 0;
		for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
			{
			skitem = sk_ASN1_VALUE_value(sk, i);
			skcontlen += ASN1_item_ex_i2d(&skitem, NULL,
						ASN1_ITEM_ptr(tt->item),
							-1, iclass);
			}
		sklen = ASN1_object_size(ndef, skcontlen, sktag);
		/* If EXPLICIT need length of surrounding tag */
		if (flags & ASN1_TFLG_EXPTAG)
			ret = ASN1_object_size(ndef, sklen, ttag);
		else ret = sklen;

		if (!out)
			return ret;

		/* Now encode this lot... */
		/* EXPLICIT tag */
		if (flags & ASN1_TFLG_EXPTAG)
			ASN1_put_object(out, ndef, sklen, ttag, tclass);
		/* SET or SEQUENCE and IMPLICIT tag */
		ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
		/* And the stuff itself */
		asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item),
								isset, iclass);
		if (ndef == 2)
			{
			ASN1_put_eoc(out);
			if (flags & ASN1_TFLG_EXPTAG)
				ASN1_put_eoc(out);
			}

		return ret;
		}

	if (flags & ASN1_TFLG_EXPTAG)
		{
		/* EXPLICIT tagging */
		/* Find length of tagged item */
		i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item),
								-1, iclass);
		if (!i)
			return 0;
		/* Find length of EXPLICIT tag */
		ret = ASN1_object_size(ndef, i, ttag);
		if (out)
			{
			/* Output tag and item */
			ASN1_put_object(out, ndef, i, ttag, tclass);
			ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
								-1, iclass);
			if (ndef == 2)
				ASN1_put_eoc(out);
			}
		return ret;
		}

	/* Either normal or IMPLICIT tagging: combine class and flags */
	return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
						ttag, tclass | iclass);

}

/* Temporary structure used to hold DER encoding of items for SET OF */

typedef	struct {
	unsigned char *data;
	int length;
	ASN1_VALUE *field;
} DER_ENC;

static int der_cmp(const void *a, const void *b)
	{
	const DER_ENC *d1 = a, *d2 = b;
	int cmplen, i;
	cmplen = (d1->length < d2->length) ? d1->length : d2->length;
	i = memcmp(d1->data, d2->data, cmplen);
	if (i)
		return i;
	return d1->length - d2->length;
	}

/* Output the content octets of SET OF or SEQUENCE OF */

static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
					int skcontlen, const ASN1_ITEM *item,
					int do_sort, int iclass)
	{
	int i;
	ASN1_VALUE *skitem;
	unsigned char *tmpdat = NULL, *p = NULL;
	DER_ENC *derlst = NULL, *tder;
	if (do_sort)
		 {
		/* Don't need to sort less than 2 items */
		if (sk_ASN1_VALUE_num(sk) < 2)
			do_sort = 0;
		else
			{
			derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk)
						* sizeof(*derlst));
			if (!derlst)
				return 0;
			tmpdat = OPENSSL_malloc(skcontlen);
			if (!tmpdat)
				{
				OPENSSL_free(derlst);
				return 0;
				}
			}
		}
	/* If not sorting just output each item */
	if (!do_sort)
		{
		for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
			{
			skitem = sk_ASN1_VALUE_value(sk, i);
			ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
			}
		return 1;
		}
	p = tmpdat;

	/* Doing sort: build up a list of each member's DER encoding */
	for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
		{
		skitem = sk_ASN1_VALUE_value(sk, i);
		tder->data = p;
		tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
		tder->field = skitem;
		}

	/* Now sort them */
	qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
	/* Output sorted DER encoding */	
	p = *out;
	for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
		{
		memcpy(p, tder->data, tder->length);
		p += tder->length;
		}
	*out = p;
	/* If do_sort is 2 then reorder the STACK */
	if (do_sort == 2)
		{
		for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk);
							i++, tder++)
			(void)sk_ASN1_VALUE_set(sk, i, tder->field);
		}
	OPENSSL_free(derlst);
	OPENSSL_free(tmpdat);
	return 1;
	}

static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
				const ASN1_ITEM *it, int tag, int aclass)
	{
	int len;
	int utype;
	int usetag;
	int ndef = 0;

	utype = it->utype;

	/* Get length of content octets and maybe find
	 * out the underlying type.
	 */

	len = asn1_ex_i2c(pval, NULL, &utype, it);

	/* If SEQUENCE, SET or OTHER then header is
	 * included in pseudo content octets so don't
	 * include tag+length. We need to check here
	 * because the call to asn1_ex_i2c() could change
	 * utype.
	 */
	if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) ||
	   (utype == V_ASN1_OTHER))
		usetag = 0;
	else usetag = 1;

	/* -1 means omit type */

	if (len == -1)
		return 0;

	/* -2 return is special meaning use ndef */
	if (len == -2)
		{
		ndef = 2;
		len = 0;
		}

	/* If not implicitly tagged get tag from underlying type */
	if (tag == -1) tag = utype;

	/* Output tag+length followed by content octets */
	if (out)
		{
		if (usetag)
			ASN1_put_object(out, ndef, len, tag, aclass);
		asn1_ex_i2c(pval, *out, &utype, it);
		if (ndef)
			ASN1_put_eoc(out);
		else
			*out += len;
		}

	if (usetag)
		return ASN1_object_size(ndef, len, tag);
	return len;
	}

/* Produce content octets from a structure */

int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
				const ASN1_ITEM *it)
	{
	ASN1_BOOLEAN *tbool = NULL;
	ASN1_STRING *strtmp;
	ASN1_OBJECT *otmp;
	int utype;
	const unsigned char *cont;
	unsigned char c;
	int len;
	const ASN1_PRIMITIVE_FUNCS *pf;
	pf = it->funcs;
	if (pf && pf->prim_i2c)
		return pf->prim_i2c(pval, cout, putype, it);

	/* Should type be omitted? */
	if ((it->itype != ASN1_ITYPE_PRIMITIVE)
		|| (it->utype != V_ASN1_BOOLEAN))
		{
		if (!*pval) return -1;
		}

	if (it->itype == ASN1_ITYPE_MSTRING)
		{
		/* If MSTRING type set the underlying type */
		strtmp = (ASN1_STRING *)*pval;
		utype = strtmp->type;
		*putype = utype;
		}
	else if (it->utype == V_ASN1_ANY)
		{
		/* If ANY set type and pointer to value */
		ASN1_TYPE *typ;
		typ = (ASN1_TYPE *)*pval;
		utype = typ->type;
		*putype = utype;
		pval = &typ->value.asn1_value;
		}
	else utype = *putype;

	switch(utype)
		{
		case V_ASN1_OBJECT:
		otmp = (ASN1_OBJECT *)*pval;
		cont = otmp->data;
		len = otmp->length;
		break;

		case V_ASN1_NULL:
		cont = NULL;
		len = 0;
		break;

		case V_ASN1_BOOLEAN:
		tbool = (ASN1_BOOLEAN *)pval;
		if (*tbool == -1)
			return -1;
		if (it->utype != V_ASN1_ANY)
			{
			/* Default handling if value == size field then omit */
			if (*tbool && (it->size > 0))
				return -1;
			if (!*tbool && !it->size)
				return -1;
			}
		c = (unsigned char)*tbool;
		cont = &c;
		len = 1;
		break;

		case V_ASN1_BIT_STRING:
		return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
							cout ? &cout : NULL);
		break;

		case V_ASN1_INTEGER:
		case V_ASN1_NEG_INTEGER:
		case V_ASN1_ENUMERATED:
		case V_ASN1_NEG_ENUMERATED:
		/* These are all have the same content format
		 * as ASN1_INTEGER
		 */
		return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval,
							cout ? &cout : NULL);
		break;

		case V_ASN1_OCTET_STRING:
		case V_ASN1_NUMERICSTRING:
		case V_ASN1_PRINTABLESTRING:
		case V_ASN1_T61STRING:
		case V_ASN1_VIDEOTEXSTRING:
		case V_ASN1_IA5STRING:
		case V_ASN1_UTCTIME:
		case V_ASN1_GENERALIZEDTIME:
		case V_ASN1_GRAPHICSTRING:
		case V_ASN1_VISIBLESTRING:
		case V_ASN1_GENERALSTRING:
		case V_ASN1_UNIVERSALSTRING:
		case V_ASN1_BMPSTRING:
		case V_ASN1_UTF8STRING:
		case V_ASN1_SEQUENCE:
		case V_ASN1_SET:
		default:
		/* All based on ASN1_STRING and handled the same */
		strtmp = (ASN1_STRING *)*pval;
		/* Special handling for NDEF */
		if ((it->size == ASN1_TFLG_NDEF)
			&& (strtmp->flags & ASN1_STRING_FLAG_NDEF))
			{
			if (cout)
				{
				strtmp->data = cout;
				strtmp->length = 0;
				}
			/* Special return code */
			return -2;
			}
		cont = strtmp->data;
		len = strtmp->length;

		break;

		}
	if (cout && len)
		memcpy(cout, cont, len);
	return len;
	}
