[svn] GnuPG - r4922 - trunk/scd
svn author wk
cvs at cvs.gnupg.org
Tue Jan 27 17:38:33 CET 2009
Author: wk
Date: 2009-01-27 17:38:33 +0100 (Tue, 27 Jan 2009)
New Revision: 4922
Modified:
trunk/scd/ChangeLog
trunk/scd/app-geldkarte.c
Log:
Return the balance of a Geldkarte.
Modified: trunk/scd/ChangeLog
===================================================================
--- trunk/scd/ChangeLog 2009-01-27 11:30:02 UTC (rev 4921)
+++ trunk/scd/ChangeLog 2009-01-27 16:38:33 UTC (rev 4922)
@@ -1,5 +1,7 @@
2009-01-27 Werner Koch <wk at g10code.com>
+ * app-geldkarte.c: Changed to use an AID.
+
* app.c (app_munge_serialno): Add case for no serialno.
(app_get_serial_and_stamp): Ditto.
Modified: trunk/scd/app-geldkarte.c
===================================================================
--- trunk/scd/app-geldkarte.c 2009-01-27 11:30:02 UTC (rev 4921)
+++ trunk/scd/app-geldkarte.c 2009-01-27 16:38:33 UTC (rev 4922)
@@ -20,10 +20,9 @@
/* This is a read-only application to quickly dump information of a
- German Geldkarte (debit card for small amounts).
-
- Because this application does no use an AID it is best to test for
- it after the test for other applications.
+ German Geldkarte (debit card for small amounts). We only support
+ newer Geldkarte (with the AID DF_BOERSE_NEU) issued since 2000 or
+ even earlier.
*/
@@ -58,6 +57,9 @@
unsigned int currency_mult100;
unsigned char chipid;
unsigned char osvers;
+ int balance;
+ int maxamount;
+ int maxamount1;
};
@@ -109,11 +111,6 @@
err = send_one_string (ctrl, name, ld->country);
else if (!strcmp (name, "X-CURRENCY"))
err = send_one_string (ctrl, name, ld->currency);
- else if (!strcmp (name, "X-CRNCMULT"))
- {
- snprintf (numbuf, sizeof numbuf, "%u", ld->currency_mult100);
- err = send_one_string (ctrl, name, numbuf);
- }
else if (!strcmp (name, "X-ZKACHIPID"))
{
snprintf (numbuf, sizeof numbuf, "0x%02X", ld->chipid);
@@ -124,6 +121,24 @@
snprintf (numbuf, sizeof numbuf, "0x%02X", ld->osvers);
err = send_one_string (ctrl, name, numbuf);
}
+ else if (!strcmp (name, "X-BALANCE"))
+ {
+ snprintf (numbuf, sizeof numbuf, "%.2f",
+ (double)ld->balance / 100 * ld->currency_mult100);
+ err = send_one_string (ctrl, name, numbuf);
+ }
+ else if (!strcmp (name, "X-MAXAMOUNT"))
+ {
+ snprintf (numbuf, sizeof numbuf, "%.2f",
+ (double)ld->maxamount / 100 * ld->currency_mult100);
+ err = send_one_string (ctrl, name, numbuf);
+ }
+ else if (!strcmp (name, "X-MAXAMOUNT1"))
+ {
+ snprintf (numbuf, sizeof numbuf, "%.2f",
+ (double)ld->maxamount1 / 100 * ld->currency_mult100);
+ err = send_one_string (ctrl, name, numbuf);
+ }
else
err = gpg_error (GPG_ERR_INV_NAME);
@@ -142,9 +157,11 @@
"X-VALIDFROM",
"X-COUNTRY",
"X-CURRENCY",
- "X-CRNCMULT",
"X-ZKACHIPID",
"X-OSVERSION",
+ "X-BALANCE",
+ "X-MAXAMOUNT",
+ "X-MAXAMOUNT1",
NULL
};
gpg_error_t err = 0;
@@ -235,12 +252,28 @@
}
+/* Convert the BCD number at STING of LENGTH into an integer and store
+ that at RESULT. Return 0 on success. */
+static gpg_error_t
+bcd_to_int (const unsigned char *string, size_t length, int *result)
+{
+ char *tmp;
+ tmp = copy_bcd (string, length);
+ if (!tmp)
+ return gpg_error (GPG_ERR_BAD_DATA);
+ *result = strtol (tmp, NULL, 10);
+ xfree (tmp);
+ return 0;
+}
+
/* Select the Geldkarte application. */
gpg_error_t
app_select_geldkarte (app_t app)
{
+ static unsigned char const aid[] =
+ { 0xD2, 0x76, 0x00, 0x00, 0x25, 0x45, 0x50, 0x02, 0x00 };
gpg_error_t err;
int slot = app->slot;
unsigned char *result = NULL;
@@ -248,16 +281,16 @@
struct app_local_s *ld;
const char *banktype;
- err = iso7816_select_file (slot, 0x3f00, 1, NULL, NULL);
+ err = iso7816_select_application (slot, aid, sizeof aid, 0);
if (err)
- goto leave; /* Oops. */
-
- /* Read short EF 0xbc. We require this record to be at least 24
- bytes with the the first byte 0x67 and a correct the filler
- byte. */
- err = iso7816_read_record (slot, 1, 1, 0xbc, &result, &resultlen);
+ goto leave;
+
+ /* Read the first record of EF_ID (SFI=0x17). We require this
+ record to be at least 24 bytes with the the first byte 0x67 and a
+ correct filler byte. */
+ err = iso7816_read_record (slot, 1, 1, ((0x17 << 3)|4), &result, &resultlen);
if (err)
- goto leave; /* No such record or other error - not a Geldkarte. */
+ goto leave; /* Oops - not a Geldkarte. */
if (resultlen < 24 || *result != 0x67 || result[22])
{
err = gpg_error (GPG_ERR_NOT_FOUND);
@@ -280,6 +313,23 @@
app->apptype = "GELDKARTE";
app->fnc.deinit = do_deinit;
+ /* If we don't have a serialno yet construct it from the EF_ID. */
+ if (!app->serialno)
+ {
+ app->serialno = xtrymalloc (10);
+ if (!app->serialno)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ memcpy (app->serialno, result, 10);
+ app->serialnolen = 10;
+ err = app_munge_serialno (app);
+ if (err)
+ goto leave;
+ }
+
+
app->app_local = ld = xtrycalloc (1, sizeof *app->app_local);
if (!app->app_local)
{
@@ -324,6 +374,26 @@
ld->chipid = result[21];
ld->osvers = result[23];
+ /* Read the first record of EF_BETRAG (SFI=0x18). */
+ xfree (result);
+ err = iso7816_read_record (slot, 1, 1, ((0x18 << 3)|4), &result, &resultlen);
+ if (err)
+ goto leave; /* It does not make sense to continue. */
+ if (resultlen < 12)
+ {
+ err = gpg_error (GPG_ERR_NOT_FOUND);
+ goto leave;
+ }
+ err = bcd_to_int (result+0, 3, &ld->balance);
+ if (!err)
+ err = bcd_to_int (result+3, 3, &ld->maxamount);
+ if (!err)
+ err = bcd_to_int (result+6, 3, &ld->maxamount1);
+ /* The next 3 bytes are the maximum amount chargable without using a
+ MAC. This is usually 0. */
+ if (err)
+ goto leave;
+
/* Setup the rest of the methods. */
app->fnc.learn_status = do_learn_status;
app->fnc.getattr = do_getattr;
More information about the Gnupg-commits
mailing list