1109998Smarkm/* tasn_new.c */ 2296465Sdelphij/* 3296465Sdelphij * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4296465Sdelphij * 2000. 5109998Smarkm */ 6109998Smarkm/* ==================================================================== 7160814Ssimon * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. 8109998Smarkm * 9109998Smarkm * Redistribution and use in source and binary forms, with or without 10109998Smarkm * modification, are permitted provided that the following conditions 11109998Smarkm * are met: 12109998Smarkm * 13109998Smarkm * 1. Redistributions of source code must retain the above copyright 14296465Sdelphij * notice, this list of conditions and the following disclaimer. 15109998Smarkm * 16109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 17109998Smarkm * notice, this list of conditions and the following disclaimer in 18109998Smarkm * the documentation and/or other materials provided with the 19109998Smarkm * distribution. 20109998Smarkm * 21109998Smarkm * 3. All advertising materials mentioning features or use of this 22109998Smarkm * software must display the following acknowledgment: 23109998Smarkm * "This product includes software developed by the OpenSSL Project 24109998Smarkm * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25109998Smarkm * 26109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27109998Smarkm * endorse or promote products derived from this software without 28109998Smarkm * prior written permission. For written permission, please contact 29109998Smarkm * licensing@OpenSSL.org. 30109998Smarkm * 31109998Smarkm * 5. Products derived from this software may not be called "OpenSSL" 32109998Smarkm * nor may "OpenSSL" appear in their names without prior written 33109998Smarkm * permission of the OpenSSL Project. 34109998Smarkm * 35109998Smarkm * 6. Redistributions of any form whatsoever must retain the following 36109998Smarkm * acknowledgment: 37109998Smarkm * "This product includes software developed by the OpenSSL Project 38109998Smarkm * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39109998Smarkm * 40109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43109998Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE. 52109998Smarkm * ==================================================================== 53109998Smarkm * 54109998Smarkm * This product includes cryptographic software written by Eric Young 55109998Smarkm * (eay@cryptsoft.com). This product includes software written by Tim 56109998Smarkm * Hudson (tjh@cryptsoft.com). 57109998Smarkm * 58109998Smarkm */ 59109998Smarkm 60109998Smarkm#include <stddef.h> 61109998Smarkm#include <openssl/asn1.h> 62109998Smarkm#include <openssl/objects.h> 63109998Smarkm#include <openssl/err.h> 64109998Smarkm#include <openssl/asn1t.h> 65109998Smarkm#include <string.h> 66109998Smarkm 67160814Ssimonstatic int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, 68296465Sdelphij int combine); 69109998Smarkmstatic void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 70109998Smarkmstatic void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); 71109998Smarkmvoid asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 72109998Smarkm 73109998SmarkmASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) 74296465Sdelphij{ 75296465Sdelphij ASN1_VALUE *ret = NULL; 76296465Sdelphij if (ASN1_item_ex_new(&ret, it) > 0) 77296465Sdelphij return ret; 78296465Sdelphij return NULL; 79296465Sdelphij} 80109998Smarkm 81109998Smarkm/* Allocate an ASN1 structure */ 82109998Smarkm 83109998Smarkmint ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 84296465Sdelphij{ 85296465Sdelphij return asn1_item_ex_combine_new(pval, it, 0); 86296465Sdelphij} 87109998Smarkm 88160814Ssimonstatic int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, 89296465Sdelphij int combine) 90296465Sdelphij{ 91296465Sdelphij const ASN1_TEMPLATE *tt = NULL; 92296465Sdelphij const ASN1_COMPAT_FUNCS *cf; 93296465Sdelphij const ASN1_EXTERN_FUNCS *ef; 94296465Sdelphij const ASN1_AUX *aux = it->funcs; 95296465Sdelphij ASN1_aux_cb *asn1_cb; 96296465Sdelphij ASN1_VALUE **pseqval; 97296465Sdelphij int i; 98296465Sdelphij if (aux && aux->asn1_cb) 99296465Sdelphij asn1_cb = aux->asn1_cb; 100296465Sdelphij else 101296465Sdelphij asn1_cb = 0; 102109998Smarkm 103109998Smarkm#ifdef CRYPTO_MDEBUG 104296465Sdelphij if (it->sname) 105296465Sdelphij CRYPTO_push_info(it->sname); 106109998Smarkm#endif 107109998Smarkm 108296465Sdelphij switch (it->itype) { 109109998Smarkm 110296465Sdelphij case ASN1_ITYPE_EXTERN: 111296465Sdelphij ef = it->funcs; 112296465Sdelphij if (ef && ef->asn1_ex_new) { 113296465Sdelphij if (!ef->asn1_ex_new(pval, it)) 114296465Sdelphij goto memerr; 115296465Sdelphij } 116296465Sdelphij break; 117109998Smarkm 118296465Sdelphij case ASN1_ITYPE_COMPAT: 119296465Sdelphij cf = it->funcs; 120296465Sdelphij if (cf && cf->asn1_new) { 121296465Sdelphij *pval = cf->asn1_new(); 122296465Sdelphij if (!*pval) 123296465Sdelphij goto memerr; 124296465Sdelphij } 125296465Sdelphij break; 126109998Smarkm 127296465Sdelphij case ASN1_ITYPE_PRIMITIVE: 128296465Sdelphij if (it->templates) { 129296465Sdelphij if (!ASN1_template_new(pval, it->templates)) 130296465Sdelphij goto memerr; 131296465Sdelphij } else if (!ASN1_primitive_new(pval, it)) 132296465Sdelphij goto memerr; 133296465Sdelphij break; 134109998Smarkm 135296465Sdelphij case ASN1_ITYPE_MSTRING: 136296465Sdelphij if (!ASN1_primitive_new(pval, it)) 137296465Sdelphij goto memerr; 138296465Sdelphij break; 139109998Smarkm 140296465Sdelphij case ASN1_ITYPE_CHOICE: 141296465Sdelphij if (asn1_cb) { 142296465Sdelphij i = asn1_cb(ASN1_OP_NEW_PRE, pval, it); 143296465Sdelphij if (!i) 144296465Sdelphij goto auxerr; 145296465Sdelphij if (i == 2) { 146109998Smarkm#ifdef CRYPTO_MDEBUG 147296465Sdelphij if (it->sname) 148296465Sdelphij CRYPTO_pop_info(); 149109998Smarkm#endif 150296465Sdelphij return 1; 151296465Sdelphij } 152296465Sdelphij } 153296465Sdelphij if (!combine) { 154296465Sdelphij *pval = OPENSSL_malloc(it->size); 155296465Sdelphij if (!*pval) 156296465Sdelphij goto memerr; 157296465Sdelphij memset(*pval, 0, it->size); 158296465Sdelphij } 159296465Sdelphij asn1_set_choice_selector(pval, -1, it); 160296465Sdelphij if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it)) 161296465Sdelphij goto auxerr; 162296465Sdelphij break; 163109998Smarkm 164296465Sdelphij case ASN1_ITYPE_NDEF_SEQUENCE: 165296465Sdelphij case ASN1_ITYPE_SEQUENCE: 166296465Sdelphij if (asn1_cb) { 167296465Sdelphij i = asn1_cb(ASN1_OP_NEW_PRE, pval, it); 168296465Sdelphij if (!i) 169296465Sdelphij goto auxerr; 170296465Sdelphij if (i == 2) { 171109998Smarkm#ifdef CRYPTO_MDEBUG 172296465Sdelphij if (it->sname) 173296465Sdelphij CRYPTO_pop_info(); 174109998Smarkm#endif 175296465Sdelphij return 1; 176296465Sdelphij } 177296465Sdelphij } 178296465Sdelphij if (!combine) { 179296465Sdelphij *pval = OPENSSL_malloc(it->size); 180296465Sdelphij if (!*pval) 181296465Sdelphij goto memerr; 182296465Sdelphij memset(*pval, 0, it->size); 183296465Sdelphij asn1_do_lock(pval, 0, it); 184296465Sdelphij asn1_enc_init(pval, it); 185296465Sdelphij } 186296465Sdelphij for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { 187296465Sdelphij pseqval = asn1_get_field_ptr(pval, tt); 188296465Sdelphij if (!ASN1_template_new(pseqval, tt)) 189296465Sdelphij goto memerr; 190296465Sdelphij } 191296465Sdelphij if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it)) 192296465Sdelphij goto auxerr; 193296465Sdelphij break; 194296465Sdelphij } 195109998Smarkm#ifdef CRYPTO_MDEBUG 196296465Sdelphij if (it->sname) 197296465Sdelphij CRYPTO_pop_info(); 198109998Smarkm#endif 199296465Sdelphij return 1; 200109998Smarkm 201296465Sdelphij memerr: 202296465Sdelphij ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE); 203109998Smarkm#ifdef CRYPTO_MDEBUG 204296465Sdelphij if (it->sname) 205296465Sdelphij CRYPTO_pop_info(); 206109998Smarkm#endif 207296465Sdelphij return 0; 208109998Smarkm 209296465Sdelphij auxerr: 210296465Sdelphij ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR); 211296465Sdelphij ASN1_item_ex_free(pval, it); 212109998Smarkm#ifdef CRYPTO_MDEBUG 213296465Sdelphij if (it->sname) 214296465Sdelphij CRYPTO_pop_info(); 215109998Smarkm#endif 216296465Sdelphij return 0; 217109998Smarkm 218296465Sdelphij} 219109998Smarkm 220109998Smarkmstatic void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 221296465Sdelphij{ 222296465Sdelphij const ASN1_EXTERN_FUNCS *ef; 223109998Smarkm 224296465Sdelphij switch (it->itype) { 225109998Smarkm 226296465Sdelphij case ASN1_ITYPE_EXTERN: 227296465Sdelphij ef = it->funcs; 228296465Sdelphij if (ef && ef->asn1_ex_clear) 229296465Sdelphij ef->asn1_ex_clear(pval, it); 230296465Sdelphij else 231296465Sdelphij *pval = NULL; 232296465Sdelphij break; 233109998Smarkm 234296465Sdelphij case ASN1_ITYPE_PRIMITIVE: 235296465Sdelphij if (it->templates) 236296465Sdelphij asn1_template_clear(pval, it->templates); 237296465Sdelphij else 238296465Sdelphij asn1_primitive_clear(pval, it); 239296465Sdelphij break; 240109998Smarkm 241296465Sdelphij case ASN1_ITYPE_MSTRING: 242296465Sdelphij asn1_primitive_clear(pval, it); 243296465Sdelphij break; 244109998Smarkm 245296465Sdelphij case ASN1_ITYPE_COMPAT: 246296465Sdelphij case ASN1_ITYPE_CHOICE: 247296465Sdelphij case ASN1_ITYPE_SEQUENCE: 248296465Sdelphij case ASN1_ITYPE_NDEF_SEQUENCE: 249296465Sdelphij *pval = NULL; 250296465Sdelphij break; 251296465Sdelphij } 252296465Sdelphij} 253109998Smarkm 254109998Smarkmint ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 255296465Sdelphij{ 256296465Sdelphij const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item); 257296465Sdelphij int ret; 258296465Sdelphij if (tt->flags & ASN1_TFLG_OPTIONAL) { 259296465Sdelphij asn1_template_clear(pval, tt); 260296465Sdelphij return 1; 261296465Sdelphij } 262296465Sdelphij /* If ANY DEFINED BY nothing to do */ 263109998Smarkm 264296465Sdelphij if (tt->flags & ASN1_TFLG_ADB_MASK) { 265296465Sdelphij *pval = NULL; 266296465Sdelphij return 1; 267296465Sdelphij } 268109998Smarkm#ifdef CRYPTO_MDEBUG 269296465Sdelphij if (tt->field_name) 270296465Sdelphij CRYPTO_push_info(tt->field_name); 271109998Smarkm#endif 272296465Sdelphij /* If SET OF or SEQUENCE OF, its a STACK */ 273296465Sdelphij if (tt->flags & ASN1_TFLG_SK_MASK) { 274296465Sdelphij STACK_OF(ASN1_VALUE) *skval; 275296465Sdelphij skval = sk_ASN1_VALUE_new_null(); 276296465Sdelphij if (!skval) { 277296465Sdelphij ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE); 278296465Sdelphij ret = 0; 279296465Sdelphij goto done; 280296465Sdelphij } 281296465Sdelphij *pval = (ASN1_VALUE *)skval; 282296465Sdelphij ret = 1; 283296465Sdelphij goto done; 284296465Sdelphij } 285296465Sdelphij /* Otherwise pass it back to the item routine */ 286296465Sdelphij ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE); 287296465Sdelphij done: 288109998Smarkm#ifdef CRYPTO_MDEBUG 289296465Sdelphij if (it->sname) 290296465Sdelphij CRYPTO_pop_info(); 291109998Smarkm#endif 292296465Sdelphij return ret; 293296465Sdelphij} 294109998Smarkm 295109998Smarkmstatic void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 296296465Sdelphij{ 297296465Sdelphij /* If ADB or STACK just NULL the field */ 298296465Sdelphij if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK)) 299296465Sdelphij *pval = NULL; 300296465Sdelphij else 301296465Sdelphij asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item)); 302296465Sdelphij} 303109998Smarkm 304296465Sdelphij/* 305296465Sdelphij * NB: could probably combine most of the real XXX_new() behaviour and junk 306160814Ssimon * all the old functions. 307109998Smarkm */ 308109998Smarkm 309109998Smarkmint ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 310296465Sdelphij{ 311296465Sdelphij ASN1_TYPE *typ; 312296465Sdelphij int utype; 313160814Ssimon 314296465Sdelphij if (it && it->funcs) { 315296465Sdelphij const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; 316296465Sdelphij if (pf->prim_new) 317296465Sdelphij return pf->prim_new(pval, it); 318296465Sdelphij } 319160814Ssimon 320296465Sdelphij if (!it || (it->itype == ASN1_ITYPE_MSTRING)) 321296465Sdelphij utype = -1; 322296465Sdelphij else 323296465Sdelphij utype = it->utype; 324296465Sdelphij switch (utype) { 325296465Sdelphij case V_ASN1_OBJECT: 326296465Sdelphij *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef); 327296465Sdelphij return 1; 328109998Smarkm 329296465Sdelphij case V_ASN1_BOOLEAN: 330296465Sdelphij if (it) 331296465Sdelphij *(ASN1_BOOLEAN *)pval = it->size; 332296465Sdelphij else 333296465Sdelphij *(ASN1_BOOLEAN *)pval = -1; 334296465Sdelphij return 1; 335109998Smarkm 336296465Sdelphij case V_ASN1_NULL: 337296465Sdelphij *pval = (ASN1_VALUE *)1; 338296465Sdelphij return 1; 339109998Smarkm 340296465Sdelphij case V_ASN1_ANY: 341296465Sdelphij typ = OPENSSL_malloc(sizeof(ASN1_TYPE)); 342296465Sdelphij if (!typ) 343296465Sdelphij return 0; 344296465Sdelphij typ->value.ptr = NULL; 345296465Sdelphij typ->type = -1; 346296465Sdelphij *pval = (ASN1_VALUE *)typ; 347296465Sdelphij break; 348109998Smarkm 349296465Sdelphij default: 350296465Sdelphij *pval = (ASN1_VALUE *)ASN1_STRING_type_new(utype); 351296465Sdelphij break; 352296465Sdelphij } 353296465Sdelphij if (*pval) 354296465Sdelphij return 1; 355296465Sdelphij return 0; 356296465Sdelphij} 357109998Smarkm 358109998Smarkmvoid asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 359296465Sdelphij{ 360296465Sdelphij int utype; 361296465Sdelphij if (it && it->funcs) { 362296465Sdelphij const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; 363296465Sdelphij if (pf->prim_clear) 364296465Sdelphij pf->prim_clear(pval, it); 365296465Sdelphij else 366296465Sdelphij *pval = NULL; 367296465Sdelphij return; 368296465Sdelphij } 369296465Sdelphij if (!it || (it->itype == ASN1_ITYPE_MSTRING)) 370296465Sdelphij utype = -1; 371296465Sdelphij else 372296465Sdelphij utype = it->utype; 373296465Sdelphij if (utype == V_ASN1_BOOLEAN) 374296465Sdelphij *(ASN1_BOOLEAN *)pval = it->size; 375296465Sdelphij else 376296465Sdelphij *pval = NULL; 377296465Sdelphij} 378