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