[Pkg-gnupg-commit] [gnupg2] 71/116: scd: Add --demand option for SERIALNO.
Daniel Kahn Gillmor
dkg at fifthhorseman.net
Tue Jan 24 04:40:55 UTC 2017
This is an automated email from the git hooks/post-receive script.
dkg pushed a commit to branch master
in repository gnupg2.
commit 2e6f1c99d4f66a23a752092397e20a84964edf48
Author: NIIBE Yutaka <gniibe at fsij.org>
Date: Mon Jan 16 10:26:16 2017 +0900
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 at fsij.org>
---
scd/app-common.h | 3 +-
scd/app.c | 39 ++++++++++++++++++-------
scd/command.c | 88 ++++++++++++++++++++++++++++++++++++++------------------
3 files changed, 91 insertions(+), 39 deletions(-)
diff --git a/scd/app-common.h b/scd/app-common.h
index 2371818..fb0fe55 100644
--- a/scd/app-common.h
+++ b/scd/app-common.h
@@ -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 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,
- int scan);
+ int scan, const unsigned char *serialno_bin,
+ size_t serialno_bin_len);
char *get_supported_applications (void);
void release_application (app_t app);
gpg_error_t app_munge_serialno (app_t app);
diff --git a/scd/app.c b/scd/app.c
index 6db9e27..06850d8 100644
--- a/scd/app.c
+++ b/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
R_APP if no application was found or no card is present. */
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;
- app_t app;
+ app_t a;
*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)
err = 0;
+ else if (sw == SW_HOST_NO_CARD)
+ err = gpg_error (GPG_ERR_CARD_NOT_PRESENT);
else
err = gpg_error (GPG_ERR_ENODEV);
if (!err)
err = app_new_register (slot, ctrl, name);
else
- apdu_close_reader (slot);
+ {
+ /* We close a reader with no card. */
+ apdu_close_reader (slot);
+ }
}
apdu_dev_list_finish (l);
}
- app = app_top;
- if (app)
+ npth_mutex_lock (&app_list_lock);
+ for (a = app_top; a; a = a->next)
{
- lock_app (app, ctrl);
- err = check_conflict (app, name);
+ lock_app (a, ctrl);
+ 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)
{
- app->ref_count++;
- *r_app = app;
+ a->ref_count++;
+ *r_app = a;
}
- unlock_app (app);
+ unlock_app (a);
}
else
err = gpg_error (GPG_ERR_ENODEV);
+ npth_mutex_unlock (&app_list_lock);
+
return err;
}
diff --git a/scd/command.c b/scd/command.c
index ce2be34..dc854e3 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -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. */
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
the SERIALNO command and a reset are able to clear from that
state. */
@@ -206,24 +204,46 @@ open_card (ctrl_t ctrl, const char *apptype, int scan)
if ( IS_LOCKED (ctrl) )
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
need to check that the client didn't requested a specific
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);
- 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;
}
static const char hlp_serialno[] =
- "SERIALNO [<apptype>]\n"
+ "SERIALNO [--demand=<serialno>] [<apptype>]\n"
"\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"
"\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"
"error is returned if the application is not supported or available.\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;
char *serial;
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) )
- return gpg_error (GPG_ERR_LOCKED);
+ if ( IS_LOCKED (ctrl) )
+ 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;
+
+ /* 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 (ctrl, *line? line:NULL, 1)))
+ if ((rc = open_card_with_request (ctrl, *line? line:NULL, demand)))
{
ctrl->server_local->card_removed = 1;
return rc;
@@ -357,7 +389,7 @@ cmd_learn (assuan_context_t ctx, char *line)
int rc = 0;
int only_keypairinfo = has_option (line, "--keypairinfo");
- if ((rc = open_card (ctrl, NULL, 0)))
+ if ((rc = open_card (ctrl)))
return rc;
/* 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;
size_t ncert;
- if ((rc = open_card (ctrl, NULL, 0)))
+ if ((rc = open_card (ctrl)))
return rc;
line = xstrdup (line); /* Need a copy of the line. */
@@ -482,7 +514,7 @@ cmd_readkey (assuan_context_t ctx, char *line)
unsigned char *pk;
size_t pklen;
- if ((rc = open_card (ctrl, NULL, 0)))
+ if ((rc = open_card (ctrl)))
return rc;
if (has_option (line, "--advanced"))
@@ -704,7 +736,7 @@ cmd_pksign (assuan_context_t ctx, char *line)
line = skip_options (line);
- if ((rc = open_card (ctrl, NULL, 0)))
+ if ((rc = open_card (ctrl)))
return rc;
/* 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;
char *keyidstr;
- if ((rc = open_card (ctrl, NULL, 0)))
+ if ((rc = open_card (ctrl)))
return rc;
if (!ctrl->app_ctx)
@@ -793,7 +825,7 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line)
char *keyidstr;
unsigned int infoflags;
- if ((rc = open_card (ctrl, NULL, 0)))
+ if ((rc = open_card (ctrl)))
return rc;
keyidstr = xtrystrdup (line);
@@ -846,7 +878,7 @@ cmd_getattr (assuan_context_t ctx, char *line)
int rc;
const char *keyword;
- if ((rc = open_card (ctrl, NULL, 0)))
+ if ((rc = open_card (ctrl)))
return rc;
keyword = line;
@@ -888,7 +920,7 @@ cmd_setattr (assuan_context_t ctx, char *orig_line)
size_t nbytes;
char *line, *linebuf;
- if ((rc = open_card (ctrl, NULL, 0)))
+ if ((rc = open_card (ctrl)))
return rc;
/* 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 = 0;
- if ((rc = open_card (ctrl, NULL, 0)))
+ if ((rc = open_card (ctrl)))
return rc;
if (!ctrl->app_ctx)
@@ -1005,7 +1037,7 @@ cmd_writekey (assuan_context_t ctx, char *line)
line++;
*line = 0;
- if ((rc = open_card (ctrl, NULL, 0)))
+ if ((rc = open_card (ctrl)))
return rc;
if (!ctrl->app_ctx)
@@ -1092,7 +1124,7 @@ cmd_genkey (assuan_context_t ctx, char *line)
line++;
*line = 0;
- if ((rc = open_card (ctrl, NULL, 0)))
+ if ((rc = open_card (ctrl)))
return rc;
if (!ctrl->app_ctx)
@@ -1130,7 +1162,7 @@ cmd_random (assuan_context_t ctx, char *line)
"number of requested bytes missing");
nbytes = strtoul (line, NULL, 0);
- if ((rc = open_card (ctrl, NULL, 0)))
+ if ((rc = open_card (ctrl)))
return rc;
if (!ctrl->app_ctx)
@@ -1183,7 +1215,7 @@ cmd_passwd (assuan_context_t ctx, char *line)
line++;
*line = 0;
- if ((rc = open_card (ctrl, NULL, 0)))
+ if ((rc = open_card (ctrl)))
return rc;
if (!ctrl->app_ctx)
@@ -1240,7 +1272,7 @@ cmd_checkpin (assuan_context_t ctx, char *line)
int rc;
char *idstr;
- if ((rc = open_card (ctrl, NULL, 0)))
+ if ((rc = open_card (ctrl)))
return rc;
if (!ctrl->app_ctx)
@@ -1531,7 +1563,7 @@ cmd_apdu (assuan_context_t ctx, char *line)
line = skip_options (line);
- if ((rc = open_card (ctrl, NULL, 0)))
+ if ((rc = open_card (ctrl)))
return rc;
app = ctrl->app_ctx;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/gnupg2.git
More information about the Pkg-gnupg-commit
mailing list