2001-10-19 19:52:00 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <winscard.h>
|
|
|
|
|
|
|
|
#include "sc-pkcs11.h"
|
2001-10-20 16:53:51 +00:00
|
|
|
#include "../sc.h"
|
2001-10-19 19:52:00 +00:00
|
|
|
|
2001-10-20 16:53:51 +00:00
|
|
|
struct sc_context *ctx = NULL;
|
|
|
|
struct sc_pkcs15_card *p15card = NULL;
|
2001-10-19 19:52:00 +00:00
|
|
|
|
|
|
|
void LOG(char *format, ...)
|
|
|
|
{
|
|
|
|
va_list valist;
|
|
|
|
FILE *out;
|
|
|
|
|
|
|
|
out = fopen("/tmp/libsc-pkcs11.log", "a");
|
|
|
|
if (out != NULL) {
|
|
|
|
va_start(valist, format);
|
|
|
|
vfprintf(out, format, valist);
|
|
|
|
va_end(valist);
|
|
|
|
fclose(out);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV C_Initialize(CK_VOID_PTR pReserved)
|
|
|
|
{
|
|
|
|
int reader_count, reader_buf_size, rv;
|
|
|
|
char *reader_buf, *p;
|
|
|
|
|
|
|
|
LOG("C_Initialize(0x%x)\n", pReserved);
|
|
|
|
|
2001-10-20 16:53:51 +00:00
|
|
|
ctx = NULL;
|
|
|
|
rv = sc_establish_context(&ctx);
|
|
|
|
if (rv != 0) {
|
2001-10-19 19:52:00 +00:00
|
|
|
LOG("ERROR: Unable to connect to Resource Manager\n");
|
|
|
|
return CKR_DEVICE_ERROR;
|
|
|
|
}
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV C_Finalize(CK_VOID_PTR pReserved)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
LOG("C_Finalize(0x%x)\n", pReserved);
|
|
|
|
|
2001-10-20 16:53:51 +00:00
|
|
|
if (p15card != NULL) {
|
|
|
|
sc_disconnect_card(p15card->card);
|
|
|
|
sc_pkcs15_destroy(p15card);
|
|
|
|
}
|
|
|
|
sc_destroy_context(ctx);
|
2001-10-19 19:52:00 +00:00
|
|
|
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV C_GetInfo(CK_INFO_PTR pInfo)
|
|
|
|
{
|
|
|
|
LOG("C_GetInfo(0x%x)\n", pInfo);
|
|
|
|
memset(pInfo, 0, sizeof(CK_INFO));
|
|
|
|
pInfo->cryptokiVersion.major = 2;
|
|
|
|
pInfo->cryptokiVersion.minor = 10;
|
|
|
|
strcpy(pInfo->manufacturerID, "Timo Teras & Juha Yrjola");
|
2001-10-20 16:53:51 +00:00
|
|
|
strcpy(pInfo->libraryDescription, "PC/SC PKCS#15 SmartCard reader");
|
2001-10-19 19:52:00 +00:00
|
|
|
pInfo->libraryVersion.major = 0;
|
|
|
|
pInfo->libraryVersion.minor = 1;
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)
|
|
|
|
{
|
|
|
|
LOG("C_GetFunctionList(0x%x)\n", ppFunctionList);
|
|
|
|
*ppFunctionList = &function_list;
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV C_GetSlotList(CK_BBOOL tokenPresent, /* only slots with token present */
|
|
|
|
CK_SLOT_ID_PTR pSlotList, /* receives the array of slot IDs */
|
|
|
|
CK_ULONG_PTR pulCount) /* receives the number of slots */
|
|
|
|
{
|
|
|
|
int i, num;
|
|
|
|
|
|
|
|
LOG("C_GetSlotList(%d, 0x%x, 0x%x)\n", tokenPresent, pSlotList, pulCount);
|
|
|
|
|
|
|
|
if (pSlotList == NULL_PTR) {
|
2001-10-20 16:53:51 +00:00
|
|
|
*pulCount = ctx->reader_count;
|
2001-10-19 19:52:00 +00:00
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
|
2001-10-20 16:53:51 +00:00
|
|
|
num = ctx->reader_count > *pulCount ? *pulCount : ctx->reader_count;
|
2001-10-19 19:52:00 +00:00
|
|
|
for (i = 0; i < num; i++)
|
|
|
|
pSlotList[i] = i;
|
|
|
|
*pulCount = num;
|
|
|
|
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
|
|
|
|
{
|
|
|
|
LOG("C_GetSlotInfo(%d, 0x%x)\n", slotID, pInfo);
|
|
|
|
|
2001-10-20 16:53:51 +00:00
|
|
|
if (slotID < 0 || slotID >= ctx->reader_count)
|
2001-10-19 19:52:00 +00:00
|
|
|
return CKR_SLOT_ID_INVALID;
|
|
|
|
|
|
|
|
memset(pInfo, 0, sizeof(CK_SLOT_INFO));
|
2001-10-20 16:53:51 +00:00
|
|
|
strncpy(pInfo->slotDescription, ctx->readers[slotID],
|
2001-10-19 19:52:00 +00:00
|
|
|
sizeof(pInfo->slotDescription));
|
2001-10-20 16:53:51 +00:00
|
|
|
strcpy(pInfo->manufacturerID, "PC/SC interface");
|
2001-10-19 19:52:00 +00:00
|
|
|
pInfo->flags = CKF_REMOVABLE_DEVICE | CKF_HW_SLOT;
|
2001-10-20 16:53:51 +00:00
|
|
|
if (sc_detect_card(ctx, slotID) == 1)
|
|
|
|
pInfo->flags |= CKF_TOKEN_PRESENT;
|
|
|
|
else {
|
|
|
|
if (p15card != NULL) {
|
|
|
|
sc_disconnect_card(p15card->card);
|
|
|
|
sc_pkcs15_destroy(p15card);
|
|
|
|
p15card = NULL;
|
|
|
|
}
|
|
|
|
}
|
2001-10-19 19:52:00 +00:00
|
|
|
pInfo->hardwareVersion.major = 1;
|
|
|
|
pInfo->firmwareVersion.major = 1;
|
|
|
|
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
|
|
|
|
{
|
2001-10-20 16:53:51 +00:00
|
|
|
int r;
|
|
|
|
struct sc_card *card;
|
|
|
|
|
2001-10-19 19:52:00 +00:00
|
|
|
LOG("C_GetTokenInfo(%d, 0x%x)\n", slotID, pInfo);
|
2001-10-20 16:53:51 +00:00
|
|
|
if (slotID < 0 || slotID >= ctx->reader_count)
|
|
|
|
return CKR_SLOT_ID_INVALID;
|
|
|
|
|
|
|
|
memset(pInfo, 0, sizeof(CK_SLOT_INFO));
|
|
|
|
|
|
|
|
if (p15card == NULL) {
|
|
|
|
r = sc_connect_card(ctx, slotID, &card);
|
|
|
|
if (r)
|
|
|
|
return CKR_DEVICE_ERROR;
|
|
|
|
r = sc_pkcs15_init(card, &p15card);
|
|
|
|
if (r) {
|
|
|
|
/* PKCS#15 compatible SC probably not present */
|
|
|
|
sc_disconnect_card(card);
|
|
|
|
return CKR_DEVICE_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
strcpy(pInfo->label, p15card->label);
|
|
|
|
strcpy(pInfo->manufacturerID, "unknown");
|
|
|
|
strcpy(pInfo->model, "unknown");
|
|
|
|
strcpy(pInfo->serialNumber, "unknown");
|
|
|
|
pInfo->flags = CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED;
|
|
|
|
pInfo->ulMaxSessionCount = 1; /* opened in exclusive mode */
|
|
|
|
pInfo->ulSessionCount = 0;
|
|
|
|
pInfo->ulMaxRwSessionCount = 1;
|
|
|
|
pInfo->ulRwSessionCount = 0;
|
|
|
|
pInfo->ulMaxPinLen = 8; /* FIXME: get these from PIN objects */
|
|
|
|
pInfo->ulMinPinLen = 4;
|
|
|
|
pInfo->ulTotalPublicMemory = 0;
|
|
|
|
pInfo->ulFreePublicMemory = 0;
|
|
|
|
pInfo->ulTotalPrivateMemory = 0;
|
|
|
|
pInfo->ulFreePrivateMemory = 0;
|
|
|
|
pInfo->hardwareVersion.major = 1;
|
|
|
|
pInfo->hardwareVersion.minor = 0;
|
|
|
|
pInfo->firmwareVersion.major = 1;
|
|
|
|
pInfo->firmwareVersion.minor = 0;
|
|
|
|
|
|
|
|
return CKR_OK;
|
2001-10-19 19:52:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV C_GetMechanismList(CK_SLOT_ID slotID,
|
|
|
|
CK_MECHANISM_TYPE_PTR pMechanismList,
|
|
|
|
CK_ULONG_PTR pulCount)
|
|
|
|
{
|
|
|
|
LOG("C_GetMechanismList(%d, 0x%x, 0x%x)\n", slotID, pMechanismList, pulCount);
|
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV C_GetMechanismInfo(CK_SLOT_ID slotID,
|
|
|
|
CK_MECHANISM_TYPE type,
|
|
|
|
CK_MECHANISM_INFO_PTR pInfo)
|
|
|
|
{
|
|
|
|
LOG("C_GetMechanismInfo(%d, %d, 0x%x)\n", slotID, type, pInfo);
|
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV C_InitToken(CK_SLOT_ID slotID,
|
|
|
|
CK_CHAR_PTR pPin,
|
|
|
|
CK_ULONG ulPinLen,
|
|
|
|
CK_CHAR_PTR pLabel)
|
|
|
|
{
|
|
|
|
LOG("C_InitToken(%d, '%s', %d, '%s')\n", slotID, pPin, ulPinLen, pLabel);
|
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV C_SetPIN(CK_SESSION_HANDLE hSession,
|
|
|
|
CK_CHAR_PTR pOldPin,
|
|
|
|
CK_ULONG ulOldLen,
|
|
|
|
CK_CHAR_PTR pNewPin,
|
|
|
|
CK_ULONG ulNewLen)
|
|
|
|
{
|
|
|
|
LOG("C_SetPIN(%d, '%s', %d, '%s', %d)\n", hSession, pOldPin, ulOldLen, pNewPin, ulNewLen);
|
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
|
|
|
}
|