- Introduce locks around all pkcs11 operations, in case the caller
is multithreaded and wants to access us from different threads. git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@912 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
5265456cab
commit
cf6037314f
|
@ -32,15 +32,17 @@ extern CK_FUNCTION_LIST pkcs11_function_list;
|
|||
|
||||
CK_RV C_Initialize(CK_VOID_PTR pReserved)
|
||||
{
|
||||
int i, rc;
|
||||
int i, rc, rv;
|
||||
|
||||
if (context != NULL) {
|
||||
error(context, "C_Initialize(): Cryptoki already initialized\n");
|
||||
return CKR_CRYPTOKI_ALREADY_INITIALIZED;
|
||||
}
|
||||
rc = sc_establish_context(&context, "opensc-pkcs11");
|
||||
if (rc != 0)
|
||||
return CKR_DEVICE_ERROR;
|
||||
if (rc != 0) {
|
||||
rv = CKR_DEVICE_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Load configuration */
|
||||
load_pkcs11_parameters(&sc_pkcs11_conf, context);
|
||||
|
@ -55,25 +57,34 @@ CK_RV C_Initialize(CK_VOID_PTR pReserved)
|
|||
/* Detect any card, but do not flag "insert" events */
|
||||
__card_detect_all(0);
|
||||
|
||||
debug(context, "Cryptoki initialized\n");
|
||||
return CKR_OK;
|
||||
rv = sc_pkcs11_init_lock((CK_C_INITIALIZE_ARGS_PTR) pReserved);
|
||||
|
||||
out: debug(context, "C_Initialize: result = %d\n", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
CK_RV C_Finalize(CK_VOID_PTR pReserved)
|
||||
{
|
||||
int i;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
debug(context, "Shutting down Cryptoki\n");
|
||||
for (i=0; i<context->reader_count; i++)
|
||||
card_removed(i);
|
||||
|
||||
sc_release_context(context);
|
||||
context = NULL;
|
||||
sc_pkcs11_unlock();
|
||||
sc_pkcs11_free_lock();
|
||||
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
CK_RV C_GetInfo(CK_INFO_PTR pInfo)
|
||||
{
|
||||
sc_pkcs11_lock();
|
||||
|
||||
debug(context, "Cryptoki info query\n");
|
||||
|
||||
memset(pInfo, 0, sizeof(CK_INFO));
|
||||
|
@ -88,6 +99,7 @@ CK_RV C_GetInfo(CK_INFO_PTR pInfo)
|
|||
pInfo->libraryVersion.major = 0;
|
||||
pInfo->libraryVersion.minor = 2;
|
||||
|
||||
sc_pkcs11_unlock();
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
|
@ -104,6 +116,9 @@ CK_RV C_GetSlotList(CK_BBOOL tokenPresent, /* only slots with token prese
|
|||
CK_SLOT_ID found[SC_PKCS11_MAX_VIRTUAL_SLOTS];
|
||||
int numMatches, i;
|
||||
sc_pkcs11_slot_t *slot;
|
||||
CK_RV rv;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
debug(context, "Getting slot listing\n");
|
||||
card_detect_all();
|
||||
|
@ -119,20 +134,25 @@ CK_RV C_GetSlotList(CK_BBOOL tokenPresent, /* only slots with token prese
|
|||
if (pSlotList == NULL_PTR) {
|
||||
debug(context, "was only a size inquiry (%d)\n", numMatches);
|
||||
*pulCount = numMatches;
|
||||
return CKR_OK;
|
||||
rv = CKR_OK;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (*pulCount < numMatches) {
|
||||
debug(context, "buffer was too small (needed %d)\n", numMatches);
|
||||
*pulCount = numMatches;
|
||||
return CKR_BUFFER_TOO_SMALL;
|
||||
rv = CKR_BUFFER_TOO_SMALL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(pSlotList, found, numMatches * sizeof(CK_SLOT_ID));
|
||||
*pulCount = numMatches;
|
||||
rv = CKR_OK;
|
||||
|
||||
debug(context, "returned %d slots\n", numMatches);
|
||||
return CKR_OK;
|
||||
|
||||
out: sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
CK_RV C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
|
||||
|
@ -140,19 +160,19 @@ CK_RV C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
|
|||
struct sc_pkcs11_slot *slot;
|
||||
CK_RV rv;
|
||||
|
||||
rv = slot_get_slot(slotID, &slot);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
|
||||
if (!slot->card) {
|
||||
rv = card_detect_all();
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
}
|
||||
sc_pkcs11_lock();
|
||||
|
||||
debug(context, "Getting info about slot %d\n", slotID);
|
||||
memcpy(pInfo, &slot->slot_info, sizeof(CK_SLOT_INFO));
|
||||
return CKR_OK;
|
||||
|
||||
rv = slot_get_slot(slotID, &slot);
|
||||
if (rv == CKR_OK && !slot->card)
|
||||
rv = card_detect_all();
|
||||
|
||||
if (rv == CKR_OK)
|
||||
memcpy(pInfo, &slot->slot_info, sizeof(CK_SLOT_INFO));
|
||||
|
||||
sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
|
||||
|
@ -160,13 +180,16 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
|
|||
struct sc_pkcs11_slot *slot;
|
||||
CK_RV rv;
|
||||
|
||||
rv = slot_get_token(slotID, &slot);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
sc_pkcs11_lock();
|
||||
|
||||
debug(context, "Getting info about token in slot %d\n", slotID);
|
||||
memcpy(pInfo, &slot->token_info, sizeof(CK_TOKEN_INFO));
|
||||
return CKR_OK;
|
||||
|
||||
rv = slot_get_token(slotID, &slot);
|
||||
if (rv == CKR_OK)
|
||||
memcpy(pInfo, &slot->token_info, sizeof(CK_TOKEN_INFO));
|
||||
|
||||
sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
CK_RV C_GetMechanismList(CK_SLOT_ID slotID,
|
||||
|
@ -176,11 +199,14 @@ CK_RV C_GetMechanismList(CK_SLOT_ID slotID,
|
|||
struct sc_pkcs11_slot *slot;
|
||||
CK_RV rv;
|
||||
|
||||
rv = slot_get_token(slotID, &slot);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
sc_pkcs11_lock();
|
||||
|
||||
return sc_pkcs11_get_mechanism_list(slot->card, pMechanismList, pulCount);
|
||||
rv = slot_get_token(slotID, &slot);
|
||||
if (rv == CKR_OK)
|
||||
rv = sc_pkcs11_get_mechanism_list(slot->card, pMechanismList, pulCount);
|
||||
|
||||
sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
CK_RV C_GetMechanismInfo(CK_SLOT_ID slotID,
|
||||
|
@ -190,11 +216,14 @@ CK_RV C_GetMechanismInfo(CK_SLOT_ID slotID,
|
|||
struct sc_pkcs11_slot *slot;
|
||||
CK_RV rv;
|
||||
|
||||
rv = slot_get_token(slotID, &slot);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
sc_pkcs11_lock();
|
||||
|
||||
return sc_pkcs11_get_mechanism_info(slot->card, type, pInfo);
|
||||
rv = slot_get_token(slotID, &slot);
|
||||
if (rv == CKR_OK)
|
||||
rv = sc_pkcs11_get_mechanism_info(slot->card, type, pInfo);
|
||||
|
||||
sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
CK_RV C_InitToken(CK_SLOT_ID slotID,
|
||||
|
@ -207,15 +236,19 @@ CK_RV C_InitToken(CK_SLOT_ID slotID,
|
|||
struct sc_pkcs11_slot *slot;
|
||||
CK_RV rv;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = slot_get_token(slotID, &slot);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
/* Make sure there's no open session for this token */
|
||||
for (item = session_pool.head; item; item = item->next) {
|
||||
session = (struct sc_pkcs11_session*) item->item;
|
||||
if (session->slot == slot)
|
||||
return CKR_SESSION_EXISTS;
|
||||
if (session->slot == slot) {
|
||||
rv = CKR_SESSION_EXISTS;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (slot->card->framework->init_token == NULL)
|
||||
|
@ -223,12 +256,13 @@ CK_RV C_InitToken(CK_SLOT_ID slotID,
|
|||
rv = slot->card->framework->init_token(slot->card,
|
||||
slot->fw_data, pPin, ulPinLen, pLabel);
|
||||
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
if (rv == CKR_OK) {
|
||||
/* Now we should re-bind all tokens so they get the
|
||||
* corresponding function vector and flags */
|
||||
}
|
||||
|
||||
/* Now we should re-bind all tokens so they get the
|
||||
* corresponding function vector and flags */
|
||||
return CKR_OK;
|
||||
out: sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
CK_RV C_WaitForSlotEvent(CK_FLAGS flags, /* blocking/nonblocking flag */
|
||||
|
@ -241,11 +275,13 @@ CK_RV C_WaitForSlotEvent(CK_FLAGS flags, /* blocking/nonblocking flag */
|
|||
unsigned int mask, events;
|
||||
CK_RV rv;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
mask = SC_EVENT_CARD_INSERTED|SC_EVENT_CARD_REMOVED;
|
||||
|
||||
if ((rv = slot_find_changed(pSlot, mask)) == CKR_OK
|
||||
|| (flags & CKF_DONT_BLOCK))
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
for (i = k = 0; i < context->reader_count; i++) {
|
||||
reader = context->reader[i];
|
||||
|
@ -255,16 +291,103 @@ CK_RV C_WaitForSlotEvent(CK_FLAGS flags, /* blocking/nonblocking flag */
|
|||
}
|
||||
}
|
||||
|
||||
sc_pkcs11_unlock();
|
||||
r = sc_wait_for_event(readers, slots, k, mask, &found, &events, -1);
|
||||
sc_pkcs11_lock();
|
||||
|
||||
if (r != SC_SUCCESS) {
|
||||
error(context, "sc_wait_for_event() returned %d\n", r);
|
||||
return sc_to_cryptoki_error(r, -1);
|
||||
rv = sc_to_cryptoki_error(r, -1);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((rv = slot_find_changed(pSlot, mask)) == CKR_OK)
|
||||
return rv;
|
||||
if ((rv = slot_find_changed(pSlot, mask)) != CKR_OK)
|
||||
rv = CKR_FUNCTION_FAILED;
|
||||
|
||||
return CKR_FUNCTION_FAILED;
|
||||
out: sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Locking functions
|
||||
*/
|
||||
#include "../libopensc/internal.h"
|
||||
|
||||
static CK_C_INITIALIZE_ARGS_PTR _locking;
|
||||
static void * _lock = NULL;
|
||||
|
||||
CK_RV
|
||||
sc_pkcs11_init_lock(CK_C_INITIALIZE_ARGS_PTR args)
|
||||
{
|
||||
int rv = CKR_OK;
|
||||
|
||||
if (_lock)
|
||||
return CKR_OK;
|
||||
|
||||
/* No CK_C_INITIALIZE_ARGS pointer, no locking */
|
||||
if (!args)
|
||||
return CKR_OK;
|
||||
|
||||
if (args->pReserved)
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
|
||||
/* If the app tells us OS locking is okay,
|
||||
* use that. Otherwise use the supplied functions.
|
||||
*/
|
||||
_locking = NULL;
|
||||
if (args->flags & CKF_OS_LOCKING_OK) {
|
||||
if (!(_lock = sc_mutex_new()))
|
||||
rv = CKR_CANT_LOCK;
|
||||
} else
|
||||
if (args->CreateMutex
|
||||
&& args->DestroyMutex
|
||||
&& args->LockMutex
|
||||
&& args->UnlockMutex) {
|
||||
rv = args->CreateMutex(&_lock);
|
||||
if (rv == CKR_OK)
|
||||
_locking = args;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
sc_pkcs11_free_lock()
|
||||
{
|
||||
if (!_lock)
|
||||
return;
|
||||
if (_locking)
|
||||
_locking->DestroyMutex(_lock);
|
||||
else
|
||||
sc_mutex_free((sc_mutex_t *) _lock);
|
||||
_locking = NULL;
|
||||
_lock = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
sc_pkcs11_lock()
|
||||
{
|
||||
if (!_lock)
|
||||
return;
|
||||
if (_locking) {
|
||||
while (_locking->LockMutex(_lock) != CKR_OK)
|
||||
;
|
||||
} else {
|
||||
sc_mutex_lock((sc_mutex_t *) _lock);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sc_pkcs11_unlock()
|
||||
{
|
||||
if (!_lock)
|
||||
return;
|
||||
if (_locking) {
|
||||
while (_locking->UnlockMutex(_lock) != CKR_OK)
|
||||
;
|
||||
} else {
|
||||
sc_mutex_unlock((sc_mutex_t *) _lock);
|
||||
}
|
||||
}
|
||||
|
||||
CK_FUNCTION_LIST pkcs11_function_list = {
|
||||
|
|
|
@ -37,18 +37,22 @@ CK_RV C_CreateObject(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
struct sc_pkcs11_card *card;
|
||||
int rv;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
dump_template("C_CreateObject()", pTemplate, ulCount);
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
card = session->slot->card;
|
||||
if (card->framework->create_object == NULL)
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
|
||||
return card->framework->create_object(card, session->slot,
|
||||
rv = CKR_FUNCTION_NOT_SUPPORTED;
|
||||
else
|
||||
rv = card->framework->create_object(card, session->slot,
|
||||
pTemplate, ulCount, phObject);
|
||||
|
||||
out: sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
CK_RV C_CopyObject(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
|
@ -90,13 +94,15 @@ CK_RV C_GetAttributeValue(CK_SESSION_HANDLE hSession, /* the session's handle
|
|||
struct sc_pkcs11_object *object;
|
||||
int res, res_type;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
rv = pool_find(&session->slot->object_pool, hObject, (void**) &object);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
res_type = 0;
|
||||
for (i = 0; i < ulCount; i++) {
|
||||
|
@ -125,6 +131,7 @@ CK_RV C_GetAttributeValue(CK_SESSION_HANDLE hSession, /* the session's handle
|
|||
}
|
||||
}
|
||||
|
||||
out: sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -137,24 +144,28 @@ CK_RV C_SetAttributeValue(CK_SESSION_HANDLE hSession, /* the session's handle
|
|||
struct sc_pkcs11_session *session;
|
||||
struct sc_pkcs11_object *object;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
rv = pool_find(&session->slot->object_pool, hObject, (void**) &object);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
if (object->ops->set_attribute == NULL)
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
|
||||
for (i = 0; i < ulCount; i++) {
|
||||
rv = object->ops->set_attribute(session, object, &pTemplate[i]);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
rv = CKR_FUNCTION_NOT_SUPPORTED;
|
||||
else {
|
||||
for (i = 0; i < ulCount; i++) {
|
||||
rv = object->ops->set_attribute(session, object, &pTemplate[i]);
|
||||
if (rv != CKR_OK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CKR_OK;
|
||||
out: sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
CK_RV C_FindObjectsInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
|
@ -170,9 +181,11 @@ CK_RV C_FindObjectsInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
struct sc_pkcs11_find_operation *operation;
|
||||
struct sc_pkcs11_pool_item *item;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
debug(context, "C_FindObjectsInit(slot = %d)\n", session->slot->id);
|
||||
dump_template("C_FindObjectsInit()", pTemplate, ulCount);
|
||||
|
@ -180,9 +193,8 @@ CK_RV C_FindObjectsInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
rv = session_start_operation(session, SC_PKCS11_OPERATION_FIND,
|
||||
&find_mechanism,
|
||||
(struct sc_pkcs11_operation**) &operation);
|
||||
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
operation->current_handle = 0;
|
||||
operation->num_handles = 0;
|
||||
|
@ -234,7 +246,9 @@ CK_RV C_FindObjectsInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
}
|
||||
|
||||
debug(context, "%d matching objects\n", operation->num_handles);
|
||||
return CKR_OK;
|
||||
|
||||
out: sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
CK_RV C_FindObjects(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
|
@ -246,14 +260,16 @@ CK_RV C_FindObjects(CK_SESSION_HANDLE hSession, /* the session's han
|
|||
struct sc_pkcs11_session *session;
|
||||
struct sc_pkcs11_find_operation *operation;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
rv = session_get_operation(session, SC_PKCS11_OPERATION_FIND,
|
||||
(sc_pkcs11_operation_t **) &operation);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
to_return = operation->num_handles - operation->current_handle;
|
||||
if (to_return > ulMaxObjectCount)
|
||||
|
@ -267,7 +283,8 @@ CK_RV C_FindObjects(CK_SESSION_HANDLE hSession, /* the session's han
|
|||
|
||||
operation->current_handle += to_return;
|
||||
|
||||
return CKR_OK;
|
||||
out: sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE hSession) /* the session's handle */
|
||||
|
@ -275,16 +292,18 @@ CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE hSession) /* the session's handle */
|
|||
int rv;
|
||||
struct sc_pkcs11_session *session;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
rv = session_get_operation(session, SC_PKCS11_OPERATION_FIND, NULL);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
if (rv == CKR_OK)
|
||||
session_stop_operation(session, SC_PKCS11_OPERATION_FIND);
|
||||
|
||||
session_stop_operation(session, SC_PKCS11_OPERATION_FIND);
|
||||
return CKR_OK;
|
||||
out: sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -298,13 +317,14 @@ CK_RV C_DigestInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
int rv;
|
||||
struct sc_pkcs11_session *session;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
|
||||
rv = sc_pkcs11_md_init(session, pMechanism);
|
||||
|
||||
if (rv == CKR_OK)
|
||||
rv = sc_pkcs11_md_init(session, pMechanism);
|
||||
debug(context, "C_DigestInit returns %d\n", rv);
|
||||
|
||||
sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -317,15 +337,19 @@ CK_RV C_Digest(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
int rv;
|
||||
struct sc_pkcs11_session *session;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
rv = sc_pkcs11_md_update(session, pData, ulDataLen);
|
||||
if (rv == CKR_OK)
|
||||
rv = sc_pkcs11_md_final(session, pDigest, pulDigestLen);
|
||||
|
||||
debug(context, "C_Digest returns %d\n", rv);
|
||||
out: debug(context, "C_Digest returns %d\n", rv);
|
||||
sc_pkcs11_unlock();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -336,13 +360,14 @@ CK_RV C_DigestUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
int rv;
|
||||
struct sc_pkcs11_session *session;
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = sc_pkcs11_md_update(session, pPart, ulPartLen);
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv == CKR_OK)
|
||||
rv = sc_pkcs11_md_update(session, pPart, ulPartLen);
|
||||
|
||||
debug(context, "C_DigestUpdate returns %d\n", rv);
|
||||
sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -359,13 +384,14 @@ CK_RV C_DigestFinal(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
int rv;
|
||||
struct sc_pkcs11_session *session;
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = sc_pkcs11_md_final(session, pDigest, pulDigestLen);
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv == CKR_OK)
|
||||
rv = sc_pkcs11_md_final(session, pDigest, pulDigestLen);
|
||||
|
||||
debug(context, "C_DigestFinal returns %d\n", rv);
|
||||
sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -377,34 +403,42 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
CK_KEY_TYPE key_type;
|
||||
CK_ATTRIBUTE sign_attribute = { CKA_SIGN, &can_sign, sizeof(can_sign) };
|
||||
CK_ATTRIBUTE key_type_attr = { CKA_KEY_TYPE, &key_type, sizeof(key_type) };
|
||||
|
||||
int rv;
|
||||
struct sc_pkcs11_session *session;
|
||||
struct sc_pkcs11_object *object;
|
||||
int rv;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
rv = pool_find(&session->slot->object_pool, hKey, (void**) &object);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
if (object->ops->sign == NULL_PTR)
|
||||
return CKR_KEY_TYPE_INCONSISTENT;
|
||||
if (object->ops->sign == NULL_PTR) {
|
||||
rv = CKR_KEY_TYPE_INCONSISTENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rv = object->ops->get_attribute(session, object, &sign_attribute);
|
||||
if (rv != CKR_OK || !can_sign)
|
||||
return CKR_KEY_TYPE_INCONSISTENT;
|
||||
if (rv != CKR_OK || !can_sign) {
|
||||
rv = CKR_KEY_TYPE_INCONSISTENT;
|
||||
goto out;
|
||||
}
|
||||
rv = object->ops->get_attribute(session, object, &key_type_attr);
|
||||
if (rv != CKR_OK)
|
||||
return CKR_KEY_TYPE_INCONSISTENT;
|
||||
if (rv != CKR_OK) {
|
||||
rv = CKR_KEY_TYPE_INCONSISTENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
debug(context, "Sign operation initialized\n");
|
||||
|
||||
rv = sc_pkcs11_sign_init(session, pMechanism, object, key_type);
|
||||
|
||||
debug(context, "Sign initialization returns %d\n", rv);
|
||||
out: debug(context, "Sign initialization returns %d\n", rv);
|
||||
sc_pkcs11_unlock();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -418,9 +452,11 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
struct sc_pkcs11_session *session;
|
||||
CK_ULONG length;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
/* According to the pkcs11 specs, we must not do any calls that
|
||||
* change our crypto state if the caller is just asking for the
|
||||
|
@ -428,18 +464,20 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
* CKR_BUFFER_TOO_SMALL. Thus we cannot do the sign_update call
|
||||
* below. */
|
||||
if ((rv = sc_pkcs11_sign_size(session, &length)) != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
if (pSignature == NULL || length > *pulSignatureLen) {
|
||||
*pulSignatureLen = length;
|
||||
return pSignature? CKR_BUFFER_TOO_SMALL : CKR_OK;
|
||||
rv = pSignature? CKR_BUFFER_TOO_SMALL : CKR_OK;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rv = sc_pkcs11_sign_update(session, pData, ulDataLen);
|
||||
if (rv == CKR_OK)
|
||||
rv = sc_pkcs11_sign_final(session, pSignature, pulSignatureLen);
|
||||
|
||||
debug(context, "Signing result was %d\n", rv);
|
||||
out: debug(context, "Signing result was %d\n", rv);
|
||||
sc_pkcs11_unlock();
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
@ -448,15 +486,17 @@ CK_RV C_SignUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
CK_BYTE_PTR pPart, /* the data (digest) to be signed */
|
||||
CK_ULONG ulPartLen) /* count of bytes to be signed */
|
||||
{
|
||||
int rv;
|
||||
struct sc_pkcs11_session *session;
|
||||
int rv;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
if (rv == CKR_OK)
|
||||
rv = sc_pkcs11_sign_update(session, pPart, ulPartLen);
|
||||
|
||||
rv = sc_pkcs11_sign_update(session, pPart, ulPartLen);
|
||||
debug(context, "C_SignUpdate returns %d\n", rv);
|
||||
sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -464,13 +504,15 @@ CK_RV C_SignFinal(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
CK_BYTE_PTR pSignature, /* receives the signature */
|
||||
CK_ULONG_PTR pulSignatureLen) /* receives byte count of signature */
|
||||
{
|
||||
int rv;
|
||||
struct sc_pkcs11_session *session;
|
||||
CK_ULONG length;
|
||||
int rv;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
/* According to the pkcs11 specs, we must not do any calls that
|
||||
* change our crypto state if the caller is just asking for the
|
||||
|
@ -478,16 +520,18 @@ CK_RV C_SignFinal(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
* CKR_BUFFER_TOO_SMALL.
|
||||
*/
|
||||
if ((rv = sc_pkcs11_sign_size(session, &length)) != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
if (pSignature == NULL || length > *pulSignatureLen) {
|
||||
*pulSignatureLen = length;
|
||||
return pSignature? CKR_BUFFER_TOO_SMALL : CKR_OK;
|
||||
rv = pSignature? CKR_BUFFER_TOO_SMALL : CKR_OK;
|
||||
} else {
|
||||
rv = sc_pkcs11_sign_final(session, pSignature, pulSignatureLen);
|
||||
}
|
||||
|
||||
out: debug(context, "C_SignFinal returns %d\n", rv);
|
||||
sc_pkcs11_unlock();
|
||||
|
||||
rv = sc_pkcs11_sign_final(session, pSignature, pulSignatureLen);
|
||||
debug(context, "C_SignFinal returns %d\n", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -499,28 +543,35 @@ CK_RV C_SignRecoverInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
CK_KEY_TYPE key_type;
|
||||
CK_ATTRIBUTE sign_attribute = { CKA_SIGN, &can_sign, sizeof(can_sign) };
|
||||
CK_ATTRIBUTE key_type_attr = { CKA_KEY_TYPE, &key_type, sizeof(key_type) };
|
||||
|
||||
int rv;
|
||||
struct sc_pkcs11_session *session;
|
||||
struct sc_pkcs11_object *object;
|
||||
int rv;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
rv = pool_find(&session->slot->object_pool, hKey, (void**) &object);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
if (object->ops->sign == NULL_PTR)
|
||||
return CKR_KEY_TYPE_INCONSISTENT;
|
||||
if (object->ops->sign == NULL_PTR) {
|
||||
rv = CKR_KEY_TYPE_INCONSISTENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rv = object->ops->get_attribute(session, object, &sign_attribute);
|
||||
if (rv != CKR_OK || !can_sign)
|
||||
return CKR_KEY_TYPE_INCONSISTENT;
|
||||
if (rv != CKR_OK || !can_sign) {
|
||||
rv = CKR_KEY_TYPE_INCONSISTENT;
|
||||
goto out;
|
||||
}
|
||||
rv = object->ops->get_attribute(session, object, &key_type_attr);
|
||||
if (rv != CKR_OK)
|
||||
return CKR_KEY_TYPE_INCONSISTENT;
|
||||
if (rv != CKR_OK) {
|
||||
rv = CKR_KEY_TYPE_INCONSISTENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* XXX: need to tell the signature algorithm that we want
|
||||
* to recover the signature */
|
||||
|
@ -528,7 +579,8 @@ CK_RV C_SignRecoverInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
|
||||
rv = sc_pkcs11_sign_init(session, pMechanism, object, key_type);
|
||||
|
||||
debug(context, "Sign initialization returns %d\n", rv);
|
||||
out: debug(context, "Sign initialization returns %d\n", rv);
|
||||
sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -681,21 +733,25 @@ CK_RV C_UnwrapKey(CK_SESSION_HANDLE hSession, /* the session's handl
|
|||
CK_ULONG ulAttributeCount, /* # of attributes in template */
|
||||
CK_OBJECT_HANDLE_PTR phKey) /* gets handle of recovered key */
|
||||
{
|
||||
int rv;
|
||||
struct sc_pkcs11_session *session;
|
||||
struct sc_pkcs11_object *object, *result;
|
||||
int rv;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
rv = pool_find(&session->slot->object_pool, hUnwrappingKey,
|
||||
(void**) &object);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
if (object->ops->sign == NULL_PTR)
|
||||
return CKR_KEY_TYPE_INCONSISTENT;
|
||||
if (object->ops->sign == NULL_PTR) {
|
||||
rv = CKR_KEY_TYPE_INCONSISTENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rv = object->ops->unwrap_key(session, object, pMechanism,
|
||||
pWrappedKey, ulWrappedKeyLen,
|
||||
|
@ -704,10 +760,10 @@ CK_RV C_UnwrapKey(CK_SESSION_HANDLE hSession, /* the session's handl
|
|||
|
||||
debug(context, "Unwrapping result was %d\n", rv);
|
||||
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
if (rv == CKR_OK)
|
||||
rv = pool_insert(&session->slot->object_pool, result, phKey);
|
||||
|
||||
rv = pool_insert(&session->slot->object_pool, result, phKey);
|
||||
out: sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -729,11 +785,14 @@ CK_RV C_SeedRandom(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
struct sc_pkcs11_session *session;
|
||||
int rv;
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
sc_pkcs11_lock();
|
||||
|
||||
return sc_pkcs11_openssl_add_seed_rand(session, pSeed, ulSeedLen);
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv == CKR_OK)
|
||||
rv = sc_pkcs11_openssl_add_seed_rand(session, pSeed, ulSeedLen);
|
||||
|
||||
sc_pkcs11_unlock();
|
||||
return rv;
|
||||
#else
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
#endif
|
||||
|
@ -747,11 +806,14 @@ CK_RV C_GenerateRandom(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
struct sc_pkcs11_session *session;
|
||||
int rv;
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
sc_pkcs11_lock();
|
||||
|
||||
return sc_pkcs11_openssl_add_gen_rand(session, RandomData, ulRandomLen);
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv == CKR_OK)
|
||||
rv = sc_pkcs11_openssl_add_gen_rand(session, RandomData, ulRandomLen);
|
||||
|
||||
sc_pkcs11_unlock();
|
||||
return rv;
|
||||
#else
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
#endif
|
||||
|
|
|
@ -33,18 +33,24 @@ CK_RV C_OpenSession(CK_SLOT_ID slotID, /* the slot's ID */
|
|||
struct sc_pkcs11_session *session;
|
||||
int rv;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
debug(context, "Opening new session for slot %d\n", slotID);
|
||||
|
||||
if (!(flags & CKF_SERIAL_SESSION))
|
||||
return CKR_SESSION_PARALLEL_NOT_SUPPORTED;
|
||||
if (!(flags & CKF_SERIAL_SESSION)) {
|
||||
rv = CKR_SESSION_PARALLEL_NOT_SUPPORTED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rv = slot_get_token(slotID, &slot);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
/* Check that no conflictions sessions exist */
|
||||
if (!(flags & CKF_RW_SESSION) && (slot->login_user == CKU_SO))
|
||||
return CKR_SESSION_READ_WRITE_SO_EXISTS;
|
||||
if (!(flags & CKF_RW_SESSION) && (slot->login_user == CKU_SO)) {
|
||||
rv = CKR_SESSION_READ_WRITE_SO_EXISTS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
session = (struct sc_pkcs11_session*) malloc(sizeof(struct sc_pkcs11_session));
|
||||
memset(session, 0, sizeof(struct sc_pkcs11_session));
|
||||
|
@ -59,18 +65,21 @@ CK_RV C_OpenSession(CK_SLOT_ID slotID, /* the slot's ID */
|
|||
else
|
||||
slot->nsessions++;
|
||||
|
||||
out: sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
CK_RV C_CloseSession(CK_SESSION_HANDLE hSession) /* the session's handle */
|
||||
{
|
||||
struct sc_pkcs11_slot *slot;
|
||||
int rv;
|
||||
struct sc_pkcs11_session *session;
|
||||
int rv;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = pool_find_and_delete(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
debug(context, "C_CloseSession(slot %d)\n", session->slot->id);
|
||||
|
||||
|
@ -84,10 +93,14 @@ CK_RV C_CloseSession(CK_SESSION_HANDLE hSession) /* the session's handle */
|
|||
}
|
||||
|
||||
free(session);
|
||||
return CKR_OK;
|
||||
|
||||
out: sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
CK_RV C_CloseAllSessions(CK_SLOT_ID slotID) /* the token's slot */
|
||||
/* Internal version of C_CloseAllSessions that gets called with
|
||||
* the global lock held */
|
||||
CK_RV sc_pkcs11_close_all_sessions(CK_SLOT_ID slotID)
|
||||
{
|
||||
struct sc_pkcs11_pool_item *item, *next;
|
||||
struct sc_pkcs11_session *session;
|
||||
|
@ -105,15 +118,27 @@ CK_RV C_CloseAllSessions(CK_SLOT_ID slotID) /* the token's slot */
|
|||
return CKR_OK;
|
||||
}
|
||||
|
||||
CK_RV C_CloseAllSessions(CK_SLOT_ID slotID) /* the token's slot */
|
||||
{
|
||||
int rv;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
rv = sc_pkcs11_close_all_sessions(slotID);
|
||||
sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_SESSION_INFO_PTR pInfo) /* receives session information */
|
||||
{
|
||||
int rv;
|
||||
struct sc_pkcs11_session *session;
|
||||
int rv;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
debug(context, "C_GetSessionInfo(slot %d).\n", session->slot->id);
|
||||
pInfo->slotID = session->slot->id;
|
||||
|
@ -133,7 +158,8 @@ CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
? CKS_RW_PUBLIC_SESSION : CKS_RO_PUBLIC_SESSION;
|
||||
}
|
||||
|
||||
return CKR_OK;
|
||||
out: sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
CK_RV C_GetOperationState(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
|
@ -161,22 +187,30 @@ CK_RV C_Login(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
struct sc_pkcs11_session *session;
|
||||
struct sc_pkcs11_slot *slot;
|
||||
|
||||
if (userType != CKU_USER && userType != CKU_SO)
|
||||
return CKR_USER_TYPE_INVALID;
|
||||
sc_pkcs11_lock();
|
||||
|
||||
if (userType != CKU_USER && userType != CKU_SO) {
|
||||
rv = CKR_USER_TYPE_INVALID;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
debug(context, "Login for session %d\n", hSession);
|
||||
|
||||
slot = session->slot;
|
||||
|
||||
if (!(slot->token_info.flags & CKF_USER_PIN_INITIALIZED))
|
||||
return CKR_USER_PIN_NOT_INITIALIZED;
|
||||
if (!(slot->token_info.flags & CKF_USER_PIN_INITIALIZED)) {
|
||||
rv = CKR_USER_PIN_NOT_INITIALIZED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (slot->login_user >= 0)
|
||||
return CKR_USER_ALREADY_LOGGED_IN;
|
||||
if (slot->login_user >= 0) {
|
||||
rv = CKR_USER_ALREADY_LOGGED_IN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rv = slot->card->framework->login(slot->card,
|
||||
slot->fw_data,
|
||||
|
@ -184,6 +218,7 @@ CK_RV C_Login(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
if (rv == CKR_OK)
|
||||
slot->login_user = userType;
|
||||
|
||||
out: sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -193,19 +228,23 @@ CK_RV C_Logout(CK_SESSION_HANDLE hSession) /* the session's handle */
|
|||
struct sc_pkcs11_session *session;
|
||||
struct sc_pkcs11_slot *slot;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
debug(context, "Logout for session %d\n", hSession);
|
||||
|
||||
slot = session->slot;
|
||||
|
||||
if (slot->login_user < 0)
|
||||
return CKR_OK;
|
||||
if (slot->login_user >= 0) {
|
||||
slot->login_user = -1;
|
||||
rv = slot->card->framework->logout(slot->card, slot->fw_data);
|
||||
}
|
||||
|
||||
slot->login_user = -1;
|
||||
return slot->card->framework->logout(slot->card, slot->fw_data);
|
||||
out: sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
CK_RV C_InitPIN(CK_SESSION_HANDLE hSession,
|
||||
|
@ -216,17 +255,25 @@ CK_RV C_InitPIN(CK_SESSION_HANDLE hSession,
|
|||
struct sc_pkcs11_slot *slot;
|
||||
int rv;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
slot = session->slot;
|
||||
if (slot->login_user != CKU_SO)
|
||||
return CKR_USER_NOT_LOGGED_IN;
|
||||
if (slot->card->framework->init_pin == NULL)
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
return slot->card->framework->init_pin(slot->card, slot,
|
||||
if (slot->login_user != CKU_SO) {
|
||||
rv = CKR_USER_NOT_LOGGED_IN;
|
||||
} else
|
||||
if (slot->card->framework->init_pin == NULL) {
|
||||
rv = CKR_FUNCTION_NOT_SUPPORTED;
|
||||
} else {
|
||||
rv = slot->card->framework->init_pin(slot->card, slot,
|
||||
pPin, ulPinLen);
|
||||
}
|
||||
|
||||
out: sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
CK_RV C_SetPIN(CK_SESSION_HANDLE hSession,
|
||||
|
@ -239,18 +286,25 @@ CK_RV C_SetPIN(CK_SESSION_HANDLE hSession,
|
|||
struct sc_pkcs11_session *session;
|
||||
struct sc_pkcs11_slot *slot;
|
||||
|
||||
sc_pkcs11_lock();
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
goto out;
|
||||
|
||||
debug(context, "Changing PIN (session %d)\n", hSession);
|
||||
#if 0
|
||||
if (!(ses->flags & CKF_RW_SESSION))
|
||||
return CKR_SESSION_READ_ONLY;
|
||||
if (!(ses->flags & CKF_RW_SESSION)) {
|
||||
rv = CKR_SESSION_READ_ONLY;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
slot = session->slot;
|
||||
return slot->card->framework->change_pin(slot->card, slot->fw_data,
|
||||
rv = slot->card->framework->change_pin(slot->card, slot->fw_data,
|
||||
pOldPin, ulOldLen,
|
||||
pNewPin, ulNewLen);
|
||||
|
||||
out: sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -314,6 +314,7 @@ CK_RV session_start_operation(struct sc_pkcs11_session *,
|
|||
CK_RV session_get_operation(struct sc_pkcs11_session *, int,
|
||||
struct sc_pkcs11_operation **);
|
||||
CK_RV session_stop_operation(struct sc_pkcs11_session *, int);
|
||||
CK_RV sc_pkcs11_close_all_sessions(CK_SLOT_ID);
|
||||
|
||||
/* Generic secret key stuff */
|
||||
CK_RV sc_pkcs11_create_secret_key(struct sc_pkcs11_session *,
|
||||
|
@ -372,6 +373,12 @@ CK_RV sc_pkcs11_openssl_add_gen_rand(struct sc_pkcs11_session *, CK_BYTE_PTR, CK
|
|||
/* Load configuration defaults */
|
||||
void load_pkcs11_parameters(struct sc_pkcs11_config *, struct sc_context *);
|
||||
|
||||
/* Locking primitives at the pkcs11 level */
|
||||
CK_RV sc_pkcs11_init_lock(CK_C_INITIALIZE_ARGS_PTR);
|
||||
void sc_pkcs11_lock(void);
|
||||
void sc_pkcs11_unlock(void);
|
||||
void sc_pkcs11_free_lock(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -278,7 +278,7 @@ CK_RV slot_token_removed(int id)
|
|||
token_was_present = (slot->slot_info.flags & CKF_TOKEN_PRESENT);
|
||||
|
||||
/* Terminate active sessions */
|
||||
C_CloseAllSessions(id);
|
||||
sc_pkcs11_close_all_sessions(id);
|
||||
|
||||
/* Object pool */
|
||||
while (pool_find_and_delete(&slot->object_pool, 0, (void**) &object) == CKR_OK) {
|
||||
|
|
Loading…
Reference in New Issue