/* crypto/x509/x509_att.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 <openssl/stack.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>

int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x)
{
	if (!x) return 0;
	return(sk_X509_ATTRIBUTE_num(x));
}

int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
			  int lastpos)
{
	ASN1_OBJECT *obj;

	obj=OBJ_nid2obj(nid);
	if (obj == NULL) return(-2);
	return(X509at_get_attr_by_OBJ(x,obj,lastpos));
}

int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, ASN1_OBJECT *obj,
			  int lastpos)
{
	int n;
	X509_ATTRIBUTE *ex;

	if (sk == NULL) return(-1);
	lastpos++;
	if (lastpos < 0)
		lastpos=0;
	n=sk_X509_ATTRIBUTE_num(sk);
	for ( ; lastpos < n; lastpos++)
		{
		ex=sk_X509_ATTRIBUTE_value(sk,lastpos);
		if (OBJ_cmp(ex->object,obj) == 0)
			return(lastpos);
		}
	return(-1);
}

X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc)
{
	if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0)
		return NULL;
	else
		return sk_X509_ATTRIBUTE_value(x,loc);
}

X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc)
{
	X509_ATTRIBUTE *ret;

	if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0)
		return(NULL);
	ret=sk_X509_ATTRIBUTE_delete(x,loc);
	return(ret);
}

STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
					 X509_ATTRIBUTE *attr)
{
	X509_ATTRIBUTE *new_attr=NULL;
	STACK_OF(X509_ATTRIBUTE) *sk=NULL;

	if ((x != NULL) && (*x == NULL))
		{
		if ((sk=sk_X509_ATTRIBUTE_new_null()) == NULL)
			goto err;
		}
	else
		sk= *x;

	if ((new_attr=X509_ATTRIBUTE_dup(attr)) == NULL)
		goto err2;
	if (!sk_X509_ATTRIBUTE_push(sk,new_attr))
		goto err;
	if ((x != NULL) && (*x == NULL))
		*x=sk;
	return(sk);
err:
	X509err(X509_F_X509_ADD_ATTR,ERR_R_MALLOC_FAILURE);
err2:
	if (new_attr != NULL) X509_ATTRIBUTE_free(new_attr);
	if (sk != NULL) sk_X509_ATTRIBUTE_free(sk);
	return(NULL);
}

STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x,
			const ASN1_OBJECT *obj, int type,
			const unsigned char *bytes, int len)
{
	X509_ATTRIBUTE *attr;
	STACK_OF(X509_ATTRIBUTE) *ret;
	attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len);
	if(!attr) return 0;
	ret = X509at_add1_attr(x, attr);
	X509_ATTRIBUTE_free(attr);
	return ret;
}

STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x,
			int nid, int type,
			const unsigned char *bytes, int len)
{
	X509_ATTRIBUTE *attr;
	STACK_OF(X509_ATTRIBUTE) *ret;
	attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len);
	if(!attr) return 0;
	ret = X509at_add1_attr(x, attr);
	X509_ATTRIBUTE_free(attr);
	return ret;
}

STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x,
			const char *attrname, int type,
			const unsigned char *bytes, int len)
{
	X509_ATTRIBUTE *attr;
	STACK_OF(X509_ATTRIBUTE) *ret;
	attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len);
	if(!attr) return 0;
	ret = X509at_add1_attr(x, attr);
	X509_ATTRIBUTE_free(attr);
	return ret;
}

X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
	     int atrtype, const void *data, int len)
{
	ASN1_OBJECT *obj;
	X509_ATTRIBUTE *ret;

	obj=OBJ_nid2obj(nid);
	if (obj == NULL)
		{
		X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_NID,X509_R_UNKNOWN_NID);
		return(NULL);
		}
	ret=X509_ATTRIBUTE_create_by_OBJ(attr,obj,atrtype,data,len);
	if (ret == NULL) ASN1_OBJECT_free(obj);
	return(ret);
}

X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
	     const ASN1_OBJECT *obj, int atrtype, const void *data, int len)
{
	X509_ATTRIBUTE *ret;

	if ((attr == NULL) || (*attr == NULL))
		{
		if ((ret=X509_ATTRIBUTE_new()) == NULL)
			{
			X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ,ERR_R_MALLOC_FAILURE);
			return(NULL);
			}
		}
	else
		ret= *attr;

	if (!X509_ATTRIBUTE_set1_object(ret,obj))
		goto err;
	if (!X509_ATTRIBUTE_set1_data(ret,atrtype,data,len))
		goto err;
	
	if ((attr != NULL) && (*attr == NULL)) *attr=ret;
	return(ret);
err:
	if ((attr == NULL) || (ret != *attr))
		X509_ATTRIBUTE_free(ret);
	return(NULL);
}

X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
		const char *atrname, int type, const unsigned char *bytes, int len)
	{
	ASN1_OBJECT *obj;
	X509_ATTRIBUTE *nattr;

	obj=OBJ_txt2obj(atrname, 0);
	if (obj == NULL)
		{
		X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT,
						X509_R_INVALID_FIELD_NAME);
		ERR_add_error_data(2, "name=", atrname);
		return(NULL);
		}
	nattr = X509_ATTRIBUTE_create_by_OBJ(attr,obj,type,bytes,len);
	ASN1_OBJECT_free(obj);
	return nattr;
	}

int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj)
{
	if ((attr == NULL) || (obj == NULL))
		return(0);
	ASN1_OBJECT_free(attr->object);
	attr->object=OBJ_dup(obj);
	return(1);
}

int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len)
{
	ASN1_TYPE *ttmp;
	ASN1_STRING *stmp;
	int atype;
	if (!attr) return 0;
	if(attrtype & MBSTRING_FLAG) {
		stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype,
						OBJ_obj2nid(attr->object));
		if(!stmp) {
			X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_ASN1_LIB);
			return 0;
		}
		atype = stmp->type;
	} else {
		if(!(stmp = ASN1_STRING_type_new(attrtype))) goto err;
		if(!ASN1_STRING_set(stmp, data, len)) goto err;
		atype = attrtype;
	}
	if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err;
	if(!(ttmp = ASN1_TYPE_new())) goto err;
	if(!sk_ASN1_TYPE_push(attr->value.set, ttmp)) goto err;
	attr->single = 0;
	ASN1_TYPE_set(ttmp, atype, stmp);
	return 1;
	err:
	X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_MALLOC_FAILURE);
	return 0;
}

int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr)
{
	if(!attr->single) return sk_ASN1_TYPE_num(attr->value.set);
	if(attr->value.single) return 1;
	return 0;
}

ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr)
{
	if (attr == NULL) return(NULL);
	return(attr->object);
}

void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
					int atrtype, void *data)
{
	ASN1_TYPE *ttmp;
	ttmp = X509_ATTRIBUTE_get0_type(attr, idx);
	if(!ttmp) return NULL;
	if(atrtype != ASN1_TYPE_get(ttmp)){
		X509err(X509_F_X509_ATTRIBUTE_GET0_DATA, X509_R_WRONG_TYPE);
		return NULL;
	}
	return ttmp->value.ptr;
}

ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx)
{
	if (attr == NULL) return(NULL);
	if(idx >= X509_ATTRIBUTE_count(attr)) return NULL;
	if(!attr->single) return sk_ASN1_TYPE_value(attr->value.set, idx);
	else return attr->value.single;
}
