1109998Smarkm/* tasn_new.c */ 2194206Ssimon/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3109998Smarkm * project 2000. 4109998Smarkm */ 5109998Smarkm/* ==================================================================== 6160814Ssimon * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. 7109998Smarkm * 8109998Smarkm * Redistribution and use in source and binary forms, with or without 9109998Smarkm * modification, are permitted provided that the following conditions 10109998Smarkm * are met: 11109998Smarkm * 12109998Smarkm * 1. Redistributions of source code must retain the above copyright 13109998Smarkm * notice, this list of conditions and the following disclaimer. 14109998Smarkm * 15109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 16109998Smarkm * notice, this list of conditions and the following disclaimer in 17109998Smarkm * the documentation and/or other materials provided with the 18109998Smarkm * distribution. 19109998Smarkm * 20109998Smarkm * 3. All advertising materials mentioning features or use of this 21109998Smarkm * software must display the following acknowledgment: 22109998Smarkm * "This product includes software developed by the OpenSSL Project 23109998Smarkm * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24109998Smarkm * 25109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26109998Smarkm * endorse or promote products derived from this software without 27109998Smarkm * prior written permission. For written permission, please contact 28109998Smarkm * licensing@OpenSSL.org. 29109998Smarkm * 30109998Smarkm * 5. Products derived from this software may not be called "OpenSSL" 31109998Smarkm * nor may "OpenSSL" appear in their names without prior written 32109998Smarkm * permission of the OpenSSL Project. 33109998Smarkm * 34109998Smarkm * 6. Redistributions of any form whatsoever must retain the following 35109998Smarkm * acknowledgment: 36109998Smarkm * "This product includes software developed by the OpenSSL Project 37109998Smarkm * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38109998Smarkm * 39109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42109998Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE. 51109998Smarkm * ==================================================================== 52109998Smarkm * 53109998Smarkm * This product includes cryptographic software written by Eric Young 54109998Smarkm * (eay@cryptsoft.com). This product includes software written by Tim 55109998Smarkm * Hudson (tjh@cryptsoft.com). 56109998Smarkm * 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, 68160814Ssimon 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); 71238405Sjkimstatic void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 72109998Smarkm 73109998SmarkmASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) 74160814Ssimon { 75109998Smarkm ASN1_VALUE *ret = NULL; 76160814Ssimon if (ASN1_item_ex_new(&ret, it) > 0) 77160814Ssimon return ret; 78109998Smarkm return NULL; 79160814Ssimon } 80109998Smarkm 81109998Smarkm/* Allocate an ASN1 structure */ 82109998Smarkm 83109998Smarkmint ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 84160814Ssimon { 85109998Smarkm return asn1_item_ex_combine_new(pval, it, 0); 86160814Ssimon } 87109998Smarkm 88160814Ssimonstatic int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, 89160814Ssimon int combine) 90160814Ssimon { 91109998Smarkm const ASN1_TEMPLATE *tt = NULL; 92109998Smarkm const ASN1_COMPAT_FUNCS *cf; 93109998Smarkm const ASN1_EXTERN_FUNCS *ef; 94109998Smarkm const ASN1_AUX *aux = it->funcs; 95109998Smarkm ASN1_aux_cb *asn1_cb; 96109998Smarkm ASN1_VALUE **pseqval; 97109998Smarkm int i; 98160814Ssimon if (aux && aux->asn1_cb) 99160814Ssimon asn1_cb = aux->asn1_cb; 100160814Ssimon else 101160814Ssimon asn1_cb = 0; 102109998Smarkm 103160814Ssimon if (!combine) *pval = NULL; 104109998Smarkm 105109998Smarkm#ifdef CRYPTO_MDEBUG 106160814Ssimon if (it->sname) 107160814Ssimon CRYPTO_push_info(it->sname); 108109998Smarkm#endif 109109998Smarkm 110160814Ssimon switch(it->itype) 111160814Ssimon { 112109998Smarkm 113109998Smarkm case ASN1_ITYPE_EXTERN: 114109998Smarkm ef = it->funcs; 115160814Ssimon if (ef && ef->asn1_ex_new) 116160814Ssimon { 117160814Ssimon if (!ef->asn1_ex_new(pval, it)) 118109998Smarkm goto memerr; 119160814Ssimon } 120109998Smarkm break; 121109998Smarkm 122109998Smarkm case ASN1_ITYPE_COMPAT: 123109998Smarkm cf = it->funcs; 124160814Ssimon if (cf && cf->asn1_new) { 125109998Smarkm *pval = cf->asn1_new(); 126160814Ssimon if (!*pval) 127160814Ssimon goto memerr; 128109998Smarkm } 129109998Smarkm break; 130109998Smarkm 131109998Smarkm case ASN1_ITYPE_PRIMITIVE: 132160814Ssimon if (it->templates) 133160814Ssimon { 134160814Ssimon if (!ASN1_template_new(pval, it->templates)) 135109998Smarkm goto memerr; 136160814Ssimon } 137160814Ssimon else if (!ASN1_primitive_new(pval, it)) 138109998Smarkm goto memerr; 139109998Smarkm break; 140109998Smarkm 141109998Smarkm case ASN1_ITYPE_MSTRING: 142160814Ssimon if (!ASN1_primitive_new(pval, it)) 143109998Smarkm goto memerr; 144109998Smarkm break; 145109998Smarkm 146109998Smarkm case ASN1_ITYPE_CHOICE: 147160814Ssimon if (asn1_cb) 148160814Ssimon { 149238405Sjkim i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); 150160814Ssimon if (!i) 151160814Ssimon goto auxerr; 152160814Ssimon if (i==2) 153160814Ssimon { 154109998Smarkm#ifdef CRYPTO_MDEBUG 155160814Ssimon if (it->sname) 156160814Ssimon CRYPTO_pop_info(); 157109998Smarkm#endif 158109998Smarkm return 1; 159160814Ssimon } 160109998Smarkm } 161160814Ssimon if (!combine) 162160814Ssimon { 163109998Smarkm *pval = OPENSSL_malloc(it->size); 164160814Ssimon if (!*pval) 165160814Ssimon goto memerr; 166109998Smarkm memset(*pval, 0, it->size); 167160814Ssimon } 168109998Smarkm asn1_set_choice_selector(pval, -1, it); 169238405Sjkim if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) 170109998Smarkm goto auxerr; 171109998Smarkm break; 172109998Smarkm 173160814Ssimon case ASN1_ITYPE_NDEF_SEQUENCE: 174109998Smarkm case ASN1_ITYPE_SEQUENCE: 175160814Ssimon if (asn1_cb) 176160814Ssimon { 177238405Sjkim i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); 178160814Ssimon if (!i) 179160814Ssimon goto auxerr; 180160814Ssimon if (i==2) 181160814Ssimon { 182109998Smarkm#ifdef CRYPTO_MDEBUG 183160814Ssimon if (it->sname) 184160814Ssimon CRYPTO_pop_info(); 185109998Smarkm#endif 186109998Smarkm return 1; 187160814Ssimon } 188109998Smarkm } 189160814Ssimon if (!combine) 190160814Ssimon { 191109998Smarkm *pval = OPENSSL_malloc(it->size); 192160814Ssimon if (!*pval) 193160814Ssimon goto memerr; 194109998Smarkm memset(*pval, 0, it->size); 195109998Smarkm asn1_do_lock(pval, 0, it); 196109998Smarkm asn1_enc_init(pval, it); 197160814Ssimon } 198160814Ssimon for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) 199160814Ssimon { 200109998Smarkm pseqval = asn1_get_field_ptr(pval, tt); 201160814Ssimon if (!ASN1_template_new(pseqval, tt)) 202160814Ssimon goto memerr; 203160814Ssimon } 204238405Sjkim if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) 205109998Smarkm goto auxerr; 206109998Smarkm break; 207109998Smarkm } 208109998Smarkm#ifdef CRYPTO_MDEBUG 209160814Ssimon if (it->sname) CRYPTO_pop_info(); 210109998Smarkm#endif 211109998Smarkm return 1; 212109998Smarkm 213109998Smarkm memerr: 214160814Ssimon ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE); 215109998Smarkm#ifdef CRYPTO_MDEBUG 216160814Ssimon if (it->sname) CRYPTO_pop_info(); 217109998Smarkm#endif 218109998Smarkm return 0; 219109998Smarkm 220109998Smarkm auxerr: 221160814Ssimon ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR); 222109998Smarkm ASN1_item_ex_free(pval, it); 223109998Smarkm#ifdef CRYPTO_MDEBUG 224160814Ssimon if (it->sname) CRYPTO_pop_info(); 225109998Smarkm#endif 226109998Smarkm return 0; 227109998Smarkm 228160814Ssimon } 229109998Smarkm 230109998Smarkmstatic void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 231160814Ssimon { 232109998Smarkm const ASN1_EXTERN_FUNCS *ef; 233109998Smarkm 234160814Ssimon switch(it->itype) 235160814Ssimon { 236109998Smarkm 237109998Smarkm case ASN1_ITYPE_EXTERN: 238109998Smarkm ef = it->funcs; 239160814Ssimon if (ef && ef->asn1_ex_clear) 240109998Smarkm ef->asn1_ex_clear(pval, it); 241109998Smarkm else *pval = NULL; 242109998Smarkm break; 243109998Smarkm 244109998Smarkm 245109998Smarkm case ASN1_ITYPE_PRIMITIVE: 246160814Ssimon if (it->templates) 247109998Smarkm asn1_template_clear(pval, it->templates); 248109998Smarkm else 249109998Smarkm asn1_primitive_clear(pval, it); 250109998Smarkm break; 251109998Smarkm 252109998Smarkm case ASN1_ITYPE_MSTRING: 253109998Smarkm asn1_primitive_clear(pval, it); 254109998Smarkm break; 255109998Smarkm 256109998Smarkm case ASN1_ITYPE_COMPAT: 257109998Smarkm case ASN1_ITYPE_CHOICE: 258109998Smarkm case ASN1_ITYPE_SEQUENCE: 259160814Ssimon case ASN1_ITYPE_NDEF_SEQUENCE: 260109998Smarkm *pval = NULL; 261109998Smarkm break; 262160814Ssimon } 263109998Smarkm } 264109998Smarkm 265109998Smarkm 266109998Smarkmint ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 267160814Ssimon { 268109998Smarkm const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item); 269109998Smarkm int ret; 270160814Ssimon if (tt->flags & ASN1_TFLG_OPTIONAL) 271160814Ssimon { 272109998Smarkm asn1_template_clear(pval, tt); 273109998Smarkm return 1; 274160814Ssimon } 275109998Smarkm /* If ANY DEFINED BY nothing to do */ 276109998Smarkm 277160814Ssimon if (tt->flags & ASN1_TFLG_ADB_MASK) 278160814Ssimon { 279109998Smarkm *pval = NULL; 280109998Smarkm return 1; 281160814Ssimon } 282109998Smarkm#ifdef CRYPTO_MDEBUG 283160814Ssimon if (tt->field_name) 284160814Ssimon CRYPTO_push_info(tt->field_name); 285109998Smarkm#endif 286109998Smarkm /* If SET OF or SEQUENCE OF, its a STACK */ 287160814Ssimon if (tt->flags & ASN1_TFLG_SK_MASK) 288160814Ssimon { 289109998Smarkm STACK_OF(ASN1_VALUE) *skval; 290109998Smarkm skval = sk_ASN1_VALUE_new_null(); 291160814Ssimon if (!skval) 292160814Ssimon { 293109998Smarkm ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE); 294109998Smarkm ret = 0; 295109998Smarkm goto done; 296160814Ssimon } 297109998Smarkm *pval = (ASN1_VALUE *)skval; 298109998Smarkm ret = 1; 299109998Smarkm goto done; 300160814Ssimon } 301109998Smarkm /* Otherwise pass it back to the item routine */ 302109998Smarkm ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE); 303109998Smarkm done: 304109998Smarkm#ifdef CRYPTO_MDEBUG 305160814Ssimon if (it->sname) 306160814Ssimon CRYPTO_pop_info(); 307109998Smarkm#endif 308109998Smarkm return ret; 309160814Ssimon } 310109998Smarkm 311109998Smarkmstatic void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 312160814Ssimon { 313109998Smarkm /* If ADB or STACK just NULL the field */ 314160814Ssimon if (tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK)) 315109998Smarkm *pval = NULL; 316109998Smarkm else 317109998Smarkm asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item)); 318160814Ssimon } 319109998Smarkm 320109998Smarkm 321160814Ssimon/* NB: could probably combine most of the real XXX_new() behaviour and junk 322160814Ssimon * all the old functions. 323109998Smarkm */ 324109998Smarkm 325109998Smarkmint ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 326160814Ssimon { 327109998Smarkm ASN1_TYPE *typ; 328238405Sjkim ASN1_STRING *str; 329109998Smarkm int utype; 330160814Ssimon 331160814Ssimon if (it && it->funcs) 332160814Ssimon { 333160814Ssimon const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; 334160814Ssimon if (pf->prim_new) 335160814Ssimon return pf->prim_new(pval, it); 336160814Ssimon } 337160814Ssimon 338160814Ssimon if (!it || (it->itype == ASN1_ITYPE_MSTRING)) 339160814Ssimon utype = -1; 340160814Ssimon else 341160814Ssimon utype = it->utype; 342160814Ssimon switch(utype) 343160814Ssimon { 344109998Smarkm case V_ASN1_OBJECT: 345109998Smarkm *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef); 346109998Smarkm return 1; 347109998Smarkm 348109998Smarkm case V_ASN1_BOOLEAN: 349238405Sjkim *(ASN1_BOOLEAN *)pval = it->size; 350109998Smarkm return 1; 351109998Smarkm 352109998Smarkm case V_ASN1_NULL: 353109998Smarkm *pval = (ASN1_VALUE *)1; 354109998Smarkm return 1; 355109998Smarkm 356109998Smarkm case V_ASN1_ANY: 357109998Smarkm typ = OPENSSL_malloc(sizeof(ASN1_TYPE)); 358160814Ssimon if (!typ) 359160814Ssimon return 0; 360109998Smarkm typ->value.ptr = NULL; 361109998Smarkm typ->type = -1; 362109998Smarkm *pval = (ASN1_VALUE *)typ; 363109998Smarkm break; 364109998Smarkm 365109998Smarkm default: 366238405Sjkim str = ASN1_STRING_type_new(utype); 367238405Sjkim if (it->itype == ASN1_ITYPE_MSTRING && str) 368238405Sjkim str->flags |= ASN1_STRING_FLAG_MSTRING; 369238405Sjkim *pval = (ASN1_VALUE *)str; 370109998Smarkm break; 371160814Ssimon } 372160814Ssimon if (*pval) 373160814Ssimon return 1; 374160814Ssimon return 0; 375109998Smarkm } 376109998Smarkm 377238405Sjkimstatic void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 378160814Ssimon { 379109998Smarkm int utype; 380160814Ssimon if (it && it->funcs) 381160814Ssimon { 382160814Ssimon const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; 383160814Ssimon if (pf->prim_clear) 384109998Smarkm pf->prim_clear(pval, it); 385109998Smarkm else 386109998Smarkm *pval = NULL; 387109998Smarkm return; 388160814Ssimon } 389160814Ssimon if (!it || (it->itype == ASN1_ITYPE_MSTRING)) 390160814Ssimon utype = -1; 391160814Ssimon else 392160814Ssimon utype = it->utype; 393160814Ssimon if (utype == V_ASN1_BOOLEAN) 394109998Smarkm *(ASN1_BOOLEAN *)pval = it->size; 395109998Smarkm else *pval = NULL; 396160814Ssimon } 397