1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-05-31 22:18:03 +02:00

card: For passwd add a PIV menu and make the OpenPGP menu optional.

* tools/gpg-card.c (get_selection): New.
(cmd_passwd): Reworked.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2019-03-28 14:46:05 +01:00
parent 2f761251c5
commit 80c069b5e1
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B

View File

@ -429,6 +429,24 @@ put_data_to_file (const char *fname, const void *buffer, size_t length)
} }
/* Return a malloced string with the number opf the menu PROMPT.
* Control-D is mapped to "Q". */
static char *
get_selection (const char *prompt)
{
char *answer;
tty_printf ("\n");
tty_printf ("%s", prompt);
tty_printf ("\n");
answer = tty_get (_("Your selection? "));
tty_kill_prompt ();
if (*answer == CONTROL_D)
strcpy (answer, "q");
return answer;
}
/* Simply prints TEXT to the output. Returns 0 as a convenience. /* Simply prints TEXT to the output. Returns 0 as a convenience.
* This is a separate fucntion so that it can be extended to run * This is a separate fucntion so that it can be extended to run
@ -2097,21 +2115,23 @@ cmd_generate (card_info_t info, char *argstr)
/* Sub-menu to change a PIN. */ /* Change a PIN. */
static gpg_error_t static gpg_error_t
cmd_passwd (card_info_t info, char *argstr) cmd_passwd (card_info_t info, char *argstr)
{ {
gpg_error_t err; gpg_error_t err = 0;
char *answer = NULL; char *answer = NULL;
const char *pinref; const char *pinref = NULL;
int reset_mode = 0;
int menu_used = 0;
if (!info) if (!info)
return print_help return print_help
("PASSWD [PINREF]\n\n" ("PASSWD [PINREF]\n\n"
"Menu to change or unblock the PINs. Note that the\n" "Change or unblock the PINs. Note that in interactive mode\n"
"presented menu options depend on the type of card\n" "and without a PINREF a menu is presented for certain cards;\n"
"and whether the admin mode is enabled. For OpenPGP\n" "in non-interactive and without a PINREF a default value is\n"
"and PIV cards defaults for PINREF are available.", "used for these cards.",
0); 0);
if (opt.interactive || opt.verbose) if (opt.interactive || opt.verbose)
@ -2119,92 +2139,93 @@ cmd_passwd (card_info_t info, char *argstr)
app_type_string (info->apptype), app_type_string (info->apptype),
info->dispserialno? info->dispserialno : info->serialno); info->dispserialno? info->dispserialno : info->serialno);
if (!*argstr && info->apptype == APP_TYPE_OPENPGP) if (*argstr)
pinref = argstr;
else if (opt.interactive && info->apptype == APP_TYPE_OPENPGP)
{ {
/* For an OpenPGP card we present the well known menu if no menu_used = 1;
* argument is given. */ while (!pinref)
for (;;)
{ {
tty_printf ("\n");
tty_printf ("1 - change PIN\n"
"2 - unblock and set new PIN\n"
"3 - change Admin PIN\n"
"4 - set the Reset Code\n"
"Q - quit\n");
tty_printf ("\n");
err = 0;
xfree (answer); xfree (answer);
answer = tty_get (_("Your selection? ")); answer = get_selection ("1 - change the PIN\n"
tty_kill_prompt (); "2 - unblock and set new a PIN\n"
if (*answer == CONTROL_D) "3 - change the Admin PIN\n"
break; /* Quit. */ "4 - set the Reset Code\n"
"Q - quit\n");
if (strlen (answer) != 1) if (strlen (answer) != 1)
continue; continue;
if (*answer == 'q' || *answer == 'Q') else if (*answer == 'q' || *answer == 'Q')
break; /* Quit. */ goto leave;
else if (*answer == '1')
if (*answer == '1') pinref = "OPENPGP.1";
{
/* Change PIN (same as the direct thing in non-admin mode). */
err = scd_change_pin ("OPENPGP.1", 0);
if (err)
log_error ("Error changing the PIN: %s\n", gpg_strerror (err));
else
log_info ("PIN changed.\n");
}
else if (*answer == '2') else if (*answer == '2')
{ { pinref = "OPENPGP.1"; reset_mode = 1; }
/* Unblock PIN by setting a new PIN. */
err = scd_change_pin ("OPENPGP.1", 1);
if (err)
log_error ("Error unblocking the PIN: %s\n", gpg_strerror(err));
else
log_info ("PIN unblocked and new PIN set.\n");
}
else if (*answer == '3') else if (*answer == '3')
{ pinref = "OPENPGP.3";
/* Change Admin PIN. */
err = scd_change_pin ("OPENPGP.3", 0);
if (err)
log_error ("Error changing the PIN: %s\n", gpg_strerror (err));
else
log_info ("PIN changed.\n");
}
else if (*answer == '4') else if (*answer == '4')
{ { pinref = "OPENPGP.2"; reset_mode = 1; }
/* Set a new Reset Code. */ }
err = scd_change_pin ("OPENPGP.2", 1); }
if (err) else if (info->apptype == APP_TYPE_OPENPGP)
log_error ("Error setting the Reset Code: %s\n", pinref = "OPENPGP.1";
gpg_strerror (err)); else if (opt.interactive && info->apptype == APP_TYPE_PIV)
else {
log_info ("Reset Code set.\n"); menu_used = 1;
} while (!pinref)
{
xfree (answer);
answer = get_selection ("1 - change the PIN\n"
"2 - change the PUK\n"
"3 - change the Global PIN\n"
"Q - quit\n");
if (strlen (answer) != 1)
;
else if (*answer == 'q' || *answer == 'Q')
goto leave;
else if (*answer == '1')
pinref = "PIV.80";
else if (*answer == '2')
pinref = "PIV.81";
else if (*answer == '3')
pinref = "PIV.00";
}
}
else if (info->apptype == APP_TYPE_PIV)
pinref = "PIV.80";
else
{
err = gpg_error (GPG_ERR_MISSING_VALUE);
goto leave;
}
} /*end for loop*/ err = scd_change_pin (pinref, reset_mode);
if (err)
{
if (!opt.interactive && !menu_used && !opt.verbose)
;
else if (!ascii_strcasecmp (pinref, "PIV.81"))
log_error ("Error changing the PUK.\n");
else if (!ascii_strcasecmp (pinref, "OPENPGP.1") && reset_mode)
log_error ("Error unblocking the PIN.\n");
else if (!ascii_strcasecmp (pinref, "OPENPGP.2") && reset_mode)
log_error ("Error setting the Reset Code.\n");
else if (!ascii_strcasecmp (pinref, "OPENPGP.3"))
log_error ("Error changing the Admin PIN.\n");
else
log_error ("Error changing the PIN.\n");
} }
else else
{ {
if (*argstr) if (!opt.interactive && !opt.verbose)
pinref = argstr; ;
else if (info->apptype == APP_TYPE_PIV) else if (!ascii_strcasecmp (pinref, "PIV.81"))
pinref = "PIV.80";
else
{
/* Note that we do not have a default value for OpenPGP
* because we want to be mostly compatible to "gpg
* --card-edit" and show a menu in that case (above). */
err = gpg_error (GPG_ERR_MISSING_VALUE);
goto leave;
}
err = scd_change_pin (pinref, 0);
if (err)
goto leave;
if (info->apptype == APP_TYPE_PIV
&& !ascii_strcasecmp (pinref, "PIV.81"))
log_info ("PUK changed.\n"); log_info ("PUK changed.\n");
else if (!ascii_strcasecmp (pinref, "OPENPGP.1") && reset_mode)
log_info ("PIN unblocked and new PIN set.\n");
else if (!ascii_strcasecmp (pinref, "OPENPGP.2") && reset_mode)
log_info ("Reset Code set.\n");
else if (!ascii_strcasecmp (pinref, "OPENPGP.3"))
log_info ("Admin PIN changed.\n");
else else
log_info ("PIN changed.\n"); log_info ("PIN changed.\n");
} }
@ -2261,7 +2282,7 @@ cmd_unblock (card_info_t info)
} }
else else
{ {
log_info ("Unblocking not yet supported for '%s'\n", log_info ("Unblocking not supported for '%s'.\n",
app_type_string (info->apptype)); app_type_string (info->apptype));
err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
} }