Fix importing data with TLV length > 0x7f.

Should fix #3.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2022-11-29 20:21:11 +01:00
parent 2c5b67597e
commit 23824afc1f

View File

@@ -1563,6 +1563,18 @@ static int cmd_mse() {
return SW_OK(); return SW_OK();
} }
size_t tag_len(uint8_t **data) {
size_t len = *(*data)++;
if (len == 0x82) {
len = *(*data)++ << 8;
len |= *(*data)++;
}
else if (len == 0x81) {
len = *(*data)++;
}
return len;
}
static int cmd_import_data() { static int cmd_import_data() {
file_t *ef = NULL; file_t *ef = NULL;
uint16_t fid = 0x0; uint16_t fid = 0x0;
@@ -1570,39 +1582,44 @@ static int cmd_import_data() {
return SW_WRONG_P1P2(); return SW_WRONG_P1P2();
if (apdu.nc < 5) if (apdu.nc < 5)
return SW_WRONG_LENGTH(); return SW_WRONG_LENGTH();
if (apdu.data[0] != 0x4D || (apdu.data[2] != 0xB6 && apdu.data[2] != 0xB8 && apdu.data[2] != 0xA4)) uint8_t *start = apdu.data;
if (*start++ != 0x4D)
return SW_WRONG_DATA(); return SW_WRONG_DATA();
if (apdu.data[2] == 0xB6) size_t tgl =tag_len(&start);
if (*start != 0xB6 && *start != 0xB8 && *start != 0xA4)
return SW_WRONG_DATA();
if (*start == 0xB6)
fid = EF_PK_SIG; fid = EF_PK_SIG;
else if (apdu.data[2] != 0xB8) else if (*start == 0xB8)
fid = EF_PK_DEC; fid = EF_PK_DEC;
else if (apdu.data[2] != 0xA4) else if (*start == 0xA4)
fid = EF_PK_AUT; fid = EF_PK_AUT;
else else
return SW_WRONG_DATA(); return SW_WRONG_DATA();
start++;
if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF))) if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF)))
return SW_REFERENCE_NOT_FOUND(); return SW_REFERENCE_NOT_FOUND();
if (!authenticate_action(ef, ACL_OP_UPDATE_ERASE)) { if (!authenticate_action(ef, ACL_OP_UPDATE_ERASE)) {
return SW_SECURITY_STATUS_NOT_SATISFIED(); return SW_SECURITY_STATUS_NOT_SATISFIED();
} }
start += (*start + 1);
uint8_t *start = apdu.data + 4 + apdu.data[3];
if (*start++ != 0x7F || *start++ != 0x48) if (*start++ != 0x7F || *start++ != 0x48)
return SW_WRONG_DATA(); return SW_WRONG_DATA();
uint8_t tag_len = *start++, *end = start+tag_len, len[9] = {0}, *p[9] = {NULL}; tgl = tag_len(&start);
uint8_t *end = start + tgl, len[9] = {0}, *p[9] = {0};
while (start < end) { while (start < end) {
uint8_t tag = *start++; uint8_t tag = *start++;
if ((tag >= 0x91 && tag <= 0x97) || tag == 0x99) { if ((tag >= 0x91 && tag <= 0x97) || tag == 0x99) {
len[tag-0x91] = *start++; len[tag-0x91] = tag_len(&start);
} }
else else
return SW_WRONG_DATA(); return SW_WRONG_DATA();
} }
if (*start++ != 0x5F || *start++ != 0x48) if (*start++ != 0x5F || *start++ != 0x48)
return SW_WRONG_DATA(); return SW_WRONG_DATA();
tag_len = *start++; tgl = tag_len(&start);
end = start+tag_len; end = start+tgl;
for (int t = 0; start < end; t++) { for (int t = 0; start < end && t < 9; t++) {
if (len[t] > 0) { if (len[t] > 0) {
p[t] = start; p[t] = start;
start += len[t]; start += len[t];