X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fasn1%2Ftasn_dec.c;h=930ee7025b20a674891a10315adbf4723e49d925;hp=0caa8f6bd347e67e765fbbe3427de321cd582a3b;hb=bf0d176e48c6dd44c6cb3250d1e56d9d098f815a;hpb=9d6b1ce6441c7cc6aed344f02d9f676ab5e04217 diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c index 0caa8f6bd3..930ee7025b 100644 --- a/crypto/asn1/tasn_dec.c +++ b/crypto/asn1/tasn_dec.c @@ -201,7 +201,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1 if(tag != -1) { p = *in; imphack = *p; - *p = (*p & V_ASN1_CONSTRUCTED) | it->utype; + *p = (unsigned char)((*p & V_ASN1_CONSTRUCTED) | it->utype); } ptmpval = cf->asn1_d2i(pval, in, len); @@ -315,7 +315,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1 * it increases efficiency in some cases. */ if(i == (it->tcount - 1)) isopt = 0; - else isopt = seqtt->flags & ASN1_TFLG_OPTIONAL; + else isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL); /* attempt to read in field, allowing each to be OPTIONAL */ ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx); if(!ret) { @@ -606,7 +606,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inl cont = *in; /* If indefinite length constructed find the real end */ if(inf) { - asn1_collect(NULL, &p, plen, inf, -1, -1); + if(!asn1_collect(NULL, &p, plen, inf, -1, -1)) goto err; len = p - cont; } else { len = p - cont + plen; @@ -623,9 +623,15 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inl * internally irrespective of the type. So instead just check * for UNIVERSAL class and ignore the tag. */ - asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL); - cont = (unsigned char *)buf.data; + if(!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL)) goto err; len = buf.length; + /* Append a final null to string */ + if(!BUF_MEM_grow(&buf, len + 1)) { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE); + return 0; + } + buf.data[len] = 0; + cont = (unsigned char *)buf.data; free_cont = 1; } else { cont = p; @@ -658,7 +664,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char if(!*pval) { typ = ASN1_TYPE_new(); *pval = (ASN1_VALUE *)typ; - } else typ = (ASN1_TYPE *)pval; + } else typ = (ASN1_TYPE *)*pval; if(utype != typ->type) ASN1_TYPE_set(typ, utype, NULL); pval = (ASN1_VALUE **)&typ->value.ptr; } @@ -865,14 +871,14 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *i ctx->ptag = ptag; ctx->hdrlen = p - q; ctx->valid = 1; - } - /* If definite length, length + header can't exceed total - * amount of data available. - */ - if(!(i & 1) && ((plen + ctx->hdrlen) > len)) { - ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG); - asn1_tlc_clear(ctx); - return 0; + /* If definite length, length + header can't exceed total + * amount of data available. + */ + if(!(i & 1) && ((plen + ctx->hdrlen) > len)) { + ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG); + asn1_tlc_clear(ctx); + return 0; + } } }