[pkg-opensc-commit] [opensc] 37/295: use sc_pkcs15_get_pin_info in C_GetTokenInfo
Eric Dorland
eric at moszumanska.debian.org
Sat Jun 24 21:11:14 UTC 2017
This is an automated email from the git hooks/post-receive script.
eric pushed a commit to branch master
in repository opensc.
commit 2f10de4f5c190e61bec4e6a582982404780f0d9b
Author: Frank Morgner <frankmorgner at gmail.com>
Date: Fri Jun 10 13:41:18 2016 +0200
use sc_pkcs15_get_pin_info in C_GetTokenInfo
introduced paramter to signal back the login state
- used for the pin command SC_PIN_CMD_GET_INFO
- implemented in accordance to ISO 7816-4; all other implementations
are currently set to an unknown login state
implemented and exporeted sc_pkcs15_get_pin_info
use sc_pkcs15_get_pin_info in C_GetTokenInfo
C_GetSessionInfo: Check whether a logout was done
Closes https://github.com/OpenSC/OpenSC/pull/624
rebased by @viktorTarasov
---
src/libopensc/card-authentic.c | 1 +
src/libopensc/card-epass2003.c | 1 +
src/libopensc/card-gids.c | 1 +
src/libopensc/card-iasecc.c | 1 +
src/libopensc/card-mcrd.c | 1 +
src/libopensc/iso7816.c | 6 ++++-
src/libopensc/libopensc.exports | 1 +
src/libopensc/opensc.h | 6 +++++
src/libopensc/pkcs15-pin.c | 40 ++++++++++++++++++++++++++++
src/libopensc/pkcs15.h | 4 ++-
src/pkcs11/framework-pkcs15.c | 59 +++++++++++++++++++++++++++--------------
src/pkcs11/pkcs11-session.c | 6 +++--
src/pkcs11/sc-pkcs11.h | 1 +
13 files changed, 104 insertions(+), 24 deletions(-)
diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c
index a4b32d6..8272a85 100644
--- a/src/libopensc/card-authentic.c
+++ b/src/libopensc/card-authentic.c
@@ -1561,6 +1561,7 @@ authentic_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data)
data->pin1.offset = 5;
data->pin1.pad_char = 0xFF;
data->pin1.pad_length = data->pin1.max_length;
+ data->pin1.logged_in = SC_PIN_STATE_UNKNOWN;
data->flags |= SC_PIN_CMD_NEED_PADDING;
diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c
index d4725c5..1727f25 100644
--- a/src/libopensc/card-epass2003.c
+++ b/src/libopensc/card-epass2003.c
@@ -2352,6 +2352,7 @@ epass2003_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries
LOG_TEST_RET(card->ctx, r, "get max counter failed");
data->pin1.max_tries = maxtries;
+ data->pin1.logged_in = SC_PIN_STATE_UNKNOWN;
}
return r;
diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c
index 4a79bf0..d7e8569 100644
--- a/src/libopensc/card-gids.c
+++ b/src/libopensc/card-gids.c
@@ -954,6 +954,7 @@ static int gids_get_pin_policy(struct sc_card *card, struct sc_pin_cmd_data *dat
data->pin1.stored_length = 0;
data->pin1.encoding = SC_PIN_ENCODING_ASCII;
data->pin1.offset = 5;
+ data->pin1.logged_in = SC_PIN_STATE_UNKNOWN;
return SC_SUCCESS;
}
diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c
index d8744e5..4fc53ca 100644
--- a/src/libopensc/card-iasecc.c
+++ b/src/libopensc/card-iasecc.c
@@ -2230,6 +2230,7 @@ iasecc_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data)
data->pin1.encoding = SC_PIN_ENCODING_ASCII;
data->pin1.offset = 5;
+ data->pin1.logged_in = SC_PIN_STATE_UNKNOWN;
sc_log(ctx, "PIN policy: size max/min %i/%i, tries max/left %i/%i",
data->pin1.max_length, data->pin1.min_length,
diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c
index 3c2c98b..dd456ce 100644
--- a/src/libopensc/card-mcrd.c
+++ b/src/libopensc/card-mcrd.c
@@ -1420,6 +1420,7 @@ static int mcrd_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data,
return SC_ERROR_INTERNAL;
data->pin1.tries_left = buf[5];
data->pin1.max_tries = buf[2];
+ data->pin1.logged_in = SC_PIN_STATE_UNKNOWN;
return SC_SUCCESS;
}
diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c
index 7ad7dc2..8f51799 100644
--- a/src/libopensc/iso7816.c
+++ b/src/libopensc/iso7816.c
@@ -1121,11 +1121,15 @@ iso7816_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_l
r = sc_check_sw(card, apdu->sw1, apdu->sw2);
if (data->cmd == SC_PIN_CMD_GET_INFO) {
- if (r == SC_ERROR_PIN_CODE_INCORRECT) {
+ if (r == SC_SUCCESS) {
+ data->pin1.logged_in = SC_PIN_STATE_LOGGED_IN;
+ } else if (r == SC_ERROR_PIN_CODE_INCORRECT) {
data->pin1.tries_left = apdu->sw2 & 0xF;
+ data->pin1.logged_in = SC_PIN_STATE_LOGGED_OUT;
r = SC_SUCCESS;
} else if (r == SC_ERROR_AUTH_METHOD_BLOCKED) {
data->pin1.tries_left = 0;
+ data->pin1.logged_in = SC_PIN_STATE_LOGGED_OUT;
r = SC_SUCCESS;
}
diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports
index 945afc5..87895f7 100644
--- a/src/libopensc/libopensc.exports
+++ b/src/libopensc/libopensc.exports
@@ -236,6 +236,7 @@ sc_pkcs15_search_objects
sc_pkcs15_unbind
sc_pkcs15_unblock_pin
sc_pkcs15_verify_pin
+sc_pkcs15_get_pin_info
sc_pkcs15emu_add_data_object
sc_pkcs15emu_add_pin_obj
sc_pkcs15emu_add_rsa_prkey
diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h
index c97154d..5a76fca 100644
--- a/src/libopensc/opensc.h
+++ b/src/libopensc/opensc.h
@@ -339,6 +339,11 @@ typedef struct sc_reader {
#define SC_PIN_ENCODING_BCD 1
#define SC_PIN_ENCODING_GLP 2 /* Global Platform - Card Specification v2.0.1 */
+/** Values for sc_pin_cmd_pin.logged_in */
+#define SC_PIN_STATE_UNKNOWN -1
+#define SC_PIN_STATE_LOGGED_OUT 0
+#define SC_PIN_STATE_LOGGED_IN 1
+
struct sc_pin_cmd_pin {
const char *prompt; /* Prompt to display */
@@ -359,6 +364,7 @@ struct sc_pin_cmd_pin {
int max_tries; /* Used for signaling back from SC_PIN_CMD_GET_INFO */
int tries_left; /* Used for signaling back from SC_PIN_CMD_GET_INFO */
+ int logged_in; /* Used for signaling back from SC_PIN_CMD_GET_INFO */
struct sc_acl_entry acls[SC_MAX_SDO_ACLS];
};
diff --git a/src/libopensc/pkcs15-pin.c b/src/libopensc/pkcs15-pin.c
index 5464a92..1bd1034 100644
--- a/src/libopensc/pkcs15-pin.c
+++ b/src/libopensc/pkcs15-pin.c
@@ -575,6 +575,46 @@ out:
LOG_FUNC_RETURN(ctx, r);
}
+int sc_pkcs15_get_pin_info(struct sc_pkcs15_card *p15card,
+ struct sc_pkcs15_object *pin_obj)
+{
+ int r;
+ struct sc_pin_cmd_data data;
+ struct sc_card *card = p15card->card;
+ struct sc_context *ctx = card->ctx;
+ struct sc_pkcs15_auth_info *pin_info = (struct sc_pkcs15_auth_info *) pin_obj->data;
+
+ LOG_FUNC_CALLED(ctx);
+
+ r = sc_lock(card);
+ if (r != SC_SUCCESS)
+ return r;
+
+ if (pin_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) {
+ r = SC_ERROR_INVALID_DATA;
+ goto out;
+ }
+
+ /* Try to update PIN info from card */
+ memset(&data, 0, sizeof(data));
+ data.cmd = SC_PIN_CMD_GET_INFO;
+ data.pin_type = SC_AC_CHV;
+ data.pin_reference = pin_info->attrs.pin.reference;
+
+ r = sc_pin_cmd(card, &data, NULL);
+ if (r == SC_SUCCESS) {
+ if (data.pin1.max_tries > 0)
+ pin_info->max_tries = data.pin1.max_tries;
+ /* tries_left must be supported or sc_pin_cmd should not return SC_SUCCESS */
+ pin_info->tries_left = data.pin1.tries_left;
+ pin_info->logged_in = data.pin1.logged_in;
+ }
+
+out:
+ sc_unlock(card);
+ LOG_FUNC_RETURN(ctx, r);
+}
+
void sc_pkcs15_free_auth_info(sc_pkcs15_auth_info_t *auth_info)
{
diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h
index 42d4fce..09ca2ea 100644
--- a/src/libopensc/pkcs15.h
+++ b/src/libopensc/pkcs15.h
@@ -129,7 +129,7 @@ struct sc_pkcs15_auth_info {
/* authentication method: CHV, SEN, SYMBOLIC, ... */
unsigned int auth_method;
- int tries_left, max_tries;
+ int tries_left, max_tries, logged_in;
int max_unlocks;
};
typedef struct sc_pkcs15_auth_info sc_pkcs15_auth_info_t;
@@ -749,6 +749,8 @@ int sc_pkcs15_unblock_pin(struct sc_pkcs15_card *card,
struct sc_pkcs15_object *pin_obj,
const u8 *puk, size_t puklen,
const u8 *newpin, size_t newpinlen);
+int sc_pkcs15_get_pin_info(struct sc_pkcs15_card *card,
+ struct sc_pkcs15_object *pin_obj);
int sc_pkcs15_find_pin_by_auth_id(struct sc_pkcs15_card *card,
const struct sc_pkcs15_id *id,
struct sc_pkcs15_object **out);
diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c
index 9fcea24..88f47f5 100644
--- a/src/pkcs11/framework-pkcs15.c
+++ b/src/pkcs11/framework-pkcs15.c
@@ -466,10 +466,10 @@ __pkcs15_delete_object(struct pkcs15_fw_data *fw_data, struct pkcs15_any_object
CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
{
struct sc_pkcs11_slot *slot;
+ struct pkcs15_fw_data *fw_data = NULL;
+ struct sc_pkcs15_card *p15card = NULL;
struct sc_pkcs15_object *auth;
struct sc_pkcs15_auth_info *pin_info;
- struct sc_pin_cmd_data data;
- int r;
CK_RV rv;
sc_log(context, "C_GetTokenInfo(%lx)", slotID);
@@ -486,6 +486,11 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
goto out;
}
+ fw_data = (struct pkcs15_fw_data *) slot->p11card->fws_data[slot->fw_data_idx];
+ if (!fw_data)
+ return sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_GetTokenInfo");
+ p15card = fw_data->p15_card;
+
/* User PIN flags are cleared before re-calculation */
slot->token_info.flags &= ~(CKF_USER_PIN_COUNT_LOW|CKF_USER_PIN_FINAL_TRY|CKF_USER_PIN_LOCKED);
auth = slot_data_auth(slot->fw_data);
@@ -493,24 +498,7 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
if (auth) {
pin_info = (struct sc_pkcs15_auth_info*) auth->data;
- if (pin_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) {
- rv = CKR_FUNCTION_REJECTED;
- goto out;
- }
-
- /* Try to update PIN info from card */
- memset(&data, 0, sizeof(data));
- data.cmd = SC_PIN_CMD_GET_INFO;
- data.pin_type = SC_AC_CHV;
- data.pin_reference = pin_info->attrs.pin.reference;
-
- r = sc_pin_cmd(slot->p11card->card, &data, NULL);
- if (r == SC_SUCCESS) {
- if (data.pin1.max_tries > 0)
- pin_info->max_tries = data.pin1.max_tries;
- /* tries_left must be supported or sc_pin_cmd should not return SC_SUCCESS */
- pin_info->tries_left = data.pin1.tries_left;
- }
+ sc_pkcs15_get_pin_info(p15card, auth);
if (pin_info->tries_left >= 0) {
if (pin_info->tries_left == 1 || pin_info->max_tries == 1)
@@ -1096,6 +1084,37 @@ _is_slot_auth_object(struct sc_pkcs15_auth_info *pin_info)
return 1;
}
+int slot_get_logged_in_state(struct sc_pkcs11_slot *slot)
+{
+ int logged_in = SC_PIN_STATE_UNKNOWN;
+ struct pkcs15_fw_data *fw_data = NULL;
+ struct sc_pkcs15_card *p15card = NULL;
+ struct sc_pkcs15_object *pin_obj = NULL;
+ struct sc_pkcs15_auth_info *pin_info;
+
+ fw_data = (struct pkcs15_fw_data *) slot->p11card->fws_data[slot->fw_data_idx];
+ if (!fw_data)
+ goto out;
+ p15card = fw_data->p15_card;
+
+ if (slot->login_user == CKU_SO) {
+ sc_pkcs15_find_so_pin(p15card, &pin_obj);
+ } else {
+ pin_obj = slot_data_auth(slot->fw_data);
+ }
+
+ if (!pin_obj)
+ goto out;
+
+ pin_info = (struct sc_pkcs15_auth_info *)pin_obj->data;
+ if (!pin_info)
+ goto out;
+ sc_pkcs15_get_pin_info(p15card, pin_obj);
+ logged_in = pin_info->logged_in;
+out:
+ return logged_in;
+}
+
struct sc_pkcs15_object *
_get_auth_object_by_name(struct sc_pkcs15_card *p15card, char *name)
diff --git a/src/pkcs11/pkcs11-session.c b/src/pkcs11/pkcs11-session.c
index 47110a9..270e1c3 100644
--- a/src/pkcs11/pkcs11-session.c
+++ b/src/pkcs11/pkcs11-session.c
@@ -180,6 +180,7 @@ CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, /* the session's handle */
CK_RV rv;
struct sc_pkcs11_session *session;
struct sc_pkcs11_slot *slot;
+ int logged_out;
if (pInfo == NULL_PTR)
return CKR_ARGUMENTS_BAD;
@@ -202,9 +203,10 @@ CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, /* the session's handle */
pInfo->ulDeviceError = 0;
slot = session->slot;
- if (slot->login_user == CKU_SO) {
+ logged_out = (slot_get_logged_in_state(slot) == SC_PIN_STATE_LOGGED_OUT);
+ if (slot->login_user == CKU_SO && !logged_out) {
pInfo->state = CKS_RW_SO_FUNCTIONS;
- } else if (slot->login_user == CKU_USER || (!(slot->token_info.flags & CKF_LOGIN_REQUIRED))) {
+ } else if ((slot->login_user == CKU_USER && !logged_out) || (!(slot->token_info.flags & CKF_LOGIN_REQUIRED))) {
pInfo->state = (session->flags & CKF_RW_SESSION)
? CKS_RW_USER_FUNCTIONS : CKS_RO_USER_FUNCTIONS;
} else {
diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h
index 21b92bb..ab05ba6 100644
--- a/src/pkcs11/sc-pkcs11.h
+++ b/src/pkcs11/sc-pkcs11.h
@@ -350,6 +350,7 @@ CK_RV slot_get_token(CK_SLOT_ID id, struct sc_pkcs11_slot **);
CK_RV slot_token_removed(CK_SLOT_ID id);
CK_RV slot_allocate(struct sc_pkcs11_slot **, struct sc_pkcs11_card *);
CK_RV slot_find_changed(CK_SLOT_ID_PTR idp, int mask);
+int slot_get_logged_in_state(struct sc_pkcs11_slot *slot);
/* Login tracking functions */
CK_RV restore_login_state(struct sc_pkcs11_slot *slot);
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-opensc/opensc.git
More information about the pkg-opensc-commit
mailing list