mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-23 10:29:58 +01:00
cygwin fixes
This commit is contained in:
parent
b9f1815947
commit
2b50f31435
@ -1,3 +1,26 @@
|
|||||||
|
2005-10-27 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* gpg.c [__CYGWIN__]: Set default driver to winscard.dll.
|
||||||
|
|
||||||
|
* apdu.c, apdu.h: Updated from gnupg 1.9. Changes are:
|
||||||
|
* apdu.c [__CYGWIN__]: Make cygwin environment similar to _WIN32.
|
||||||
|
Suggested by John P. Clizbe.
|
||||||
|
* apdu.h (SW_HOST_NO_KEYPAD): New.
|
||||||
|
* apdu.c (host_sw_string): Support new code.
|
||||||
|
(reader_table_s): New field CHECK_KEYPAD.
|
||||||
|
(new_reader_slot, open_ct_reader, open_pcsc_reader)
|
||||||
|
(open_ccid_reader, open_rapdu_reader): Initialize it.
|
||||||
|
(check_ccid_keypad): New.
|
||||||
|
(apdu_check_keypad): New.
|
||||||
|
(apdu_send_le): Factored all code out to ...
|
||||||
|
(send_le): .. new. Takes an additional arg; changed all callers
|
||||||
|
of the orginal function to use this one with a NULL for the new
|
||||||
|
arg.
|
||||||
|
(apdu_send_simple_kp): New.
|
||||||
|
(ct_send_apdu, pcsc_send_apdu, my_rapdu_send_apdu)
|
||||||
|
(send_apdu_ccid): New arg PININFO.
|
||||||
|
(send_apdu_ccid): Use the new arg.
|
||||||
|
|
||||||
2005-10-26 David Shaw <dshaw@jabberwocky.com>
|
2005-10-26 David Shaw <dshaw@jabberwocky.com>
|
||||||
|
|
||||||
* keygen.c (proc_parameter_file): Default key and subkey usage
|
* keygen.c (proc_parameter_file): Default key and subkey usage
|
||||||
|
168
g10/apdu.c
168
g10/apdu.c
@ -66,10 +66,10 @@
|
|||||||
#include "ccid-driver.h"
|
#include "ccid-driver.h"
|
||||||
|
|
||||||
|
|
||||||
/* To to conflicting use of threading libraries we usually can't link
|
/* Due to conflicting use of threading libraries we usually can't link
|
||||||
against libpcsclite. Instead we use a wrapper program. */
|
against libpcsclite. Instead we use a wrapper program. */
|
||||||
#ifdef USE_GNU_PTH
|
#ifdef USE_GNU_PTH
|
||||||
#ifndef HAVE_W32_SYSTEM
|
#if !defined(HAVE_W32_SYSTEM) && !defined(__CYGWIN__)
|
||||||
#define NEED_PCSC_WRAPPER 1
|
#define NEED_PCSC_WRAPPER 1
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@ -78,7 +78,7 @@
|
|||||||
#define MAX_READER 4 /* Number of readers we support concurrently. */
|
#define MAX_READER 4 /* Number of readers we support concurrently. */
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
#define DLSTDCALL __stdcall
|
#define DLSTDCALL __stdcall
|
||||||
#else
|
#else
|
||||||
#define DLSTDCALL
|
#define DLSTDCALL
|
||||||
@ -90,6 +90,14 @@
|
|||||||
#define MAX_OPEN_FDS 20
|
#define MAX_OPEN_FDS 20
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Helper to pass patrameters related to keypad based operations. */
|
||||||
|
struct pininfo_s
|
||||||
|
{
|
||||||
|
int mode;
|
||||||
|
int minlen;
|
||||||
|
int maxlen;
|
||||||
|
int padlen;
|
||||||
|
};
|
||||||
|
|
||||||
/* A structure to collect information pertaining to one reader
|
/* A structure to collect information pertaining to one reader
|
||||||
slot. */
|
slot. */
|
||||||
@ -103,7 +111,8 @@ struct reader_table_s {
|
|||||||
int (*reset_reader)(int);
|
int (*reset_reader)(int);
|
||||||
int (*get_status_reader)(int, unsigned int *);
|
int (*get_status_reader)(int, unsigned int *);
|
||||||
int (*send_apdu_reader)(int,unsigned char *,size_t,
|
int (*send_apdu_reader)(int,unsigned char *,size_t,
|
||||||
unsigned char *, size_t *);
|
unsigned char *, size_t *, struct pininfo_s *);
|
||||||
|
int (*check_keypad)(int, int, int, int, int, int);
|
||||||
void (*dump_status_reader)(int);
|
void (*dump_status_reader)(int);
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@ -320,6 +329,7 @@ new_reader_slot (void)
|
|||||||
reader_table[reader].reset_reader = NULL;
|
reader_table[reader].reset_reader = NULL;
|
||||||
reader_table[reader].get_status_reader = NULL;
|
reader_table[reader].get_status_reader = NULL;
|
||||||
reader_table[reader].send_apdu_reader = NULL;
|
reader_table[reader].send_apdu_reader = NULL;
|
||||||
|
reader_table[reader].check_keypad = NULL;
|
||||||
reader_table[reader].dump_status_reader = NULL;
|
reader_table[reader].dump_status_reader = NULL;
|
||||||
|
|
||||||
reader_table[reader].used = 1;
|
reader_table[reader].used = 1;
|
||||||
@ -372,6 +382,7 @@ host_sw_string (long err)
|
|||||||
case SW_HOST_GENERAL_ERROR: return "general error";
|
case SW_HOST_GENERAL_ERROR: return "general error";
|
||||||
case SW_HOST_NO_READER: return "no reader";
|
case SW_HOST_NO_READER: return "no reader";
|
||||||
case SW_HOST_ABORTED: return "aborted";
|
case SW_HOST_ABORTED: return "aborted";
|
||||||
|
case SW_HOST_NO_KEYPAD: return "no keypad";
|
||||||
default: return "unknown host status error";
|
default: return "unknown host status error";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -533,7 +544,7 @@ ct_get_status (int slot, unsigned int *status)
|
|||||||
set to BUFLEN. Returns: CT API error code. */
|
set to BUFLEN. Returns: CT API error code. */
|
||||||
static int
|
static int
|
||||||
ct_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
|
ct_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
|
||||||
unsigned char *buffer, size_t *buflen)
|
unsigned char *buffer, size_t *buflen, struct pininfo_s *pininfo)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
unsigned char dad[1], sad[1];
|
unsigned char dad[1], sad[1];
|
||||||
@ -596,6 +607,7 @@ open_ct_reader (int port)
|
|||||||
reader_table[reader].reset_reader = reset_ct_reader;
|
reader_table[reader].reset_reader = reset_ct_reader;
|
||||||
reader_table[reader].get_status_reader = ct_get_status;
|
reader_table[reader].get_status_reader = ct_get_status;
|
||||||
reader_table[reader].send_apdu_reader = ct_send_apdu;
|
reader_table[reader].send_apdu_reader = ct_send_apdu;
|
||||||
|
reader_table[reader].check_keypad = NULL;
|
||||||
reader_table[reader].dump_status_reader = ct_dump_reader_status;
|
reader_table[reader].dump_status_reader = ct_dump_reader_status;
|
||||||
|
|
||||||
dump_reader_status (reader);
|
dump_reader_status (reader);
|
||||||
@ -1082,7 +1094,8 @@ pcsc_get_status (int slot, unsigned int *status)
|
|||||||
set to BUFLEN. Returns: CT API error code. */
|
set to BUFLEN. Returns: CT API error code. */
|
||||||
static int
|
static int
|
||||||
pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
|
pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
|
||||||
unsigned char *buffer, size_t *buflen)
|
unsigned char *buffer, size_t *buflen,
|
||||||
|
struct pininfo_s *pininfo)
|
||||||
{
|
{
|
||||||
#ifdef NEED_PCSC_WRAPPER
|
#ifdef NEED_PCSC_WRAPPER
|
||||||
long err;
|
long err;
|
||||||
@ -1479,6 +1492,7 @@ open_pcsc_reader (const char *portstr)
|
|||||||
reader_table[slot].reset_reader = reset_pcsc_reader;
|
reader_table[slot].reset_reader = reset_pcsc_reader;
|
||||||
reader_table[slot].get_status_reader = pcsc_get_status;
|
reader_table[slot].get_status_reader = pcsc_get_status;
|
||||||
reader_table[slot].send_apdu_reader = pcsc_send_apdu;
|
reader_table[slot].send_apdu_reader = pcsc_send_apdu;
|
||||||
|
reader_table[slot].check_keypad = NULL;
|
||||||
reader_table[slot].dump_status_reader = dump_pcsc_reader_status;
|
reader_table[slot].dump_status_reader = dump_pcsc_reader_status;
|
||||||
|
|
||||||
/* Read the status so that IS_T0 will be set. */
|
/* Read the status so that IS_T0 will be set. */
|
||||||
@ -1625,6 +1639,7 @@ open_pcsc_reader (const char *portstr)
|
|||||||
reader_table[slot].reset_reader = reset_pcsc_reader;
|
reader_table[slot].reset_reader = reset_pcsc_reader;
|
||||||
reader_table[slot].get_status_reader = pcsc_get_status;
|
reader_table[slot].get_status_reader = pcsc_get_status;
|
||||||
reader_table[slot].send_apdu_reader = pcsc_send_apdu;
|
reader_table[slot].send_apdu_reader = pcsc_send_apdu;
|
||||||
|
reader_table[slot].check_keypad = NULL;
|
||||||
reader_table[slot].dump_status_reader = dump_pcsc_reader_status;
|
reader_table[slot].dump_status_reader = dump_pcsc_reader_status;
|
||||||
|
|
||||||
/* log_debug ("state from pcsc_status: 0x%lx\n", card_state); */
|
/* log_debug ("state from pcsc_status: 0x%lx\n", card_state); */
|
||||||
@ -1713,7 +1728,8 @@ get_status_ccid (int slot, unsigned int *status)
|
|||||||
set to BUFLEN. Returns: Internal CCID driver error code. */
|
set to BUFLEN. Returns: Internal CCID driver error code. */
|
||||||
static int
|
static int
|
||||||
send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen,
|
send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen,
|
||||||
unsigned char *buffer, size_t *buflen)
|
unsigned char *buffer, size_t *buflen,
|
||||||
|
struct pininfo_s *pininfo)
|
||||||
{
|
{
|
||||||
long err;
|
long err;
|
||||||
size_t maxbuflen;
|
size_t maxbuflen;
|
||||||
@ -1727,6 +1743,15 @@ send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen,
|
|||||||
log_printhex (" APDU_data:", apdu, apdulen);
|
log_printhex (" APDU_data:", apdu, apdulen);
|
||||||
|
|
||||||
maxbuflen = *buflen;
|
maxbuflen = *buflen;
|
||||||
|
if (pininfo)
|
||||||
|
err = ccid_transceive_secure (reader_table[slot].ccid.handle,
|
||||||
|
apdu, apdulen,
|
||||||
|
pininfo->mode,
|
||||||
|
pininfo->minlen,
|
||||||
|
pininfo->maxlen,
|
||||||
|
pininfo->padlen,
|
||||||
|
buffer, maxbuflen, buflen);
|
||||||
|
else
|
||||||
err = ccid_transceive (reader_table[slot].ccid.handle,
|
err = ccid_transceive (reader_table[slot].ccid.handle,
|
||||||
apdu, apdulen,
|
apdu, apdulen,
|
||||||
buffer, maxbuflen, buflen);
|
buffer, maxbuflen, buflen);
|
||||||
@ -1737,6 +1762,24 @@ send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Check whether the CCID reader supports the ISO command code COMMAND
|
||||||
|
on the keypad. Return 0 on success. For a description of the pin
|
||||||
|
parameters, see ccid-driver.c */
|
||||||
|
static int
|
||||||
|
check_ccid_keypad (int slot, int command, int pin_mode,
|
||||||
|
int pinlen_min, int pinlen_max, int pin_padlen)
|
||||||
|
{
|
||||||
|
unsigned char apdu[] = { 0, 0, 0, 0x81 };
|
||||||
|
|
||||||
|
apdu[1] = command;
|
||||||
|
return ccid_transceive_secure (reader_table[slot].ccid.handle,
|
||||||
|
apdu, sizeof apdu,
|
||||||
|
pin_mode, pinlen_min, pinlen_max, pin_padlen,
|
||||||
|
NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Open the reader and try to read an ATR. */
|
/* Open the reader and try to read an ATR. */
|
||||||
static int
|
static int
|
||||||
open_ccid_reader (const char *portstr)
|
open_ccid_reader (const char *portstr)
|
||||||
@ -1776,6 +1819,7 @@ open_ccid_reader (const char *portstr)
|
|||||||
reader_table[slot].reset_reader = reset_ccid_reader;
|
reader_table[slot].reset_reader = reset_ccid_reader;
|
||||||
reader_table[slot].get_status_reader = get_status_ccid;
|
reader_table[slot].get_status_reader = get_status_ccid;
|
||||||
reader_table[slot].send_apdu_reader = send_apdu_ccid;
|
reader_table[slot].send_apdu_reader = send_apdu_ccid;
|
||||||
|
reader_table[slot].check_keypad = check_ccid_keypad;
|
||||||
reader_table[slot].dump_status_reader = dump_ccid_reader_status;
|
reader_table[slot].dump_status_reader = dump_ccid_reader_status;
|
||||||
|
|
||||||
dump_reader_status (slot);
|
dump_reader_status (slot);
|
||||||
@ -1932,7 +1976,8 @@ my_rapdu_get_status (int slot, unsigned int *status)
|
|||||||
set to BUFLEN. Returns: APDU error code. */
|
set to BUFLEN. Returns: APDU error code. */
|
||||||
static int
|
static int
|
||||||
my_rapdu_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
|
my_rapdu_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
|
||||||
unsigned char *buffer, size_t *buflen)
|
unsigned char *buffer, size_t *buflen,
|
||||||
|
struct pininfo_s *pininfo)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
reader_table_t slotp;
|
reader_table_t slotp;
|
||||||
@ -2063,6 +2108,7 @@ open_rapdu_reader (int portno,
|
|||||||
reader_table[slot].reset_reader = reset_rapdu_reader;
|
reader_table[slot].reset_reader = reset_rapdu_reader;
|
||||||
reader_table[slot].get_status_reader = my_rapdu_get_status;
|
reader_table[slot].get_status_reader = my_rapdu_get_status;
|
||||||
reader_table[slot].send_apdu_reader = my_rapdu_send_apdu;
|
reader_table[slot].send_apdu_reader = my_rapdu_send_apdu;
|
||||||
|
reader_table[slot].check_keypad = NULL;
|
||||||
reader_table[slot].dump_status_reader = NULL;
|
reader_table[slot].dump_status_reader = NULL;
|
||||||
|
|
||||||
dump_reader_status (slot);
|
dump_reader_status (slot);
|
||||||
@ -2198,28 +2244,28 @@ apdu_open_reader (const char *portstr)
|
|||||||
pcsc_establish_context = dlsym (handle, "SCardEstablishContext");
|
pcsc_establish_context = dlsym (handle, "SCardEstablishContext");
|
||||||
pcsc_release_context = dlsym (handle, "SCardReleaseContext");
|
pcsc_release_context = dlsym (handle, "SCardReleaseContext");
|
||||||
pcsc_list_readers = dlsym (handle, "SCardListReaders");
|
pcsc_list_readers = dlsym (handle, "SCardListReaders");
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
if (!pcsc_list_readers)
|
if (!pcsc_list_readers)
|
||||||
pcsc_list_readers = dlsym (handle, "SCardListReadersA");
|
pcsc_list_readers = dlsym (handle, "SCardListReadersA");
|
||||||
#endif
|
#endif
|
||||||
pcsc_get_status_change = dlsym (handle, "SCardGetStatusChange");
|
pcsc_get_status_change = dlsym (handle, "SCardGetStatusChange");
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
if (!pcsc_get_status_change)
|
if (!pcsc_get_status_change)
|
||||||
pcsc_get_status_change = dlsym (handle, "SCardGetStatusChangeA");
|
pcsc_get_status_change = dlsym (handle, "SCardGetStatusChangeA");
|
||||||
#endif
|
#endif
|
||||||
pcsc_connect = dlsym (handle, "SCardConnect");
|
pcsc_connect = dlsym (handle, "SCardConnect");
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
if (!pcsc_connect)
|
if (!pcsc_connect)
|
||||||
pcsc_connect = dlsym (handle, "SCardConnectA");
|
pcsc_connect = dlsym (handle, "SCardConnectA");
|
||||||
#endif
|
#endif
|
||||||
pcsc_reconnect = dlsym (handle, "SCardReconnect");
|
pcsc_reconnect = dlsym (handle, "SCardReconnect");
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
if (!pcsc_reconnect)
|
if (!pcsc_reconnect)
|
||||||
pcsc_reconnect = dlsym (handle, "SCardReconnectA");
|
pcsc_reconnect = dlsym (handle, "SCardReconnectA");
|
||||||
#endif
|
#endif
|
||||||
pcsc_disconnect = dlsym (handle, "SCardDisconnect");
|
pcsc_disconnect = dlsym (handle, "SCardDisconnect");
|
||||||
pcsc_status = dlsym (handle, "SCardStatus");
|
pcsc_status = dlsym (handle, "SCardStatus");
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
if (!pcsc_status)
|
if (!pcsc_status)
|
||||||
pcsc_status = dlsym (handle, "SCardStatusA");
|
pcsc_status = dlsym (handle, "SCardStatusA");
|
||||||
#endif
|
#endif
|
||||||
@ -2492,11 +2538,30 @@ apdu_get_status (int slot, int hang,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Check whether the reader supports the ISO command code COMMAND on
|
||||||
|
the keypad. Return 0 on success. For a description of the pin
|
||||||
|
parameters, see ccid-driver.c */
|
||||||
|
int
|
||||||
|
apdu_check_keypad (int slot, int command, int pin_mode,
|
||||||
|
int pinlen_min, int pinlen_max, int pin_padlen)
|
||||||
|
{
|
||||||
|
if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
|
||||||
|
return SW_HOST_NO_DRIVER;
|
||||||
|
|
||||||
|
if (reader_table[slot].check_keypad)
|
||||||
|
return reader_table[slot].check_keypad (slot, command,
|
||||||
|
pin_mode, pinlen_min, pinlen_max,
|
||||||
|
pin_padlen);
|
||||||
|
else
|
||||||
|
return SW_HOST_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Dispatcher for the actual send_apdu function. Note, that this
|
/* Dispatcher for the actual send_apdu function. Note, that this
|
||||||
function should be called in locked state. */
|
function should be called in locked state. */
|
||||||
static int
|
static int
|
||||||
send_apdu (int slot, unsigned char *apdu, size_t apdulen,
|
send_apdu (int slot, unsigned char *apdu, size_t apdulen,
|
||||||
unsigned char *buffer, size_t *buflen)
|
unsigned char *buffer, size_t *buflen, struct pininfo_s *pininfo)
|
||||||
{
|
{
|
||||||
if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
|
if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
|
||||||
return SW_HOST_NO_DRIVER;
|
return SW_HOST_NO_DRIVER;
|
||||||
@ -2504,24 +2569,20 @@ send_apdu (int slot, unsigned char *apdu, size_t apdulen,
|
|||||||
if (reader_table[slot].send_apdu_reader)
|
if (reader_table[slot].send_apdu_reader)
|
||||||
return reader_table[slot].send_apdu_reader (slot,
|
return reader_table[slot].send_apdu_reader (slot,
|
||||||
apdu, apdulen,
|
apdu, apdulen,
|
||||||
buffer, buflen);
|
buffer, buflen, pininfo);
|
||||||
else
|
else
|
||||||
return SW_HOST_NOT_SUPPORTED;
|
return SW_HOST_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send an APDU to the card in SLOT. The APDU is created from all
|
|
||||||
given parameters: CLASS, INS, P0, P1, LC, DATA, LE. A value of -1
|
/* Core APDU trabceiver function. Parameters are described at
|
||||||
for LC won't sent this field and the data field; in this case DATA
|
apdu_send_le with the exception of PININFO which indicates keypad
|
||||||
must also be passed as NULL. The return value is the status word
|
related operations if not NULL. */
|
||||||
or -1 for an invalid SLOT or other non card related error. If
|
static int
|
||||||
RETBUF is not NULL, it will receive an allocated buffer with the
|
send_le (int slot, int class, int ins, int p0, int p1,
|
||||||
returned data. The length of that data will be put into
|
|
||||||
*RETBUFLEN. The caller is reponsible for releasing the buffer even
|
|
||||||
in case of errors. */
|
|
||||||
int
|
|
||||||
apdu_send_le(int slot, int class, int ins, int p0, int p1,
|
|
||||||
int lc, const char *data, int le,
|
int lc, const char *data, int le,
|
||||||
unsigned char **retbuf, size_t *retbuflen)
|
unsigned char **retbuf, size_t *retbuflen,
|
||||||
|
struct pininfo_s *pininfo)
|
||||||
{
|
{
|
||||||
#define RESULTLEN 256
|
#define RESULTLEN 256
|
||||||
unsigned char result[RESULTLEN+10]; /* 10 extra in case of bugs in
|
unsigned char result[RESULTLEN+10]; /* 10 extra in case of bugs in
|
||||||
@ -2570,7 +2631,7 @@ apdu_send_le(int slot, int class, int ins, int p0, int p1,
|
|||||||
/* As safeguard don't pass any garbage from the stack to the driver. */
|
/* As safeguard don't pass any garbage from the stack to the driver. */
|
||||||
memset (apdu+apdulen, 0, sizeof (apdu) - apdulen);
|
memset (apdu+apdulen, 0, sizeof (apdu) - apdulen);
|
||||||
resultlen = RESULTLEN;
|
resultlen = RESULTLEN;
|
||||||
rc = send_apdu (slot, apdu, apdulen, result, &resultlen);
|
rc = send_apdu (slot, apdu, apdulen, result, &resultlen, pininfo);
|
||||||
if (rc || resultlen < 2)
|
if (rc || resultlen < 2)
|
||||||
{
|
{
|
||||||
log_error ("apdu_send_simple(%d) failed: %s\n",
|
log_error ("apdu_send_simple(%d) failed: %s\n",
|
||||||
@ -2638,7 +2699,7 @@ apdu_send_le(int slot, int class, int ins, int p0, int p1,
|
|||||||
apdu[apdulen++] = len;
|
apdu[apdulen++] = len;
|
||||||
memset (apdu+apdulen, 0, sizeof (apdu) - apdulen);
|
memset (apdu+apdulen, 0, sizeof (apdu) - apdulen);
|
||||||
resultlen = RESULTLEN;
|
resultlen = RESULTLEN;
|
||||||
rc = send_apdu (slot, apdu, apdulen, result, &resultlen);
|
rc = send_apdu (slot, apdu, apdulen, result, &resultlen, NULL);
|
||||||
if (rc || resultlen < 2)
|
if (rc || resultlen < 2)
|
||||||
{
|
{
|
||||||
log_error ("apdu_send_simple(%d) for get response failed: %s\n",
|
log_error ("apdu_send_simple(%d) for get response failed: %s\n",
|
||||||
@ -2703,6 +2764,27 @@ apdu_send_le(int slot, int class, int ins, int p0, int p1,
|
|||||||
#undef RESULTLEN
|
#undef RESULTLEN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Send an APDU to the card in SLOT. The APDU is created from all
|
||||||
|
given parameters: CLASS, INS, P0, P1, LC, DATA, LE. A value of -1
|
||||||
|
for LC won't sent this field and the data field; in this case DATA
|
||||||
|
must also be passed as NULL. The return value is the status word
|
||||||
|
or -1 for an invalid SLOT or other non card related error. If
|
||||||
|
RETBUF is not NULL, it will receive an allocated buffer with the
|
||||||
|
returned data. The length of that data will be put into
|
||||||
|
*RETBUFLEN. The caller is reponsible for releasing the buffer even
|
||||||
|
in case of errors. */
|
||||||
|
int
|
||||||
|
apdu_send_le(int slot, int class, int ins, int p0, int p1,
|
||||||
|
int lc, const char *data, int le,
|
||||||
|
unsigned char **retbuf, size_t *retbuflen)
|
||||||
|
{
|
||||||
|
return send_le (slot, class, ins, p0, p1,
|
||||||
|
lc, data, le,
|
||||||
|
retbuf, retbuflen,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Send an APDU to the card in SLOT. The APDU is created from all
|
/* Send an APDU to the card in SLOT. The APDU is created from all
|
||||||
given parameters: CLASS, INS, P0, P1, LC, DATA. A value of -1 for
|
given parameters: CLASS, INS, P0, P1, LC, DATA. A value of -1 for
|
||||||
LC won't sent this field and the data field; in this case DATA must
|
LC won't sent this field and the data field; in this case DATA must
|
||||||
@ -2716,8 +2798,8 @@ int
|
|||||||
apdu_send (int slot, int class, int ins, int p0, int p1,
|
apdu_send (int slot, int class, int ins, int p0, int p1,
|
||||||
int lc, const char *data, unsigned char **retbuf, size_t *retbuflen)
|
int lc, const char *data, unsigned char **retbuf, size_t *retbuflen)
|
||||||
{
|
{
|
||||||
return apdu_send_le (slot, class, ins, p0, p1, lc, data, 256,
|
return send_le (slot, class, ins, p0, p1, lc, data, 256,
|
||||||
retbuf, retbuflen);
|
retbuf, retbuflen, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send an APDU to the card in SLOT. The APDU is created from all
|
/* Send an APDU to the card in SLOT. The APDU is created from all
|
||||||
@ -2730,7 +2812,25 @@ int
|
|||||||
apdu_send_simple (int slot, int class, int ins, int p0, int p1,
|
apdu_send_simple (int slot, int class, int ins, int p0, int p1,
|
||||||
int lc, const char *data)
|
int lc, const char *data)
|
||||||
{
|
{
|
||||||
return apdu_send_le (slot, class, ins, p0, p1, lc, data, -1, NULL, NULL);
|
return send_le (slot, class, ins, p0, p1, lc, data, -1, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Same as apdu_send_simple but uses the keypad of the reader. */
|
||||||
|
int
|
||||||
|
apdu_send_simple_kp (int slot, int class, int ins, int p0, int p1,
|
||||||
|
int lc, const char *data,
|
||||||
|
int pin_mode,
|
||||||
|
int pinlen_min, int pinlen_max, int pin_padlen)
|
||||||
|
{
|
||||||
|
struct pininfo_s pininfo;
|
||||||
|
|
||||||
|
pininfo.mode = pin_mode;
|
||||||
|
pininfo.minlen = pinlen_min;
|
||||||
|
pininfo.maxlen = pinlen_max;
|
||||||
|
pininfo.padlen = pin_padlen;
|
||||||
|
return send_le (slot, class, ins, p0, p1, lc, data, -1,
|
||||||
|
NULL, NULL, &pininfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2771,7 +2871,7 @@ apdu_send_direct (int slot, const unsigned char *apdudata, size_t apdudatalen,
|
|||||||
class = apdulen? *apdu : 0;
|
class = apdulen? *apdu : 0;
|
||||||
|
|
||||||
resultlen = RESULTLEN;
|
resultlen = RESULTLEN;
|
||||||
rc = send_apdu (slot, apdu, apdulen, result, &resultlen);
|
rc = send_apdu (slot, apdu, apdulen, result, &resultlen, NULL);
|
||||||
if (rc || resultlen < 2)
|
if (rc || resultlen < 2)
|
||||||
{
|
{
|
||||||
log_error ("apdu_send_direct(%d) failed: %s\n",
|
log_error ("apdu_send_direct(%d) failed: %s\n",
|
||||||
@ -2825,7 +2925,7 @@ apdu_send_direct (int slot, const unsigned char *apdudata, size_t apdudatalen,
|
|||||||
apdu[apdulen++] = len;
|
apdu[apdulen++] = len;
|
||||||
memset (apdu+apdulen, 0, sizeof (apdu) - apdulen);
|
memset (apdu+apdulen, 0, sizeof (apdu) - apdulen);
|
||||||
resultlen = RESULTLEN;
|
resultlen = RESULTLEN;
|
||||||
rc = send_apdu (slot, apdu, apdulen, result, &resultlen);
|
rc = send_apdu (slot, apdu, apdulen, result, &resultlen, NULL);
|
||||||
if (rc || resultlen < 2)
|
if (rc || resultlen < 2)
|
||||||
{
|
{
|
||||||
log_error ("apdu_send_direct(%d) for get response failed: %s\n",
|
log_error ("apdu_send_direct(%d) for get response failed: %s\n",
|
||||||
|
@ -63,7 +63,8 @@ enum {
|
|||||||
SW_HOST_CARD_IO_ERROR = 0x1000a,
|
SW_HOST_CARD_IO_ERROR = 0x1000a,
|
||||||
SW_HOST_GENERAL_ERROR = 0x1000b,
|
SW_HOST_GENERAL_ERROR = 0x1000b,
|
||||||
SW_HOST_NO_READER = 0x1000c,
|
SW_HOST_NO_READER = 0x1000c,
|
||||||
SW_HOST_ABORTED = 0x1000d
|
SW_HOST_ABORTED = 0x1000d,
|
||||||
|
SW_HOST_NO_KEYPAD = 0x1000e
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -96,8 +97,14 @@ int apdu_activate (int slot);
|
|||||||
int apdu_reset (int slot);
|
int apdu_reset (int slot);
|
||||||
int apdu_get_status (int slot, int hang,
|
int apdu_get_status (int slot, int hang,
|
||||||
unsigned int *status, unsigned int *changed);
|
unsigned int *status, unsigned int *changed);
|
||||||
|
int apdu_check_keypad (int slot, int command, int pin_mode,
|
||||||
|
int pinlen_min, int pinlen_max, int pin_padlen);
|
||||||
int apdu_send_simple (int slot, int class, int ins, int p0, int p1,
|
int apdu_send_simple (int slot, int class, int ins, int p0, int p1,
|
||||||
int lc, const char *data);
|
int lc, const char *data);
|
||||||
|
int apdu_send_simple_kp (int slot, int class, int ins, int p0, int p1,
|
||||||
|
int lc, const char *data,
|
||||||
|
int pin_mode,
|
||||||
|
int pinlen_min, int pinlen_max, int pin_padlen);
|
||||||
int apdu_send (int slot, int class, int ins, int p0, int p1,
|
int apdu_send (int slot, int class, int ins, int p0, int p1,
|
||||||
int lc, const char *data,
|
int lc, const char *data,
|
||||||
unsigned char **retbuf, size_t *retbuflen);
|
unsigned char **retbuf, size_t *retbuflen);
|
||||||
|
@ -1710,7 +1710,7 @@ main (int argc, char **argv )
|
|||||||
set_homedir ( default_homedir () );
|
set_homedir ( default_homedir () );
|
||||||
|
|
||||||
#ifdef ENABLE_CARD_SUPPORT
|
#ifdef ENABLE_CARD_SUPPORT
|
||||||
# ifdef _WIN32
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
opt.pcsc_driver = "winscard.dll";
|
opt.pcsc_driver = "winscard.dll";
|
||||||
#else
|
#else
|
||||||
opt.pcsc_driver = "libpcsclite.so";
|
opt.pcsc_driver = "libpcsclite.so";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user