{ERR_FUNC(ASN1_F_ASN1_ITEM_D2I_FP), "ASN1_item_d2i_fp"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_DUP), "ASN1_item_dup"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_EX_D2I), "ASN1_ITEM_EX_D2I"},
- {ERR_FUNC(ASN1_F_ASN1_ITEM_EX_NEW), "ASN1_ITEM_EX_NEW"},
+ {ERR_FUNC(ASN1_F_ASN1_ITEM_EMBED_NEW), "ASN1_ITEM_EMBED_NEW"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_BIO), "ASN1_item_i2d_bio"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP), "ASN1_item_i2d_fp"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_PACK), "ASN1_item_pack"},
{
int flags, aclass;
int ret;
+ ASN1_VALUE *tval;
const unsigned char *p, *q;
if (!val)
return 0;
p = *in;
q = p;
+ /*
+ * If field is embedded then val needs fixing so it is a pointer to
+ * a pointer to a field.
+ */
+ if (tt->flags & ASN1_TFLG_EMBED) {
+ tval = (ASN1_VALUE *)val;
+ val = &tval;
+ }
+
if (flags & ASN1_TFLG_SK_MASK) {
/* SET OF, SEQUENCE OF */
int sktag, skaclass;
const ASN1_TEMPLATE *tt, int tag, int iclass)
{
int i, ret, flags, ttag, tclass, ndef;
+ ASN1_VALUE *tval;
flags = tt->flags;
+
+ /*
+ * If field is embedded then val needs fixing so it is a pointer to
+ * a pointer to a field.
+ */
+ if (flags & ASN1_TFLG_EMBED) {
+ tval = (ASN1_VALUE *)pval;
+ pval = &tval;
+ }
/*
* Work out tag and class to use: tagging may come either from the
* template or the arguments, not both because this would create
#include <openssl/objects.h>
#include "asn1_locl.h"
+static void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
+ int embed);
+
/* Free up an ASN1 structure */
void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
{
- ASN1_item_ex_free(&val, it);
+ asn1_item_embed_free(&val, it, 0);
}
void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ asn1_item_embed_free(pval, it, 0);
+}
+
+static void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
+ int embed)
{
const ASN1_TEMPLATE *tt = NULL, *seqtt;
const ASN1_EXTERN_FUNCS *ef;
}
if (asn1_cb)
asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
- OPENSSL_free(*pval);
- *pval = NULL;
+ if (embed == 0) {
+ OPENSSL_free(*pval);
+ *pval = NULL;
+ }
break;
}
}
void asn1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
{
+ int embed = tt->flags & ASN1_TFLG_EMBED;
+ ASN1_VALUE *tval;
+ if (embed) {
+ tval = (ASN1_VALUE *)pval;
+ pval = &tval;
+ }
if (tt->flags & ASN1_TFLG_SK_MASK) {
STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
int i;
for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
ASN1_VALUE *vtmp = sk_ASN1_VALUE_value(sk, i);
- ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item));
+ asn1_item_embed_free(&vtmp, ASN1_ITEM_ptr(tt->item), embed);
}
sk_ASN1_VALUE_free(sk);
*pval = NULL;
} else {
- ASN1_item_ex_free(pval, ASN1_ITEM_ptr(tt->item));
+ asn1_item_embed_free(pval, ASN1_ITEM_ptr(tt->item), embed);
}
}
#include <string.h>
#include "asn1_locl.h"
+static int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
+ int embed);
static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
/* Allocate an ASN1 structure */
int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ return asn1_item_embed_new(pval, it, 0);
+}
+
+int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
{
const ASN1_TEMPLATE *tt = NULL;
const ASN1_EXTERN_FUNCS *ef;
return 1;
}
}
- *pval = OPENSSL_zalloc(it->size);
- if (!*pval)
- goto memerr;
+ if (embed) {
+ memset(*pval, 0, it->size);
+ } else {
+ *pval = OPENSSL_zalloc(it->size);
+ if (!*pval)
+ goto memerr;
+ }
asn1_do_lock(pval, 0, it);
asn1_enc_init(pval, it);
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
return 1;
memerr:
- ASN1err(ASN1_F_ASN1_ITEM_EX_NEW, ERR_R_MALLOC_FAILURE);
+ ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ERR_R_MALLOC_FAILURE);
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
return 0;
auxerr:
- ASN1err(ASN1_F_ASN1_ITEM_EX_NEW, ASN1_R_AUX_ERROR);
+ ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ASN1_R_AUX_ERROR);
ASN1_item_ex_free(pval, it);
#ifdef CRYPTO_MDEBUG
if (it->sname)
static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
{
const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
+ int embed = tt->flags & ASN1_TFLG_EMBED;
+ ASN1_VALUE *tval;
int ret;
+ if (embed) {
+ tval = (ASN1_VALUE *)pval;
+ pval = &tval;
+ }
if (tt->flags & ASN1_TFLG_OPTIONAL) {
asn1_template_clear(pval, tt);
return 1;
goto done;
}
/* Otherwise pass it back to the item routine */
- ret = ASN1_item_ex_new(pval, it);
+ ret = asn1_item_embed_new(pval, it, embed);
done:
#ifdef CRYPTO_MDEBUG
if (it->sname)
# define ASN1_F_ASN1_ITEM_D2I_FP 206
# define ASN1_F_ASN1_ITEM_DUP 191
# define ASN1_F_ASN1_ITEM_EX_D2I 120
-# define ASN1_F_ASN1_ITEM_EX_NEW 121
+# define ASN1_F_ASN1_ITEM_EMBED_NEW 121
# define ASN1_F_ASN1_ITEM_I2D_BIO 192
# define ASN1_F_ASN1_ITEM_I2D_FP 193
# define ASN1_F_ASN1_ITEM_PACK 198
# endif
/* Plain simple type */
# define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type)
+/* Embedded simple type */
+# define ASN1_EMBED(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_EMBED,0, stname, field, type)
/* OPTIONAL simple type */
# define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type)
# define ASN1_TFLG_NDEF (0x1<<11)
+/* Field is embedded and not a pointer */
+# define ASN1_TFLG_EMBED (0x1 << 12)
+
/* This is the actual ASN1 item itself */
struct ASN1_ITEM_st {