pkcs11: prepare internal API for multi-application mode

- simplify some of framework handles: remove from it's prototype the arguments that can be derived from the other arguments;
for exemple: foo(slot, slot->card) --> foo(slot)
- add the 'application' argument to the bind, unbind and similar handles;
- preview more then one framework data attached to the pkcs11card object.
- placehold for the future 'derive' and 'can_do' handles.
This commit is contained in:
Viktor Tarasov 2012-05-22 17:18:00 +02:00
parent d1cf65754b
commit 14049fb806
9 changed files with 223 additions and 223 deletions

View File

@ -155,16 +155,16 @@ static CK_RV set_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)
static CK_RV pkcs15_bind(struct sc_pkcs11_card *p11card, struct sc_app_info *app_info)
{
struct pkcs15_fw_data *fw_data;
int rc;
CK_RV rv;
sc_log(context, "Bind PKCS#15 application");
sc_log(context, "Bind PKCS#15 '%s' application", app_info ? app_info->label : "<anonymous>");
if (!(fw_data = calloc(1, sizeof(*fw_data))))
return CKR_HOST_MEMORY;
p11card->fw_data = fw_data;
p11card->fws_data[0] = fw_data;
rc = sc_pkcs15_bind(p11card->card, NULL, &fw_data->p15_card);
if (rc != SC_SUCCESS) {
@ -183,7 +183,7 @@ static CK_RV pkcs15_bind(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->fw_data;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
unsigned int i;
int rc;
@ -765,7 +765,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->fw_data;
card_fw_data = (struct pkcs15_fw_data *) slot->card->fws_data[0];
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;
@ -847,7 +847,7 @@ static CK_RV pkcs15_create_slot(struct sc_pkcs11_card *p11card,
struct sc_pkcs15_object *auth,
struct sc_pkcs11_slot **out)
{
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
struct sc_pkcs11_slot *slot;
int rv;
@ -865,9 +865,12 @@ static CK_RV pkcs15_create_slot(struct sc_pkcs11_card *p11card,
return CKR_OK;
}
static CK_RV pkcs15_create_tokens(struct sc_pkcs11_card *p11card)
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->fw_data;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
struct sc_pkcs15_object *auths[MAX_OBJECTS];
struct sc_pkcs11_slot *slot = NULL;
int i, rv;
@ -1048,7 +1051,7 @@ static CK_RV pkcs15_create_tokens(struct sc_pkcs11_card *p11card)
static CK_RV pkcs15_release_token(struct sc_pkcs11_card *p11card, void *fw_token)
{
unlock_card((struct pkcs15_fw_data *) p11card->fw_data);
unlock_card((struct pkcs15_fw_data *) p11card->fws_data[0]);
free(fw_token);
return CKR_OK;
}
@ -1060,7 +1063,7 @@ 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->fw_data;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
struct sc_pkcs15_card *p15card = fw_data->p15_card;
struct sc_pkcs15_object *auth_object;
struct sc_pkcs15_auth_info *pin_info;
@ -1236,9 +1239,10 @@ static CK_RV pkcs15_login(struct sc_pkcs11_slot *slot,
return CKR_OK;
}
static CK_RV pkcs15_logout(struct sc_pkcs11_card *p11card, void *fw_token)
static CK_RV pkcs15_logout(struct sc_pkcs11_slot *slot)
{
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;
struct sc_pkcs11_card *p11card = slot->card;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
CK_RV ret = CKR_OK;
int rc;
@ -1265,15 +1269,19 @@ static CK_RV pkcs15_logout(struct sc_pkcs11_card *p11card, void *fw_token)
return ret;
}
static CK_RV pkcs15_change_pin(struct sc_pkcs11_card *p11card,
void *fw_token, int login_user,
CK_CHAR_PTR pOldPin, CK_ULONG ulOldLen,
CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen)
static CK_RV
pkcs15_change_pin(struct sc_pkcs11_slot *slot,
CK_CHAR_PTR pOldPin, CK_ULONG ulOldLen,
CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen)
{
int rc;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;
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 sc_pkcs15_auth_info *auth_info;
struct sc_pkcs15_object *pin_obj;
int rc;
if (!(pin_obj = slot_data_auth(fw_token)))
return CKR_USER_PIN_NOT_INITIALIZED;
@ -1344,11 +1352,11 @@ static CK_RV pkcs15_change_pin(struct sc_pkcs11_card *p11card,
}
#ifdef USE_PKCS15_INIT
static CK_RV pkcs15_init_pin(struct sc_pkcs11_card *p11card,
struct sc_pkcs11_slot *slot,
CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
static CK_RV
pkcs15_init_pin(struct sc_pkcs11_slot *slot, CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
{
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;
struct sc_pkcs11_card *p11card = slot->card;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
struct sc_pkcs15init_pinargs args;
struct sc_profile *profile;
struct sc_pkcs15_object *auth_obj;
@ -1422,13 +1430,15 @@ pkcs15_check_bool_cka(CK_ATTRIBUTE_PTR attr, unsigned long flag)
return 0;
}
static CK_RV pkcs15_create_private_key(struct sc_pkcs11_card *p11card,
struct sc_pkcs11_slot *slot,
static CK_RV
pkcs15_create_private_key(struct sc_pkcs11_slot *slot,
struct sc_profile *profile,
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
CK_OBJECT_HANDLE_PTR phObject)
{
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;
struct sc_pkcs11_card *p11card = slot->card;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
struct sc_pkcs15init_prkeyargs args;
struct pkcs15_any_object *key_any_obj;
struct sc_pkcs15_object *key_obj;
@ -1568,13 +1578,15 @@ static CK_RV pkcs15_create_private_key(struct sc_pkcs11_card *p11card,
out: return rv;
}
static CK_RV pkcs15_create_public_key(struct sc_pkcs11_card *p11card,
struct sc_pkcs11_slot *slot,
static CK_RV
pkcs15_create_public_key(struct sc_pkcs11_slot *slot,
struct sc_profile *profile,
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
CK_OBJECT_HANDLE_PTR phObject)
{
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;
struct sc_pkcs11_card *p11card = slot->card;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
struct sc_pkcs15init_pubkeyargs args;
struct pkcs15_any_object *key_any_obj;
struct sc_pkcs15_object *key_obj;
@ -1665,13 +1677,15 @@ static CK_RV pkcs15_create_public_key(struct sc_pkcs11_card *p11card,
out: return rv;
}
static CK_RV pkcs15_create_certificate(struct sc_pkcs11_card *p11card,
struct sc_pkcs11_slot *slot,
static CK_RV
pkcs15_create_certificate(struct sc_pkcs11_slot *slot,
struct sc_profile *profile,
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
CK_OBJECT_HANDLE_PTR phObject)
{
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;
struct sc_pkcs11_card *p11card = slot->card;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
struct sc_pkcs15init_certargs args;
struct pkcs15_any_object *cert_any_obj;
struct sc_pkcs15_object *cert_obj;
@ -1743,13 +1757,15 @@ static CK_RV pkcs15_create_certificate(struct sc_pkcs11_card *p11card,
out: return rv;
}
static CK_RV pkcs15_create_data(struct sc_pkcs11_card *p11card,
struct sc_pkcs11_slot *slot,
static CK_RV
pkcs15_create_data(struct sc_pkcs11_slot *slot,
struct sc_profile *profile,
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
CK_OBJECT_HANDLE_PTR phObject)
{
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;
struct sc_pkcs11_card *p11card = slot->card;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
struct sc_pkcs15init_dataargs args;
struct pkcs15_any_object *data_any_obj;
struct sc_pkcs15_object *data_obj;
@ -1826,11 +1842,13 @@ static CK_RV pkcs15_create_data(struct sc_pkcs11_card *p11card,
out: return rv;
}
static CK_RV pkcs15_create_object(struct sc_pkcs11_card *p11card,
struct sc_pkcs11_slot *slot,
static CK_RV
pkcs15_create_object(struct sc_pkcs11_slot *slot,
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
CK_OBJECT_HANDLE_PTR phObject)
{
struct sc_pkcs11_card *p11card = slot->card;
struct sc_profile *profile = NULL;
CK_OBJECT_CLASS _class;
int rv, rc;
@ -1852,20 +1870,16 @@ static CK_RV pkcs15_create_object(struct sc_pkcs11_card *p11card,
switch (_class) {
case CKO_PRIVATE_KEY:
rv = pkcs15_create_private_key(p11card, slot, profile,
pTemplate, ulCount, phObject);
rv = pkcs15_create_private_key(slot, profile, pTemplate, ulCount, phObject);
break;
case CKO_PUBLIC_KEY:
rv = pkcs15_create_public_key(p11card, slot, profile,
pTemplate, ulCount, phObject);
rv = pkcs15_create_public_key(slot, profile, pTemplate, ulCount, phObject);
break;
case CKO_CERTIFICATE:
rv = pkcs15_create_certificate(p11card, slot, profile,
pTemplate, ulCount, phObject);
rv = pkcs15_create_certificate(slot, profile, pTemplate, ulCount, phObject);
break;
case CKO_DATA:
rv = pkcs15_create_data(p11card, slot, profile,
pTemplate, ulCount, phObject);
rv = pkcs15_create_data(slot, profile, pTemplate, ulCount, phObject);
break;
default:
rv = CKR_FUNCTION_NOT_SUPPORTED;
@ -1966,16 +1980,17 @@ set_gost_params(struct sc_pkcs15init_keyarg_gost_params *first_params,
}
/* FIXME: check for the public exponent in public key template and use this value */
static CK_RV pkcs15_gen_keypair(struct sc_pkcs11_card *p11card,
struct sc_pkcs11_slot *slot,
static CK_RV
pkcs15_gen_keypair(struct sc_pkcs11_slot *slot,
CK_MECHANISM_PTR pMechanism,
CK_ATTRIBUTE_PTR pPubTpl, CK_ULONG ulPubCnt,
CK_ATTRIBUTE_PTR pPrivTpl, CK_ULONG ulPrivCnt,
CK_OBJECT_HANDLE_PTR phPubKey, CK_OBJECT_HANDLE_PTR phPrivKey) /* gets priv. key handle */
{
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->fw_data;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
struct sc_pkcs15init_keygen_args keygen_args;
struct sc_pkcs15init_pubkeyargs pub_args;
struct sc_pkcs15_object *priv_key_obj;
@ -2146,7 +2161,7 @@ static CK_RV pkcs15_any_destroy(struct sc_pkcs11_session *session, void *object)
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->fw_data;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) card->fws_data[0];
struct sc_profile *profile = NULL;
int rv;
@ -2182,12 +2197,13 @@ static CK_RV pkcs15_any_destroy(struct sc_pkcs11_session *session, void *object)
}
static CK_RV pkcs15_get_random(struct sc_pkcs11_card *p11card,
static CK_RV pkcs15_get_random(struct sc_pkcs11_slot *slot,
CK_BYTE_PTR p, CK_ULONG len)
{
int rc;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;
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;
int rc;
rc = sc_get_challenge(card, p, (size_t)len);
return sc_to_cryptoki_error(rc, "C_GenerateRandom");
@ -2223,7 +2239,7 @@ static CK_RV pkcs15_set_attrib(struct sc_pkcs11_session *session,
#else
struct sc_profile *profile = NULL;
struct sc_pkcs11_card *p11card = session->slot->card;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fws_data[0];
struct sc_pkcs15_id id;
int rc = 0;
CK_RV rv = CKR_OK;
@ -2299,7 +2315,7 @@ static CK_RV pkcs15_cert_get_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->fw_data;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) session->slot->card->fws_data[0];
size_t len;
switch (attr->type) {
@ -2386,7 +2402,7 @@ 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->fw_data;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) session->slot->card->fws_data[0];
u8 *data;
size_t len;
@ -2429,10 +2445,12 @@ struct sc_pkcs11_object_ops pkcs15_cert_ops = {
pkcs15_cert_get_attribute,
pkcs15_cert_cmp_attribute,
pkcs15_any_destroy,
NULL,
NULL,
NULL,
NULL
NULL, /* get_size */
NULL, /* sign */
NULL, /* unwrap_key */
NULL, /* decrypt */
NULL, /* derive */
NULL /* can_do */
};
/*
@ -2456,7 +2474,7 @@ static CK_RV pkcs15_prkey_get_attribute(struct sc_pkcs11_session *session,
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->fw_data;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) session->slot->card->fws_data[0];
struct sc_pkcs15_pubkey *key = NULL;
unsigned int usage;
size_t len;
@ -2622,7 +2640,7 @@ static CK_RV pkcs15_prkey_sign(struct sc_pkcs11_session *ses, void *obj,
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->fw_data;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) ses->slot->card->fws_data[0];
int rv, flags = 0;
sc_log(context, "Initiating signing operation, mechanism 0x%x.\n",
@ -2733,7 +2751,7 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *ses, void *obj,
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->fw_data;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) ses->slot->card->fws_data[0];
struct pkcs15_prkey_object *prkey;
u8 decrypted[256]; /* FIXME: Will not work for keys above 2048 bits */
int buff_too_small, rv, flags = 0;
@ -2804,8 +2822,10 @@ struct sc_pkcs11_object_ops pkcs15_prkey_ops = {
pkcs15_any_destroy,
NULL,
pkcs15_prkey_sign,
NULL, /* unwrap */
pkcs15_prkey_decrypt
NULL, /* unwrap */
pkcs15_prkey_decrypt,
NULL, /* derive */
NULL /* can_do */
};
/*
@ -2836,7 +2856,7 @@ static CK_RV pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session,
{
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->fw_data;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) session->slot->card->fws_data[0];
size_t len;
/* We may need to get these from cert */
@ -2983,10 +3003,12 @@ struct sc_pkcs11_object_ops pkcs15_pubkey_ops = {
pkcs15_pubkey_get_attribute,
sc_pkcs11_any_cmp_attribute,
pkcs15_any_destroy,
NULL,
NULL,
NULL,
NULL
NULL, /* get_size */
NULL, /* sign */
NULL, /* unwrap_key */
NULL, /* decrypt */
NULL, /* derive */
NULL /* can_do */
};
@ -3011,8 +3033,7 @@ static int pkcs15_dobj_get_value(struct sc_pkcs11_session *session,
struct sc_pkcs15_data **out_data)
{
int rv;
struct pkcs15_fw_data *fw_data =
(struct pkcs15_fw_data *) session->slot->card->fw_data;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) session->slot->card->fws_data[0];
sc_card_t *card = session->slot->card->card;
if (!out_data)
@ -3123,13 +3144,14 @@ struct sc_pkcs11_object_ops pkcs15_dobj_ops = {
pkcs15_dobj_get_attribute,
sc_pkcs11_any_cmp_attribute,
pkcs15_any_destroy,
NULL,
NULL,
NULL,
NULL,
NULL, /* get_size */
NULL, /* sign */
NULL, /* unwrap_key */
NULL, /* decrypt */
NULL, /* derive */
NULL /* can_do */
};
/*
* get_attribute helpers
*/

View File

@ -30,7 +30,7 @@
/*
* Deal with uninitialized cards
*/
static CK_RV pkcs15init_bind(struct sc_pkcs11_card *p11card)
static CK_RV pkcs15init_bind(struct sc_pkcs11_card *p11card, struct sc_app_info *app_info)
{
struct sc_card *card = p11card->card;
struct sc_profile *profile;
@ -38,7 +38,7 @@ static CK_RV pkcs15init_bind(struct sc_pkcs11_card *p11card)
rc = sc_pkcs15init_bind(card, "pkcs15", NULL, &profile);
if (rc == 0)
p11card->fw_data = profile;
p11card->fws_data[0] = profile;
return sc_to_cryptoki_error(rc, NULL);
}
@ -46,18 +46,21 @@ static CK_RV pkcs15init_unbind(struct sc_pkcs11_card *p11card)
{
struct sc_profile *profile;
profile = (struct sc_profile *) p11card->fw_data;
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)
static CK_RV
pkcs15init_create_tokens(struct sc_pkcs11_card *p11card, struct sc_app_info *app_info,
struct sc_pkcs11_slot **first_slot)
{
struct sc_profile *profile;
struct sc_pkcs11_slot *slot;
int rc;
profile = (struct sc_profile *) p11card->fw_data;
profile = (struct sc_profile *) p11card->fws_data[0];
rc = slot_allocate(&slot, p11card);
if (rc == CKR_OK) {
@ -106,13 +109,13 @@ pkcs15init_login(struct sc_pkcs11_slot *slot,
}
static CK_RV
pkcs15init_logout(struct sc_pkcs11_card *p11card, void *ptr)
pkcs15init_logout(struct sc_pkcs11_slot *slot)
{
return CKR_CRYPTOKI_NOT_INITIALIZED;
}
static CK_RV
pkcs15init_change_pin(struct sc_pkcs11_card *p11card, void *ptr, int login_user,
pkcs15init_change_pin(struct sc_pkcs11_slot *slot,
CK_CHAR_PTR oldPin, CK_ULONG oldPinLength,
CK_CHAR_PTR newPin, CK_ULONG newPinLength)
{
@ -124,7 +127,7 @@ pkcs15init_initialize(struct sc_pkcs11_card *p11card, void *ptr,
CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen,
CK_UTF8CHAR_PTR pLabel)
{
struct sc_profile *profile = (struct sc_profile *) p11card->fw_data;
struct sc_profile *profile = (struct sc_profile *) p11card->fws_data[0];
struct sc_pkcs15init_initargs args;
struct sc_pkcs11_slot *slot;
int rc, rv, id;
@ -142,9 +145,9 @@ pkcs15init_initialize(struct sc_pkcs11_card *p11card, void *ptr,
/* Change the binding from the pkcs15init framework
* to the pkcs15 framework on the fly.
* First, try to bind pkcs15 framework */
if ((rv = framework_pkcs15.bind(p11card)) != CKR_OK) {
if ((rv = framework_pkcs15.bind(p11card, NULL)) != CKR_OK) {
/* whoops, bad */
p11card->fw_data = profile;
p11card->fws_data[0] = profile;
return rv;
}

View File

@ -335,8 +335,9 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx)
free(tmp);
sc_log(ctx, "PKCS#11 options: plug_and_play=%d max_virtual_slots=%d slots_per_card=%d "
"hide_empty_tokens=%d lock_login=%d pin_unblock_style=%d zero_ckaid_for_ca_certs=%d",
"hide_empty_tokens=%d lock_login=%d pin_unblock_style=%d "
"zero_ckaid_for_ca_certs=%d create_slots_flags=0x%X",
conf->plug_and_play, conf->max_virtual_slots, conf->slots_per_card,
conf->hide_empty_tokens, conf->lock_login, conf->pin_unblock_style,
conf->zero_ckaid_for_ca_certs);
conf->zero_ckaid_for_ca_certs, conf->create_slots_flags);
}

View File

@ -44,16 +44,11 @@ static sc_pkcs11_mechanism_type_t openssl_sha1_mech = {
sc_pkcs11_openssl_md_init,
sc_pkcs11_openssl_md_update,
sc_pkcs11_openssl_md_final,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
NULL, NULL, NULL, NULL, /* sign_* */
NULL, NULL, NULL, /* verif_* */
NULL, NULL, /* decrypt_* */
NULL, /* derive */
NULL /* mech_data */
};
#if OPENSSL_VERSION_NUMBER >= 0x00908000L
@ -66,16 +61,11 @@ static sc_pkcs11_mechanism_type_t openssl_sha256_mech = {
sc_pkcs11_openssl_md_init,
sc_pkcs11_openssl_md_update,
sc_pkcs11_openssl_md_final,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
NULL, NULL, NULL, NULL, /* sign_* */
NULL, NULL, NULL, /* verif_* */
NULL, NULL, /* decrypt_* */
NULL, /* derive */
NULL /* mech_data */
};
static sc_pkcs11_mechanism_type_t openssl_sha384_mech = {
@ -87,16 +77,11 @@ static sc_pkcs11_mechanism_type_t openssl_sha384_mech = {
sc_pkcs11_openssl_md_init,
sc_pkcs11_openssl_md_update,
sc_pkcs11_openssl_md_final,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
NULL, NULL, NULL, NULL, /* sign_* */
NULL, NULL, NULL, /* verif_* */
NULL, NULL, /* decrypt_* */
NULL, /* derive */
NULL /* mech_data */
};
static sc_pkcs11_mechanism_type_t openssl_sha512_mech = {
@ -108,16 +93,11 @@ static sc_pkcs11_mechanism_type_t openssl_sha512_mech = {
sc_pkcs11_openssl_md_init,
sc_pkcs11_openssl_md_update,
sc_pkcs11_openssl_md_final,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
NULL, NULL, NULL, NULL, /* sign_* */
NULL, NULL, NULL, /* verif_* */
NULL, NULL, /* decrypt_* */
NULL, /* derive */
NULL /* mech_data */
};
#endif
@ -131,16 +111,11 @@ static sc_pkcs11_mechanism_type_t openssl_gostr3411_mech = {
sc_pkcs11_openssl_md_init,
sc_pkcs11_openssl_md_update,
sc_pkcs11_openssl_md_final,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
NULL, NULL, NULL, NULL, /* sign_* */
NULL, NULL, NULL, /* verif_* */
NULL, NULL, /* decrypt_* */
NULL, /* derive */
NULL /* mech_data */
};
#endif
@ -153,16 +128,11 @@ static sc_pkcs11_mechanism_type_t openssl_md5_mech = {
sc_pkcs11_openssl_md_init,
sc_pkcs11_openssl_md_update,
sc_pkcs11_openssl_md_final,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
NULL, NULL, NULL, NULL, /* sign_* */
NULL, NULL, NULL, /* verif_* */
NULL, NULL, /* decrypt_* */
NULL, /* derive */
NULL /* mech_data */
};
static sc_pkcs11_mechanism_type_t openssl_ripemd160_mech = {
@ -174,16 +144,11 @@ static sc_pkcs11_mechanism_type_t openssl_ripemd160_mech = {
sc_pkcs11_openssl_md_init,
sc_pkcs11_openssl_md_update,
sc_pkcs11_openssl_md_final,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
NULL, NULL, NULL, NULL, /* sign_* */
NULL, NULL, NULL, /* verif_* */
NULL, NULL, /* decrypt_* */
NULL, /* derive */
NULL /* mech_data */
};
void

View File

@ -200,7 +200,7 @@ print_dn(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR ar
void
print_print(FILE *f, CK_LONG type, CK_VOID_PTR value, CK_ULONG size, CK_VOID_PTR arg)
{
CK_ULONG i, j;
CK_ULONG i, j=0;
CK_BYTE c;
if((CK_LONG)size != -1) {

View File

@ -41,13 +41,12 @@ static sc_pkcs11_mechanism_type_t find_mechanism = {
NULL, /* sign_update */
NULL, /* sign_final */
NULL, /* sign_size */
#ifdef ENABLE_OPENSSL
NULL, /* verif_init */
NULL, /* verif_update */
NULL, /* verif_final */
#endif
NULL, /* decrypt_init */
NULL, /* decrypt */
NULL, /* derive */
NULL /* mech_data */
};
@ -116,8 +115,7 @@ CK_RV C_CreateObject(CK_SESSION_HANDLE hSession, /* the session's handle */
if (card->framework->create_object == NULL)
rv = CKR_FUNCTION_NOT_SUPPORTED;
else
rv = card->framework->create_object(card, session->slot,
pTemplate, ulCount, phObject);
rv = card->framework->create_object(session->slot, pTemplate, ulCount, phObject);
out: sc_pkcs11_unlock();
LOG_FUNC_RETURN(context, rv);
@ -958,7 +956,7 @@ CK_RV C_GenerateKeyPair(CK_SESSION_HANDLE hSession, /* the session's handle */
if (slot->card->framework->gen_keypair == NULL) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
} else {
rv = slot->card->framework->gen_keypair(slot->card, slot,
rv = slot->card->framework->gen_keypair(slot,
pMechanism, pPublicKeyTemplate,
ulPublicKeyAttributeCount,
pPrivateKeyTemplate,
@ -1028,7 +1026,7 @@ CK_RV C_GenerateRandom(CK_SESSION_HANDLE hSession, /* the session's handle */
if (slot->card->framework->get_random == NULL)
rv = CKR_RANDOM_NO_RNG;
else
rv = slot->card->framework->get_random(slot->card, RandomData, ulRandomLen);
rv = slot->card->framework->get_random(slot, RandomData, ulRandomLen);
}
sc_pkcs11_unlock();

View File

@ -107,7 +107,7 @@ static CK_RV sc_pkcs11_close_session(CK_SESSION_HANDLE hSession)
slot->nsessions--;
if (slot->nsessions == 0 && slot->login_user >= 0) {
slot->login_user = -1;
slot->card->framework->logout(slot->card, slot->fw_data);
slot->card->framework->logout(slot);
}
if (list_delete(&sessions, session) != 0)
@ -141,7 +141,7 @@ CK_RV C_CloseSession(CK_SESSION_HANDLE hSession)
if (rv != CKR_OK)
return rv;
sc_log(context, "C_CloseSession(0x%lx)\n", hSession);
sc_log(context, "C_CloseSession(0x%lx)", hSession);
rv = sc_pkcs11_close_session(hSession);
@ -158,7 +158,7 @@ CK_RV C_CloseAllSessions(CK_SLOT_ID slotID)
if (rv != CKR_OK)
return rv;
sc_log(context, "C_CloseAllSessions(0x%lx)\n", slotID);
sc_log(context, "C_CloseAllSessions(0x%lx)", slotID);
rv = slot_get_token(slotID, &slot);
if (rv != CKR_OK)
@ -184,7 +184,7 @@ CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, /* the session's handle */
if (rv != CKR_OK)
return rv;
sc_log(context, "C_GetSessionInfo(0x%lx)", hSession);
sc_log(context, "C_GetSessionInfo(hSession:0x%lx)", hSession);
session = list_seek(&sessions, &hSession);
if (!session) {
@ -192,7 +192,7 @@ CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, /* the session's handle */
goto out;
}
sc_log(context, "C_GetSessionInfo(slot 0x%lx).", session->slot->id);
sc_log(context, "C_GetSessionInfo(slot:0x%lx)", session->slot->id);
pInfo->slotID = session->slot->id;
pInfo->flags = session->flags;
pInfo->ulDeviceError = 0;
@ -208,7 +208,7 @@ CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, /* the session's handle */
? CKS_RW_PUBLIC_SESSION : CKS_RO_PUBLIC_SESSION;
}
out:
out:
sc_log(context, "C_GetSessionInfo(0x%lx) = %s", hSession, lookup_enum(RV_T, rv));
sc_pkcs11_unlock();
return rv;
@ -306,13 +306,13 @@ CK_RV C_Logout(CK_SESSION_HANDLE hSession)
goto out;
}
sc_log(context, "C_Logout(0x%lx)", hSession);
sc_log(context, "C_Logout(hSession:0x%lx)", hSession);
slot = session->slot;
if (slot->login_user >= 0) {
slot->login_user = -1;
rv = slot->card->framework->logout(slot->card, slot->fw_data);
rv = slot->card->framework->logout(slot);
} else
rv = CKR_USER_NOT_LOGGED_IN;
@ -350,7 +350,7 @@ CK_RV C_InitPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
} 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);
rv = slot->card->framework->init_pin(slot, pPin, ulPinLen);
}
out:sc_pkcs11_unlock();
@ -364,8 +364,7 @@ CK_RV C_SetPIN(CK_SESSION_HANDLE hSession,
struct sc_pkcs11_session *session;
struct sc_pkcs11_slot *slot;
if ((pOldPin == NULL_PTR && ulOldLen > 0)
|| (pNewPin == NULL_PTR && ulNewLen > 0))
if ((pOldPin == NULL_PTR && ulOldLen > 0) || (pNewPin == NULL_PTR && ulNewLen > 0))
return CKR_ARGUMENTS_BAD;
rv = sc_pkcs11_lock();
@ -379,18 +378,15 @@ CK_RV C_SetPIN(CK_SESSION_HANDLE hSession,
}
slot = session->slot;
sc_log(context, "Changing PIN (session 0x%lx; login user %d)\n", hSession,
slot->login_user);
sc_log(context, "Changing PIN (session 0x%lx; login user %d)", hSession, slot->login_user);
if (!(session->flags & CKF_RW_SESSION)) {
rv = CKR_SESSION_READ_ONLY;
goto out;
}
rv = slot->card->framework->change_pin(slot->card, slot->fw_data,
slot->login_user, pOldPin, ulOldLen, pNewPin,
ulNewLen);
out:sc_pkcs11_unlock();
rv = slot->card->framework->change_pin(slot, pOldPin, ulOldLen, pNewPin, ulNewLen);
out:
sc_pkcs11_unlock();
return rv;
}

View File

@ -46,15 +46,15 @@ extern "C" {
#define PKCS11_DEFAULT_MODULE_NAME "opensc-pkcs11.so"
#endif
#define SC_PKCS11_PIN_UNBLOCK_NOT_ALLOWED 0
#define SC_PKCS11_PIN_UNBLOCK_UNLOGGED_SETPIN 1
#define SC_PKCS11_PIN_UNBLOCK_SCONTEXT_SETPIN 2
#define SC_PKCS11_PIN_UNBLOCK_SO_LOGGED_INITPIN 3
#define SC_PKCS11_PIN_UNBLOCK_NOT_ALLOWED 0
#define SC_PKCS11_PIN_UNBLOCK_UNLOGGED_SETPIN 1
#define SC_PKCS11_PIN_UNBLOCK_SCONTEXT_SETPIN 2
#define SC_PKCS11_PIN_UNBLOCK_SO_LOGGED_INITPIN 3
#define SC_PKCS11_SLOT_FOR_PIN_USER 1
#define SC_PKCS11_SLOT_FOR_PIN_SIGN 2
#define SC_PKCS11_SLOT_FOR_APPLICATION 4
#define SC_PKCS11_SLOT_CREATE_ALL 8
#define SC_PKCS11_SLOT_FOR_PIN_USER 1
#define SC_PKCS11_SLOT_FOR_PIN_SIGN 2
#define SC_PKCS11_SLOT_FOR_APPLICATION 4
#define SC_PKCS11_SLOT_CREATE_ALL 8
extern void *C_LoadModule(const char *name, CK_FUNCTION_LIST_PTR_PTR);
extern CK_RV C_UnloadModule(void *module);
@ -85,7 +85,7 @@ struct sc_pkcs11_config {
unsigned int pin_unblock_style;
unsigned int create_puk_slot;
unsigned int zero_ckaid_for_ca_certs;
unsigned int create_slots_flags;
unsigned int create_slots_flags;
};
/*
@ -119,6 +119,14 @@ struct sc_pkcs11_object_ops {
CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen,
CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen);
CK_RV (*derive)(struct sc_pkcs11_session *, void *,
CK_MECHANISM_PTR,
CK_BYTE_PTR pSeedData, CK_ULONG ulSeedDataLen,
CK_BYTE_PTR pDerived, CK_ULONG_PTR pulDerivedLen);
/* Check compatibility of PKCS#15 object usage and an asked PKCS#11 mechanism. */
CK_RV (*can_do)(struct sc_pkcs11_session *, void *, CK_MECHANISM_TYPE, unsigned int);
/* Others to be added when implemented */
};
@ -139,20 +147,20 @@ struct sc_pkcs11_object {
struct sc_pkcs11_framework_ops {
/* Detect and bind card to framework */
CK_RV (*bind)(struct sc_pkcs11_card *);
CK_RV (*bind)(struct sc_pkcs11_card *, struct sc_app_info *);
/* Unbind and release allocated resources */
CK_RV (*unbind)(struct sc_pkcs11_card *);
/* Create tokens to virtual slots and
* objects in tokens; called after bind */
CK_RV (*create_tokens)(struct sc_pkcs11_card *);
CK_RV (*create_tokens)(struct sc_pkcs11_card *, struct sc_app_info *, struct sc_pkcs11_slot **);
CK_RV (*release_token)(struct sc_pkcs11_card *, void *);
/* Login and logout */
CK_RV (*login)(struct sc_pkcs11_slot *,
CK_USER_TYPE, CK_CHAR_PTR, CK_ULONG);
CK_RV (*logout)(struct sc_pkcs11_card *, void *);
CK_RV (*change_pin)(struct sc_pkcs11_card *, void *, int,
CK_RV (*logout)(struct sc_pkcs11_slot *);
CK_RV (*change_pin)(struct sc_pkcs11_slot *,
CK_CHAR_PTR, CK_ULONG,
CK_CHAR_PTR, CK_ULONG);
@ -163,20 +171,17 @@ struct sc_pkcs11_framework_ops {
CK_RV (*init_token)(struct sc_pkcs11_card *, void *,
CK_UTF8CHAR_PTR, CK_ULONG,
CK_UTF8CHAR_PTR);
CK_RV (*init_pin)(struct sc_pkcs11_card *,
struct sc_pkcs11_slot *,
CK_RV (*init_pin)(struct sc_pkcs11_slot *,
CK_UTF8CHAR_PTR, CK_ULONG);
CK_RV (*create_object)(struct sc_pkcs11_card *,
struct sc_pkcs11_slot *,
CK_RV (*create_object)(struct sc_pkcs11_slot *,
CK_ATTRIBUTE_PTR, CK_ULONG,
CK_OBJECT_HANDLE_PTR);
CK_RV (*gen_keypair)(struct sc_pkcs11_card *p11card,
struct sc_pkcs11_slot *slot,
CK_MECHANISM_PTR pMechanism,
CK_ATTRIBUTE_PTR pPubKeyTempl, CK_ULONG ulPubKeyAttrCnt,
CK_ATTRIBUTE_PTR pPrivKeyTempl, CK_ULONG ulPrivKeyAttrCnt,
CK_OBJECT_HANDLE_PTR phPubKey, CK_OBJECT_HANDLE_PTR phPrivKey);
CK_RV (*get_random)(struct sc_pkcs11_card *p11card,
CK_RV (*gen_keypair)(struct sc_pkcs11_slot *,
CK_MECHANISM_PTR,
CK_ATTRIBUTE_PTR, CK_ULONG,
CK_ATTRIBUTE_PTR, CK_ULONG,
CK_OBJECT_HANDLE_PTR, CK_OBJECT_HANDLE_PTR);
CK_RV (*get_random)(struct sc_pkcs11_slot *,
CK_BYTE_PTR, CK_ULONG);
};
@ -190,11 +195,12 @@ typedef unsigned long long sc_timestamp_t;
typedef unsigned __int64 sc_timestamp_t;
#endif
#define SC_PKCS11_FRAMEWORK_DATA_MAX_NUM 4
struct sc_pkcs11_card {
sc_reader_t *reader;
sc_card_t *card;
struct sc_pkcs11_framework_ops *framework;
void *fw_data;
void *fws_data[SC_PKCS11_FRAMEWORK_DATA_MAX_NUM];
/* List of supported mechanisms */
struct sc_pkcs11_mechanism_type **mechanisms;
@ -202,17 +208,20 @@ struct sc_pkcs11_card {
};
struct sc_pkcs11_slot {
CK_SLOT_ID id; /* ID of the slot */
int login_user; /* Currently logged in user */
CK_SLOT_INFO slot_info; /* Slot specific information (information about reader) */
CK_TOKEN_INFO token_info; /* Token specific information (information about card) */
sc_reader_t *reader; /* same as card->reader if there's a card present */
struct sc_pkcs11_card *card; /* The card associated with this slot */
unsigned int events; /* Card events SC_EVENT_CARD_{INSERTED,REMOVED} */
void *fw_data; /* Framework specific data */
list_t objects; /* Objects in this slot */
unsigned int nsessions; /* Number of sessions using this slot */
CK_SLOT_ID id; /* ID of the slot */
int login_user; /* Currently logged in user */
CK_SLOT_INFO slot_info; /* Slot specific information (information about reader) */
CK_TOKEN_INFO token_info; /* Token specific information (information about card) */
sc_reader_t *reader; /* same as card->reader if there's a card present */
struct sc_pkcs11_card *card; /* The card associated with this slot */
unsigned int events; /* Card events SC_EVENT_CARD_{INSERTED,REMOVED} */
void *fw_data; /* Framework specific data */ /* TODO: get know how it used */
list_t objects; /* Objects in this slot */
unsigned int nsessions; /* Number of sessions using this slot */
sc_timestamp_t slot_state_expires;
int fw_data_idx; /* Index of framework data */
struct sc_app_info *app_info; /* Application assosiated to slot */
};
typedef struct sc_pkcs11_slot sc_pkcs11_slot_t;
@ -226,6 +235,7 @@ enum {
SC_PKCS11_OPERATION_VERIFY,
SC_PKCS11_OPERATION_DIGEST,
SC_PKCS11_OPERATION_DECRYPT,
SC_PKCS11_OPERATION_DERIVE,
SC_PKCS11_OPERATION_MAX
};
@ -254,19 +264,21 @@ struct sc_pkcs11_mechanism_type {
CK_BYTE_PTR, CK_ULONG_PTR);
CK_RV (*sign_size)(sc_pkcs11_operation_t *,
CK_ULONG_PTR);
#ifdef ENABLE_OPENSSL
CK_RV (*verif_init)(sc_pkcs11_operation_t *,
struct sc_pkcs11_object *);
CK_RV (*verif_update)(sc_pkcs11_operation_t *,
CK_BYTE_PTR, CK_ULONG);
CK_RV (*verif_final)(sc_pkcs11_operation_t *,
CK_BYTE_PTR, CK_ULONG);
#endif
CK_RV (*decrypt_init)(sc_pkcs11_operation_t *,
struct sc_pkcs11_object *);
CK_RV (*decrypt)(sc_pkcs11_operation_t *,
CK_BYTE_PTR, CK_ULONG,
CK_BYTE_PTR, CK_ULONG_PTR);
CK_RV (*derive)(sc_pkcs11_operation_t *,
struct sc_pkcs11_object *,
CK_BYTE_PTR, CK_ULONG,
CK_BYTE_PTR, CK_ULONG_PTR);
/* mechanism specific data */
const void * mech_data;
};
@ -388,6 +400,9 @@ CK_RV sc_pkcs11_verif_final(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG);
#endif
CK_RV sc_pkcs11_decr_init(struct sc_pkcs11_session *, CK_MECHANISM_PTR, struct sc_pkcs11_object *, CK_MECHANISM_TYPE);
CK_RV sc_pkcs11_decr(struct sc_pkcs11_session *, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR);
CK_RV sc_pkcs11_deri(struct sc_pkcs11_session *, CK_MECHANISM_PTR,
struct sc_pkcs11_object *, CK_KEY_TYPE,
CK_SESSION_HANDLE, CK_OBJECT_HANDLE, struct sc_pkcs11_object *);
sc_pkcs11_mechanism_type_t *sc_pkcs11_find_mechanism(struct sc_pkcs11_card *,
CK_MECHANISM_TYPE, unsigned int);
sc_pkcs11_mechanism_type_t *sc_pkcs11_new_fw_mechanism(CK_MECHANISM_TYPE,

View File

@ -237,12 +237,12 @@ CK_RV card_detect(sc_reader_t *reader)
/* Detect the framework */
if (p11card->framework == NULL) {
sc_log(context, "%s: Detecting Framework\n", reader->name);
sc_log(context, "%s: Detecting Framework", reader->name);
for (i = 0; frameworks[i]; i++) {
if (frameworks[i]->bind == NULL)
continue;
rv = frameworks[i]->bind(p11card);
rv = frameworks[i]->bind(p11card, NULL);
if (rv == CKR_OK)
break;
}
@ -251,8 +251,8 @@ CK_RV card_detect(sc_reader_t *reader)
return CKR_TOKEN_NOT_RECOGNIZED;
/* Initialize framework */
sc_log(context, "%s: Detected framework %d. Creating tokens.\n", reader->name, i);
rv = frameworks[i]->create_tokens(p11card);
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;