1 // Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <openssl/asn1.h>
16 
17 #include <assert.h>
18 
19 #include <openssl/asn1t.h>
20 #include <openssl/mem.h>
21 
22 #include "internal.h"
23 
24 // Free up an ASN1 structure
25 
ASN1_item_free(ASN1_VALUE * val,const ASN1_ITEM * it)26 void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it) {
27   ASN1_item_ex_free(&val, it);
28 }
29 
ASN1_item_ex_free(ASN1_VALUE ** pval,const ASN1_ITEM * it)30 void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) {
31   if (!pval) {
32     return;
33   }
34   if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) {
35     return;
36   }
37 
38   switch (it->itype) {
39     case ASN1_ITYPE_PRIMITIVE:
40       if (it->templates) {
41         ASN1_template_free(pval, it->templates);
42       } else {
43         ASN1_primitive_free(pval, it);
44       }
45       break;
46 
47     case ASN1_ITYPE_MSTRING:
48       ASN1_primitive_free(pval, it);
49       break;
50 
51     case ASN1_ITYPE_CHOICE: {
52       const ASN1_AUX *aux = reinterpret_cast<const ASN1_AUX *>(it->funcs);
53       ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL;
54       if (asn1_cb) {
55         if (asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL) == 2) {
56           return;
57         }
58       }
59       int i = asn1_get_choice_selector(pval, it);
60       if ((i >= 0) && (i < it->tcount)) {
61         const ASN1_TEMPLATE *tt = it->templates + i;
62         ASN1_VALUE **pchval = asn1_get_field_ptr(pval, tt);
63         ASN1_template_free(pchval, tt);
64       }
65       if (asn1_cb) {
66         asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
67       }
68       OPENSSL_free(*pval);
69       *pval = NULL;
70       break;
71     }
72 
73     case ASN1_ITYPE_EXTERN: {
74       const ASN1_EXTERN_FUNCS *ef =
75           reinterpret_cast<const ASN1_EXTERN_FUNCS *>(it->funcs);
76       if (ef && ef->asn1_ex_free) {
77         ef->asn1_ex_free(pval, it);
78       }
79       break;
80     }
81 
82     case ASN1_ITYPE_SEQUENCE: {
83       if (!asn1_refcount_dec_and_test_zero(pval, it)) {
84         return;
85       }
86       const ASN1_AUX *aux = reinterpret_cast<const ASN1_AUX *>(it->funcs);
87       ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL;
88       if (asn1_cb) {
89         if (asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL) == 2) {
90           return;
91         }
92       }
93       asn1_enc_free(pval, it);
94       // If we free up as normal we will invalidate any ANY DEFINED BY
95       // field and we wont be able to determine the type of the field it
96       // defines. So free up in reverse order.
97       for (int i = it->tcount - 1; i >= 0; i--) {
98         const ASN1_TEMPLATE *seqtt = asn1_do_adb(pval, &it->templates[i], 0);
99         if (!seqtt) {
100           continue;
101         }
102         ASN1_VALUE **pseqval = asn1_get_field_ptr(pval, seqtt);
103         ASN1_template_free(pseqval, seqtt);
104       }
105       if (asn1_cb) {
106         asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
107       }
108       OPENSSL_free(*pval);
109       *pval = NULL;
110       break;
111     }
112   }
113 }
114 
ASN1_template_free(ASN1_VALUE ** pval,const ASN1_TEMPLATE * tt)115 void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) {
116   if (tt->flags & ASN1_TFLG_SK_MASK) {
117     STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
118     for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
119       ASN1_VALUE *vtmp = sk_ASN1_VALUE_value(sk, i);
120       ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item));
121     }
122     sk_ASN1_VALUE_free(sk);
123     *pval = NULL;
124   } else {
125     ASN1_item_ex_free(pval, ASN1_ITEM_ptr(tt->item));
126   }
127 }
128 
ASN1_primitive_free(ASN1_VALUE ** pval,const ASN1_ITEM * it)129 void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) {
130   // Historically, |it->funcs| for primitive types contained an
131   // |ASN1_PRIMITIVE_FUNCS| table of calbacks.
132   assert(it->funcs == NULL);
133 
134   int utype = it->itype == ASN1_ITYPE_MSTRING ? -1 : it->utype;
135   switch (utype) {
136     case V_ASN1_OBJECT:
137       ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
138       break;
139 
140     case V_ASN1_BOOLEAN:
141       if (it) {
142         *(ASN1_BOOLEAN *)pval = (ASN1_BOOLEAN)it->size;
143       } else {
144         *(ASN1_BOOLEAN *)pval = ASN1_BOOLEAN_NONE;
145       }
146       return;
147 
148     case V_ASN1_NULL:
149       break;
150 
151     case V_ASN1_ANY:
152       if (*pval != NULL) {
153         asn1_type_cleanup((ASN1_TYPE *)*pval);
154         OPENSSL_free(*pval);
155       }
156       break;
157 
158     default:
159       ASN1_STRING_free((ASN1_STRING *)*pval);
160       *pval = NULL;
161       break;
162   }
163   *pval = NULL;
164 }
165