* app.c (select_application): Fixed serial number extraction and

added the BMI card workaround.
(app_munge_serialno): New.
* app-openpgp.c (app_select_openpgp): Try munging serialno.
This commit is contained in:
Werner Koch 2004-09-09 07:28:47 +00:00
parent 0cb56ad4ac
commit 9d74d40da1
4 changed files with 74 additions and 3 deletions

View File

@ -1,3 +1,10 @@
2004-08-20 Werner Koch <wk@g10code.de>
* app.c (select_application): Fixed serial number extraction and
added the BMI card workaround.
(app_munge_serialno): New.
* app-openpgp.c (app_select_openpgp): Try munging serialno.
2004-08-05 Werner Koch <wk@g10code.de>
* scdaemon.c (main): New option --disable-application.

View File

@ -95,6 +95,7 @@ size_t app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff);
/*-- app.c --*/
app_t select_application (ctrl_t ctrl, int slot, const char *name);
void release_application (app_t app);
int app_munge_serialno (app_t app);
int app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp);
int app_write_learn_status (app_t app, ctrl_t ctrl);
int app_readcert (app_t app, const char *certid,
@ -159,6 +160,9 @@ int app_select_nks (app_t app);
/*-- app-dinsig.c --*/
int app_select_dinsig (app_t app);
/*-- app-p15.c --*/
int app_select_p15 (app_t app);
#endif

View File

@ -1394,6 +1394,13 @@ app_select_openpgp (APP app)
log_info ("got AID: ");
log_printhex ("", buffer, buflen);
}
#if GNUPG_MAJOR_VERSION != 1
/* A valid OpenPGP card should never need this but well the test
is cheap. */
rc = app_number_serialno (app);
if (rc)
goto leave;
#endif
app->card_version = buffer[6] << 8;
app->card_version |= buffer[7];

View File

@ -1,5 +1,5 @@
/* app.c - Application selection.
* Copyright (C) 2003 Free Software Foundation, Inc.
* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -45,6 +45,7 @@ is_app_allowed (const char *name)
return 1; /* yes */
}
/* If called with NAME as NULL, select the best fitting application
and return a context; otherwise select the application with NAME
and return a context. SLOT identifies the reader device. Returns
@ -81,31 +82,50 @@ select_application (ctrl_t ctrl, int slot, const char *name)
const unsigned char *p;
p = find_tlv (result, resultlen, 0x5A, &n);
if (p && n && n >= (resultlen - (p - result)))
if (p)
resultlen -= (p-result);
if (p && n > resultlen && n == 0x0d && resultlen+1 == n)
{
/* The object it does not fit into the buffer. This is an
invalid encoding (or the buffer is too short. However, I
have some test cards with such an invalid encoding and
therefore I use this ugly workaround to return something
I can further experiment with. */
log_debug ("enabling BMI testcard workaround\n");
n--;
}
if (p && n <= resultlen)
{
/* The GDO file is pretty short, thus we simply reuse it for
storing the serial number. */
memmove (result, p, n);
app->serialno = result;
app->serialnolen = n;
rc = app_munge_serialno (app);
if (rc)
goto leave;
}
else
xfree (result);
result = NULL;
}
rc = gpg_error (GPG_ERR_NOT_FOUND);
if (rc && is_app_allowed ("openpgp") && (!name || !strcmp (name, "openpgp")))
rc = app_select_openpgp (app);
if (rc && is_app_allowed ("nks") && (!name || !strcmp (name, "nks")))
rc = app_select_nks (app);
/* if (rc && is_app_allowed ("p12") && (!name || !strcmp (name, "p12"))) */
/* rc = app_select_p12 (app); */
if (rc && is_app_allowed ("dinsig") && (!name || !strcmp (name, "dinsig")))
rc = app_select_dinsig (app);
if (rc && name)
rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
leave:
if (rc)
{
if (name)
@ -141,6 +161,39 @@ release_application (app_t app)
/* The serial number may need some cosmetics. Do it here. This
function shall only be called once after a new serial number has
been put into APP->serialno.
Prefixes we use:
FF 00 00 = For serial numbers starting with an FF
FF 01 00 = Some german p15 cards return an empty serial number so the
serial number from the EF(TokeInfo is used instead.
All other serial number not starting with FF are used as they are.
*/
int
app_munge_serialno (app_t app)
{
if (app->serialnolen && app->serialno[0] == 0xff)
{
/* The serial number starts with our special prefix. This
requires that we put our default prefix "FF0000" in front. */
unsigned char *p = xtrymalloc (app->serialnolen + 3);
if (!p)
return gpg_error (gpg_err_code_from_errno (errno));
memcpy (p, "\xff\0", 3);
memcpy (p+3, app->serialno, app->serialnolen);
app->serialnolen += 3;
xfree (app->serialno);
app->serialno = p;
}
return 0;
}
/* 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