Implemented atomic PKCS#11 transactions
This commit is contained in:
parent
9cc7da4c80
commit
83ef753799
|
@ -594,6 +594,27 @@ app opensc-pkcs11 {
|
||||||
# Default: false
|
# Default: false
|
||||||
# lock_login = true;
|
# lock_login = true;
|
||||||
|
|
||||||
|
# By default, interacting with the OpenSC PKCS#11 module may change the
|
||||||
|
# state of the token, e.g. whether a user is logged in or not.
|
||||||
|
#
|
||||||
|
# Thus other users or other applications may change or use the state of
|
||||||
|
# the token unknowingly. Other applications may create signatures
|
||||||
|
# abusing an existing login or they may logout unnoticed.
|
||||||
|
#
|
||||||
|
# With this setting enabled the login state of the token is tracked and
|
||||||
|
# cached (including the PIN). Every transaction is preceeded by
|
||||||
|
# restoring the login state. After every transaction a logout is
|
||||||
|
# performed. This setting by default also enables `lock_login` (see
|
||||||
|
# above) to disable access for other applications during the atomic
|
||||||
|
# transactions.
|
||||||
|
#
|
||||||
|
# Please note that any PIN-pad should be disabled (see `enable_pinpad`
|
||||||
|
# above), because the user would have to input his PIN for every
|
||||||
|
# transaction.
|
||||||
|
#
|
||||||
|
# Default: false
|
||||||
|
# atomic = true;
|
||||||
|
|
||||||
# With this setting disabled, the OpenSC PKCS#11 module will initialize
|
# With this setting disabled, the OpenSC PKCS#11 module will initialize
|
||||||
# the slots available when the application calls `C_GetSlotList`. With
|
# the slots available when the application calls `C_GetSlotList`. With
|
||||||
# this setting enabled, the slots will also get initialized when
|
# this setting enabled, the slots will also get initialized when
|
||||||
|
|
|
@ -125,6 +125,7 @@ sc_list_files
|
||||||
sc_lock
|
sc_lock
|
||||||
sc_logout
|
sc_logout
|
||||||
sc_make_cache_dir
|
sc_make_cache_dir
|
||||||
|
sc_mem_alloc_secure
|
||||||
sc_mem_clear
|
sc_mem_clear
|
||||||
sc_mem_reverse
|
sc_mem_reverse
|
||||||
sc_match_atr_block
|
sc_match_atr_block
|
||||||
|
|
|
@ -127,6 +127,114 @@ CK_RV sc_to_cryptoki_error(int rc, const char *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct sc_pkcs11_login {
|
||||||
|
CK_USER_TYPE userType;
|
||||||
|
CK_CHAR_PTR pPin;
|
||||||
|
CK_ULONG ulPinLen;
|
||||||
|
};
|
||||||
|
|
||||||
|
CK_RV restore_login_state(struct sc_pkcs11_slot *slot)
|
||||||
|
{
|
||||||
|
CK_RV r = CKR_OK;
|
||||||
|
|
||||||
|
if (sc_pkcs11_conf.atomic && slot) {
|
||||||
|
if (list_iterator_start(&slot->logins)) {
|
||||||
|
struct sc_pkcs11_login *login = list_iterator_next(&slot->logins);
|
||||||
|
while (login) {
|
||||||
|
r = slot->p11card->framework->login(slot, login->userType,
|
||||||
|
login->pPin, login->ulPinLen);
|
||||||
|
if (r != CKR_OK)
|
||||||
|
break;
|
||||||
|
login = list_iterator_next(&slot->logins);
|
||||||
|
}
|
||||||
|
list_iterator_stop(&slot->logins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
CK_RV reset_login_state(struct sc_pkcs11_slot *slot)
|
||||||
|
{
|
||||||
|
if (sc_pkcs11_conf.atomic
|
||||||
|
&& slot && slot->p11card && slot->p11card->framework) {
|
||||||
|
slot->p11card->framework->logout(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CKR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
CK_RV push_login_state(struct sc_pkcs11_slot *slot,
|
||||||
|
CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
|
||||||
|
{
|
||||||
|
CK_RV r = CKR_HOST_MEMORY;
|
||||||
|
struct sc_pkcs11_login *login = NULL;
|
||||||
|
|
||||||
|
if (!sc_pkcs11_conf.atomic || !slot) {
|
||||||
|
r = CKR_OK;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
login = (struct sc_pkcs11_login *) malloc(sizeof *login);
|
||||||
|
if (login == NULL) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
login->pPin = sc_mem_alloc_secure(context, (sizeof *pPin)*ulPinLen);
|
||||||
|
if (login->pPin == NULL) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
memcpy(login->pPin, pPin, (sizeof *pPin)*ulPinLen);
|
||||||
|
login->ulPinLen = ulPinLen;
|
||||||
|
login->userType = userType;
|
||||||
|
|
||||||
|
if (0 > list_append(&slot->logins, login)) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = CKR_OK;
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (r != CKR_OK && login) {
|
||||||
|
sc_mem_clear(login->pPin, login->ulPinLen);
|
||||||
|
free(login->pPin);
|
||||||
|
free(login);
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop_login_state(struct sc_pkcs11_slot *slot)
|
||||||
|
{
|
||||||
|
if (slot) {
|
||||||
|
unsigned int size = list_size(&slot->logins);
|
||||||
|
if (size > 0) {
|
||||||
|
struct sc_pkcs11_login *login = list_get_at(&slot->logins, size-1);
|
||||||
|
if (login) {
|
||||||
|
sc_mem_clear(login->pPin, login->ulPinLen);
|
||||||
|
free(login->pPin);
|
||||||
|
free(login);
|
||||||
|
}
|
||||||
|
if (0 > list_delete_at(&slot->logins, size-1))
|
||||||
|
sc_log(context, "Error deleting login state");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop_all_login_states(struct sc_pkcs11_slot *slot)
|
||||||
|
{
|
||||||
|
if (sc_pkcs11_conf.atomic && slot) {
|
||||||
|
struct sc_pkcs11_login *login = list_fetch(&slot->logins);
|
||||||
|
while (login) {
|
||||||
|
sc_mem_clear(login->pPin, login->ulPinLen);
|
||||||
|
free(login->pPin);
|
||||||
|
free(login);
|
||||||
|
login = list_fetch(&slot->logins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Session manipulation */
|
/* Session manipulation */
|
||||||
CK_RV session_start_operation(struct sc_pkcs11_session * session,
|
CK_RV session_start_operation(struct sc_pkcs11_session * session,
|
||||||
int type, sc_pkcs11_mechanism_type_t * mech, struct sc_pkcs11_operation ** operation)
|
int type, sc_pkcs11_mechanism_type_t * mech, struct sc_pkcs11_operation ** operation)
|
||||||
|
@ -323,6 +431,7 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx)
|
||||||
conf->slots_per_card = 4;
|
conf->slots_per_card = 4;
|
||||||
}
|
}
|
||||||
conf->hide_empty_tokens = 1;
|
conf->hide_empty_tokens = 1;
|
||||||
|
conf->atomic = 0;
|
||||||
conf->lock_login = 0;
|
conf->lock_login = 0;
|
||||||
conf->init_sloppy = 1;
|
conf->init_sloppy = 1;
|
||||||
conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_NOT_ALLOWED;
|
conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_NOT_ALLOWED;
|
||||||
|
@ -339,6 +448,9 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx)
|
||||||
conf->max_virtual_slots = scconf_get_int(conf_block, "max_virtual_slots", conf->max_virtual_slots);
|
conf->max_virtual_slots = scconf_get_int(conf_block, "max_virtual_slots", conf->max_virtual_slots);
|
||||||
conf->slots_per_card = scconf_get_int(conf_block, "slots_per_card", conf->slots_per_card);
|
conf->slots_per_card = scconf_get_int(conf_block, "slots_per_card", conf->slots_per_card);
|
||||||
conf->hide_empty_tokens = scconf_get_bool(conf_block, "hide_empty_tokens", conf->hide_empty_tokens);
|
conf->hide_empty_tokens = scconf_get_bool(conf_block, "hide_empty_tokens", conf->hide_empty_tokens);
|
||||||
|
conf->atomic = scconf_get_bool(conf_block, "atomic", conf->atomic);
|
||||||
|
if (conf->atomic)
|
||||||
|
conf->lock_login = 1;
|
||||||
conf->lock_login = scconf_get_bool(conf_block, "lock_login", conf->lock_login);
|
conf->lock_login = scconf_get_bool(conf_block, "lock_login", conf->lock_login);
|
||||||
conf->init_sloppy = scconf_get_bool(conf_block, "init_sloppy", conf->init_sloppy);
|
conf->init_sloppy = scconf_get_bool(conf_block, "init_sloppy", conf->init_sloppy);
|
||||||
|
|
||||||
|
@ -371,9 +483,9 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx)
|
||||||
free(tmp);
|
free(tmp);
|
||||||
|
|
||||||
sc_log(ctx, "PKCS#11 options: plug_and_play=%d max_virtual_slots=%d slots_per_card=%d "
|
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 "
|
"hide_empty_tokens=%d lock_login=%d atomic=%d pin_unblock_style=%d "
|
||||||
"zero_ckaid_for_ca_certs=%d create_slots_flags=0x%X",
|
"zero_ckaid_for_ca_certs=%d create_slots_flags=0x%X",
|
||||||
conf->plug_and_play, conf->max_virtual_slots, conf->slots_per_card,
|
conf->plug_and_play, conf->max_virtual_slots, conf->slots_per_card,
|
||||||
conf->hide_empty_tokens, conf->lock_login, conf->pin_unblock_style,
|
conf->hide_empty_tokens, conf->lock_login, conf->atomic, conf->pin_unblock_style,
|
||||||
conf->zero_ckaid_for_ca_certs, conf->create_slots_flags);
|
conf->zero_ckaid_for_ca_certs, conf->create_slots_flags);
|
||||||
}
|
}
|
||||||
|
|
|
@ -324,6 +324,8 @@ CK_RV C_Finalize(CK_VOID_PTR pReserved)
|
||||||
|
|
||||||
while ((slot = list_fetch(&virtual_slots))) {
|
while ((slot = list_fetch(&virtual_slots))) {
|
||||||
list_destroy(&slot->objects);
|
list_destroy(&slot->objects);
|
||||||
|
pop_all_login_states(slot);
|
||||||
|
list_destroy(&slot->logins);
|
||||||
free(slot);
|
free(slot);
|
||||||
}
|
}
|
||||||
list_destroy(&virtual_slots);
|
list_destroy(&virtual_slots);
|
||||||
|
|
|
@ -541,7 +541,8 @@ C_Digest(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
if (rv == CKR_OK)
|
if (rv == CKR_OK)
|
||||||
rv = sc_pkcs11_md_final(session, pDigest, pulDigestLen);
|
rv = sc_pkcs11_md_final(session, pDigest, pulDigestLen);
|
||||||
|
|
||||||
out: sc_log(context, "C_Digest() = %s", lookup_enum ( RV_T, rv ));
|
out:
|
||||||
|
sc_log(context, "C_Digest() = %s", lookup_enum ( RV_T, rv ));
|
||||||
sc_pkcs11_unlock();
|
sc_pkcs11_unlock();
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -685,8 +686,16 @@ C_Sign(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = sc_pkcs11_sign_update(session, pData, ulDataLen);
|
rv = sc_pkcs11_sign_update(session, pData, ulDataLen);
|
||||||
if (rv == CKR_OK)
|
if (rv == CKR_OK) {
|
||||||
rv = sc_pkcs11_sign_final(session, pSignature, pulSignatureLen);
|
rv = restore_login_state(session->slot);
|
||||||
|
if (rv == CKR_OK)
|
||||||
|
rv = sc_pkcs11_sign_final(session, pSignature, pulSignatureLen);
|
||||||
|
if (rv == CKR_OK) {
|
||||||
|
rv = reset_login_state(session->slot);
|
||||||
|
} else {
|
||||||
|
reset_login_state(session->slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
sc_log(context, "C_Sign() = %s", lookup_enum ( RV_T, rv ));
|
sc_log(context, "C_Sign() = %s", lookup_enum ( RV_T, rv ));
|
||||||
|
@ -746,7 +755,14 @@ C_SignFinal(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
*pulSignatureLen = length;
|
*pulSignatureLen = length;
|
||||||
rv = pSignature ? CKR_BUFFER_TOO_SMALL : CKR_OK;
|
rv = pSignature ? CKR_BUFFER_TOO_SMALL : CKR_OK;
|
||||||
} else {
|
} else {
|
||||||
rv = sc_pkcs11_sign_final(session, pSignature, pulSignatureLen);
|
rv = restore_login_state(session->slot);
|
||||||
|
if (rv == CKR_OK)
|
||||||
|
rv = sc_pkcs11_sign_final(session, pSignature, pulSignatureLen);
|
||||||
|
if (rv == CKR_OK) {
|
||||||
|
rv = reset_login_state(session->slot);
|
||||||
|
} else {
|
||||||
|
reset_login_state(session->slot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -859,7 +875,8 @@ CK_RV C_DecryptInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
|
|
||||||
rv = sc_pkcs11_decr_init(session, pMechanism, object, key_type);
|
rv = sc_pkcs11_decr_init(session, pMechanism, object, key_type);
|
||||||
|
|
||||||
out: sc_log(context, "C_DecryptInit() = %s", lookup_enum ( RV_T, rv ));
|
out:
|
||||||
|
sc_log(context, "C_DecryptInit() = %s", lookup_enum ( RV_T, rv ));
|
||||||
sc_pkcs11_unlock();
|
sc_pkcs11_unlock();
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -878,9 +895,18 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
rv = get_session(hSession, &session);
|
rv = get_session(hSession, &session);
|
||||||
if (rv == CKR_OK)
|
if (rv == CKR_OK) {
|
||||||
rv = sc_pkcs11_decr(session, pEncryptedData, ulEncryptedDataLen,
|
rv = restore_login_state(session->slot);
|
||||||
pData, pulDataLen);
|
if (rv == CKR_OK) {
|
||||||
|
rv = sc_pkcs11_decr(session, pEncryptedData,
|
||||||
|
ulEncryptedDataLen, pData, pulDataLen);
|
||||||
|
}
|
||||||
|
if (rv == CKR_OK) {
|
||||||
|
rv = reset_login_state(session->slot);
|
||||||
|
} else {
|
||||||
|
reset_login_state(session->slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sc_log(context, "C_Decrypt() = %s", lookup_enum ( RV_T, rv ));
|
sc_log(context, "C_Decrypt() = %s", lookup_enum ( RV_T, rv ));
|
||||||
sc_pkcs11_unlock();
|
sc_pkcs11_unlock();
|
||||||
|
@ -985,11 +1011,19 @@ CK_RV C_GenerateKeyPair(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
slot = session->slot;
|
slot = session->slot;
|
||||||
if (slot->p11card->framework->gen_keypair == NULL)
|
if (slot->p11card->framework->gen_keypair == NULL)
|
||||||
rv = CKR_FUNCTION_NOT_SUPPORTED;
|
rv = CKR_FUNCTION_NOT_SUPPORTED;
|
||||||
else
|
else {
|
||||||
rv = slot->p11card->framework->gen_keypair(slot, pMechanism,
|
rv = restore_login_state(slot);
|
||||||
pPublicKeyTemplate, ulPublicKeyAttributeCount,
|
if (rv == CKR_OK)
|
||||||
pPrivateKeyTemplate, ulPrivateKeyAttributeCount,
|
rv = slot->p11card->framework->gen_keypair(slot, pMechanism,
|
||||||
phPublicKey, phPrivateKey);
|
pPublicKeyTemplate, ulPublicKeyAttributeCount,
|
||||||
|
pPrivateKeyTemplate, ulPrivateKeyAttributeCount,
|
||||||
|
phPublicKey, phPrivateKey);
|
||||||
|
if (rv == CKR_OK) {
|
||||||
|
rv = reset_login_state(session->slot);
|
||||||
|
} else {
|
||||||
|
reset_login_state(session->slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
sc_pkcs11_unlock();
|
sc_pkcs11_unlock();
|
||||||
|
@ -1084,9 +1118,16 @@ CK_RV C_DeriveKey(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = sc_pkcs11_deri(session, pMechanism, object, key_type,
|
rv = restore_login_state(session->slot);
|
||||||
hSession, *phKey, key_object);
|
if (rv == CKR_OK)
|
||||||
|
rv = sc_pkcs11_deri(session, pMechanism, object, key_type,
|
||||||
|
hSession, *phKey, key_object);
|
||||||
/* TODO if (rv != CK_OK) need to destroy the object */
|
/* TODO if (rv != CK_OK) need to destroy the object */
|
||||||
|
if (rv == CKR_OK) {
|
||||||
|
rv = reset_login_state(session->slot);
|
||||||
|
} else {
|
||||||
|
reset_login_state(session->slot);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1175,7 +1216,8 @@ CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
|
|
||||||
rv = sc_pkcs11_verif_init(session, pMechanism, object, key_type);
|
rv = sc_pkcs11_verif_init(session, pMechanism, object, key_type);
|
||||||
|
|
||||||
out: sc_log(context, "C_VerifyInit() = %s", lookup_enum ( RV_T, rv ));
|
out:
|
||||||
|
sc_log(context, "C_VerifyInit() = %s", lookup_enum ( RV_T, rv ));
|
||||||
sc_pkcs11_unlock();
|
sc_pkcs11_unlock();
|
||||||
return rv;
|
return rv;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1202,10 +1244,19 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rv = sc_pkcs11_verif_update(session, pData, ulDataLen);
|
rv = sc_pkcs11_verif_update(session, pData, ulDataLen);
|
||||||
if (rv == CKR_OK)
|
if (rv == CKR_OK) {
|
||||||
rv = sc_pkcs11_verif_final(session, pSignature, ulSignatureLen);
|
rv = restore_login_state(session->slot);
|
||||||
|
if (rv == CKR_OK)
|
||||||
|
rv = sc_pkcs11_verif_final(session, pSignature, ulSignatureLen);
|
||||||
|
if (rv == CKR_OK) {
|
||||||
|
rv = reset_login_state(session->slot);
|
||||||
|
} else {
|
||||||
|
reset_login_state(session->slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
out: sc_log(context, "C_Verify() = %s", lookup_enum ( RV_T, rv ));
|
out:
|
||||||
|
sc_log(context, "C_Verify() = %s", lookup_enum ( RV_T, rv ));
|
||||||
sc_pkcs11_unlock();
|
sc_pkcs11_unlock();
|
||||||
return rv;
|
return rv;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1250,8 +1301,16 @@ CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
rv = get_session(hSession, &session);
|
rv = get_session(hSession, &session);
|
||||||
if (rv == CKR_OK)
|
if (rv == CKR_OK) {
|
||||||
rv = sc_pkcs11_verif_final(session, pSignature, ulSignatureLen);
|
rv = restore_login_state(session->slot);
|
||||||
|
if (rv == CKR_OK)
|
||||||
|
rv = sc_pkcs11_verif_final(session, pSignature, ulSignatureLen);
|
||||||
|
if (rv == CKR_OK) {
|
||||||
|
rv = reset_login_state(session->slot);
|
||||||
|
} else {
|
||||||
|
reset_login_state(session->slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sc_log(context, "C_VerifyFinal() = %s", lookup_enum ( RV_T, rv ));
|
sc_log(context, "C_VerifyFinal() = %s", lookup_enum ( RV_T, rv ));
|
||||||
sc_pkcs11_unlock();
|
sc_pkcs11_unlock();
|
||||||
|
|
|
@ -107,7 +107,10 @@ static CK_RV sc_pkcs11_close_session(CK_SESSION_HANDLE hSession)
|
||||||
slot->nsessions--;
|
slot->nsessions--;
|
||||||
if (slot->nsessions == 0 && slot->login_user >= 0) {
|
if (slot->nsessions == 0 && slot->login_user >= 0) {
|
||||||
slot->login_user = -1;
|
slot->login_user = -1;
|
||||||
slot->p11card->framework->logout(slot);
|
if (sc_pkcs11_conf.atomic)
|
||||||
|
pop_all_login_states(slot);
|
||||||
|
else
|
||||||
|
slot->p11card->framework->logout(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (list_delete(&sessions, session) != 0)
|
if (list_delete(&sessions, session) != 0)
|
||||||
|
@ -166,7 +169,8 @@ CK_RV C_CloseAllSessions(CK_SLOT_ID slotID)
|
||||||
|
|
||||||
rv = sc_pkcs11_close_all_sessions(slotID);
|
rv = sc_pkcs11_close_all_sessions(slotID);
|
||||||
|
|
||||||
out:sc_pkcs11_unlock();
|
out:
|
||||||
|
sc_pkcs11_unlock();
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,10 +273,16 @@ CK_RV C_Login(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
if (userType == CKU_CONTEXT_SPECIFIC) {
|
if (userType == CKU_CONTEXT_SPECIFIC) {
|
||||||
if (slot->login_user == -1) {
|
if (slot->login_user == -1) {
|
||||||
rv = CKR_OPERATION_NOT_INITIALIZED;
|
rv = CKR_OPERATION_NOT_INITIALIZED;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rv = slot->p11card->framework->login(slot, userType, pPin, ulPinLen);
|
rv = restore_login_state(slot);
|
||||||
|
if (rv == CKR_OK)
|
||||||
|
rv = slot->p11card->framework->login(slot, userType, pPin, ulPinLen);
|
||||||
|
if (rv == CKR_OK) {
|
||||||
|
rv = reset_login_state(session->slot);
|
||||||
|
} else {
|
||||||
|
reset_login_state(session->slot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -285,11 +295,20 @@ CK_RV C_Login(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
sc_log(context, "C_Login() userType %li", userType);
|
rv = restore_login_state(slot);
|
||||||
rv = slot->p11card->framework->login(slot, userType, pPin, ulPinLen);
|
if (rv == CKR_OK) {
|
||||||
sc_log(context, "fLogin() rv %li", rv);
|
sc_log(context, "C_Login() userType %li", userType);
|
||||||
|
rv = slot->p11card->framework->login(slot, userType, pPin, ulPinLen);
|
||||||
|
sc_log(context, "fLogin() rv %li", rv);
|
||||||
|
}
|
||||||
if (rv == CKR_OK)
|
if (rv == CKR_OK)
|
||||||
|
rv = push_login_state(slot, userType, pPin, ulPinLen);
|
||||||
|
if (rv == CKR_OK) {
|
||||||
slot->login_user = userType;
|
slot->login_user = userType;
|
||||||
|
rv = reset_login_state(session->slot);
|
||||||
|
} else {
|
||||||
|
reset_login_state(session->slot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -319,11 +338,15 @@ CK_RV C_Logout(CK_SESSION_HANDLE hSession)
|
||||||
|
|
||||||
if (slot->login_user >= 0) {
|
if (slot->login_user >= 0) {
|
||||||
slot->login_user = -1;
|
slot->login_user = -1;
|
||||||
rv = slot->p11card->framework->logout(slot);
|
if (sc_pkcs11_conf.atomic)
|
||||||
|
pop_all_login_states(slot);
|
||||||
|
else
|
||||||
|
rv = slot->p11card->framework->logout(slot);
|
||||||
} else
|
} else
|
||||||
rv = CKR_USER_NOT_LOGGED_IN;
|
rv = CKR_USER_NOT_LOGGED_IN;
|
||||||
|
|
||||||
out:sc_pkcs11_unlock();
|
out:
|
||||||
|
sc_pkcs11_unlock();
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,8 +381,16 @@ CK_RV C_InitPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
|
||||||
} else if (slot->p11card->framework->init_pin == NULL) {
|
} else if (slot->p11card->framework->init_pin == NULL) {
|
||||||
rv = CKR_FUNCTION_NOT_SUPPORTED;
|
rv = CKR_FUNCTION_NOT_SUPPORTED;
|
||||||
} else {
|
} else {
|
||||||
rv = slot->p11card->framework->init_pin(slot, pPin, ulPinLen);
|
rv = restore_login_state(slot);
|
||||||
sc_log(context, "C_InitPIN() init-pin result %li", rv);
|
if (rv == CKR_OK) {
|
||||||
|
rv = slot->p11card->framework->init_pin(slot, pPin, ulPinLen);
|
||||||
|
sc_log(context, "C_InitPIN() init-pin result %li", rv);
|
||||||
|
}
|
||||||
|
if (rv == CKR_OK) {
|
||||||
|
rv = reset_login_state(session->slot);
|
||||||
|
} else {
|
||||||
|
reset_login_state(session->slot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -395,7 +426,15 @@ CK_RV C_SetPIN(CK_SESSION_HANDLE hSession,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = slot->p11card->framework->change_pin(slot, pOldPin, ulOldLen, pNewPin, ulNewLen);
|
rv = restore_login_state(slot);
|
||||||
|
if (rv == CKR_OK)
|
||||||
|
rv = slot->p11card->framework->change_pin(slot, pOldPin, ulOldLen, pNewPin, ulNewLen);
|
||||||
|
if (rv == CKR_OK) {
|
||||||
|
rv = reset_login_state(session->slot);
|
||||||
|
} else {
|
||||||
|
reset_login_state(session->slot);
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
sc_pkcs11_unlock();
|
sc_pkcs11_unlock();
|
||||||
return rv;
|
return rv;
|
||||||
|
|
|
@ -78,6 +78,7 @@ struct sc_pkcs11_config {
|
||||||
unsigned int slots_per_card;
|
unsigned int slots_per_card;
|
||||||
unsigned char hide_empty_tokens;
|
unsigned char hide_empty_tokens;
|
||||||
unsigned char lock_login;
|
unsigned char lock_login;
|
||||||
|
unsigned char atomic;
|
||||||
unsigned char init_sloppy;
|
unsigned char init_sloppy;
|
||||||
unsigned int pin_unblock_style;
|
unsigned int pin_unblock_style;
|
||||||
unsigned int create_puk_slot;
|
unsigned int create_puk_slot;
|
||||||
|
@ -218,6 +219,7 @@ struct sc_pkcs11_slot {
|
||||||
|
|
||||||
int fw_data_idx; /* Index of framework data */
|
int fw_data_idx; /* Index of framework data */
|
||||||
struct sc_app_info *app_info; /* Application assosiated to slot */
|
struct sc_app_info *app_info; /* Application assosiated to slot */
|
||||||
|
list_t logins; /* tracks all calls to C_Login if atomic operations are requested */
|
||||||
};
|
};
|
||||||
typedef struct sc_pkcs11_slot sc_pkcs11_slot_t;
|
typedef struct sc_pkcs11_slot sc_pkcs11_slot_t;
|
||||||
|
|
||||||
|
@ -348,6 +350,14 @@ CK_RV slot_token_removed(CK_SLOT_ID id);
|
||||||
CK_RV slot_allocate(struct sc_pkcs11_slot **, struct sc_pkcs11_card *);
|
CK_RV slot_allocate(struct sc_pkcs11_slot **, struct sc_pkcs11_card *);
|
||||||
CK_RV slot_find_changed(CK_SLOT_ID_PTR idp, int mask);
|
CK_RV slot_find_changed(CK_SLOT_ID_PTR idp, int mask);
|
||||||
|
|
||||||
|
/* Login tracking functions */
|
||||||
|
CK_RV restore_login_state(struct sc_pkcs11_slot *slot);
|
||||||
|
CK_RV reset_login_state(struct sc_pkcs11_slot *slot);
|
||||||
|
CK_RV push_login_state(struct sc_pkcs11_slot *slot,
|
||||||
|
CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG ulPinLen);
|
||||||
|
void pop_login_state(struct sc_pkcs11_slot *slot);
|
||||||
|
void pop_all_login_states(struct sc_pkcs11_slot *slot);
|
||||||
|
|
||||||
/* Session manipulation */
|
/* Session manipulation */
|
||||||
CK_RV get_session(CK_SESSION_HANDLE hSession, struct sc_pkcs11_session ** session);
|
CK_RV get_session(CK_SESSION_HANDLE hSession, struct sc_pkcs11_session ** session);
|
||||||
CK_RV session_start_operation(struct sc_pkcs11_session *,
|
CK_RV session_start_operation(struct sc_pkcs11_session *,
|
||||||
|
|
|
@ -92,6 +92,8 @@ CK_RV create_slot(sc_reader_t *reader)
|
||||||
list_init(&slot->objects);
|
list_init(&slot->objects);
|
||||||
list_attributes_seeker(&slot->objects, object_list_seeker);
|
list_attributes_seeker(&slot->objects, object_list_seeker);
|
||||||
|
|
||||||
|
list_init(&slot->logins);
|
||||||
|
|
||||||
init_slot_info(&slot->slot_info);
|
init_slot_info(&slot->slot_info);
|
||||||
if (reader != NULL) {
|
if (reader != NULL) {
|
||||||
slot->reader = reader;
|
slot->reader = reader;
|
||||||
|
|
Loading…
Reference in New Issue