aboutsummaryrefslogtreecommitdiffstats
path: root/scd/app.c
diff options
context:
space:
mode:
authorMarcus Brinkmann <[email protected]>2012-01-03 17:13:19 +0000
committerMarcus Brinkmann <[email protected]>2012-01-03 17:13:19 +0000
commit0868997e186cd847663668f9d7a29806a12da2d2 (patch)
tree73645f778a2d16213723121a76d2b38ca90edfcc /scd/app.c
parentAdd lost ChangeLog entry. (diff)
parentSilence gcc warning. (diff)
downloadgnupg-npth.tar.gz
gnupg-npth.zip
Merge branch 'master' into npthnpth
Conflicts: ChangeLog-2011 Makefile.am agent/ChangeLog-2011 agent/gpg-agent.c dirmngr/ChangeLog-2011 dirmngr/dirmngr.c doc/HACKING g13/g13.c po/de.po scd/ChangeLog-2011 scd/apdu.c scd/command.c scd/scdaemon.c scripts/gitlog-to-changelog tools/ChangeLog-2011
Diffstat (limited to 'scd/app.c')
-rw-r--r--scd/app.c104
1 files changed, 61 insertions, 43 deletions
diff --git a/scd/app.c b/scd/app.c
index 97260082e..79e3eac0f 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -198,18 +198,19 @@ application_notify_card_reset (int slot)
used to request a specific application and the connection has
already done a select_application. */
gpg_error_t
-check_application_conflict (ctrl_t ctrl, const char *name)
+check_application_conflict (ctrl_t ctrl, int slot, const char *name)
{
- int slot = ctrl->reader_slot;
app_t app;
+ (void)ctrl;
+
if (slot < 0 || slot >= DIM (lock_table))
return gpg_error (GPG_ERR_INV_VALUE);
app = lock_table[slot].initialized ? lock_table[slot].app : NULL;
if (app && app->apptype && name)
if ( ascii_strcasecmp (app->apptype, name))
- return gpg_error (GPG_ERR_CONFLICT);
+ return gpg_error (GPG_ERR_CONFLICT);
return 0;
}
@@ -226,11 +227,14 @@ select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app)
app_t app = NULL;
unsigned char *result = NULL;
size_t resultlen;
+ int want_undefined;
(void)ctrl;
*r_app = NULL;
+ want_undefined = (name && !strcmp (name, "undefined"));
+
err = lock_reader (slot, ctrl);
if (err)
return err;
@@ -310,45 +314,49 @@ select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app)
/* Fixme: We should now first check whether a card is at all
present. */
- /* Try to read the GDO file first to get a default serial number. */
- err = iso7816_select_file (slot, 0x3F00, 1, NULL, NULL);
- if (!err)
- err = iso7816_select_file (slot, 0x2F02, 0, NULL, NULL);
- if (!err)
- err = iso7816_read_binary (slot, 0, 0, &result, &resultlen);
- if (!err)
+ /* Try to read the GDO file first to get a default serial number.
+ We skip this if the undefined application has been requested. */
+ if (!want_undefined)
{
- size_t n;
- const unsigned char *p;
-
- p = find_tlv_unchecked (result, resultlen, 0x5A, &n);
- if (p)
- resultlen -= (p-result);
- if (p && n > resultlen && n == 0x0d && resultlen+1 == n)
+ err = iso7816_select_file (slot, 0x3F00, 1, NULL, NULL);
+ if (!err)
+ err = iso7816_select_file (slot, 0x2F02, 0, NULL, NULL);
+ if (!err)
+ err = iso7816_read_binary (slot, 0, 0, &result, &resultlen);
+ if (!err)
{
- /* 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_info ("enabling BMI testcard workaround\n");
- n--;
+ size_t n;
+ const unsigned char *p;
+
+ p = find_tlv_unchecked (result, resultlen, 0x5A, &n);
+ 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_info ("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;
+ err = app_munge_serialno (app);
+ if (err)
+ goto leave;
+ }
+ else
+ xfree (result);
+ result = NULL;
}
-
- 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;
- err = app_munge_serialno (app);
- if (err)
- goto leave;
- }
- else
- xfree (result);
- result = NULL;
}
/* For certain error codes, there is no need to try more. */
@@ -357,7 +365,15 @@ select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app)
goto leave;
/* Figure out the application to use. */
- err = gpg_error (GPG_ERR_NOT_FOUND);
+ if (want_undefined)
+ {
+ /* We switch to the "undefined" application only if explicitly
+ requested. */
+ app->apptype = "UNDEFINED";
+ err = 0;
+ }
+ else
+ err = gpg_error (GPG_ERR_NOT_FOUND);
if (err && is_app_allowed ("openpgp")
&& (!name || !strcmp (name, "openpgp")))
@@ -366,11 +382,11 @@ select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app)
err = app_select_nks (app);
if (err && is_app_allowed ("p15") && (!name || !strcmp (name, "p15")))
err = app_select_p15 (app);
- if (err && is_app_allowed ("dinsig") && (!name || !strcmp (name, "dinsig")))
- err = app_select_dinsig (app);
if (err && is_app_allowed ("geldkarte")
&& (!name || !strcmp (name, "geldkarte")))
err = app_select_geldkarte (app);
+ if (err && is_app_allowed ("dinsig") && (!name || !strcmp (name, "dinsig")))
+ err = app_select_dinsig (app);
if (err && name)
err = gpg_error (GPG_ERR_NOT_SUPPORTED);
@@ -404,8 +420,10 @@ get_supported_applications (void)
"openpgp",
"nks",
"p15",
- "dinsig",
"geldkarte",
+ "dinsig",
+ /* Note: "undefined" is not listed here because it needs special
+ treatment by the client. */
NULL
};
int idx;