pkcs11: create tokens and slots for multiple on-card applications
In card detection procedure bind all present applications and create tokens for them. Treatement of the different 'create-slots' configuration cases, joining the objects from different applications into one slot are previewed for the next commits.
This commit is contained in:
parent
80266ff466
commit
343fa20a00
|
@ -153,58 +153,115 @@ static int reselect_app_df(sc_pkcs15_card_t *p15card);
|
|||
static CK_RV set_gost_params(struct sc_pkcs15init_keyarg_gost_params *,
|
||||
struct sc_pkcs15init_keyarg_gost_params *,
|
||||
CK_ATTRIBUTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG);
|
||||
/* PKCS#15 Framework */
|
||||
|
||||
static CK_RV pkcs15_bind(struct sc_pkcs11_card *p11card, struct sc_app_info *app_info)
|
||||
/* Returns forst available WF data or WF data corresponding to the given application */
|
||||
static struct pkcs15_fw_data *
|
||||
get_fw_data(struct sc_pkcs11_card *p11card, struct sc_app_info *app_info, int *out_idx)
|
||||
{
|
||||
struct pkcs15_fw_data *fw_data;
|
||||
int rc;
|
||||
CK_RV rv;
|
||||
struct pkcs15_fw_data *out = NULL;
|
||||
int idx;
|
||||
|
||||
for (idx=0; idx < SC_PKCS11_FRAMEWORK_DATA_MAX_NUM; idx++) {
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[idx];
|
||||
struct sc_file *file_app = NULL;
|
||||
|
||||
if (!fw_data || !fw_data->p15_card)
|
||||
continue;
|
||||
|
||||
if (app_info) {
|
||||
file_app = fw_data->p15_card->file_app;
|
||||
if (file_app->path.len != app_info->path.len)
|
||||
continue;
|
||||
if (file_app->path.aid.len != app_info->path.aid.len)
|
||||
continue;
|
||||
if (memcmp(file_app->path.aid.value, app_info->path.aid.value, app_info->path.aid.len))
|
||||
continue;
|
||||
if (memcmp(file_app->path.value, app_info->path.value, app_info->path.len))
|
||||
continue;
|
||||
}
|
||||
|
||||
out = fw_data;
|
||||
if (out_idx)
|
||||
*out_idx = idx;
|
||||
break;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/* PKCS#15 Framework */
|
||||
static CK_RV
|
||||
pkcs15_bind(struct sc_pkcs11_card *p11card, struct sc_app_info *app_info)
|
||||
{
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
struct sc_aid *aid = app_info ? &app_info->aid : NULL;
|
||||
int rc, idx;
|
||||
CK_RV ck_rv;
|
||||
|
||||
sc_log(context, "Bind PKCS#15 '%s' application", app_info ? app_info->label : "<anonymous>");
|
||||
for (idx=0; idx<SC_PKCS11_FRAMEWORK_DATA_MAX_NUM; idx++)
|
||||
if (!p11card->fws_data[idx])
|
||||
break;
|
||||
if (idx == SC_PKCS11_FRAMEWORK_DATA_MAX_NUM)
|
||||
return CKR_USER_TOO_MANY_TYPES;
|
||||
|
||||
if (!(fw_data = calloc(1, sizeof(*fw_data))))
|
||||
return CKR_HOST_MEMORY;
|
||||
p11card->fws_data[0] = fw_data;
|
||||
p11card->fws_data[idx] = fw_data;
|
||||
|
||||
rc = sc_pkcs15_bind(p11card->card, NULL, &fw_data->p15_card);
|
||||
rc = sc_pkcs15_bind(p11card->card, aid, &fw_data->p15_card);
|
||||
if (rc != SC_SUCCESS) {
|
||||
sc_log(context, "sc_pkcs15_bind failed: %d", rc);
|
||||
return sc_to_cryptoki_error(rc, NULL);
|
||||
}
|
||||
|
||||
rv = register_mechanisms(p11card);
|
||||
if (rv != CKR_OK) {
|
||||
sc_log(context, "register_mechanisms failed: 0x%x", rv);
|
||||
return rv;
|
||||
ck_rv = register_mechanisms(p11card);
|
||||
if (ck_rv != CKR_OK) {
|
||||
sc_log(context, "cannot register mechanisms; CKR 0x%X", ck_rv);
|
||||
return ck_rv;
|
||||
}
|
||||
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
static CK_RV pkcs15_unbind(struct sc_pkcs11_card *p11card)
|
||||
|
||||
static CK_RV
|
||||
pkcs15_unbind(struct sc_pkcs11_card *p11card)
|
||||
{
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
|
||||
unsigned int i;
|
||||
int rc;
|
||||
unsigned int i, idx;
|
||||
int rv = SC_SUCCESS;
|
||||
|
||||
for (i = 0; i < fw_data->num_objects; i++) {
|
||||
struct pkcs15_any_object *obj = fw_data->objects[i];
|
||||
for (idx=0; idx<SC_PKCS11_FRAMEWORK_DATA_MAX_NUM; idx++) {
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[idx];
|
||||
|
||||
/* use object specific release method if existing */
|
||||
if (obj->base.ops && obj->base.ops->release)
|
||||
obj->base.ops->release(obj);
|
||||
else
|
||||
__pkcs15_release_object(obj);
|
||||
if (!fw_data)
|
||||
break;
|
||||
for (i = 0; i < fw_data->num_objects; i++) {
|
||||
struct pkcs15_any_object *obj = fw_data->objects[i];
|
||||
|
||||
/* use object specific release method if existing */
|
||||
if (obj->base.ops && obj->base.ops->release)
|
||||
obj->base.ops->release(obj);
|
||||
else
|
||||
__pkcs15_release_object(obj);
|
||||
}
|
||||
|
||||
unlock_card(fw_data);
|
||||
|
||||
if (fw_data->p15_card)
|
||||
rv = sc_pkcs15_unbind(fw_data->p15_card);
|
||||
fw_data->p15_card = NULL;
|
||||
|
||||
free(fw_data);
|
||||
p11card->fws_data[idx] = NULL;
|
||||
}
|
||||
|
||||
unlock_card(fw_data);
|
||||
|
||||
rc = sc_pkcs15_unbind(fw_data->p15_card);
|
||||
free(fw_data);
|
||||
return sc_to_cryptoki_error(rc, NULL);
|
||||
return sc_to_cryptoki_error(rv, NULL);
|
||||
}
|
||||
|
||||
static void pkcs15_init_token_info(struct sc_pkcs15_card *p15card, CK_TOKEN_INFO_PTR pToken)
|
||||
|
||||
static void
|
||||
pkcs15_init_token_info(struct sc_pkcs15_card *p15card, CK_TOKEN_INFO_PTR pToken)
|
||||
{
|
||||
strcpy_bp(pToken->manufacturerID, p15card->tokeninfo->manufacturer_id, 32);
|
||||
if (p15card->flags & SC_PKCS15_CARD_FLAG_EMULATED)
|
||||
|
@ -765,7 +822,7 @@ pkcs15_add_object(struct sc_pkcs11_slot *slot,
|
|||
case SC_PKCS15_TYPE_PRKEY_GOSTR3410:
|
||||
case SC_PKCS15_TYPE_PRKEY_EC:
|
||||
pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_pubkey, NULL);
|
||||
card_fw_data = (struct pkcs15_fw_data *) slot->card->fws_data[0];
|
||||
card_fw_data = (struct pkcs15_fw_data *) slot->card->fws_data[slot->fw_data_idx];
|
||||
for (i = 0; i < card_fw_data->num_objects; i++) {
|
||||
struct pkcs15_any_object *obj2 = card_fw_data->objects[i];
|
||||
struct pkcs15_cert_object *cert;
|
||||
|
@ -790,9 +847,12 @@ pkcs15_add_object(struct sc_pkcs11_slot *slot,
|
|||
obj->base.flags &= ~SC_PKCS11_OBJECT_RECURS;
|
||||
}
|
||||
|
||||
static void pkcs15_init_slot(struct sc_pkcs15_card *p15card,
|
||||
|
||||
static void
|
||||
pkcs15_init_slot(struct sc_pkcs15_card *p15card,
|
||||
struct sc_pkcs11_slot *slot,
|
||||
struct sc_pkcs15_object *auth)
|
||||
struct sc_pkcs15_object *auth,
|
||||
struct sc_app_info *app_info)
|
||||
{
|
||||
struct pkcs15_slot_data *fw_data;
|
||||
struct sc_pkcs15_auth_info *pin_info = NULL;
|
||||
|
@ -832,22 +892,28 @@ static void pkcs15_init_slot(struct sc_pkcs15_card *p15card,
|
|||
if (pin_info) {
|
||||
slot->token_info.ulMaxPinLen = pin_info->attrs.pin.max_length;
|
||||
slot->token_info.ulMinPinLen = pin_info->attrs.pin.min_length;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/* choose reasonable defaults */
|
||||
slot->token_info.ulMaxPinLen = 8;
|
||||
slot->token_info.ulMinPinLen = 4;
|
||||
}
|
||||
|
||||
if (p15card->flags & SC_PKCS15_CARD_FLAG_EMULATED)
|
||||
slot->token_info.flags |= CKF_WRITE_PROTECTED;
|
||||
|
||||
if (app_info)
|
||||
slot->app_info = app_info;
|
||||
|
||||
sc_log(context, "Initialized token '%s' in slot 0x%lx", tmp, slot->id);
|
||||
}
|
||||
|
||||
static CK_RV pkcs15_create_slot(struct sc_pkcs11_card *p11card,
|
||||
struct pkcs15_fw_data *fw_data,
|
||||
struct sc_pkcs15_object *auth,
|
||||
struct sc_app_info *app_info,
|
||||
struct sc_pkcs11_slot **out)
|
||||
{
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
|
||||
struct sc_pkcs11_slot *slot;
|
||||
int rv;
|
||||
|
||||
|
@ -859,7 +925,7 @@ static CK_RV pkcs15_create_slot(struct sc_pkcs11_card *p11card,
|
|||
slot->slot_info.flags |= CKF_TOKEN_PRESENT;
|
||||
|
||||
/* Fill in the slot/token info from pkcs15 data */
|
||||
pkcs15_init_slot(fw_data->p15_card, slot, auth);
|
||||
pkcs15_init_slot(fw_data->p15_card, slot, auth, app_info);
|
||||
|
||||
*out = slot;
|
||||
return CKR_OK;
|
||||
|
@ -870,21 +936,28 @@ static CK_RV
|
|||
pkcs15_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app_info,
|
||||
struct sc_pkcs11_slot **first_slot)
|
||||
{
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
|
||||
struct sc_pkcs15_object *auths[MAX_OBJECTS];
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
struct sc_pkcs15_object *auths[SC_PKCS15_MAX_PINS];
|
||||
struct sc_pkcs11_slot *slot = NULL;
|
||||
int i, rv;
|
||||
int auth_count;
|
||||
int found_auth_count = 0;
|
||||
int auth_count, found_auth_count = 0;
|
||||
int i, rv, idx;
|
||||
unsigned int j;
|
||||
|
||||
rv = sc_pkcs15_get_objects(fw_data->p15_card,
|
||||
SC_PKCS15_TYPE_AUTH_PIN,
|
||||
auths,
|
||||
SC_PKCS15_MAX_PINS);
|
||||
sc_log(context, "create PKCS#15 tokens; fws:%p,%p,%p",
|
||||
p11card->fws_data[0], p11card->fws_data[1], p11card->fws_data[2]);
|
||||
sc_log(context, "CreateSlotsFlags: 0x%X", sc_pkcs11_conf.create_slots_flags);
|
||||
|
||||
/* Find out framework data corresponding to the given application */
|
||||
fw_data = get_fw_data(p11card, app_info, &idx);
|
||||
if (!fw_data)
|
||||
return sc_to_cryptoki_error(SC_ERROR_PKCS15_APP_NOT_FOUND, NULL);
|
||||
sc_log(context, "Use FW data with index %i; fw_data->p15_card %p", idx, fw_data->p15_card);
|
||||
|
||||
rv = sc_pkcs15_get_objects(fw_data->p15_card, SC_PKCS15_TYPE_AUTH_PIN,
|
||||
auths, SC_PKCS15_MAX_PINS);
|
||||
if (rv < 0)
|
||||
return sc_to_cryptoki_error(rv, NULL);
|
||||
sc_log(context, "Found %d authentication objects\n", rv);
|
||||
sc_log(context, "Found %d authentication objects", rv);
|
||||
auth_count = rv;
|
||||
|
||||
rv = pkcs15_create_pkcs11_objects(fw_data,
|
||||
|
@ -974,7 +1047,7 @@ pkcs15_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app_inf
|
|||
|
||||
found_auth_count++;
|
||||
|
||||
rv = pkcs15_create_slot(p11card, auths[i], &slot);
|
||||
rv = pkcs15_create_slot(p11card, fw_data, auths[i], app_info, &slot);
|
||||
if (rv != CKR_OK)
|
||||
return CKR_OK; /* no more slots available for this card */
|
||||
|
||||
|
@ -1007,6 +1080,9 @@ pkcs15_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app_inf
|
|||
}
|
||||
}
|
||||
|
||||
if (slot)
|
||||
slot->fw_data_idx = idx;
|
||||
|
||||
auth_count = found_auth_count;
|
||||
|
||||
/* Add all public objects to a virtual slot without pin protection.
|
||||
|
@ -1027,7 +1103,7 @@ pkcs15_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app_inf
|
|||
sc_log(context, "%d: Object ('%s',type:%X) was not seen previously\n", j,
|
||||
obj->p15_object->label, obj->p15_object->type);
|
||||
if (!slot) {
|
||||
rv = pkcs15_create_slot(p11card, NULL, &slot);
|
||||
rv = pkcs15_create_slot(p11card, fw_data, NULL, app_info, &slot);
|
||||
if (rv != CKR_OK)
|
||||
return CKR_OK; /* no more slots available for this card */
|
||||
}
|
||||
|
@ -1051,9 +1127,14 @@ pkcs15_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app_inf
|
|||
|
||||
static CK_RV pkcs15_release_token(struct sc_pkcs11_card *p11card, void *fw_token)
|
||||
{
|
||||
#if 0
|
||||
unlock_card((struct pkcs15_fw_data *) p11card->fws_data[0]);
|
||||
free(fw_token);
|
||||
return CKR_OK;
|
||||
#else
|
||||
sc_log(context, "pkcs15_release_token() not implemented");
|
||||
return CKR_FUNCTION_REJECTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
static CK_RV pkcs15_login(struct sc_pkcs11_slot *slot,
|
||||
|
@ -1063,11 +1144,12 @@ static CK_RV pkcs15_login(struct sc_pkcs11_slot *slot,
|
|||
{
|
||||
int rc;
|
||||
struct sc_pkcs11_card *p11card = slot->card;
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
struct sc_pkcs15_card *p15card = fw_data->p15_card;
|
||||
struct sc_pkcs15_object *auth_object;
|
||||
struct sc_pkcs15_auth_info *pin_info;
|
||||
|
||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx];
|
||||
switch (userType) {
|
||||
case CKU_USER:
|
||||
auth_object = slot_data_auth(slot->fw_data);
|
||||
|
@ -1123,7 +1205,7 @@ static CK_RV pkcs15_login(struct sc_pkcs11_slot *slot,
|
|||
/* For a while, used only to unblock User PIN. */
|
||||
rc = 0;
|
||||
if (sc_pkcs11_conf.lock_login)
|
||||
rc = lock_card(fw_data);
|
||||
rc = lock_card(fw_data);
|
||||
#if 0
|
||||
/* TODO: Look for pkcs15 auth object with 'unblockingPin' flag activated.
|
||||
* If exists, do verification of PIN (in fact PUK). */
|
||||
|
@ -1242,10 +1324,12 @@ static CK_RV pkcs15_login(struct sc_pkcs11_slot *slot,
|
|||
static CK_RV pkcs15_logout(struct sc_pkcs11_slot *slot)
|
||||
{
|
||||
struct sc_pkcs11_card *p11card = slot->card;
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
CK_RV ret = CKR_OK;
|
||||
int rc;
|
||||
|
||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx];
|
||||
|
||||
memset(fw_data->user_puk, 0, sizeof(fw_data->user_puk));
|
||||
fw_data->user_puk_len = 0;
|
||||
|
||||
|
@ -1278,7 +1362,7 @@ pkcs15_change_pin(struct sc_pkcs11_slot *slot,
|
|||
struct sc_pkcs11_card *p11card = slot->card;
|
||||
void *fw_token = slot->fw_data;
|
||||
int login_user = slot->login_user;
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
struct sc_pkcs15_auth_info *auth_info;
|
||||
struct sc_pkcs15_object *pin_obj;
|
||||
int rc;
|
||||
|
@ -1289,6 +1373,8 @@ pkcs15_change_pin(struct sc_pkcs11_slot *slot,
|
|||
if (!(auth_info = slot_data_auth_info(fw_token)))
|
||||
return CKR_USER_PIN_NOT_INITIALIZED;
|
||||
|
||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx];
|
||||
|
||||
sc_log(context, "Change '%s', reference %i; login type %i",
|
||||
pin_obj->label, auth_info->attrs.pin.reference, login_user);
|
||||
if (p11card->card->reader->capabilities & SC_READER_CAP_PIN_PAD) {
|
||||
|
@ -1331,8 +1417,8 @@ pkcs15_change_pin(struct sc_pkcs11_slot *slot,
|
|||
return sc_to_cryptoki_error(rc, "C_SetPIN");
|
||||
auth_count = rc;
|
||||
for (i = 0; i < auth_count; i++) {
|
||||
auth_info = (struct sc_pkcs15_auth_info*) auths[i]->data;
|
||||
if ((auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN))
|
||||
auth_info = (struct sc_pkcs15_auth_info*) auths[i]->data;
|
||||
if ((auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN))
|
||||
break;
|
||||
}
|
||||
if (i == auth_count) {
|
||||
|
@ -1356,7 +1442,7 @@ static CK_RV
|
|||
pkcs15_init_pin(struct sc_pkcs11_slot *slot, CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
|
||||
{
|
||||
struct sc_pkcs11_card *p11card = slot->card;
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
struct sc_pkcs15init_pinargs args;
|
||||
struct sc_profile *profile;
|
||||
struct sc_pkcs15_object *auth_obj;
|
||||
|
@ -1366,6 +1452,7 @@ pkcs15_init_pin(struct sc_pkcs11_slot *slot, CK_CHAR_PTR pPin, CK_ULONG ulPinLen
|
|||
sc_log(context, "pkcs15 init PIN: pin %p:%d; unblock style %i",
|
||||
pPin, ulPinLen, sc_pkcs11_conf.pin_unblock_style);
|
||||
|
||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx];
|
||||
auth_info = slot_data_auth_info(slot->fw_data);
|
||||
if (auth_info && sc_pkcs11_conf.pin_unblock_style == SC_PKCS11_PIN_UNBLOCK_SO_LOGGED_INITPIN) {
|
||||
/* C_InitPIN is used to unblock User PIN or set it in the SO session .*/
|
||||
|
@ -1412,7 +1499,7 @@ pkcs15_init_pin(struct sc_pkcs11_slot *slot, CK_CHAR_PTR pPin, CK_ULONG ulPinLen
|
|||
|
||||
/* Re-initialize the slot */
|
||||
free(slot->fw_data);
|
||||
pkcs15_init_slot(fw_data->p15_card, slot, auth_obj);
|
||||
pkcs15_init_slot(fw_data->p15_card, slot, auth_obj, slot->app_info);
|
||||
|
||||
auth_info = (sc_pkcs15_auth_info_t *) auth_obj->data;
|
||||
return CKR_OK;
|
||||
|
@ -1438,7 +1525,7 @@ pkcs15_create_private_key(struct sc_pkcs11_slot *slot,
|
|||
CK_OBJECT_HANDLE_PTR phObject)
|
||||
{
|
||||
struct sc_pkcs11_card *p11card = slot->card;
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
struct sc_pkcs15init_prkeyargs args;
|
||||
struct pkcs15_any_object *key_any_obj;
|
||||
struct sc_pkcs15_object *key_obj;
|
||||
|
@ -1563,6 +1650,7 @@ pkcs15_create_private_key(struct sc_pkcs11_slot *slot,
|
|||
}
|
||||
}
|
||||
|
||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx];
|
||||
rc = sc_pkcs15init_store_private_key(fw_data->p15_card, profile, &args, &key_obj);
|
||||
if (rc < 0) {
|
||||
rv = sc_to_cryptoki_error(rc, "C_CreateObject");
|
||||
|
@ -1586,7 +1674,7 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot,
|
|||
CK_OBJECT_HANDLE_PTR phObject)
|
||||
{
|
||||
struct sc_pkcs11_card *p11card = slot->card;
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
struct sc_pkcs15init_pubkeyargs args;
|
||||
struct pkcs15_any_object *key_any_obj;
|
||||
struct sc_pkcs15_object *key_obj;
|
||||
|
@ -1662,6 +1750,7 @@ pkcs15_create_public_key(struct sc_pkcs11_slot *slot,
|
|||
goto out;
|
||||
}
|
||||
|
||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx];
|
||||
rc = sc_pkcs15init_store_public_key(fw_data->p15_card, profile, &args, &key_obj);
|
||||
if (rc < 0) {
|
||||
rv = sc_to_cryptoki_error(rc, "C_CreateObject");
|
||||
|
@ -1685,7 +1774,7 @@ pkcs15_create_certificate(struct sc_pkcs11_slot *slot,
|
|||
CK_OBJECT_HANDLE_PTR phObject)
|
||||
{
|
||||
struct sc_pkcs11_card *p11card = slot->card;
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
struct sc_pkcs15init_certargs args;
|
||||
struct pkcs15_any_object *cert_any_obj;
|
||||
struct sc_pkcs15_object *cert_obj;
|
||||
|
@ -1743,6 +1832,7 @@ pkcs15_create_certificate(struct sc_pkcs11_slot *slot,
|
|||
goto out;
|
||||
}
|
||||
|
||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx];
|
||||
rc = sc_pkcs15init_store_certificate(fw_data->p15_card, profile, &args, &cert_obj);
|
||||
if (rc < 0) {
|
||||
rv = sc_to_cryptoki_error(rc, "C_CreateObject");
|
||||
|
@ -1765,7 +1855,7 @@ pkcs15_create_data(struct sc_pkcs11_slot *slot,
|
|||
CK_OBJECT_HANDLE_PTR phObject)
|
||||
{
|
||||
struct sc_pkcs11_card *p11card = slot->card;
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
struct sc_pkcs15init_dataargs args;
|
||||
struct pkcs15_any_object *data_any_obj;
|
||||
struct sc_pkcs15_object *data_obj;
|
||||
|
@ -1828,6 +1918,7 @@ pkcs15_create_data(struct sc_pkcs11_slot *slot,
|
|||
goto out;
|
||||
}
|
||||
|
||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx];
|
||||
rc = sc_pkcs15init_store_data_object(fw_data->p15_card, profile, &args, &data_obj);
|
||||
if (rc < 0) {
|
||||
rv = sc_to_cryptoki_error(rc, "C_CreateObject");
|
||||
|
@ -1990,7 +2081,7 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot,
|
|||
struct sc_profile *profile = NULL;
|
||||
struct sc_pkcs11_card *p11card = slot->card;
|
||||
struct sc_pkcs15_auth_info *pin;
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
struct sc_pkcs15init_keygen_args keygen_args;
|
||||
struct sc_pkcs15init_pubkeyargs pub_args;
|
||||
struct sc_pkcs15_object *priv_key_obj;
|
||||
|
@ -2099,8 +2190,7 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot,
|
|||
pub_args.label = pub_label;
|
||||
}
|
||||
|
||||
rv = get_X509_usage_privk(pPrivTpl, ulPrivCnt,
|
||||
&keygen_args.prkey_args.x509_usage);
|
||||
rv = get_X509_usage_privk(pPrivTpl, ulPrivCnt, &keygen_args.prkey_args.x509_usage);
|
||||
if (rv == CKR_OK)
|
||||
rv = get_X509_usage_pubk(pPubTpl, ulPubCnt,
|
||||
&keygen_args.prkey_args.x509_usage);
|
||||
|
@ -2109,7 +2199,7 @@ pkcs15_gen_keypair(struct sc_pkcs11_slot *slot,
|
|||
pub_args.x509_usage = keygen_args.prkey_args.x509_usage;
|
||||
|
||||
/* 3.a Try on-card key pair generation */
|
||||
|
||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx];
|
||||
sc_pkcs15init_set_p15card(profile, fw_data->p15_card);
|
||||
|
||||
sc_log(context, "Try on-card key pair generation");
|
||||
|
@ -2160,19 +2250,26 @@ static CK_RV pkcs15_any_destroy(struct sc_pkcs11_session *session, void *object)
|
|||
#else
|
||||
struct pkcs15_data_object *obj = (struct pkcs15_data_object*) object;
|
||||
struct pkcs15_any_object *any_obj = (struct pkcs15_any_object*) object;
|
||||
struct sc_pkcs11_card *card = session->slot->card;
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) card->fws_data[0];
|
||||
struct sc_pkcs11_card *p11card = session->slot->card;
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
struct sc_profile *profile = NULL;
|
||||
int rv;
|
||||
|
||||
rv = sc_lock(card->card);
|
||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx];
|
||||
rv = sc_lock(p11card->card);
|
||||
if (rv < 0)
|
||||
return sc_to_cryptoki_error(rv, "C_DestroyObject");
|
||||
|
||||
/* Bind the profile */
|
||||
rv = sc_pkcs15init_bind(card->card, "pkcs15", NULL, &profile);
|
||||
rv = sc_pkcs15init_bind(p11card->card, "pkcs15", NULL, &profile);
|
||||
if (rv < 0) {
|
||||
sc_unlock(card->card);
|
||||
sc_unlock(p11card->card);
|
||||
return sc_to_cryptoki_error(rv, "C_DestroyObject");
|
||||
}
|
||||
|
||||
rv = sc_pkcs15init_finalize_profile(p11card->card, profile, NULL);
|
||||
if (rv != CKR_OK) {
|
||||
sc_log(context, "Cannot finalize profile: %i", rv);
|
||||
return sc_to_cryptoki_error(rv, "C_DestroyObject");
|
||||
}
|
||||
|
||||
|
@ -2187,7 +2284,7 @@ static CK_RV pkcs15_any_destroy(struct sc_pkcs11_session *session, void *object)
|
|||
}
|
||||
|
||||
sc_pkcs15init_unbind(profile);
|
||||
sc_unlock(card->card);
|
||||
sc_unlock(p11card->card);
|
||||
|
||||
if (rv < 0)
|
||||
return sc_to_cryptoki_error(rv, "C_DestroyObject");
|
||||
|
@ -2201,10 +2298,12 @@ static CK_RV pkcs15_get_random(struct sc_pkcs11_slot *slot,
|
|||
CK_BYTE_PTR p, CK_ULONG len)
|
||||
{
|
||||
struct sc_pkcs11_card *p11card = slot->card;
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
|
||||
struct sc_card *card = fw_data->p15_card->card;
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
struct sc_card *card = NULL;
|
||||
int rc;
|
||||
|
||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx];
|
||||
card = fw_data->p15_card->card;
|
||||
rc = sc_get_challenge(card, p, (size_t)len);
|
||||
return sc_to_cryptoki_error(rc, "C_GenerateRandom");
|
||||
}
|
||||
|
@ -2238,12 +2337,14 @@ static CK_RV pkcs15_set_attrib(struct sc_pkcs11_session *session,
|
|||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
#else
|
||||
struct sc_profile *profile = NULL;
|
||||
struct sc_pkcs11_slot *slot = session->slot;
|
||||
struct sc_pkcs11_card *p11card = session->slot->card;
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
struct sc_pkcs15_id id;
|
||||
int rc = 0;
|
||||
CK_RV rv = CKR_OK;
|
||||
|
||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx];
|
||||
rc = sc_lock(p11card->card);
|
||||
if (rc < 0)
|
||||
return sc_to_cryptoki_error(rc, "C_SetAttributeValue");
|
||||
|
@ -2314,10 +2415,12 @@ static CK_RV pkcs15_cert_get_attribute(struct sc_pkcs11_session *session,
|
|||
void *object,
|
||||
CK_ATTRIBUTE_PTR attr)
|
||||
{
|
||||
struct sc_pkcs11_card *p11card = session->slot->card;
|
||||
struct pkcs15_cert_object *cert = (struct pkcs15_cert_object*) object;
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) session->slot->card->fws_data[0];
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
size_t len;
|
||||
|
||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx];
|
||||
switch (attr->type) {
|
||||
case CKA_CLASS:
|
||||
check_attribute_buffer(attr, sizeof(CK_OBJECT_CLASS));
|
||||
|
@ -2402,10 +2505,12 @@ pkcs15_cert_cmp_attribute(struct sc_pkcs11_session *session,
|
|||
CK_ATTRIBUTE_PTR attr)
|
||||
{
|
||||
struct pkcs15_cert_object *cert = (struct pkcs15_cert_object*) object;
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) session->slot->card->fws_data[0];
|
||||
struct sc_pkcs11_card *p11card = session->slot->card;
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
u8 *data;
|
||||
size_t len;
|
||||
|
||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx];
|
||||
switch (attr->type) {
|
||||
/* Check the issuer. Some pkcs11 callers (i.e. netscape) will pass
|
||||
* in the ASN.1 encoded SEQUENCE OF SET ... while OpenSC just
|
||||
|
@ -2469,12 +2574,14 @@ static CK_RV pkcs15_prkey_set_attribute(struct sc_pkcs11_session *session,
|
|||
return pkcs15_set_attrib(session, prkey->base.p15_object, attr);
|
||||
}
|
||||
|
||||
static CK_RV pkcs15_prkey_get_attribute(struct sc_pkcs11_session *session,
|
||||
void *object,
|
||||
CK_ATTRIBUTE_PTR attr)
|
||||
|
||||
static CK_RV
|
||||
pkcs15_prkey_get_attribute(struct sc_pkcs11_session *session,
|
||||
void *object, CK_ATTRIBUTE_PTR attr)
|
||||
{
|
||||
struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object*) object;
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) session->slot->card->fws_data[0];
|
||||
struct sc_pkcs11_card *p11card = session->slot->card;
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
struct sc_pkcs15_pubkey *key = NULL;
|
||||
unsigned int usage;
|
||||
size_t len;
|
||||
|
@ -2491,6 +2598,7 @@ static CK_RV pkcs15_prkey_get_attribute(struct sc_pkcs11_session *session,
|
|||
* applications assume they can get that from the private
|
||||
* key, something PKCS#11 doesn't guarantee.
|
||||
*/
|
||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx];
|
||||
if ((attr->type == CKA_MODULUS) || (attr->type == CKA_PUBLIC_EXPONENT) ||
|
||||
((attr->type == CKA_MODULUS_BITS) && (prkey->prv_p15obj->type == SC_PKCS15_TYPE_PRKEY_EC)) ||
|
||||
(attr->type == CKA_ECDSA_PARAMS)) {
|
||||
|
@ -2634,23 +2742,27 @@ static CK_RV pkcs15_prkey_get_attribute(struct sc_pkcs11_session *session,
|
|||
return CKR_OK;
|
||||
}
|
||||
|
||||
static CK_RV pkcs15_prkey_sign(struct sc_pkcs11_session *ses, void *obj,
|
||||
|
||||
static CK_RV
|
||||
pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj,
|
||||
CK_MECHANISM_PTR pMechanism, CK_BYTE_PTR pData,
|
||||
CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
|
||||
CK_ULONG_PTR pulDataLen)
|
||||
{
|
||||
struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object *) obj;
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) ses->slot->card->fws_data[0];
|
||||
struct sc_pkcs11_card *p11card = session->slot->card;
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
int rv, flags = 0;
|
||||
unsigned sign_flags = SC_PKCS15_PRKEY_USAGE_SIGN
|
||||
| SC_PKCS15_PRKEY_USAGE_SIGNRECOVER
|
||||
| SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
|
||||
|
||||
sc_log(context, "Initiating signing operation, mechanism 0x%x.\n",
|
||||
pMechanism->mechanism);
|
||||
|
||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx];
|
||||
/* See which of the alternative keys supports signing */
|
||||
while (prkey
|
||||
&& !(prkey->prv_info->usage
|
||||
& (SC_PKCS15_PRKEY_USAGE_SIGN|SC_PKCS15_PRKEY_USAGE_SIGNRECOVER|
|
||||
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION)))
|
||||
while (prkey && !(prkey->prv_info->usage & sign_flags))
|
||||
prkey = prkey->prv_next;
|
||||
|
||||
if (prkey == NULL)
|
||||
|
@ -2712,19 +2824,19 @@ static CK_RV pkcs15_prkey_sign(struct sc_pkcs11_session *ses, void *obj,
|
|||
return CKR_MECHANISM_INVALID;
|
||||
}
|
||||
|
||||
rv = sc_lock(ses->slot->card->card);
|
||||
rv = sc_lock(p11card->card);
|
||||
if (rv < 0)
|
||||
return sc_to_cryptoki_error(rv, "C_Sign");
|
||||
|
||||
if (!sc_pkcs11_conf.lock_login) {
|
||||
rv = reselect_app_df(fw_data->p15_card);
|
||||
if (rv < 0) {
|
||||
sc_unlock(ses->slot->card->card);
|
||||
sc_unlock(p11card->card);
|
||||
return sc_to_cryptoki_error(rv, "C_Sign");
|
||||
}
|
||||
}
|
||||
|
||||
sc_log(context, "Selected flags %X. Now computing signature for %d bytes. %d bytes reserved.\n", flags, ulDataLen, *pulDataLen);
|
||||
sc_log(context, "Selected flags %X. Now computing signature for %d bytes. %d bytes reserved.", flags, ulDataLen, *pulDataLen);
|
||||
rv = sc_pkcs15_compute_signature(fw_data->p15_card,
|
||||
prkey->prv_p15obj,
|
||||
flags,
|
||||
|
@ -2733,9 +2845,9 @@ static CK_RV pkcs15_prkey_sign(struct sc_pkcs11_session *ses, void *obj,
|
|||
pSignature,
|
||||
*pulDataLen);
|
||||
|
||||
sc_unlock(ses->slot->card->card);
|
||||
sc_unlock(p11card->card);
|
||||
|
||||
sc_log(context, "Sign complete. Result %d.\n", rv);
|
||||
sc_log(context, "Sign complete. Result %d.", rv);
|
||||
|
||||
if (rv > 0) {
|
||||
*pulDataLen = rv;
|
||||
|
@ -2746,18 +2858,20 @@ static CK_RV pkcs15_prkey_sign(struct sc_pkcs11_session *ses, void *obj,
|
|||
}
|
||||
|
||||
static CK_RV
|
||||
pkcs15_prkey_decrypt(struct sc_pkcs11_session *ses, void *obj,
|
||||
pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj,
|
||||
CK_MECHANISM_PTR pMechanism,
|
||||
CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen,
|
||||
CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
|
||||
{
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) ses->slot->card->fws_data[0];
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
struct sc_pkcs11_card *p11card = session->slot->card;
|
||||
struct pkcs15_prkey_object *prkey;
|
||||
u8 decrypted[256]; /* FIXME: Will not work for keys above 2048 bits */
|
||||
unsigned char decrypted[256]; /* FIXME: Will not work for keys above 2048 bits */
|
||||
int buff_too_small, rv, flags = 0;
|
||||
|
||||
sc_log(context, "Initiating decryption.\n");
|
||||
sc_log(context, "Initiating decryption.");
|
||||
|
||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx];
|
||||
/* See which of the alternative keys supports decrypt */
|
||||
prkey = (struct pkcs15_prkey_object *) obj;
|
||||
while (prkey
|
||||
|
@ -2780,14 +2894,14 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *ses, void *obj,
|
|||
return CKR_MECHANISM_INVALID;
|
||||
}
|
||||
|
||||
rv = sc_lock(ses->slot->card->card);
|
||||
rv = sc_lock(p11card->card);
|
||||
if (rv < 0)
|
||||
return sc_to_cryptoki_error(rv, "C_Decrypt");
|
||||
|
||||
if (!sc_pkcs11_conf.lock_login) {
|
||||
rv = reselect_app_df(fw_data->p15_card);
|
||||
if (rv < 0) {
|
||||
sc_unlock(ses->slot->card->card);
|
||||
sc_unlock(p11card->card);
|
||||
return sc_to_cryptoki_error(rv, "C_Decrypt");
|
||||
}
|
||||
}
|
||||
|
@ -2796,9 +2910,9 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *ses, void *obj,
|
|||
flags, pEncryptedData, ulEncryptedDataLen,
|
||||
decrypted, sizeof(decrypted));
|
||||
|
||||
sc_unlock(ses->slot->card->card);
|
||||
sc_unlock(p11card->card);
|
||||
|
||||
sc_log(context, "Decryption complete. Result %d.\n", rv);
|
||||
sc_log(context, "Decryption complete. Result %d.", rv);
|
||||
|
||||
if (rv < 0)
|
||||
return sc_to_cryptoki_error(rv, "C_Decrypt");
|
||||
|
@ -2854,11 +2968,13 @@ static CK_RV pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session,
|
|||
void *object,
|
||||
CK_ATTRIBUTE_PTR attr)
|
||||
{
|
||||
struct sc_pkcs11_card *p11card = session->slot->card;
|
||||
struct pkcs15_pubkey_object *pubkey = (struct pkcs15_pubkey_object*) object;
|
||||
struct pkcs15_cert_object *cert = pubkey->pub_genfrom;
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) session->slot->card->fws_data[0];
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
size_t len;
|
||||
|
||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx];
|
||||
/* We may need to get these from cert */
|
||||
switch (attr->type) {
|
||||
case CKA_MODULUS:
|
||||
|
@ -3032,10 +3148,12 @@ static int pkcs15_dobj_get_value(struct sc_pkcs11_session *session,
|
|||
struct pkcs15_data_object *dobj,
|
||||
struct sc_pkcs15_data **out_data)
|
||||
{
|
||||
struct sc_pkcs11_card *p11card = session->slot->card;
|
||||
struct pkcs15_fw_data *fw_data = NULL;
|
||||
struct sc_card *card = session->slot->card->card;
|
||||
int rv;
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) session->slot->card->fws_data[0];
|
||||
sc_card_t *card = session->slot->card->card;
|
||||
|
||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx];
|
||||
if (!out_data)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
|
|
|
@ -181,7 +181,7 @@ CK_RV card_detect(sc_reader_t *reader)
|
|||
{
|
||||
struct sc_pkcs11_card *p11card = NULL;
|
||||
int rc, rv;
|
||||
unsigned int i;
|
||||
unsigned int i, j;
|
||||
|
||||
rv = CKR_OK;
|
||||
|
||||
|
@ -237,28 +237,64 @@ CK_RV card_detect(sc_reader_t *reader)
|
|||
|
||||
/* Detect the framework */
|
||||
if (p11card->framework == NULL) {
|
||||
sc_log(context, "%s: Detecting Framework", reader->name);
|
||||
struct sc_app_info *app_generic = sc_pkcs15_get_application_by_type(p11card->card, "generic");
|
||||
struct sc_pkcs11_slot *first_slot = NULL;
|
||||
|
||||
for (i = 0; frameworks[i]; i++) {
|
||||
if (frameworks[i]->bind == NULL)
|
||||
continue;
|
||||
rv = frameworks[i]->bind(p11card, NULL);
|
||||
if (rv == CKR_OK)
|
||||
sc_log(context, "%s: Detecting Framework. %i on-card applications", reader->name, p11card->card->app_count);
|
||||
sc_log(context, "%s: generic application %s", reader->name, app_generic ? app_generic->label : "<none>");
|
||||
|
||||
for (i = 0; frameworks[i]; i++)
|
||||
if (frameworks[i]->bind != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
/*TODO: only first framework is used: pkcs15init framework is not reachable here */
|
||||
if (frameworks[i] == NULL)
|
||||
return CKR_TOKEN_NOT_RECOGNIZED;
|
||||
return CKR_GENERAL_ERROR;
|
||||
|
||||
/* Initialize framework */
|
||||
sc_log(context, "%s: Detected framework %d. Creating tokens.", reader->name, i);
|
||||
rv = frameworks[i]->create_tokens(p11card, NULL, NULL);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
/* Bind firstly 'generic' application or (emulated?) card without applications */
|
||||
if (app_generic || !p11card->card->app_count) {
|
||||
sc_log(context, "%s: Try to bind 'generic' token.", reader->name);
|
||||
rv = frameworks[i]->bind(p11card, app_generic);
|
||||
if (rv != CKR_OK) {
|
||||
sc_log(context, "%s: cannot bind 'generic' token.", reader->name);
|
||||
return rv;
|
||||
}
|
||||
|
||||
sc_log(context, "%s: Creating 'generic' token.", reader->name);
|
||||
rv = frameworks[i]->create_tokens(p11card, app_generic, &first_slot);
|
||||
if (rv != CKR_OK) {
|
||||
sc_log(context, "%s: cannot create 'generic' token.", reader->name);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now bind the rest of applications that are not 'generic' */
|
||||
for (j = 0; j < p11card->card->app_count; j++) {
|
||||
struct sc_app_info *app_info = p11card->card->app[j];
|
||||
char *app_name = app_info ? app_info->label : "<anonymous>";
|
||||
|
||||
if (app_generic && app_generic == p11card->card->app[j])
|
||||
continue;
|
||||
|
||||
sc_log(context, "%s: Binding %s token.", reader->name, app_name);
|
||||
rv = frameworks[i]->bind(p11card, app_info);
|
||||
if (rv != CKR_OK) {
|
||||
sc_log(context, "%s: cannot bind %s token.", reader->name, app_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
sc_log(context, "%s: Creating %s token.", reader->name, app_name);
|
||||
rv = frameworks[i]->create_tokens(p11card, app_info, &first_slot);
|
||||
if (rv != CKR_OK) {
|
||||
sc_log(context, "%s: cannot create %s token.", reader->name, app_name);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
p11card->framework = frameworks[i];
|
||||
}
|
||||
sc_log(context, "%s: Detection ended\n", reader->name);
|
||||
sc_log(context, "%s: Detection ended", reader->name);
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue