aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2004-09-09 07:28:47 +0000
committerWerner Koch <[email protected]>2004-09-09 07:28:47 +0000
commit9d74d40da1e3b58a994dc3435e6feb07fb1fc420 (patch)
treed070f73e64fd768480b1b2303117586e8f097878
parent(check_for_running_agent): New. (diff)
downloadgnupg-9d74d40da1e3b58a994dc3435e6feb07fb1fc420.tar.gz
gnupg-9d74d40da1e3b58a994dc3435e6feb07fb1fc420.zip
* 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.
-rw-r--r--scd/ChangeLog7
-rw-r--r--scd/app-common.h4
-rw-r--r--scd/app-openpgp.c7
-rw-r--r--scd/app.c59
4 files changed, 74 insertions, 3 deletions
diff --git a/scd/ChangeLog b/scd/ChangeLog
index 80b244ef1..a527b5da5 100644
--- a/scd/ChangeLog
+++ b/scd/ChangeLog
@@ -1,3 +1,10 @@
+2004-08-20 Werner Koch <[email protected]>
+
+ * 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 <[email protected]>
* scdaemon.c (main): New option --disable-application.
diff --git a/scd/app-common.h b/scd/app-common.h
index c61bcca60..c15f174bf 100644
--- a/scd/app-common.h
+++ b/scd/app-common.h
@@ -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
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index 3dc015baa..67bc336ec 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -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];
diff --git a/scd/app.c b/scd/app.c
index b3a13f19a..55fb5861e 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -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