1/* tasn_new.c */ 2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL 3 * project 2000. 4 */ 5/* ==================================================================== 6 * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * licensing@OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@cryptsoft.com). 56 * 57 */ 58 59 60#include <stddef.h> 61#include <openssl/asn1.h> 62#include <openssl/objects.h> 63#include <openssl/err.h> 64#include <openssl/asn1t.h> 65#include <string.h> 66 67static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine); 68static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 69static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); 70void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 71 72ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) 73{ 74 ASN1_VALUE *ret = NULL; 75 if(ASN1_item_ex_new(&ret, it) > 0) return ret; 76 return NULL; 77} 78 79/* Allocate an ASN1 structure */ 80 81int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 82{ 83 return asn1_item_ex_combine_new(pval, it, 0); 84} 85 86static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine) 87{ 88 const ASN1_TEMPLATE *tt = NULL; 89 const ASN1_COMPAT_FUNCS *cf; 90 const ASN1_EXTERN_FUNCS *ef; 91 const ASN1_AUX *aux = it->funcs; 92 ASN1_aux_cb *asn1_cb; 93 ASN1_VALUE **pseqval; 94 int i; 95 if(aux && aux->asn1_cb) asn1_cb = aux->asn1_cb; 96 else asn1_cb = 0; 97 98 if(!combine) *pval = NULL; 99 100#ifdef CRYPTO_MDEBUG 101 if(it->sname) CRYPTO_push_info(it->sname); 102#endif 103 104 switch(it->itype) { 105 106 case ASN1_ITYPE_EXTERN: 107 ef = it->funcs; 108 if(ef && ef->asn1_ex_new) { 109 if(!ef->asn1_ex_new(pval, it)) 110 goto memerr; 111 } 112 break; 113 114 case ASN1_ITYPE_COMPAT: 115 cf = it->funcs; 116 if(cf && cf->asn1_new) { 117 *pval = cf->asn1_new(); 118 if(!*pval) goto memerr; 119 } 120 break; 121 122 case ASN1_ITYPE_PRIMITIVE: 123 if(it->templates) { 124 if(!ASN1_template_new(pval, it->templates)) 125 goto memerr; 126 } else { 127 if(!ASN1_primitive_new(pval, it)) 128 goto memerr; 129 } 130 break; 131 132 case ASN1_ITYPE_MSTRING: 133 if(!ASN1_primitive_new(pval, it)) 134 goto memerr; 135 break; 136 137 case ASN1_ITYPE_CHOICE: 138 if(asn1_cb) { 139 i = asn1_cb(ASN1_OP_NEW_PRE, pval, it); 140 if(!i) goto auxerr; 141 if(i==2) { 142#ifdef CRYPTO_MDEBUG 143 if(it->sname) CRYPTO_pop_info(); 144#endif 145 return 1; 146 } 147 } 148 if(!combine) { 149 *pval = OPENSSL_malloc(it->size); 150 if(!*pval) goto memerr; 151 memset(*pval, 0, it->size); 152 } 153 asn1_set_choice_selector(pval, -1, it); 154 if(asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it)) 155 goto auxerr; 156 break; 157 158 case ASN1_ITYPE_SEQUENCE: 159 if(asn1_cb) { 160 i = asn1_cb(ASN1_OP_NEW_PRE, pval, it); 161 if(!i) goto auxerr; 162 if(i==2) { 163#ifdef CRYPTO_MDEBUG 164 if(it->sname) CRYPTO_pop_info(); 165#endif 166 return 1; 167 } 168 } 169 if(!combine) { 170 *pval = OPENSSL_malloc(it->size); 171 if(!*pval) goto memerr; 172 memset(*pval, 0, it->size); 173 asn1_do_lock(pval, 0, it); 174 asn1_enc_init(pval, it); 175 } 176 for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) { 177 pseqval = asn1_get_field_ptr(pval, tt); 178 if(!ASN1_template_new(pseqval, tt)) goto memerr; 179 } 180 if(asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it)) 181 goto auxerr; 182 break; 183 } 184#ifdef CRYPTO_MDEBUG 185 if(it->sname) CRYPTO_pop_info(); 186#endif 187 return 1; 188 189 memerr: 190 ASN1err(ASN1_F_ASN1_ITEM_NEW, ERR_R_MALLOC_FAILURE); 191#ifdef CRYPTO_MDEBUG 192 if(it->sname) CRYPTO_pop_info(); 193#endif 194 return 0; 195 196 auxerr: 197 ASN1err(ASN1_F_ASN1_ITEM_NEW, ASN1_R_AUX_ERROR); 198 ASN1_item_ex_free(pval, it); 199#ifdef CRYPTO_MDEBUG 200 if(it->sname) CRYPTO_pop_info(); 201#endif 202 return 0; 203 204} 205 206static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 207{ 208 const ASN1_EXTERN_FUNCS *ef; 209 210 switch(it->itype) { 211 212 case ASN1_ITYPE_EXTERN: 213 ef = it->funcs; 214 if(ef && ef->asn1_ex_clear) 215 ef->asn1_ex_clear(pval, it); 216 else *pval = NULL; 217 break; 218 219 220 case ASN1_ITYPE_PRIMITIVE: 221 if(it->templates) 222 asn1_template_clear(pval, it->templates); 223 else 224 asn1_primitive_clear(pval, it); 225 break; 226 227 case ASN1_ITYPE_MSTRING: 228 asn1_primitive_clear(pval, it); 229 break; 230 231 case ASN1_ITYPE_COMPAT: 232 case ASN1_ITYPE_CHOICE: 233 case ASN1_ITYPE_SEQUENCE: 234 *pval = NULL; 235 break; 236 } 237} 238 239 240int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 241{ 242 const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item); 243 int ret; 244 if(tt->flags & ASN1_TFLG_OPTIONAL) { 245 asn1_template_clear(pval, tt); 246 return 1; 247 } 248 /* If ANY DEFINED BY nothing to do */ 249 250 if(tt->flags & ASN1_TFLG_ADB_MASK) { 251 *pval = NULL; 252 return 1; 253 } 254#ifdef CRYPTO_MDEBUG 255 if(tt->field_name) CRYPTO_push_info(tt->field_name); 256#endif 257 /* If SET OF or SEQUENCE OF, its a STACK */ 258 if(tt->flags & ASN1_TFLG_SK_MASK) { 259 STACK_OF(ASN1_VALUE) *skval; 260 skval = sk_ASN1_VALUE_new_null(); 261 if(!skval) { 262 ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE); 263 ret = 0; 264 goto done; 265 } 266 *pval = (ASN1_VALUE *)skval; 267 ret = 1; 268 goto done; 269 } 270 /* Otherwise pass it back to the item routine */ 271 ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE); 272 done: 273#ifdef CRYPTO_MDEBUG 274 if(it->sname) CRYPTO_pop_info(); 275#endif 276 return ret; 277} 278 279static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 280{ 281 /* If ADB or STACK just NULL the field */ 282 if(tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK)) 283 *pval = NULL; 284 else 285 asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item)); 286} 287 288 289/* NB: could probably combine most of the real XXX_new() behaviour and junk all the old 290 * functions. 291 */ 292 293int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 294{ 295 ASN1_TYPE *typ; 296 int utype; 297 const ASN1_PRIMITIVE_FUNCS *pf; 298 pf = it->funcs; 299 if(pf && pf->prim_new) return pf->prim_new(pval, it); 300 if(!it || (it->itype == ASN1_ITYPE_MSTRING)) utype = -1; 301 else utype = it->utype; 302 switch(utype) { 303 case V_ASN1_OBJECT: 304 *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef); 305 return 1; 306 307 case V_ASN1_BOOLEAN: 308 if (it) 309 *(ASN1_BOOLEAN *)pval = it->size; 310 else 311 *(ASN1_BOOLEAN *)pval = -1; 312 return 1; 313 314 case V_ASN1_NULL: 315 *pval = (ASN1_VALUE *)1; 316 return 1; 317 318 case V_ASN1_ANY: 319 typ = OPENSSL_malloc(sizeof(ASN1_TYPE)); 320 if(!typ) return 0; 321 typ->value.ptr = NULL; 322 typ->type = -1; 323 *pval = (ASN1_VALUE *)typ; 324 break; 325 326 default: 327 *pval = (ASN1_VALUE *)ASN1_STRING_type_new(utype); 328 break; 329 } 330 if(*pval) return 1; 331 return 0; 332} 333 334void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 335{ 336 int utype; 337 const ASN1_PRIMITIVE_FUNCS *pf; 338 pf = it->funcs; 339 if(pf) { 340 if(pf->prim_clear) 341 pf->prim_clear(pval, it); 342 else 343 *pval = NULL; 344 return; 345 } 346 if(!it || (it->itype == ASN1_ITYPE_MSTRING)) utype = -1; 347 else utype = it->utype; 348 if(utype == V_ASN1_BOOLEAN) 349 *(ASN1_BOOLEAN *)pval = it->size; 350 else *pval = NULL; 351} 352