76 lines
3.0 KiB
Diff
76 lines
3.0 KiB
Diff
diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c
|
|
index 70ea5f08798..197fd241054 100644
|
|
--- a/crypto/asn1/tasn_dec.c
|
|
+++ b/crypto/asn1/tasn_dec.c
|
|
@@ -54,7 +54,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
|
|
const ASN1_ITEM *it,
|
|
int tag, int aclass, char opt,
|
|
ASN1_TLC *ctx);
|
|
-static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
|
|
+static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, long len,
|
|
int utype, char *free_cont, const ASN1_ITEM *it);
|
|
|
|
/* Table to convert tags to bit values, used for MSTRING type */
|
|
@@ -855,19 +855,24 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
|
|
|
|
/* Translate ASN1 content octets into a structure */
|
|
|
|
-static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
|
|
+static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, long len,
|
|
int utype, char *free_cont, const ASN1_ITEM *it)
|
|
{
|
|
ASN1_VALUE **opval = NULL;
|
|
ASN1_STRING *stmp;
|
|
ASN1_TYPE *typ = NULL;
|
|
int ret = 0;
|
|
+ int ilen = (int)len;
|
|
const ASN1_PRIMITIVE_FUNCS *pf;
|
|
ASN1_INTEGER **tint;
|
|
pf = it->funcs;
|
|
|
|
- if (pf && pf->prim_c2i)
|
|
- return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
|
|
+ if (pf && pf->prim_c2i) {
|
|
+ if (len == (long)ilen)
|
|
+ return pf->prim_c2i(pval, cont, ilen, utype, free_cont, it);
|
|
+ ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LONG);
|
|
+ return 0;
|
|
+ }
|
|
/* If ANY type clear type and set pointer to internal value */
|
|
if (it->utype == V_ASN1_ANY) {
|
|
if (*pval == NULL) {
|
|
@@ -885,7 +890,8 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
|
|
}
|
|
switch (utype) {
|
|
case V_ASN1_OBJECT:
|
|
- if (!ossl_c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
|
|
+ if (len != (long)ilen
|
|
+ || !ossl_c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, ilen))
|
|
goto err;
|
|
break;
|
|
|
|
@@ -940,6 +946,10 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
|
|
case V_ASN1_SET:
|
|
case V_ASN1_SEQUENCE:
|
|
default:
|
|
+ if (len != (long)ilen) {
|
|
+ ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LONG);
|
|
+ goto err;
|
|
+ }
|
|
if (utype == V_ASN1_BMPSTRING && (len & 1)) {
|
|
ERR_raise(ERR_LIB_ASN1, ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
|
|
goto err;
|
|
@@ -970,10 +980,10 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
|
|
}
|
|
/* If we've already allocated a buffer use it */
|
|
if (*free_cont) {
|
|
- ASN1_STRING_set0(stmp, (unsigned char *)cont /* UGLY CAST! */, len);
|
|
+ ASN1_STRING_set0(stmp, (unsigned char *)cont /* UGLY CAST! */, ilen);
|
|
*free_cont = 0;
|
|
} else {
|
|
- if (!ASN1_STRING_set(stmp, cont, len)) {
|
|
+ if (!ASN1_STRING_set(stmp, cont, ilen)) {
|
|
ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
|
|
ASN1_STRING_free(stmp);
|
|
*pval = NULL;
|