asn1: Allow non-strict INTEGER parsing for other code paths (FCI parsing)
This commit is contained in:
parent
fefff2e462
commit
aaa302ca35
|
@ -713,7 +713,7 @@ static int encode_bit_field(const u8 *inbuf, size_t inlen,
|
|||
return encode_bit_string(data, bits, outbuf, outlen, 1);
|
||||
}
|
||||
|
||||
int sc_asn1_decode_integer(const u8 * inbuf, size_t inlen, int *out)
|
||||
int sc_asn1_decode_integer(const u8 * inbuf, size_t inlen, int *out, int strict)
|
||||
{
|
||||
int a = 0, is_negative = 0;
|
||||
size_t i = 0;
|
||||
|
@ -725,14 +725,14 @@ int sc_asn1_decode_integer(const u8 * inbuf, size_t inlen, int *out)
|
|||
return SC_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
if (inbuf[0] & 0x80) {
|
||||
if (inlen > 1 && inbuf[0] == 0xff && (inbuf[1] & 0x80)) {
|
||||
if (strict && inlen > 1 && inbuf[0] == 0xff && (inbuf[1] & 0x80)) {
|
||||
return SC_ERROR_INVALID_ASN1_OBJECT;
|
||||
}
|
||||
is_negative = 1;
|
||||
a |= 0xff^(*inbuf++);
|
||||
i = 1;
|
||||
} else {
|
||||
if (inlen > 1 && inbuf[0] == 0x00 && (inbuf[1] & 0x80) == 0) {
|
||||
if (strict && inlen > 1 && inbuf[0] == 0x00 && (inbuf[1] & 0x80) == 0) {
|
||||
return SC_ERROR_INVALID_ASN1_OBJECT;
|
||||
}
|
||||
}
|
||||
|
@ -1496,7 +1496,7 @@ static int asn1_decode_entry(sc_context_t *ctx,struct sc_asn1_entry *entry,
|
|||
case SC_ASN1_INTEGER:
|
||||
case SC_ASN1_ENUMERATED:
|
||||
if (parm != NULL) {
|
||||
r = sc_asn1_decode_integer(obj, objlen, (int *) entry->parm);
|
||||
r = sc_asn1_decode_integer(obj, objlen, (int *) entry->parm, 1);
|
||||
sc_debug(ctx, SC_LOG_DEBUG_ASN1, "%*.*sdecoding '%s' returned %d\n", depth, depth, "",
|
||||
entry->name, *((int *) entry->parm));
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ int sc_asn1_decode_bit_string(const u8 * inbuf, size_t inlen,
|
|||
/* non-inverting version */
|
||||
int sc_asn1_decode_bit_string_ni(const u8 * inbuf, size_t inlen,
|
||||
void *outbuf, size_t outlen);
|
||||
int sc_asn1_decode_integer(const u8 * inbuf, size_t inlen, int *out);
|
||||
int sc_asn1_decode_integer(const u8 * inbuf, size_t inlen, int *out, int strict);
|
||||
int sc_asn1_decode_object_id(const u8 * inbuf, size_t inlen,
|
||||
struct sc_object_id *id);
|
||||
int sc_asn1_encode_object_id(u8 **buf, size_t *buflen,
|
||||
|
|
|
@ -358,7 +358,7 @@ iso7816_process_fci(struct sc_card *card, struct sc_file *file,
|
|||
/* fall through */
|
||||
case 0x80:
|
||||
/* determine the file size */
|
||||
if (sc_asn1_decode_integer(p, length, &size) == 0 && size >= 0) {
|
||||
if (sc_asn1_decode_integer(p, length, &size, 0) == 0 && size >= 0) {
|
||||
file->size = size;
|
||||
sc_log(ctx, " bytes in file: %"SC_FORMAT_LEN_SIZE_T"u",
|
||||
file->size);
|
||||
|
|
|
@ -177,8 +177,8 @@ static void torture_integer(void **state)
|
|||
u8 padded_zero[] = {0x00, 0x00};
|
||||
u8 zero[] = {0x00};
|
||||
u8 one[] = {0x01};
|
||||
u8 padded_one[] = {0x00, 0x01};
|
||||
u8 minus_one[] = {0xFF};
|
||||
u8 padded_one[] = {0x00, 0x01};
|
||||
u8 padded_minus_one[] = {0xFF, 0xFF};
|
||||
u8 padded_127[] = {0x00, 0x7F};
|
||||
u8 padded_128[] = {0x00, 0x80};
|
||||
|
@ -192,22 +192,34 @@ static void torture_integer(void **state)
|
|||
size_t buflen = 0;
|
||||
int rv = 0;
|
||||
|
||||
rv = sc_asn1_decode_integer(null, sizeof(null), &value);
|
||||
rv = sc_asn1_decode_integer(null, sizeof(null), &value, 1);
|
||||
assert_int_equal(rv, SC_ERROR_INVALID_ASN1_OBJECT);
|
||||
|
||||
rv = sc_asn1_decode_integer(padded_zero, sizeof(padded_zero), &value);
|
||||
rv = sc_asn1_decode_integer(padded_zero, sizeof(padded_zero), &value, 1);
|
||||
assert_int_equal(rv, SC_ERROR_INVALID_ASN1_OBJECT);
|
||||
|
||||
rv = sc_asn1_decode_integer(padded_one, sizeof(padded_one), &value);
|
||||
rv = sc_asn1_decode_integer(padded_one, sizeof(padded_one), &value, 1);
|
||||
assert_int_equal(rv, SC_ERROR_INVALID_ASN1_OBJECT);
|
||||
/* but we can parse them without the strict checking */
|
||||
rv = sc_asn1_decode_integer(padded_one, sizeof(padded_one), &value, 0);
|
||||
assert_int_equal(rv, SC_SUCCESS);
|
||||
assert_int_equal(value, 1);
|
||||
|
||||
rv = sc_asn1_decode_integer(padded_minus_one, sizeof(padded_minus_one), &value);
|
||||
rv = sc_asn1_decode_integer(padded_minus_one, sizeof(padded_minus_one), &value, 1);
|
||||
assert_int_equal(rv, SC_ERROR_INVALID_ASN1_OBJECT);
|
||||
/* but we can parse them without the strict checking */
|
||||
rv = sc_asn1_decode_integer(padded_minus_one, sizeof(padded_minus_one), &value, 0);
|
||||
assert_int_equal(rv, SC_SUCCESS);
|
||||
assert_int_equal(value, -1);
|
||||
|
||||
rv = sc_asn1_decode_integer(padded_127, sizeof(padded_127), &value);
|
||||
rv = sc_asn1_decode_integer(padded_127, sizeof(padded_127), &value, 1);
|
||||
assert_int_equal(rv, SC_ERROR_INVALID_ASN1_OBJECT);
|
||||
/* but we can parse them without the strict checking */
|
||||
rv = sc_asn1_decode_integer(padded_127, sizeof(padded_127), &value, 0);
|
||||
assert_int_equal(rv, SC_SUCCESS);
|
||||
assert_int_equal(value, 127);
|
||||
|
||||
rv = sc_asn1_decode_integer(padded_128, sizeof(padded_128), &value);
|
||||
rv = sc_asn1_decode_integer(padded_128, sizeof(padded_128), &value, 1);
|
||||
assert_int_equal(rv, SC_SUCCESS);
|
||||
assert_int_equal(value, 128);
|
||||
rv = asn1_encode_integer(value, &buf, &buflen);
|
||||
|
@ -216,7 +228,7 @@ static void torture_integer(void **state)
|
|||
assert_memory_equal(buf, padded_128, buflen);
|
||||
free(buf);
|
||||
|
||||
rv = sc_asn1_decode_integer(zero, sizeof(zero), &value);
|
||||
rv = sc_asn1_decode_integer(zero, sizeof(zero), &value, 1);
|
||||
assert_int_equal(rv, SC_SUCCESS);
|
||||
assert_int_equal(value, 0);
|
||||
rv = asn1_encode_integer(value, &buf, &buflen);
|
||||
|
@ -225,7 +237,7 @@ static void torture_integer(void **state)
|
|||
assert_memory_equal(buf, zero, buflen);
|
||||
free(buf);
|
||||
|
||||
rv = sc_asn1_decode_integer(one, sizeof(one), &value);
|
||||
rv = sc_asn1_decode_integer(one, sizeof(one), &value, 1);
|
||||
assert_int_equal(rv, SC_SUCCESS);
|
||||
assert_int_equal(value, 1);
|
||||
rv = asn1_encode_integer(value, &buf, &buflen);
|
||||
|
@ -234,7 +246,7 @@ static void torture_integer(void **state)
|
|||
assert_memory_equal(buf, one, buflen);
|
||||
free(buf);
|
||||
|
||||
rv = sc_asn1_decode_integer(minus_one, sizeof(minus_one), &value);
|
||||
rv = sc_asn1_decode_integer(minus_one, sizeof(minus_one), &value, 1);
|
||||
assert_int_equal(rv, SC_SUCCESS);
|
||||
assert_int_equal(value, -1);
|
||||
rv = asn1_encode_integer(value, &buf, &buflen);
|
||||
|
@ -243,7 +255,7 @@ static void torture_integer(void **state)
|
|||
assert_memory_equal(buf, minus_one, buflen);
|
||||
free(buf);
|
||||
|
||||
rv = sc_asn1_decode_integer(max2, sizeof(max2), &value);
|
||||
rv = sc_asn1_decode_integer(max2, sizeof(max2), &value, 1);
|
||||
assert_int_equal(rv, SC_SUCCESS);
|
||||
assert_int_equal(value, 32767);
|
||||
rv = asn1_encode_integer(value, &buf, &buflen);
|
||||
|
@ -252,7 +264,7 @@ static void torture_integer(void **state)
|
|||
assert_memory_equal(buf, max2, buflen);
|
||||
free(buf);
|
||||
|
||||
rv = sc_asn1_decode_integer(min2, sizeof(min2), &value);
|
||||
rv = sc_asn1_decode_integer(min2, sizeof(min2), &value, 1);
|
||||
assert_int_equal(rv, SC_SUCCESS);
|
||||
assert_int_equal(value, -32768);
|
||||
rv = asn1_encode_integer(value, &buf, &buflen);
|
||||
|
@ -262,7 +274,7 @@ static void torture_integer(void **state)
|
|||
free(buf);
|
||||
|
||||
if (sizeof(int) == 4) {
|
||||
rv = sc_asn1_decode_integer(max4, sizeof(max4), &value);
|
||||
rv = sc_asn1_decode_integer(max4, sizeof(max4), &value, 1);
|
||||
assert_int_equal(rv, SC_SUCCESS);
|
||||
assert_int_equal(value, 2147483647);
|
||||
rv = asn1_encode_integer(value, &buf, &buflen);
|
||||
|
@ -271,7 +283,7 @@ static void torture_integer(void **state)
|
|||
assert_memory_equal(buf, max4, buflen);
|
||||
free(buf);
|
||||
|
||||
rv = sc_asn1_decode_integer(min4, sizeof(min4), &value);
|
||||
rv = sc_asn1_decode_integer(min4, sizeof(min4), &value, 1);
|
||||
assert_int_equal(rv, SC_SUCCESS);
|
||||
assert_int_equal(value, -2147483648);
|
||||
rv = asn1_encode_integer(value, &buf, &buflen);
|
||||
|
@ -280,14 +292,14 @@ static void torture_integer(void **state)
|
|||
assert_memory_equal(buf, min4, buflen);
|
||||
free(buf);
|
||||
|
||||
rv = sc_asn1_decode_integer(over, sizeof(over), &value);
|
||||
rv = sc_asn1_decode_integer(over, sizeof(over), &value, 1);
|
||||
assert_int_equal(rv, SC_ERROR_NOT_SUPPORTED);
|
||||
} else {
|
||||
/* On more esoteric architectures, we can have different size of int */
|
||||
rv = sc_asn1_decode_integer(max4, sizeof(max4), &value);
|
||||
rv = sc_asn1_decode_integer(max4, sizeof(max4), &value, 1);
|
||||
assert_int_equal(rv, SC_ERROR_NOT_SUPPORTED);
|
||||
|
||||
rv = sc_asn1_decode_integer(min4, sizeof(min4), &value);
|
||||
rv = sc_asn1_decode_integer(min4, sizeof(min4), &value, 1);
|
||||
assert_int_equal(rv, SC_ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
}
|
||||
|
@ -308,7 +320,7 @@ static void torture_negative_int(void **state)
|
|||
int value;
|
||||
int rv = 0;
|
||||
|
||||
rv = sc_asn1_decode_integer(data1, sizeof(data1), &value);
|
||||
rv = sc_asn1_decode_integer(data1, sizeof(data1), &value, 1);
|
||||
assert_int_equal(rv, SC_SUCCESS);
|
||||
assert_int_equal(value, -224);
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ soc_info(sc_context_t *ctx, sc_card_t *card)
|
|||
&& cla == SC_ASN1_TAG_UNIVERSAL && tag == SC_ASN1_TAG_INTEGER) {
|
||||
int applet_count = 0;
|
||||
/* number of applets */
|
||||
if (SC_SUCCESS == sc_asn1_decode_integer(p, length, &applet_count)) {
|
||||
if (SC_SUCCESS == sc_asn1_decode_integer(p, length, &applet_count, 0)) {
|
||||
printf("SoCManager knows %d applet%s%s\n", applet_count,
|
||||
applet_count == 1 ? "" : "s", applet_count == 0 ? "" : ":");
|
||||
/* AID of client applet #x */
|
||||
|
|
Loading…
Reference in New Issue