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