1/*
2 * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License").  You may not use
5 * this file except in compliance with the License.  You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <stddef.h>
11#include <openssl/asn1.h>
12#include <openssl/asn1t.h>
13#include <openssl/objects.h>
14#include "asn1_local.h"
15
16/* Free up an ASN1 structure */
17
18void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
19{
20    ossl_asn1_item_embed_free(&val, it, 0);
21}
22
23void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
24{
25    ossl_asn1_item_embed_free(pval, it, 0);
26}
27
28void ossl_asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
29{
30    const ASN1_TEMPLATE *tt = NULL, *seqtt;
31    const ASN1_EXTERN_FUNCS *ef;
32    const ASN1_AUX *aux = it->funcs;
33    ASN1_aux_cb *asn1_cb;
34    int i;
35
36    if (pval == NULL)
37        return;
38    if ((it->itype != ASN1_ITYPE_PRIMITIVE) && *pval == NULL)
39        return;
40    if (aux && aux->asn1_cb)
41        asn1_cb = aux->asn1_cb;
42    else
43        asn1_cb = 0;
44
45    switch (it->itype) {
46
47    case ASN1_ITYPE_PRIMITIVE:
48        if (it->templates)
49            ossl_asn1_template_free(pval, it->templates);
50        else
51            ossl_asn1_primitive_free(pval, it, embed);
52        break;
53
54    case ASN1_ITYPE_MSTRING:
55        ossl_asn1_primitive_free(pval, it, embed);
56        break;
57
58    case ASN1_ITYPE_CHOICE:
59        if (asn1_cb) {
60            i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
61            if (i == 2)
62                return;
63        }
64        i = ossl_asn1_get_choice_selector(pval, it);
65        if ((i >= 0) && (i < it->tcount)) {
66            ASN1_VALUE **pchval;
67
68            tt = it->templates + i;
69            pchval = ossl_asn1_get_field_ptr(pval, tt);
70            ossl_asn1_template_free(pchval, tt);
71        }
72        if (asn1_cb)
73            asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
74        if (embed == 0) {
75            OPENSSL_free(*pval);
76            *pval = NULL;
77        }
78        break;
79
80    case ASN1_ITYPE_EXTERN:
81        ef = it->funcs;
82        if (ef && ef->asn1_ex_free)
83            ef->asn1_ex_free(pval, it);
84        break;
85
86    case ASN1_ITYPE_NDEF_SEQUENCE:
87    case ASN1_ITYPE_SEQUENCE:
88        if (ossl_asn1_do_lock(pval, -1, it) != 0) /* if error or ref-counter > 0 */
89            return;
90        if (asn1_cb) {
91            i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
92            if (i == 2)
93                return;
94        }
95        ossl_asn1_enc_free(pval, it);
96        /*
97         * If we free up as normal we will invalidate any ANY DEFINED BY
98         * field and we won't be able to determine the type of the field it
99         * defines. So free up in reverse order.
100         */
101        tt = it->templates + it->tcount;
102        for (i = 0; i < it->tcount; i++) {
103            ASN1_VALUE **pseqval;
104
105            tt--;
106            seqtt = ossl_asn1_do_adb(*pval, tt, 0);
107            if (!seqtt)
108                continue;
109            pseqval = ossl_asn1_get_field_ptr(pval, seqtt);
110            ossl_asn1_template_free(pseqval, seqtt);
111        }
112        if (asn1_cb)
113            asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
114        if (embed == 0) {
115            OPENSSL_free(*pval);
116            *pval = NULL;
117        }
118        break;
119    }
120}
121
122void ossl_asn1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
123{
124    int embed = tt->flags & ASN1_TFLG_EMBED;
125    ASN1_VALUE *tval;
126    if (embed) {
127        tval = (ASN1_VALUE *)pval;
128        pval = &tval;
129    }
130    if (tt->flags & ASN1_TFLG_SK_MASK) {
131        STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
132        int i;
133
134        for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
135            ASN1_VALUE *vtmp = sk_ASN1_VALUE_value(sk, i);
136
137            ossl_asn1_item_embed_free(&vtmp, ASN1_ITEM_ptr(tt->item), embed);
138        }
139        sk_ASN1_VALUE_free(sk);
140        *pval = NULL;
141    } else {
142        ossl_asn1_item_embed_free(pval, ASN1_ITEM_ptr(tt->item), embed);
143    }
144}
145
146void ossl_asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
147{
148    int utype;
149
150    /* Special case: if 'it' is a primitive with a free_func, use that. */
151    if (it) {
152        const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
153
154        if (embed) {
155            if (pf && pf->prim_clear) {
156                pf->prim_clear(pval, it);
157                return;
158            }
159        } else if (pf && pf->prim_free) {
160            pf->prim_free(pval, it);
161            return;
162        }
163    }
164
165    /* Special case: if 'it' is NULL, free contents of ASN1_TYPE */
166    if (!it) {
167        ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
168
169        utype = typ->type;
170        pval = &typ->value.asn1_value;
171        if (*pval == NULL)
172            return;
173    } else if (it->itype == ASN1_ITYPE_MSTRING) {
174        utype = -1;
175        if (*pval == NULL)
176            return;
177    } else {
178        utype = it->utype;
179        if ((utype != V_ASN1_BOOLEAN) && *pval == NULL)
180            return;
181    }
182
183    switch (utype) {
184    case V_ASN1_OBJECT:
185        ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
186        break;
187
188    case V_ASN1_BOOLEAN:
189        if (it)
190            *(ASN1_BOOLEAN *)pval = it->size;
191        else
192            *(ASN1_BOOLEAN *)pval = -1;
193        return;
194
195    case V_ASN1_NULL:
196        break;
197
198    case V_ASN1_ANY:
199        ossl_asn1_primitive_free(pval, NULL, 0);
200        OPENSSL_free(*pval);
201        break;
202
203    default:
204        ossl_asn1_string_embed_free((ASN1_STRING *)*pval, embed);
205        break;
206    }
207    *pval = NULL;
208}
209