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/asn1t.h> 13e1051a39Sopenharmony_ci#include <openssl/objects.h> 14e1051a39Sopenharmony_ci#include "asn1_local.h" 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci/* Free up an ASN1 structure */ 17e1051a39Sopenharmony_ci 18e1051a39Sopenharmony_civoid ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it) 19e1051a39Sopenharmony_ci{ 20e1051a39Sopenharmony_ci ossl_asn1_item_embed_free(&val, it, 0); 21e1051a39Sopenharmony_ci} 22e1051a39Sopenharmony_ci 23e1051a39Sopenharmony_civoid ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) 24e1051a39Sopenharmony_ci{ 25e1051a39Sopenharmony_ci ossl_asn1_item_embed_free(pval, it, 0); 26e1051a39Sopenharmony_ci} 27e1051a39Sopenharmony_ci 28e1051a39Sopenharmony_civoid ossl_asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) 29e1051a39Sopenharmony_ci{ 30e1051a39Sopenharmony_ci const ASN1_TEMPLATE *tt = NULL, *seqtt; 31e1051a39Sopenharmony_ci const ASN1_EXTERN_FUNCS *ef; 32e1051a39Sopenharmony_ci const ASN1_AUX *aux = it->funcs; 33e1051a39Sopenharmony_ci ASN1_aux_cb *asn1_cb; 34e1051a39Sopenharmony_ci int i; 35e1051a39Sopenharmony_ci 36e1051a39Sopenharmony_ci if (pval == NULL) 37e1051a39Sopenharmony_ci return; 38e1051a39Sopenharmony_ci if ((it->itype != ASN1_ITYPE_PRIMITIVE) && *pval == NULL) 39e1051a39Sopenharmony_ci return; 40e1051a39Sopenharmony_ci if (aux && aux->asn1_cb) 41e1051a39Sopenharmony_ci asn1_cb = aux->asn1_cb; 42e1051a39Sopenharmony_ci else 43e1051a39Sopenharmony_ci asn1_cb = 0; 44e1051a39Sopenharmony_ci 45e1051a39Sopenharmony_ci switch (it->itype) { 46e1051a39Sopenharmony_ci 47e1051a39Sopenharmony_ci case ASN1_ITYPE_PRIMITIVE: 48e1051a39Sopenharmony_ci if (it->templates) 49e1051a39Sopenharmony_ci ossl_asn1_template_free(pval, it->templates); 50e1051a39Sopenharmony_ci else 51e1051a39Sopenharmony_ci ossl_asn1_primitive_free(pval, it, embed); 52e1051a39Sopenharmony_ci break; 53e1051a39Sopenharmony_ci 54e1051a39Sopenharmony_ci case ASN1_ITYPE_MSTRING: 55e1051a39Sopenharmony_ci ossl_asn1_primitive_free(pval, it, embed); 56e1051a39Sopenharmony_ci break; 57e1051a39Sopenharmony_ci 58e1051a39Sopenharmony_ci case ASN1_ITYPE_CHOICE: 59e1051a39Sopenharmony_ci if (asn1_cb) { 60e1051a39Sopenharmony_ci i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); 61e1051a39Sopenharmony_ci if (i == 2) 62e1051a39Sopenharmony_ci return; 63e1051a39Sopenharmony_ci } 64e1051a39Sopenharmony_ci i = ossl_asn1_get_choice_selector(pval, it); 65e1051a39Sopenharmony_ci if ((i >= 0) && (i < it->tcount)) { 66e1051a39Sopenharmony_ci ASN1_VALUE **pchval; 67e1051a39Sopenharmony_ci 68e1051a39Sopenharmony_ci tt = it->templates + i; 69e1051a39Sopenharmony_ci pchval = ossl_asn1_get_field_ptr(pval, tt); 70e1051a39Sopenharmony_ci ossl_asn1_template_free(pchval, tt); 71e1051a39Sopenharmony_ci } 72e1051a39Sopenharmony_ci if (asn1_cb) 73e1051a39Sopenharmony_ci asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); 74e1051a39Sopenharmony_ci if (embed == 0) { 75e1051a39Sopenharmony_ci OPENSSL_free(*pval); 76e1051a39Sopenharmony_ci *pval = NULL; 77e1051a39Sopenharmony_ci } 78e1051a39Sopenharmony_ci break; 79e1051a39Sopenharmony_ci 80e1051a39Sopenharmony_ci case ASN1_ITYPE_EXTERN: 81e1051a39Sopenharmony_ci ef = it->funcs; 82e1051a39Sopenharmony_ci if (ef && ef->asn1_ex_free) 83e1051a39Sopenharmony_ci ef->asn1_ex_free(pval, it); 84e1051a39Sopenharmony_ci break; 85e1051a39Sopenharmony_ci 86e1051a39Sopenharmony_ci case ASN1_ITYPE_NDEF_SEQUENCE: 87e1051a39Sopenharmony_ci case ASN1_ITYPE_SEQUENCE: 88e1051a39Sopenharmony_ci if (ossl_asn1_do_lock(pval, -1, it) != 0) /* if error or ref-counter > 0 */ 89e1051a39Sopenharmony_ci return; 90e1051a39Sopenharmony_ci if (asn1_cb) { 91e1051a39Sopenharmony_ci i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); 92e1051a39Sopenharmony_ci if (i == 2) 93e1051a39Sopenharmony_ci return; 94e1051a39Sopenharmony_ci } 95e1051a39Sopenharmony_ci ossl_asn1_enc_free(pval, it); 96e1051a39Sopenharmony_ci /* 97e1051a39Sopenharmony_ci * If we free up as normal we will invalidate any ANY DEFINED BY 98e1051a39Sopenharmony_ci * field and we won't be able to determine the type of the field it 99e1051a39Sopenharmony_ci * defines. So free up in reverse order. 100e1051a39Sopenharmony_ci */ 101e1051a39Sopenharmony_ci tt = it->templates + it->tcount; 102e1051a39Sopenharmony_ci for (i = 0; i < it->tcount; i++) { 103e1051a39Sopenharmony_ci ASN1_VALUE **pseqval; 104e1051a39Sopenharmony_ci 105e1051a39Sopenharmony_ci tt--; 106e1051a39Sopenharmony_ci seqtt = ossl_asn1_do_adb(*pval, tt, 0); 107e1051a39Sopenharmony_ci if (!seqtt) 108e1051a39Sopenharmony_ci continue; 109e1051a39Sopenharmony_ci pseqval = ossl_asn1_get_field_ptr(pval, seqtt); 110e1051a39Sopenharmony_ci ossl_asn1_template_free(pseqval, seqtt); 111e1051a39Sopenharmony_ci } 112e1051a39Sopenharmony_ci if (asn1_cb) 113e1051a39Sopenharmony_ci asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); 114e1051a39Sopenharmony_ci if (embed == 0) { 115e1051a39Sopenharmony_ci OPENSSL_free(*pval); 116e1051a39Sopenharmony_ci *pval = NULL; 117e1051a39Sopenharmony_ci } 118e1051a39Sopenharmony_ci break; 119e1051a39Sopenharmony_ci } 120e1051a39Sopenharmony_ci} 121e1051a39Sopenharmony_ci 122e1051a39Sopenharmony_civoid ossl_asn1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 123e1051a39Sopenharmony_ci{ 124e1051a39Sopenharmony_ci int embed = tt->flags & ASN1_TFLG_EMBED; 125e1051a39Sopenharmony_ci ASN1_VALUE *tval; 126e1051a39Sopenharmony_ci if (embed) { 127e1051a39Sopenharmony_ci tval = (ASN1_VALUE *)pval; 128e1051a39Sopenharmony_ci pval = &tval; 129e1051a39Sopenharmony_ci } 130e1051a39Sopenharmony_ci if (tt->flags & ASN1_TFLG_SK_MASK) { 131e1051a39Sopenharmony_ci STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; 132e1051a39Sopenharmony_ci int i; 133e1051a39Sopenharmony_ci 134e1051a39Sopenharmony_ci for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) { 135e1051a39Sopenharmony_ci ASN1_VALUE *vtmp = sk_ASN1_VALUE_value(sk, i); 136e1051a39Sopenharmony_ci 137e1051a39Sopenharmony_ci ossl_asn1_item_embed_free(&vtmp, ASN1_ITEM_ptr(tt->item), embed); 138e1051a39Sopenharmony_ci } 139e1051a39Sopenharmony_ci sk_ASN1_VALUE_free(sk); 140e1051a39Sopenharmony_ci *pval = NULL; 141e1051a39Sopenharmony_ci } else { 142e1051a39Sopenharmony_ci ossl_asn1_item_embed_free(pval, ASN1_ITEM_ptr(tt->item), embed); 143e1051a39Sopenharmony_ci } 144e1051a39Sopenharmony_ci} 145e1051a39Sopenharmony_ci 146e1051a39Sopenharmony_civoid ossl_asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) 147e1051a39Sopenharmony_ci{ 148e1051a39Sopenharmony_ci int utype; 149e1051a39Sopenharmony_ci 150e1051a39Sopenharmony_ci /* Special case: if 'it' is a primitive with a free_func, use that. */ 151e1051a39Sopenharmony_ci if (it) { 152e1051a39Sopenharmony_ci const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; 153e1051a39Sopenharmony_ci 154e1051a39Sopenharmony_ci if (embed) { 155e1051a39Sopenharmony_ci if (pf && pf->prim_clear) { 156e1051a39Sopenharmony_ci pf->prim_clear(pval, it); 157e1051a39Sopenharmony_ci return; 158e1051a39Sopenharmony_ci } 159e1051a39Sopenharmony_ci } else if (pf && pf->prim_free) { 160e1051a39Sopenharmony_ci pf->prim_free(pval, it); 161e1051a39Sopenharmony_ci return; 162e1051a39Sopenharmony_ci } 163e1051a39Sopenharmony_ci } 164e1051a39Sopenharmony_ci 165e1051a39Sopenharmony_ci /* Special case: if 'it' is NULL, free contents of ASN1_TYPE */ 166e1051a39Sopenharmony_ci if (!it) { 167e1051a39Sopenharmony_ci ASN1_TYPE *typ = (ASN1_TYPE *)*pval; 168e1051a39Sopenharmony_ci 169e1051a39Sopenharmony_ci utype = typ->type; 170e1051a39Sopenharmony_ci pval = &typ->value.asn1_value; 171e1051a39Sopenharmony_ci if (*pval == NULL) 172e1051a39Sopenharmony_ci return; 173e1051a39Sopenharmony_ci } else if (it->itype == ASN1_ITYPE_MSTRING) { 174e1051a39Sopenharmony_ci utype = -1; 175e1051a39Sopenharmony_ci if (*pval == NULL) 176e1051a39Sopenharmony_ci return; 177e1051a39Sopenharmony_ci } else { 178e1051a39Sopenharmony_ci utype = it->utype; 179e1051a39Sopenharmony_ci if ((utype != V_ASN1_BOOLEAN) && *pval == NULL) 180e1051a39Sopenharmony_ci return; 181e1051a39Sopenharmony_ci } 182e1051a39Sopenharmony_ci 183e1051a39Sopenharmony_ci switch (utype) { 184e1051a39Sopenharmony_ci case V_ASN1_OBJECT: 185e1051a39Sopenharmony_ci ASN1_OBJECT_free((ASN1_OBJECT *)*pval); 186e1051a39Sopenharmony_ci break; 187e1051a39Sopenharmony_ci 188e1051a39Sopenharmony_ci case V_ASN1_BOOLEAN: 189e1051a39Sopenharmony_ci if (it) 190e1051a39Sopenharmony_ci *(ASN1_BOOLEAN *)pval = it->size; 191e1051a39Sopenharmony_ci else 192e1051a39Sopenharmony_ci *(ASN1_BOOLEAN *)pval = -1; 193e1051a39Sopenharmony_ci return; 194e1051a39Sopenharmony_ci 195e1051a39Sopenharmony_ci case V_ASN1_NULL: 196e1051a39Sopenharmony_ci break; 197e1051a39Sopenharmony_ci 198e1051a39Sopenharmony_ci case V_ASN1_ANY: 199e1051a39Sopenharmony_ci ossl_asn1_primitive_free(pval, NULL, 0); 200e1051a39Sopenharmony_ci OPENSSL_free(*pval); 201e1051a39Sopenharmony_ci break; 202e1051a39Sopenharmony_ci 203e1051a39Sopenharmony_ci default: 204e1051a39Sopenharmony_ci ossl_asn1_string_embed_free((ASN1_STRING *)*pval, embed); 205e1051a39Sopenharmony_ci break; 206e1051a39Sopenharmony_ci } 207e1051a39Sopenharmony_ci *pval = NULL; 208e1051a39Sopenharmony_ci} 209