mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
scd: Add --demand option for SERIALNO.
* scd/app.c (select_application): Add SERIALNO_BIN and SERIALNO_BIN_LEN arguments. Return matched APP with a serial number when specified. * scd/command.c (open_card): Modify for the implicit open only. (open_card_with_request): New for explicit open and support match with a serial number. (cmd_serialno): Support --demand option. (cmd_learn, cmd_readcert, cmd_readkey, cmd_pksign, cmd_pkauth) (cmd_pkdecrypt, cmd_getattr, cmd_setattr, cmd_writecert, cmd_writekey) (cmd_genkey, cmd_random, cmd_passwd, cmd_checkpin, cmd_apdu): Follow the change of open_card. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
3db76c9277
commit
2e6f1c99d4
@ -129,7 +129,8 @@ void application_notify_card_reset (int slot);
|
|||||||
gpg_error_t check_application_conflict (const char *name, app_t app);
|
gpg_error_t check_application_conflict (const char *name, app_t app);
|
||||||
gpg_error_t app_reset (app_t app, ctrl_t ctrl, int send_reset);
|
gpg_error_t app_reset (app_t app, ctrl_t ctrl, int send_reset);
|
||||||
gpg_error_t select_application (ctrl_t ctrl, const char *name, app_t *r_app,
|
gpg_error_t select_application (ctrl_t ctrl, const char *name, app_t *r_app,
|
||||||
int scan);
|
int scan, const unsigned char *serialno_bin,
|
||||||
|
size_t serialno_bin_len);
|
||||||
char *get_supported_applications (void);
|
char *get_supported_applications (void);
|
||||||
void release_application (app_t app);
|
void release_application (app_t app);
|
||||||
gpg_error_t app_munge_serialno (app_t app);
|
gpg_error_t app_munge_serialno (app_t app);
|
||||||
|
37
scd/app.c
37
scd/app.c
@ -317,10 +317,12 @@ app_new_register (int slot, ctrl_t ctrl, const char *name)
|
|||||||
and return a context. Returns an error code and stores NULL at
|
and return a context. Returns an error code and stores NULL at
|
||||||
R_APP if no application was found or no card is present. */
|
R_APP if no application was found or no card is present. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
select_application (ctrl_t ctrl, const char *name, app_t *r_app, int scan)
|
select_application (ctrl_t ctrl, const char *name, app_t *r_app,
|
||||||
|
int scan, const unsigned char *serialno_bin,
|
||||||
|
size_t serialno_bin_len)
|
||||||
{
|
{
|
||||||
gpg_error_t err = 0;
|
gpg_error_t err = 0;
|
||||||
app_t app;
|
app_t a;
|
||||||
|
|
||||||
*r_app = NULL;
|
*r_app = NULL;
|
||||||
|
|
||||||
@ -352,33 +354,50 @@ select_application (ctrl_t ctrl, const char *name, app_t *r_app, int scan)
|
|||||||
|
|
||||||
if (!sw || sw == SW_HOST_ALREADY_CONNECTED)
|
if (!sw || sw == SW_HOST_ALREADY_CONNECTED)
|
||||||
err = 0;
|
err = 0;
|
||||||
|
else if (sw == SW_HOST_NO_CARD)
|
||||||
|
err = gpg_error (GPG_ERR_CARD_NOT_PRESENT);
|
||||||
else
|
else
|
||||||
err = gpg_error (GPG_ERR_ENODEV);
|
err = gpg_error (GPG_ERR_ENODEV);
|
||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
err = app_new_register (slot, ctrl, name);
|
err = app_new_register (slot, ctrl, name);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
/* We close a reader with no card. */
|
||||||
apdu_close_reader (slot);
|
apdu_close_reader (slot);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
apdu_dev_list_finish (l);
|
apdu_dev_list_finish (l);
|
||||||
}
|
}
|
||||||
|
|
||||||
app = app_top;
|
npth_mutex_lock (&app_list_lock);
|
||||||
if (app)
|
for (a = app_top; a; a = a->next)
|
||||||
{
|
{
|
||||||
lock_app (app, ctrl);
|
lock_app (a, ctrl);
|
||||||
err = check_conflict (app, name);
|
if (serialno_bin == NULL)
|
||||||
|
break;
|
||||||
|
if (a->serialnolen == serialno_bin_len
|
||||||
|
&& !memcmp (a->serialno, serialno_bin, a->serialnolen))
|
||||||
|
break;
|
||||||
|
unlock_app (a);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a)
|
||||||
|
{
|
||||||
|
err = check_conflict (a, name);
|
||||||
if (!err)
|
if (!err)
|
||||||
{
|
{
|
||||||
app->ref_count++;
|
a->ref_count++;
|
||||||
*r_app = app;
|
*r_app = a;
|
||||||
}
|
}
|
||||||
unlock_app (app);
|
unlock_app (a);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
err = gpg_error (GPG_ERR_ENODEV);
|
err = gpg_error (GPG_ERR_ENODEV);
|
||||||
|
|
||||||
|
npth_mutex_unlock (&app_list_lock);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,10 +193,8 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
|
|||||||
|
|
||||||
/* If the card has not yet been opened, do it. */
|
/* If the card has not yet been opened, do it. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
open_card (ctrl_t ctrl, const char *apptype, int scan)
|
open_card (ctrl_t ctrl)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
|
||||||
|
|
||||||
/* If we ever got a card not present error code, return that. Only
|
/* If we ever got a card not present error code, return that. Only
|
||||||
the SERIALNO command and a reset are able to clear from that
|
the SERIALNO command and a reset are able to clear from that
|
||||||
state. */
|
state. */
|
||||||
@ -206,24 +204,46 @@ open_card (ctrl_t ctrl, const char *apptype, int scan)
|
|||||||
if ( IS_LOCKED (ctrl) )
|
if ( IS_LOCKED (ctrl) )
|
||||||
return gpg_error (GPG_ERR_LOCKED);
|
return gpg_error (GPG_ERR_LOCKED);
|
||||||
|
|
||||||
|
if (ctrl->app_ctx)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return select_application (ctrl, NULL, &ctrl->app_ctx, 0, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Explicitly open a card for a specific use of APPTYPE or SERIALNO. */
|
||||||
|
static gpg_error_t
|
||||||
|
open_card_with_request (ctrl_t ctrl, const char *apptype, const char *serialno)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
unsigned char *serialno_bin = NULL;
|
||||||
|
size_t serialno_bin_len = 0;
|
||||||
|
|
||||||
/* If we are already initialized for one specific application we
|
/* If we are already initialized for one specific application we
|
||||||
need to check that the client didn't requested a specific
|
need to check that the client didn't requested a specific
|
||||||
application different from the one in use before we continue. */
|
application different from the one in use before we continue. */
|
||||||
if (!scan && ctrl->app_ctx)
|
if (apptype && ctrl->app_ctx)
|
||||||
return check_application_conflict (apptype, ctrl->app_ctx);
|
return check_application_conflict (apptype, ctrl->app_ctx);
|
||||||
|
|
||||||
err = select_application (ctrl, apptype, &ctrl->app_ctx, scan);
|
if (serialno)
|
||||||
|
serialno_bin = hex_to_buffer (serialno, &serialno_bin_len);
|
||||||
|
|
||||||
|
err = select_application (ctrl, apptype, &ctrl->app_ctx, 1,
|
||||||
|
serialno_bin, serialno_bin_len);
|
||||||
|
xfree (serialno_bin);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char hlp_serialno[] =
|
static const char hlp_serialno[] =
|
||||||
"SERIALNO [<apptype>]\n"
|
"SERIALNO [--demand=<serialno>] [<apptype>]\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Return the serial number of the card using a status response. This\n"
|
"Return the serial number of the card using a status response. This\n"
|
||||||
"function should be used to check for the presence of a card.\n"
|
"function should be used to check for the presence of a card.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
"If --demand is given, an application on the card with SERIALNO is\n"
|
||||||
|
"selected and an error is returned if no such card available.\n"
|
||||||
|
"\n"
|
||||||
"If APPTYPE is given, an application of that type is selected and an\n"
|
"If APPTYPE is given, an application of that type is selected and an\n"
|
||||||
"error is returned if the application is not supported or available.\n"
|
"error is returned if the application is not supported or available.\n"
|
||||||
"The default is to auto-select the application using a hardwired\n"
|
"The default is to auto-select the application using a hardwired\n"
|
||||||
@ -245,17 +265,29 @@ cmd_serialno (assuan_context_t ctx, char *line)
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
char *serial;
|
char *serial;
|
||||||
time_t stamp;
|
time_t stamp;
|
||||||
|
const char *demand;
|
||||||
|
|
||||||
/* Clear the remove flag so that the open_card is able to reread it. */
|
|
||||||
if (ctrl->server_local->card_removed)
|
|
||||||
{
|
|
||||||
if ( IS_LOCKED (ctrl) )
|
if ( IS_LOCKED (ctrl) )
|
||||||
return gpg_error (GPG_ERR_LOCKED);
|
return gpg_error (GPG_ERR_LOCKED);
|
||||||
|
|
||||||
ctrl->server_local->card_removed = 0;
|
if ((demand = has_option_name (line, "--demand")))
|
||||||
|
{
|
||||||
|
if (*demand != '=')
|
||||||
|
return set_error (GPG_ERR_ASS_PARAMETER, "missing value for option");
|
||||||
|
line = (char *)++demand;
|
||||||
|
for (; *line && !spacep (line); line++)
|
||||||
|
;
|
||||||
|
if (*line)
|
||||||
|
*line++ = 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
demand = NULL;
|
||||||
|
|
||||||
if ((rc = open_card (ctrl, *line? line:NULL, 1)))
|
/* Clear the remove flag so that the open_card is able to reread it. */
|
||||||
|
if (ctrl->server_local->card_removed)
|
||||||
|
ctrl->server_local->card_removed = 0;
|
||||||
|
|
||||||
|
if ((rc = open_card_with_request (ctrl, *line? line:NULL, demand)))
|
||||||
{
|
{
|
||||||
ctrl->server_local->card_removed = 1;
|
ctrl->server_local->card_removed = 1;
|
||||||
return rc;
|
return rc;
|
||||||
@ -357,7 +389,7 @@ cmd_learn (assuan_context_t ctx, char *line)
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
int only_keypairinfo = has_option (line, "--keypairinfo");
|
int only_keypairinfo = has_option (line, "--keypairinfo");
|
||||||
|
|
||||||
if ((rc = open_card (ctrl, NULL, 0)))
|
if ((rc = open_card (ctrl)))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
/* Unless the force option is used we try a shortcut by identifying
|
/* Unless the force option is used we try a shortcut by identifying
|
||||||
@ -440,7 +472,7 @@ cmd_readcert (assuan_context_t ctx, char *line)
|
|||||||
unsigned char *cert;
|
unsigned char *cert;
|
||||||
size_t ncert;
|
size_t ncert;
|
||||||
|
|
||||||
if ((rc = open_card (ctrl, NULL, 0)))
|
if ((rc = open_card (ctrl)))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
line = xstrdup (line); /* Need a copy of the line. */
|
line = xstrdup (line); /* Need a copy of the line. */
|
||||||
@ -482,7 +514,7 @@ cmd_readkey (assuan_context_t ctx, char *line)
|
|||||||
unsigned char *pk;
|
unsigned char *pk;
|
||||||
size_t pklen;
|
size_t pklen;
|
||||||
|
|
||||||
if ((rc = open_card (ctrl, NULL, 0)))
|
if ((rc = open_card (ctrl)))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (has_option (line, "--advanced"))
|
if (has_option (line, "--advanced"))
|
||||||
@ -704,7 +736,7 @@ cmd_pksign (assuan_context_t ctx, char *line)
|
|||||||
|
|
||||||
line = skip_options (line);
|
line = skip_options (line);
|
||||||
|
|
||||||
if ((rc = open_card (ctrl, NULL, 0)))
|
if ((rc = open_card (ctrl)))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
/* We have to use a copy of the key ID because the function may use
|
/* We have to use a copy of the key ID because the function may use
|
||||||
@ -748,7 +780,7 @@ cmd_pkauth (assuan_context_t ctx, char *line)
|
|||||||
size_t outdatalen;
|
size_t outdatalen;
|
||||||
char *keyidstr;
|
char *keyidstr;
|
||||||
|
|
||||||
if ((rc = open_card (ctrl, NULL, 0)))
|
if ((rc = open_card (ctrl)))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (!ctrl->app_ctx)
|
if (!ctrl->app_ctx)
|
||||||
@ -793,7 +825,7 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line)
|
|||||||
char *keyidstr;
|
char *keyidstr;
|
||||||
unsigned int infoflags;
|
unsigned int infoflags;
|
||||||
|
|
||||||
if ((rc = open_card (ctrl, NULL, 0)))
|
if ((rc = open_card (ctrl)))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
keyidstr = xtrystrdup (line);
|
keyidstr = xtrystrdup (line);
|
||||||
@ -846,7 +878,7 @@ cmd_getattr (assuan_context_t ctx, char *line)
|
|||||||
int rc;
|
int rc;
|
||||||
const char *keyword;
|
const char *keyword;
|
||||||
|
|
||||||
if ((rc = open_card (ctrl, NULL, 0)))
|
if ((rc = open_card (ctrl)))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
keyword = line;
|
keyword = line;
|
||||||
@ -888,7 +920,7 @@ cmd_setattr (assuan_context_t ctx, char *orig_line)
|
|||||||
size_t nbytes;
|
size_t nbytes;
|
||||||
char *line, *linebuf;
|
char *line, *linebuf;
|
||||||
|
|
||||||
if ((rc = open_card (ctrl, NULL, 0)))
|
if ((rc = open_card (ctrl)))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
/* We need to use a copy of LINE, because PIN_CB uses the same
|
/* We need to use a copy of LINE, because PIN_CB uses the same
|
||||||
@ -943,7 +975,7 @@ cmd_writecert (assuan_context_t ctx, char *line)
|
|||||||
line++;
|
line++;
|
||||||
*line = 0;
|
*line = 0;
|
||||||
|
|
||||||
if ((rc = open_card (ctrl, NULL, 0)))
|
if ((rc = open_card (ctrl)))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (!ctrl->app_ctx)
|
if (!ctrl->app_ctx)
|
||||||
@ -1005,7 +1037,7 @@ cmd_writekey (assuan_context_t ctx, char *line)
|
|||||||
line++;
|
line++;
|
||||||
*line = 0;
|
*line = 0;
|
||||||
|
|
||||||
if ((rc = open_card (ctrl, NULL, 0)))
|
if ((rc = open_card (ctrl)))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (!ctrl->app_ctx)
|
if (!ctrl->app_ctx)
|
||||||
@ -1092,7 +1124,7 @@ cmd_genkey (assuan_context_t ctx, char *line)
|
|||||||
line++;
|
line++;
|
||||||
*line = 0;
|
*line = 0;
|
||||||
|
|
||||||
if ((rc = open_card (ctrl, NULL, 0)))
|
if ((rc = open_card (ctrl)))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (!ctrl->app_ctx)
|
if (!ctrl->app_ctx)
|
||||||
@ -1130,7 +1162,7 @@ cmd_random (assuan_context_t ctx, char *line)
|
|||||||
"number of requested bytes missing");
|
"number of requested bytes missing");
|
||||||
nbytes = strtoul (line, NULL, 0);
|
nbytes = strtoul (line, NULL, 0);
|
||||||
|
|
||||||
if ((rc = open_card (ctrl, NULL, 0)))
|
if ((rc = open_card (ctrl)))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (!ctrl->app_ctx)
|
if (!ctrl->app_ctx)
|
||||||
@ -1183,7 +1215,7 @@ cmd_passwd (assuan_context_t ctx, char *line)
|
|||||||
line++;
|
line++;
|
||||||
*line = 0;
|
*line = 0;
|
||||||
|
|
||||||
if ((rc = open_card (ctrl, NULL, 0)))
|
if ((rc = open_card (ctrl)))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (!ctrl->app_ctx)
|
if (!ctrl->app_ctx)
|
||||||
@ -1240,7 +1272,7 @@ cmd_checkpin (assuan_context_t ctx, char *line)
|
|||||||
int rc;
|
int rc;
|
||||||
char *idstr;
|
char *idstr;
|
||||||
|
|
||||||
if ((rc = open_card (ctrl, NULL, 0)))
|
if ((rc = open_card (ctrl)))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (!ctrl->app_ctx)
|
if (!ctrl->app_ctx)
|
||||||
@ -1531,7 +1563,7 @@ cmd_apdu (assuan_context_t ctx, char *line)
|
|||||||
|
|
||||||
line = skip_options (line);
|
line = skip_options (line);
|
||||||
|
|
||||||
if ((rc = open_card (ctrl, NULL, 0)))
|
if ((rc = open_card (ctrl)))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
app = ctrl->app_ctx;
|
app = ctrl->app_ctx;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user