diff --git a/etc/opensc.conf.example b/etc/opensc.conf.example index 4b4f5721..1bbb075a 100644 --- a/etc/opensc.conf.example +++ b/etc/opensc.conf.example @@ -153,7 +153,7 @@ app opensc-pkcs11 { # maximum on the overall number of slots # the pkcs11 module is able to handle. num_slots = 4; - # + # Normally, the pkcs11 module will create # the full number of slots defined above by # num_slots. If there are fewer pins/keys on @@ -161,8 +161,22 @@ app opensc-pkcs11 { # (and you will be able to create new objects # within them). # - # Set this option to false to hide these empty + # Set this option to true to hide these empty # slots. hide_empty_slots = false; + + # By default, the OpenSC PKCS#11 module will + # try to lock this card once you have authenticated + # to the card via C_Login. This is done so that no + # other user can connect to the card and perform + # crypto operations (which may be possible because + # you have already authenticated with the card). + # + # However, this also means that no other application + # that _you_ run can use the card until your application + # has done a C_Logout or C_Finalize. In the case of + # Netscape or Mozilla, this does not happen until + # you exit the browser. + lock_login = true; } } diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 1003c8e2..1f4d9326 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -450,10 +450,16 @@ static CK_RV pkcs15_login(struct sc_pkcs11_card *p11card, ulPinLen > pin->stored_length) return CKR_PIN_LEN_RANGE; - rc = sc_lock(card->card); - if (rc < 0) { - debug(context, "Failed to lock card (%d)\n", rc); - return sc_to_cryptoki_error(rc, p11card->reader); + /* By default, we make the pcsc daemon keep other processes + * from accessing the card while we're logged in. Otherwise + * an attacker could perform some crypto operation after + * we've authenticated with the card */ + if (sc_pkcs11_conf.lock_login) { + rc = sc_lock(card->card); + if (rc < 0) { + debug(context, "Failed to lock card (%d)\n", rc); + return sc_to_cryptoki_error(rc, p11card->reader); + } } rc = sc_pkcs15_verify_pin(card, pin, pPin, ulPinLen); @@ -468,12 +474,13 @@ static CK_RV pkcs15_login(struct sc_pkcs11_card *p11card, static CK_RV pkcs15_logout(struct sc_pkcs11_card *p11card, void *fw_token) { struct sc_pkcs15_card *card = (struct sc_pkcs15_card*) p11card->fw_data; - int rc; + int rc = 0; cache_pin(fw_token, CKU_SO, NULL, 0); cache_pin(fw_token, CKU_USER, NULL, 0); - rc = sc_unlock(card->card); + if (sc_pkcs11_conf.lock_login) + rc = sc_unlock(card->card); return sc_to_cryptoki_error(rc, p11card->reader); } diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c index 85e50922..803ecba0 100644 --- a/src/pkcs11/misc.c +++ b/src/pkcs11/misc.c @@ -305,6 +305,7 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, struct sc_context *ct /* Set defaults */ conf->num_slots = SC_PKCS11_MAX_VIRTUAL_SLOTS; conf->hide_empty_slots = 0; + conf->lock_login = 1; for (i = 0; ctx->conf_blocks[i] != NULL; i++) { blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], @@ -320,4 +321,5 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, struct sc_context *ct conf->num_slots = scconf_get_int(conf_block, "num_slots", conf->num_slots); conf->hide_empty_slots = scconf_get_bool(conf_block, "hide_empty_slots", 0); + conf->lock_login = scconf_get_bool(conf_block, "lock_login", 1); } diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index beb1eb64..8824be11 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -81,6 +81,7 @@ struct sc_pkcs11_pool { struct sc_pkcs11_config { unsigned int num_slots; unsigned char hide_empty_slots; + unsigned char lock_login; }; /*