From a0a4744bd0640e587b33ec3dae819ec4054f0472 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 27 Aug 2020 11:55:37 +0200 Subject: [PATCH] scd: New option to APDU command to return the ATR as data. * scd/command.c (cmd_apdu): Add new option --data-atr. * tools/gpg-card.c (cmd_apdu): Use that here. Also fix the --exlen option and do not print the statusword in atr mode. * tools/card-call-scd.c (scd_apdu): Detect atr mode anddon't assume a status word. Signed-off-by: Werner Koch --- scd/command.c | 18 ++++++++++++++++-- tools/card-call-scd.c | 10 +++++++--- tools/gpg-card.c | 9 ++++++--- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/scd/command.c b/scd/command.c index 018058b73..e2d366d47 100644 --- a/scd/command.c +++ b/scd/command.c @@ -1933,6 +1933,8 @@ cmd_apdu (assuan_context_t ctx, char *line) size_t exlen; if (has_option (line, "--dump-atr")) + with_atr = 3; + else if (has_option (line, "--data-atr")) with_atr = 2; else with_atr = has_option (line, "--atr"); @@ -1969,7 +1971,7 @@ cmd_apdu (assuan_context_t ctx, char *line) rc = gpg_error (GPG_ERR_INV_CARD); goto leave; } - if (with_atr == 2) + if (with_atr == 3) { char *string, *p, *pend; @@ -1986,7 +1988,19 @@ cmd_apdu (assuan_context_t ctx, char *line) rc = assuan_send_data (ctx, p, strlen (p)); es_free (string); if (rc) - goto leave; + { + xfree (atr); + goto leave; + } + } + } + else if (with_atr == 2) + { + rc = assuan_send_data (ctx, atr, atrlen); + if (rc) + { + xfree (atr); + goto leave; } } else diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c index 8e029a2bf..160d9480e 100644 --- a/tools/card-call-scd.c +++ b/tools/card-call-scd.c @@ -485,9 +485,13 @@ scd_apdu (const char *hexapdu, const char *options, unsigned int *r_sw, membuf_t mb; unsigned char *data; size_t datalen; + int no_sw; init_membuf (&mb, 256); + no_sw = (options && (strstr (options, "--dump-atr") + || strstr (options, "--data-atr"))); + snprintf (line, DIM(line), "SCD APDU %s%s%s", options?options:"", options?" -- ":"", hexapdu); err = assuan_transact (agent_ctx, line, @@ -497,16 +501,16 @@ scd_apdu (const char *hexapdu, const char *options, unsigned int *r_sw, data = get_membuf (&mb, &datalen); if (!data) err = gpg_error_from_syserror (); - else if (datalen < 2) /* Ooops */ + else if (datalen < (no_sw?1:2)) /* Ooops */ err = gpg_error (GPG_ERR_CARD); else { if (r_sw) - *r_sw = buf16_to_uint (data+datalen-2); + *r_sw = no_sw? 0 : buf16_to_uint (data+datalen-2); if (r_data && r_datalen) { *r_data = data; - *r_datalen = datalen - 2; + *r_datalen = datalen - (no_sw?0:2); data = NULL; } } diff --git a/tools/gpg-card.c b/tools/gpg-card.c index bf3663924..9238b4759 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -3472,14 +3472,17 @@ cmd_apdu (card_info_t info, char *argstr) if (with_atr || handle_more || exlenstr) options = xasprintf ("%s%s%s%.*s", - with_atr == 2? " --dump-atr": with_atr? " --atr":"", + with_atr == 2? " --dump-atr": + with_atr? " --data-atr":"", handle_more?" --more":"", - exlenstr?" ":"", exlenstrlen, exlenstr?exlenstr:""); + exlenstr?" --exlen=":"", + exlenstrlen, exlenstr?exlenstr:""); err = scd_apdu (argstr, options, &sw, &result, &resultlen); if (err) goto leave; - log_info ("Statusword: 0x%04x\n", sw); + if (!with_atr) + log_info ("Statusword: 0x%04x\n", sw); for (i=0; i < resultlen; ) { size_t save_i = i;