/* 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:
	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++);
			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)
