Skip to content

Commit 9cb58e6

Browse files
hamaritucfrankmorgner
authored andcommitted
dtrust: prevent unnecessary PIN prompts on pin pad readers
closes OpenSC#2244
1 parent d50b169 commit 9cb58e6

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

src/libopensc/card-dtrust.c

+43
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,48 @@ dtrust_finish(sc_card_t *card)
285285
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
286286
}
287287

288+
static int
289+
dtrust_pin_cmd(struct sc_card *card,
290+
struct sc_pin_cmd_data *data,
291+
int *tries_left)
292+
{
293+
int r;
294+
295+
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
296+
297+
if (!data)
298+
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
299+
300+
/* Upper layers may try to verify the PIN twice, first with PIN type
301+
* SC_AC_CHV and then with PIN type SC_AC_CONTEXT_SPECIFIC. For the
302+
* second attempt we first check by SC_PIN_CMD_GET_INFO whether a
303+
* second PIN authentication is still necessary. If not, we simply
304+
* return without a second verification attempt. Otherwise we perform
305+
* the verification as requested. This only matters for pin pad readers
306+
* to prevent the user from prompting the PIN twice. */
307+
if (data->cmd == SC_PIN_CMD_VERIFY && data->pin_type == SC_AC_CONTEXT_SPECIFIC) {
308+
struct sc_pin_cmd_data data2;
309+
310+
memset(&data2, 0, sizeof(struct sc_pin_cmd_data));
311+
data2.pin_reference = data->pin_reference;
312+
data2.pin1 = data->pin1;
313+
314+
/* Check verification state */
315+
data2.cmd = SC_PIN_CMD_GET_INFO;
316+
data2.pin_type = data->pin_type;
317+
r = iso_ops->pin_cmd(card, &data2, tries_left);
318+
319+
if (data2.pin1.logged_in == SC_PIN_STATE_LOGGED_IN) {
320+
/* Return if we are already authenticated */
321+
data->pin1 = data2.pin1;
322+
LOG_FUNC_RETURN(card->ctx, r);
323+
}
324+
}
325+
326+
r = iso_ops->pin_cmd(card, data, tries_left);
327+
LOG_FUNC_RETURN(card->ctx, r);
328+
}
329+
288330
static int
289331
dtrust_set_security_env(sc_card_t *card,
290332
const sc_security_env_t *env,
@@ -498,6 +540,7 @@ sc_get_dtrust_driver(void)
498540
dtrust_ops.match_card = dtrust_match_card;
499541
dtrust_ops.init = dtrust_init;
500542
dtrust_ops.finish = dtrust_finish;
543+
dtrust_ops.pin_cmd = dtrust_pin_cmd;
501544
dtrust_ops.set_security_env = dtrust_set_security_env;
502545
dtrust_ops.compute_signature = dtrust_compute_signature;
503546
dtrust_ops.decipher = dtrust_decipher;

0 commit comments

Comments
 (0)