/* tasn_fre.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 <stddef.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>

static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine);

/* Free up an ASN1 structure */

void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
	{
	asn1_item_combine_free(&val, it, 0);
	}

void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
	{
	asn1_item_combine_free(pval, it, 0);
	}

static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
	{
	const ASN1_TEMPLATE *tt = NULL, *seqtt;
	const ASN1_EXTERN_FUNCS *ef;
	const ASN1_COMPAT_FUNCS *cf;
	const ASN1_AUX *aux = it->funcs;
	ASN1_aux_cb *asn1_cb;
	int i;
	if (!pval)
		return;
	if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
		return;
	if (aux && aux->asn1_cb)
		asn1_cb = aux->asn1_cb;
	else
		asn1_cb = 0;

	switch(it->itype)
		{

		case ASN1_ITYPE_PRIMITIVE:
		if (it->templates)
			ASN1_template_free(pval, it->templates);
		else
			ASN1_primitive_free(pval, it);
		break;

		case ASN1_ITYPE_MSTRING:
		ASN1_primitive_free(pval, it);
		break;

		case ASN1_ITYPE_CHOICE:
		if (asn1_cb)
			{
			i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
			if (i == 2)
				return;
			}
		i = asn1_get_choice_selector(pval, it);
		if (asn1_cb)
			asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
		if ((i >= 0) && (i < it->tcount))
			{
			ASN1_VALUE **pchval;
			tt = it->templates + i;
			pchval = asn1_get_field_ptr(pval, tt);
			ASN1_template_free(pchval, tt);
			}
		if (asn1_cb)
			asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
		if (!combine)
			{
			OPENSSL_free(*pval);
			*pval = NULL;
			}
		break;

		case ASN1_ITYPE_COMPAT:
		cf = it->funcs;
		if (cf && cf->asn1_free)
			cf->asn1_free(*pval);
		break;

		case ASN1_ITYPE_EXTERN:
		ef = it->funcs;
		if (ef && ef->asn1_ex_free)
			ef->asn1_ex_free(pval, it);
		break;

		case ASN1_ITYPE_NDEF_SEQUENCE:
		case ASN1_ITYPE_SEQUENCE:
		if (asn1_do_lock(pval, -1, it) > 0)
			return;
		if (asn1_cb)
			{
			i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
			if (i == 2)
				return;
			}		
		asn1_enc_free(pval, it);
		/* If we free up as normal we will invalidate any
		 * ANY DEFINED BY field and we wont be able to 
		 * determine the type of the field it defines. So
		 * free up in reverse order.
		 */
		tt = it->templates + it->tcount - 1;
		for (i = 0; i < it->tcount; tt--, i++)
			{
			ASN1_VALUE **pseqval;
			seqtt = asn1_do_adb(pval, tt, 0);
			if (!seqtt)
				continue;
			pseqval = asn1_get_field_ptr(pval, seqtt);
			ASN1_template_free(pseqval, seqtt);
			}
		if (asn1_cb)
			asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
		if (!combine)
			{
			OPENSSL_free(*pval);
			*pval = NULL;
			}
		break;
		}
	}

void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
	{
	int i;
	if (tt->flags & ASN1_TFLG_SK_MASK)
		{
		STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
		for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
			{
			ASN1_VALUE *vtmp;
			vtmp = sk_ASN1_VALUE_value(sk, i);
			asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item),
									0);
			}
		sk_ASN1_VALUE_free(sk);
		*pval = NULL;
		}
	else
		asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item),
						tt->flags & ASN1_TFLG_COMBINE);
	}

void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
	{
	int utype;
	if (it)
		{
		const ASN1_PRIMITIVE_FUNCS *pf;
		pf = it->funcs;
		if (pf && pf->prim_free)
			{
			pf->prim_free(pval, it);
			return;
			}
		}
	/* Special case: if 'it' is NULL free contents of ASN1_TYPE */
	if (!it)
		{
		ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
		utype = typ->type;
		pval = (ASN1_VALUE **)&typ->value.ptr;
		if (!*pval)
			return;
		}
	else if (it->itype == ASN1_ITYPE_MSTRING)
		{
		utype = -1;
		if (!*pval)
			return;
		}
	else
		{
		utype = it->utype;
		if ((utype != V_ASN1_BOOLEAN) && !*pval)
			return;
		}

	switch(utype)
		{
		case V_ASN1_OBJECT:
		ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
		break;

		case V_ASN1_BOOLEAN:
		if (it)
			*(ASN1_BOOLEAN *)pval = it->size;
		else
			*(ASN1_BOOLEAN *)pval = -1;
		return;

		case V_ASN1_NULL:
		break;

		case V_ASN1_ANY:
		ASN1_primitive_free(pval, NULL);
		OPENSSL_free(*pval);
		break;

		default:
		ASN1_STRING_free((ASN1_STRING *)*pval);
		*pval = NULL;
		break;
		}
	*pval = NULL;
	}
