/* tasn_fre.c */
/*
 * Written by Dr Stephen N Henson (steve@openssl.org) 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 <openssl/opensslconf.h>
#if !defined(OPENSSL_SYS_STARBOARD)
#include <stddef.h>
#endif  // !defined(OPENSSL_SYS_STARBOARD)
#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 ((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 = &typ->value.asn1_value;
        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;
}
