pkcs11: fixed state tracking

- when listing the slots, we don't have a hotplug slot anymore with
slot->reader == NULL. Instead, we're now using this state for any left
over slots when a reader is removed. So we don't need to include this in
the slot list

- when listing the slots, we need to remember which slots the
application has seen already, to not shrink the list of slots (which is
allowed in PKCS#11 v2.2, but NSS can't handle this)
This commit is contained in:
Frank Morgner 2020-03-04 16:43:51 +01:00
parent 2a6bf1e577
commit dba0f56722
3 changed files with 15 additions and 9 deletions

View File

@ -474,10 +474,11 @@ CK_RV C_GetSlotList(CK_BBOOL tokenPresent, /* only slots with token prese
* - any slot with token;
* - any slot that has already been seen;
*/
if ((!tokenPresent && !slot->reader)
|| (!tokenPresent && slot->reader != prev_reader)
|| (slot->slot_info.flags & CKF_TOKEN_PRESENT)) {
if ((!tokenPresent && slot->reader != prev_reader)
|| (slot->slot_info.flags & CKF_TOKEN_PRESENT)
|| (slot->flags & SC_PKCS11_SLOT_FLAG_SEEN)) {
found[numMatches++] = slot->id;
slot->flags |= SC_PKCS11_SLOT_FLAG_SEEN;
}
prev_reader = slot->reader;
}

View File

@ -200,6 +200,11 @@ struct sc_pkcs11_card {
unsigned int nmechanisms;
};
/* If the slot did already show with `C_GetSlotList`, then we need to keep this
* slot alive. PKCS#11 2.30 allows allows adding but not removing slots until
* the application calls `C_GetSlotList` with `NULL`. This flag tracks the
* visibility to the application */
#define SC_PKCS11_SLOT_FLAG_SEEN 1
struct sc_pkcs11_slot {
CK_SLOT_ID id; /* ID of the slot */

View File

@ -379,7 +379,7 @@ fail:
CK_RV
card_detect_all(void)
{
unsigned int i;
unsigned int i, j;
sc_log(context, "Detect all cards");
/* Detect cards in all initialized readers */
@ -394,8 +394,8 @@ card_detect_all(void)
* https://bugzilla.mozilla.org/show_bug.cgi?id=1613632 */
/* Instead, remove the releation between reader and slot */
for (i = 0; i<list_size(&virtual_slots); i++) {
sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i);
for (j = 0; j<list_size(&virtual_slots); j++) {
sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, j);
if (slot->reader == reader) {
slot->reader = NULL;
}
@ -403,15 +403,15 @@ card_detect_all(void)
} else {
/* Locate a slot related to the reader */
int found = 0;
for (i = 0; i<list_size(&virtual_slots); i++) {
sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i);
for (j = 0; j<list_size(&virtual_slots); j++) {
sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, j);
if (slot->reader == reader) {
found = 1;
break;
}
}
if (!found) {
for (i = 0; i < sc_pkcs11_conf.slots_per_card; i++) {
for (j = 0; j < sc_pkcs11_conf.slots_per_card; j++) {
CK_RV rv = create_slot(reader);
if (rv != CKR_OK)
return rv;