2001-10-20 23:51:58 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <malloc.h>
|
2001-10-19 19:52:00 +00:00
|
|
|
#include "sc-pkcs11.h"
|
|
|
|
|
|
|
|
|
|
|
|
CK_RV C_OpenSession(CK_SLOT_ID slotID, /* the slot's ID */
|
|
|
|
CK_FLAGS flags, /* defined in CK_SESSION_INFO */
|
|
|
|
CK_VOID_PTR pApplication, /* pointer passed to callback */
|
|
|
|
CK_NOTIFY Notify, /* notification callback function */
|
|
|
|
CK_SESSION_HANDLE_PTR phSession) /* receives new session handle */
|
|
|
|
{
|
2001-10-20 23:51:58 +00:00
|
|
|
int i, rc;
|
|
|
|
struct pkcs11_session *ses;
|
|
|
|
|
|
|
|
LOG("C_OpenSession(%d, 0x%x, 0x%x, 0x%x, 0x%x)\n",
|
|
|
|
slotID, flags, pApplication, Notify, phSession);
|
|
|
|
|
|
|
|
if (!(flags & CKF_SERIAL_SESSION))
|
|
|
|
return CKR_SESSION_PARALLEL_NOT_SUPPORTED;
|
|
|
|
|
2001-10-21 16:01:07 +00:00
|
|
|
for (i=1; i<PKCS11_MAX_SESSIONS; i++)
|
2001-10-20 23:51:58 +00:00
|
|
|
if (session[i] == NULL)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (i >= PKCS11_MAX_SESSIONS)
|
|
|
|
return CKR_SESSION_COUNT;
|
|
|
|
|
2001-10-21 16:01:07 +00:00
|
|
|
if (!(slot[slotID].flags & SLOT_CONNECTED)) {
|
|
|
|
rc = slot_connect(slotID);
|
|
|
|
if (rc)
|
|
|
|
return rc;
|
2001-10-20 23:51:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ses = session[i] = (struct pkcs11_session*) malloc(sizeof(struct pkcs11_session));
|
|
|
|
memset(ses, 0, sizeof(struct pkcs11_session));
|
|
|
|
ses->slot = slotID;
|
|
|
|
if (flags & CKF_RW_SESSION)
|
|
|
|
ses->state = CKS_RW_PUBLIC_SESSION;
|
|
|
|
else ses->state = CKS_RO_PUBLIC_SESSION;
|
|
|
|
ses->flags = flags;
|
|
|
|
ses->notify_callback = Notify;
|
|
|
|
ses->notify_parameter = pApplication;
|
|
|
|
|
|
|
|
*phSession = i;
|
|
|
|
return CKR_OK;
|
2001-10-19 19:52:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV C_CloseSession(CK_SESSION_HANDLE hSession) /* the session's handle */
|
|
|
|
{
|
2001-10-21 16:01:07 +00:00
|
|
|
LOG("C_CloseSession(%d)\n", hSession);
|
2001-10-21 16:26:46 +00:00
|
|
|
if (hSession < 1 || hSession > PKCS11_MAX_SESSIONS || session[hSession] == NULL)
|
2001-10-20 23:51:58 +00:00
|
|
|
return CKR_SESSION_HANDLE_INVALID;
|
|
|
|
|
|
|
|
free(session[hSession]);
|
|
|
|
session[hSession] = NULL;
|
|
|
|
return CKR_OK;
|
2001-10-19 19:52:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV C_CloseAllSessions(CK_SLOT_ID slotID) /* the token's slot */
|
|
|
|
{
|
2001-10-20 23:51:58 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
LOG("C_CloseAllSessions(%d)\n", slotID);
|
|
|
|
for (i = 0; i < PKCS11_MAX_SESSIONS; i++) {
|
|
|
|
if (session[i] && session[i]->slot == slotID)
|
|
|
|
C_CloseSession(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
return CKR_OK;
|
2001-10-19 19:52:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_SESSION_INFO_PTR pInfo) /* receives session information */
|
|
|
|
{
|
2001-10-20 23:51:58 +00:00
|
|
|
struct pkcs11_session *ses;
|
|
|
|
|
2001-10-21 16:01:07 +00:00
|
|
|
LOG("C_GetSessionInfo(%d, 0x%x)\n", hSession, pInfo);
|
2001-10-21 16:26:46 +00:00
|
|
|
if (hSession < 1 || hSession > PKCS11_MAX_SESSIONS || session[hSession] == NULL)
|
2001-10-20 23:51:58 +00:00
|
|
|
return CKR_SESSION_HANDLE_INVALID;
|
|
|
|
|
|
|
|
ses = session[hSession];
|
|
|
|
pInfo->slotID = ses->slot;
|
|
|
|
pInfo->state = ses->state;
|
|
|
|
pInfo->flags = ses->flags;
|
|
|
|
pInfo->ulDeviceError = 0;
|
|
|
|
|
|
|
|
return CKR_OK;
|
2001-10-19 19:52:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV C_GetOperationState(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pOperationState, /* location receiving state */
|
|
|
|
CK_ULONG_PTR pulOperationStateLen) /* location receiving state length */
|
|
|
|
{
|
2001-10-21 16:01:07 +00:00
|
|
|
LOG("C_GetOperationState(%d, %0x%x, %d)\n", hSession,
|
2001-10-20 23:51:58 +00:00
|
|
|
pOperationState, pulOperationStateLen);
|
2001-10-19 19:52:00 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV C_SetOperationState(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pOperationState, /* the location holding the state */
|
|
|
|
CK_ULONG ulOperationStateLen, /* location holding state length */
|
|
|
|
CK_OBJECT_HANDLE hEncryptionKey, /* handle of en/decryption key */
|
|
|
|
CK_OBJECT_HANDLE hAuthenticationKey) /* handle of sign/verify key */
|
|
|
|
{
|
2001-10-21 16:01:07 +00:00
|
|
|
LOG("C_SetOperationState(%d, 0x%x, %d, 0x%x, 0x%x)\n",
|
2001-10-20 23:51:58 +00:00
|
|
|
hSession, pOperationState, ulOperationStateLen,
|
|
|
|
hEncryptionKey, hAuthenticationKey);
|
2001-10-19 19:52:00 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV C_Login(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_USER_TYPE userType, /* the user type */
|
|
|
|
CK_CHAR_PTR pPin, /* the user's PIN */
|
|
|
|
CK_ULONG ulPinLen) /* the length of the PIN */
|
|
|
|
{
|
2001-10-20 23:51:58 +00:00
|
|
|
struct pkcs11_session *ses;
|
|
|
|
struct sc_pkcs15_card *card;
|
|
|
|
int rc;
|
|
|
|
|
2001-10-21 16:01:07 +00:00
|
|
|
LOG("C_Login(%d, %d, 0x%x, %d)\n", hSession, userType, pPin, ulPinLen);
|
2001-10-21 16:26:46 +00:00
|
|
|
if (hSession < 1 || hSession > PKCS11_MAX_SESSIONS || session[hSession] == NULL)
|
2001-10-20 23:51:58 +00:00
|
|
|
return CKR_SESSION_HANDLE_INVALID;
|
|
|
|
|
|
|
|
if (userType != CKU_USER) {
|
|
|
|
LOG("Login tried for Security Officer\n");
|
|
|
|
return CKR_USER_TYPE_INVALID;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ulPinLen < 4 || ulPinLen > 8)
|
|
|
|
return CKR_PIN_LEN_RANGE;
|
|
|
|
|
|
|
|
ses = session[hSession];
|
2001-10-21 16:01:07 +00:00
|
|
|
card = slot[ses->slot].p15card;
|
2001-10-20 23:51:58 +00:00
|
|
|
|
|
|
|
if (ses->state != CKS_RO_PUBLIC_SESSION &&
|
|
|
|
ses->state != CKS_RW_PUBLIC_SESSION)
|
|
|
|
return CKR_USER_ALREADY_LOGGED_IN;
|
|
|
|
|
|
|
|
LOG("Master PIN code verification starts.\n");
|
2001-10-21 19:42:32 +00:00
|
|
|
rc = sc_pkcs15_verify_pin(card, &card->pin_info[0], pPin, ulPinLen);
|
2001-10-20 23:51:58 +00:00
|
|
|
switch (rc) {
|
|
|
|
case 0:
|
|
|
|
LOG("Master PIN code verified succesfully.\n");
|
|
|
|
if (ses->state == CKS_RO_PUBLIC_SESSION)
|
|
|
|
ses->state = CKS_RO_USER_FUNCTIONS;
|
|
|
|
else ses->state = CKS_RW_USER_FUNCTIONS;
|
|
|
|
break;
|
|
|
|
case SC_ERROR_PIN_CODE_INCORRECT:
|
|
|
|
LOG("Master PIN code INVALID!\n");
|
|
|
|
return CKR_PIN_INCORRECT;
|
|
|
|
default:
|
|
|
|
LOG("Device error!? rc=%d\n", rc);
|
|
|
|
return CKR_DEVICE_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CKR_OK;
|
2001-10-19 19:52:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV C_Logout(CK_SESSION_HANDLE hSession) /* the session's handle */
|
|
|
|
{
|
2001-10-20 23:51:58 +00:00
|
|
|
struct pkcs11_session *ses;
|
|
|
|
|
2001-10-21 16:01:07 +00:00
|
|
|
LOG("C_Logout(%d)\n", hSession);
|
2001-10-21 16:26:46 +00:00
|
|
|
if (hSession < 1 || hSession > PKCS11_MAX_SESSIONS || session[hSession] == NULL)
|
2001-10-20 23:51:58 +00:00
|
|
|
return CKR_SESSION_HANDLE_INVALID;
|
|
|
|
|
|
|
|
ses = session[hSession];
|
|
|
|
switch (ses->state) {
|
|
|
|
case CKS_RO_PUBLIC_SESSION:
|
|
|
|
case CKS_RW_PUBLIC_SESSION:
|
|
|
|
return CKR_USER_NOT_LOGGED_IN;
|
|
|
|
case CKS_RO_USER_FUNCTIONS:
|
|
|
|
ses->state = CKS_RO_PUBLIC_SESSION;
|
|
|
|
break;
|
|
|
|
case CKS_RW_USER_FUNCTIONS:
|
|
|
|
case CKS_RW_SO_FUNCTIONS:
|
|
|
|
ses->state = CKS_RW_PUBLIC_SESSION;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV C_InitPIN(CK_SESSION_HANDLE hSession,
|
|
|
|
CK_CHAR_PTR pPin,
|
|
|
|
CK_ULONG ulPinLen)
|
|
|
|
{
|
|
|
|
LOG("C_InitPIN(%d, '%s', %d)\n", hSession, pPin, ulPinLen);
|
2001-10-19 19:52:00 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
|
2001-10-20 23:51:58 +00:00
|
|
|
CK_RV C_SetPIN(CK_SESSION_HANDLE hSession,
|
|
|
|
CK_CHAR_PTR pOldPin,
|
|
|
|
CK_ULONG ulOldLen,
|
|
|
|
CK_CHAR_PTR pNewPin,
|
|
|
|
CK_ULONG ulNewLen)
|
|
|
|
{
|
|
|
|
struct pkcs11_session *ses;
|
|
|
|
struct sc_pkcs15_card *card;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
LOG("C_SetPIN(%d, '%s', %d, '%s', %d)\n", hSession, pOldPin, ulOldLen, pNewPin, ulNewLen);
|
2001-10-21 16:26:46 +00:00
|
|
|
if (hSession < 1 || hSession > PKCS11_MAX_SESSIONS || session[hSession] == NULL)
|
2001-10-20 23:51:58 +00:00
|
|
|
return CKR_SESSION_HANDLE_INVALID;
|
|
|
|
|
|
|
|
//if (!(ses->flags & CKF_RW_SESSION))
|
|
|
|
// return CKR_SESSION_READ_ONLY;
|
|
|
|
|
|
|
|
ses = session[hSession];
|
2001-10-21 16:01:07 +00:00
|
|
|
card = slot[ses->slot].p15card;
|
2001-10-20 23:51:58 +00:00
|
|
|
|
|
|
|
LOG("Master PIN code update starts.\n");
|
2001-10-21 19:42:32 +00:00
|
|
|
rc = sc_pkcs15_change_pin(card, &card->pin_info[0], pOldPin, ulOldLen, pNewPin, ulNewLen);
|
2001-10-20 23:51:58 +00:00
|
|
|
switch (rc) {
|
|
|
|
case 0:
|
|
|
|
LOG("Master PIN code CHANGED succesfully.\n");
|
|
|
|
break;
|
|
|
|
case SC_ERROR_PIN_CODE_INCORRECT:
|
|
|
|
LOG("Master PIN code INVALID!\n");
|
|
|
|
return CKR_PIN_INCORRECT;
|
|
|
|
default:
|
|
|
|
LOG("Device error!? rc=%d\n", rc);
|
|
|
|
return CKR_DEVICE_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
2001-10-19 19:52:00 +00:00
|
|
|
|