diff options
author | Werner Koch <[email protected]> | 2009-01-08 19:56:30 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2009-01-08 19:56:30 +0000 |
commit | 7784e86a66928fe88ba040b1eecf30300c0a1496 (patch) | |
tree | 0e50de2dfb62e152a80be598498f986c326a65d0 /scd/iso7816.c | |
parent | Fix error detection (diff) | |
download | gnupg-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.c | 57 |
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) { |