tasn_new.c revision 109998
1139826Simp/* tasn_new.c */ 252904Sshin/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL 352904Sshin * project 2000. 453541Sshin */ 552904Sshin/* ==================================================================== 652904Sshin * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 752904Sshin * 852904Sshin * Redistribution and use in source and binary forms, with or without 952904Sshin * modification, are permitted provided that the following conditions 1052904Sshin * are met: 1152904Sshin * 1252904Sshin * 1. Redistributions of source code must retain the above copyright 1352904Sshin * notice, this list of conditions and the following disclaimer. 1452904Sshin * 1552904Sshin * 2. Redistributions in binary form must reproduce the above copyright 1653541Sshin * notice, this list of conditions and the following disclaimer in 1752904Sshin * the documentation and/or other materials provided with the 1852904Sshin * distribution. 1952904Sshin * 2052904Sshin * 3. All advertising materials mentioning features or use of this 2152904Sshin * software must display the following acknowledgment: 2252904Sshin * "This product includes software developed by the OpenSSL Project 2352904Sshin * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 2452904Sshin * 2552904Sshin * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2652904Sshin * endorse or promote products derived from this software without 2752904Sshin * prior written permission. For written permission, please contact 28174510Sobrien * licensing@OpenSSL.org. 29174510Sobrien * 3052904Sshin * 5. Products derived from this software may not be called "OpenSSL" 3152904Sshin * nor may "OpenSSL" appear in their names without prior written 32139826Simp * permission of the OpenSSL Project. 3352904Sshin * 3452904Sshin * 6. Redistributions of any form whatsoever must retain the following 3552904Sshin * acknowledgment: 3652904Sshin * "This product includes software developed by the OpenSSL Project 3752904Sshin * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 3852904Sshin * 3952904Sshin * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 4052904Sshin * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4152904Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4252904Sshin * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4352904Sshin * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4452904Sshin * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4552904Sshin * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4652904Sshin * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4752904Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4852904Sshin * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 4952904Sshin * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 5052904Sshin * OF THE POSSIBILITY OF SUCH DAMAGE. 5152904Sshin * ==================================================================== 5252904Sshin * 5352904Sshin * This product includes cryptographic software written by Eric Young 5452904Sshin * (eay@cryptsoft.com). This product includes software written by Tim 5552904Sshin * Hudson (tjh@cryptsoft.com). 5652904Sshin * 5752904Sshin */ 5852904Sshin 5952904Sshin 6052904Sshin#include <stddef.h> 61174510Sobrien#include <openssl/asn1.h> 6252904Sshin#include <openssl/objects.h> 6352904Sshin#include <openssl/err.h> 6462587Sitojun#include <openssl/asn1t.h> 6578064Sume#include <string.h> 6657120Sshin 6757120Sshinstatic int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine); 6862587Sitojunstatic void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 6962587Sitojunstatic void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); 7062587Sitojunvoid asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 7152904Sshin 7252904SshinASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) 7378064Sume{ 7478064Sume ASN1_VALUE *ret = NULL; 7552904Sshin if(ASN1_item_ex_new(&ret, it) > 0) return ret; 7662587Sitojun return NULL; 77156865Ssuz} 7852904Sshin 7952904Sshin/* Allocate an ASN1 structure */ 80157209Sdwmalone 81218909Sbrucecint ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 82157209Sdwmalone{ 8352904Sshin return asn1_item_ex_combine_new(pval, it, 0); 8497181Smike} 8552904Sshin 8652904Sshinstatic int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine) 8752904Sshin{ 8852904Sshin const ASN1_TEMPLATE *tt = NULL; 8952904Sshin const ASN1_COMPAT_FUNCS *cf; 9097181Smike const ASN1_EXTERN_FUNCS *ef; 9152904Sshin const ASN1_AUX *aux = it->funcs; 9252904Sshin ASN1_aux_cb *asn1_cb; 9352904Sshin ASN1_VALUE **pseqval; 9452904Sshin int i; 9552904Sshin if(aux && aux->asn1_cb) asn1_cb = aux->asn1_cb; 9652904Sshin else asn1_cb = 0; 9797181Smike 9897181Smike if(!combine) *pval = NULL; 9997181Smike 10052904Sshin#ifdef CRYPTO_MDEBUG 10152904Sshin if(it->sname) CRYPTO_push_info(it->sname); 10252904Sshin#endif 10362587Sitojun 10495023Ssuz switch(it->itype) { 10562587Sitojun 10662587Sitojun case ASN1_ITYPE_EXTERN: 10762587Sitojun ef = it->funcs; 10852904Sshin if(ef && ef->asn1_ex_new) { 10952904Sshin if(!ef->asn1_ex_new(pval, it)) 11062587Sitojun goto memerr; 11152904Sshin } 11252904Sshin break; 11397181Smike 11497181Smike case ASN1_ITYPE_COMPAT: 11597181Smike cf = it->funcs; 11697181Smike if(cf && cf->asn1_new) { 11752904Sshin *pval = cf->asn1_new(); 11852904Sshin if(!*pval) goto memerr; 11997181Smike } 12062587Sitojun break; 12152904Sshin 12297181Smike case ASN1_ITYPE_PRIMITIVE: 12352904Sshin if(it->templates) { 124100503Sume if(!ASN1_template_new(pval, it->templates)) 12597181Smike goto memerr; 12697181Smike } else { 12797181Smike if(!ASN1_primitive_new(pval, it)) 12862587Sitojun goto memerr; 12997181Smike } 13052904Sshin break; 13152904Sshin 13252904Sshin case ASN1_ITYPE_MSTRING: 13352904Sshin if(!ASN1_primitive_new(pval, it)) 13452904Sshin goto memerr; 13595023Ssuz break; 13662587Sitojun 13762587Sitojun case ASN1_ITYPE_CHOICE: 13852904Sshin if(asn1_cb) { 13962587Sitojun i = asn1_cb(ASN1_OP_NEW_PRE, pval, it); 14052904Sshin if(!i) goto auxerr; 14162587Sitojun if(i==2) { 14252904Sshin#ifdef CRYPTO_MDEBUG 14362587Sitojun if(it->sname) CRYPTO_pop_info(); 14452904Sshin#endif 14552904Sshin return 1; 14652904Sshin } 14752904Sshin } 14878064Sume if(!combine) { 14978064Sume *pval = OPENSSL_malloc(it->size); 15052904Sshin if(!*pval) goto memerr; 15152904Sshin memset(*pval, 0, it->size); 15252904Sshin } 15352904Sshin asn1_set_choice_selector(pval, -1, it); 15452904Sshin if(asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it)) 15552904Sshin goto auxerr; 15652904Sshin break; 15752904Sshin 15852904Sshin case ASN1_ITYPE_SEQUENCE: 15952904Sshin if(asn1_cb) { 16095023Ssuz i = asn1_cb(ASN1_OP_NEW_PRE, pval, it); 16197181Smike if(!i) goto auxerr; 16262587Sitojun if(i==2) { 16362587Sitojun#ifdef CRYPTO_MDEBUG 16462587Sitojun if(it->sname) CRYPTO_pop_info(); 16562587Sitojun#endif 16662587Sitojun return 1; 16762587Sitojun } 16862587Sitojun } 16962587Sitojun if(!combine) { 17097181Smike *pval = OPENSSL_malloc(it->size); 17162587Sitojun if(!*pval) goto memerr; 17262587Sitojun memset(*pval, 0, it->size); 17362587Sitojun asn1_do_lock(pval, 0, it); 17462587Sitojun asn1_enc_init(pval, it); 17562587Sitojun } 17662587Sitojun for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) { 17762587Sitojun pseqval = asn1_get_field_ptr(pval, tt); 17862587Sitojun if(!ASN1_template_new(pseqval, tt)) goto memerr; 17952904Sshin } 18052904Sshin if(asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it)) 18152904Sshin goto auxerr; 18252904Sshin break; 18352904Sshin } 18452904Sshin#ifdef CRYPTO_MDEBUG 18597181Smike if(it->sname) CRYPTO_pop_info(); 18662587Sitojun#endif 18752904Sshin return 1; 18852904Sshin 18962587Sitojun memerr: 19052904Sshin ASN1err(ASN1_F_ASN1_ITEM_NEW, ERR_R_MALLOC_FAILURE); 19152904Sshin#ifdef CRYPTO_MDEBUG 19262587Sitojun if(it->sname) CRYPTO_pop_info(); 19352904Sshin#endif 19452904Sshin return 0; 195121315Sume 196121315Sume auxerr: 197121315Sume ASN1err(ASN1_F_ASN1_ITEM_NEW, ASN1_R_AUX_ERROR); 19862587Sitojun ASN1_item_ex_free(pval, it); 19952904Sshin#ifdef CRYPTO_MDEBUG 20052904Sshin if(it->sname) CRYPTO_pop_info(); 20162587Sitojun#endif 20252904Sshin return 0; 20352904Sshin 204191662Sbms} 205191662Sbms 206191662Sbmsstatic void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 20797181Smike{ 20852904Sshin const ASN1_EXTERN_FUNCS *ef; 20952904Sshin 21052904Sshin switch(it->itype) { 21197181Smike 21252904Sshin case ASN1_ITYPE_EXTERN: 21352904Sshin ef = it->funcs; 21452904Sshin if(ef && ef->asn1_ex_clear) 215191662Sbms ef->asn1_ex_clear(pval, it); 21697181Smike else *pval = NULL; 21752904Sshin break; 21852904Sshin 21952904Sshin 22053877Sitojun case ASN1_ITYPE_PRIMITIVE: 22153877Sitojun if(it->templates) 22253877Sitojun asn1_template_clear(pval, it->templates); 22352904Sshin else 22453877Sitojun asn1_primitive_clear(pval, it); 22562587Sitojun break; 22662587Sitojun 22753877Sitojun case ASN1_ITYPE_MSTRING: 22897181Smike asn1_primitive_clear(pval, it); 22962587Sitojun break; 23062587Sitojun 23153877Sitojun case ASN1_ITYPE_COMPAT: 23297181Smike case ASN1_ITYPE_CHOICE: 23352904Sshin case ASN1_ITYPE_SEQUENCE: 23452904Sshin *pval = NULL; 23552904Sshin break; 23652904Sshin } 23762587Sitojun} 23878064Sume 23978064Sume 24078064Sumeint ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 24178064Sume{ 24252904Sshin const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item); 24352904Sshin int ret; 24452904Sshin if(tt->flags & ASN1_TFLG_OPTIONAL) { 24552904Sshin asn1_template_clear(pval, tt); 24662587Sitojun return 1; 24778064Sume } 24878064Sume /* If ANY DEFINED BY nothing to do */ 24978064Sume 25078064Sume if(tt->flags & ASN1_TFLG_ADB_MASK) { 25152904Sshin *pval = NULL; 25252904Sshin return 1; 25352904Sshin } 25452904Sshin#ifdef CRYPTO_MDEBUG 25562587Sitojun if(tt->field_name) CRYPTO_push_info(tt->field_name); 25678064Sume#endif 25778064Sume /* If SET OF or SEQUENCE OF, its a STACK */ 25878064Sume if(tt->flags & ASN1_TFLG_SK_MASK) { 25978064Sume STACK_OF(ASN1_VALUE) *skval; 26078064Sume skval = sk_ASN1_VALUE_new_null(); 26152904Sshin if(!skval) { 26252904Sshin ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE); 26352904Sshin ret = 0; 26452904Sshin goto done; 26562587Sitojun } 26678064Sume *pval = (ASN1_VALUE *)skval; 26778064Sume ret = 1; 26878064Sume goto done; 26952904Sshin } 27052904Sshin /* Otherwise pass it back to the item routine */ 27152904Sshin ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE); 27252904Sshin done: 27352904Sshin#ifdef CRYPTO_MDEBUG 27495023Ssuz if(it->sname) CRYPTO_pop_info(); 27562587Sitojun#endif 276121315Sume return ret; 27762587Sitojun} 27862587Sitojun 27962587Sitojunstatic void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 28062587Sitojun{ 28152904Sshin /* If ADB or STACK just NULL the field */ 28262587Sitojun if(tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK)) 283121315Sume *pval = NULL; 28462587Sitojun else 28562587Sitojun asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item)); 28662587Sitojun} 28762587Sitojun 28852904Sshin 28952904Sshin/* NB: could probably combine most of the real XXX_new() behaviour and junk all the old 29052904Sshin * functions. 29152904Sshin */ 29252904Sshin 29352904Sshinint ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 29462587Sitojun{ 29552904Sshin ASN1_TYPE *typ; 29662587Sitojun int utype; 29752904Sshin const ASN1_PRIMITIVE_FUNCS *pf; 29852904Sshin pf = it->funcs; 29952904Sshin if(pf && pf->prim_new) return pf->prim_new(pval, it); 30052904Sshin if(!it || (it->itype == ASN1_ITYPE_MSTRING)) utype = -1; 30152904Sshin else utype = it->utype; 30252904Sshin switch(utype) { 30352904Sshin case V_ASN1_OBJECT: 30495023Ssuz *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef); 30562587Sitojun return 1; 30652904Sshin 30762587Sitojun case V_ASN1_BOOLEAN: 30852904Sshin if (it) 30952904Sshin *(ASN1_BOOLEAN *)pval = it->size; 31052904Sshin else 31152904Sshin *(ASN1_BOOLEAN *)pval = -1; 31252904Sshin return 1; 31395023Ssuz 31462587Sitojun case V_ASN1_NULL: 31552904Sshin *pval = (ASN1_VALUE *)1; 31652904Sshin return 1; 317121315Sume 318121315Sume case V_ASN1_ANY: 319121315Sume typ = OPENSSL_malloc(sizeof(ASN1_TYPE)); 32062587Sitojun if(!typ) return 0; 32152904Sshin typ->value.ptr = NULL; 32252904Sshin typ->type = -1; 32362587Sitojun *pval = (ASN1_VALUE *)typ; 324171260Sdelphij break; 32552904Sshin 32662587Sitojun default: 32752904Sshin *pval = (ASN1_VALUE *)ASN1_STRING_type_new(utype); 32852904Sshin break; 32962587Sitojun } 33052904Sshin if(*pval) return 1; 33152904Sshin return 0; 33252904Sshin} 33362587Sitojun 33452904Sshinvoid asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 33552904Sshin{ 33662587Sitojun int utype; 33752904Sshin const ASN1_PRIMITIVE_FUNCS *pf; 33852904Sshin pf = it->funcs; 33962587Sitojun if(pf) { 340171260Sdelphij if(pf->prim_clear) 34152904Sshin pf->prim_clear(pval, it); 34262587Sitojun else 34352904Sshin *pval = NULL; 34452904Sshin return; 34562587Sitojun } 34652904Sshin if(!it || (it->itype == ASN1_ITYPE_MSTRING)) utype = -1; 34752904Sshin else utype = it->utype; 34852904Sshin if(utype == V_ASN1_BOOLEAN) 34952904Sshin *(ASN1_BOOLEAN *)pval = it->size; 35095023Ssuz else *pval = NULL; 35178064Sume} 35252904Sshin