[pkg-opensc-commit] [opensc] 257/295: minidriver: added support for session pin
Eric Dorland
eric at moszumanska.debian.org
Sat Jun 24 21:11:38 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 7c3bb44cdf3b4b287182a443a348e5ec92d5da39
Author: Frank Morgner <frankmorgner at gmail.com>
Date: Wed Mar 1 17:53:44 2017 +0100
minidriver: added support for session pin
---
src/libopensc/libopensc.exports | 1 +
src/libopensc/pkcs15-pin.c | 40 +++++++++++++++++++-
src/libopensc/pkcs15.h | 4 ++
src/minidriver/minidriver.c | 83 +++++++++++++++++++++++++++++++++--------
4 files changed, 112 insertions(+), 16 deletions(-)
diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports
index 18f8037..70e1505 100644
--- a/src/libopensc/libopensc.exports
+++ b/src/libopensc/libopensc.exports
@@ -237,6 +237,7 @@ sc_pkcs15_unbind
sc_pkcs15_unblock_pin
sc_pkcs15_verify_pin
sc_pkcs15_get_pin_info
+sc_pkcs15_verify_pin_with_session_pin
sc_pkcs15emu_add_data_object
sc_pkcs15emu_add_pin_obj
sc_pkcs15emu_add_rsa_prkey
diff --git a/src/libopensc/pkcs15-pin.c b/src/libopensc/pkcs15-pin.c
index 28a39b7..1c7df89 100644
--- a/src/libopensc/pkcs15-pin.c
+++ b/src/libopensc/pkcs15-pin.c
@@ -331,6 +331,22 @@ int
_sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *pin_obj,
const unsigned char *pincode, size_t pinlen)
{
+ return sc_pkcs15_verify_pin_with_session_pin(p15card, pin_obj, pincode,
+ pinlen, NULL, NULL);
+}
+
+/*
+ * Verify a PIN and generate a session PIN
+ *
+ * If the code given to us has zero length, this means we
+ * should ask the card reader to obtain the PIN from the
+ * reader's PIN pad
+ */
+int sc_pkcs15_verify_pin_with_session_pin(struct sc_pkcs15_card *p15card,
+ struct sc_pkcs15_object *pin_obj,
+ const unsigned char *pincode, size_t pinlen,
+ const unsigned char *sessionpin, size_t *sessionpinlen)
+{
struct sc_context *ctx = p15card->card->ctx;
struct sc_pkcs15_auth_info *auth_info = (struct sc_pkcs15_auth_info *)pin_obj->data;
int r;
@@ -350,7 +366,6 @@ _sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *p
/* Initialize arguments */
memset(&data, 0, sizeof(data));
- data.cmd = SC_PIN_CMD_VERIFY;
data.pin_type = auth_info->auth_method;
if (auth_info->auth_type == SC_PKCS15_PIN_AUTH_TYPE_PIN) {
@@ -404,6 +419,19 @@ _sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *p
data.pin1.prompt = "Please enter PIN";
}
+ if (card->caps & SC_CARD_CAP_SESSION_PIN && sessionpin && sessionpinlen) {
+ /* session pin is requested and supported with standard verification*/
+ data.cmd = SC_PIN_CMD_GET_SESSION_PIN;
+ memcpy(&data.pin2, &data.pin1, sizeof (data.pin1));
+ data.pin2.data = sessionpin;
+ data.pin2.len = *sessionpinlen;
+ } else {
+ /* perform a standard verify */
+ data.cmd = SC_PIN_CMD_VERIFY;
+ if (sessionpinlen)
+ *sessionpinlen = 0;
+ }
+
r = sc_lock(card);
LOG_TEST_RET(ctx, r, "sc_lock() failed");
@@ -416,6 +444,16 @@ _sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *p
r = sc_pin_cmd(card, &data, &auth_info->tries_left);
sc_log(ctx, "PIN cmd result %i", r);
+ if (r == SC_SUCCESS) {
+ sc_pkcs15_pincache_add(p15card, pin_obj, pincode, pinlen);
+ if (data.cmd == SC_PIN_CMD_GET_SESSION_PIN) {
+ *sessionpinlen = data.pin2.len;
+ }
+ } else {
+ if (data.cmd == SC_PIN_CMD_GET_SESSION_PIN) {
+ *sessionpinlen = 0;
+ }
+ }
out:
sc_unlock(card);
LOG_FUNC_RETURN(ctx, r);
diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h
index 1746cd3..5352f9f 100644
--- a/src/libopensc/pkcs15.h
+++ b/src/libopensc/pkcs15.h
@@ -767,6 +767,10 @@ int sc_pkcs15_find_skey_by_id(struct sc_pkcs15_card *card,
int sc_pkcs15_verify_pin(struct sc_pkcs15_card *card,
struct sc_pkcs15_object *pin_obj,
const u8 *pincode, size_t pinlen);
+int sc_pkcs15_verify_pin_with_session_pin(struct sc_pkcs15_card *p15card,
+ struct sc_pkcs15_object *pin_obj,
+ const unsigned char *pincode, size_t pinlen,
+ const unsigned char *sessionpin, size_t *sessionpinlen);
int sc_pkcs15_change_pin(struct sc_pkcs15_card *card,
struct sc_pkcs15_object *pin_obj,
const u8 *oldpincode, size_t oldpinlen,
diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c
index 34b1288..0e6ab78 100644
--- a/src/minidriver/minidriver.c
+++ b/src/minidriver/minidriver.c
@@ -2346,18 +2346,21 @@ md_dialog_perform_pin_operation_thread(PVOID lpParameter)
const u8 *pin1 = (const u8 *) parameter[3];
size_t pin1len = parameter[4];
const u8 *pin2 = (const u8 *) parameter[5];
- size_t pin2len = parameter[6];
+ size_t *pin2len = (size_t *) parameter[6];
int rv = 0;
switch (operation)
{
case SC_PIN_CMD_VERIFY:
rv = sc_pkcs15_verify_pin(p15card, pin_obj, pin1, pin1len);
break;
+ case SC_PIN_CMD_GET_SESSION_PIN:
+ rv = sc_pkcs15_verify_pin_with_session_pin(p15card, pin_obj, pin1, pin1len, pin2, pin2len);
+ break;
case SC_PIN_CMD_CHANGE:
- rv = sc_pkcs15_change_pin(p15card, pin_obj, pin1, pin1len,pin2, pin2len);
+ rv = sc_pkcs15_change_pin(p15card, pin_obj, pin1, pin1len,pin2, pin2len ? *pin2len : 0);
break;
case SC_PIN_CMD_UNBLOCK:
- rv = sc_pkcs15_unblock_pin(p15card, pin_obj, pin1, pin1len,pin2, pin2len);
+ rv = sc_pkcs15_unblock_pin(p15card, pin_obj, pin1, pin1len,pin2, pin2len ? *pin2len : 0);
break;
default:
rv = (DWORD) ERROR_INVALID_PARAMETER;
@@ -2421,7 +2424,7 @@ static int
md_dialog_perform_pin_operation(PCARD_DATA pCardData, int operation, struct sc_pkcs15_card *p15card,
struct sc_pkcs15_object *pin_obj,
const u8 *pin1, size_t pin1len,
- const u8 *pin2, size_t pin2len, BOOL displayUI)
+ const u8 *pin2, size_t *pin2len, BOOL displayUI)
{
LONG_PTR parameter[10];
INT_PTR result = 0;
@@ -4750,6 +4753,7 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData,
VENDOR_SPECIFIC *vs;
struct sc_pkcs15_object *pin_obj = NULL;
struct sc_pkcs15_auth_info *auth_info = NULL;
+ unsigned int auth_method;
int r;
BOOL DisplayPinpadUI = FALSE;
@@ -4773,11 +4777,16 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData,
if ((vs->p15card) == NULL)
return SCARD_F_INTERNAL_ERROR;
+#if 0
+ /* TODO do we need to return SCARD_E_UNSUPPORTED_FEATURE if the card
+ * doesn't support it or if the minidriver doesn't support it in general?
+ * */
if (dwFlags == CARD_AUTHENTICATE_GENERATE_SESSION_PIN || dwFlags == CARD_AUTHENTICATE_SESSION_PIN) {
if (! (vs->reader->capabilities & SC_READER_CAP_PIN_PAD
|| vs->p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH))
return SCARD_E_UNSUPPORTED_FEATURE;
}
+#endif
if (dwFlags & ~(CARD_AUTHENTICATE_GENERATE_SESSION_PIN | CARD_AUTHENTICATE_SESSION_PIN | CARD_PIN_SILENT_CONTEXT))
return SCARD_E_INVALID_PARAMETER;
@@ -4808,6 +4817,8 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData,
if (!pin_obj)
return SCARD_F_INTERNAL_ERROR;
auth_info = (struct sc_pkcs15_auth_info *)pin_obj->data;
+ /* save the pin type */
+ auth_method = auth_info->auth_method;
/* Do we need to display a prompt to enter PIN on pin pad? */
logprintf(pCardData, 7, "PIN pad=%s, pbPinData=%p, hwndParent=%p\n",
@@ -4815,13 +4826,53 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData,
|| vs->p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH
? "yes" : "no", pbPinData, vs->hwndParent);
- /* check if the pin is the session pin generated by a previous authentication with a pinpad */
- if (pbPinData != NULL && cbPinData == sizeof(MAGIC_SESSION_PIN) && memcmp(MAGIC_SESSION_PIN, pbPinData, sizeof(MAGIC_SESSION_PIN)) == 0) {
- pbPinData = NULL;
- cbPinData = 0;
+ if (dwFlags & CARD_AUTHENTICATE_SESSION_PIN) {
+ /* check if the pin is the session pin generated by a previous authentication with a pinpad */
+ if (pbPinData != NULL && cbPinData == sizeof(MAGIC_SESSION_PIN) && memcmp(MAGIC_SESSION_PIN, pbPinData, sizeof(MAGIC_SESSION_PIN)) == 0) {
+ logprintf(pCardData, 2, "use magic session pin");
+ pbPinData = NULL;
+ cbPinData = 0;
+ } else {
+ /* seems we have a real session pin, set the pin type accordingly */
+ logprintf(pCardData, 2, "use real session pin with %d bytes", cbPinData);
+ auth_info->auth_method = SC_AC_SESSION;
+ }
+ }
+
+ /* set the session pin according to the minidriver specification */
+ if (dwFlags & CARD_AUTHENTICATE_GENERATE_SESSION_PIN) {
+ logprintf(pCardData, 2, "generating session pin");
+ if (ppbSessionPin) *ppbSessionPin = pCardData->pfnCspAlloc(SC_MAX_PIN_SIZE);
+ if (ppbSessionPin) *pcbSessionPin = SC_MAX_PIN_SIZE;
+ r = md_dialog_perform_pin_operation(pCardData, SC_PIN_CMD_GET_SESSION_PIN, vs->p15card, pin_obj, (const u8 *) pbPinData, cbPinData,
+ ppbSessionPin && *ppbSessionPin ? *ppbSessionPin : NULL, pcbSessionPin, DisplayPinpadUI);
+ if (r) {
+ if (ppbSessionPin) {
+ pCardData->pfnCspFree(*ppbSessionPin);
+ *ppbSessionPin = NULL;
+ }
+ if (pcbSessionPin) *pcbSessionPin = 0;
+ logprintf(pCardData, 2, "generating session pin failed");
+ } else {
+ if (pcbSessionPin && *pcbSessionPin) {
+ logprintf(pCardData, 2, "generated session pin with %d bytes", *pcbSessionPin);
+ } else {
+ logprintf(pCardData, 2, "session pin not supported");
+ if (ppbSessionPin) {
+ pCardData->pfnCspFree(*ppbSessionPin);
+ *ppbSessionPin = NULL;
+ }
+ }
+ }
+ } else {
+ if (pcbSessionPin) *pcbSessionPin = 0;
+ if (ppbSessionPin) *ppbSessionPin = NULL;
+ logprintf(pCardData, 2, "standard pin verification");
+ r = md_dialog_perform_pin_operation(pCardData, SC_PIN_CMD_VERIFY, vs->p15card, pin_obj, (const u8 *) pbPinData, cbPinData, NULL, NULL, DisplayPinpadUI);
}
- r = md_dialog_perform_pin_operation(pCardData, SC_PIN_CMD_VERIFY, vs->p15card, pin_obj, (const u8 *) pbPinData, cbPinData, NULL, 0, DisplayPinpadUI);
+ /* restore the pin type */
+ auth_info->auth_method = auth_method;
if (r) {
logprintf(pCardData, 1, "PIN code verification failed: %s; tries left %i\n", sc_strerror(r), auth_info->tries_left);
@@ -4841,17 +4892,16 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData,
/* set the session pin according to the minidriver specification */
if (dwFlags == CARD_AUTHENTICATE_GENERATE_SESSION_PIN
+ && pcbSessionPin && *pcbSessionPin == 0
&& (vs->reader->capabilities & SC_READER_CAP_PIN_PAD
|| vs->p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)) {
- /* we set it to a special value for pinpad authentication to force a new pinpad authentication */
- if (pcbSessionPin) *pcbSessionPin = sizeof(MAGIC_SESSION_PIN);
+ /* If we could not generate a real session PIN, set it to a special
+ * value for pinpad authentication to force a new pinpad authentication */
+ *pcbSessionPin = sizeof(MAGIC_SESSION_PIN);
if (ppbSessionPin) {
*ppbSessionPin = pCardData->pfnCspAlloc(sizeof(MAGIC_SESSION_PIN));
if (ppbSessionPin) memcpy(*ppbSessionPin, MAGIC_SESSION_PIN, sizeof(MAGIC_SESSION_PIN));
}
- } else {
- if (pcbSessionPin) *pcbSessionPin = 0;
- if (ppbSessionPin) *ppbSessionPin = NULL;
}
return SCARD_S_SUCCESS;
@@ -4945,7 +4995,7 @@ DWORD WINAPI CardChangeAuthenticatorEx(__in PCARD_DATA pCardData,
(*pcAttemptsRemaining) = (DWORD) -1;
rv = md_dialog_perform_pin_operation(pCardData, (dwFlags & PIN_CHANGE_FLAG_UNBLOCK ? SC_PIN_CMD_UNBLOCK:SC_PIN_CMD_CHANGE),
- vs->p15card, pin_obj, (const u8 *) pbAuthenticatingPinData, cbAuthenticatingPinData, pbTargetData, cbTargetData, DisplayPinpadUI);
+ vs->p15card, pin_obj, (const u8 *) pbAuthenticatingPinData, cbAuthenticatingPinData, pbTargetData, &cbTargetData, DisplayPinpadUI);
if (rv) {
logprintf(pCardData, 2, "Failed to %s %s PIN: '%s' (%i)\n",
@@ -5261,6 +5311,9 @@ DWORD WINAPI CardGetProperty(__in PCARD_DATA pCardData,
if (cbData < sizeof(*p))
return ERROR_INSUFFICIENT_BUFFER;
*p = CARD_PIN_STRENGTH_PLAINTEXT;
+ if (vs->p15card->card->caps & SC_CARD_CAP_SESSION_PIN) {
+ *p |= CARD_PIN_STRENGTH_SESSION_PIN;
+ }
}
else if (wcscmp(CP_KEY_IMPORT_SUPPORT, wszProperty) == 0) {
DWORD *p = (DWORD *)pbData;
--
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