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 #include "../internal.h" 67 68 69 static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, 70 int combine); 71 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 72 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); 73 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 74 75 ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) 76 { 77 ASN1_VALUE *ret = NULL; 78 if (ASN1_item_ex_new(&ret, it) > 0) 79 return ret; 80 return NULL; 81 } 82 83 /* Allocate an ASN1 structure */ 84 85 int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 86 { 87 return asn1_item_ex_combine_new(pval, it, 0); 88 } 89 90 static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, 91 int combine) 92 { 93 const ASN1_TEMPLATE *tt = NULL; 94 const ASN1_COMPAT_FUNCS *cf; 95 const ASN1_EXTERN_FUNCS *ef; 96 const ASN1_AUX *aux = it->funcs; 97 ASN1_aux_cb *asn1_cb; 98 ASN1_VALUE **pseqval; 99 int i; 100 if (aux && aux->asn1_cb) 101 asn1_cb = aux->asn1_cb; 102 else 103 asn1_cb = 0; 104 105 #ifdef CRYPTO_MDEBUG 106 if (it->sname) 107 CRYPTO_push_info(it->sname); 108 #endif 109 110 switch (it->itype) { 111 112 case ASN1_ITYPE_EXTERN: 113 ef = it->funcs; 114 if (ef && ef->asn1_ex_new) { 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 if (!ASN1_template_new(pval, it->templates)) 132 goto memerr; 133 } else if (!ASN1_primitive_new(pval, it)) 134 goto memerr; 135 break; 136 137 case ASN1_ITYPE_MSTRING: 138 if (!ASN1_primitive_new(pval, it)) 139 goto memerr; 140 break; 141 142 case ASN1_ITYPE_CHOICE: 143 if (asn1_cb) { 144 i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); 145 if (!i) 146 goto auxerr; 147 if (i == 2) { 148 #ifdef CRYPTO_MDEBUG 149 if (it->sname) 150 CRYPTO_pop_info(); 151 #endif 152 return 1; 153 } 154 } 155 if (!combine) { 156 *pval = OPENSSL_malloc(it->size); 157 if (!*pval) 158 goto memerr; 159 OPENSSL_memset(*pval, 0, it->size); 160 } 161 asn1_set_choice_selector(pval, -1, it); 162 if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) 163 goto auxerr2; 164 break; 165 166 case ASN1_ITYPE_NDEF_SEQUENCE: 167 case ASN1_ITYPE_SEQUENCE: 168 if (asn1_cb) { 169 i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); 170 if (!i) 171 goto auxerr; 172 if (i == 2) { 173 #ifdef CRYPTO_MDEBUG 174 if (it->sname) 175 CRYPTO_pop_info(); 176 #endif 177 return 1; 178 } 179 } 180 if (!combine) { 181 *pval = OPENSSL_malloc(it->size); 182 if (!*pval) 183 goto memerr; 184 OPENSSL_memset(*pval, 0, it->size); 185 asn1_refcount_set_one(pval, it); 186 asn1_enc_init(pval, it); 187 } 188 for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { 189 pseqval = asn1_get_field_ptr(pval, tt); 190 if (!ASN1_template_new(pseqval, tt)) 191 goto memerr2; 192 } 193 if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) 194 goto auxerr2; 195 break; 196 } 197 #ifdef CRYPTO_MDEBUG 198 if (it->sname) 199 CRYPTO_pop_info(); 200 #endif 201 return 1; 202 203 memerr2: 204 ASN1_item_ex_free(pval, it); 205 memerr: 206 OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); 207 #ifdef CRYPTO_MDEBUG 208 if (it->sname) 209 CRYPTO_pop_info(); 210 #endif 211 return 0; 212 213 auxerr2: 214 ASN1_item_ex_free(pval, it); 215 auxerr: 216 OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR); 217 #ifdef CRYPTO_MDEBUG 218 if (it->sname) 219 CRYPTO_pop_info(); 220 #endif 221 return 0; 222 223 } 224 225 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 226 { 227 const ASN1_EXTERN_FUNCS *ef; 228 229 switch (it->itype) { 230 231 case ASN1_ITYPE_EXTERN: 232 ef = it->funcs; 233 if (ef && ef->asn1_ex_clear) 234 ef->asn1_ex_clear(pval, it); 235 else 236 *pval = NULL; 237 break; 238 239 case ASN1_ITYPE_PRIMITIVE: 240 if (it->templates) 241 asn1_template_clear(pval, it->templates); 242 else 243 asn1_primitive_clear(pval, it); 244 break; 245 246 case ASN1_ITYPE_MSTRING: 247 asn1_primitive_clear(pval, it); 248 break; 249 250 case ASN1_ITYPE_COMPAT: 251 case ASN1_ITYPE_CHOICE: 252 case ASN1_ITYPE_SEQUENCE: 253 case ASN1_ITYPE_NDEF_SEQUENCE: 254 *pval = NULL; 255 break; 256 } 257 } 258 259 int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 260 { 261 const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item); 262 int ret; 263 if (tt->flags & ASN1_TFLG_OPTIONAL) { 264 asn1_template_clear(pval, tt); 265 return 1; 266 } 267 /* If ANY DEFINED BY nothing to do */ 268 269 if (tt->flags & ASN1_TFLG_ADB_MASK) { 270 *pval = NULL; 271 return 1; 272 } 273 #ifdef CRYPTO_MDEBUG 274 if (tt->field_name) 275 CRYPTO_push_info(tt->field_name); 276 #endif 277 /* If SET OF or SEQUENCE OF, its a STACK */ 278 if (tt->flags & ASN1_TFLG_SK_MASK) { 279 STACK_OF(ASN1_VALUE) *skval; 280 skval = sk_ASN1_VALUE_new_null(); 281 if (!skval) { 282 OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); 283 ret = 0; 284 goto done; 285 } 286 *pval = (ASN1_VALUE *)skval; 287 ret = 1; 288 goto done; 289 } 290 /* Otherwise pass it back to the item routine */ 291 ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE); 292 done: 293 #ifdef CRYPTO_MDEBUG 294 if (it->sname) 295 CRYPTO_pop_info(); 296 #endif 297 return ret; 298 } 299 300 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 301 { 302 /* If ADB or STACK just NULL the field */ 303 if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK)) 304 *pval = NULL; 305 else 306 asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item)); 307 } 308 309 /* 310 * NB: could probably combine most of the real XXX_new() behaviour and junk 311 * all the old functions. 312 */ 313 314 int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 315 { 316 ASN1_TYPE *typ; 317 ASN1_STRING *str; 318 int utype; 319 320 if (!it) 321 return 0; 322 323 if (it->funcs) { 324 const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; 325 if (pf->prim_new) 326 return pf->prim_new(pval, it); 327 } 328 329 if (it->itype == ASN1_ITYPE_MSTRING) 330 utype = -1; 331 else 332 utype = it->utype; 333 switch (utype) { 334 case V_ASN1_OBJECT: 335 *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef); 336 return 1; 337 338 case V_ASN1_BOOLEAN: 339 *(ASN1_BOOLEAN *)pval = it->size; 340 return 1; 341 342 case V_ASN1_NULL: 343 *pval = (ASN1_VALUE *)1; 344 return 1; 345 346 case V_ASN1_ANY: 347 typ = OPENSSL_malloc(sizeof(ASN1_TYPE)); 348 if (!typ) 349 return 0; 350 typ->value.ptr = NULL; 351 typ->type = -1; 352 *pval = (ASN1_VALUE *)typ; 353 break; 354 355 default: 356 str = ASN1_STRING_type_new(utype); 357 if (it->itype == ASN1_ITYPE_MSTRING && str) 358 str->flags |= ASN1_STRING_FLAG_MSTRING; 359 *pval = (ASN1_VALUE *)str; 360 break; 361 } 362 if (*pval) 363 return 1; 364 return 0; 365 } 366 367 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 368 { 369 int utype; 370 if (it && it->funcs) { 371 const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; 372 if (pf->prim_clear) 373 pf->prim_clear(pval, it); 374 else 375 *pval = NULL; 376 return; 377 } 378 if (!it || (it->itype == ASN1_ITYPE_MSTRING)) 379 utype = -1; 380 else 381 utype = it->utype; 382 if (utype == V_ASN1_BOOLEAN) 383 *(ASN1_BOOLEAN *)pval = it->size; 384 else 385 *pval = NULL; 386 } 387