Skip to content

Commit a32f612

Browse files
committed
Removed internal caching for current EF/DF
This fixes concurrent access to the card from different threads or processes at the cost of potentially causing more card interactions than necessary. Since the card driver for IAS/ECC uses the cached path additionally for managing the ACLs in SM context, this state tracking was moved to a card driver private scope.
1 parent e6ca5f8 commit a32f612

15 files changed

+104
-822
lines changed

src/libopensc/apdu.c

-1
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,6 @@ int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu)
636636
}
637637

638638
if (r == SC_ERROR_CARD_RESET || r == SC_ERROR_READER_REATTACHED) {
639-
sc_invalidate_cache(card);
640639
/* give card driver a chance to react on resets */
641640
if (card->ops->card_reader_lock_obtained)
642641
card->ops->card_reader_lock_obtained(card, 1);

src/libopensc/card-atrust-acos.c

+12-118
Original file line numberDiff line numberDiff line change
@@ -255,11 +255,6 @@ static int atrust_acos_select_aid(struct sc_card *card,
255255
if (!(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) && apdu.sw1 != 0x61)
256256
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
257257

258-
/* update cache */
259-
card->cache.current_path.type = SC_PATH_TYPE_DF_NAME;
260-
card->cache.current_path.len = len;
261-
memcpy(card->cache.current_path.value, aid, len);
262-
263258
if (file_out) {
264259
sc_file_t *file = sc_file_new();
265260
if (!file)
@@ -331,26 +326,11 @@ static int atrust_acos_select_fid(struct sc_card *card,
331326
if (apdu.sw1 != 0x61 && (apdu.sw1 != 0x90 || apdu.sw2 != 0x00))
332327
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
333328

334-
/* update cache */
335-
if (bIsDF) {
336-
card->cache.current_path.type = SC_PATH_TYPE_PATH;
337-
card->cache.current_path.value[0] = 0x3f;
338-
card->cache.current_path.value[1] = 0x00;
339-
if (id_hi == 0x3f && id_lo == 0x00)
340-
card->cache.current_path.len = 2;
341-
else {
342-
card->cache.current_path.len = 4;
343-
card->cache.current_path.value[2] = id_hi;
344-
card->cache.current_path.value[3] = id_lo;
345-
}
346-
}
347-
348329
if (file_out) {
349330
sc_file_t *file = sc_file_new();
350331
if (!file)
351332
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
352-
file->id = (id_hi << 8) + id_lo;
353-
file->path = card->cache.current_path;
333+
file->id = (id_hi << 8) + id_lo;
354334

355335
if (bIsDF) {
356336
/* we have a DF */
@@ -385,48 +365,22 @@ static int atrust_acos_select_file(struct sc_card *card,
385365
u8 pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf;
386366
int r;
387367
size_t i, pathlen;
388-
char pbuf[SC_MAX_PATH_STRING_SIZE];
389-
390-
391-
r = sc_path_print(pbuf, sizeof(pbuf), &card->cache.current_path);
392-
if (r != SC_SUCCESS)
393-
pbuf[0] = '\0';
394-
395-
sc_log(card->ctx,
396-
"current path (%s, %s): %s (len: %"SC_FORMAT_LEN_SIZE_T"u)\n",
397-
card->cache.current_path.type == SC_PATH_TYPE_DF_NAME ?
398-
"aid" : "path",
399-
card->cache.valid ? "valid" : "invalid", pbuf,
400-
card->cache.current_path.len);
401368

402369
memcpy(path, in_path->value, in_path->len);
403370
pathlen = in_path->len;
404371

405-
if (in_path->type == SC_PATH_TYPE_FILE_ID)
406-
{ /* SELECT EF/DF with ID */
372+
if (in_path->type == SC_PATH_TYPE_FILE_ID) {
373+
/* SELECT EF/DF with ID */
407374
/* Select with 2byte File-ID */
408375
if (pathlen != 2)
409376
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_INVALID_ARGUMENTS);
410377
return atrust_acos_select_fid(card, path[0], path[1], file_out);
411-
}
412-
else if (in_path->type == SC_PATH_TYPE_DF_NAME)
413-
{ /* SELECT DF with AID */
378+
} else if (in_path->type == SC_PATH_TYPE_DF_NAME) {
379+
/* SELECT DF with AID */
414380
/* Select with 1-16byte Application-ID */
415-
if (card->cache.valid
416-
&& card->cache.current_path.type == SC_PATH_TYPE_DF_NAME
417-
&& card->cache.current_path.len == pathlen
418-
&& memcmp(card->cache.current_path.value, pathbuf, pathlen) == 0 )
419-
{
420-
sc_log(card->ctx, "cache hit\n");
421-
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
422-
}
423-
else
424-
return atrust_acos_select_aid(card, pathbuf, pathlen, file_out);
425-
}
426-
else if (in_path->type == SC_PATH_TYPE_PATH)
427-
{
381+
return atrust_acos_select_aid(card, pathbuf, pathlen, file_out);
382+
} else if (in_path->type == SC_PATH_TYPE_PATH) {
428383
u8 n_pathbuf[SC_MAX_PATH_SIZE];
429-
size_t bMatch = 0;
430384

431385
/* Select with path (sequence of File-IDs) */
432386
/* ACOS only supports one
@@ -450,72 +404,12 @@ static int atrust_acos_select_file(struct sc_card *card,
450404
pathlen += 2;
451405
}
452406

453-
/* check current working directory */
454-
if (card->cache.valid
455-
&& card->cache.current_path.type == SC_PATH_TYPE_PATH
456-
&& card->cache.current_path.len >= 2
457-
&& card->cache.current_path.len <= pathlen )
458-
{
459-
for (i=0; i < card->cache.current_path.len; i+=2)
460-
if (card->cache.current_path.value[i] == path[i]
461-
&& card->cache.current_path.value[i+1] == path[i+1] )
462-
bMatch += 2;
407+
for (i = 0; i < pathlen - 2; i += 2) {
408+
r = atrust_acos_select_fid(card, path[i], path[i + 1], NULL);
409+
LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed");
463410
}
464-
465-
if (card->cache.valid && bMatch > 2) {
466-
if ( pathlen - bMatch == 2 )
467-
/* we are in the right directory */
468-
return atrust_acos_select_fid(card, path[bMatch], path[bMatch+1], file_out);
469-
else if ( pathlen - bMatch > 2 )
470-
{
471-
/* two more steps to go */
472-
sc_path_t new_path;
473-
474-
/* first step: change directory */
475-
r = atrust_acos_select_fid(card, path[bMatch], path[bMatch+1], NULL);
476-
LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed");
477-
478-
memset(&new_path, 0, sizeof(sc_path_t));
479-
new_path.type = SC_PATH_TYPE_PATH;
480-
new_path.len = pathlen - bMatch-2;
481-
memcpy(new_path.value, &(path[bMatch+2]), new_path.len);
482-
/* final step: select file */
483-
return atrust_acos_select_file(card, &new_path, file_out);
484-
}
485-
else /* if (bMatch - pathlen == 0) */
486-
{
487-
/* done: we are already in the
488-
* requested directory */
489-
sc_log(card->ctx, "cache hit\n");
490-
/* copy file info (if necessary) */
491-
if (file_out) {
492-
sc_file_t *file = sc_file_new();
493-
if (!file)
494-
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
495-
file->id = (path[pathlen-2] << 8) +
496-
path[pathlen-1];
497-
file->path = card->cache.current_path;
498-
file->type = SC_FILE_TYPE_DF;
499-
file->ef_structure = SC_FILE_EF_UNKNOWN;
500-
file->size = 0;
501-
file->namelen = 0;
502-
file->magic = SC_FILE_MAGIC;
503-
*file_out = file;
504-
}
505-
/* nothing left to do */
506-
return SC_SUCCESS;
507-
}
508-
} else {
509-
/* no usable cache */
510-
for ( i=0; i<pathlen-2; i+=2 )
511-
{
512-
r = atrust_acos_select_fid(card, path[i], path[i+1], NULL);
513-
LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed");
514-
}
515-
return atrust_acos_select_fid(card, path[pathlen-2], path[pathlen-1], file_out);
516-
}
517-
}
518-
else
411+
return atrust_acos_select_fid(card, path[pathlen - 2], path[pathlen - 1], file_out);
412+
} else
519413
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
520414
}
521415

0 commit comments

Comments
 (0)