X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fasn1%2Ftasn_dec.c;h=aa26a44eadbdda8d4498e6a6f35b0f02bf3c4a12;hp=0fc1f421e28dc3819a3631aabbfd086d7e9814ce;hb=875a644a9047e96dfcce27af876d30460759805e;hpb=866eedb93652b809adc3c81cefaebb63c5ad9044 diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c index 0fc1f421e2..aa26a44ead 100644 --- a/crypto/asn1/tasn_dec.c +++ b/crypto/asn1/tasn_dec.c @@ -65,14 +65,14 @@ #include #include -static int asn1_check_eoc(unsigned char **in, long len); -static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag, int aclass); -static int collect_data(BUF_MEM *buf, unsigned char **p, long plen); +static int asn1_check_eoc(const unsigned char **in, long len); +static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, char inf, int tag, int aclass); +static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen); static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, char *cst, - unsigned char **in, long len, int exptag, int expclass, char opt, ASN1_TLC *ctx); -static int asn1_template_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx); -static int asn1_template_noexp_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx); -static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long len, + const unsigned char **in, long len, int exptag, int expclass, char opt, ASN1_TLC *ctx); +static int asn1_template_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx); +static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx); +static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx); /* Table to convert tags to bit values, used for MSTRING type */ @@ -106,7 +106,7 @@ unsigned long ASN1_tag2bit(int tag) * case. */ -ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_ITEM *it) +ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it) { ASN1_TLC c; ASN1_VALUE *ptmpval = NULL; @@ -117,7 +117,7 @@ ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const return NULL; } -int ASN1_template_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_TEMPLATE *tt) +int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt) { ASN1_TLC c; asn1_tlc_clear(&c); @@ -129,7 +129,7 @@ int ASN1_template_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN * If 'opt' set and tag mismatch return -1 to handle OPTIONAL */ -int ASN1_item_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_ITEM *it, +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx) { const ASN1_TEMPLATE *tt, *errtt = NULL; @@ -137,7 +137,9 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1 const ASN1_EXTERN_FUNCS *ef; const ASN1_AUX *aux = it->funcs; ASN1_aux_cb *asn1_cb; - unsigned char *p, *q, imphack = 0, oclass; + const unsigned char *p, *q; + unsigned char *wp=NULL; /* BIG FAT WARNING! BREAKS CONST WHERE USED */ + unsigned char imphack = 0, oclass; char seq_eoc, seq_nolen, cst, isopt; long tmplen; int i; @@ -229,14 +231,14 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1 */ if(tag != -1) { - p = *in; - imphack = *p; - *p = (unsigned char)((*p & V_ASN1_CONSTRUCTED) | it->utype); + wp = *(unsigned char **)in; + imphack = *wp; + *wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED) | it->utype); } ptmpval = cf->asn1_d2i(pval, in, len); - if(tag != -1) *p = imphack; + if(tag != -1) *wp = imphack; if(ptmpval) return 1; ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); @@ -289,6 +291,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1 goto auxerr; return 1; + case ASN1_ITYPE_NDEF_SEQUENCE: case ASN1_ITYPE_SEQUENCE: p = *in; tmplen = len; @@ -415,12 +418,12 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1 * rest. */ -static int asn1_template_ex_d2i(ASN1_VALUE **val, unsigned char **in, long inlen, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx) +static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long inlen, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx) { int flags, aclass; int ret; long len; - unsigned char *p, *q; + const unsigned char *p, *q; char exp_eoc; if(!val) return 0; flags = tt->flags; @@ -477,11 +480,11 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, unsigned char **in, long inlen return 0; } -static int asn1_template_noexp_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx) +static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx) { int flags, aclass; int ret; - unsigned char *p, *q; + const unsigned char *p, *q; if(!val) return 0; flags = tt->flags; aclass = flags & ASN1_TFLG_TAG_CLASS; @@ -577,16 +580,16 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, unsigned char **in, long le return 0; } -static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inlen, +static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen, const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx) { int ret = 0, utype; long plen; char cst, inf, free_cont = 0; - unsigned char *p; + const unsigned char *p; BUF_MEM buf; - unsigned char *cont = NULL; + const unsigned char *cont = NULL; long len; if(!pval) { ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL); @@ -664,12 +667,12 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inl 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)) { + if(!BUF_MEM_grow_clean(&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; + cont = (const unsigned char *)buf.data; free_cont = 1; } else { cont = p; @@ -689,8 +692,9 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inl /* Translate ASN1 content octets into a structure */ -int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it) +int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it) { + ASN1_VALUE **opval = NULL; ASN1_STRING *stmp; ASN1_TYPE *typ = NULL; int ret = 0; @@ -705,6 +709,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *pval = (ASN1_VALUE *)typ; } else typ = (ASN1_TYPE *)*pval; if(utype != typ->type) ASN1_TYPE_set(typ, utype, NULL); + opval = pval; pval = (ASN1_VALUE **)&typ->value.ptr; } switch(utype) { @@ -778,7 +783,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char /* If we've already allocated a buffer use it */ if(*free_cont) { if(stmp->data) OPENSSL_free(stmp->data); - stmp->data = cont; + stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */ stmp->length = len; *free_cont = 0; } else { @@ -796,7 +801,12 @@ int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char ret = 1; err: - if(!ret) ASN1_TYPE_free(typ); + if(!ret) + { + ASN1_TYPE_free(typ); + if (opval) + *opval = NULL; + } return ret; } @@ -808,9 +818,9 @@ int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char * length constructed stuff. */ -static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag, int aclass) +static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, char inf, int tag, int aclass) { - unsigned char *p, *q; + const unsigned char *p, *q; long plen; char cst, ininf; p = *in; @@ -852,12 +862,12 @@ static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, in return 1; } -static int collect_data(BUF_MEM *buf, unsigned char **p, long plen) +static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen) { int len; if(buf) { len = buf->length; - if(!BUF_MEM_grow(buf, len + plen)) { + if(!BUF_MEM_grow_clean(buf, len + plen)) { ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE); return 0; } @@ -869,9 +879,9 @@ static int collect_data(BUF_MEM *buf, unsigned char **p, long plen) /* Check for ASN1 EOC and swallow it if found */ -static int asn1_check_eoc(unsigned char **in, long len) +static int asn1_check_eoc(const unsigned char **in, long len) { - unsigned char *p; + const unsigned char *p; if(len < 2) return 0; p = *in; if(!p[0] && !p[1]) { @@ -889,12 +899,12 @@ static int asn1_check_eoc(unsigned char **in, long len) */ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, char *cst, - unsigned char **in, long len, int exptag, int expclass, char opt, ASN1_TLC *ctx) + const unsigned char **in, long len, int exptag, int expclass, char opt, ASN1_TLC *ctx) { int i; int ptag, pclass; long plen; - unsigned char *p, *q; + const unsigned char *p, *q; p = *in; q = p; @@ -913,10 +923,10 @@ 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 definite length, and no error, length + + * header can't exceed total amount of data available. */ - if(!(i & 1) && ((plen + ctx->hdrlen) > len)) { + if(!(i & 0x81) && ((plen + ctx->hdrlen) > len)) { ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG); asn1_tlc_clear(ctx); return 0;