Skip to content

Commit

Permalink
pkcs11: leverage sc_wait_for_event to avoid unneccesary queries to card
Browse files Browse the repository at this point in the history
card_detect_all() is now used as global entry point even to reader
specific card detection (card_detect() is removed). This enforces
a constant update of reader_states so that no events are silently
dropped. This removes the need for having a timer in C_GetSlotInfo() for
avoiding too many queries. If the reader implementation (i.e.
reader-*.c) does not implement wait_for_event, then all slots will be
queried on request just like it used to be.

fixes OpenSC#3107
  • Loading branch information
frankmorgner committed Apr 24, 2024
1 parent fe2c1c8 commit 7091cff
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 51 deletions.
49 changes: 9 additions & 40 deletions src/pkcs11/pkcs11-global.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ sc_context_t *context = NULL;
struct sc_pkcs11_config sc_pkcs11_conf;
list_t sessions;
list_t virtual_slots;
void *reader_states = NULL;
#if !defined(_WIN32)
pid_t initialized_pid = (pid_t)-1;
#endif
Expand Down Expand Up @@ -432,6 +433,9 @@ CK_RV C_Finalize(CK_VOID_PTR pReserved)
}
list_destroy(&virtual_slots);

sc_wait_for_event(context, 0, NULL, NULL, 0, &reader_states);
reader_states = NULL;

sc_release_context(context);
context = NULL;

Expand Down Expand Up @@ -585,37 +589,9 @@ CK_RV C_GetSlotList(CK_BBOOL tokenPresent, /* only slots with token prese
return rv;
}

static sc_timestamp_t get_current_time(void)
{
#if HAVE_GETTIMEOFDAY
struct timeval tv;
struct timezone tz;
sc_timestamp_t curr;

if (gettimeofday(&tv, &tz) != 0)
return 0;

curr = tv.tv_sec;
curr *= 1000;
curr += tv.tv_usec / 1000;
#else
struct _timeb time_buf;
sc_timestamp_t curr;

_ftime(&time_buf);

curr = time_buf.time;
curr *= 1000;
curr += time_buf.millitm;
#endif

return curr;
}

CK_RV C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
{
struct sc_pkcs11_slot *slot = NULL;
sc_timestamp_t now;
const char *name;
CK_RV rv;

Expand Down Expand Up @@ -644,18 +620,11 @@ CK_RV C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
if (slot->reader == NULL) {
rv = CKR_TOKEN_NOT_PRESENT;
} else {
now = get_current_time();
if (now >= slot->slot_state_expires || now == 0) {
/* Update slot status */
rv = card_detect(slot->reader);
sc_log(context, "C_GetSlotInfo() card detect rv 0x%lX", rv);

if (rv == CKR_TOKEN_NOT_RECOGNIZED || rv == CKR_OK)
slot->slot_info.flags |= CKF_TOKEN_PRESENT;

/* Don't ask again within the next second */
slot->slot_state_expires = now + 1000;
}
/* Update slot status */
card_detect_all();

if (slot->p11card && slot->p11card->card)
slot->slot_info.flags |= CKF_TOKEN_PRESENT;
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/pkcs11/sc-pkcs11.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,6 @@ struct sc_pkcs11_slot {
void *fw_data; /* Framework specific data */ /* TODO: get know how it used */
list_t objects; /* Objects in this slot */
unsigned int nsessions; /* Number of sessions using this slot */
sc_timestamp_t slot_state_expires;

int fw_data_idx; /* Index of framework data */
struct sc_app_info *app_info; /* Application associated to slot */
Expand Down Expand Up @@ -393,6 +392,7 @@ extern struct sc_pkcs11_config sc_pkcs11_conf;
extern list_t sessions;
extern list_t virtual_slots;
extern list_t cards;
extern void *reader_states;

/* Framework definitions */
extern struct sc_pkcs11_framework_ops framework_pkcs15;
Expand All @@ -412,7 +412,6 @@ CK_RV card_removed(sc_reader_t *reader);
CK_RV card_detect_all(void);
CK_RV create_slot(sc_reader_t *reader);
void init_slot_info(CK_SLOT_INFO_PTR pInfo, sc_reader_t *reader);
CK_RV card_detect(sc_reader_t *reader);
CK_RV slot_get_slot(CK_SLOT_ID id, struct sc_pkcs11_slot **);
CK_RV slot_get_token(CK_SLOT_ID id, struct sc_pkcs11_slot **);
CK_RV slot_token_removed(CK_SLOT_ID id);
Expand Down
20 changes: 11 additions & 9 deletions src/pkcs11/slot.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,8 +389,18 @@ CK_RV
card_detect_all(void)
{
unsigned int i, j;
const unsigned int event_mask = SC_EVENT_CARD_EVENTS|SC_EVENT_READER_EVENTS;
unsigned int events = 0;
sc_reader_t *event_reader = NULL;
int r;

sc_log(context, "Detect all cards");
r = sc_wait_for_event(context, event_mask, &event_reader, &events, 1, &reader_states);
if ((SC_SUCCESS == r && events == 0) || SC_ERROR_EVENT_TIMEOUT == r) {
sc_log(context, "No state change since last call, skipping card detection");
return CKR_OK;
}

/* Detect cards in all initialized readers */
for (i=0; i< sc_ctx_get_reader_count(context); i++) {
sc_reader_t *reader = sc_ctx_get_reader(context, i);
Expand Down Expand Up @@ -474,15 +484,7 @@ CK_RV slot_get_token(CK_SLOT_ID id, struct sc_pkcs11_slot ** slot)
if (rv != CKR_OK)
return rv;

if (!((*slot)->slot_info.flags & CKF_TOKEN_PRESENT)) {
if ((*slot)->reader == NULL)
return CKR_TOKEN_NOT_PRESENT;
sc_log(context, "Slot(id=0x%lX): get token: now detect card", id);
rv = card_detect((*slot)->reader);
if (rv != CKR_OK)
return rv;
}

card_detect_all();
if (!((*slot)->slot_info.flags & CKF_TOKEN_PRESENT)) {
sc_log(context, "card detected, but slot not presenting token");
return CKR_TOKEN_NOT_PRESENT;
Expand Down

0 comments on commit 7091cff

Please sign in to comment.