@@ -285,6 +285,48 @@ dtrust_finish(sc_card_t *card)
285
285
LOG_FUNC_RETURN (card -> ctx , SC_SUCCESS );
286
286
}
287
287
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
+
288
330
static int
289
331
dtrust_set_security_env (sc_card_t * card ,
290
332
const sc_security_env_t * env ,
@@ -498,6 +540,7 @@ sc_get_dtrust_driver(void)
498
540
dtrust_ops .match_card = dtrust_match_card ;
499
541
dtrust_ops .init = dtrust_init ;
500
542
dtrust_ops .finish = dtrust_finish ;
543
+ dtrust_ops .pin_cmd = dtrust_pin_cmd ;
501
544
dtrust_ops .set_security_env = dtrust_set_security_env ;
502
545
dtrust_ops .compute_signature = dtrust_compute_signature ;
503
546
dtrust_ops .decipher = dtrust_decipher ;
0 commit comments