From 3231ecdafd71ac47b734469b07170756979ede72 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 5 Feb 2019 14:48:49 +0100 Subject: [PATCH] scd: Allow standard keyref scheme for app-openpgp. * scd/app-openpgp.c (do_change_pin): Allow prefixing the CHVNO with "OPENPGP." * tools/card-call-scd.c (scd_change_pin): Change API to use strings. * tools/gpg-card-tool.c (cmd_passwd): Adjust for change. (cmd_unblock): Ditto. -- The generic keyref allows for better error detection in case a keyref is send to a wrong card. Signed-off-by: Werner Koch --- doc/wks.texi | 2 +- scd/app-openpgp.c | 15 ++++++++++++++- scd/iso7816.c | 1 + tools/card-call-scd.c | 11 +++-------- tools/card-tool.h | 2 +- tools/gpg-card-tool.c | 12 ++++++------ 6 files changed, 26 insertions(+), 17 deletions(-) diff --git a/doc/wks.texi b/doc/wks.texi index a0b2a34b9..f132b3186 100644 --- a/doc/wks.texi +++ b/doc/wks.texi @@ -124,7 +124,7 @@ Requires installation of that command. @item --with-colons @opindex with-colons This option has currently only an effect on the @option{--supported} -command. If it is used all arguimenst on the command line are taken +command. If it is used all arguments on the command line are taken as domain names and tested for WKD support. The output format is one line per domain with colon delimited fields. The currently specified fields are (future versions may specify additional fields): diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index dbc51be7f..72ed80a3d 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -2583,6 +2583,8 @@ do_writecert (app_t app, ctrl_t ctrl, - 2 1 Verify CHV2 and set a new CHV1 and CHV2. - 2 2 Verify Reset Code and set a new PW1. - 3 any Verify CHV3/PW3 and set a new CHV3/PW3. + + The CHVNO can be prefixed with "OPENPGP.". */ static gpg_error_t do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, @@ -2591,7 +2593,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, void *pincb_arg) { int rc = 0; - int chvno = atoi (chvnostr); + int chvno; char *resetcode = NULL; char *oldpinvalue = NULL; char *pinvalue = NULL; @@ -2605,6 +2607,17 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, (void)ctrl; + if (digitp (chvnostr)) + chvno = atoi (chvnostr); + else if (!ascii_strcasecmp (chvnostr, "OPENPGP.1")) + chvno = 1; + else if (!ascii_strcasecmp (chvnostr, "OPENPGP.2")) + chvno = 2; + else if (!ascii_strcasecmp (chvnostr, "OPENPGP.3")) + chvno = 3; + else + return gpg_error (GPG_ERR_INV_ID); + memset (&pininfo, 0, sizeof pininfo); pininfo.fixedlen = -1; pininfo.minlen = minlen; diff --git a/scd/iso7816.c b/scd/iso7816.c index c8a2138cb..69009c43e 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -346,6 +346,7 @@ iso7816_change_reference_data (int slot, int chvno, sw = apdu_send_simple (slot, 0, 0x00, CMD_CHANGE_REFERENCE_DATA, oldchvlen? 0 : 1, chvno, oldchvlen+newchvlen, buf); + wipememory (buf, oldchvlen+newchvlen); xfree (buf); return map_sw (sw); diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c index c51282f14..7add56daf 100644 --- a/tools/card-call-scd.c +++ b/tools/card-call-scd.c @@ -1368,28 +1368,23 @@ scd_cardlist (strlist_t *result) * 101: Set a new PIN and reset the retry counter * 102: For v1 cars: Same as 101. * For v2 cards: Set a new Reset Code. - * SERIALNO is not used. */ gpg_error_t -scd_change_pin (int chvno) +scd_change_pin (const char *pinref, int reset_mode) { gpg_error_t err; char line[ASSUAN_LINELENGTH]; - const char *reset = ""; struct default_inq_parm_s dfltparm; memset (&dfltparm, 0, sizeof dfltparm); - if (chvno >= 100) - reset = "--reset"; - chvno %= 100; - err = start_agent (0); if (err) return err; dfltparm.ctx = agent_ctx; - snprintf (line, sizeof line, "SCD PASSWD %s %d", reset, chvno); + snprintf (line, sizeof line, "SCD PASSWD%s %s", + reset_mode? " --reset":"", pinref); err = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, &dfltparm, diff --git a/tools/card-tool.h b/tools/card-tool.h index 9aca8131d..2707b3e8f 100644 --- a/tools/card-tool.h +++ b/tools/card-tool.h @@ -212,7 +212,7 @@ gpg_error_t scd_serialno (char **r_serialno, const char *demand); gpg_error_t scd_readcert (const char *certidstr, void **r_buf, size_t *r_buflen); gpg_error_t scd_cardlist (strlist_t *result); -gpg_error_t scd_change_pin (int chvno); +gpg_error_t scd_change_pin (const char *pinref, int reset_mode); gpg_error_t scd_checkpin (const char *serialno); unsigned long agent_get_s2k_count (void); diff --git a/tools/gpg-card-tool.c b/tools/gpg-card-tool.c index 243ee555a..1c4413b15 100644 --- a/tools/gpg-card-tool.c +++ b/tools/gpg-card-tool.c @@ -1865,7 +1865,7 @@ cmd_passwd (card_info_t info, int allow_admin) if (!allow_admin) { - err = scd_change_pin (1); + err = scd_change_pin ("OPENPGP.1", 0); if (err) goto leave; log_info ("PIN changed.\n"); @@ -1896,7 +1896,7 @@ cmd_passwd (card_info_t info, int allow_admin) if (*answer == '1') { /* Change PIN (same as the direct thing in non-admin mode). */ - err = scd_change_pin (1); + err = scd_change_pin ("OPENPGP.1", 0); if (err) log_error ("Error changing the PIN: %s\n", gpg_strerror (err)); else @@ -1905,7 +1905,7 @@ cmd_passwd (card_info_t info, int allow_admin) else if (*answer == '2') { /* Unblock PIN by setting a new PIN. */ - err = scd_change_pin (101); + err = scd_change_pin ("OPENPGP.1", 1); if (err) log_error ("Error unblocking the PIN: %s\n", gpg_strerror(err)); else @@ -1914,7 +1914,7 @@ cmd_passwd (card_info_t info, int allow_admin) else if (*answer == '3') { /* Change Admin PIN. */ - err = scd_change_pin (3); + err = scd_change_pin ("OPENPGP.3", 0); if (err) log_error ("Error changing the PIN: %s\n", gpg_strerror (err)); else @@ -1923,7 +1923,7 @@ cmd_passwd (card_info_t info, int allow_admin) else if (*answer == '4') { /* Set a new Reset Code. */ - err = scd_change_pin (102); + err = scd_change_pin ("OPENPGP.2", 1); if (err) log_error ("Error setting the Reset Code: %s\n", gpg_strerror (err)); @@ -1969,7 +1969,7 @@ cmd_unblock (card_info_t info) log_error (_("Reset Code not or not anymore available\n")); else if (info->apptype == APP_TYPE_OPENPGP) { - err = scd_change_pin (2); + err = scd_change_pin ("OPENPGP.2", 0); if (!err) log_info ("PIN changed.\n"); }