1/* 2 * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10#include <stddef.h> 11#include <openssl/asn1.h> 12#include <openssl/objects.h> 13#include <openssl/err.h> 14#include <openssl/asn1t.h> 15#include <string.h> 16#include "asn1_local.h" 17 18static int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, 19 int embed, OSSL_LIB_CTX *libctx, 20 const char *propq); 21static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it, 22 int embed); 23static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 24static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, 25 OSSL_LIB_CTX *libctx, const char *propq); 26static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); 27static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 28 29ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) 30{ 31 ASN1_VALUE *ret = NULL; 32 if (ASN1_item_ex_new(&ret, it) > 0) 33 return ret; 34 return NULL; 35} 36 37ASN1_VALUE *ASN1_item_new_ex(const ASN1_ITEM *it, OSSL_LIB_CTX *libctx, 38 const char *propq) 39{ 40 ASN1_VALUE *ret = NULL; 41 if (asn1_item_embed_new(&ret, it, 0, libctx, propq) > 0) 42 return ret; 43 return NULL; 44} 45 46/* Allocate an ASN1 structure */ 47 48 49int ossl_asn1_item_ex_new_intern(ASN1_VALUE **pval, const ASN1_ITEM *it, 50 OSSL_LIB_CTX *libctx, const char *propq) 51{ 52 return asn1_item_embed_new(pval, it, 0, libctx, propq); 53} 54 55int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 56{ 57 return asn1_item_embed_new(pval, it, 0, NULL, NULL); 58} 59 60int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed, 61 OSSL_LIB_CTX *libctx, const char *propq) 62{ 63 const ASN1_TEMPLATE *tt = NULL; 64 const ASN1_EXTERN_FUNCS *ef; 65 const ASN1_AUX *aux = it->funcs; 66 ASN1_aux_cb *asn1_cb; 67 ASN1_VALUE **pseqval; 68 int i; 69 if (aux && aux->asn1_cb) 70 asn1_cb = aux->asn1_cb; 71 else 72 asn1_cb = 0; 73 74 switch (it->itype) { 75 76 case ASN1_ITYPE_EXTERN: 77 ef = it->funcs; 78 if (ef != NULL) { 79 if (ef->asn1_ex_new_ex != NULL) { 80 if (!ef->asn1_ex_new_ex(pval, it, libctx, propq)) 81 goto memerr; 82 } else if (ef->asn1_ex_new != NULL) { 83 if (!ef->asn1_ex_new(pval, it)) 84 goto memerr; 85 } 86 } 87 break; 88 89 case ASN1_ITYPE_PRIMITIVE: 90 if (it->templates) { 91 if (!asn1_template_new(pval, it->templates, libctx, propq)) 92 goto memerr; 93 } else if (!asn1_primitive_new(pval, it, embed)) 94 goto memerr; 95 break; 96 97 case ASN1_ITYPE_MSTRING: 98 if (!asn1_primitive_new(pval, it, embed)) 99 goto memerr; 100 break; 101 102 case ASN1_ITYPE_CHOICE: 103 if (asn1_cb) { 104 i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); 105 if (!i) 106 goto auxerr; 107 if (i == 2) { 108 return 1; 109 } 110 } 111 if (embed) { 112 memset(*pval, 0, it->size); 113 } else { 114 *pval = OPENSSL_zalloc(it->size); 115 if (*pval == NULL) 116 goto memerr; 117 } 118 ossl_asn1_set_choice_selector(pval, -1, it); 119 if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) 120 goto auxerr2; 121 break; 122 123 case ASN1_ITYPE_NDEF_SEQUENCE: 124 case ASN1_ITYPE_SEQUENCE: 125 if (asn1_cb) { 126 i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); 127 if (!i) 128 goto auxerr; 129 if (i == 2) { 130 return 1; 131 } 132 } 133 if (embed) { 134 memset(*pval, 0, it->size); 135 } else { 136 *pval = OPENSSL_zalloc(it->size); 137 if (*pval == NULL) 138 goto memerr; 139 } 140 /* 0 : init. lock */ 141 if (ossl_asn1_do_lock(pval, 0, it) < 0) { 142 if (!embed) { 143 OPENSSL_free(*pval); 144 *pval = NULL; 145 } 146 goto memerr; 147 } 148 ossl_asn1_enc_init(pval, it); 149 for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { 150 pseqval = ossl_asn1_get_field_ptr(pval, tt); 151 if (!asn1_template_new(pseqval, tt, libctx, propq)) 152 goto memerr2; 153 } 154 if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) 155 goto auxerr2; 156 break; 157 } 158 return 1; 159 160 memerr2: 161 ossl_asn1_item_embed_free(pval, it, embed); 162 memerr: 163 ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 164 return 0; 165 166 auxerr2: 167 ossl_asn1_item_embed_free(pval, it, embed); 168 auxerr: 169 ERR_raise(ERR_LIB_ASN1, ASN1_R_AUX_ERROR); 170 return 0; 171 172} 173 174static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 175{ 176 const ASN1_EXTERN_FUNCS *ef; 177 178 switch (it->itype) { 179 180 case ASN1_ITYPE_EXTERN: 181 ef = it->funcs; 182 if (ef && ef->asn1_ex_clear) 183 ef->asn1_ex_clear(pval, it); 184 else 185 *pval = NULL; 186 break; 187 188 case ASN1_ITYPE_PRIMITIVE: 189 if (it->templates) 190 asn1_template_clear(pval, it->templates); 191 else 192 asn1_primitive_clear(pval, it); 193 break; 194 195 case ASN1_ITYPE_MSTRING: 196 asn1_primitive_clear(pval, it); 197 break; 198 199 case ASN1_ITYPE_CHOICE: 200 case ASN1_ITYPE_SEQUENCE: 201 case ASN1_ITYPE_NDEF_SEQUENCE: 202 *pval = NULL; 203 break; 204 } 205} 206 207static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, 208 OSSL_LIB_CTX *libctx, const char *propq) 209{ 210 const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item); 211 int embed = tt->flags & ASN1_TFLG_EMBED; 212 ASN1_VALUE *tval; 213 int ret; 214 if (embed) { 215 tval = (ASN1_VALUE *)pval; 216 pval = &tval; 217 } 218 if (tt->flags & ASN1_TFLG_OPTIONAL) { 219 asn1_template_clear(pval, tt); 220 return 1; 221 } 222 /* If ANY DEFINED BY nothing to do */ 223 224 if (tt->flags & ASN1_TFLG_ADB_MASK) { 225 *pval = NULL; 226 return 1; 227 } 228 /* If SET OF or SEQUENCE OF, its a STACK */ 229 if (tt->flags & ASN1_TFLG_SK_MASK) { 230 STACK_OF(ASN1_VALUE) *skval; 231 skval = sk_ASN1_VALUE_new_null(); 232 if (!skval) { 233 ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 234 ret = 0; 235 goto done; 236 } 237 *pval = (ASN1_VALUE *)skval; 238 ret = 1; 239 goto done; 240 } 241 /* Otherwise pass it back to the item routine */ 242 ret = asn1_item_embed_new(pval, it, embed, libctx, propq); 243 done: 244 return ret; 245} 246 247static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 248{ 249 /* If ADB or STACK just NULL the field */ 250 if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK)) 251 *pval = NULL; 252 else 253 asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item)); 254} 255 256/* 257 * NB: could probably combine most of the real XXX_new() behaviour and junk 258 * all the old functions. 259 */ 260 261static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it, 262 int embed) 263{ 264 ASN1_TYPE *typ; 265 ASN1_STRING *str; 266 int utype; 267 268 if (!it) 269 return 0; 270 271 if (it->funcs) { 272 const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; 273 if (embed) { 274 if (pf->prim_clear) { 275 pf->prim_clear(pval, it); 276 return 1; 277 } 278 } else if (pf->prim_new) { 279 return pf->prim_new(pval, it); 280 } 281 } 282 283 if (it->itype == ASN1_ITYPE_MSTRING) 284 utype = -1; 285 else 286 utype = it->utype; 287 switch (utype) { 288 case V_ASN1_OBJECT: 289 *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef); 290 return 1; 291 292 case V_ASN1_BOOLEAN: 293 *(ASN1_BOOLEAN *)pval = it->size; 294 return 1; 295 296 case V_ASN1_NULL: 297 *pval = (ASN1_VALUE *)1; 298 return 1; 299 300 case V_ASN1_ANY: 301 if ((typ = OPENSSL_malloc(sizeof(*typ))) == NULL) { 302 ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 303 return 0; 304 } 305 typ->value.ptr = NULL; 306 typ->type = -1; 307 *pval = (ASN1_VALUE *)typ; 308 break; 309 310 default: 311 if (embed) { 312 str = *(ASN1_STRING **)pval; 313 memset(str, 0, sizeof(*str)); 314 str->type = utype; 315 str->flags = ASN1_STRING_FLAG_EMBED; 316 } else { 317 str = ASN1_STRING_type_new(utype); 318 *pval = (ASN1_VALUE *)str; 319 } 320 if (it->itype == ASN1_ITYPE_MSTRING && str) 321 str->flags |= ASN1_STRING_FLAG_MSTRING; 322 break; 323 } 324 if (*pval) 325 return 1; 326 return 0; 327} 328 329static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 330{ 331 int utype; 332 if (it && it->funcs) { 333 const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; 334 if (pf->prim_clear) 335 pf->prim_clear(pval, it); 336 else 337 *pval = NULL; 338 return; 339 } 340 if (!it || (it->itype == ASN1_ITYPE_MSTRING)) 341 utype = -1; 342 else 343 utype = it->utype; 344 if (utype == V_ASN1_BOOLEAN) 345 *(ASN1_BOOLEAN *)pval = it->size; 346 else 347 *pval = NULL; 348} 349