1/* 2 * Copyright (c) 2011-12 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* tasn_fre.c */ 24/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 25 * project 2000. 26 */ 27/* ==================================================================== 28 * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 29 * 30 * Redistribution and use in source and binary forms, with or without 31 * modification, are permitted provided that the following conditions 32 * are met: 33 * 34 * 1. Redistributions of source code must retain the above copyright 35 * notice, this list of conditions and the following disclaimer. 36 * 37 * 2. Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in 39 * the documentation and/or other materials provided with the 40 * distribution. 41 * 42 * 3. All advertising materials mentioning features or use of this 43 * software must display the following acknowledgment: 44 * "This product includes software developed by the OpenSSL Project 45 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 46 * 47 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 48 * endorse or promote products derived from this software without 49 * prior written permission. For written permission, please contact 50 * licensing@OpenSSL.org. 51 * 52 * 5. Products derived from this software may not be called "OpenSSL" 53 * nor may "OpenSSL" appear in their names without prior written 54 * permission of the OpenSSL Project. 55 * 56 * 6. Redistributions of any form whatsoever must retain the following 57 * acknowledgment: 58 * "This product includes software developed by the OpenSSL Project 59 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 60 * 61 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 62 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 63 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 64 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 65 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 66 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 67 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 68 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 69 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 70 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 71 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 72 * OF THE POSSIBILITY OF SUCH DAMAGE. 73 * ==================================================================== 74 * 75 * This product includes cryptographic software written by Eric Young 76 * (eay@cryptsoft.com). This product includes software written by Tim 77 * Hudson (tjh@cryptsoft.com). 78 * 79 */ 80 81 82#include <stddef.h> 83#include <stdio.h> 84#include <string.h> 85#include <time.h> 86 87#if 0 88#include <openssl/asn1.h> 89#include <openssl/asn1t.h> 90#include <openssl/objects.h> 91#else 92#include "cs-asn1.h" 93#include "cs-asn1t.h" 94#include "cs-objects.h" 95#endif 96 97static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine); 98 99/* Free up an ASN1 structure */ 100 101void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it) 102 { 103 asn1_item_combine_free(&val, it, 0); 104 } 105 106void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) 107 { 108 asn1_item_combine_free(pval, it, 0); 109 } 110 111static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine) 112 { 113 const ASN1_TEMPLATE *tt = NULL, *seqtt; 114 const ASN1_EXTERN_FUNCS *ef; 115 const ASN1_COMPAT_FUNCS *cf; 116 const ASN1_AUX *aux = it->funcs; 117 ASN1_aux_cb *asn1_cb; 118 int i; 119 if (!pval) 120 return; 121 if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) 122 return; 123 if (aux && aux->asn1_cb) 124 asn1_cb = aux->asn1_cb; 125 else 126 asn1_cb = 0; 127 128 switch(it->itype) 129 { 130 131 case ASN1_ITYPE_PRIMITIVE: 132 if (it->templates) 133 ASN1_template_free(pval, it->templates); 134 else 135 ASN1_primitive_free(pval, it); 136 break; 137 138 case ASN1_ITYPE_MSTRING: 139 ASN1_primitive_free(pval, it); 140 break; 141 142 case ASN1_ITYPE_CHOICE: 143 if (asn1_cb) 144 { 145 i = asn1_cb(ASN1_OP_FREE_PRE, pval, it); 146 if (i == 2) 147 return; 148 } 149 i = asn1_get_choice_selector(pval, it); 150 if ((i >= 0) && (i < it->tcount)) 151 { 152 ASN1_VALUE **pchval; 153 tt = it->templates + i; 154 pchval = asn1_get_field_ptr(pval, tt); 155 ASN1_template_free(pchval, tt); 156 } 157 if (asn1_cb) 158 asn1_cb(ASN1_OP_FREE_POST, pval, it); 159 if (!combine) 160 { 161 free(*pval); 162 *pval = NULL; 163 } 164 break; 165 166 case ASN1_ITYPE_COMPAT: 167 cf = it->funcs; 168 if (cf && cf->asn1_free) 169 cf->asn1_free(*pval); 170 break; 171 172 case ASN1_ITYPE_EXTERN: 173 ef = it->funcs; 174 if (ef && ef->asn1_ex_free) 175 ef->asn1_ex_free(pval, it); 176 break; 177 178 case ASN1_ITYPE_NDEF_SEQUENCE: 179 case ASN1_ITYPE_SEQUENCE: 180 if (asn1_do_lock(pval, -1, it) > 0) 181 return; 182 if (asn1_cb) 183 { 184 i = asn1_cb(ASN1_OP_FREE_PRE, pval, it); 185 if (i == 2) 186 return; 187 } 188 asn1_enc_free(pval, it); 189 /* If we free up as normal we will invalidate any 190 * ANY DEFINED BY field and we wont be able to 191 * determine the type of the field it defines. So 192 * free up in reverse order. 193 */ 194 tt = it->templates + it->tcount - 1; 195 for (i = 0; i < it->tcount; tt--, i++) 196 { 197 ASN1_VALUE **pseqval; 198 seqtt = asn1_do_adb(pval, tt, 0); 199 if (!seqtt) 200 continue; 201 pseqval = asn1_get_field_ptr(pval, seqtt); 202 ASN1_template_free(pseqval, seqtt); 203 } 204 if (asn1_cb) 205 asn1_cb(ASN1_OP_FREE_POST, pval, it); 206 if (!combine) 207 { 208 free(*pval); 209 *pval = NULL; 210 } 211 break; 212 } 213 } 214 215void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 216 { 217 int i; 218 if (tt->flags & ASN1_TFLG_SK_MASK) 219 { 220 STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; 221 for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) 222 { 223 ASN1_VALUE *vtmp; 224 vtmp = sk_ASN1_VALUE_value(sk, i); 225 asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item), 226 0); 227 } 228 sk_ASN1_VALUE_free(sk); 229 *pval = NULL; 230 } 231 else 232 asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item), 233 tt->flags & ASN1_TFLG_COMBINE); 234 } 235 236void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) 237 { 238 int utype; 239 if (it) 240 { 241 const ASN1_PRIMITIVE_FUNCS *pf; 242 pf = it->funcs; 243 if (pf && pf->prim_free) 244 { 245 pf->prim_free(pval, it); 246 return; 247 } 248 } 249 /* Special case: if 'it' is NULL free contents of ASN1_TYPE */ 250 if (!it) 251 { 252 ASN1_TYPE *typ = (ASN1_TYPE *)*pval; 253 utype = typ->type; 254 pval = &typ->value.asn1_value; 255 if (!*pval) 256 return; 257 } 258 else if (it->itype == ASN1_ITYPE_MSTRING) 259 { 260 utype = -1; 261 if (!*pval) 262 return; 263 } 264 else 265 { 266 utype = it->utype; 267 if ((utype != V_ASN1_BOOLEAN) && !*pval) 268 return; 269 } 270 271 switch(utype) 272 { 273 case V_ASN1_OBJECT: 274 ASN1_OBJECT_free((ASN1_OBJECT *)*pval); 275 break; 276 277 case V_ASN1_BOOLEAN: 278 if (it) 279 *(ASN1_BOOLEAN *)pval = it->size; 280 else 281 *(ASN1_BOOLEAN *)pval = -1; 282 return; 283 284 case V_ASN1_NULL: 285 break; 286 287 case V_ASN1_ANY: 288 ASN1_primitive_free(pval, NULL); 289 free(*pval); 290 break; 291 292 default: 293 ASN1_STRING_free((ASN1_STRING *)*pval); 294 *pval = NULL; 295 break; 296 } 297 *pval = NULL; 298 } 299