scd: Cleanup SERIALNO protocol.

* scd/app.c (app_get_serial_and_stamp): Remove.
(app_get_serialno): New.
(app_write_learn_status): Use send_status_direct.
(app_getattr): Use app_get_serialno for SERIALNO and
send with send_status_direct.
* scd/app-openpgp.c (do_getattr): Likewise.
* scd/command.c (cmd_serialno): Don't send TIMESTAMP of 0.
(cmd_learn): Likewise.  Don't inquire with TIMESTAMP of 0.

--

In the SERIALNO protocol, timestamp used to be considered, but had never
used at all.  In the new implementation, removed card/token is always
detected and connection becomes invalid, no timestamp is required any
more.  Examined scute and poldi as well for this protocol change.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2017-01-18 15:48:50 +09:00
parent 8b1f24a29e
commit 79cea89774
5 changed files with 40 additions and 68 deletions

View File

@ -516,11 +516,10 @@ done on the same card unless he call this function.
Return the serial number of the card using a status response like:
@example
S SERIALNO D27600000000000000000000 0
S SERIALNO D27600000000000000000000
@end example
The trailing 0 should be ignored for now, it is reserved for a future
extension. The serial number is the hex encoded value identified by
The serial number is the hex encoded value identified by
the @code{0x5A} tag in the GDO file (FIX=0x2F02).
@ -537,7 +536,7 @@ used without the @option{--force} option, the command might do an INQUIRE
like this:
@example
INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp>
INQUIRE KNOWNCARDP <hexstring_with_serialNumber>
@end example
The client should just send an @code{END} if the processing should go on

View File

@ -124,6 +124,7 @@ size_t app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff);
app_t app_list_start (void);
void app_list_finish (void);
void app_send_card_list (ctrl_t ctrl);
char *app_get_serialno (app_t app);
void app_dump_state (void);
void application_notify_card_reset (int slot);
@ -135,7 +136,6 @@ gpg_error_t select_application (ctrl_t ctrl, const char *name, app_t *r_app,
char *get_supported_applications (void);
void release_application (app_t app);
gpg_error_t app_munge_serialno (app_t app);
gpg_error_t app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp);
gpg_error_t app_write_learn_status (app_t app, ctrl_t ctrl,
unsigned int flags);
gpg_error_t app_readcert (app_t app, ctrl_t ctrl, const char *certid,

View File

@ -978,21 +978,13 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
if (table[idx].special == -1)
{
/* The serial number is very special. We could have used the
AID DO to retrieve it, but we have it already in the app
context and the stamp argument is required anyway which we
can't by other means. The AID DO is available anyway but not
hex formatted. */
char *serial;
time_t stamp;
char tmp[50];
AID DO to retrieve it. The AID DO is available anyway but
not hex formatted. */
char *serial = app_get_serialno (app);
if (!app_get_serial_and_stamp (app, &serial, &stamp))
if (serial)
{
sprintf (tmp, "%lu", (unsigned long)stamp);
send_status_info (ctrl, "SERIALNO",
serial, strlen (serial),
tmp, strlen (tmp),
NULL, 0);
send_status_direct (ctrl, "SERIALNO", serial);
xfree (serial);
}
return 0;
@ -1029,10 +1021,9 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
}
if (table[idx].special == -4)
{
char *serial;
time_t stamp;
char *serial = app_get_serialno (app);
if (!app_get_serial_and_stamp (app, &serial, &stamp))
if (serial)
{
if (strlen (serial) > 16+12)
{

View File

@ -534,33 +534,23 @@ app_munge_serialno (app_t app)
/* Retrieve the serial number and the time of the last update of the
card. The serial number is returned as a malloced string (hex
encoded) in SERIAL and the time of update is returned in STAMP. If
no update time is available the returned value is 0. Caller must
free SERIAL unless the function returns an error. If STAMP is not
of interest, NULL may be passed. */
gpg_error_t
app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp)
/* Retrieve the serial number of the card. The serial number is
returned as a malloced string (hex encoded) in SERIAL. Caller must
free SERIAL unless the function returns an error. */
char *
app_get_serialno (app_t app)
{
char *buf;
char *serial;
if (!app || !serial)
return gpg_error (GPG_ERR_INV_VALUE);
*serial = NULL;
if (stamp)
*stamp = 0; /* not available */
if (!app)
return NULL;
if (!app->serialnolen)
buf = xtrystrdup ("FF7F00");
serial = xtrystrdup ("FF7F00");
else
buf = bin2hex (app->serialno, app->serialnolen, NULL);
if (!buf)
return gpg_error_from_syserror ();
serial = bin2hex (app->serialno, app->serialnolen, NULL);
*serial = buf;
return 0;
return serial;
}
@ -578,8 +568,7 @@ app_write_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
/* We do not send APPTYPE if only keypairinfo is requested. */
if (app->apptype && !(flags & 1))
send_status_info (ctrl, "APPTYPE",
app->apptype, strlen (app->apptype), NULL, 0);
send_status_direct (ctrl, "APPTYPE", app->apptype);
err = lock_app (app, ctrl);
if (err)
return err;
@ -660,20 +649,18 @@ app_getattr (app_t app, ctrl_t ctrl, const char *name)
if (app->apptype && name && !strcmp (name, "APPTYPE"))
{
send_status_info (ctrl, "APPTYPE",
app->apptype, strlen (app->apptype), NULL, 0);
send_status_direct (ctrl, "APPTYPE", app->apptype);
return 0;
}
if (name && !strcmp (name, "SERIALNO"))
{
char *serial;
time_t stamp;
int rc;
rc = app_get_serial_and_stamp (app, &serial, &stamp);
if (rc)
return rc;
send_status_info (ctrl, "SERIALNO", serial, strlen (serial), NULL, 0);
serial = app_get_serialno (app);
if (!serial)
return gpg_error (GPG_ERR_INV_VALUE);
send_status_direct (ctrl, "SERIALNO", serial);
xfree (serial);
return 0;
}
@ -1114,7 +1101,7 @@ app_send_card_list (ctrl_t ctrl)
for (a = app_top; a; a = a->next)
{
if (DIM (buf) < 2 * a->serialnolen + 1)
continue;
continue;
bin2hex (a->serialno, a->serialnolen, buf);
send_status_direct (ctrl, "SERIALNO", buf);

View File

@ -264,7 +264,6 @@ cmd_serialno (assuan_context_t ctx, char *line)
struct server_local_s *sl;
int rc = 0;
char *serial;
time_t stamp;
const char *demand;
if ( IS_LOCKED (ctrl) )
@ -302,12 +301,11 @@ cmd_serialno (assuan_context_t ctx, char *line)
c->server_local->card_removed = 0;
}
rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
if (rc)
return rc;
serial = app_get_serialno (ctrl->app_ctx);
if (!serial)
return gpg_error (GPG_ERR_INV_VALUE);
rc = print_assuan_status (ctx, "SERIALNO", "%s %lu",
serial, (unsigned long)stamp);
rc = assuan_write_status (ctx, "SERIALNO", serial);
xfree (serial);
return rc;
}
@ -320,7 +318,7 @@ static const char hlp_learn[] =
"used without the force options, the command might do an INQUIRE\n"
"like this:\n"
"\n"
" INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp>\n"
" INQUIRE KNOWNCARDP <hexstring_with_serialNumber>\n"
"\n"
"The client should just send an \"END\" if the processing should go on\n"
"or a \"CANCEL\" to force the function to terminate with a Cancel\n"
@ -400,7 +398,6 @@ cmd_learn (assuan_context_t ctx, char *line)
{
const char *reader;
char *serial;
time_t stamp;
app_t app = ctrl->app_ctx;
if (!app)
@ -412,12 +409,11 @@ cmd_learn (assuan_context_t ctx, char *line)
send_status_direct (ctrl, "READER", reader);
/* No need to free the string of READER. */
rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
if (rc)
return rc;
serial = app_get_serialno (ctrl->app_ctx);
if (!serial)
return gpg_error (GPG_ERR_INV_VALUE);
rc = print_assuan_status (ctx, "SERIALNO", "%s %lu",
serial, (unsigned long)stamp);
rc = assuan_write_status (ctx, "SERIALNO", serial);
if (rc < 0)
{
xfree (serial);
@ -428,8 +424,7 @@ cmd_learn (assuan_context_t ctx, char *line)
{
char *command;
rc = gpgrt_asprintf (&command, "KNOWNCARDP %s %lu",
serial, (unsigned long)stamp);
rc = gpgrt_asprintf (&command, "KNOWNCARDP %s", serial);
if (rc < 0)
{
xfree (serial);