diff options
Diffstat (limited to 'crypto/asn1/asn1_lib.c')
| -rw-r--r-- | crypto/asn1/asn1_lib.c | 32 | 
1 files changed, 18 insertions, 14 deletions
| diff --git a/crypto/asn1/asn1_lib.c b/crypto/asn1/asn1_lib.c index 874b1af8b09a4..e63e82a8b4762 100644 --- a/crypto/asn1/asn1_lib.c +++ b/crypto/asn1/asn1_lib.c @@ -256,26 +256,30 @@ static void asn1_put_length(unsigned char **pp, int length)  int ASN1_object_size(int constructed, int length, int tag)  { -    int ret; - -    ret = length; -    ret++; +    int ret = 1; +    if (length < 0) +        return -1;      if (tag >= 31) {          while (tag > 0) {              tag >>= 7;              ret++;          }      } -    if (constructed == 2) -        return ret + 3; -    ret++; -    if (length > 127) { -        while (length > 0) { -            length >>= 8; -            ret++; +    if (constructed == 2) { +        ret += 3; +    } else { +        ret++; +        if (length > 127) { +            int tmplen = length; +            while (tmplen > 0) { +                tmplen >>= 8; +                ret++; +            }          }      } -    return (ret); +    if (ret >= INT_MAX - length) +        return -1; +    return ret + length;  }  static int _asn1_Finish(ASN1_const_CTX *c) @@ -324,7 +328,7 @@ int asn1_GetSequence(ASN1_const_CTX *c, long *length)          return (0);      }      if (c->inf == (1 | V_ASN1_CONSTRUCTED)) -        c->slen = *length + *(c->pp) - c->p; +        c->slen = *length;      c->eos = 0;      return (1);  } @@ -366,7 +370,7 @@ int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)          else              len = strlen(data);      } -    if ((str->length < len) || (str->data == NULL)) { +    if ((str->length <= len) || (str->data == NULL)) {          c = str->data;          if (c == NULL)              str->data = OPENSSL_malloc(len + 1); | 
