mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-30 16:17:02 +01:00
scd: Add new command: KEYINFO.
* scd/app-common.h (struct app_ctx_s): Add with_keygrip function. * scd/app-openpgp.c (do_with_keygrip): New. * scd/app.c (app_do_with_keygrip): New. * scd/command.c (cmd_keyinfo): New. (send_keyinfo): New. -- KEYGRIP_ACTION_LOOKUP is not yet used. It will be used for directly asking PK* action to determine an APP. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
d5443b918d
commit
874bc970ba
@ -126,9 +126,18 @@ struct app_ctx_s {
|
||||
gpg_error_t (*check_pin) (app_t app, const char *keyidstr,
|
||||
gpg_error_t (*pincb)(void*, const char *, char **),
|
||||
void *pincb_arg);
|
||||
int (*with_keygrip) (app_t app, ctrl_t ctrl, int action,
|
||||
const char *keygrip_str);
|
||||
} fnc;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
KEYGRIP_ACTION_SEND_DATA,
|
||||
KEYGRIP_ACTION_WRITE_STATUS,
|
||||
KEYGRIP_ACTION_LOOKUP
|
||||
};
|
||||
|
||||
/*-- app-help.c --*/
|
||||
unsigned int app_help_count_bits (const unsigned char *a, size_t len);
|
||||
gpg_error_t app_help_get_keygrip_string_pk (const void *pk, size_t pklen,
|
||||
@ -206,6 +215,7 @@ gpg_error_t app_change_pin (app_t app, ctrl_t ctrl,
|
||||
gpg_error_t app_check_pin (app_t app, ctrl_t ctrl, const char *keyidstr,
|
||||
gpg_error_t (*pincb)(void*, const char *, char **),
|
||||
void *pincb_arg);
|
||||
app_t app_do_with_keygrip (ctrl_t ctrl, int action, const char *keygrip_str);
|
||||
|
||||
|
||||
/*-- app-openpgp.c --*/
|
||||
|
@ -4945,6 +4945,59 @@ do_check_pin (app_t app, const char *keyidstr,
|
||||
return verify_chv2 (app, pincb, pincb_arg);
|
||||
}
|
||||
|
||||
static int
|
||||
do_with_keygrip (app_t app, ctrl_t ctrl, int action, const char *keygrip_str)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (action == KEYGRIP_ACTION_LOOKUP)
|
||||
{
|
||||
if (keygrip_str == NULL)
|
||||
return 1;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
if (app->app_local->pk[i].read_done
|
||||
&& !strcmp (keygrip_str, app->app_local->pk[i].keygrip_str))
|
||||
return 0; /* Found */
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
char idbuf[50];
|
||||
char buf[65];
|
||||
int data = (action == KEYGRIP_ACTION_SEND_DATA);
|
||||
|
||||
if (DIM (buf) < 2 * app->serialnolen + 1)
|
||||
return 0;
|
||||
|
||||
bin2hex (app->serialno, app->serialnolen, buf);
|
||||
|
||||
if (keygrip_str == NULL)
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
if (app->app_local->pk[i].read_done)
|
||||
{
|
||||
sprintf (idbuf, "OPENPGP.%d", i+1);
|
||||
send_keyinfo (ctrl, data,
|
||||
app->app_local->pk[i].keygrip_str,buf, idbuf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
if (app->app_local->pk[i].read_done
|
||||
&& !strcmp (keygrip_str, app->app_local->pk[i].keygrip_str))
|
||||
{
|
||||
sprintf (idbuf, "OPENPGP.%d", i+1);
|
||||
send_keyinfo (ctrl, data, keygrip_str, buf, idbuf);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Show information about card capabilities. */
|
||||
static void
|
||||
@ -5327,6 +5380,7 @@ app_select_openpgp (app_t app)
|
||||
app->fnc.decipher = do_decipher;
|
||||
app->fnc.change_pin = do_change_pin;
|
||||
app->fnc.check_pin = do_check_pin;
|
||||
app->fnc.with_keygrip = do_with_keygrip;
|
||||
}
|
||||
|
||||
leave:
|
||||
|
21
scd/app.c
21
scd/app.c
@ -1290,3 +1290,24 @@ app_send_card_list (ctrl_t ctrl)
|
||||
}
|
||||
npth_mutex_unlock (&app_list_lock);
|
||||
}
|
||||
|
||||
/* Execute an action for each app. ACTION can be one of:
|
||||
KEYGRIP_ACTION_SEND_DATA: send data if KEYGRIP_STR matches
|
||||
KEYGRIP_ACTION_WRITE_STATUS: write status if KEYGRIP_STR matches
|
||||
KEYGRIP_ACTION_LOOKUP: Return matching APP
|
||||
*/
|
||||
app_t
|
||||
app_do_with_keygrip (ctrl_t ctrl, int action, const char *keygrip_str)
|
||||
{
|
||||
app_t a;
|
||||
|
||||
npth_mutex_lock (&app_list_lock);
|
||||
|
||||
for (a = app_top; a; a = a->next)
|
||||
if (a->fnc.with_keygrip
|
||||
&& !a->fnc.with_keygrip (a, ctrl, action, keygrip_str))
|
||||
break;
|
||||
|
||||
npth_mutex_unlock (&app_list_lock);
|
||||
return a;
|
||||
}
|
||||
|
@ -424,7 +424,7 @@ cmd_learn (assuan_context_t ctx, char *line)
|
||||
|
||||
serial = app_get_serialno (ctrl->app_ctx);
|
||||
if (!serial)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
|
||||
rc = assuan_write_status (ctx, "SERIALNO", serial);
|
||||
if (rc < 0)
|
||||
@ -1757,6 +1757,76 @@ cmd_killscd (assuan_context_t ctx, char *line)
|
||||
}
|
||||
|
||||
|
||||
static const char hlp_keyinfo[] =
|
||||
"KEYINFO [--list] [--data] <keygrip>\n"
|
||||
"\n"
|
||||
"Return information about the key specified by the KEYGRIP. If the\n"
|
||||
"key is not available GPG_ERR_NOT_FOUND is returned. If the option\n"
|
||||
"--list is given the keygrip is ignored and information about all\n"
|
||||
"available keys are returned. Unless --data is given, the\n"
|
||||
"information is returned as a status line using the format:\n"
|
||||
"\n"
|
||||
" KEYINFO <keygrip> T <serialno> <idstr>\n"
|
||||
"\n"
|
||||
"KEYGRIP is the keygrip.\n"
|
||||
"\n"
|
||||
"SERIALNO is an ASCII string with the serial number of the\n"
|
||||
" smartcard. If the serial number is not known a single\n"
|
||||
" dash '-' is used instead.\n"
|
||||
"\n"
|
||||
"IDSTR is the IDSTR used to distinguish keys on a smartcard. If it\n"
|
||||
" is not known a dash is used instead.\n"
|
||||
"\n"
|
||||
"More information may be added in the future.";
|
||||
static gpg_error_t
|
||||
cmd_keyinfo (assuan_context_t ctx, char *line)
|
||||
{
|
||||
int list_mode;
|
||||
int opt_data;
|
||||
int action;
|
||||
char *keygrip_str;
|
||||
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||
|
||||
list_mode = has_option (line, "--list");
|
||||
opt_data = has_option (line, "--data");
|
||||
line = skip_options (line);
|
||||
|
||||
if (list_mode)
|
||||
keygrip_str = NULL;
|
||||
else
|
||||
keygrip_str = line;
|
||||
|
||||
if (opt_data)
|
||||
action = KEYGRIP_ACTION_SEND_DATA;
|
||||
else
|
||||
action = KEYGRIP_ACTION_WRITE_STATUS;
|
||||
|
||||
app_do_with_keygrip (ctrl, action, keygrip_str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
send_keyinfo (ctrl_t ctrl, int data, const char *keygrip_str,
|
||||
const char *serialno, const char *idstr)
|
||||
{
|
||||
char *string;
|
||||
assuan_context_t ctx = ctrl->server_local->assuan_ctx;
|
||||
|
||||
string = xtryasprintf ("%s T %s %s\n", keygrip_str,
|
||||
serialno? serialno : "-",
|
||||
idstr? idstr : "-");
|
||||
if (!string)
|
||||
return;
|
||||
|
||||
if (!data)
|
||||
assuan_write_status (ctx, "KEYINFO", string);
|
||||
else
|
||||
assuan_send_data (ctx, string, strlen (string));
|
||||
|
||||
xfree (string);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Tell the assuan library about our commands */
|
||||
static int
|
||||
@ -1792,6 +1862,7 @@ register_commands (assuan_context_t ctx)
|
||||
{ "DISCONNECT", cmd_disconnect,hlp_disconnect },
|
||||
{ "APDU", cmd_apdu, hlp_apdu },
|
||||
{ "KILLSCD", cmd_killscd, hlp_killscd },
|
||||
{ "KEYINFO", cmd_keyinfo, hlp_keyinfo },
|
||||
{ NULL }
|
||||
};
|
||||
int i, rc;
|
||||
|
@ -125,6 +125,8 @@ void send_status_info (ctrl_t ctrl, const char *keyword, ...)
|
||||
void send_status_direct (ctrl_t ctrl, const char *keyword, const char *args);
|
||||
gpg_error_t send_status_printf (ctrl_t ctrl, const char *keyword,
|
||||
const char *format, ...) GPGRT_ATTR_PRINTF(3,4);
|
||||
void send_keyinfo (ctrl_t ctrl, int data, const char *keygrip_str,
|
||||
const char *serialno, const char *idstr);
|
||||
|
||||
void popup_prompt (void *opaque, int on);
|
||||
void send_client_notifications (app_t app, int removal);
|
||||
|
Loading…
x
Reference in New Issue
Block a user