summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2016-08-02 00:45:31 +0100
committerDr. Stephen Henson <steve@openssl.org>2016-08-02 20:55:06 +0100
commite3db6f1c43f59eefec2608cef1fb3ca47c81a58f (patch)
tree4e83009245a09ce0d027441b9bb6cf536854c139
parent6adf409c7432b90c06d9890787fe56c48f2a16e7 (diff)
Check for overlows and error return from ASN1_object_size()
Reviewed-by: Richard Levitte <levitte@openssl.org> (cherry picked from commit 56f9953c846204cb3251ab27605e403c7444fd72)
-rw-r--r--crypto/asn1/a_object.c2
-rw-r--r--crypto/asn1/tasn_enc.c25
2 files changed, 17 insertions, 10 deletions
diff --git a/crypto/asn1/a_object.c b/crypto/asn1/a_object.c
index 27f9c16914..fba9f66454 100644
--- a/crypto/asn1/a_object.c
+++ b/crypto/asn1/a_object.c
@@ -73,7 +73,7 @@ int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
return (0);
objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
- if (pp == NULL)
+ if (pp == NULL || objsize == -1)
return objsize;
p = *pp;
diff --git a/crypto/asn1/tasn_enc.c b/crypto/asn1/tasn_enc.c
index f7f83e56a9..255b11e756 100644
--- a/crypto/asn1/tasn_enc.c
+++ b/crypto/asn1/tasn_enc.c
@@ -216,17 +216,19 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
const ASN1_TEMPLATE *seqtt;
ASN1_VALUE **pseqval;
+ int tmplen;
seqtt = asn1_do_adb(pval, tt, 1);
if (!seqtt)
return 0;
pseqval = asn1_get_field_ptr(pval, seqtt);
- /* FIXME: check for errors in enhanced version */
- seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,
- -1, aclass);
+ tmplen = asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, aclass);
+ if (tmplen == -1 || (tmplen > INT_MAX - seqcontlen))
+ return -1;
+ seqcontlen += tmplen;
}
seqlen = ASN1_object_size(ndef, seqcontlen, tag);
- if (!out)
+ if (!out || seqlen == -1)
return seqlen;
/* Output SEQUENCE header */
ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
@@ -339,19 +341,24 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
/* Determine total length of items */
skcontlen = 0;
for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
+ int tmplen;
skitem = sk_ASN1_VALUE_value(sk, i);
- skcontlen += ASN1_item_ex_i2d(&skitem, NULL,
- ASN1_ITEM_ptr(tt->item),
- -1, iclass);
+ tmplen = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item),
+ -1, iclass);
+ if (tmplen == -1 || (skcontlen > INT_MAX - tmplen))
+ return -1;
+ skcontlen += tmplen;
}
sklen = ASN1_object_size(ndef, skcontlen, sktag);
+ if (sklen == -1)
+ return -1;
/* If EXPLICIT need length of surrounding tag */
if (flags & ASN1_TFLG_EXPTAG)
ret = ASN1_object_size(ndef, sklen, ttag);
else
ret = sklen;
- if (!out)
+ if (!out || ret == -1)
return ret;
/* Now encode this lot... */
@@ -380,7 +387,7 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
return 0;
/* Find length of EXPLICIT tag */
ret = ASN1_object_size(ndef, i, ttag);
- if (out) {
+ if (out && ret != -1) {
/* Output tag and item */
ASN1_put_object(out, ndef, i, ttag, tclass);
ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, iclass);