[svn] GnuPG - r3916 - trunk/g10
svn author wk
cvs at cvs.gnupg.org
Thu Oct 27 11:14:29 CEST 2005
Author: wk
Date: 2005-10-27 11:14:27 +0200 (Thu, 27 Oct 2005)
New Revision: 3916
Modified:
trunk/g10/ChangeLog
trunk/g10/apdu.c
trunk/g10/apdu.h
trunk/g10/gpg.c
Log:
cygwin fixes
Modified: trunk/g10/ChangeLog
===================================================================
--- trunk/g10/ChangeLog 2005-10-26 16:09:23 UTC (rev 3915)
+++ trunk/g10/ChangeLog 2005-10-27 09:14:27 UTC (rev 3916)
@@ -1,3 +1,26 @@
+2005-10-27 Werner Koch <wk at 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 at jabberwocky.com>
* keygen.c (proc_parameter_file): Default key and subkey usage
Modified: trunk/g10/apdu.c
===================================================================
--- trunk/g10/apdu.c 2005-10-26 16:09:23 UTC (rev 3915)
+++ trunk/g10/apdu.c 2005-10-27 09:14:27 UTC (rev 3916)
@@ -66,10 +66,10 @@
#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. */
#ifdef USE_GNU_PTH
-#ifndef HAVE_W32_SYSTEM
+#if !defined(HAVE_W32_SYSTEM) && !defined(__CYGWIN__)
#define NEED_PCSC_WRAPPER 1
#endif
#endif
@@ -78,7 +78,7 @@
#define MAX_READER 4 /* Number of readers we support concurrently. */
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
#define DLSTDCALL __stdcall
#else
#define DLSTDCALL
@@ -90,6 +90,14 @@
#define MAX_OPEN_FDS 20
#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
slot. */
@@ -103,7 +111,8 @@
int (*reset_reader)(int);
int (*get_status_reader)(int, unsigned int *);
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);
struct {
@@ -320,6 +329,7 @@
reader_table[reader].reset_reader = NULL;
reader_table[reader].get_status_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].used = 1;
@@ -372,6 +382,7 @@
case SW_HOST_GENERAL_ERROR: return "general error";
case SW_HOST_NO_READER: return "no reader";
case SW_HOST_ABORTED: return "aborted";
+ case SW_HOST_NO_KEYPAD: return "no keypad";
default: return "unknown host status error";
}
}
@@ -533,7 +544,7 @@
set to BUFLEN. Returns: CT API error code. */
static int
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;
unsigned char dad[1], sad[1];
@@ -596,6 +607,7 @@
reader_table[reader].reset_reader = reset_ct_reader;
reader_table[reader].get_status_reader = ct_get_status;
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;
dump_reader_status (reader);
@@ -1082,7 +1094,8 @@
set to BUFLEN. Returns: CT API error code. */
static int
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
long err;
@@ -1479,6 +1492,7 @@
reader_table[slot].reset_reader = reset_pcsc_reader;
reader_table[slot].get_status_reader = pcsc_get_status;
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;
/* Read the status so that IS_T0 will be set. */
@@ -1625,6 +1639,7 @@
reader_table[slot].reset_reader = reset_pcsc_reader;
reader_table[slot].get_status_reader = pcsc_get_status;
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;
/* log_debug ("state from pcsc_status: 0x%lx\n", card_state); */
@@ -1713,7 +1728,8 @@
set to BUFLEN. Returns: Internal CCID driver error code. */
static int
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;
size_t maxbuflen;
@@ -1727,9 +1743,18 @@
log_printhex (" APDU_data:", apdu, apdulen);
maxbuflen = *buflen;
- err = ccid_transceive (reader_table[slot].ccid.handle,
- apdu, apdulen,
- buffer, 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,
+ apdu, apdulen,
+ buffer, maxbuflen, buflen);
if (err)
log_error ("ccid_transceive failed: (0x%lx)\n",
err);
@@ -1737,6 +1762,24 @@
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. */
static int
open_ccid_reader (const char *portstr)
@@ -1776,6 +1819,7 @@
reader_table[slot].reset_reader = reset_ccid_reader;
reader_table[slot].get_status_reader = get_status_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;
dump_reader_status (slot);
@@ -1932,7 +1976,8 @@
set to BUFLEN. Returns: APDU error code. */
static int
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;
reader_table_t slotp;
@@ -2063,6 +2108,7 @@
reader_table[slot].reset_reader = reset_rapdu_reader;
reader_table[slot].get_status_reader = my_rapdu_get_status;
reader_table[slot].send_apdu_reader = my_rapdu_send_apdu;
+ reader_table[slot].check_keypad = NULL;
reader_table[slot].dump_status_reader = NULL;
dump_reader_status (slot);
@@ -2198,28 +2244,28 @@
pcsc_establish_context = dlsym (handle, "SCardEstablishContext");
pcsc_release_context = dlsym (handle, "SCardReleaseContext");
pcsc_list_readers = dlsym (handle, "SCardListReaders");
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
if (!pcsc_list_readers)
pcsc_list_readers = dlsym (handle, "SCardListReadersA");
#endif
pcsc_get_status_change = dlsym (handle, "SCardGetStatusChange");
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
if (!pcsc_get_status_change)
pcsc_get_status_change = dlsym (handle, "SCardGetStatusChangeA");
#endif
pcsc_connect = dlsym (handle, "SCardConnect");
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
if (!pcsc_connect)
pcsc_connect = dlsym (handle, "SCardConnectA");
#endif
pcsc_reconnect = dlsym (handle, "SCardReconnect");
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
if (!pcsc_reconnect)
pcsc_reconnect = dlsym (handle, "SCardReconnectA");
#endif
pcsc_disconnect = dlsym (handle, "SCardDisconnect");
pcsc_status = dlsym (handle, "SCardStatus");
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
if (!pcsc_status)
pcsc_status = dlsym (handle, "SCardStatusA");
#endif
@@ -2492,11 +2538,30 @@
}
+/* 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
function should be called in locked state. */
static int
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 )
return SW_HOST_NO_DRIVER;
@@ -2504,24 +2569,20 @@
if (reader_table[slot].send_apdu_reader)
return reader_table[slot].send_apdu_reader (slot,
apdu, apdulen,
- buffer, buflen);
+ buffer, buflen, pininfo);
else
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
- 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)
+
+/* Core APDU trabceiver function. Parameters are described at
+ apdu_send_le with the exception of PININFO which indicates keypad
+ related operations if not NULL. */
+static int
+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,
+ struct pininfo_s *pininfo)
{
#define RESULTLEN 256
unsigned char result[RESULTLEN+10]; /* 10 extra in case of bugs in
@@ -2570,7 +2631,7 @@
/* As safeguard don't pass any garbage from the stack to the driver. */
memset (apdu+apdulen, 0, sizeof (apdu) - apdulen);
resultlen = RESULTLEN;
- rc = send_apdu (slot, apdu, apdulen, result, &resultlen);
+ rc = send_apdu (slot, apdu, apdulen, result, &resultlen, pininfo);
if (rc || resultlen < 2)
{
log_error ("apdu_send_simple(%d) failed: %s\n",
@@ -2638,7 +2699,7 @@
apdu[apdulen++] = len;
memset (apdu+apdulen, 0, sizeof (apdu) - apdulen);
resultlen = RESULTLEN;
- rc = send_apdu (slot, apdu, apdulen, result, &resultlen);
+ rc = send_apdu (slot, apdu, apdulen, result, &resultlen, NULL);
if (rc || resultlen < 2)
{
log_error ("apdu_send_simple(%d) for get response failed: %s\n",
@@ -2704,6 +2765,27 @@
}
/* 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
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
also be passed as NULL. The return value is the status word or -1
@@ -2716,8 +2798,8 @@
apdu_send (int slot, int class, int ins, int p0, int p1,
int lc, const char *data, unsigned char **retbuf, size_t *retbuflen)
{
- return apdu_send_le (slot, class, ins, p0, p1, lc, data, 256,
- retbuf, retbuflen);
+ return send_le (slot, class, ins, p0, p1, lc, data, 256,
+ retbuf, retbuflen, NULL);
}
/* Send an APDU to the card in SLOT. The APDU is created from all
@@ -2730,10 +2812,28 @@
apdu_send_simple (int slot, int class, int ins, int p0, int p1,
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);
+}
+
+
/* This is a more generic version of the apdu sending routine. It
takes an already formatted APDU in APDUDATA or length APDUDATALEN
and returns the with the APDU including the status word. With
@@ -2771,7 +2871,7 @@
class = apdulen? *apdu : 0;
resultlen = RESULTLEN;
- rc = send_apdu (slot, apdu, apdulen, result, &resultlen);
+ rc = send_apdu (slot, apdu, apdulen, result, &resultlen, NULL);
if (rc || resultlen < 2)
{
log_error ("apdu_send_direct(%d) failed: %s\n",
@@ -2825,7 +2925,7 @@
apdu[apdulen++] = len;
memset (apdu+apdulen, 0, sizeof (apdu) - apdulen);
resultlen = RESULTLEN;
- rc = send_apdu (slot, apdu, apdulen, result, &resultlen);
+ rc = send_apdu (slot, apdu, apdulen, result, &resultlen, NULL);
if (rc || resultlen < 2)
{
log_error ("apdu_send_direct(%d) for get response failed: %s\n",
Modified: trunk/g10/apdu.h
===================================================================
--- trunk/g10/apdu.h 2005-10-26 16:09:23 UTC (rev 3915)
+++ trunk/g10/apdu.h 2005-10-27 09:14:27 UTC (rev 3916)
@@ -63,7 +63,8 @@
SW_HOST_CARD_IO_ERROR = 0x1000a,
SW_HOST_GENERAL_ERROR = 0x1000b,
SW_HOST_NO_READER = 0x1000c,
- SW_HOST_ABORTED = 0x1000d
+ SW_HOST_ABORTED = 0x1000d,
+ SW_HOST_NO_KEYPAD = 0x1000e
};
@@ -96,8 +97,14 @@
int apdu_reset (int slot);
int apdu_get_status (int slot, int hang,
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 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 lc, const char *data,
unsigned char **retbuf, size_t *retbuflen);
Modified: trunk/g10/gpg.c
===================================================================
--- trunk/g10/gpg.c 2005-10-26 16:09:23 UTC (rev 3915)
+++ trunk/g10/gpg.c 2005-10-27 09:14:27 UTC (rev 3916)
@@ -1710,7 +1710,7 @@
set_homedir ( default_homedir () );
#ifdef ENABLE_CARD_SUPPORT
-# ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
opt.pcsc_driver = "winscard.dll";
#else
opt.pcsc_driver = "libpcsclite.so";
More information about the Gnupg-commits
mailing list