mirror of
https://github.com/openssl/openssl.git
synced 2025-01-30 14:01:55 +08:00
ASN.1: Add some sanity checks for input len <= 0; related coding improvements
Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/14357)
This commit is contained in:
parent
db76a35e26
commit
3e73111d13
@ -101,6 +101,7 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
|
||||
uint32_t eos = 0;
|
||||
size_t off = 0;
|
||||
size_t len = 0;
|
||||
size_t diff;
|
||||
|
||||
const unsigned char *q;
|
||||
long slen;
|
||||
@ -114,15 +115,16 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
|
||||
|
||||
ERR_clear_error();
|
||||
for (;;) {
|
||||
if (want >= (len - off)) {
|
||||
want -= (len - off);
|
||||
diff = len - off;
|
||||
if (want >= diff) {
|
||||
want -= diff;
|
||||
|
||||
if (len + want < len || !BUF_MEM_grow_clean(b, len + want)) {
|
||||
ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
i = BIO_read(in, &(b->data[len]), want);
|
||||
if ((i < 0) && ((len - off) == 0)) {
|
||||
if (i < 0 && diff == 0) {
|
||||
ERR_raise(ERR_LIB_ASN1, ASN1_R_NOT_ENOUGH_DATA);
|
||||
goto err;
|
||||
}
|
||||
@ -138,15 +140,17 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
|
||||
|
||||
p = (unsigned char *)&(b->data[off]);
|
||||
q = p;
|
||||
inf = ASN1_get_object(&q, &slen, &tag, &xclass, len - off);
|
||||
diff = len - off;
|
||||
if (diff == 0)
|
||||
goto err;
|
||||
inf = ASN1_get_object(&q, &slen, &tag, &xclass, diff);
|
||||
if (inf & 0x80) {
|
||||
unsigned long e;
|
||||
|
||||
e = ERR_GET_REASON(ERR_peek_error());
|
||||
if (e != ASN1_R_TOO_LONG)
|
||||
goto err;
|
||||
else
|
||||
ERR_clear_error(); /* clear error */
|
||||
ERR_clear_error();
|
||||
}
|
||||
i = q - p; /* header length */
|
||||
off += i; /* end of data */
|
||||
|
@ -52,8 +52,10 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
|
||||
int tag, xclass, inf;
|
||||
long max = omax;
|
||||
|
||||
if (!max)
|
||||
goto err;
|
||||
if (omax <= 0) {
|
||||
ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_SMALL);
|
||||
return 0x80;
|
||||
}
|
||||
ret = (*p & V_ASN1_CONSTRUCTED);
|
||||
xclass = (*p & V_ASN1_PRIVATE);
|
||||
i = *p & V_ASN1_PRIMITIVE_TAG;
|
||||
|
@ -159,6 +159,10 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
|
||||
ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (len <= 0) {
|
||||
ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
aux = it->funcs;
|
||||
if (aux && aux->asn1_cb)
|
||||
asn1_cb = aux->asn1_cb;
|
||||
@ -1108,6 +1112,10 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
|
||||
p = *in;
|
||||
q = p;
|
||||
|
||||
if (len <= 0) {
|
||||
ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_SMALL);
|
||||
goto err;
|
||||
}
|
||||
if (ctx != NULL && ctx->valid) {
|
||||
i = ctx->ret;
|
||||
plen = ctx->plen;
|
||||
@ -1129,14 +1137,15 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
|
||||
*/
|
||||
if ((i & 0x81) == 0 && (plen + ctx->hdrlen) > len) {
|
||||
ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LONG);
|
||||
asn1_tlc_clear(ctx);
|
||||
return 0;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((i & 0x80) != 0)
|
||||
if ((i & 0x80) != 0) {
|
||||
ERR_raise(ERR_LIB_ASN1, ASN1_R_BAD_OBJECT_HEADER);
|
||||
goto err;
|
||||
}
|
||||
if (exptag >= 0) {
|
||||
if (exptag != ptag || expclass != pclass) {
|
||||
/*
|
||||
@ -1144,9 +1153,8 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
|
||||
*/
|
||||
if (opt != 0)
|
||||
return -1;
|
||||
asn1_tlc_clear(ctx);
|
||||
ERR_raise(ERR_LIB_ASN1, ASN1_R_WRONG_TAG);
|
||||
return 0;
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* We have a tag and class match: assume we are going to do something
|
||||
@ -1177,7 +1185,6 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
|
||||
return 1;
|
||||
|
||||
err:
|
||||
ERR_raise(ERR_LIB_ASN1, ASN1_R_BAD_OBJECT_HEADER);
|
||||
asn1_tlc_clear(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user