/* crypto/asn1/x_name.c */
/* 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 <stdio.h>
#include <ctype.h>
#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include "asn1_locl.h"

typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)

static int x509_name_ex_d2i(ASN1_VALUE **val,
				const unsigned char **in, long len,
				const ASN1_ITEM *it,
				int tag, int aclass, char opt, ASN1_TLC *ctx);

static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
				const ASN1_ITEM *it, int tag, int aclass);
static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);

static int x509_name_encode(X509_NAME *a);
static int x509_name_canon(X509_NAME *a);
static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in);
static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname,
			  unsigned char **in);


static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
						int indent,
						const char *fname, 
						const ASN1_PCTX *pctx);

ASN1_SEQUENCE(X509_NAME_ENTRY) = {
	ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
	ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
} ASN1_SEQUENCE_END(X509_NAME_ENTRY)

IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY)
IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)

/* For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY }
 * so declare two template wrappers for this
 */

ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) =
	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)

ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)

/* Normally that's where it would end: we'd have two nested STACK structures
 * representing the ASN1. Unfortunately X509_NAME uses a completely different
 * form and caches encodings so we have to process the internal form and convert
 * to the external form.
 */

const ASN1_EXTERN_FUNCS x509_name_ff = {
	NULL,
	x509_name_ex_new,
	x509_name_ex_free,
	0,	/* Default clear behaviour is OK */
	x509_name_ex_d2i,
	x509_name_ex_i2d,
	x509_name_ex_print
};

IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) 

IMPLEMENT_ASN1_FUNCTIONS(X509_NAME)
IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME)

static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
{
	X509_NAME *ret = NULL;
	ret = OPENSSL_malloc(sizeof(X509_NAME));
	if(!ret) goto memerr;
	if ((ret->entries=sk_X509_NAME_ENTRY_new_null()) == NULL)
		goto memerr;
	if((ret->bytes = BUF_MEM_new()) == NULL) goto memerr;
	ret->canon_enc = NULL;
	ret->canon_enclen = 0;
	ret->modified=1;
	*val = (ASN1_VALUE *)ret;
	return 1;

 memerr:
	ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE);
	if (ret)
		{
		if (ret->entries)
			sk_X509_NAME_ENTRY_free(ret->entries);
		OPENSSL_free(ret);
		}
	return 0;
}

static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
	X509_NAME *a;
	if(!pval || !*pval)
	    return;
	a = (X509_NAME *)*pval;

	BUF_MEM_free(a->bytes);
	sk_X509_NAME_ENTRY_pop_free(a->entries,X509_NAME_ENTRY_free);
	if (a->canon_enc)
		OPENSSL_free(a->canon_enc);
	OPENSSL_free(a);
	*pval = NULL;
}

static int x509_name_ex_d2i(ASN1_VALUE **val,
			const unsigned char **in, long len, const ASN1_ITEM *it,
				int tag, int aclass, char opt, ASN1_TLC *ctx)
{
	const unsigned char *p = *in, *q;
	union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
		ASN1_VALUE *a; } intname = {NULL};
	union { X509_NAME *x; ASN1_VALUE *a; } nm = {NULL};
	int i, j, ret;
	STACK_OF(X509_NAME_ENTRY) *entries;
	X509_NAME_ENTRY *entry;
	q = p;

	/* Get internal representation of Name */
	ret = ASN1_item_ex_d2i(&intname.a,
			       &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
			       tag, aclass, opt, ctx);
	
	if(ret <= 0) return ret;

	if(*val) x509_name_ex_free(val, NULL);
	if(!x509_name_ex_new(&nm.a, NULL)) goto err;
	/* We've decoded it: now cache encoding */
	if(!BUF_MEM_grow(nm.x->bytes, p - q)) goto err;
	memcpy(nm.x->bytes->data, q, p - q);

	/* Convert internal representation to X509_NAME structure */
	for(i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
		entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
		for(j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
			entry = sk_X509_NAME_ENTRY_value(entries, j);
			entry->set = i;
			if(!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
				goto err;
		}
		sk_X509_NAME_ENTRY_free(entries);
	}
	sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
	ret = x509_name_canon(nm.x);
	if (!ret)
		goto err;
	nm.x->modified = 0;
	*val = nm.a;
	*in = p;
	return ret;
err:
        if (nm.x != NULL)
		X509_NAME_free(nm.x);
	ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
	return 0;
}

static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass)
{
	int ret;
	X509_NAME *a = (X509_NAME *)*val;
	if(a->modified) {
		ret = x509_name_encode(a);
		if(ret < 0)
			return ret;
		ret = x509_name_canon(a);
		if(ret < 0)
			return ret;
	}
	ret = a->bytes->length;
	if(out != NULL) {
		memcpy(*out,a->bytes->data,ret);
		*out+=ret;
	}
	return ret;
}

static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
	{
	sk_X509_NAME_ENTRY_free(ne);
	}

static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
	{
	sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
	}

static int x509_name_encode(X509_NAME *a)
{
	union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
		ASN1_VALUE *a; } intname = {NULL};
	int len;
	unsigned char *p;
	STACK_OF(X509_NAME_ENTRY) *entries = NULL;
	X509_NAME_ENTRY *entry;
	int i, set = -1;
	intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
	if(!intname.s) goto memerr;
	for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
		entry = sk_X509_NAME_ENTRY_value(a->entries, i);
		if(entry->set != set) {
			entries = sk_X509_NAME_ENTRY_new_null();
			if(!entries) goto memerr;
			if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s,
							     entries))
				goto memerr;
			set = entry->set;
		}
		if(!sk_X509_NAME_ENTRY_push(entries, entry)) goto memerr;
	}
	len = ASN1_item_ex_i2d(&intname.a, NULL,
			       ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
	if (!BUF_MEM_grow(a->bytes,len)) goto memerr;
	p=(unsigned char *)a->bytes->data;
	ASN1_item_ex_i2d(&intname.a,
			 &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
	sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
					     local_sk_X509_NAME_ENTRY_free);
	a->modified = 0;
	return len;
memerr:
	sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
					     local_sk_X509_NAME_ENTRY_free);
	ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE);
	return -1;
}

static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
						int indent,
						const char *fname, 
						const ASN1_PCTX *pctx)
	{
	if (X509_NAME_print_ex(out, (X509_NAME *)*pval,
					indent, pctx->nm_flags) <= 0)
		return 0;
	return 2;
	}

/* This function generates the canonical encoding of the Name structure.
 * In it all strings are converted to UTF8, leading, trailing and
 * multiple spaces collapsed, converted to lower case and the leading
 * SEQUENCE header removed.
 *
 * In future we could also normalize the UTF8 too.
 *
 * By doing this comparison of Name structures can be rapidly
 * perfomed by just using memcmp() of the canonical encoding.
 * By omitting the leading SEQUENCE name constraints of type
 * dirName can also be checked with a simple memcmp().
 */

static int x509_name_canon(X509_NAME *a)
	{
	unsigned char *p;
	STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
	STACK_OF(X509_NAME_ENTRY) *entries = NULL;
	X509_NAME_ENTRY *entry, *tmpentry = NULL;
	int i, set = -1, ret = 0;

	if (a->canon_enc)
		{
		OPENSSL_free(a->canon_enc);
		a->canon_enc = NULL;
		}
	/* Special case: empty X509_NAME => null encoding */
	if (sk_X509_NAME_ENTRY_num(a->entries) == 0)
		{
		a->canon_enclen = 0;
		return 1;
		}
	intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
	if(!intname)
		goto err;
	for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++)
		{
		entry = sk_X509_NAME_ENTRY_value(a->entries, i);
		if(entry->set != set)
			{
			entries = sk_X509_NAME_ENTRY_new_null();
			if(!entries)
				goto err;
			if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries))
				goto err;
			set = entry->set;
			}
		tmpentry = X509_NAME_ENTRY_new();
		tmpentry->object = OBJ_dup(entry->object);
		if (!asn1_string_canon(tmpentry->value, entry->value))
			goto err;
		if(!sk_X509_NAME_ENTRY_push(entries, tmpentry))
			goto err;
		tmpentry = NULL;
		}

	/* Finally generate encoding */

	a->canon_enclen = i2d_name_canon(intname, NULL);

	p = OPENSSL_malloc(a->canon_enclen);

	if (!p)
		goto err;

	a->canon_enc = p;

	i2d_name_canon(intname, &p);

	ret = 1;

	err:

	if (tmpentry)
		X509_NAME_ENTRY_free(tmpentry);
	if (intname)
		sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
					local_sk_X509_NAME_ENTRY_pop_free);
	return ret;
	}

/* Bitmap of all the types of string that will be canonicalized. */

#define ASN1_MASK_CANON	\
	(B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
	| B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
	| B_ASN1_VISIBLESTRING)
	

static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in)
	{
	unsigned char *to, *from;
	int len, i;

	/* If type not in bitmask just copy string across */
	if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON))
		{
		out->type = in->type;
		if (!ASN1_STRING_set(out, in->data, in->length))
			return 0;
		return 1;
		}

	out->type = V_ASN1_UTF8STRING;
	out->length = ASN1_STRING_to_UTF8(&out->data, in);
	if (out->length == -1)
		return 0;

	to = out->data;
	from = to;

	len = out->length;

	/* Convert string in place to canonical form.
	 * Ultimately we may need to handle a wider range of characters
	 * but for now ignore anything with MSB set and rely on the
	 * isspace() and tolower() functions.
	 */

	/* Ignore leading spaces */
	while((len > 0) && !(*from & 0x80) && isspace(*from))
		{
		from++;
		len--;
		}

	to = from + len - 1;

	/* Ignore trailing spaces */
	while ((len > 0) && !(*to & 0x80) && isspace(*to))
		{
		to--;
		len--;
		}

	to = out->data;

	i = 0;
	while(i < len)
		{
		/* If MSB set just copy across */
		if (*from & 0x80)
			{
			*to++ = *from++;
			i++;
			}
		/* Collapse multiple spaces */
		else if (isspace(*from))
			{
			/* Copy one space across */
			*to++ = ' ';
			/* Ignore subsequent spaces. Note: don't need to
			 * check len here because we know the last 
			 * character is a non-space so we can't overflow.
			 */
			do
				{
				from++;
				i++;
				}
			while(!(*from & 0x80) && isspace(*from));
			}
		else
			{
			*to++ = tolower(*from);
			from++;
			i++;
			}
		}

	out->length = to - out->data;

	return 1;

	}

static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname,
			  unsigned char **in)
	{
	int i, len, ltmp;
	ASN1_VALUE *v;
	STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;

	len = 0;
	for (i = 0; i < sk_ASN1_VALUE_num(intname); i++)
		{
		v = sk_ASN1_VALUE_value(intname, i);
		ltmp = ASN1_item_ex_i2d(&v, in,
			ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
		if (ltmp < 0)
			return ltmp;
		len += ltmp;
		}
	return len;
	}

int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
	{
	X509_NAME *in;

	if (!xn || !name) return(0);

	if (*xn != name)
		{
		in=X509_NAME_dup(name);
		if (in != NULL)
			{
			X509_NAME_free(*xn);
			*xn=in;
			}
		}
	return(*xn != NULL);
	}
	
IMPLEMENT_STACK_OF(X509_NAME_ENTRY)
IMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY)
