aboutsummaryrefslogtreecommitdiffstats
path: root/tools/gpg-card-tool.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/gpg-card-tool.c')
-rw-r--r--tools/gpg-card-tool.c108
1 files changed, 76 insertions, 32 deletions
diff --git a/tools/gpg-card-tool.c b/tools/gpg-card-tool.c
index 1c4413b15..fd7aa9a7e 100644
--- a/tools/gpg-card-tool.c
+++ b/tools/gpg-card-tool.c
@@ -899,7 +899,7 @@ list_piv (card_info_t info, estream_t fp)
switch (info->chvinfo[i])
{
case -1: s = "[error]"; break;
- case -2: s = "-"; break; /* No such PIN */
+ case -2: s = "-"; break; /* No such PIN or info not available. */
case -3: s = "[blocked]"; break;
case -5: s = "[verified]"; break;
default: s = "[?]"; break;
@@ -950,15 +950,21 @@ static gpg_error_t
cmd_verify (card_info_t info, char *argstr)
{
gpg_error_t err;
+ const char *pinref;
if (!info)
return print_help ("verify [chvid]", 0);
- if (info->apptype == APP_TYPE_OPENPGP)
- err = scd_checkpin (info->serialno);
+ if (*argstr)
+ pinref = argstr;
+ else if (info->apptype == APP_TYPE_OPENPGP)
+ pinref = info->serialno;
+ else if (info->apptype == APP_TYPE_PIV)
+ pinref = "PIV.80";
else
- err = scd_checkpin (argstr);
+ return gpg_error (GPG_ERR_MISSING_VALUE);
+ err = scd_checkpin (pinref);
if (err)
log_error ("verify failed: %s <%s>\n",
gpg_strerror (err), gpg_strsource (err));
@@ -1845,30 +1851,48 @@ cmd_generate (card_info_t info)
/* Sub-menu to change a PIN. The presented options may depend on the
* the ALLOW_ADMIN flag. */
static gpg_error_t
-cmd_passwd (card_info_t info, int allow_admin)
+cmd_passwd (card_info_t info, int allow_admin, char *argstr)
{
gpg_error_t err;
char *answer = NULL;
+ const char *pinref;
if (!info)
return print_help
- ("PASSWD\n\n"
+ ("PASSWD [PINREF]\n\n"
"Menu to change or unblock the PINs. Note that the\n"
"presented menu options depend on the type of card\n"
- "and whether the admin mode is enabled.",
+ "and whether the admin mode is enabled. For OpenPGP\n"
+ "and PIV cards defaults for PINREF are available.",
0);
- /* Convenience message because we did this in gpg --card-edit too. */
- if (info->apptype == APP_TYPE_OPENPGP)
- log_info (_("OpenPGP card no. %s detected\n"),
+ if (opt.interactive || opt.verbose)
+ log_info (_("%s card no. %s detected\n"),
+ app_type_string (info->apptype),
info->dispserialno? info->dispserialno : info->serialno);
- if (!allow_admin)
+ if (!allow_admin || info->apptype != APP_TYPE_OPENPGP)
{
- err = scd_change_pin ("OPENPGP.1", 0);
+ if (*argstr)
+ pinref = argstr;
+ else if (info->apptype == APP_TYPE_OPENPGP)
+ pinref = "OPENPGP.1";
+ else if (info->apptype == APP_TYPE_PIV)
+ pinref = "PIV.80";
+ else
+ {
+ err = gpg_error (GPG_ERR_MISSING_VALUE);
+ goto leave;
+ }
+ err = scd_change_pin (pinref, 0);
if (err)
goto leave;
- log_info ("PIN changed.\n");
+
+ if (info->apptype == APP_TYPE_PIV
+ && !ascii_strcasecmp (pinref, "PIV.81"))
+ log_info ("PUK changed.\n");
+ else
+ log_info ("PIN changed.\n");
}
else if (info->apptype == APP_TYPE_OPENPGP)
{
@@ -1959,23 +1983,43 @@ cmd_unblock (card_info_t info)
"command can be used to set a new PIN.",
0);
- if (info->apptype == APP_TYPE_OPENPGP)
- log_info (_("OpenPGP card no. %s detected\n"),
+ if (opt.interactive || opt.verbose)
+ log_info (_("%s card no. %s detected\n"),
+ app_type_string (info->apptype),
info->dispserialno? info->dispserialno : info->serialno);
- if (info->apptype == APP_TYPE_OPENPGP && !info->is_v2)
- log_error (_("This command is only available for version 2 cards\n"));
- else if (info->apptype == APP_TYPE_OPENPGP && !info->chvinfo[1])
- log_error (_("Reset Code not or not anymore available\n"));
- else if (info->apptype == APP_TYPE_OPENPGP)
+ if (info->apptype == APP_TYPE_OPENPGP)
{
- err = scd_change_pin ("OPENPGP.2", 0);
+ if (!info->is_v2)
+ {
+ log_error (_("This command is only available for version 2 cards\n"));
+ err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+ }
+ else if (!info->chvinfo[1])
+ {
+ log_error (_("Reset Code not or not anymore available\n"));
+ err = gpg_error (GPG_ERR_PIN_BLOCKED);
+ }
+ else
+ {
+ err = scd_change_pin ("OPENPGP.2", 0);
+ if (!err)
+ log_info ("PIN changed.\n");
+ }
+ }
+ else if (info->apptype == APP_TYPE_PIV)
+ {
+ /* Unblock the Application PIN. */
+ err = scd_change_pin ("PIV.80", 1);
if (!err)
- log_info ("PIN changed.\n");
+ log_info ("PIN unblocked and changed.\n");
}
else
- log_info ("Unblocking not yet supported for '%s'\n",
- app_type_string (info->apptype));
+ {
+ log_info ("Unblocking not yet supported for '%s'\n",
+ app_type_string (info->apptype));
+ err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ }
return err;
}
@@ -2079,15 +2123,15 @@ cmd_factoryreset (card_info_t info)
goto leave;
}
+ if (opt.interactive || opt.verbose)
+ log_info (_("%s card no. %s detected\n"),
+ app_type_string (info->apptype),
+ info->dispserialno? info->dispserialno : info->serialno);
+
if (!termstate || is_yubikey)
{
- if (is_yubikey)
- log_info (_("Yubikey no. %s with PIV application detected\n"),
- info->dispserialno? info->dispserialno : info->serialno);
- else
+ if (!is_yubikey)
{
- log_info (_("OpenPGP card no. %s detected\n"),
- info->dispserialno? info->dispserialno : info->serialno);
if (!(info->status_indicator == 3 || info->status_indicator == 5))
{
/* Note: We won't see status-indicator 3 here because it
@@ -2865,7 +2909,7 @@ dispatch_command (card_info_t info, const char *orig_command)
case cmdREADCERT: err = cmd_readcert (info, argstr); break;
case cmdFORCESIG: err = cmd_forcesig (info); break;
case cmdGENERATE: err = cmd_generate (info); break;
- case cmdPASSWD: err = cmd_passwd (info, 1); break;
+ case cmdPASSWD: err = cmd_passwd (info, 1, argstr); break;
case cmdUNBLOCK: err = cmd_unblock (info); break;
case cmdFACTORYRESET: err = cmd_factoryreset (info); break;
case cmdKDFSETUP: err = cmd_kdfsetup (info, argstr); break;
@@ -3131,7 +3175,7 @@ interactive_loop (void)
case cmdREADCERT: err = cmd_readcert (info, argstr); break;
case cmdFORCESIG: err = cmd_forcesig (info); break;
case cmdGENERATE: err = cmd_generate (info); break;
- case cmdPASSWD: err = cmd_passwd (info, allow_admin); break;
+ case cmdPASSWD: err = cmd_passwd (info, allow_admin, argstr); break;
case cmdUNBLOCK: err = cmd_unblock (info); break;
case cmdFACTORYRESET:
err = cmd_factoryreset (info);