diff --git a/etc/opensc.conf.example b/etc/opensc.conf.example index 9ff6b421..e07a77c0 100644 --- a/etc/opensc.conf.example +++ b/etc/opensc.conf.example @@ -141,3 +141,19 @@ app scam { use_caching = false; } } + +# Parameters for the OpenSC PKCS11 module +app opensc-pkcs11 { + pkcs11 { + # Maxmimum number of slots per smart card. + # If the card has fewer keys than defined here, + # the remaining number of slots will be empty. + # Setting this value to 0 will cause the pkcs11 + # module to allocate just as many slots as needed. + # + # Note that there is currently a compile time + # maximum on the overall number of slots + # the pkcs11 module is able to handle. + num_slots = 4; + } +} diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 5db10c5e..0cb05597 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -389,9 +389,11 @@ static CK_RV pkcs15_create_tokens(struct sc_pkcs11_card *p11card) } /* Create read/write slots */ - while (slot_allocate(&slot, p11card) == CKR_OK) { - pkcs15_init_token_info(card, &slot->token_info); - slot->token_info.flags = CKF_TOKEN_INITIALIZED; + if (sc_pkcs11_conf.num_slots != 0) { + while (slot_allocate(&slot, p11card) == CKR_OK) { + pkcs15_init_token_info(card, &slot->token_info); + slot->token_info.flags = CKF_TOKEN_INITIALIZED; + } } debug(context, "All tokens created\n"); diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c index 746f2de9..8057ddc5 100644 --- a/src/pkcs11/misc.c +++ b/src/pkcs11/misc.c @@ -297,3 +297,25 @@ CK_RV attr_find_var(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, return attr_extract(pTemplate, ptr, sizep); } +void load_pkcs11_parameters(struct sc_pkcs11_config *conf, struct sc_context *ctx) +{ + scconf_block *conf_block = NULL, **blocks; + int i; + + /* Set defaults */ + conf->num_slots = SC_PKCS11_MAX_VIRTUAL_SLOTS; + + for (i = 0; ctx->conf_blocks[i] != NULL; i++) { + blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], + "pkcs11", NULL); + conf_block = blocks[0]; + free(blocks); + if (conf_block != NULL) + break; + } + + if (!conf_block) + return; + + conf->num_slots = scconf_get_int(conf_block, "num_slots", conf->num_slots); +} diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index ca3dcbe9..5e6dcaf0 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -26,6 +26,7 @@ struct sc_context *context = NULL; struct sc_pkcs11_pool session_pool; struct sc_pkcs11_slot virtual_slots[SC_PKCS11_MAX_VIRTUAL_SLOTS]; struct sc_pkcs11_card card_table[SC_PKCS11_MAX_READERS]; +struct sc_pkcs11_config sc_pkcs11_conf; extern CK_FUNCTION_LIST pkcs11_function_list; @@ -41,6 +42,9 @@ CK_RV C_Initialize(CK_VOID_PTR pReserved) if (rc != 0) return CKR_DEVICE_ERROR; + /* Load configuration */ + load_pkcs11_parameters(&sc_pkcs11_conf, context); + pool_initialize(&session_pool, POOL_TYPE_SESSION); for (i=0; imax_slots = SC_PKCS11_MAX_VIRTUAL_SLOTS; + else + card->max_slots = sc_pkcs11_conf.num_slots; + card->num_slots = 0; + for (i = 0; frameworks[i]; i++) { if (frameworks[i]->bind == NULL) continue; @@ -142,6 +149,10 @@ CK_RV slot_initialize(int id, struct sc_pkcs11_slot *slot) CK_RV slot_allocate(struct sc_pkcs11_slot **slot, struct sc_pkcs11_card *card) { int i; + + if (card->num_slots >= card->max_slots) + return CKR_FUNCTION_FAILED; + for (i=0; inum_slots++; + return CKR_OK; } } return CKR_FUNCTION_FAILED;