mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
card: New subcommand "checkkeys".
* agent/command.c (cmd_havekey): Add new option --info. * tools/card-call-scd.c (scd_readkey): Allow using without result arg. (struct havekey_status_parm_s): New. (havekey_status_cb): New. (scd_havekey_info): New. (scd_delete_key): New. * tools/gpg-card.c (print_keygrip): Add arg with_lf. (cmd_checkkeys): New. (cmdCHECKKEYS): New. (cmds): Add command "checkkeys". (dispatch_command, interactive_loop): Call cmd_checkkeys. -- GnuPG-bug-id: 6943
This commit is contained in:
parent
c8060a8f23
commit
adeb17e375
4 changed files with 265 additions and 11 deletions
138
tools/gpg-card.c
138
tools/gpg-card.c
|
@ -582,13 +582,14 @@ print_shax_fpr (estream_t fp, const unsigned char *fpr, unsigned int fprlen)
|
|||
|
||||
/* Print the keygrip GRP. */
|
||||
static void
|
||||
print_keygrip (estream_t fp, const unsigned char *grp)
|
||||
print_keygrip (estream_t fp, const unsigned char *grp, int with_lf)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < 20 ; i++, grp++)
|
||||
tty_fprintf (fp, "%02X", *grp);
|
||||
tty_fprintf (fp, "\n");
|
||||
if (with_lf)
|
||||
tty_fprintf (fp, "\n");
|
||||
}
|
||||
|
||||
|
||||
|
@ -700,7 +701,7 @@ list_one_kinfo (card_info_t info, key_info_t kinfo,
|
|||
goto leave;
|
||||
}
|
||||
|
||||
print_keygrip (fp, kinfo->grip);
|
||||
print_keygrip (fp, kinfo->grip, 1);
|
||||
tty_fprintf (fp, " keyref .....: %s", kinfo->keyref);
|
||||
if (kinfo->usage)
|
||||
{
|
||||
|
@ -1376,6 +1377,133 @@ cmd_list (card_info_t info, char *argstr)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/* The CHECKKEYS command. */
|
||||
static gpg_error_t
|
||||
cmd_checkkeys (card_info_t callerinfo, char *argstr)
|
||||
{
|
||||
gpg_error_t err;
|
||||
estream_t fp = opt.interactive? NULL : es_stdout;
|
||||
strlist_t cards = NULL;
|
||||
strlist_t sl;
|
||||
int opt_ondisk;
|
||||
int opt_delete_clear;
|
||||
int opt_delete_protected;
|
||||
int delete_count = 0;
|
||||
struct card_info_s info_buffer = { 0 };
|
||||
card_info_t info = &info_buffer;
|
||||
key_info_t kinfo;
|
||||
|
||||
|
||||
if (!callerinfo)
|
||||
return print_help
|
||||
("CHECKKEYS [--ondisk] [--delete-clear-copy]\n\n"
|
||||
"Print a list of keys on all inserted cards. With --ondisk only\n"
|
||||
"keys are listed which also have a copy on disk. Missing shadow\n"
|
||||
"keys are created. With --delete-clear, copies of keys also stored\n"
|
||||
"on disk without any protection will be deleted.\n"
|
||||
, 0);
|
||||
|
||||
|
||||
opt_ondisk = has_leading_option (argstr, "--ondisk");
|
||||
opt_delete_clear = has_leading_option (argstr, "--delete-clear-copy");
|
||||
opt_delete_protected = has_leading_option (argstr, "--delete-protected-copy");
|
||||
argstr = skip_options (argstr);
|
||||
|
||||
if (*argstr)
|
||||
{
|
||||
/* No args expected */
|
||||
err = gpg_error (GPG_ERR_INV_ARG);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (!callerinfo->serialno)
|
||||
{
|
||||
/* This is probably the first call We need to send a SERIALNO
|
||||
* command to scdaemon so that our session knows all cards. */
|
||||
err = scd_serialno (NULL, NULL);
|
||||
if (err)
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* Get the list of all cards. */
|
||||
err = scd_cardlist (&cards);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
/* Loop over all cards. We use our own info buffer here. */
|
||||
for (sl = cards; sl; sl = sl->next)
|
||||
{
|
||||
err = scd_switchcard (sl->d);
|
||||
if (err)
|
||||
{
|
||||
log_error ("Error switching to card %s: %s\n",
|
||||
sl->d, gpg_strerror (err));
|
||||
continue;
|
||||
}
|
||||
release_card_info (info);
|
||||
err = scd_learn (info, 0);
|
||||
if (err)
|
||||
{
|
||||
log_error ("Error getting infos from card %s: %s\n",
|
||||
sl->d, gpg_strerror (err));
|
||||
continue;
|
||||
}
|
||||
|
||||
for (kinfo = info->kinfo; kinfo; kinfo = kinfo->next)
|
||||
{
|
||||
char *infostr;
|
||||
|
||||
err = scd_havekey_info (kinfo->grip, &infostr);
|
||||
if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
|
||||
{
|
||||
/* Create a shadow key and try again. */
|
||||
scd_readkey (kinfo->keyref, 1, NULL);
|
||||
err = scd_havekey_info (kinfo->grip, &infostr);
|
||||
}
|
||||
if (err)
|
||||
log_error ("Error getting infos for a key: %s\n",
|
||||
gpg_strerror (err));
|
||||
|
||||
if (opt_ondisk && infostr && !strcmp (infostr, "shadowed"))
|
||||
; /* Don't print this one. */
|
||||
else
|
||||
{
|
||||
tty_fprintf (fp, "%s %s ",
|
||||
nullnone (info->serialno),
|
||||
app_type_string (info->apptype));
|
||||
print_keygrip (fp, kinfo->grip, 0);
|
||||
tty_fprintf (fp, " %s %s\n",
|
||||
kinfo->keyref, infostr? infostr: "error");
|
||||
}
|
||||
if (infostr
|
||||
&& ((opt_delete_clear && !strcmp (infostr, "clear"))
|
||||
|| (opt_delete_protected && !strcmp (infostr, "protected"))))
|
||||
{
|
||||
err = scd_delete_key (kinfo->grip, 0);
|
||||
if (err)
|
||||
log_error ("Error deleting a key copy: %s\n",
|
||||
gpg_strerror (err));
|
||||
else
|
||||
delete_count++;
|
||||
}
|
||||
xfree (infostr);
|
||||
}
|
||||
}
|
||||
if (delete_count)
|
||||
log_info ("Number of deleted key copies: %d\n", delete_count);
|
||||
|
||||
err = 0;
|
||||
|
||||
leave:
|
||||
release_card_info (info);
|
||||
free_strlist (cards);
|
||||
/* Better reset to the original card. */
|
||||
scd_learn (callerinfo, 0);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* The VERIFY command. */
|
||||
static gpg_error_t
|
||||
|
@ -3726,6 +3854,7 @@ enum cmdids
|
|||
cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT,
|
||||
cmdREADCERT, cmdWRITEKEY, cmdUNBLOCK, cmdFACTRST, cmdKDFSETUP,
|
||||
cmdUIF, cmdAUTH, cmdYUBIKEY, cmdAPDU, cmdGPG, cmdGPGSM, cmdHISTORY,
|
||||
cmdCHECKKEYS,
|
||||
cmdINVCMD
|
||||
};
|
||||
|
||||
|
@ -3765,6 +3894,7 @@ static struct
|
|||
{ "readcert", cmdREADCERT, N_("read a certificate from a data object")},
|
||||
{ "writecert", cmdWRITECERT, N_("store a certificate to a data object")},
|
||||
{ "writekey", cmdWRITEKEY, N_("store a private key to a data object")},
|
||||
{ "checkkeys", cmdCHECKKEYS, N_("run various checks on the keys")},
|
||||
{ "yubikey", cmdYUBIKEY, N_("Yubikey management commands")},
|
||||
{ "gpg", cmdGPG, NULL},
|
||||
{ "gpgsm", cmdGPGSM, NULL},
|
||||
|
@ -3901,6 +4031,7 @@ dispatch_command (card_info_t info, const char *orig_command)
|
|||
case cmdGPG: err = cmd_gpg (info, argstr, 0); break;
|
||||
case cmdGPGSM: err = cmd_gpg (info, argstr, 1); break;
|
||||
case cmdHISTORY: err = 0; break; /* Only used in interactive mode. */
|
||||
case cmdCHECKKEYS: err = cmd_checkkeys (info, argstr); break;
|
||||
|
||||
case cmdINVCMD:
|
||||
default:
|
||||
|
@ -4160,6 +4291,7 @@ interactive_loop (void)
|
|||
case cmdGPG: err = cmd_gpg (info, argstr, 0); break;
|
||||
case cmdGPGSM: err = cmd_gpg (info, argstr, 1); break;
|
||||
case cmdHISTORY: err = cmd_history (info, argstr); break;
|
||||
case cmdCHECKKEYS: err = cmd_checkkeys (info, argstr); break;
|
||||
|
||||
case cmdINVCMD:
|
||||
default:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue