/* 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/asn1.h>

#include <time.h>

#include <openssl/asn1t.h>
#include <openssl/err.h>
#include <openssl/obj.h>
#include <openssl/mem.h>

#include "asn1_locl.h"



/* Print routines.
 */

/* ASN1_PCTX routines */

static ASN1_PCTX default_pctx = 
	{
	ASN1_PCTX_FLAGS_SHOW_ABSENT,	/* flags */
	0,	/* nm_flags */
	0,	/* cert_flags */
	0,	/* oid_flags */
	0	/* str_flags */
	};
	

ASN1_PCTX *ASN1_PCTX_new(void)
	{
	ASN1_PCTX *ret;
	ret = OPENSSL_malloc(sizeof(ASN1_PCTX));
	if (ret == NULL)
		{
		OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
		return NULL;
		}
	ret->flags = 0;
	ret->nm_flags = 0;
	ret->cert_flags = 0;
	ret->oid_flags = 0;
	ret->str_flags = 0;
	return ret;
	}

void ASN1_PCTX_free(ASN1_PCTX *p)
	{
	OPENSSL_free(p);
	}

unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p)
	{
	return p->flags;
	}

void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
	{
	p->flags = flags;
	}

unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p)
	{
	return p->nm_flags;
	}

void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
	{
	p->nm_flags = flags;
	}

unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p)
	{
	return p->cert_flags;
	}

void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
	{
	p->cert_flags = flags;
	}

unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p)
	{
	return p->oid_flags;
	}

void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
	{
	p->oid_flags = flags;
	}

unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p)
	{
	return p->str_flags;
	}

void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
	{
	p->str_flags = flags;
	}

/* Main print routines */

static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
				const ASN1_ITEM *it,
				const char *fname, const char *sname,
				int nohdr, const ASN1_PCTX *pctx);

int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
				const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);

static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
				const ASN1_ITEM *it, int indent,
				const char *fname, const char *sname,
				const ASN1_PCTX *pctx);

static int asn1_print_fsname(BIO *out, int indent,
			const char *fname, const char *sname,
			const ASN1_PCTX *pctx);

int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
				const ASN1_ITEM *it, const ASN1_PCTX *pctx)
	{
	const char *sname;
	if (pctx == NULL)
		pctx = &default_pctx;
	if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
		sname = NULL;
	else
		sname = it->sname;
	return asn1_item_print_ctx(out, &ifld, indent, it,
							NULL, sname, 0, pctx);
	}

static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
				const ASN1_ITEM *it,
				const char *fname, const char *sname,
				int nohdr, const ASN1_PCTX *pctx)
	{
	const ASN1_TEMPLATE *tt;
	const ASN1_EXTERN_FUNCS *ef;
	ASN1_VALUE **tmpfld;
	const ASN1_AUX *aux = it->funcs;
	ASN1_aux_cb *asn1_cb;
	ASN1_PRINT_ARG parg;
	int i;
	if (aux && aux->asn1_cb)
		{
		parg.out = out;
		parg.indent = indent;
		parg.pctx = pctx;
		asn1_cb = aux->asn1_cb;
		}
	else asn1_cb = 0;

	if(*fld == NULL)
		{
		if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT)
			{
			if (!nohdr && !asn1_print_fsname(out, indent,
							fname, sname, pctx))
				return 0;
			if (BIO_puts(out, "<ABSENT>\n") <= 0)
				return 0;
			}
		return 1;
		}

	switch(it->itype)
		{
		case ASN1_ITYPE_PRIMITIVE:
		if(it->templates)
			{
			if (!asn1_template_print_ctx(out, fld, indent,
							it->templates, pctx))
				return 0;
			break;
			}
		/* fall thru */
		case ASN1_ITYPE_MSTRING:
		if (!asn1_primitive_print(out, fld, it,
				indent, fname, sname,pctx))
			return 0;
		break;

		case ASN1_ITYPE_EXTERN:
		if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
			return 0;
		/* Use new style print routine if possible */
		ef = it->funcs;
		if (ef && ef->asn1_ex_print)
			{
			i = ef->asn1_ex_print(out, fld, indent, "", pctx);
			if (!i)
				return 0;
			if ((i == 2) && (BIO_puts(out, "\n") <= 0))
				return 0;
			return 1;
			}
		else if (sname && 
			BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
			return 0;
		break;

		case ASN1_ITYPE_CHOICE:
#if 0
		if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
			return 0;
#endif
		/* CHOICE type, get selector */
		i = asn1_get_choice_selector(fld, it);
		/* This should never happen... */
		if((i < 0) || (i >= it->tcount))
			{
			if (BIO_printf(out,
				"ERROR: selector [%d] invalid\n", i) <= 0)
				return 0;
			return 1;
			}
		tt = it->templates + i;
		tmpfld = asn1_get_field_ptr(fld, tt);
		if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
			return 0;
		break;

		case ASN1_ITYPE_SEQUENCE:
		case ASN1_ITYPE_NDEF_SEQUENCE:
		if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
			return 0;
		if (fname || sname)
			{
			if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
				{
				if (BIO_puts(out, " {\n") <= 0)
					return 0;
				}
			else
				{
				if (BIO_puts(out, "\n") <= 0)
					return 0;
				}
			}

		if (asn1_cb)
			{
			i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
			if (i == 0)
				return 0;
			if (i == 2)
				return 1;
			}

		/* Print each field entry */
		for(i = 0, tt = it->templates; i < it->tcount; i++, tt++)
			{
			const ASN1_TEMPLATE *seqtt;
			seqtt = asn1_do_adb(fld, tt, 1);
			if (!seqtt)
				return 0;
			tmpfld = asn1_get_field_ptr(fld, seqtt);
			if (!asn1_template_print_ctx(out, tmpfld,
						indent + 2, seqtt, pctx))
				return 0;
			}
		if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
			{
			if (BIO_printf(out, "%*s}\n", indent, "") < 0)
				return 0;
			}

		if (asn1_cb)
			{
			i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
			if (i == 0)
				return 0;
			}
		break;

		default:
		BIO_printf(out, "Unprocessed type %d\n", it->itype);
		return 0;
		}

	return 1;
	}

int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
				const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
	{
	int flags;
	size_t i;
	const char *sname, *fname;
	flags = tt->flags;
	if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
		sname = ASN1_ITEM_ptr(tt->item)->sname;
	else
		sname = NULL;
	if(pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
		fname = NULL;
	else
		fname = tt->field_name;
	if(flags & ASN1_TFLG_SK_MASK)
		{
		const char *tname;
		ASN1_VALUE *skitem;
		STACK_OF(ASN1_VALUE) *stack;

		/* SET OF, SEQUENCE OF */
		if (fname)
			{
			if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF)
				{
				if(flags & ASN1_TFLG_SET_OF)
					tname = "SET";
				else
					tname = "SEQUENCE";
				if (BIO_printf(out, "%*s%s OF %s {\n",
					indent, "", tname, tt->field_name) <= 0)
					return 0;
				}
			else if (BIO_printf(out, "%*s%s:\n", indent, "",
					fname) <= 0)
				return 0;
			}
		stack = (STACK_OF(ASN1_VALUE) *)*fld;
		for(i = 0; i < sk_ASN1_VALUE_num(stack); i++)
			{
			if ((i > 0) && (BIO_puts(out, "\n") <= 0))
				return 0;

			skitem = sk_ASN1_VALUE_value(stack, i);
			if (!asn1_item_print_ctx(out, &skitem, indent + 2,
				ASN1_ITEM_ptr(tt->item), NULL, NULL, 1, pctx))
				return 0;
			}
		if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0)
				return 0;
		if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
			{
			if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
				return 0;
			}
		return 1;
		}
	return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
							fname, sname, 0, pctx);
	}

static int asn1_print_fsname(BIO *out, int indent,
			const char *fname, const char *sname,
			const ASN1_PCTX *pctx)
	{
	static char spaces[] = "                    ";
	const int nspaces = sizeof(spaces) - 1;

#if 0
	if (!sname && !fname)
		return 1;
#endif

	while (indent > nspaces)
		{
		if (BIO_write(out, spaces, nspaces) != nspaces)
			return 0;
		indent -= nspaces;
		}
	if (BIO_write(out, spaces, indent) != indent)
		return 0;
	if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
		sname = NULL;
	if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
		fname = NULL;
	if (!sname && !fname)
		return 1;
	if (fname)
		{
		if (BIO_puts(out, fname) <= 0)
			return 0;
		}
	if (sname)
		{
		if (fname)
			{
			if (BIO_printf(out, " (%s)", sname) <= 0)
				return 0;
			}
		else
			{
			if (BIO_puts(out, sname) <= 0)
				return 0;
			}
		}
	if (BIO_write(out, ": ", 2) != 2)
		return 0;
	return 1;
	}

static int asn1_print_boolean_ctx(BIO *out, int boolval,
							const ASN1_PCTX *pctx)
	{
	const char *str;
	switch (boolval)
		{
		case -1:
		str = "BOOL ABSENT";
		break;

		case 0:
		str = "FALSE";
		break;

		default:
		str = "TRUE";
		break;

		}

	if (BIO_puts(out, str) <= 0)
		return 0;
	return 1;

	}

static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str,
						const ASN1_PCTX *pctx)
	{
	BIGNUM *bn = NULL;
	char *s = NULL;
	int ret = 1;

	bn = ASN1_INTEGER_to_BN(str, NULL);
	if (bn == NULL) {
		return 0;
	}
	s = BN_bn2dec(bn);
	BN_free(bn);
	if (s == NULL) {
		return 0;
	}

	if (BIO_puts(out, s) <= 0) {
		ret = 0;
	}
	OPENSSL_free(s);
	return ret;
	}

static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid,
						const ASN1_PCTX *pctx)
	{
	char objbuf[80];
	const char *ln;
	ln = OBJ_nid2ln(OBJ_obj2nid(oid));
	if(!ln)
		ln = "";
	OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1);
	if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
		return 0;
	return 1;
	}

static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent,
						const ASN1_PCTX *pctx)
	{
	if (str->type == V_ASN1_BIT_STRING)
		{
		if (BIO_printf(out, " (%ld unused bits)\n",
					str->flags & 0x7) <= 0)
				return 0;
		}
	else if (BIO_puts(out, "\n") <= 0)
		return 0;
	if (str->length > 0 && !BIO_hexdump(out, str->data, str->length, indent + 2)) {
		return 0;
	}
	return 1;
	}

static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
				const ASN1_ITEM *it, int indent,
				const char *fname, const char *sname,
				const ASN1_PCTX *pctx)
	{
	long utype;
	ASN1_STRING *str;
	int ret = 1, needlf = 1;
	const char *pname;
	const ASN1_PRIMITIVE_FUNCS *pf;
	pf = it->funcs;
	if (!asn1_print_fsname(out, indent, fname, sname, pctx))
			return 0;
	if (pf && pf->prim_print)
		return pf->prim_print(out, fld, it, indent, pctx);
	str = (ASN1_STRING *)*fld;
	if (it->itype == ASN1_ITYPE_MSTRING)
		utype = str->type & ~V_ASN1_NEG;
	else
		utype = it->utype;
	if (utype == V_ASN1_ANY)
		{
		ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
		utype = atype->type;
		fld = &atype->value.asn1_value;
		str = (ASN1_STRING *)*fld;
		if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
			pname = NULL;
		else 
			pname = ASN1_tag2str(utype);
		}
	else
		{
		if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
			pname = ASN1_tag2str(utype);
		else 
			pname = NULL;
		}

	if (utype == V_ASN1_NULL)
		{
		if (BIO_puts(out, "NULL\n") <= 0)
			return 0;
		return 1;
		}

	if (pname)
		{
		if (BIO_puts(out, pname) <= 0)
			return 0;
		if (BIO_puts(out, ":") <= 0)
			return 0;
		}

	switch (utype)
		{
		case V_ASN1_BOOLEAN:
			{
			int boolval = *(int *)fld;
			if (boolval == -1)
				boolval = it->size;
			ret = asn1_print_boolean_ctx(out, boolval, pctx);
			}
		break;

		case V_ASN1_INTEGER:
		case V_ASN1_ENUMERATED:
		ret = asn1_print_integer_ctx(out, str, pctx);
		break;

		case V_ASN1_UTCTIME:
		ret = ASN1_UTCTIME_print(out, str);
		break;

		case V_ASN1_GENERALIZEDTIME:
		ret = ASN1_GENERALIZEDTIME_print(out, str);
		break;

		case V_ASN1_OBJECT:
		ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx);
		break;

		case V_ASN1_OCTET_STRING:
		case V_ASN1_BIT_STRING:
		ret = asn1_print_obstring_ctx(out, str, indent, pctx);
		needlf = 0;
		break;

		case V_ASN1_SEQUENCE:
		case V_ASN1_SET:
		case V_ASN1_OTHER:
		if (BIO_puts(out, "\n") <= 0)
			return 0;
		if (ASN1_parse_dump(out, str->data, str->length,
						indent, 0) <= 0)
			ret = 0;
		needlf = 0;
		break;

		default:
		ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);

		}
	if (!ret)
		return 0;
	if (needlf && BIO_puts(out, "\n") <= 0)
		return 0;
	return 1;
	}
