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