/* 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 */

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