1/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2 * All rights reserved. 3 * 4 * This package is an SSL implementation written 5 * by Eric Young (eay@cryptsoft.com). 6 * The implementation was written so as to conform with Netscapes SSL. 7 * 8 * This library is free for commercial and non-commercial use as long as 9 * the following conditions are aheared to. The following conditions 10 * apply to all code found in this distribution, be it the RC4, RSA, 11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12 * included with this distribution is covered by the same copyright terms 13 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 14 * 15 * Copyright remains Eric Young's, and as such any Copyright notices in 16 * the code are not to be removed. 17 * If this package is used in a product, Eric Young should be given attribution 18 * as the author of the parts of the library used. 19 * This can be in the form of a textual message at program startup or 20 * in documentation (online or textual) provided with the package. 21 * 22 * Redistribution and use in source and binary forms, with or without 23 * modification, are permitted provided that the following conditions 24 * are met: 25 * 1. Redistributions of source code must retain the copyright 26 * notice, this list of conditions and the following disclaimer. 27 * 2. Redistributions in binary form must reproduce the above copyright 28 * notice, this list of conditions and the following disclaimer in the 29 * documentation and/or other materials provided with the distribution. 30 * 3. All advertising materials mentioning features or use of this software 31 * must display the following acknowledgement: 32 * "This product includes cryptographic software written by 33 * Eric Young (eay@cryptsoft.com)" 34 * The word 'cryptographic' can be left out if the rouines from the library 35 * being used are not cryptographic related :-). 36 * 4. If you include any Windows specific code (or a derivative thereof) from 37 * the apps directory (application code) you must include an acknowledgement: 38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * SUCH DAMAGE. 51 * 52 * The licence and distribution terms for any publically available version or 53 * derivative of this code cannot be changed. i.e. this code cannot simply be 54 * copied and put under another distribution licence 55 * [including the GNU Public Licence.] */ 56 57#include <openssl/asn1.h> 58 59#include <openssl/asn1t.h> 60#include <openssl/err.h> 61#include <openssl/mem.h> 62#include <openssl/obj.h> 63 64 65static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, 66 int combine); 67static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 68static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); 69static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 70 71ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) 72 { 73 ASN1_VALUE *ret = NULL; 74 if (ASN1_item_ex_new(&ret, it) > 0) 75 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, 87 int combine) 88 { 89 const ASN1_TEMPLATE *tt = NULL; 90 const ASN1_COMPAT_FUNCS *cf; 91 const ASN1_EXTERN_FUNCS *ef; 92 const ASN1_AUX *aux = it->funcs; 93 ASN1_aux_cb *asn1_cb; 94 ASN1_VALUE **pseqval; 95 int i; 96 if (aux && aux->asn1_cb) 97 asn1_cb = aux->asn1_cb; 98 else 99 asn1_cb = 0; 100 101 if (!combine) *pval = NULL; 102 103#ifdef CRYPTO_MDEBUG 104 if (it->sname) 105 CRYPTO_push_info(it->sname); 106#endif 107 108 switch(it->itype) 109 { 110 111 case ASN1_ITYPE_EXTERN: 112 ef = it->funcs; 113 if (ef && ef->asn1_ex_new) 114 { 115 if (!ef->asn1_ex_new(pval, it)) 116 goto memerr; 117 } 118 break; 119 120 case ASN1_ITYPE_COMPAT: 121 cf = it->funcs; 122 if (cf && cf->asn1_new) { 123 *pval = cf->asn1_new(); 124 if (!*pval) 125 goto memerr; 126 } 127 break; 128 129 case ASN1_ITYPE_PRIMITIVE: 130 if (it->templates) 131 { 132 if (!ASN1_template_new(pval, it->templates)) 133 goto memerr; 134 } 135 else if (!ASN1_primitive_new(pval, it)) 136 goto memerr; 137 break; 138 139 case ASN1_ITYPE_MSTRING: 140 if (!ASN1_primitive_new(pval, it)) 141 goto memerr; 142 break; 143 144 case ASN1_ITYPE_CHOICE: 145 if (asn1_cb) 146 { 147 i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); 148 if (!i) 149 goto auxerr; 150 if (i==2) 151 { 152#ifdef CRYPTO_MDEBUG 153 if (it->sname) 154 CRYPTO_pop_info(); 155#endif 156 return 1; 157 } 158 } 159 if (!combine) 160 { 161 *pval = OPENSSL_malloc(it->size); 162 if (!*pval) 163 goto memerr; 164 memset(*pval, 0, it->size); 165 } 166 asn1_set_choice_selector(pval, -1, it); 167 if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) 168 goto auxerr; 169 break; 170 171 case ASN1_ITYPE_NDEF_SEQUENCE: 172 case ASN1_ITYPE_SEQUENCE: 173 if (asn1_cb) 174 { 175 i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); 176 if (!i) 177 goto auxerr; 178 if (i==2) 179 { 180#ifdef CRYPTO_MDEBUG 181 if (it->sname) 182 CRYPTO_pop_info(); 183#endif 184 return 1; 185 } 186 } 187 if (!combine) 188 { 189 *pval = OPENSSL_malloc(it->size); 190 if (!*pval) 191 goto memerr; 192 memset(*pval, 0, it->size); 193 asn1_do_lock(pval, 0, it); 194 asn1_enc_init(pval, it); 195 } 196 for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) 197 { 198 pseqval = asn1_get_field_ptr(pval, tt); 199 if (!ASN1_template_new(pseqval, tt)) 200 goto memerr; 201 } 202 if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) 203 goto auxerr; 204 break; 205 } 206#ifdef CRYPTO_MDEBUG 207 if (it->sname) CRYPTO_pop_info(); 208#endif 209 return 1; 210 211 memerr: 212 OPENSSL_PUT_ERROR(ASN1, asn1_item_ex_combine_new, ERR_R_MALLOC_FAILURE); 213#ifdef CRYPTO_MDEBUG 214 if (it->sname) CRYPTO_pop_info(); 215#endif 216 return 0; 217 218 auxerr: 219 OPENSSL_PUT_ERROR(ASN1, asn1_item_ex_combine_new, ASN1_R_AUX_ERROR); 220 ASN1_item_ex_free(pval, it); 221#ifdef CRYPTO_MDEBUG 222 if (it->sname) CRYPTO_pop_info(); 223#endif 224 return 0; 225 226 } 227 228static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 229 { 230 const ASN1_EXTERN_FUNCS *ef; 231 232 switch(it->itype) 233 { 234 235 case ASN1_ITYPE_EXTERN: 236 ef = it->funcs; 237 if (ef && ef->asn1_ex_clear) 238 ef->asn1_ex_clear(pval, it); 239 else *pval = NULL; 240 break; 241 242 243 case ASN1_ITYPE_PRIMITIVE: 244 if (it->templates) 245 asn1_template_clear(pval, it->templates); 246 else 247 asn1_primitive_clear(pval, it); 248 break; 249 250 case ASN1_ITYPE_MSTRING: 251 asn1_primitive_clear(pval, it); 252 break; 253 254 case ASN1_ITYPE_COMPAT: 255 case ASN1_ITYPE_CHOICE: 256 case ASN1_ITYPE_SEQUENCE: 257 case ASN1_ITYPE_NDEF_SEQUENCE: 258 *pval = NULL; 259 break; 260 } 261 } 262 263 264int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 265 { 266 const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item); 267 int ret; 268 if (tt->flags & ASN1_TFLG_OPTIONAL) 269 { 270 asn1_template_clear(pval, tt); 271 return 1; 272 } 273 /* If ANY DEFINED BY nothing to do */ 274 275 if (tt->flags & ASN1_TFLG_ADB_MASK) 276 { 277 *pval = NULL; 278 return 1; 279 } 280#ifdef CRYPTO_MDEBUG 281 if (tt->field_name) 282 CRYPTO_push_info(tt->field_name); 283#endif 284 /* If SET OF or SEQUENCE OF, its a STACK */ 285 if (tt->flags & ASN1_TFLG_SK_MASK) 286 { 287 STACK_OF(ASN1_VALUE) *skval; 288 skval = sk_ASN1_VALUE_new_null(); 289 if (!skval) 290 { 291 OPENSSL_PUT_ERROR(ASN1, ASN1_template_new, ERR_R_MALLOC_FAILURE); 292 ret = 0; 293 goto done; 294 } 295 *pval = (ASN1_VALUE *)skval; 296 ret = 1; 297 goto done; 298 } 299 /* Otherwise pass it back to the item routine */ 300 ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE); 301 done: 302#ifdef CRYPTO_MDEBUG 303 if (it->sname) 304 CRYPTO_pop_info(); 305#endif 306 return ret; 307 } 308 309static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 310 { 311 /* If ADB or STACK just NULL the field */ 312 if (tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK)) 313 *pval = NULL; 314 else 315 asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item)); 316 } 317 318 319/* NB: could probably combine most of the real XXX_new() behaviour and junk 320 * all the old functions. 321 */ 322 323int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 324 { 325 ASN1_TYPE *typ; 326 ASN1_STRING *str; 327 int utype; 328 329 if (it && it->funcs) 330 { 331 const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; 332 if (pf->prim_new) 333 return pf->prim_new(pval, it); 334 } 335 336 if (!it || (it->itype == ASN1_ITYPE_MSTRING)) 337 utype = -1; 338 else 339 utype = it->utype; 340 switch(utype) 341 { 342 case V_ASN1_OBJECT: 343 *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef); 344 return 1; 345 346 case V_ASN1_BOOLEAN: 347 *(ASN1_BOOLEAN *)pval = it->size; 348 return 1; 349 350 case V_ASN1_NULL: 351 *pval = (ASN1_VALUE *)1; 352 return 1; 353 354 case V_ASN1_ANY: 355 typ = OPENSSL_malloc(sizeof(ASN1_TYPE)); 356 if (!typ) 357 return 0; 358 typ->value.ptr = NULL; 359 typ->type = -1; 360 *pval = (ASN1_VALUE *)typ; 361 break; 362 363 default: 364 str = ASN1_STRING_type_new(utype); 365 if (it->itype == ASN1_ITYPE_MSTRING && str) 366 str->flags |= ASN1_STRING_FLAG_MSTRING; 367 *pval = (ASN1_VALUE *)str; 368 break; 369 } 370 if (*pval) 371 return 1; 372 return 0; 373 } 374 375static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 376 { 377 int utype; 378 if (it && it->funcs) 379 { 380 const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; 381 if (pf->prim_clear) 382 pf->prim_clear(pval, it); 383 else 384 *pval = NULL; 385 return; 386 } 387 if (!it || (it->itype == ASN1_ITYPE_MSTRING)) 388 utype = -1; 389 else 390 utype = it->utype; 391 if (utype == V_ASN1_BOOLEAN) 392 *(ASN1_BOOLEAN *)pval = it->size; 393 else *pval = NULL; 394 } 395