tasn_fre.c revision 302408
1147072Sbrooks/* tasn_fre.c */ 2147072Sbrooks/* 3147072Sbrooks * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4147072Sbrooks * 2000. 5147072Sbrooks */ 6147072Sbrooks/* ==================================================================== 7147072Sbrooks * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 8147072Sbrooks * 9147072Sbrooks * Redistribution and use in source and binary forms, with or without 10147072Sbrooks * modification, are permitted provided that the following conditions 11147072Sbrooks * are met: 12147072Sbrooks * 13147072Sbrooks * 1. Redistributions of source code must retain the above copyright 14147072Sbrooks * notice, this list of conditions and the following disclaimer. 15147072Sbrooks * 16147072Sbrooks * 2. Redistributions in binary form must reproduce the above copyright 17147072Sbrooks * notice, this list of conditions and the following disclaimer in 18147072Sbrooks * the documentation and/or other materials provided with the 19147072Sbrooks * distribution. 20147072Sbrooks * 21147072Sbrooks * 3. All advertising materials mentioning features or use of this 22147072Sbrooks * software must display the following acknowledgment: 23147072Sbrooks * "This product includes software developed by the OpenSSL Project 24147072Sbrooks * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25147072Sbrooks * 26147072Sbrooks * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27147072Sbrooks * endorse or promote products derived from this software without 28147072Sbrooks * prior written permission. For written permission, please contact 29147072Sbrooks * licensing@OpenSSL.org. 30147072Sbrooks * 31147072Sbrooks * 5. Products derived from this software may not be called "OpenSSL" 32147072Sbrooks * nor may "OpenSSL" appear in their names without prior written 33147072Sbrooks * permission of the OpenSSL Project. 34147072Sbrooks * 35147072Sbrooks * 6. Redistributions of any form whatsoever must retain the following 36147072Sbrooks * acknowledgment: 37147072Sbrooks * "This product includes software developed by the OpenSSL Project 38147072Sbrooks * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39147072Sbrooks * 40147072Sbrooks * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41147072Sbrooks * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42147072Sbrooks * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43149399Sbrooks * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44149399Sbrooks * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45149399Sbrooks * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46147072Sbrooks * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47147072Sbrooks * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48147072Sbrooks * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49147072Sbrooks * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50147072Sbrooks * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51147072Sbrooks * OF THE POSSIBILITY OF SUCH DAMAGE. 52147072Sbrooks * ==================================================================== 53147072Sbrooks * 54147072Sbrooks * This product includes cryptographic software written by Eric Young 55147072Sbrooks * (eay@cryptsoft.com). This product includes software written by Tim 56147072Sbrooks * Hudson (tjh@cryptsoft.com). 57147072Sbrooks * 58147072Sbrooks */ 59147072Sbrooks 60147072Sbrooks#include <stddef.h> 61147072Sbrooks#include <openssl/asn1.h> 62147072Sbrooks#include <openssl/asn1t.h> 63147072Sbrooks#include <openssl/objects.h> 64147072Sbrooks 65147072Sbrooksstatic void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, 66147072Sbrooks int combine); 67147072Sbrooks 68147072Sbrooks/* Free up an ASN1 structure */ 69147072Sbrooks 70147072Sbrooksvoid ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it) 71147072Sbrooks{ 72147072Sbrooks asn1_item_combine_free(&val, it, 0); 73147072Sbrooks} 74147072Sbrooks 75147072Sbrooksvoid ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) 76147072Sbrooks{ 77147072Sbrooks asn1_item_combine_free(pval, it, 0); 78147072Sbrooks} 79147072Sbrooks 80148411Sbrooksstatic void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, 81147072Sbrooks int combine) 82147072Sbrooks{ 83147072Sbrooks const ASN1_TEMPLATE *tt = NULL, *seqtt; 84147072Sbrooks const ASN1_EXTERN_FUNCS *ef; 85147072Sbrooks const ASN1_COMPAT_FUNCS *cf; 86147072Sbrooks const ASN1_AUX *aux = it->funcs; 87147072Sbrooks ASN1_aux_cb *asn1_cb; 88147072Sbrooks int i; 89147072Sbrooks if (!pval) 90147072Sbrooks return; 91147072Sbrooks if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) 92147072Sbrooks return; 93147072Sbrooks if (aux && aux->asn1_cb) 94147072Sbrooks asn1_cb = aux->asn1_cb; 95147072Sbrooks else 96147072Sbrooks asn1_cb = 0; 97147072Sbrooks 98147072Sbrooks switch (it->itype) { 99147072Sbrooks 100147072Sbrooks case ASN1_ITYPE_PRIMITIVE: 101147072Sbrooks if (it->templates) 102147072Sbrooks ASN1_template_free(pval, it->templates); 103147072Sbrooks else 104147072Sbrooks ASN1_primitive_free(pval, it); 105147072Sbrooks break; 106147072Sbrooks 107147072Sbrooks case ASN1_ITYPE_MSTRING: 108147072Sbrooks ASN1_primitive_free(pval, it); 109147072Sbrooks break; 110147072Sbrooks 111147072Sbrooks case ASN1_ITYPE_CHOICE: 112147072Sbrooks if (asn1_cb) { 113147072Sbrooks i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); 114147072Sbrooks if (i == 2) 115147072Sbrooks return; 116147072Sbrooks } 117147072Sbrooks i = asn1_get_choice_selector(pval, it); 118147072Sbrooks if ((i >= 0) && (i < it->tcount)) { 119147072Sbrooks ASN1_VALUE **pchval; 120147072Sbrooks tt = it->templates + i; 121147072Sbrooks pchval = asn1_get_field_ptr(pval, tt); 122147072Sbrooks ASN1_template_free(pchval, tt); 123147072Sbrooks } 124147072Sbrooks if (asn1_cb) 125147072Sbrooks asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); 126147072Sbrooks if (!combine) { 127147072Sbrooks OPENSSL_free(*pval); 128147072Sbrooks *pval = NULL; 129147072Sbrooks } 130147072Sbrooks break; 131147072Sbrooks 132147072Sbrooks case ASN1_ITYPE_COMPAT: 133147072Sbrooks cf = it->funcs; 134147072Sbrooks if (cf && cf->asn1_free) 135147072Sbrooks cf->asn1_free(*pval); 136147072Sbrooks break; 137147072Sbrooks 138147072Sbrooks case ASN1_ITYPE_EXTERN: 139147072Sbrooks ef = it->funcs; 140147072Sbrooks if (ef && ef->asn1_ex_free) 141147072Sbrooks ef->asn1_ex_free(pval, it); 142147072Sbrooks break; 143147072Sbrooks 144147072Sbrooks case ASN1_ITYPE_NDEF_SEQUENCE: 145147072Sbrooks case ASN1_ITYPE_SEQUENCE: 146147072Sbrooks if (asn1_do_lock(pval, -1, it) > 0) 147147072Sbrooks return; 148147072Sbrooks if (asn1_cb) { 149147072Sbrooks i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); 150147072Sbrooks if (i == 2) 151147072Sbrooks return; 152147072Sbrooks } 153147072Sbrooks asn1_enc_free(pval, it); 154147072Sbrooks /* 155147072Sbrooks * If we free up as normal we will invalidate any ANY DEFINED BY 156147072Sbrooks * field and we wont be able to determine the type of the field it 157147072Sbrooks * defines. So free up in reverse order. 158147072Sbrooks */ 159147072Sbrooks tt = it->templates + it->tcount - 1; 160147072Sbrooks for (i = 0; i < it->tcount; tt--, i++) { 161147072Sbrooks ASN1_VALUE **pseqval; 162147072Sbrooks seqtt = asn1_do_adb(pval, tt, 0); 163147072Sbrooks if (!seqtt) 164147072Sbrooks continue; 165147072Sbrooks pseqval = asn1_get_field_ptr(pval, seqtt); 166147072Sbrooks ASN1_template_free(pseqval, seqtt); 167147072Sbrooks } 168147072Sbrooks if (asn1_cb) 169147072Sbrooks asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); 170147072Sbrooks if (!combine) { 171147072Sbrooks OPENSSL_free(*pval); 172147072Sbrooks *pval = NULL; 173147072Sbrooks } 174147072Sbrooks break; 175147072Sbrooks } 176147072Sbrooks} 177147072Sbrooks 178147072Sbrooksvoid ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 179147072Sbrooks{ 180147072Sbrooks int i; 181147072Sbrooks if (tt->flags & ASN1_TFLG_SK_MASK) { 182147072Sbrooks STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; 183147072Sbrooks for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) { 184147072Sbrooks ASN1_VALUE *vtmp; 185147072Sbrooks vtmp = sk_ASN1_VALUE_value(sk, i); 186147072Sbrooks asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item), 0); 187228259Sdumbbell } 188147072Sbrooks sk_ASN1_VALUE_free(sk); 189166602Semaste *pval = NULL; 190147072Sbrooks } else 191147072Sbrooks asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item), 192147072Sbrooks tt->flags & ASN1_TFLG_COMBINE); 193147072Sbrooks} 194147072Sbrooks 195147072Sbrooksvoid ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) 196147072Sbrooks{ 197147072Sbrooks int utype; 198147072Sbrooks if (it) { 199147072Sbrooks const ASN1_PRIMITIVE_FUNCS *pf; 200147072Sbrooks pf = it->funcs; 201147072Sbrooks if (pf && pf->prim_free) { 202147072Sbrooks pf->prim_free(pval, it); 203147072Sbrooks return; 204147072Sbrooks } 205147072Sbrooks } 206147072Sbrooks /* Special case: if 'it' is NULL free contents of ASN1_TYPE */ 207147072Sbrooks if (!it) { 208147072Sbrooks ASN1_TYPE *typ = (ASN1_TYPE *)*pval; 209147072Sbrooks utype = typ->type; 210147072Sbrooks pval = &typ->value.asn1_value; 211147072Sbrooks if (!*pval) 212147072Sbrooks return; 213147072Sbrooks } else if (it->itype == ASN1_ITYPE_MSTRING) { 214147072Sbrooks utype = -1; 215147072Sbrooks if (!*pval) 216147072Sbrooks return; 217147072Sbrooks } else { 218147072Sbrooks utype = it->utype; 219147072Sbrooks if ((utype != V_ASN1_BOOLEAN) && !*pval) 220147072Sbrooks return; 221147072Sbrooks } 222147072Sbrooks 223147072Sbrooks switch (utype) { 224147072Sbrooks case V_ASN1_OBJECT: 225147072Sbrooks ASN1_OBJECT_free((ASN1_OBJECT *)*pval); 226147072Sbrooks break; 227147072Sbrooks 228147072Sbrooks case V_ASN1_BOOLEAN: 229147072Sbrooks if (it) 230147072Sbrooks *(ASN1_BOOLEAN *)pval = it->size; 231147072Sbrooks else 232147072Sbrooks *(ASN1_BOOLEAN *)pval = -1; 233147072Sbrooks return; 234147072Sbrooks 235147072Sbrooks case V_ASN1_NULL: 236147072Sbrooks break; 237147072Sbrooks 238147072Sbrooks case V_ASN1_ANY: 239147072Sbrooks ASN1_primitive_free(pval, NULL); 240147072Sbrooks OPENSSL_free(*pval); 241147072Sbrooks break; 242147072Sbrooks 243147072Sbrooks default: 244147072Sbrooks ASN1_STRING_free((ASN1_STRING *)*pval); 245147072Sbrooks *pval = NULL; 246147072Sbrooks break; 247147072Sbrooks } 248147072Sbrooks *pval = NULL; 249147072Sbrooks} 250147072Sbrooks