From 6843ab41904397dd2905735bfc8b6f828f0faf7a Mon Sep 17 00:00:00 2001 From: Mardalemer <35370670+Mardalemer@users.noreply.github.com> Date: Tue, 13 Feb 2018 15:24:28 +0300 Subject: [PATCH] pkcs15init: Fix rutokenS FCP parsing (#1259) RutokenS returns data with little endian byte order, due to this fact token wouldn't work with standard function. So function for parsing fcp from little endian data was inplemented. --- src/libopensc/card-rutoken.c | 39 ++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/src/libopensc/card-rutoken.c b/src/libopensc/card-rutoken.c index 6c710703..c1331ee9 100644 --- a/src/libopensc/card-rutoken.c +++ b/src/libopensc/card-rutoken.c @@ -358,7 +358,6 @@ static int rutoken_select_file(sc_card_t *card, u8 buf[SC_MAX_APDU_BUFFER_SIZE], pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf; sc_file_t *file = NULL; size_t pathlen; - u8 t0, t1; int ret; assert(card && card->ctx); @@ -428,15 +427,6 @@ static int rutoken_select_file(sc_card_t *card, if (apdu.resplen > 1 && apdu.resplen >= (size_t)apdu.resp[1] + 2) { ret = card->ops->process_fci(card, file, apdu.resp+2, apdu.resp[1]); - if (ret == SC_SUCCESS) - { - t0 = file->id & 0xFF; - t1 = (file->id >> 8) & 0xFF; - file->id = (t0 << 8) | t1; - t0 = file->size & 0xFF; - t1 = (file->size >> 8) & 0xFF; - file->size = (t0 << 8) | t1; - } } if (file->sec_attr && file->sec_attr_len == sizeof(sc_SecAttrV2_t)) set_acl_from_sec_attr(card, file); @@ -452,6 +442,33 @@ static int rutoken_select_file(sc_card_t *card, SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); } +static int rutoken_process_fci(struct sc_card *card, sc_file_t *file, + const unsigned char *buf, size_t buflen) +{ + size_t taglen; + int ret; + const unsigned char *tag; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + ret = iso_ops->process_fci(card, file, buf, buflen); + if (ret == SC_SUCCESS) + { + /* Rutoken S returns buffers in little-endian. */ + /* Set correct file id. */ + file->id = ((file->id & 0xFF) << 8) | ((file->id >> 8) & 0xFF); + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, " file identifier: 0x%04X", file->id); + /* Determine file size. */ + tag = sc_asn1_find_tag(card->ctx, buf, buflen, 0x80, &taglen); + /* Rutoken S always returns 2 bytes. */ + if (tag != NULL && taglen == 2) + { + file->size = (tag[1] << 8) | tag[0]; + sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, " bytes in file: %"SC_FORMAT_LEN_SIZE_T"u", file->size); + } + } + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, ret); +} + static int rutoken_construct_fci(sc_card_t *card, const sc_file_t *file, u8 *out, size_t *outlen) { @@ -1286,7 +1303,7 @@ static struct sc_card_driver* get_rutoken_driver(void) rutoken_ops.list_files = rutoken_list_files; rutoken_ops.check_sw = rutoken_check_sw; rutoken_ops.card_ctl = rutoken_card_ctl; - /* process_fci */ + rutoken_ops.process_fci = rutoken_process_fci; rutoken_ops.construct_fci = rutoken_construct_fci; rutoken_ops.pin_cmd = NULL;