From fefff2e46209079af26d9c34090f18217b8dcf51 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 5 Nov 2019 13:15:23 +0100 Subject: [PATCH] asn1: Simplify the OID decoding --- src/libopensc/asn1.c | 48 ++++++++++++++++---------------------------- 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 2756fff0..83265c23 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -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; }