#include "config.h"
#include <stdlib.h>
#include <string.h>
#include "sc-pkcs11.h"
#ifdef USE_PKCS15_INIT
#include "pkcs15init/pkcs15-init.h"
static CK_RV pkcs15init_bind(struct sc_pkcs11_card *p11card, struct sc_app_info *app_info)
{
struct sc_card *card;
struct sc_profile *profile;
int rc;
if (!p11card)
return CKR_TOKEN_NOT_RECOGNIZED;
card = p11card->card;
rc = sc_pkcs15init_bind(card, "pkcs15", NULL, NULL, &profile);
if (rc == 0)
p11card->fws_data[0] = profile;
return sc_to_cryptoki_error(rc, NULL);
}
static CK_RV pkcs15init_unbind(struct sc_pkcs11_card *p11card)
{
struct sc_profile *profile;
if (!p11card)
return CKR_TOKEN_NOT_RECOGNIZED;
profile = (struct sc_profile *) p11card->fws_data[0];
sc_pkcs15init_unbind(profile);
return CKR_OK;
}
static CK_RV
pkcs15init_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app_info)
{
struct sc_profile *profile;
struct sc_pkcs11_slot *slot;
CK_RV rc;
if (!p11card)
return CKR_TOKEN_NOT_RECOGNIZED;
profile = (struct sc_profile *) p11card->fws_data[0];
rc = slot_allocate(&slot, p11card);
if (rc == CKR_OK) {
CK_TOKEN_INFO_PTR pToken = &slot->token_info;
const char *string;
slot->slot_info.flags |= CKF_TOKEN_PRESENT;
strcpy_bp(pToken->model, "PKCS #15 SCard", 16);
sc_pkcs15init_get_manufacturer(profile, &string);
if (!string)
string = "Unknown";
strcpy_bp(pToken->manufacturerID, string, 32);
sc_pkcs15init_get_serial(profile, &string);
if (!string)
string = "";
strcpy_bp(pToken->serialNumber, string, 16);
pToken->ulMaxSessionCount = CK_EFFECTIVELY_INFINITE;
pToken->ulSessionCount = 0;
pToken->ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE;
pToken->ulRwSessionCount = 0;
pToken->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION;
pToken->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION;
pToken->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION;
pToken->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION;
pToken->hardwareVersion.major = 0;
pToken->hardwareVersion.minor = 0;
pToken->firmwareVersion.major = 0;
pToken->firmwareVersion.minor = 0;
}
return CKR_OK;
}
static CK_RV
pkcs15init_release_token(struct sc_pkcs11_card *p11card, void *ptr)
{
return CKR_OK;
}
static CK_RV
pkcs15init_login(struct sc_pkcs11_slot *slot,
CK_USER_TYPE user, CK_CHAR_PTR pin, CK_ULONG pinLength)
{
return CKR_CRYPTOKI_NOT_INITIALIZED;
}
static CK_RV
pkcs15init_logout(struct sc_pkcs11_slot *slot)
{
return CKR_CRYPTOKI_NOT_INITIALIZED;
}
static CK_RV
pkcs15init_change_pin(struct sc_pkcs11_slot *slot,
CK_CHAR_PTR oldPin, CK_ULONG oldPinLength,
CK_CHAR_PTR newPin, CK_ULONG newPinLength)
{
return CKR_CRYPTOKI_NOT_INITIALIZED;
}
static CK_RV
pkcs15init_initialize(struct sc_pkcs11_slot *pslot, void *ptr,
CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen,
CK_UTF8CHAR_PTR pLabel)
{
struct sc_pkcs11_card *p11card = pslot->p11card;
struct sc_profile *profile;
struct sc_pkcs15init_initargs args;
struct sc_pkcs11_slot *slot;
CK_RV rv;
int rc, id;
if (!p11card)
return CKR_TOKEN_NOT_RECOGNIZED;
profile = (struct sc_profile *) p11card->fws_data[0];
memset(&args, 0, sizeof(args));
args.so_pin = pPin;
args.so_pin_len = ulPinLen;
args.so_puk = pPin;
args.so_puk_len = ulPinLen;
args.label = (const char *) pLabel;
rc = sc_pkcs15init_add_app(p11card->card, profile, &args);
if (rc < 0)
return sc_to_cryptoki_error(rc, NULL);
if ((rv = framework_pkcs15.bind(p11card, NULL)) != CKR_OK) {
p11card->fws_data[0] = profile;
return rv;
}
p11card->framework = &framework_pkcs15;
for (id = 0; slot_get_slot(id, &slot) == CKR_OK; id++) {
if (slot->p11card == p11card)
slot->token_info.flags |= CKF_TOKEN_INITIALIZED;
if (slot->p11card->card->caps & SC_CARD_CAP_RNG)
slot->token_info.flags |= CKF_RNG;
}
sc_pkcs15init_unbind(profile);
return CKR_OK;
}
struct sc_pkcs11_framework_ops framework_pkcs15init = {
pkcs15init_bind,
pkcs15init_unbind,
pkcs15init_create_tokens,
pkcs15init_release_token,
pkcs15init_login,
pkcs15init_logout,
pkcs15init_change_pin,
pkcs15init_initialize,
NULL,
NULL,
NULL,
NULL
};
#else
struct sc_pkcs11_framework_ops framework_pkcs15init = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
#endif