/* a_strex.c */
/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
 * project 2000.
 */
/* ====================================================================
 * Copyright (c) 2000 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 <stdio.h>
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/asn1.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)


/* Three IO functions for sending data to memory, a BIO and
 * and a FILE pointer.
 */

int send_mem_chars(void *arg, const void *buf, int len)
{
	unsigned char **out = arg;
	if(!out) return 1;
	memcpy(*out, buf, len);
	*out += len;
	return 1;
}

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

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

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[11];
	if(c > 0xffff) {
		BIO_snprintf(tmphex, 11, "\\W%08lX", c);
		if(!io_ch(arg, tmphex, 10)) return -1;
		return 10;
	}
	if(c > 0xff) {
		BIO_snprintf(tmphex, 11, "\\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(!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) 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;
		}
		if (p == q) orflags = CHARTYPE_LAST_ESC_2253;
		if(type & BUF_TYPE_CONVUTF8) {
			unsigned char utfbuf[6];
			int utflen;
			utflen = UTF8_putc(utfbuf, 6, 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)
{
	const static 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.
 */

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

const static 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 */
};

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

/* 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(outlen < 0) return -1;
	outlen += len;
	if(quotes) outlen += 2;
	if(!arg) return outlen;
	if(quotes && !io_ch(arg, "\"", 1)) return -1;
	do_buf(str->data, str->length, type, flags, NULL, io_ch, arg);
	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;
	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, 80, 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);
}


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

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


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

/* 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(!*out || !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;
	ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING);
	if(ret < 0) return ret;
	if(out) *out = stmp.data;
	return stmp.length;
}
