added patches for distribution packages of ccid and pcsc-lite

git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@159 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
frankmorgner
2010-06-20 19:52:45 +00:00
parent 49efd686ee
commit 28bea2815c
3 changed files with 305 additions and 0 deletions

View File

@@ -0,0 +1,293 @@
Index: src/ifdhandler.c
===================================================================
--- src/ifdhandler.c (Revision 4347)
+++ src/ifdhandler.c (Arbeitskopie)
@@ -1266,6 +1266,16 @@
iBytesReturned += sizeof(PCSC_TLV_STRUCTURE);
}
+ if (get_ccid_descriptor(reader_index) -> bPINSupport & CCID_CLASS_PIN_PACE_CAPABILITIES)
+ {
+ pcsc_tlv -> tag = FEATURE_EXECUTE_PACE;
+ pcsc_tlv -> length = 0x04; /* always 0x04 */
+ pcsc_tlv -> value = htonl(IOCTL_FEATURE_EXECUTE_PACE);
+
+ pcsc_tlv++;
+ iBytesReturned += sizeof(PCSC_TLV_STRUCTURE);
+ }
+
#ifdef FEATURE_IFD_PIN_PROPERTIES
/* We can always forward wLcdLayout */
pcsc_tlv -> tag = FEATURE_IFD_PIN_PROPERTIES;
@@ -1365,6 +1375,43 @@
}
}
+ if (IOCTL_FEATURE_EXECUTE_PACE == dwControlCode)
+ {
+ if (TxLength < 3 || !TxBuffer) {
+ DEBUG_CRITICAL("Buffer too small, could not determine length of "
+ "input data");
+ return_value = IFD_COMMUNICATION_ERROR;
+ } else {
+ uint16_t lengthInputData;
+ lengthInputData = *((uint16_t *) (TxBuffer + 1));
+
+ if (TxLength != 3+lengthInputData) {
+ DEBUG_CRITICAL3("Buffer too small or too big to contain only "
+ "function index and input data (expected %u, got %u)",
+ 3+lengthInputData, TxLength);
+ return_value = IFD_COMMUNICATION_ERROR;
+ } else {
+ unsigned int iBytesReturned;
+ iBytesReturned = RxLength;
+
+ if (*TxBuffer == 1) {
+ return_value = SecurePINPACECapabilities(reader_index,
+ TxBuffer + 3, lengthInputData,
+ RxBuffer, &iBytesReturned);
+ *pdwBytesReturned = iBytesReturned;
+ } else if (*TxBuffer == 2) {
+ return_value = SecurePINPACEVerify(reader_index,
+ TxBuffer + 3, lengthInputData,
+ RxBuffer, &iBytesReturned);
+ *pdwBytesReturned = iBytesReturned;
+ } else {
+ DEBUG_CRITICAL2("Unknown PACE function %u", *TxBuffer);
+ return_value = IFD_COMMUNICATION_ERROR;
+ }
+ }
+ }
+ }
+
if (IFD_SUCCESS != return_value)
*pdwBytesReturned = 0;
Index: src/commands.c
===================================================================
--- src/commands.c (Revision 4347)
+++ src/commands.c (Arbeitskopie)
@@ -68,7 +68,13 @@
unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length,
unsigned char rx_buffer[]);
+static RESPONSECODE SecurePINPACE(unsigned int reader_index,
+ unsigned char TxBuffer[], unsigned int TxLength,
+ unsigned char RxBuffer[], unsigned int *RxLength,
+ unsigned char bPINOperation);
+
static void i2dw(int value, unsigned char *buffer);
+static void i2w(uint16_t value, unsigned char *buffer);
/*****************************************************************************
@@ -691,7 +697,144 @@
return ret;
} /* SecurePINModify */
+RESPONSECODE SecurePINPACEVerify(unsigned int reader_index,
+ unsigned char TxBuffer[], unsigned int TxLength,
+ unsigned char RxBuffer[], unsigned int *RxLength)
+{
+ RESPONSECODE return_value;
+ unsigned char lengthCHAT, lengthPIN;
+ uint16_t lengthCertificateDescription;
+ int old_read_timeout;
+ _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
+ old_read_timeout= ccid_descriptor -> readTimeout;
+ ccid_descriptor -> readTimeout = 30*1000; /* 30 seconds */
+
+ if (TxLength < 2) {
+ DEBUG_CRITICAL("Buffer too small, could not determine length of "
+ "CHAT");
+ return_value = IFD_COMMUNICATION_ERROR;
+ goto err;
+ }
+ lengthCHAT = *(TxBuffer + 1);
+
+ if (TxLength < 2+lengthCHAT) {
+ DEBUG_CRITICAL("Buffer too small, could not determine length of "
+ "PIN");
+ return_value = IFD_COMMUNICATION_ERROR;
+ goto err;
+ }
+ lengthPIN = *(TxBuffer + 1 + lengthCHAT);
+
+ if (TxLength < 3+lengthCHAT+lengthPIN) {
+ DEBUG_CRITICAL("Buffer too small, could not determine length of "
+ "certificate description");
+ return_value = IFD_COMMUNICATION_ERROR;
+ goto err;
+ }
+ lengthCertificateDescription = *((uint16_t *)
+ (TxBuffer + 1 + lengthCHAT + lengthPIN));
+
+ if (TxLength != 5+lengthCHAT+lengthPIN+lengthCertificateDescription) {
+ DEBUG_CRITICAL3("Buffer too small or too big to contain only "
+ "CHAT, PIN and certificate description (expected %u, got %u)",
+ 5+lengthCHAT+lengthPIN+lengthCertificateDescription, TxLength);
+ return_value = IFD_COMMUNICATION_ERROR;
+ goto err;
+ }
+
+ i2w(lengthCertificateDescription, TxBuffer + 1 + lengthCHAT + lengthPIN);
+
+ /* bPINOperation: PIN PACE Capabilities */
+ return_value = SecurePINPACE(reader_index, TxBuffer, TxLength, RxBuffer,
+ RxLength, CCID_CLASS_PIN_PACE_EXECUTE);
+
+err:
+ ccid_descriptor -> readTimeout = old_read_timeout;
+ return return_value;
+}
+
+RESPONSECODE SecurePINPACECapabilities(unsigned int reader_index,
+ unsigned char TxBuffer[], unsigned int TxLength,
+ unsigned char RxBuffer[], unsigned int *RxLength)
+{
+ /* bPINOperation: PIN PACE Capabilities */
+ return SecurePINPACE(reader_index, TxBuffer, TxLength, RxBuffer,
+ RxLength, CCID_CLASS_PIN_PACE_CAPABILITIES);
+}
+
+static RESPONSECODE SecurePINPACE(unsigned int reader_index,
+ unsigned char TxBuffer[], unsigned int TxLength,
+ unsigned char RxBuffer[], unsigned int *RxLength,
+ unsigned char bPINOperation)
+{
+ unsigned char cmd[11+CMD_BUF_SIZE];
+ unsigned int length;
+ _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
+ status_t res;
+
+ cmd[0] = 0x69; /* Secure */
+ i2dw(TxLength, cmd+1); /* dwLength */
+ cmd[5] = ccid_descriptor->bCurrentSlotIndex; /* slot number */
+ cmd[6] = (*ccid_descriptor->pbSeq)++;
+ cmd[7] = 0; /* bBWI */
+ cmd[8] = 0; /* wLevelParameter */
+ cmd[9] = 0;
+ cmd[10] = bPINOperation;
+
+ memcpy(cmd + 11, TxBuffer, TxLength);
+
+ res = WritePort(reader_index, 11 + TxLength, cmd);
+ if (res != STATUS_SUCCESS)
+ {
+ if (STATUS_NO_SUCH_DEVICE == res)
+ return IFD_NO_SUCH_DEVICE;
+ return IFD_COMMUNICATION_ERROR;
+ }
+
+ length = sizeof(cmd);
+ res = ReadPort(reader_index, &length, cmd);
+ if (res != STATUS_SUCCESS)
+ {
+ if (STATUS_NO_SUCH_DEVICE == res)
+ return IFD_NO_SUCH_DEVICE;
+ return IFD_COMMUNICATION_ERROR;
+ }
+
+ if (length < STATUS_OFFSET+1)
+ {
+ DEBUG_CRITICAL2("Not enough data received: %d bytes", length);
+ return IFD_COMMUNICATION_ERROR;
+ }
+
+ if (cmd[STATUS_OFFSET] & CCID_COMMAND_FAILED)
+ {
+ ccid_error(cmd[ERROR_OFFSET], __FILE__, __LINE__, __FUNCTION__); /* bError */
+ return IFD_COMMUNICATION_ERROR;
+ }
+
+ /* we have read less (or more) data than the CCID frame says to contain */
+ if (length-10 != dw2i(cmd, 1))
+ {
+ DEBUG_CRITICAL3("Can't read all data (%d out of %d expected)",
+ length-10, dw2i(cmd, 1));
+ return IFD_COMMUNICATION_ERROR;
+ }
+
+ length = dw2i(cmd, 1);
+ if (length <= *RxLength)
+ *RxLength = length;
+ else
+ {
+ DEBUG_CRITICAL2("overrun by %d bytes", length - *RxLength);
+ length = *RxLength;
+ return IFD_ERROR_INSUFFICIENT_BUFFER;
+ }
+
+ return IFD_SUCCESS;
+}
+
+
/*****************************************************************************
*
* Escape
@@ -2081,3 +2224,15 @@
buffer[3] = (value >> 24) & 0xFF;
} /* i2dw */
+
+/*****************************************************************************
+ *
+ * i2w
+ *
+ ****************************************************************************/
+static void i2w(uint16_t value, unsigned char buffer[])
+{
+ buffer[0] = value & 0xFF;
+ buffer[1] = (value >> 8) & 0xFF;
+} /* i2w */
+
Index: src/commands.h
===================================================================
--- src/commands.h (Revision 4347)
+++ src/commands.h (Arbeitskopie)
@@ -37,6 +37,14 @@
unsigned char TxBuffer[], unsigned int TxLength,
unsigned char RxBuffer[], unsigned int *RxLength);
+RESPONSECODE SecurePINPACECapabilities(unsigned int reader_index,
+ unsigned char TxBuffer[], unsigned int TxLength,
+ unsigned char RxBuffer[], unsigned int *RxLength);
+
+RESPONSECODE SecurePINPACEVerify(unsigned int reader_index,
+ unsigned char TxBuffer[], unsigned int TxLength,
+ unsigned char RxBuffer[], unsigned int *RxLength);
+
RESPONSECODE CmdEscape(unsigned int reader_index,
const unsigned char TxBuffer[], unsigned int TxLength,
unsigned char RxBuffer[], unsigned int *RxLength);
Index: src/ccid.h
===================================================================
--- src/ccid.h (Revision 4347)
+++ src/ccid.h (Arbeitskopie)
@@ -137,8 +137,10 @@
#define CCID_CLASS_EXCHANGE_MASK 0x00070000
/* Features from bPINSupport */
-#define CCID_CLASS_PIN_VERIFY 0x01
-#define CCID_CLASS_PIN_MODIFY 0x02
+#define CCID_CLASS_PIN_VERIFY 0x01
+#define CCID_CLASS_PIN_MODIFY 0x02
+#define CCID_CLASS_PIN_PACE_CAPABILITIES 0x10
+#define CCID_CLASS_PIN_PACE_EXECUTE 0x20
/* See CCID specs ch. 4.2.1 */
#define CCID_ICC_PRESENT_ACTIVE 0x00 /* 00 0000 00 */
Index: src/ccid_ifdhandler.h
===================================================================
--- src/ccid_ifdhandler.h (Revision 4347)
+++ src/ccid_ifdhandler.h (Arbeitskopie)
@@ -38,6 +38,8 @@
#define IOCTL_FEATURE_IFD_PIN_PROPERTIES \
SCARD_CTL_CODE(FEATURE_IFD_PIN_PROPERTIES + CLASS2_IOCTL_MAGIC)
#endif
+#define IOCTL_FEATURE_EXECUTE_PACE \
+ SCARD_CTL_CODE(FEATURE_EXECUTE_PACE + CLASS2_IOCTL_MAGIC)
#define DRIVER_OPTION_CCID_EXCHANGE_AUTHORIZED 1
#define DRIVER_OPTION_GEMPC_TWIN_KEY_APDU 2

View File

@@ -0,0 +1,12 @@
Index: src/PCSC/reader.h.in
===================================================================
--- src/PCSC/reader.h.in (Revision 4345)
+++ src/PCSC/reader.h.in (Arbeitskopie)
@@ -118,6 +118,7 @@
#define FEATURE_WRITE_DISPLAY 0x0F
#define FEATURE_GET_KEY 0x10
#define FEATURE_IFD_DISPLAY_PROPERTIES 0x11
+#define FEATURE_EXECUTE_PACE 0x20
/* structures used (but not defined) in PC/SC Part 10 revision 2.02.05:
* "IFDs with Secure Pin Entry Capabilities" */