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 18 static int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, 19 int embed, OSSL_LIB_CTX *libctx, 20 const char *propq); 21 static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it, 22 int embed); 23 static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 24 static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, 25 OSSL_LIB_CTX *libctx, const char *propq); 26 static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); 27 static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 28 29 ASN1_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 37 ASN1_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 49 int 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 55 int 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 60 int 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 174 static 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 207 static 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 247 static 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 261 static 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 329 static 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