diff --git a/ccid/patches/Makefile.am b/ccid/patches/Makefile.am index 313e86f..26b6536 100644 --- a/ccid/patches/Makefile.am +++ b/ccid/patches/Makefile.am @@ -1,3 +1,2 @@ -EXTRA_DIST = ccid-1.3.11.patch ccid-1.3.13.patch \ - pcsc-lite-1.5.5.patch pcsc-lite-1.6.1.patch \ - pcsclite_trunk_r5067.patch +EXTRA_DIST = ccid-1.3.11.patch \ + pcsc-lite-1.5.5.patch pcsc-lite-1.6.1.patch diff --git a/ccid/patches/ccid-1.3.13.patch b/ccid/patches/ccid-1.3.13.patch deleted file mode 100644 index 2a3f599..0000000 --- a/ccid/patches/ccid-1.3.13.patch +++ /dev/null @@ -1,470 +0,0 @@ -Index: ccid-1.3.13/src/ifdhandler.c -=================================================================== ---- ccid-1.3.13/src/ifdhandler.c (Revision 4979) -+++ ccid-1.3.13/src/ifdhandler.c (Arbeitskopie) -@@ -1384,6 +1384,16 @@ - iBytesReturned += sizeof(PCSC_TLV_STRUCTURE); - } - -+ if (ccid_descriptor -> 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); -+ } -+ - /* We can always forward wLcdLayout */ - pcsc_tlv -> tag = FEATURE_IFD_PIN_PROPERTIES; - pcsc_tlv -> length = 0x04; /* always 0x04 */ -@@ -1548,6 +1558,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; -+ memcpy(&lengthInputData, &TxBuffer[1], 2); -+ -+ 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: ccid-1.3.13/src/commands.c -=================================================================== ---- ccid-1.3.13/src/commands.c (Revision 4979) -+++ ccid-1.3.13/src/commands.c (Arbeitskopie) -@@ -68,7 +68,19 @@ - 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 RESPONSECODE transform_EstablishPACEChannel_InputData( -+ unsigned char input[], unsigned int input_length); -+ -+static RESPONSECODE transform_EstablishPACEChannel_OutputData( -+ unsigned char output[], unsigned int output_length); -+ - static void i2dw(int value, unsigned char *buffer); -+static void i2w(uint16_t value, unsigned char *buffer); - - - /***************************************************************************** -@@ -712,7 +724,306 @@ - return ret; - } /* SecurePINModify */ - -+static RESPONSECODE transform_EstablishPACEChannel_InputData( -+ unsigned char input[], unsigned int input_length) -+{ -+ uint8_t lengthCHAT, lengthPIN; -+ uint16_t lengthCertificateDescription; -+ size_t parsed = 0; - -+ /* transform length fields of input data to little endian */ -+ -+ if (input_length < parsed+1) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ switch (input[parsed]) { -+ case 0x01: -+ DEBUG_COMM("Initiating PACE with MRZ"); -+ break; -+ case 0x02: -+ DEBUG_COMM("Initiating PACE with CAN"); -+ break; -+ case 0x03: -+ DEBUG_COMM("Initiating PACE with PIN"); -+ break; -+ case 0x04: -+ DEBUG_COMM("Initiating PACE with PUK"); -+ break; -+ default: -+ DEBUG_COMM("Initiating PACE with unknown PACE secret type"); -+ break; -+ } -+ parsed += 1; -+ -+ if (input_length < parsed+1) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ lengthCHAT = input[parsed]; -+ parsed += 1; -+ -+ if (input_length < parsed+lengthCHAT) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ if (lengthCHAT) -+ DEBUG_INFO_XXD("CHAT:\n", &input[parsed], lengthCHAT); -+ parsed += lengthCHAT; -+ -+ if (input_length < parsed+1) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ lengthPIN = input[parsed]; -+ parsed += 1; -+ -+ if (input_length < parsed+lengthPIN) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+#if 0 -+ /* dont print secrets... */ -+ if (lengthPIN) -+ DEBUG_INFO_XXD("PIN:\n", &input[parsed], lengthPIN); -+#endif -+ parsed += lengthPIN; -+ -+ if (input_length < parsed+2) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ memcpy(&lengthCertificateDescription, &input[parsed], 2); -+ i2w(lengthCertificateDescription, &input[parsed]); -+ parsed += 2; -+ -+ if (input_length < parsed+lengthCertificateDescription) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ if (lengthCertificateDescription) -+ DEBUG_INFO_XXD("Certificate description:\n", &input[parsed], lengthCertificateDescription); -+ parsed += lengthCertificateDescription; -+ -+ if (parsed < input_length) { -+ DEBUG_CRITICAL2("Overrun by %u bytes", input_length - parsed); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ -+ return IFD_SUCCESS; -+} -+ -+static RESPONSECODE transform_EstablishPACEChannel_OutputData( -+ unsigned char output[], unsigned int output_length) -+{ -+ uint8_t lengthCAR, lengthCARprev; -+ uint16_t lengthEF_CardAccess, length_IDicc; -+ size_t parsed = 0; -+ -+ if (parsed+2 > output_length) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ DEBUG_INFO3("MSE:Set AT Statusbytes: %02X %02X", -+ output[parsed+0], output[parsed+1]); -+ parsed += 2; -+ -+ if (parsed+2 > output_length) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ lengthEF_CardAccess = w2i(output, parsed); -+ memcpy(&output[parsed], &lengthEF_CardAccess, 2); -+ parsed += 2; -+ -+ if (parsed+lengthEF_CardAccess > output_length) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ if (lengthEF_CardAccess) -+ DEBUG_INFO_XXD("EF.CardAccess:\n", &output[parsed], lengthEF_CardAccess); -+ parsed += lengthEF_CardAccess; -+ -+ if (parsed+1 > output_length) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ lengthCAR = output[parsed]; -+ parsed += 1; -+ -+ if (parsed+lengthCAR > output_length) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ if (lengthCAR) -+ DEBUG_INFO_XXD("Recent Certificate Authority:\n", -+ &output[parsed], lengthCAR); -+ parsed += lengthCAR; -+ -+ if (parsed+1 > output_length) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ lengthCARprev = output[parsed]; -+ parsed += 1; -+ -+ if (parsed+lengthCARprev > output_length) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ if (lengthCARprev) -+ DEBUG_INFO_XXD("Previous Certificate Authority:\n", -+ &output[parsed], lengthCARprev); -+ parsed += lengthCARprev; -+ -+ if (parsed+2 > output_length) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ length_IDicc = w2i(output, parsed); -+ memcpy(&output[parsed], &length_IDicc, 2); -+ parsed += 2; -+ -+ if (parsed+length_IDicc > output_length) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ if (length_IDicc) -+ DEBUG_INFO_XXD("IDicc:\n", &output[parsed], length_IDicc); -+ parsed += length_IDicc; -+ -+ if (parsed < output_length) { -+ DEBUG_CRITICAL2("Overrun by %u bytes", output_length - parsed); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ -+ return IFD_SUCCESS; -+} -+ -+RESPONSECODE SecurePINPACEVerify(unsigned int reader_index, -+ unsigned char TxBuffer[], unsigned int TxLength, -+ unsigned char RxBuffer[], unsigned int *RxLength) -+{ -+ RESPONSECODE return_value; -+ 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 */ -+ -+ return_value = transform_EstablishPACEChannel_InputData(TxBuffer, TxLength); -+ if (IFD_SUCCESS != return_value) -+ goto err; -+ -+ /* bPINOperation: PIN PACE Capabilities */ -+ return_value = SecurePINPACE(reader_index, TxBuffer, TxLength, RxBuffer, -+ RxLength, CCID_CLASS_PIN_PACE_EXECUTE); -+ if (IFD_SUCCESS != return_value) -+ goto err; -+ -+ if (*RxLength < 6) { -+ DEBUG_CRITICAL("Malformed Establish PACE output buffer."); -+ return_value = IFD_COMMUNICATION_ERROR; -+ goto err; -+ } -+ -+ return_value = transform_EstablishPACEChannel_OutputData(RxBuffer+6, (*RxLength)-6); -+ if (IFD_SUCCESS != return_value) -+ goto err; -+ -+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[1024]; -+ 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) -+ { -+ DEBUG_CRITICAL(""); -+ if (STATUS_NO_SUCH_DEVICE == res) -+ return IFD_NO_SUCH_DEVICE; -+ DEBUG_CRITICAL(""); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ -+ length = sizeof(cmd); -+ res = ReadPort(reader_index, &length, cmd); -+ if (res != STATUS_SUCCESS) -+ { -+ DEBUG_CRITICAL(""); -+ if (STATUS_NO_SUCH_DEVICE == res) -+ return IFD_NO_SUCH_DEVICE; -+ DEBUG_CRITICAL(""); -+ 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 + 6 <= *RxLength) -+ *RxLength = length + 6; -+ else -+ { -+ DEBUG_CRITICAL2("overrun by %d bytes", length + 6 - *RxLength); -+ return IFD_ERROR_INSUFFICIENT_BUFFER; -+ } -+ uint32_t s = 0x00000000; /* "Kein Fehler" */ -+ memcpy(RxBuffer, &s, 4); -+ memcpy(RxBuffer+4, &length, 2); /* lengthOutputData */ -+ memcpy(RxBuffer+6, &cmd[10], length); -+ -+ return IFD_SUCCESS; -+} -+ -+ - /***************************************************************************** - * - * Escape -@@ -2113,3 +2424,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: ccid-1.3.13/src/commands.h -=================================================================== ---- ccid-1.3.13/src/commands.h (Revision 4979) -+++ ccid-1.3.13/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: ccid-1.3.13/src/ccid.h -=================================================================== ---- ccid-1.3.13/src/ccid.h (Revision 4979) -+++ ccid-1.3.13/src/ccid.h (Arbeitskopie) -@@ -142,8 +142,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 */ -@@ -227,6 +229,8 @@ - - /* convert a 4 byte integer in USB format into an int */ - #define dw2i(a, x) (unsigned int)((((((a[x+3] << 8) + a[x+2]) << 8) + a[x+1]) << 8) + a[x]) -+/* convert a 2 byte integer in USB format into an int */ -+#define w2i(a, x) (unsigned int)(((a[x+1]) << 8) + a[x]) - - /* all the data rates specified by ISO 7816-3 Fi/Di tables */ - #define ISO_DATA_RATES 10753, 14337, 15625, 17204, \ -Index: ccid-1.3.13/src/ccid_ifdhandler.h -=================================================================== ---- ccid-1.3.13/src/ccid_ifdhandler.h (Revision 4979) -+++ ccid-1.3.13/src/ccid_ifdhandler.h (Arbeitskopie) -@@ -37,6 +37,8 @@ - SCARD_CTL_CODE(FEATURE_IFD_PIN_PROPERTIES + CLASS2_IOCTL_MAGIC) - #define IOCTL_FEATURE_GET_TLV_PROPERTIES \ - SCARD_CTL_CODE(FEATURE_GET_TLV_PROPERTIES + CLASS2_IOCTL_MAGIC) -+#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 diff --git a/ccid/patches/pcsclite_trunk_r5270.patch b/ccid/patches/pcsclite_trunk_r5270.patch deleted file mode 100644 index d4036e1..0000000 --- a/ccid/patches/pcsclite_trunk_r5270.patch +++ /dev/null @@ -1,483 +0,0 @@ -Index: PCSC/src/PCSC/reader.h -=================================================================== ---- PCSC/src/PCSC/reader.h (Revision 5270) -+++ PCSC/src/PCSC/reader.h (Arbeitskopie) -@@ -121,6 +121,7 @@ - #define FEATURE_IFD_DISPLAY_PROPERTIES 0x11 - #define FEATURE_GET_TLV_PROPERTIES 0x12 - #define FEATURE_CCID_ESC_COMMAND 0x13 -+#define FEATURE_EXECUTE_PACE 0x20 - - /* structures used (but not defined) in PC/SC Part 10: - * "IFDs with Secure Pin Entry Capabilities" */ -Index: Drivers/ccid/src/ifdhandler.c -=================================================================== ---- Drivers/ccid/src/ifdhandler.c (Revision 5270) -+++ Drivers/ccid/src/ifdhandler.c (Arbeitskopie) -@@ -1397,6 +1397,16 @@ - iBytesReturned += sizeof(PCSC_TLV_STRUCTURE); - } - -+ if (ccid_descriptor -> 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); -+ } -+ - /* We can always forward wLcdLayout */ - pcsc_tlv -> tag = FEATURE_IFD_PIN_PROPERTIES; - pcsc_tlv -> length = 0x04; /* always 0x04 */ -@@ -1561,6 +1571,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; -+ memcpy(&lengthInputData, &TxBuffer[1], 2); -+ -+ 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: Drivers/ccid/src/commands.c -=================================================================== ---- Drivers/ccid/src/commands.c (Revision 5270) -+++ Drivers/ccid/src/commands.c (Arbeitskopie) -@@ -73,7 +73,19 @@ - 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 RESPONSECODE transform_EstablishPACEChannel_InputData( -+ unsigned char input[], unsigned int input_length); -+ -+static RESPONSECODE transform_EstablishPACEChannel_OutputData( -+ unsigned char output[], unsigned int output_length); -+ - static void i2dw(int value, unsigned char *buffer); -+static void i2w(uint16_t value, unsigned char *buffer); - static unsigned int bei2i(unsigned char *buffer); - - -@@ -751,7 +763,302 @@ - return ret; - } /* SecurePINModify */ - -+static RESPONSECODE transform_EstablishPACEChannel_InputData( -+ unsigned char input[], unsigned int input_length) -+{ -+ uint8_t lengthCHAT, lengthPIN; -+ uint16_t lengthCertificateDescription; -+ size_t parsed = 0; - -+ /* transform length fields of input data to little endian */ -+ -+ if (input_length < parsed+1) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ switch (input[parsed]) { -+ case 0x01: -+ DEBUG_COMM("Initiating PACE with MRZ"); -+ break; -+ case 0x02: -+ DEBUG_COMM("Initiating PACE with CAN"); -+ break; -+ case 0x03: -+ DEBUG_COMM("Initiating PACE with PIN"); -+ break; -+ case 0x04: -+ DEBUG_COMM("Initiating PACE with PUK"); -+ break; -+ default: -+ DEBUG_COMM("Initiating PACE with unknown PACE secret type"); -+ break; -+ } -+ parsed += 1; -+ -+ if (input_length < parsed+1) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ lengthCHAT = input[parsed]; -+ parsed += 1; -+ -+ if (input_length < parsed+lengthCHAT) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ if (lengthCHAT) -+ DEBUG_INFO_XXD("CHAT:\n", &input[parsed], lengthCHAT); -+ parsed += lengthCHAT; -+ -+ if (input_length < parsed+1) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ lengthPIN = input[parsed]; -+ parsed += 1; -+ -+ if (input_length < parsed+lengthPIN) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+#if 0 -+ /* dont print secrets... */ -+ if (lengthPIN) -+ DEBUG_INFO_XXD("PIN:\n", &input[parsed], lengthPIN); -+#endif -+ parsed += lengthPIN; -+ -+ if (input_length < parsed+2) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ memcpy(&lengthCertificateDescription, &input[parsed], 2); -+ i2w(lengthCertificateDescription, &input[parsed]); -+ parsed += 2; -+ -+ if (input_length < parsed+lengthCertificateDescription) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel input data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ if (lengthCertificateDescription) -+ DEBUG_INFO_XXD("Certificate description:\n", &input[parsed], lengthCertificateDescription); -+ parsed += lengthCertificateDescription; -+ -+ if (parsed < input_length) { -+ DEBUG_CRITICAL2("Overrun by %u bytes", input_length - parsed); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ -+ return IFD_SUCCESS; -+} -+ -+static RESPONSECODE transform_EstablishPACEChannel_OutputData( -+ unsigned char output[], unsigned int output_length) -+{ -+ uint8_t lengthCAR, lengthCARprev; -+ uint16_t lengthEF_CardAccess, length_IDicc; -+ size_t parsed = 0; -+ -+ if (parsed+2 > output_length) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ DEBUG_INFO3("MSE:Set AT Statusbytes: %02X %02X", -+ output[parsed+0], output[parsed+1]); -+ parsed += 2; -+ -+ if (parsed+2 > output_length) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ lengthEF_CardAccess = w2i(output, parsed); -+ memcpy(&output[parsed], &lengthEF_CardAccess, 2); -+ parsed += 2; -+ -+ if (parsed+lengthEF_CardAccess > output_length) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ if (lengthEF_CardAccess) -+ DEBUG_INFO_XXD("EF.CardAccess:\n", &output[parsed], lengthEF_CardAccess); -+ parsed += lengthEF_CardAccess; -+ -+ if (parsed+1 > output_length) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ lengthCAR = output[parsed]; -+ parsed += 1; -+ -+ if (parsed+lengthCAR > output_length) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ if (lengthCAR) -+ DEBUG_INFO_XXD("Recent Certificate Authority:\n", -+ &output[parsed], lengthCAR); -+ parsed += lengthCAR; -+ -+ if (parsed+1 > output_length) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ lengthCARprev = output[parsed]; -+ parsed += 1; -+ -+ if (parsed+lengthCARprev > output_length) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ if (lengthCARprev) -+ DEBUG_INFO_XXD("Previous Certificate Authority:\n", -+ &output[parsed], lengthCARprev); -+ parsed += lengthCARprev; -+ -+ if (parsed+2 > output_length) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ length_IDicc = w2i(output, parsed); -+ memcpy(&output[parsed], &length_IDicc, 2); -+ parsed += 2; -+ -+ if (parsed+length_IDicc > output_length) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ if (length_IDicc) -+ DEBUG_INFO_XXD("IDicc:\n", &output[parsed], length_IDicc); -+ parsed += length_IDicc; -+ -+ if (parsed < output_length) { -+ DEBUG_CRITICAL2("Overrun by %u bytes", output_length - parsed); -+ return IFD_COMMUNICATION_ERROR; -+ } -+ -+ return IFD_SUCCESS; -+} -+ -+RESPONSECODE SecurePINPACEVerify(unsigned int reader_index, -+ unsigned char TxBuffer[], unsigned int TxLength, -+ unsigned char RxBuffer[], unsigned int *RxLength) -+{ -+ RESPONSECODE return_value; -+ 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 */ -+ -+ return_value = transform_EstablishPACEChannel_InputData(TxBuffer, TxLength); -+ if (IFD_SUCCESS != return_value) -+ goto err; -+ -+ /* bPINOperation: PIN PACE Capabilities */ -+ return_value = SecurePINPACE(reader_index, TxBuffer, TxLength, RxBuffer, -+ RxLength, CCID_CLASS_PIN_PACE_EXECUTE); -+ if (IFD_SUCCESS != return_value) -+ goto err; -+ -+ if (*RxLength < 6) { -+ DEBUG_CRITICAL("Malformed Establish PACE output buffer."); -+ return_value = IFD_COMMUNICATION_ERROR; -+ goto err; -+ } -+ -+ return_value = transform_EstablishPACEChannel_OutputData(RxBuffer+6, (*RxLength)-6); -+ if (IFD_SUCCESS != return_value) -+ goto err; -+ -+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[1024]; -+ 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 + 6 <= *RxLength) -+ *RxLength = length + 6; -+ else -+ { -+ DEBUG_CRITICAL2("overrun by %d bytes", length + 6 - *RxLength); -+ return IFD_ERROR_INSUFFICIENT_BUFFER; -+ } -+ uint32_t s = 0x00000000; /* "Kein Fehler" */ -+ memcpy(RxBuffer, &s, 4); -+ memcpy(RxBuffer+4, &length, 2); /* lengthOutputData */ -+ memcpy(RxBuffer+6, &cmd[10], length); -+ -+ return IFD_SUCCESS; -+} -+ -+ - /***************************************************************************** - * - * Escape -@@ -2152,7 +2459,20 @@ - 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 */ -+ -+ -+/***************************************************************************** - * - * bei2i (big endian integer to host order interger) - * -Index: Drivers/ccid/src/commands.h -=================================================================== ---- Drivers/ccid/src/commands.h (Revision 5270) -+++ Drivers/ccid/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: Drivers/ccid/src/ccid_ifdhandler.h -=================================================================== ---- Drivers/ccid/src/ccid_ifdhandler.h (Revision 5270) -+++ Drivers/ccid/src/ccid_ifdhandler.h (Arbeitskopie) -@@ -37,6 +37,8 @@ - SCARD_CTL_CODE(FEATURE_IFD_PIN_PROPERTIES + CLASS2_IOCTL_MAGIC) - #define IOCTL_FEATURE_GET_TLV_PROPERTIES \ - SCARD_CTL_CODE(FEATURE_GET_TLV_PROPERTIES + CLASS2_IOCTL_MAGIC) -+#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 -Index: Drivers/ccid/src/ccid.h -=================================================================== ---- Drivers/ccid/src/ccid.h (Revision 5270) -+++ Drivers/ccid/src/ccid.h (Arbeitskopie) -@@ -142,8 +142,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 */ -@@ -228,6 +230,8 @@ - - /* convert a 4 byte integer in USB format into an int */ - #define dw2i(a, x) (unsigned int)((((((a[x+3] << 8) + a[x+2]) << 8) + a[x+1]) << 8) + a[x]) -+/* convert a 2 byte integer in USB format into an int */ -+#define w2i(a, x) (unsigned int)(((a[x+1]) << 8) + a[x]) - - /* all the data rates specified by ISO 7816-3 Fi/Di tables */ - #define ISO_DATA_RATES 10753, 14337, 15625, 17204, \