[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