1 /* $OpenBSD: tasn_new.c,v 1.18 2019/04/01 15:48:04 jsing Exp $ */ 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3 * project 2000. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * licensing@OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@cryptsoft.com). 56 * 57 */ 58 59 60 #include <stddef.h> 61 #include <openssl/asn1.h> 62 #include <openssl/objects.h> 63 #include <openssl/err.h> 64 #include <openssl/asn1t.h> 65 #include <string.h> 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 * 74 ASN1_item_new(const ASN1_ITEM *it) 75 { 76 ASN1_VALUE *ret = NULL; 77 if (ASN1_item_ex_new(&ret, it) > 0) 78 return ret; 79 return NULL; 80 } 81 82 /* Allocate an ASN1 structure */ 83 84 int 85 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 91 asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine) 92 { 93 const ASN1_TEMPLATE *tt = NULL; 94 const ASN1_EXTERN_FUNCS *ef; 95 const ASN1_AUX *aux = it->funcs; 96 ASN1_aux_cb *asn1_cb = NULL; 97 ASN1_VALUE **pseqval; 98 int i; 99 100 if (aux != NULL && aux->asn1_cb != NULL) 101 asn1_cb = aux->asn1_cb; 102 103 if (!combine) 104 *pval = NULL; 105 106 #ifdef CRYPTO_MDEBUG 107 if (it->sname) 108 CRYPTO_push_info(it->sname); 109 #endif 110 111 switch (it->itype) { 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_PRIMITIVE: 121 if (it->templates) { 122 if (!ASN1_template_new(pval, it->templates)) 123 goto memerr; 124 } else if (!ASN1_primitive_new(pval, it)) 125 goto memerr; 126 break; 127 128 case ASN1_ITYPE_MSTRING: 129 if (!ASN1_primitive_new(pval, it)) 130 goto memerr; 131 break; 132 133 case ASN1_ITYPE_CHOICE: 134 if (asn1_cb) { 135 i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); 136 if (!i) 137 goto auxerr; 138 if (i == 2) { 139 #ifdef CRYPTO_MDEBUG 140 if (it->sname) 141 CRYPTO_pop_info(); 142 #endif 143 return 1; 144 } 145 } 146 if (!combine) { 147 *pval = calloc(1, it->size); 148 if (!*pval) 149 goto memerr; 150 } 151 asn1_set_choice_selector(pval, -1, it); 152 if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) 153 goto auxerr; 154 break; 155 156 case ASN1_ITYPE_NDEF_SEQUENCE: 157 case ASN1_ITYPE_SEQUENCE: 158 if (asn1_cb) { 159 i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); 160 if (!i) 161 goto auxerr; 162 if (i == 2) { 163 #ifdef CRYPTO_MDEBUG 164 if (it->sname) 165 CRYPTO_pop_info(); 166 #endif 167 return 1; 168 } 169 } 170 if (!combine) { 171 *pval = calloc(1, it->size); 172 if (!*pval) 173 goto memerr; 174 asn1_do_lock(pval, 0, it); 175 asn1_enc_init(pval, it); 176 } 177 for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { 178 pseqval = asn1_get_field_ptr(pval, tt); 179 if (!ASN1_template_new(pseqval, tt)) 180 goto memerr; 181 } 182 if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) 183 goto auxerr; 184 break; 185 } 186 #ifdef CRYPTO_MDEBUG 187 if (it->sname) 188 CRYPTO_pop_info(); 189 #endif 190 return 1; 191 192 memerr: 193 ASN1error(ERR_R_MALLOC_FAILURE); 194 #ifdef CRYPTO_MDEBUG 195 if (it->sname) 196 CRYPTO_pop_info(); 197 #endif 198 return 0; 199 200 auxerr: 201 ASN1error(ASN1_R_AUX_ERROR); 202 ASN1_item_ex_free(pval, it); 203 #ifdef CRYPTO_MDEBUG 204 if (it->sname) 205 CRYPTO_pop_info(); 206 #endif 207 return 0; 208 209 } 210 211 static void 212 asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 213 { 214 const ASN1_EXTERN_FUNCS *ef; 215 216 switch (it->itype) { 217 case ASN1_ITYPE_EXTERN: 218 ef = it->funcs; 219 if (ef && ef->asn1_ex_clear) 220 ef->asn1_ex_clear(pval, it); 221 else 222 *pval = NULL; 223 break; 224 225 case ASN1_ITYPE_PRIMITIVE: 226 if (it->templates) 227 asn1_template_clear(pval, it->templates); 228 else 229 asn1_primitive_clear(pval, it); 230 break; 231 232 case ASN1_ITYPE_MSTRING: 233 asn1_primitive_clear(pval, it); 234 break; 235 236 case ASN1_ITYPE_CHOICE: 237 case ASN1_ITYPE_SEQUENCE: 238 case ASN1_ITYPE_NDEF_SEQUENCE: 239 *pval = NULL; 240 break; 241 } 242 } 243 244 int 245 ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 246 { 247 const ASN1_ITEM *it = tt->item; 248 int ret; 249 250 if (tt->flags & ASN1_TFLG_OPTIONAL) { 251 asn1_template_clear(pval, tt); 252 return 1; 253 } 254 /* If ANY DEFINED BY nothing to do */ 255 256 if (tt->flags & ASN1_TFLG_ADB_MASK) { 257 *pval = NULL; 258 return 1; 259 } 260 #ifdef CRYPTO_MDEBUG 261 if (tt->field_name) 262 CRYPTO_push_info(tt->field_name); 263 #endif 264 /* If SET OF or SEQUENCE OF, its a STACK */ 265 if (tt->flags & ASN1_TFLG_SK_MASK) { 266 STACK_OF(ASN1_VALUE) *skval; 267 skval = sk_ASN1_VALUE_new_null(); 268 if (!skval) { 269 ASN1error(ERR_R_MALLOC_FAILURE); 270 ret = 0; 271 goto done; 272 } 273 *pval = (ASN1_VALUE *)skval; 274 ret = 1; 275 goto done; 276 } 277 /* Otherwise pass it back to the item routine */ 278 ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE); 279 done: 280 #ifdef CRYPTO_MDEBUG 281 if (it->sname) 282 CRYPTO_pop_info(); 283 #endif 284 return ret; 285 } 286 287 static void 288 asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 289 { 290 /* If ADB or STACK just NULL the field */ 291 if (tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK)) 292 *pval = NULL; 293 else 294 asn1_item_clear(pval, tt->item); 295 } 296 297 298 /* NB: could probably combine most of the real XXX_new() behaviour and junk 299 * all the old functions. 300 */ 301 302 int 303 ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 304 { 305 ASN1_TYPE *typ; 306 ASN1_STRING *str; 307 int utype; 308 309 if (it != NULL && it->funcs != NULL) { 310 const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; 311 312 if (pf->prim_new == NULL) 313 return 0; 314 return pf->prim_new(pval, it); 315 } 316 317 if (!it || (it->itype == ASN1_ITYPE_MSTRING)) 318 utype = V_ASN1_UNDEF; 319 else 320 utype = it->utype; 321 switch (utype) { 322 case V_ASN1_OBJECT: 323 *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef); 324 return 1; 325 326 case V_ASN1_BOOLEAN: 327 *(ASN1_BOOLEAN *)pval = it->size; 328 return 1; 329 330 case V_ASN1_NULL: 331 *pval = (ASN1_VALUE *)1; 332 return 1; 333 334 case V_ASN1_ANY: 335 typ = malloc(sizeof(ASN1_TYPE)); 336 if (typ != NULL) { 337 typ->value.ptr = NULL; 338 typ->type = V_ASN1_UNDEF; 339 } 340 *pval = (ASN1_VALUE *)typ; 341 break; 342 343 default: 344 str = ASN1_STRING_type_new(utype); 345 if (it != NULL && it->itype == ASN1_ITYPE_MSTRING && 346 str != NULL) 347 str->flags |= ASN1_STRING_FLAG_MSTRING; 348 *pval = (ASN1_VALUE *)str; 349 break; 350 } 351 if (*pval) 352 return 1; 353 return 0; 354 } 355 356 static void 357 asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 358 { 359 int utype; 360 361 if (it != NULL && it->funcs != NULL) { 362 const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; 363 364 if (pf->prim_clear) 365 pf->prim_clear(pval, it); 366 else 367 *pval = NULL; 368 return; 369 } 370 371 if (!it || (it->itype == ASN1_ITYPE_MSTRING)) 372 utype = V_ASN1_UNDEF; 373 else 374 utype = it->utype; 375 if (utype == V_ASN1_BOOLEAN) 376 *(ASN1_BOOLEAN *)pval = it->size; 377 else 378 *pval = NULL; 379 } 380