- renamed Special PIN Verification/Capabilities to PACE Verification/Capabilities
- fixed PIN PACE support in ccid descriptor - using uint16_t instead of WORD in PACE structures - fixed lengthInputData to host byteorder - fixed parsing input buffer of SCardControl with FEATURE_EXECUTE_PACE - parsing input buffer for PACE verification and adjusting the byteorder - added 30s timeout to for PACE verification - triggering PACE via PC/SC now works although quite unstable git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@155 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
@@ -18,7 +18,7 @@ Index: Drivers/ccid/src/ifdhandler.c
|
||||
iBytesReturned += sizeof(PCSC_TLV_STRUCTURE);
|
||||
}
|
||||
|
||||
+ if (ccid_descriptor -> bPINSupport & CCID_CLASS_PIN_SPECIAL_CAPABILITIES)
|
||||
+ if (ccid_descriptor -> bPINSupport & CCID_CLASS_PIN_PACE_CAPABILITIES)
|
||||
+ {
|
||||
+ pcsc_tlv -> tag = FEATURE_EXECUTE_PACE;
|
||||
+ pcsc_tlv -> length = 0x04; /* always 0x04 */
|
||||
@@ -31,34 +31,43 @@ Index: Drivers/ccid/src/ifdhandler.c
|
||||
/* We can always forward wLcdLayout */
|
||||
pcsc_tlv -> tag = FEATURE_IFD_PIN_PROPERTIES;
|
||||
pcsc_tlv -> length = 0x04; /* always 0x04 */
|
||||
@@ -1548,6 +1558,34 @@
|
||||
@@ -1548,6 +1558,43 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ if (IOCTL_FEATURE_EXECUTE_PACE == dwControlCode)
|
||||
+ {
|
||||
+ if (TxLength < 3 || !TxBuffer) {
|
||||
+ DEBUG_INFO("PACE Command refused by driver");
|
||||
+ DEBUG_CRITICAL("Buffer too small, could not determine length of "
|
||||
+ "input data");
|
||||
+ return_value = IFD_COMMUNICATION_ERROR;
|
||||
+ } else {
|
||||
+ unsigned int iBytesReturned;
|
||||
+ uint16_t lengthInputData;
|
||||
+ lengthInputData = *((uint16_t *) (TxBuffer + 1));
|
||||
+
|
||||
+ iBytesReturned = RxLength;
|
||||
+ lengthInputData = (uint16_t *) TxBuffer + 1;
|
||||
+ if (*TxBuffer == 1) {
|
||||
+ return_value = SecurePINSpecialCapabilities(reader_index,
|
||||
+ TxBuffer + 3, lengthInputData,
|
||||
+ RxBuffer, &iBytesReturned);
|
||||
+ *pdwBytesReturned = iBytesReturned;
|
||||
+ } else if (*TxBuffer == 2) {
|
||||
+ return_value = SecurePINSpecialVerify(reader_index,
|
||||
+ TxBuffer + 3, lengthInputData,
|
||||
+ RxBuffer, &iBytesReturned);
|
||||
+ *pdwBytesReturned = iBytesReturned;
|
||||
+ } else {
|
||||
+ DEBUG_INFO("PACE Command refused by driver");
|
||||
+ 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;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
@@ -74,45 +83,93 @@ Index: Drivers/ccid/src/commands.c
|
||||
unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length,
|
||||
unsigned char rx_buffer[]);
|
||||
|
||||
+static RESPONSECODE SecurePINSpecial(unsigned int reader_index,
|
||||
+ const unsigned char TxBuffer[], unsigned int TxLength,
|
||||
+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(int value, unsigned char *buffer);
|
||||
+static void i2w(uint16_t value, unsigned char *buffer);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
@@ -712,7 +718,96 @@
|
||||
@@ -712,7 +718,144 @@
|
||||
return ret;
|
||||
} /* SecurePINModify */
|
||||
|
||||
+RESPONSECODE SecurePINSpecialVerify(unsigned int reader_index,
|
||||
+ const unsigned char TxBuffer[], unsigned int TxLength,
|
||||
+RESPONSECODE SecurePINPACEVerify(unsigned int reader_index,
|
||||
+ unsigned char TxBuffer[], unsigned int TxLength,
|
||||
+ unsigned char RxBuffer[], unsigned int *RxLength)
|
||||
+{
|
||||
+ /* bPINOperation: PIN Special Capabilities */
|
||||
+ return SecurePINSpecial(reader_index, TxBuffer, TxLength, RxBuffer,
|
||||
+ RxLength, 0x11);
|
||||
+}
|
||||
+ RESPONSECODE return_value;
|
||||
+ unsigned char lengthCHAT, lengthPIN;
|
||||
+ uint16_t lengthCertificateDescription;
|
||||
+ int old_read_timeout;
|
||||
+ _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
|
||||
|
||||
+RESPONSECODE SecurePINSpecialCapabilities(unsigned int reader_index,
|
||||
+ const unsigned char TxBuffer[], unsigned int TxLength,
|
||||
+ unsigned char RxBuffer[], unsigned int *RxLength)
|
||||
+{
|
||||
+ /* bPINOperation: PIN Special Capabilities */
|
||||
+ return SecurePINSpecial(reader_index, TxBuffer, TxLength, RxBuffer,
|
||||
+ RxLength, 0x10);
|
||||
+ 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 != 4+lengthCHAT+lengthPIN+lengthCertificateDescription) {
|
||||
+ DEBUG_CRITICAL3("Buffer too small or too big to contain only "
|
||||
+ "CHAT, PIN and certificate description (expected %u, got %u)",
|
||||
+ 4+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_CAPABILITIES);
|
||||
+
|
||||
+err:
|
||||
+ ccid_descriptor -> readTimeout = old_read_timeout;
|
||||
+ return return_value;
|
||||
+}
|
||||
+
|
||||
+static RESPONSECODE SecurePINSpecial(unsigned int reader_index,
|
||||
+ const unsigned char TxBuffer[], unsigned int TxLength,
|
||||
+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_EXECUTE);
|
||||
+}
|
||||
+
|
||||
+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];
|
||||
+ int length;
|
||||
+ unsigned int length;
|
||||
+ _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
|
||||
+ status_t res;
|
||||
+
|
||||
@@ -181,16 +238,7 @@ Index: Drivers/ccid/src/commands.c
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Escape
|
||||
@@ -729,7 +824,7 @@
|
||||
int old_read_timeout;
|
||||
_ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
|
||||
|
||||
- old_read_timeout = ccid_descriptor -> readTimeout;
|
||||
+ old_read_timeout= ccid_descriptor -> readTimeout;
|
||||
ccid_descriptor -> readTimeout = 30*1000; /* 30 seconds */
|
||||
|
||||
again:
|
||||
@@ -2113,3 +2208,15 @@
|
||||
@@ -2113,3 +2256,15 @@
|
||||
buffer[3] = (value >> 24) & 0xFF;
|
||||
} /* i2dw */
|
||||
|
||||
@@ -200,7 +248,7 @@ Index: Drivers/ccid/src/commands.c
|
||||
+ * i2w
|
||||
+ *
|
||||
+ ****************************************************************************/
|
||||
+static void i2w(int value, unsigned char buffer[])
|
||||
+static void i2w(uint16_t value, unsigned char buffer[])
|
||||
+{
|
||||
+ buffer[0] = value & 0xFF;
|
||||
+ buffer[1] = (value >> 8) & 0xFF;
|
||||
@@ -214,12 +262,12 @@ Index: Drivers/ccid/src/commands.h
|
||||
unsigned char TxBuffer[], unsigned int TxLength,
|
||||
unsigned char RxBuffer[], unsigned int *RxLength);
|
||||
|
||||
+RESPONSECODE SecurePINSpecialCapabilities(unsigned int reader_index,
|
||||
+ const unsigned char TxBuffer[], unsigned int TxLength,
|
||||
+RESPONSECODE SecurePINPACECapabilities(unsigned int reader_index,
|
||||
+ unsigned char TxBuffer[], unsigned int TxLength,
|
||||
+ unsigned char RxBuffer[], unsigned int *RxLength);
|
||||
+
|
||||
+RESPONSECODE SecurePINSpecialVerify(unsigned int reader_index,
|
||||
+ const unsigned char TxBuffer[], unsigned int TxLength,
|
||||
+RESPONSECODE SecurePINPACEVerify(unsigned int reader_index,
|
||||
+ unsigned char TxBuffer[], unsigned int TxLength,
|
||||
+ unsigned char RxBuffer[], unsigned int *RxLength);
|
||||
+
|
||||
RESPONSECODE CmdEscape(unsigned int reader_index,
|
||||
@@ -237,8 +285,8 @@ Index: Drivers/ccid/src/ccid.h
|
||||
-#define CCID_CLASS_PIN_MODIFY 0x02
|
||||
+#define CCID_CLASS_PIN_VERIFY 0x01
|
||||
+#define CCID_CLASS_PIN_MODIFY 0x02
|
||||
+#define CCID_CLASS_PIN_SPECIAL_CAPABILITIES 0x10
|
||||
+#define CCID_CLASS_PIN_SPECIAL_EXECUTE 0x11
|
||||
+#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 */
|
||||
|
||||
Reference in New Issue
Block a user