From 84a69ce2ba100be8121218a61a5d549ea3cbdbfb Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Sat, 30 Jul 2016 08:11:42 -0500 Subject: [PATCH] libopensc: introduce 'reader_lock_obtained' card operation Add card_reader_lock_obtained function to sc_card_operations During sc_lock, if card->reader->ops->lock is called, card->ops->card_reader_lock_obtained will be called. If PCSC is being used as the reader driver, this occures just after pcsc_lock has done a SCardBeginTransaction and our process has exclusive control over the card. The card driver can then determine if the state of the card has changed, and take action to get the card into an acceptable state. If card->reader->ops->lock returns SC_ERROR_CARD_RESET, indicating some other process has interefered with the state of the card. was_reset=1 is passed to card->ops->card_reader_lock_obtained. Some examples of actions that could be done by the card driver is to select the AID and reset logged_in. Currently the card driver is not notified. So no default card_reader_lock_obtained is defined in iso7816.c --- src/libopensc/card.c | 7 +++++++ src/libopensc/iso7816.c | 3 ++- src/libopensc/opensc.h | 2 ++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 45ea1b0e..e8b3f3e0 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -389,6 +389,7 @@ int sc_lock(sc_card_t *card) { int r = 0, r2 = 0; int was_reset = 0; + int reader_lock_obtained = 0; if (card == NULL) return SC_ERROR_INVALID_ARGUMENTS; @@ -409,6 +410,8 @@ int sc_lock(sc_card_t *card) break; r = card->reader->ops->lock(card->reader); } + if (r == 0) + reader_lock_obtained = 1; } if (r == 0) card->cache.valid = 1; @@ -429,6 +432,10 @@ int sc_lock(sc_card_t *card) r = r != SC_SUCCESS ? r : r2; } + /* give card driver a chance to do something when reader lock first obtained */ + if (r == 0 && reader_lock_obtained == 1 && card->ops->card_reader_lock_obtained) + r = card->ops->card_reader_lock_obtained(card, was_reset); + LOG_FUNC_RETURN(card->ctx, r); } diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 8f51799c..bbab3b03 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -1224,7 +1224,8 @@ static struct sc_card_operations iso_ops = { iso7816_get_data, NULL, /* put_data */ NULL, /* delete_record */ - NULL /* read_public_key */ + NULL, /* read_public_key */ + NULL /* card_reader_lock_obtained */ }; static struct sc_card_driver iso_driver = { diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 8913cc7c..8af0227c 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -628,6 +628,8 @@ struct sc_card_operations { int (*read_public_key)(struct sc_card *, unsigned, struct sc_path *, unsigned, unsigned, unsigned char **, size_t *); + + int (*card_reader_lock_obtained)(struct sc_card *, int was_reset); }; typedef struct sc_card_driver {