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

#include <string.h>

#include <openssl/asn1.h>
#include <openssl/mem.h>
#include <openssl/obj.h>

#include "charmap.h"


/* ASN1_STRING_print_ex() and X509_NAME_print_ex().
 * Enhanced string and name printing routines handling
 * multibyte characters, RFC2253 and a host of other
 * options.
 */


#define CHARTYPE_BS_ESC		(ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253)

#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \
		  ASN1_STRFLGS_ESC_QUOTE | \
		  ASN1_STRFLGS_ESC_CTRL | \
		  ASN1_STRFLGS_ESC_MSB)


static int send_bio_chars(void *arg, const void *buf, int len)
{
	if(!arg) return 1;
	if(BIO_write(arg, buf, len) != len) return 0;
	return 1;
}

static int send_fp_chars(void *arg, const void *buf, int len)
{
	if(!arg) return 1;
	if(fwrite(buf, 1, len, arg) != (unsigned int)len) return 0;
	return 1;
}

typedef int char_io(void *arg, const void *buf, int len);

/* This function handles display of
 * strings, one character at a time.
 * It is passed an unsigned long for each
 * character because it could come from 2 or even
 * 4 byte forms.
 */

#define HEX_SIZE(type) (sizeof(type)*2)

static int do_esc_char(unsigned long c, unsigned char flags, char *do_quotes, char_io *io_ch, void *arg)
{
	unsigned char chflgs, chtmp;
	char tmphex[HEX_SIZE(long)+3];

	if(c > 0xffffffffL)
		return -1;
	if(c > 0xffff) {
		BIO_snprintf(tmphex, sizeof tmphex, "\\W%08lX", c);
		if(!io_ch(arg, tmphex, 10)) return -1;
		return 10;
	}
	if(c > 0xff) {
		BIO_snprintf(tmphex, sizeof tmphex, "\\U%04lX", c);
		if(!io_ch(arg, tmphex, 6)) return -1;
		return 6;
	}
	chtmp = (unsigned char)c;
	if(chtmp > 0x7f) chflgs = flags & ASN1_STRFLGS_ESC_MSB;
	else chflgs = char_type[chtmp] & flags;
	if(chflgs & CHARTYPE_BS_ESC) {
		/* If we don't escape with quotes, signal we need quotes */
		if(chflgs & ASN1_STRFLGS_ESC_QUOTE) {
			if(do_quotes) *do_quotes = 1;
			if(!io_ch(arg, &chtmp, 1)) return -1;
			return 1;
		}
		if(!io_ch(arg, "\\", 1)) return -1;
		if(!io_ch(arg, &chtmp, 1)) return -1;
		return 2;
	}
	if(chflgs & (ASN1_STRFLGS_ESC_CTRL|ASN1_STRFLGS_ESC_MSB)) {
		BIO_snprintf(tmphex, 11, "\\%02X", chtmp);
		if(!io_ch(arg, tmphex, 3)) return -1;
		return 3;
	}
	/* If we get this far and do any escaping at all must escape 
	 * the escape character itself: backslash.
	 */
	if (chtmp == '\\' && flags & ESC_FLAGS) {
		if(!io_ch(arg, "\\\\", 2)) return -1;
		return 2;
	}
	if(!io_ch(arg, &chtmp, 1)) return -1;
	return 1;
}

#define BUF_TYPE_WIDTH_MASK	0x7
#define BUF_TYPE_CONVUTF8	0x8

/* This function sends each character in a buffer to
 * do_esc_char(). It interprets the content formats
 * and converts to or from UTF8 as appropriate.
 */

static int do_buf(unsigned char *buf, int buflen,
			int type, unsigned char flags, char *quotes, char_io *io_ch, void *arg)
{
	int i, outlen, len;
	unsigned char orflags, *p, *q;
	unsigned long c;
	p = buf;
	q = buf + buflen;
	outlen = 0;
	while(p != q) {
		if(p == buf && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_FIRST_ESC_2253;
		else orflags = 0;
		switch(type & BUF_TYPE_WIDTH_MASK) {
			case 4:
			c = ((unsigned long)*p++) << 24;
			c |= ((unsigned long)*p++) << 16;
			c |= ((unsigned long)*p++) << 8;
			c |= *p++;
			break;

			case 2:
			c = ((unsigned long)*p++) << 8;
			c |= *p++;
			break;

			case 1:
			c = *p++;
			break;
			
			case 0:
			i = UTF8_getc(p, buflen, &c);
			if(i < 0) return -1;	/* Invalid UTF8String */
			p += i;
			break;
			default:
			return -1;	/* invalid width */
		}
		if (p == q && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_LAST_ESC_2253;
		if(type & BUF_TYPE_CONVUTF8) {
			unsigned char utfbuf[6];
			int utflen;
			utflen = UTF8_putc(utfbuf, sizeof utfbuf, c);
			for(i = 0; i < utflen; i++) {
				/* We don't need to worry about setting orflags correctly
				 * because if utflen==1 its value will be correct anyway 
				 * otherwise each character will be > 0x7f and so the 
				 * character will never be escaped on first and last.
				 */
				len = do_esc_char(utfbuf[i], (unsigned char)(flags | orflags), quotes, io_ch, arg);
				if(len < 0) return -1;
				outlen += len;
			}
		} else {
			len = do_esc_char(c, (unsigned char)(flags | orflags), quotes, io_ch, arg);
			if(len < 0) return -1;
			outlen += len;
		}
	}
	return outlen;
}

/* This function hex dumps a buffer of characters */

static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf, int buflen)
{
	static const char hexdig[] = "0123456789ABCDEF";
	unsigned char *p, *q;
	char hextmp[2];
	if(arg) {
		p = buf;
		q = buf + buflen;
		while(p != q) {
			hextmp[0] = hexdig[*p >> 4];
			hextmp[1] = hexdig[*p & 0xf];
			if(!io_ch(arg, hextmp, 2)) return -1;
			p++;
		}
	}
	return buflen << 1;
}

/* "dump" a string. This is done when the type is unknown,
 * or the flags request it. We can either dump the content
 * octets or the entire DER encoding. This uses the RFC2253
 * #01234 format.
 */

static int do_dump(unsigned long lflags, char_io *io_ch, void *arg, ASN1_STRING *str)
{
	/* Placing the ASN1_STRING in a temp ASN1_TYPE allows
	 * the DER encoding to readily obtained
	 */
	ASN1_TYPE t;
	unsigned char *der_buf, *p;
	int outlen, der_len;

	if(!io_ch(arg, "#", 1)) return -1;
	/* If we don't dump DER encoding just dump content octets */
	if(!(lflags & ASN1_STRFLGS_DUMP_DER)) {
		outlen = do_hex_dump(io_ch, arg, str->data, str->length);
		if(outlen < 0) return -1;
		return outlen + 1;
	}
	t.type = str->type;
	t.value.ptr = (char *)str;
	der_len = i2d_ASN1_TYPE(&t, NULL);
	der_buf = OPENSSL_malloc(der_len);
	if(!der_buf) return -1;
	p = der_buf;
	i2d_ASN1_TYPE(&t, &p);
	outlen = do_hex_dump(io_ch, arg, der_buf, der_len);
	OPENSSL_free(der_buf);
	if(outlen < 0) return -1;
	return outlen + 1;
}

/* Lookup table to convert tags to character widths,
 * 0 = UTF8 encoded, -1 is used for non string types
 * otherwise it is the number of bytes per character
 */

static const signed char tag2nbyte[] = {
	-1, -1, -1, -1, -1,	/* 0-4 */
	-1, -1, -1, -1, -1,	/* 5-9 */
	-1, -1, 0, -1,		/* 10-13 */
	-1, -1, -1, -1,		/* 15-17 */
	-1, 1, 1,		/* 18-20 */
	-1, 1, 1, 1,		/* 21-24 */
	-1, 1, -1,		/* 25-27 */
	4, -1, 2		/* 28-30 */
};

/* This is the main function, print out an
 * ASN1_STRING taking note of various escape
 * and display options. Returns number of
 * characters written or -1 if an error
 * occurred.
 */

static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags, ASN1_STRING *str)
{
	int outlen, len;
	int type;
	char quotes;
	unsigned char flags;
	quotes = 0;
	/* Keep a copy of escape flags */
	flags = (unsigned char)(lflags & ESC_FLAGS);

	type = str->type;

	outlen = 0;


	if(lflags & ASN1_STRFLGS_SHOW_TYPE) {
		const char *tagname;
		tagname = ASN1_tag2str(type);
		outlen += strlen(tagname);
		if(!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1)) return -1; 
		outlen++;
	}

	/* Decide what to do with type, either dump content or display it */

	/* Dump everything */
	if(lflags & ASN1_STRFLGS_DUMP_ALL) type = -1;
	/* Ignore the string type */
	else if(lflags & ASN1_STRFLGS_IGNORE_TYPE) type = 1;
	else {
		/* Else determine width based on type */
		if((type > 0) && (type < 31)) type = tag2nbyte[type];
		else type = -1;
		if((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN)) type = 1;
	}

	if(type == -1) {
		len = do_dump(lflags, io_ch, arg, str);
		if(len < 0) return -1;
		outlen += len;
		return outlen;
	}

	if(lflags & ASN1_STRFLGS_UTF8_CONVERT) {
		/* Note: if string is UTF8 and we want
		 * to convert to UTF8 then we just interpret
		 * it as 1 byte per character to avoid converting
		 * twice.
		 */
		if(!type) type = 1;
		else type |= BUF_TYPE_CONVUTF8;
	}

	len = do_buf(str->data, str->length, type, flags, &quotes, io_ch, NULL);
	if(len < 0) return -1;
	outlen += len;
	if(quotes) outlen += 2;
	if(!arg) return outlen;
	if(quotes && !io_ch(arg, "\"", 1)) return -1;
	if(do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0)
		return -1;
	if(quotes && !io_ch(arg, "\"", 1)) return -1;
	return outlen;
}

/* Used for line indenting: print 'indent' spaces */

static int do_indent(char_io *io_ch, void *arg, int indent)
{
	int i;
	for(i = 0; i < indent; i++)
			if(!io_ch(arg, " ", 1)) return 0;
	return 1;
}

#define FN_WIDTH_LN	25
#define FN_WIDTH_SN	10

static int do_name_ex(char_io *io_ch, void *arg, X509_NAME *n,
				int indent, unsigned long flags)
{
	int i, prev = -1, orflags, cnt;
	int fn_opt, fn_nid;
	ASN1_OBJECT *fn;
	ASN1_STRING *val;
	X509_NAME_ENTRY *ent;
	char objtmp[80];
	const char *objbuf;
	int outlen, len;
	const char *sep_dn, *sep_mv, *sep_eq;
	int sep_dn_len, sep_mv_len, sep_eq_len;
	if(indent < 0) indent = 0;
	outlen = indent;
	if(!do_indent(io_ch, arg, indent)) return -1;
	switch (flags & XN_FLAG_SEP_MASK)
	{
		case XN_FLAG_SEP_MULTILINE:
		sep_dn = "\n";
		sep_dn_len = 1;
		sep_mv = " + ";
		sep_mv_len = 3;
		break;

		case XN_FLAG_SEP_COMMA_PLUS:
		sep_dn = ",";
		sep_dn_len = 1;
		sep_mv = "+";
		sep_mv_len = 1;
		indent = 0;
		break;

		case XN_FLAG_SEP_CPLUS_SPC:
		sep_dn = ", ";
		sep_dn_len = 2;
		sep_mv = " + ";
		sep_mv_len = 3;
		indent = 0;
		break;

		case XN_FLAG_SEP_SPLUS_SPC:
		sep_dn = "; ";
		sep_dn_len = 2;
		sep_mv = " + ";
		sep_mv_len = 3;
		indent = 0;
		break;

		default:
		return -1;
	}

	if(flags & XN_FLAG_SPC_EQ) {
		sep_eq = " = ";
		sep_eq_len = 3;
	} else {
		sep_eq = "=";
		sep_eq_len = 1;
	}

	fn_opt = flags & XN_FLAG_FN_MASK;

	cnt = X509_NAME_entry_count(n);	
	for(i = 0; i < cnt; i++) {
		if(flags & XN_FLAG_DN_REV)
				ent = X509_NAME_get_entry(n, cnt - i - 1);
		else ent = X509_NAME_get_entry(n, i);
		if(prev != -1) {
			if(prev == ent->set) {
				if(!io_ch(arg, sep_mv, sep_mv_len)) return -1;
				outlen += sep_mv_len;
			} else {
				if(!io_ch(arg, sep_dn, sep_dn_len)) return -1;
				outlen += sep_dn_len;
				if(!do_indent(io_ch, arg, indent)) return -1;
				outlen += indent;
			}
		}
		prev = ent->set;
		fn = X509_NAME_ENTRY_get_object(ent);
		val = X509_NAME_ENTRY_get_data(ent);
		fn_nid = OBJ_obj2nid(fn);
		if(fn_opt != XN_FLAG_FN_NONE) {
			int objlen, fld_len;
			if((fn_opt == XN_FLAG_FN_OID) || (fn_nid==NID_undef) ) {
				OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1);
				fld_len = 0; /* XXX: what should this be? */
				objbuf = objtmp;
			} else {
				if(fn_opt == XN_FLAG_FN_SN) {
					fld_len = FN_WIDTH_SN;
					objbuf = OBJ_nid2sn(fn_nid);
				} else if(fn_opt == XN_FLAG_FN_LN) {
					fld_len = FN_WIDTH_LN;
					objbuf = OBJ_nid2ln(fn_nid);
				} else {
					fld_len = 0; /* XXX: what should this be? */
					objbuf = "";
				}
			}
			objlen = strlen(objbuf);
			if(!io_ch(arg, objbuf, objlen)) return -1;
			if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) {
				if (!do_indent(io_ch, arg, fld_len - objlen)) return -1;
				outlen += fld_len - objlen;
			}
			if(!io_ch(arg, sep_eq, sep_eq_len)) return -1;
			outlen += objlen + sep_eq_len;
		}
		/* If the field name is unknown then fix up the DER dump
		 * flag. We might want to limit this further so it will
 		 * DER dump on anything other than a few 'standard' fields.
		 */
		if((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS)) 
					orflags = ASN1_STRFLGS_DUMP_ALL;
		else orflags = 0;
     
		len = do_print_ex(io_ch, arg, flags | orflags, val);
		if(len < 0) return -1;
		outlen += len;
	}
	return outlen;
}

/* Wrappers round the main functions */

int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags)
{
	if(flags == XN_FLAG_COMPAT)
		return X509_NAME_print(out, nm, indent);
	return do_name_ex(send_bio_chars, out, nm, indent, flags);
}

#ifndef OPENSSL_NO_FP_API
int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags)
{
	if(flags == XN_FLAG_COMPAT)
		{
		BIO *btmp;
		int ret;
		btmp = BIO_new_fp(fp, BIO_NOCLOSE);
		if(!btmp) return -1;
		ret = X509_NAME_print(btmp, nm, indent);
		BIO_free(btmp);
		return ret;
		}
	return do_name_ex(send_fp_chars, fp, nm, indent, flags);
}
#endif

int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags)
{
	return do_print_ex(send_bio_chars, out, flags, str);
}

#ifndef OPENSSL_NO_FP_API
int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags)
{
	return do_print_ex(send_fp_chars, fp, flags, str);
}
#endif

/* Utility function: convert any string type to UTF8, returns number of bytes
 * in output string or a negative error code
 */

int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in)
{
	ASN1_STRING stmp, *str = &stmp;
	int mbflag, type, ret;
	if(!in) return -1;
	type = in->type;
	if((type < 0) || (type > 30)) return -1;
	mbflag = tag2nbyte[type];
	if(mbflag == -1) return -1;
	mbflag |= MBSTRING_FLAG;
	stmp.data = NULL;
	stmp.length = 0;
	stmp.flags = 0;
	ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING);
	if(ret < 0) return ret;
	*out = stmp.data;
	return stmp.length;
}
