1 /* 2 * Copyright 2000-2024 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 18 void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it) 19 { 20 ossl_asn1_item_embed_free(&val, it, 0); 21 } 22 23 void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) 24 { 25 ossl_asn1_item_embed_free(pval, it, 0); 26 } 27 28 void 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) { 89 /* if error or ref-counter > 0 */ 90 OPENSSL_assert(embed == 0); 91 *pval = NULL; 92 return; 93 } 94 if (asn1_cb) { 95 i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); 96 if (i == 2) 97 return; 98 } 99 ossl_asn1_enc_free(pval, it); 100 /* 101 * If we free up as normal we will invalidate any ANY DEFINED BY 102 * field and we won't be able to determine the type of the field it 103 * defines. So free up in reverse order. 104 */ 105 tt = it->templates + it->tcount; 106 for (i = 0; i < it->tcount; i++) { 107 ASN1_VALUE **pseqval; 108 109 tt--; 110 seqtt = ossl_asn1_do_adb(*pval, tt, 0); 111 if (!seqtt) 112 continue; 113 pseqval = ossl_asn1_get_field_ptr(pval, seqtt); 114 ossl_asn1_template_free(pseqval, seqtt); 115 } 116 if (asn1_cb) 117 asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); 118 if (embed == 0) { 119 OPENSSL_free(*pval); 120 *pval = NULL; 121 } 122 break; 123 } 124 } 125 126 void ossl_asn1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 127 { 128 int embed = tt->flags & ASN1_TFLG_EMBED; 129 ASN1_VALUE *tval; 130 if (embed) { 131 tval = (ASN1_VALUE *)pval; 132 pval = &tval; 133 } 134 if (tt->flags & ASN1_TFLG_SK_MASK) { 135 STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; 136 int i; 137 138 for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) { 139 ASN1_VALUE *vtmp = sk_ASN1_VALUE_value(sk, i); 140 141 ossl_asn1_item_embed_free(&vtmp, ASN1_ITEM_ptr(tt->item), embed); 142 } 143 sk_ASN1_VALUE_free(sk); 144 *pval = NULL; 145 } else { 146 ossl_asn1_item_embed_free(pval, ASN1_ITEM_ptr(tt->item), embed); 147 } 148 } 149 150 void ossl_asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) 151 { 152 int utype; 153 154 /* Special case: if 'it' is a primitive with a free_func, use that. */ 155 if (it) { 156 const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; 157 158 if (embed) { 159 if (pf && pf->prim_clear) { 160 pf->prim_clear(pval, it); 161 return; 162 } 163 } else if (pf && pf->prim_free) { 164 pf->prim_free(pval, it); 165 return; 166 } 167 } 168 169 /* Special case: if 'it' is NULL, free contents of ASN1_TYPE */ 170 if (!it) { 171 ASN1_TYPE *typ = (ASN1_TYPE *)*pval; 172 173 utype = typ->type; 174 pval = &typ->value.asn1_value; 175 if (*pval == NULL) 176 return; 177 } else if (it->itype == ASN1_ITYPE_MSTRING) { 178 utype = -1; 179 if (*pval == NULL) 180 return; 181 } else { 182 utype = it->utype; 183 if ((utype != V_ASN1_BOOLEAN) && *pval == NULL) 184 return; 185 } 186 187 switch (utype) { 188 case V_ASN1_OBJECT: 189 ASN1_OBJECT_free((ASN1_OBJECT *)*pval); 190 break; 191 192 case V_ASN1_BOOLEAN: 193 if (it) 194 *(ASN1_BOOLEAN *)pval = it->size; 195 else 196 *(ASN1_BOOLEAN *)pval = -1; 197 return; 198 199 case V_ASN1_NULL: 200 break; 201 202 case V_ASN1_ANY: 203 ossl_asn1_primitive_free(pval, NULL, 0); 204 OPENSSL_free(*pval); 205 break; 206 207 default: 208 ossl_asn1_string_embed_free((ASN1_STRING *)*pval, embed); 209 break; 210 } 211 *pval = NULL; 212 } 213