2002-01-16 22:49:03 +00:00
|
|
|
/*
|
2010-01-24 20:45:02 +00:00
|
|
|
* slot.c: reader, smart card and slot related management functions
|
2002-01-16 22:49:03 +00:00
|
|
|
*
|
2006-12-19 21:33:15 +00:00
|
|
|
* Copyright (C) 2002 Timo Teräs <timo.teras@iki.fi>
|
2010-01-24 20:45:02 +00:00
|
|
|
* Copyright (C) 2009 Martin Paljak <martin@paljak.pri.ee>
|
2002-01-16 22:49:03 +00:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
2010-03-04 08:14:36 +00:00
|
|
|
#include "config.h"
|
|
|
|
|
2002-03-21 09:36:38 +00:00
|
|
|
#include <string.h>
|
2010-01-24 20:45:02 +00:00
|
|
|
#include <stdlib.h>
|
2010-03-04 08:14:36 +00:00
|
|
|
|
2002-03-25 12:39:35 +00:00
|
|
|
#include "sc-pkcs11.h"
|
2002-01-16 22:49:03 +00:00
|
|
|
|
|
|
|
static struct sc_pkcs11_framework_ops *frameworks[] = {
|
2005-02-11 20:09:34 +00:00
|
|
|
&framework_pkcs15,
|
2002-06-20 13:16:22 +00:00
|
|
|
#ifdef USE_PKCS15_INIT
|
2002-04-05 15:03:03 +00:00
|
|
|
/* This should be the last framework, because it
|
|
|
|
* will assume the card is blank and try to initialize it */
|
2005-02-11 20:09:34 +00:00
|
|
|
&framework_pkcs15init,
|
2002-06-20 13:16:22 +00:00
|
|
|
#endif
|
2002-01-16 22:49:03 +00:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
static struct sc_pkcs11_slot * reader_get_slot(sc_reader_t *reader)
|
|
|
|
{
|
2010-06-16 13:43:05 +00:00
|
|
|
unsigned int i;
|
2010-01-24 20:45:02 +00:00
|
|
|
|
2010-06-16 13:43:05 +00:00
|
|
|
/* Locate a slot related to the reader */
|
|
|
|
for (i = 0; i<list_size(&virtual_slots); i++) {
|
|
|
|
sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i);
|
2010-01-24 20:45:02 +00:00
|
|
|
if (slot->reader == reader) {
|
2010-06-16 13:43:05 +00:00
|
|
|
return slot;
|
2012-04-02 22:00:56 +00:00
|
|
|
}
|
2010-06-16 13:43:05 +00:00
|
|
|
}
|
2010-01-24 20:45:02 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2003-02-10 14:08:29 +00:00
|
|
|
|
2003-01-13 21:38:43 +00:00
|
|
|
static void init_slot_info(CK_SLOT_INFO_PTR pInfo)
|
2002-01-16 22:49:03 +00:00
|
|
|
{
|
2010-01-24 20:45:02 +00:00
|
|
|
strcpy_bp(pInfo->slotDescription, "Virtual hotplug slot", 64);
|
2006-08-27 18:25:43 +00:00
|
|
|
strcpy_bp(pInfo->manufacturerID, "OpenSC (www.opensc-project.org)", 32);
|
2002-01-16 22:49:03 +00:00
|
|
|
pInfo->flags = CKF_REMOVABLE_DEVICE | CKF_HW_SLOT;
|
|
|
|
pInfo->hardwareVersion.major = 0;
|
|
|
|
pInfo->hardwareVersion.minor = 0;
|
|
|
|
pInfo->firmwareVersion.major = 0;
|
2005-01-19 18:15:43 +00:00
|
|
|
pInfo->firmwareVersion.minor = 0;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
/* simclist helpers to locate interesting objects by ID */
|
|
|
|
static int object_list_seeker(const void *el, const void *key)
|
2002-01-16 22:49:03 +00:00
|
|
|
{
|
2010-06-16 13:43:05 +00:00
|
|
|
const struct sc_pkcs11_object *object = (struct sc_pkcs11_object *)el;
|
2003-02-10 14:08:29 +00:00
|
|
|
|
2010-06-16 13:43:05 +00:00
|
|
|
if ((el == NULL) || (key == NULL))
|
|
|
|
return 0;
|
|
|
|
if (object->handle == *(CK_OBJECT_HANDLE*)key)
|
|
|
|
return 1;
|
|
|
|
return 0;
|
2010-01-24 20:45:02 +00:00
|
|
|
}
|
2012-04-02 22:00:56 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV create_slot(sc_reader_t *reader)
|
|
|
|
{
|
2010-06-16 13:43:05 +00:00
|
|
|
struct sc_pkcs11_slot *slot;
|
2010-01-24 20:45:02 +00:00
|
|
|
|
2010-06-16 13:43:10 +00:00
|
|
|
if (list_size(&virtual_slots) >= sc_pkcs11_conf.max_virtual_slots)
|
|
|
|
return CKR_FUNCTION_FAILED;
|
|
|
|
|
2010-06-16 13:43:05 +00:00
|
|
|
slot = (struct sc_pkcs11_slot *)calloc(1, sizeof(struct sc_pkcs11_slot));
|
2010-01-24 20:45:02 +00:00
|
|
|
if (!slot)
|
|
|
|
return CKR_HOST_MEMORY;
|
2010-06-16 13:43:10 +00:00
|
|
|
|
2010-06-16 13:43:05 +00:00
|
|
|
list_append(&virtual_slots, slot);
|
|
|
|
slot->login_user = -1;
|
2010-01-24 20:45:02 +00:00
|
|
|
slot->id = (CK_SLOT_ID) list_locate(&virtual_slots, slot);
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "Creating slot with id 0x%lx", slot->id);
|
2012-04-02 22:00:56 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
list_init(&slot->objects);
|
|
|
|
list_attributes_seeker(&slot->objects, object_list_seeker);
|
|
|
|
|
|
|
|
init_slot_info(&slot->slot_info);
|
|
|
|
if (reader != NULL) {
|
2010-06-16 13:43:05 +00:00
|
|
|
slot->reader = reader;
|
|
|
|
strcpy_bp(slot->slot_info.slotDescription, reader->name, 64);
|
|
|
|
}
|
|
|
|
return CKR_OK;
|
2010-01-24 20:45:02 +00:00
|
|
|
}
|
2003-02-10 14:08:29 +00:00
|
|
|
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
/* create slots associated with a reader, called whenever a reader is seen. */
|
|
|
|
CK_RV initialize_reader(sc_reader_t *reader)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
CK_RV rv;
|
2003-02-10 14:08:29 +00:00
|
|
|
|
2010-08-15 09:33:18 +00:00
|
|
|
scconf_block *conf_block = NULL;
|
|
|
|
const scconf_list *list = NULL;
|
|
|
|
|
|
|
|
conf_block = sc_get_conf_block(context, "pkcs11", NULL, 1);
|
|
|
|
if (conf_block != NULL) {
|
|
|
|
list = scconf_find_list(conf_block, "ignored_readers");
|
|
|
|
while (list != NULL) {
|
2010-08-16 08:59:14 +00:00
|
|
|
if (strstr(reader->name, list->data) != NULL) {
|
2010-08-15 09:33:18 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "Ignoring reader \'%s\' because of \'%s\'\n", reader->name, list->data);
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
list = list->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
for (i = 0; i < sc_pkcs11_conf.slots_per_card; i++) {
|
2010-06-16 13:43:05 +00:00
|
|
|
rv = create_slot(reader);
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
2010-01-24 20:45:02 +00:00
|
|
|
}
|
2003-02-10 14:08:29 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
if (sc_detect_card_presence(reader)) {
|
|
|
|
card_detect(reader);
|
2008-10-09 12:59:02 +00:00
|
|
|
}
|
|
|
|
|
2005-01-19 18:15:43 +00:00
|
|
|
return CKR_OK;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
|
|
|
|
CK_RV card_removed(sc_reader_t * reader)
|
2002-01-16 22:49:03 +00:00
|
|
|
{
|
2010-06-16 13:43:05 +00:00
|
|
|
unsigned int i;
|
|
|
|
struct sc_pkcs11_card *card = NULL;
|
|
|
|
/* Mark all slots as "token not present" */
|
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "%s: card removed", reader->name);
|
2010-01-24 20:45:02 +00:00
|
|
|
|
|
|
|
|
2010-06-16 13:43:05 +00:00
|
|
|
for (i=0; i < list_size(&virtual_slots); i++) {
|
2010-01-24 20:45:02 +00:00
|
|
|
sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i);
|
|
|
|
if (slot->reader == reader) {
|
2010-06-16 13:43:05 +00:00
|
|
|
/* Save the "card" object */
|
|
|
|
if (slot->card)
|
|
|
|
card = slot->card;
|
|
|
|
slot_token_removed(slot->id);
|
2010-01-24 20:45:02 +00:00
|
|
|
}
|
|
|
|
}
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
if (card) {
|
2010-06-16 13:43:05 +00:00
|
|
|
card->framework->unbind(card);
|
|
|
|
sc_disconnect_card(card->card);
|
2010-05-30 07:56:34 +00:00
|
|
|
/* FIXME: free mechanisms
|
|
|
|
* spaces allocated by the
|
|
|
|
* sc_pkcs11_register_sign_and_hash_mechanism
|
|
|
|
* and sc_pkcs11_new_fw_mechanism.
|
|
|
|
* but see sc_pkcs11_register_generic_mechanisms
|
|
|
|
for (i=0; i < card->nmechanisms; ++i) {
|
|
|
|
// if 'mech_data' is a pointer earlier returned by the ?alloc
|
|
|
|
free(card->mechanisms[i]->mech_data);
|
|
|
|
// if 'mechanisms[i]' is a pointer earlier returned by the ?alloc
|
|
|
|
free(card->mechanisms[i]);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
free(card->mechanisms);
|
2010-06-16 13:43:05 +00:00
|
|
|
free(card);
|
|
|
|
}
|
2012-04-02 22:00:56 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
return CKR_OK;
|
|
|
|
}
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2003-02-10 14:08:29 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV card_detect(sc_reader_t *reader)
|
|
|
|
{
|
2010-03-28 20:09:19 +00:00
|
|
|
struct sc_pkcs11_card *p11card = NULL;
|
2010-01-24 20:45:02 +00:00
|
|
|
int rc, rv;
|
|
|
|
unsigned int i;
|
2003-02-10 14:08:29 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = CKR_OK;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "%s: Detecting smart card\n", reader->name);
|
2010-01-24 20:45:02 +00:00
|
|
|
/* Check if someone inserted a card */
|
|
|
|
again:rc = sc_detect_card_presence(reader);
|
2003-01-19 17:47:07 +00:00
|
|
|
if (rc < 0) {
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "%s: failed, %s\n", reader->name, sc_strerror(rc));
|
2010-04-21 10:51:13 +00:00
|
|
|
return sc_to_cryptoki_error(rc, NULL);
|
2003-01-19 17:47:07 +00:00
|
|
|
}
|
|
|
|
if (rc == 0) {
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "%s: card absent\n", reader->name);
|
2010-01-24 20:45:02 +00:00
|
|
|
card_removed(reader); /* Release all resources */
|
2003-01-19 17:47:07 +00:00
|
|
|
return CKR_TOKEN_NOT_PRESENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If the card was changed, disconnect the current one */
|
2010-01-24 20:45:02 +00:00
|
|
|
if (rc & SC_READER_CARD_CHANGED) {
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "%s: Card changed\n", reader->name);
|
2003-01-19 17:47:07 +00:00
|
|
|
/* The following should never happen - but if it
|
|
|
|
* does we'll be stuck in an endless loop.
|
2012-04-02 22:00:56 +00:00
|
|
|
* So better be fussy.
|
2003-01-19 17:47:07 +00:00
|
|
|
if (!retry--)
|
2010-01-24 20:45:02 +00:00
|
|
|
return CKR_TOKEN_NOT_PRESENT; */
|
2003-01-19 17:47:07 +00:00
|
|
|
card_removed(reader);
|
|
|
|
goto again;
|
|
|
|
}
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
/* Locate a slot related to the reader */
|
|
|
|
for (i=0; i<list_size(&virtual_slots); i++) {
|
2010-06-16 13:43:05 +00:00
|
|
|
sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i);
|
2010-01-24 20:45:02 +00:00
|
|
|
if (slot->reader == reader) {
|
|
|
|
p11card = slot->card;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-01-19 17:47:07 +00:00
|
|
|
/* Detect the card if it's not known already */
|
2010-01-24 20:45:02 +00:00
|
|
|
if (p11card == NULL) {
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "%s: First seen the card ", reader->name);
|
2010-01-24 20:45:02 +00:00
|
|
|
p11card = (struct sc_pkcs11_card *)calloc(1, sizeof(struct sc_pkcs11_card));
|
|
|
|
if (!p11card)
|
|
|
|
return CKR_HOST_MEMORY;
|
|
|
|
p11card->reader = reader;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (p11card->card == NULL) {
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "%s: Connecting ... ", reader->name);
|
2010-01-24 20:45:02 +00:00
|
|
|
rc = sc_connect_card(reader, &p11card->card);
|
2002-01-16 22:49:03 +00:00
|
|
|
if (rc != SC_SUCCESS)
|
2010-04-21 10:51:13 +00:00
|
|
|
return sc_to_cryptoki_error(rc, NULL);
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Detect the framework */
|
2010-01-24 20:45:02 +00:00
|
|
|
if (p11card->framework == NULL) {
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "%s: Detecting Framework\n", reader->name);
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2002-04-05 15:03:03 +00:00
|
|
|
for (i = 0; frameworks[i]; i++) {
|
2002-08-08 20:53:40 +00:00
|
|
|
if (frameworks[i]->bind == NULL)
|
|
|
|
continue;
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = frameworks[i]->bind(p11card);
|
2002-01-16 22:49:03 +00:00
|
|
|
if (rv == CKR_OK)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (frameworks[i] == NULL)
|
|
|
|
return CKR_TOKEN_NOT_RECOGNIZED;
|
|
|
|
|
|
|
|
/* Initialize framework */
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "%s: Detected framework %d. Creating tokens.\n", reader->name, i);
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = frameworks[i]->create_tokens(p11card);
|
2002-01-16 22:49:03 +00:00
|
|
|
if (rv != CKR_OK)
|
2005-01-19 18:15:43 +00:00
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
p11card->framework = frameworks[i];
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "%s: Detection ended\n", reader->name);
|
2003-01-27 13:43:06 +00:00
|
|
|
return CKR_OK;
|
2003-01-20 09:50:33 +00:00
|
|
|
}
|
|
|
|
|
2010-03-28 20:08:30 +00:00
|
|
|
CK_RV card_detect_all(void) {
|
2010-06-16 13:43:05 +00:00
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
/* 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);
|
|
|
|
if (!reader_get_slot(reader))
|
|
|
|
initialize_reader(reader);
|
|
|
|
card_detect(sc_ctx_get_reader(context, i));
|
|
|
|
}
|
2012-04-02 22:00:56 +00:00
|
|
|
return CKR_OK;
|
2003-02-03 12:20:54 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
/* Allocates an existing slot to a card */
|
|
|
|
CK_RV slot_allocate(struct sc_pkcs11_slot ** slot, struct sc_pkcs11_card * card)
|
2002-01-16 22:49:03 +00:00
|
|
|
{
|
2010-06-16 13:43:05 +00:00
|
|
|
unsigned int i;
|
2010-01-24 20:45:02 +00:00
|
|
|
struct sc_pkcs11_slot *tmp_slot = NULL;
|
|
|
|
|
|
|
|
/* Locate a free slot for this reader */
|
|
|
|
for (i=0; i< list_size(&virtual_slots); i++) {
|
|
|
|
tmp_slot = (struct sc_pkcs11_slot *)list_get_at(&virtual_slots, i);
|
|
|
|
if (tmp_slot->reader == card->reader && tmp_slot->card == NULL)
|
|
|
|
break;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
2011-05-09 17:11:13 +00:00
|
|
|
if (!tmp_slot || (i == list_size(&virtual_slots)))
|
2002-12-21 16:45:37 +00:00
|
|
|
return CKR_FUNCTION_FAILED;
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "Allocated slot 0x%lx for card in reader %s", tmp_slot->id,
|
2010-01-24 20:45:02 +00:00
|
|
|
card->reader->name);
|
|
|
|
tmp_slot->card = card;
|
|
|
|
tmp_slot->events = SC_EVENT_CARD_INSERTED;
|
|
|
|
*slot = tmp_slot;
|
|
|
|
return CKR_OK;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV slot_get_slot(CK_SLOT_ID id, struct sc_pkcs11_slot ** slot)
|
2002-01-16 22:49:03 +00:00
|
|
|
{
|
|
|
|
if (context == NULL)
|
2005-02-11 20:09:34 +00:00
|
|
|
return CKR_CRYPTOKI_NOT_INITIALIZED;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2010-06-11 07:35:45 +00:00
|
|
|
*slot = list_seek(&virtual_slots, &id); /* FIXME: check for null? */
|
2010-01-24 20:45:02 +00:00
|
|
|
if (!*slot)
|
2002-01-16 22:49:03 +00:00
|
|
|
return CKR_SLOT_ID_INVALID;
|
2005-01-19 18:15:43 +00:00
|
|
|
return CKR_OK;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV slot_get_token(CK_SLOT_ID id, struct sc_pkcs11_slot ** slot)
|
2002-01-16 22:49:03 +00:00
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
rv = slot_get_slot(id, slot);
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
if (!((*slot)->slot_info.flags & CKF_TOKEN_PRESENT)) {
|
2012-04-02 22:00:56 +00:00
|
|
|
if ((*slot)->reader == NULL)
|
2010-06-16 13:43:05 +00:00
|
|
|
return CKR_TOKEN_NOT_PRESENT;
|
|
|
|
rv = card_detect((*slot)->reader);
|
2004-07-09 15:33:35 +00:00
|
|
|
if (rv != CKR_OK)
|
2010-01-24 20:45:02 +00:00
|
|
|
return rv;
|
2004-07-09 15:33:35 +00:00
|
|
|
}
|
2008-10-10 09:39:27 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
if (!((*slot)->slot_info.flags & CKF_TOKEN_PRESENT)) {
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "card detected, but slot not presenting token");
|
2008-10-10 09:39:27 +00:00
|
|
|
return CKR_TOKEN_NOT_PRESENT;
|
|
|
|
}
|
2005-01-19 18:15:43 +00:00
|
|
|
return CKR_OK;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV slot_token_removed(CK_SLOT_ID id)
|
2002-01-16 22:49:03 +00:00
|
|
|
{
|
2003-02-03 12:20:54 +00:00
|
|
|
int rv, token_was_present;
|
2005-01-19 18:15:43 +00:00
|
|
|
struct sc_pkcs11_slot *slot;
|
|
|
|
struct sc_pkcs11_object *object;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "slot_token_removed(0x%lx)", id);
|
2003-01-27 13:17:08 +00:00
|
|
|
rv = slot_get_slot(id, &slot);
|
2002-01-16 22:49:03 +00:00
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
|
|
|
|
2003-02-03 12:20:54 +00:00
|
|
|
token_was_present = (slot->slot_info.flags & CKF_TOKEN_PRESENT);
|
|
|
|
|
2005-01-19 18:15:43 +00:00
|
|
|
/* Terminate active sessions */
|
|
|
|
sc_pkcs11_close_all_sessions(id);
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2010-05-30 07:52:14 +00:00
|
|
|
while ((object = list_fetch(&slot->objects))) {
|
2005-01-19 18:15:43 +00:00
|
|
|
if (object->ops->release)
|
2005-01-19 19:52:08 +00:00
|
|
|
object->ops->release(object);
|
2010-05-30 07:52:14 +00:00
|
|
|
}
|
2002-01-16 22:49:03 +00:00
|
|
|
|
|
|
|
/* Release framework stuff */
|
2003-02-10 14:08:29 +00:00
|
|
|
if (slot->card != NULL) {
|
2004-04-21 21:11:06 +00:00
|
|
|
if (slot->fw_data != NULL &&
|
2010-01-24 20:45:02 +00:00
|
|
|
slot->card->framework != NULL && slot->card->framework->release_token != NULL)
|
2003-02-10 14:08:29 +00:00
|
|
|
slot->card->framework->release_token(slot->card, slot->fw_data);
|
|
|
|
}
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
/* Reset relevant slot properties */
|
|
|
|
slot->slot_info.flags &= ~CKF_TOKEN_PRESENT;
|
2002-01-16 22:49:03 +00:00
|
|
|
slot->login_user = -1;
|
2010-01-24 20:45:02 +00:00
|
|
|
slot->card = NULL;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2003-02-03 12:20:54 +00:00
|
|
|
if (token_was_present)
|
|
|
|
slot->events = SC_EVENT_CARD_REMOVED;
|
|
|
|
|
2005-01-19 18:15:43 +00:00
|
|
|
return CKR_OK;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
2003-02-03 12:20:54 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
/* Called from C_WaitForSlotEvent */
|
2003-02-03 12:20:54 +00:00
|
|
|
CK_RV slot_find_changed(CK_SLOT_ID_PTR idp, int mask)
|
|
|
|
{
|
2010-06-16 13:43:05 +00:00
|
|
|
unsigned int i;
|
2010-03-15 12:17:13 +00:00
|
|
|
SC_FUNC_CALLED(context, SC_LOG_DEBUG_NORMAL);
|
2003-02-03 12:20:54 +00:00
|
|
|
|
|
|
|
card_detect_all();
|
2010-06-16 13:43:05 +00:00
|
|
|
for (i=0; i<list_size(&virtual_slots); i++) {
|
2010-01-24 20:45:02 +00:00
|
|
|
sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i);
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "slot 0x%lx token: %d events: 0x%02X",slot->id, (slot->slot_info.flags & CKF_TOKEN_PRESENT), slot->events);
|
2003-02-03 12:32:43 +00:00
|
|
|
if ((slot->events & SC_EVENT_CARD_INSERTED)
|
2010-01-24 20:45:02 +00:00
|
|
|
&& !(slot->slot_info.flags & CKF_TOKEN_PRESENT)) {
|
2010-06-16 13:43:05 +00:00
|
|
|
/* If a token has not been initialized, clear the inserted event */
|
2003-02-03 12:32:43 +00:00
|
|
|
slot->events &= ~SC_EVENT_CARD_INSERTED;
|
2010-06-16 13:43:05 +00:00
|
|
|
}
|
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "mask: 0x%02X events: 0x%02X result: %d", mask, slot->events, (slot->events & mask));
|
2010-08-15 09:33:18 +00:00
|
|
|
|
2003-02-03 12:20:54 +00:00
|
|
|
if (slot->events & mask) {
|
|
|
|
slot->events &= ~mask;
|
2010-01-24 20:45:02 +00:00
|
|
|
*idp = slot->id;
|
2010-03-15 12:17:13 +00:00
|
|
|
SC_FUNC_RETURN(context, SC_LOG_DEBUG_VERBOSE, CKR_OK);
|
2003-02-03 12:20:54 +00:00
|
|
|
}
|
|
|
|
}
|
2010-03-15 12:17:13 +00:00
|
|
|
SC_FUNC_RETURN(context, SC_LOG_DEBUG_VERBOSE, CKR_NO_EVENT);
|
2003-02-03 12:20:54 +00:00
|
|
|
}
|