aboutsummaryrefslogtreecommitdiffstats
path: root/scd/iso7816.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2009-01-08 19:56:30 +0000
committerWerner Koch <[email protected]>2009-01-08 19:56:30 +0000
commit7784e86a66928fe88ba040b1eecf30300c0a1496 (patch)
tree0e50de2dfb62e152a80be598498f986c326a65d0 /scd/iso7816.c
parentFix error detection (diff)
downloadgnupg-7784e86a66928fe88ba040b1eecf30300c0a1496.tar.gz
gnupg-7784e86a66928fe88ba040b1eecf30300c0a1496.zip
Add limited support for NetKey 3.0 cards.
Diffstat (limited to 'scd/iso7816.c')
-rw-r--r--scd/iso7816.c57
1 files changed, 45 insertions, 12 deletions
diff --git a/scd/iso7816.c b/scd/iso7816.c
index 2286090b6..ecb6dc1bd 100644
--- a/scd/iso7816.c
+++ b/scd/iso7816.c
@@ -1,5 +1,5 @@
/* iso7816.c - ISO 7816 commands
- * Copyright (C) 2003, 2004, 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2003, 2004, 2008, 2009 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -226,6 +226,48 @@ iso7816_list_directory (int slot, int list_dirs,
}
+/* This funcion sends an already formatted APDU to the card. With
+ HANDLE_MORE set to true a MORE DATA status will be handled
+ internally. The return value is a gpg error code (i.e. a mapped
+ status word). This is basically the same as apdu_send_direct but
+ it maps the status word and does not return it in the result
+ buffer. */
+gpg_error_t
+iso7816_apdu_direct (int slot, const void *apdudata, size_t apdudatalen,
+ int handle_more,
+ unsigned char **result, size_t *resultlen)
+{
+ int sw;
+
+ if (!result || !resultlen)
+ return gpg_error (GPG_ERR_INV_VALUE);
+ *result = NULL;
+ *resultlen = 0;
+
+ sw = apdu_send_direct (slot, apdudata, apdudatalen, handle_more,
+ result, resultlen);
+ if (!sw)
+ {
+ if (*resultlen < 2)
+ sw = SW_HOST_GENERAL_ERROR;
+ else
+ {
+ sw = ((*result)[*resultlen-2] << 8) | (*result)[*resultlen-1];
+ (*resultlen)--;
+ (*resultlen)--;
+ }
+ }
+ if (sw != SW_SUCCESS)
+ {
+ /* Make sure that pending buffers are released. */
+ xfree (*result);
+ *result = NULL;
+ *resultlen = 0;
+ }
+ return map_sw (sw);
+}
+
+
/* Check whether the reader supports the ISO command code COMMAND on
the keypad. Returns 0 on success. */
gpg_error_t
@@ -668,14 +710,7 @@ iso7816_read_binary (int slot, size_t offset, size_t nmax,
{
buffer = NULL;
bufferlen = 0;
- /* Note, that we to set N to 254 due to problems either with the
- ccid driver or some TCOS cards. It actually should be 0
- which is the official ISO value to read a variable length
- object. */
- if (read_all || nmax > 254)
- n = 254;
- else
- n = nmax;
+ n = read_all? 0 : nmax;
sw = apdu_send_le (slot, 0x00, CMD_READ_BINARY,
((offset>>8) & 0xff), (offset & 0xff) , -1, NULL,
n, &buffer, &bufferlen);
@@ -769,13 +804,11 @@ iso7816_read_record (int slot, int recno, int reccount, int short_ef,
buffer = NULL;
bufferlen = 0;
- /* Fixme: Either the ccid driver or the TCOS cards have problems
- with an Le of 0. */
sw = apdu_send_le (slot, 0x00, CMD_READ_RECORD,
recno,
short_ef? short_ef : 0x04,
-1, NULL,
- 254, &buffer, &bufferlen);
+ 0, &buffer, &bufferlen);
if (sw != SW_SUCCESS && sw != SW_EOF_REACHED)
{