aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/asn1/tasn_dec.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/asn1/tasn_dec.c')
-rw-r--r--crypto/asn1/tasn_dec.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c
index b025e5809f..571592199f 100644
--- a/crypto/asn1/tasn_dec.c
+++ b/crypto/asn1/tasn_dec.c
@@ -273,6 +273,12 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
/* If field not present, try the next one */
if (ret == -1)
continue;
+ /*
+ * Set the choice selector here to ensure that the value is
+ * correctly freed upon error. It may be partially initialized
+ * even if parsing failed.
+ */
+ asn1_set_choice_selector(pval, i, it);
/* If positive return, read OK, break loop */
if (ret > 0)
break;
@@ -294,7 +300,6 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
goto err;
}
- asn1_set_choice_selector(pval, i, it);
if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
goto auxerr;
*in = p;
@@ -617,6 +622,8 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
ERR_R_NESTED_ASN1_ERROR);
+ /* |skfield| may be partially allocated despite failure. */
+ ASN1_item_free(skfield, ASN1_ITEM_ptr(tt->item));
goto err;
}
len -= p - q;