/* tasn_prn.c */
/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
 * project 2000.
 */
/* ====================================================================
 * Copyright (c) 2000,2005 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 "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/x509v3.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)
		{
		ASN1err(ASN1_F_ASN1_PCTX_NEW, 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;
			}
		/* 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);
			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 i, flags;
	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)
		{
		char *tname;
		ASN1_VALUE *skitem;
		/* 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;
			}
		for(i = 0; i < sk_num((STACK *)*fld); i++)
			{
			if ((i > 0) && (BIO_puts(out, "\n") <= 0))
				return 0;

			skitem = (ASN1_VALUE *)sk_value((STACK *)*fld, 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, const int bool,
							const ASN1_PCTX *pctx)
	{
	const char *str;
	switch (bool)
		{
		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)
	{
	char *s;
	int ret = 1;
	s = i2s_ASN1_INTEGER(NULL, str);
	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 (BIO_dump_indent(out, (char *)str->data, str->length,
				indent + 2) <= 0)
		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;
	if (!asn1_print_fsname(out, indent, fname, sname, pctx))
			return 0;
	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 = (ASN1_VALUE **)&atype->value.ptr;
		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 bool = *(int *)fld;
			if (bool == -1)
				bool = it->size;
			ret = asn1_print_boolean_ctx(out, bool, 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;
	}
