⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slot.c

📁 读写Smart卡加解密接口的程序
💻 C
字号:
/* * slot.c: Smartcard and slot related management functions * * Copyright (C) 2002  Timo Ter鋝 <timo.teras@iki.fi> * * 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 */#include <string.h>#include "sc-pkcs11.h"static struct sc_pkcs11_framework_ops *frameworks[] = {        &framework_pkcs15,#ifdef USE_PKCS15_INIT	/* This should be the last framework, because it	 * will assume the card is blank and try to initialize it */        &framework_pkcs15init,#endif	NULL};unsigned int first_free_slot = 0;static void init_slot_info(CK_SLOT_INFO_PTR pInfo){	strcpy_bp(pInfo->slotDescription, "Virtual slot", 64);	strcpy_bp(pInfo->manufacturerID, "OpenSC project (www.opensc.org)", 32);	pInfo->flags = CKF_REMOVABLE_DEVICE | CKF_HW_SLOT;	pInfo->hardwareVersion.major = 0;	pInfo->hardwareVersion.minor = 0;	pInfo->firmwareVersion.major = 0;        pInfo->firmwareVersion.minor = 0;}CK_RV card_initialize(int reader){	struct sc_pkcs11_card *card = card_table + reader;	unsigned int avail;	if (reader < 0 || reader >= SC_PKCS11_MAX_READERS)		return CKR_FUNCTION_FAILED;	memset(card, 0, sizeof(struct sc_pkcs11_card));	card->reader = reader;	/* Always allocate a fixed slot range to one reader/card.	 * Some applications get confused if readers pop up in	 * different slots. */	if (sc_pkcs11_conf.num_slots == 0)		avail = SC_PKCS11_DEF_SLOTS_PER_CARD;	else		avail = sc_pkcs11_conf.num_slots;	if (first_free_slot + avail > SC_PKCS11_MAX_VIRTUAL_SLOTS)		avail = SC_PKCS11_MAX_VIRTUAL_SLOTS - first_free_slot;	card->first_slot = first_free_slot;	card->max_slots = avail;	card->num_slots = 0;	first_free_slot += card->max_slots;        return CKR_OK;}CK_RV card_detect(int reader){	struct sc_pkcs11_card *card = &card_table[reader];        int rc, rv, i, retry = 1;        rv = CKR_OK;	sc_debug(context, "%d: Detecting SmartCard\n", reader);	for (i = card->max_slots; i--; ) {		struct sc_pkcs11_slot *slot;		slot = virtual_slots + card->first_slot + i;		strcpy_bp(slot->slot_info.slotDescription,				context->reader[reader]->name, 64);		slot->reader = reader;	}	/* Check if someone inserted a card */again:	rc = sc_detect_card_presence(context->reader[reader], 0);	if (rc < 0) {		sc_debug(context, "Card detection failed for reader %d: %s\n",				reader, sc_strerror(rc));		return sc_to_cryptoki_error(rc, reader);	}	if (rc == 0) {		sc_debug(context, "%d: Card absent\n", reader);		card_removed(reader); /* Release all resources */		return CKR_TOKEN_NOT_PRESENT;	}	/* If the card was changed, disconnect the current one */	if (rc & SC_SLOT_CARD_CHANGED) {		sc_debug(context, "%d: Card changed\n", reader);		/* The following should never happen - but if it		 * does we'll be stuck in an endless loop.		 * So better be fussy. */		if (!retry--)			return CKR_TOKEN_NOT_PRESENT;		card_removed(reader);		goto again;	}	/* Detect the card if it's not known already */	if (card->card == NULL) {		sc_debug(context, "%d: Connecting to SmartCard\n", reader);		rc = sc_connect_card(context->reader[reader], 0, &card->card);		if (rc != SC_SUCCESS)			return sc_to_cryptoki_error(rc, reader);	}	/* Detect the framework */	if (card->framework == NULL) {		sc_debug(context, "%d: Detecting Framework\n", reader);		for (i = 0; frameworks[i]; i++) {			if (frameworks[i]->bind == NULL)				continue;			rv = frameworks[i]->bind(card);			if (rv == CKR_OK)				break;		}		if (frameworks[i] == NULL)			return CKR_TOKEN_NOT_RECOGNIZED;		/* Initialize framework */		sc_debug(context, "%d: Detected framework %d. Creating tokens.\n", reader, i);		rv = frameworks[i]->create_tokens(card);		if (rv != CKR_OK)                        return rv;		card->framework = frameworks[i];	}	sc_debug(context, "%d: Detection ended\n", reader);	return rv;}CK_RV __card_detect_all(int report_events){	int i;	if (context == NULL_PTR)		return CKR_CRYPTOKI_NOT_INITIALIZED;	for (i = 0; i < context->reader_count; i++)		card_detect(i);	if (!report_events) {		CK_SLOT_ID id;		for (id = 0; id < SC_PKCS11_MAX_VIRTUAL_SLOTS; id++)			virtual_slots[id].events = 0;	}	return CKR_OK;}CK_RV card_detect_all(void){	return __card_detect_all(1);}CK_RV card_removed(int reader){	int i;        struct sc_pkcs11_card *card;	sc_debug(context, "%d: SmartCard removed\n", reader);	for (i=0; i<SC_PKCS11_MAX_VIRTUAL_SLOTS; i++) {		if (virtual_slots[i].card &&		    virtual_slots[i].card->reader == reader)                        slot_token_removed(i);	}	/* beware - do not clean the entire sc_pkcs11_card struct;	 * fields such as first_slot and max_slots are initialized	 * _once_ and need to be left untouched across card removal/	 * insertion */	card = &card_table[reader];	if (card->framework)		card->framework->unbind(card);	card->framework = NULL;	card->fw_data = NULL;	if (card->card)		sc_disconnect_card(card->card, 0);        card->card = NULL;        return CKR_OK;}CK_RV slot_initialize(int id, struct sc_pkcs11_slot *slot){	memset(slot, 0, sizeof(*slot));	slot->id = id;	slot->login_user = -1;        init_slot_info(&slot->slot_info);	pool_initialize(&slot->object_pool, POOL_TYPE_OBJECT);        return CKR_OK;}CK_RV slot_allocate(struct sc_pkcs11_slot **slot, struct sc_pkcs11_card *card){	unsigned int i, first, last;	if (card->num_slots >= card->max_slots)		return CKR_FUNCTION_FAILED;	first = card->first_slot;	last  = first + card->max_slots;	for (i = first; i < last; i++) {		if (!virtual_slots[i].card) {			sc_debug(context, "Allocated slot %d\n", i);                        virtual_slots[i].card = card;                        virtual_slots[i].events = SC_EVENT_CARD_INSERTED;			*slot = &virtual_slots[i];			card->num_slots++;			return CKR_OK;		}	}        return CKR_FUNCTION_FAILED;}CK_RV slot_get_slot(int id, struct sc_pkcs11_slot **slot){	if (context == NULL)                return CKR_CRYPTOKI_NOT_INITIALIZED;	if (id < 0 || id >= SC_PKCS11_MAX_VIRTUAL_SLOTS)		return CKR_SLOT_ID_INVALID;        *slot = &virtual_slots[id];        return CKR_OK;}CK_RV slot_get_token(int id, struct sc_pkcs11_slot **slot){	int rv;	rv = slot_get_slot(id, slot);	if (rv != CKR_OK)		return rv;	if (!((*slot)->slot_info.flags & CKF_TOKEN_PRESENT))		return CKR_TOKEN_NOT_PRESENT;        return CKR_OK;}CK_RV slot_token_removed(int id){	int rv, token_was_present;        struct sc_pkcs11_slot *slot;        struct sc_pkcs11_object *object;	CK_SLOT_INFO saved_slot_info;	int reader;	rv = slot_get_slot(id, &slot);	if (rv != CKR_OK)		return rv;	token_was_present = (slot->slot_info.flags & CKF_TOKEN_PRESENT);        /* Terminate active sessions */        sc_pkcs11_close_all_sessions(id);	/* Object pool */	while (pool_find_and_delete(&slot->object_pool, 0, (void**) &object) == CKR_OK) {                if (object->ops->release)			object->ops->release(object);	}	/* Release framework stuff */	if (slot->card != NULL) {		if (slot->fw_data != NULL)			slot->card->framework->release_token(slot->card, slot->fw_data);		slot->card->num_slots--;	}	/* Zap everything else. Restore the slot_info afterwards (it contains the reader	 * name, for instance) but clear its flags */	saved_slot_info = slot->slot_info;	reader = slot->reader;	memset(slot, 0, sizeof(*slot));	slot->slot_info = saved_slot_info;	slot->slot_info.flags = 0;	slot->login_user = -1;	slot->reader = reader;	pool_initialize(&slot->object_pool, POOL_TYPE_OBJECT);	if (token_was_present)		slot->events = SC_EVENT_CARD_REMOVED;        return CKR_OK;}CK_RV slot_find_changed(CK_SLOT_ID_PTR idp, int mask){	sc_pkcs11_slot_t *slot;	CK_SLOT_ID id;	card_detect_all();	for (id = 0; id < SC_PKCS11_MAX_VIRTUAL_SLOTS; id++) {		slot = &virtual_slots[id];		if ((slot->events & SC_EVENT_CARD_INSERTED)		 && !(slot->slot_info.flags & CKF_TOKEN_PRESENT))			slot->events &= ~SC_EVENT_CARD_INSERTED;		if (slot->events & mask) {			slot->events &= ~mask;			*idp = id;			return CKR_OK;		}	}	return CKR_NO_EVENT;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -