/*****************************************************/
#include <int.h>
-#include "parser_aux.h"
+#include <parser_aux.h>
#include <gstr.h>
-#include "structure.h"
-#include "element.h"
+#include <structure.h>
+#include <element.h>
#include <limits.h>
+#include <intprops.h>
static int
_asn1_get_indefinite_length_string (const unsigned char *der, int *len);
long
asn1_get_length_der (const unsigned char *der, int der_len, int *len)
{
- unsigned int ans, sum, last;
- int k, punt;
+ unsigned int ans;
+ int k, punt, sum;
*len = 0;
if (der_len <= 0)
ans = 0;
while (punt <= k && punt < der_len)
{
- last = ans;
-
- ans = (ans*256) + der[punt++];
- if (ans < last)
- /* we wrapped around, no bignum support... */
- return -2;
+ if (INT_MULTIPLY_OVERFLOW (ans, 256))
+ return -2;
+ ans *= 256;
+
+ if (INT_ADD_OVERFLOW (ans, ((unsigned)der[punt])))
+ return -2;
+ ans += der[punt];
+ punt++;
}
}
else
*len = punt;
}
- sum = ans + *len;
-
- /* check for overflow as well INT_MAX as a maximum upper
- * limit for length */
- if (sum >= INT_MAX || sum < ans)
+ sum = ans;
+ if (ans >= INT_MAX || INT_ADD_OVERFLOW (sum, (*len)))
return -2;
-
- if (((int) sum) > der_len)
+ sum += *len;
+
+ if (sum > (unsigned)der_len)
return -4;
return ans;
{
unsigned int ris;
int punt;
- unsigned int last;
if (der == NULL || der_len < 2 || len == NULL)
return ASN1_DER_ERROR;
ris = 0;
while (punt <= der_len && der[punt] & 128)
{
- last = ris;
- ris = (ris * 128) + (der[punt++] & 0x7F);
- if (ris < last)
- /* wrapped around, and no bignums... */
- return ASN1_DER_ERROR;
+ if (INT_MULTIPLY_OVERFLOW (ris, 128))
+ return ASN1_DER_ERROR;
+ ris *= 128;
+
+ if (INT_ADD_OVERFLOW (ris, ((unsigned)(der[punt] & 0x7F))))
+ return ASN1_DER_ERROR;
+ ris += (der[punt] & 0x7F);
+ punt++;
}
if (punt >= der_len)
return ASN1_DER_ERROR;
- last = ris;
-
- ris = (ris * 128) + (der[punt++] & 0x7F);
- if (ris < last)
- return ASN1_DER_ERROR;
+ if (INT_MULTIPLY_OVERFLOW (ris, 128))
+ return ASN1_DER_ERROR;
+ ris *= 128;
+ if (INT_ADD_OVERFLOW (ris, ((unsigned)(der[punt] & 0x7F))))
+ return ASN1_DER_ERROR;
+ ris += (der[punt] & 0x7F);
+ punt++;
+
*len = punt;
}
+
if (tag)
*tag = ris;
return ASN1_SUCCESS;
if (str == NULL || der_len <= 0)
return ASN1_GENERIC_ERROR;
+
len = asn1_get_length_der (der, der_len, &len_len);
if (len < 0 || len > der_len || len_len > der_len)
leading = 0;
/* check for wrap around */
+ if (INT_LEFT_SHIFT_OVERFLOW(val, 7))
+ return ASN1_DER_ERROR;
+
val = val << 7;
val |= der[len_len + k] & 0x7F;
- if (val < prev_val)
- return ASN1_DER_ERROR;
-
- prev_val = val;
-
if (!(der[len_len + k] & 0x80))
{
_asn1_str_cat (str, str_size, ".");
leading = 1;
}
}
+
+ if (INT_ADD_OVERFLOW(len, len_len))
+ return ASN1_DER_ERROR;
+
*ret_len = len + len_len;
return ASN1_SUCCESS;