1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com) 2 * All rights reserved. 3 * 4 * This package is an SSL implementation written 5 * by Eric Young (eay (at) 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 (at) 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 (at) 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 (at) 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 <string.h> 60 61 #include <openssl/asn1t.h> 62 #include <openssl/err.h> 63 #include <openssl/mem.h> 64 #include <openssl/obj.h> 65 66 67 static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, 68 int combine); 69 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 70 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); 71 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 72 73 ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) 74 { 75 ASN1_VALUE *ret = NULL; 76 if (ASN1_item_ex_new(&ret, it) > 0) 77 return ret; 78 return NULL; 79 } 80 81 /* Allocate an ASN1 structure */ 82 83 int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 84 { 85 return asn1_item_ex_combine_new(pval, it, 0); 86 } 87 88 static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, 89 int combine) 90 { 91 const ASN1_TEMPLATE *tt = NULL; 92 const ASN1_COMPAT_FUNCS *cf; 93 const ASN1_EXTERN_FUNCS *ef; 94 const ASN1_AUX *aux = it->funcs; 95 ASN1_aux_cb *asn1_cb; 96 ASN1_VALUE **pseqval; 97 int i; 98 if (aux && aux->asn1_cb) 99 asn1_cb = aux->asn1_cb; 100 else 101 asn1_cb = 0; 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_refcount_set_one(pval, 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, ERR_R_MALLOC_FAILURE); 213 ASN1_item_ex_free(pval, it); 214 #ifdef CRYPTO_MDEBUG 215 if (it->sname) CRYPTO_pop_info(); 216 #endif 217 return 0; 218 219 auxerr: 220 OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR); 221 ASN1_item_ex_free(pval, it); 222 #ifdef CRYPTO_MDEBUG 223 if (it->sname) CRYPTO_pop_info(); 224 #endif 225 return 0; 226 227 } 228 229 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 230 { 231 const ASN1_EXTERN_FUNCS *ef; 232 233 switch(it->itype) 234 { 235 236 case ASN1_ITYPE_EXTERN: 237 ef = it->funcs; 238 if (ef && ef->asn1_ex_clear) 239 ef->asn1_ex_clear(pval, it); 240 else *pval = NULL; 241 break; 242 243 244 case ASN1_ITYPE_PRIMITIVE: 245 if (it->templates) 246 asn1_template_clear(pval, it->templates); 247 else 248 asn1_primitive_clear(pval, it); 249 break; 250 251 case ASN1_ITYPE_MSTRING: 252 asn1_primitive_clear(pval, it); 253 break; 254 255 case ASN1_ITYPE_COMPAT: 256 case ASN1_ITYPE_CHOICE: 257 case ASN1_ITYPE_SEQUENCE: 258 case ASN1_ITYPE_NDEF_SEQUENCE: 259 *pval = NULL; 260 break; 261 } 262 } 263 264 265 int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 266 { 267 const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item); 268 int ret; 269 if (tt->flags & ASN1_TFLG_OPTIONAL) 270 { 271 asn1_template_clear(pval, tt); 272 return 1; 273 } 274 /* If ANY DEFINED BY nothing to do */ 275 276 if (tt->flags & ASN1_TFLG_ADB_MASK) 277 { 278 *pval = NULL; 279 return 1; 280 } 281 #ifdef CRYPTO_MDEBUG 282 if (tt->field_name) 283 CRYPTO_push_info(tt->field_name); 284 #endif 285 /* If SET OF or SEQUENCE OF, its a STACK */ 286 if (tt->flags & ASN1_TFLG_SK_MASK) 287 { 288 STACK_OF(ASN1_VALUE) *skval; 289 skval = sk_ASN1_VALUE_new_null(); 290 if (!skval) 291 { 292 OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); 293 ret = 0; 294 goto done; 295 } 296 *pval = (ASN1_VALUE *)skval; 297 ret = 1; 298 goto done; 299 } 300 /* Otherwise pass it back to the item routine */ 301 ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE); 302 done: 303 #ifdef CRYPTO_MDEBUG 304 if (it->sname) 305 CRYPTO_pop_info(); 306 #endif 307 return ret; 308 } 309 310 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 311 { 312 /* If ADB or STACK just NULL the field */ 313 if (tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK)) 314 *pval = NULL; 315 else 316 asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item)); 317 } 318 319 320 /* NB: could probably combine most of the real XXX_new() behaviour and junk 321 * all the old functions. 322 */ 323 324 int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 325 { 326 ASN1_TYPE *typ; 327 ASN1_STRING *str; 328 int utype; 329 330 if (!it) 331 return 0; 332 333 if (it->funcs) 334 { 335 const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; 336 if (pf->prim_new) 337 return pf->prim_new(pval, it); 338 } 339 340 if (it->itype == ASN1_ITYPE_MSTRING) 341 utype = -1; 342 else 343 utype = it->utype; 344 switch(utype) 345 { 346 case V_ASN1_OBJECT: 347 *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef); 348 return 1; 349 350 case V_ASN1_BOOLEAN: 351 *(ASN1_BOOLEAN *)pval = it->size; 352 return 1; 353 354 case V_ASN1_NULL: 355 *pval = (ASN1_VALUE *)1; 356 return 1; 357 358 case V_ASN1_ANY: 359 typ = OPENSSL_malloc(sizeof(ASN1_TYPE)); 360 if (!typ) 361 return 0; 362 typ->value.ptr = NULL; 363 typ->type = -1; 364 *pval = (ASN1_VALUE *)typ; 365 break; 366 367 default: 368 str = ASN1_STRING_type_new(utype); 369 if (it->itype == ASN1_ITYPE_MSTRING && str) 370 str->flags |= ASN1_STRING_FLAG_MSTRING; 371 *pval = (ASN1_VALUE *)str; 372 break; 373 } 374 if (*pval) 375 return 1; 376 return 0; 377 } 378 379 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 380 { 381 int utype; 382 if (it && it->funcs) 383 { 384 const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; 385 if (pf->prim_clear) 386 pf->prim_clear(pval, it); 387 else 388 *pval = NULL; 389 return; 390 } 391 if (!it || (it->itype == ASN1_ITYPE_MSTRING)) 392 utype = -1; 393 else 394 utype = it->utype; 395 if (utype == V_ASN1_BOOLEAN) 396 *(ASN1_BOOLEAN *)pval = it->size; 397 else *pval = NULL; 398 } 399