asn1: Simplify the OID decoding

This commit is contained in:
Jakub Jelen 2019-11-05 13:15:23 +01:00
parent 4569009418
commit fefff2e462
1 changed files with 17 additions and 31 deletions

View File

@ -815,7 +815,8 @@ static int asn1_encode_integer(int in, u8 ** obj, size_t * objsize)
int
sc_asn1_decode_object_id(const u8 *inbuf, size_t inlen, struct sc_object_id *id)
{
int a;
int large_second_octet = 0;
unsigned int a = 0;
const u8 *p = inbuf;
int *octet;
@ -836,42 +837,19 @@ sc_asn1_decode_object_id(const u8 *inbuf, size_t inlen, struct sc_object_id *id)
*octet++ = *p - (a * 40);
inlen--;
} else {
/* Use unsigned type here so we can process the whole INT range */
unsigned int value = (*p & 0x7F);
inlen--;
while (inlen && *p & 0x80) {
/* Limit the OID values to int size and do not overflow */
if (value > (UINT_MAX>>7)) {
sc_init_oid(id);
return SC_ERROR_NOT_SUPPORTED;
}
p++;
value <<= 7;
value |= *p & 0x7F;
inlen--;
}
if (*p & 0x80) {
/* We dropped out from previous cycle on the end of
* data while still expecting continuation of value */
sc_init_oid(id);
return SC_ERROR_INVALID_ASN1_OBJECT;
}
/* In this case, the first octet was 2 */
value -= (2 * 40);
if (value > INT_MAX) {
sc_init_oid(id);
return SC_ERROR_NOT_SUPPORTED;
}
*octet++ = value;
large_second_octet = 1;
}
while (inlen) {
p++;
if (!large_second_octet)
p++;
/* Use unsigned type here so we can process the whole INT range.
* Values can not be negative */
a = *p & 0x7F;
inlen--;
while (inlen && *p & 0x80) {
/* Limit the OID values to int size and do not overflow */
if (a > (INT_MAX>>7)) {
if (a > (UINT_MAX>>7)) {
sc_init_oid(id);
return SC_ERROR_NOT_SUPPORTED;
}
@ -886,12 +864,20 @@ sc_asn1_decode_object_id(const u8 *inbuf, size_t inlen, struct sc_object_id *id)
sc_init_oid(id);
return SC_ERROR_INVALID_ASN1_OBJECT;
}
if (large_second_octet) {
a -= (2 * 40);
}
if (a > INT_MAX) {
sc_init_oid(id);
return SC_ERROR_NOT_SUPPORTED;
}
*octet++ = a;
if (octet - id->value >= SC_MAX_OBJECT_ID_OCTETS) {
sc_init_oid(id);
return SC_ERROR_INVALID_ASN1_OBJECT;
}
};
large_second_octet = 0;
}
return 0;
}