]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/asn1/tasn_fre.c
2 * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
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
11 #include <openssl/asn1.h>
12 #include <openssl/asn1t.h>
13 #include <openssl/objects.h>
14 #include "asn1_local.h"
16 /* Free up an ASN1 structure */
18 void ASN1_item_free(ASN1_VALUE
*val
, const ASN1_ITEM
*it
)
20 asn1_item_embed_free(&val
, it
, 0);
23 void ASN1_item_ex_free(ASN1_VALUE
**pval
, const ASN1_ITEM
*it
)
25 asn1_item_embed_free(pval
, it
, 0);
28 void asn1_item_embed_free(ASN1_VALUE
**pval
, const ASN1_ITEM
*it
, int embed
)
30 const ASN1_TEMPLATE
*tt
= NULL
, *seqtt
;
31 const ASN1_EXTERN_FUNCS
*ef
;
32 const ASN1_AUX
*aux
= it
->funcs
;
38 if ((it
->itype
!= ASN1_ITYPE_PRIMITIVE
) && *pval
== NULL
)
40 if (aux
&& aux
->asn1_cb
)
41 asn1_cb
= aux
->asn1_cb
;
47 case ASN1_ITYPE_PRIMITIVE
:
49 asn1_template_free(pval
, it
->templates
);
51 asn1_primitive_free(pval
, it
, embed
);
54 case ASN1_ITYPE_MSTRING
:
55 asn1_primitive_free(pval
, it
, embed
);
58 case ASN1_ITYPE_CHOICE
:
60 i
= asn1_cb(ASN1_OP_FREE_PRE
, pval
, it
, NULL
);
64 i
= asn1_get_choice_selector(pval
, it
);
65 if ((i
>= 0) && (i
< it
->tcount
)) {
68 tt
= it
->templates
+ i
;
69 pchval
= asn1_get_field_ptr(pval
, tt
);
70 asn1_template_free(pchval
, tt
);
73 asn1_cb(ASN1_OP_FREE_POST
, pval
, it
, NULL
);
80 case ASN1_ITYPE_EXTERN
:
82 if (ef
&& ef
->asn1_ex_free
)
83 ef
->asn1_ex_free(pval
, it
);
86 case ASN1_ITYPE_NDEF_SEQUENCE
:
87 case ASN1_ITYPE_SEQUENCE
:
88 if (asn1_do_lock(pval
, -1, it
) != 0) /* if error or ref-counter > 0 */
91 i
= asn1_cb(ASN1_OP_FREE_PRE
, pval
, it
, NULL
);
95 asn1_enc_free(pval
, it
);
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.
101 tt
= it
->templates
+ it
->tcount
;
102 for (i
= 0; i
< it
->tcount
; i
++) {
103 ASN1_VALUE
**pseqval
;
106 seqtt
= asn1_do_adb(*pval
, tt
, 0);
109 pseqval
= asn1_get_field_ptr(pval
, seqtt
);
110 asn1_template_free(pseqval
, seqtt
);
113 asn1_cb(ASN1_OP_FREE_POST
, pval
, it
, NULL
);
122 void asn1_template_free(ASN1_VALUE
**pval
, const ASN1_TEMPLATE
*tt
)
124 int embed
= tt
->flags
& ASN1_TFLG_EMBED
;
127 tval
= (ASN1_VALUE
*)pval
;
130 if (tt
->flags
& ASN1_TFLG_SK_MASK
) {
131 STACK_OF(ASN1_VALUE
) *sk
= (STACK_OF(ASN1_VALUE
) *)*pval
;
134 for (i
= 0; i
< sk_ASN1_VALUE_num(sk
); i
++) {
135 ASN1_VALUE
*vtmp
= sk_ASN1_VALUE_value(sk
, i
);
137 asn1_item_embed_free(&vtmp
, ASN1_ITEM_ptr(tt
->item
), embed
);
139 sk_ASN1_VALUE_free(sk
);
142 asn1_item_embed_free(pval
, ASN1_ITEM_ptr(tt
->item
), embed
);
146 void asn1_primitive_free(ASN1_VALUE
**pval
, const ASN1_ITEM
*it
, int embed
)
150 /* Special case: if 'it' is a primitive with a free_func, use that. */
152 const ASN1_PRIMITIVE_FUNCS
*pf
= it
->funcs
;
155 if (pf
&& pf
->prim_clear
) {
156 pf
->prim_clear(pval
, it
);
159 } else if (pf
&& pf
->prim_free
) {
160 pf
->prim_free(pval
, it
);
165 /* Special case: if 'it' is NULL, free contents of ASN1_TYPE */
167 ASN1_TYPE
*typ
= (ASN1_TYPE
*)*pval
;
170 pval
= &typ
->value
.asn1_value
;
173 } else if (it
->itype
== ASN1_ITYPE_MSTRING
) {
179 if ((utype
!= V_ASN1_BOOLEAN
) && *pval
== NULL
)
185 ASN1_OBJECT_free((ASN1_OBJECT
*)*pval
);
190 *(ASN1_BOOLEAN
*)pval
= it
->size
;
192 *(ASN1_BOOLEAN
*)pval
= -1;
199 asn1_primitive_free(pval
, NULL
, 0);
204 asn1_string_embed_free((ASN1_STRING
*)*pval
, embed
);