/* 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 <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/mem.h>


#define ASN1_PARSE_MAXDEPTH 128

static int asn1_print_info(BIO *bp, int tag, int xclass,int constructed,
	int indent);
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
	int offset, int depth, int indent, int dump);
static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
	     int indent)
	{
	static const char fmt[]="%-18s";
	char str[128];
	const char *p;

	if (constructed & V_ASN1_CONSTRUCTED)
		p="cons: ";
	else
		p="prim: ";
	if (BIO_write(bp,p,6) < 6) goto err;
	BIO_indent(bp,indent,128);

	p=str;
	if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
		BIO_snprintf(str,sizeof str,"priv [ %d ] ",tag);
	else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
		BIO_snprintf(str,sizeof str,"cont [ %d ]",tag);
	else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
		BIO_snprintf(str,sizeof str,"appl [ %d ]",tag);
	else if (tag > 30)
		BIO_snprintf(str,sizeof str,"<ASN1 %d>",tag);
	else
		p = ASN1_tag2str(tag);

	if (BIO_printf(bp,fmt,p) <= 0)
		goto err;
	return(1);
err:
	return(0);
	}

int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent)
	{
	return(asn1_parse2(bp,&pp,len,0,0,indent,0));
	}

int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, int dump)
	{
	return(asn1_parse2(bp,&pp,len,0,0,indent,dump));
	}

static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset,
	     int depth, int indent, int dump)
	{
	const unsigned char *p,*ep,*tot,*op,*opp;
	long len;
	int tag,xclass,ret=0;
	int nl,hl,j,r;
	ASN1_OBJECT *o=NULL;
	ASN1_OCTET_STRING *os=NULL;
	/* ASN1_BMPSTRING *bmp=NULL;*/
	int dump_indent;

#if 0
	dump_indent = indent;
#else
	dump_indent = 6;	/* Because we know BIO_dump_indent() */
#endif

	if (depth > ASN1_PARSE_MAXDEPTH)
		{
		BIO_puts(bp, "BAD RECURSION DEPTH\n");
		return 0;
		}

	p= *pp;
	tot=p+length;
	op=p-1;
	while ((p < tot) && (op < p))
		{
		op=p;
		j=ASN1_get_object(&p,&len,&tag,&xclass,length);
#ifdef LINT
		j=j;
#endif
		if (j & 0x80)
			{
			if (BIO_puts(bp, "Error in encoding\n") <= 0)
				goto end;
			ret=0;
			goto end;
			}
		hl=(p-op);
		length-=hl;
		/* if j == 0x21 it is a constructed indefinite length object */
		if (BIO_printf(bp,"%5ld:",(long)offset+(long)(op- *pp))
			<= 0) goto end;

		if (j != (V_ASN1_CONSTRUCTED | 1))
			{
			if (BIO_printf(bp,"d=%-2d hl=%ld l=%4ld ",
				depth,(long)hl,len) <= 0)
				goto end;
			}
		else
			{
			if (BIO_printf(bp,"d=%-2d hl=%ld l=inf  ",
				depth,(long)hl) <= 0)
				goto end;
			}
		if (!asn1_print_info(bp,tag,xclass,j,(indent)?depth:0))
			goto end;
		if (j & V_ASN1_CONSTRUCTED)
			{
			ep=p+len;
			if (BIO_puts(bp, "\n") <= 0) goto end;
			if (len > length)
				{
				BIO_printf(bp,
					"length is greater than %ld\n",length);
				ret=0;
				goto end;
				}
			if ((j == 0x21) && (len == 0))
				{
				for (;;)
					{
					r=asn1_parse2(bp,&p,(long)(tot-p),
						offset+(p - *pp),depth+1,
						indent,dump);
					if (r == 0) { ret=0; goto end; }
					if ((r == 2) || (p >= tot)) break;
					}
				}
			else
				while (p < ep)
					{
					r=asn1_parse2(bp,&p,(long)len,
						offset+(p - *pp),depth+1,
						indent,dump);
					if (r == 0) { ret=0; goto end; }
					}
			}
		else if (xclass != 0)
			{
			p+=len;
			if (BIO_puts(bp, "\n") <= 0) goto end;
			}
		else
			{
			nl=0;
			if (	(tag == V_ASN1_PRINTABLESTRING) ||
				(tag == V_ASN1_T61STRING) ||
				(tag == V_ASN1_IA5STRING) ||
				(tag == V_ASN1_VISIBLESTRING) ||
				(tag == V_ASN1_NUMERICSTRING) ||
				(tag == V_ASN1_UTF8STRING) ||
				(tag == V_ASN1_UTCTIME) ||
				(tag == V_ASN1_GENERALIZEDTIME))
				{
				if (BIO_puts(bp, ":") <= 0) goto end;
				if ((len > 0) &&
					BIO_write(bp,(const char *)p,(int)len)
					!= (int)len)
					goto end;
				}
			else if (tag == V_ASN1_OBJECT)
				{
				opp=op;
				if (d2i_ASN1_OBJECT(&o,&opp,len+hl) != NULL)
					{
					if (BIO_puts(bp, ":") <= 0) goto end;
					i2a_ASN1_OBJECT(bp,o);
					}
				else
					{
					if (BIO_puts(bp, ":BAD OBJECT") <= 0)
						goto end;
					}
				}
			else if (tag == V_ASN1_BOOLEAN)
				{
				int ii;

				opp=op;
				ii=d2i_ASN1_BOOLEAN(NULL,&opp,len+hl);
				if (ii < 0)
					{
					if (BIO_puts(bp, "Bad boolean\n") <= 0)
						goto end;
					}
				BIO_printf(bp,":%d",ii);
				}
			else if (tag == V_ASN1_BMPSTRING)
				{
				/* do the BMP thang */
				}
			else if (tag == V_ASN1_OCTET_STRING)
				{
				int i,printable=1;

				opp=op;
				os=d2i_ASN1_OCTET_STRING(NULL,&opp,len+hl);
				if (os != NULL && os->length > 0)
					{
					opp = os->data;
					/* testing whether the octet string is
					 * printable */
					for (i=0; i<os->length; i++)
						{
						if ((	(opp[i] < ' ') &&
							(opp[i] != '\n') &&
							(opp[i] != '\r') &&
							(opp[i] != '\t')) ||
							(opp[i] > '~'))
							{
							printable=0;
							break;
							}
						}
					if (printable)
					/* printable string */
						{
						if (BIO_puts(bp, ":") <= 0)
							goto end;
						if (BIO_write(bp,(const char *)opp,
							os->length) <= 0)
							goto end;
						}
					else if (!dump)
					/* not printable => print octet string
					 * as hex dump */
						{
						if (BIO_puts(bp, "[HEX DUMP]:") <= 0)
							goto end;
						for (i=0; i<os->length; i++)
							{
							if (BIO_printf(bp,"%02X"
								, opp[i]) <= 0)
								goto end;
							}
						}
					else
					/* print the normal dump */
						{
						if (!nl) 
							{
							if (BIO_puts(bp, "\n") <= 0)
								goto end;
							}
						if (!BIO_hexdump(bp, opp,
							((dump == -1 || dump > 
							os->length)?os->length:dump),
							dump_indent))
							goto end;
						nl=1;
						}
					}
				if (os != NULL)
					{
					M_ASN1_OCTET_STRING_free(os);
					os=NULL;
					}
				}
			else if (tag == V_ASN1_INTEGER)
				{
				ASN1_INTEGER *bs;
				int i;

				opp=op;
				bs=d2i_ASN1_INTEGER(NULL,&opp,len+hl);
				if (bs != NULL)
					{
					if (BIO_puts(bp, ":") <= 0) goto end;
					if (bs->type == V_ASN1_NEG_INTEGER)
						if (BIO_puts(bp, "-") <= 0)
							goto end;
					for (i=0; i<bs->length; i++)
						{
						if (BIO_printf(bp,"%02X",
							bs->data[i]) <= 0)
							goto end;
						}
					if (bs->length == 0)
						{
						if (BIO_puts(bp, "00") <= 0)
							goto end;
						}
					}
				else
					{
					if (BIO_puts(bp, "BAD INTEGER") <= 0)
						goto end;
					}
				M_ASN1_INTEGER_free(bs);
				}
			else if (tag == V_ASN1_ENUMERATED)
				{
				ASN1_ENUMERATED *bs;
				int i;

				opp=op;
				bs=d2i_ASN1_ENUMERATED(NULL,&opp,len+hl);
				if (bs != NULL)
					{
					if (BIO_puts(bp, ":") <= 0) goto end;
					if (bs->type == V_ASN1_NEG_ENUMERATED)
						if (BIO_puts(bp, "-") <= 0)
							goto end;
					for (i=0; i<bs->length; i++)
						{
						if (BIO_printf(bp,"%02X",
							bs->data[i]) <= 0)
							goto end;
						}
					if (bs->length == 0)
						{
						if (BIO_puts(bp, "00") <= 0)
							goto end;
						}
					}
				else
					{
					if (BIO_puts(bp, "BAD ENUMERATED") <= 0)
						goto end;
					}
				M_ASN1_ENUMERATED_free(bs);
				}
			else if (len > 0 && dump)
				{
				if (!nl) 
					{
					if (BIO_puts(bp, "\n") <= 0)
						goto end;
					}
				if (!BIO_hexdump(bp,p,
					((dump == -1 || dump > len)?len:dump),
					dump_indent))
					goto end;
				nl=1;
				}

			if (!nl) 
				{
				if (BIO_puts(bp, "\n") <= 0) goto end;
				}
			p+=len;
			if ((tag == V_ASN1_EOC) && (xclass == 0))
				{
				ret=2; /* End of sequence */
				goto end;
				}
			}
		length-=len;
		}
	ret=1;
end:
	if (o != NULL) ASN1_OBJECT_free(o);
	if (os != NULL) M_ASN1_OCTET_STRING_free(os);
	*pp=p;
	return(ret);
	}

const char *ASN1_tag2str(int tag)
{
	static const char * const tag2str[] = {
	 "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */
	 "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
	 "ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>", 	    /* 10-13 */
	"<ASN1 14>", "<ASN1 15>", "SEQUENCE", "SET", 		    /* 15-17 */
	"NUMERICSTRING", "PRINTABLESTRING", "T61STRING",	    /* 18-20 */
	"VIDEOTEXSTRING", "IA5STRING", "UTCTIME","GENERALIZEDTIME", /* 21-24 */
	"GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING",	    /* 25-27 */
	"UNIVERSALSTRING", "<ASN1 29>", "BMPSTRING"		    /* 28-30 */
	};

	if((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
							tag &= ~0x100;

	if(tag < 0 || tag > 30) return "(unknown)";
	return tag2str[tag];
}

