diff --git a/ccid/patches/ccid-1.3.11.patch b/ccid/patches/ccid-1.3.11.patch index a63d644..4d981a9 100644 --- a/ccid/patches/ccid-1.3.11.patch +++ b/ccid/patches/ccid-1.3.11.patch @@ -1,7 +1,7 @@ -Index: ccid-1.3.11/src/ifdhandler.c +Index: src/ifdhandler.c =================================================================== ---- ccid-1.3.11/src/ifdhandler.c (Revision 4347) -+++ ccid-1.3.11/src/ifdhandler.c (Arbeitskopie) +--- src/ifdhandler.c (Revision 4347) ++++ src/ifdhandler.c (Arbeitskopie) @@ -1266,6 +1266,16 @@ iBytesReturned += sizeof(PCSC_TLV_STRUCTURE); } @@ -31,7 +31,7 @@ Index: ccid-1.3.11/src/ifdhandler.c + return_value = IFD_COMMUNICATION_ERROR; + } else { + uint16_t lengthInputData; -+ lengthInputData = *((uint16_t *) (TxBuffer + 1)); ++ memcpy(&lengthInputData, &TxBuffer[1], 2); + + if (TxLength != 3+lengthInputData) { + DEBUG_CRITICAL3("Buffer too small or too big to contain only " @@ -63,11 +63,11 @@ Index: ccid-1.3.11/src/ifdhandler.c if (IFD_SUCCESS != return_value) *pdwBytesReturned = 0; -Index: ccid-1.3.11/src/commands.c +Index: src/commands.c =================================================================== ---- ccid-1.3.11/src/commands.c (Revision 4347) -+++ ccid-1.3.11/src/commands.c (Arbeitskopie) -@@ -68,7 +68,13 @@ +--- src/commands.c (Revision 4347) ++++ src/commands.c (Arbeitskopie) +@@ -68,7 +68,19 @@ unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length, unsigned char rx_buffer[]); @@ -75,65 +75,205 @@ Index: ccid-1.3.11/src/commands.c + 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); /***************************************************************************** -@@ -691,7 +697,217 @@ +@@ -691,7 +703,299 @@ 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"); ++ case 0x02: ++ DEBUG_COMM("Initiating PACE with CAN"); ++ case 0x03: ++ DEBUG_COMM("Initiating PACE with PIN"); ++ case 0x04: ++ DEBUG_COMM("Initiating PACE with PUK"); ++ default: ++ DEBUG_COMM("Initiating PACE with unknown PACE secret type"); ++ } ++ 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 += lengthCHAT; ++ ++ if (parsed != input_length) { ++ DEBUG_CRITICAL2("Overrun by %d 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_COMM3("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); ++ 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); ++ 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 %d 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; -+ unsigned char lengthCHAT, lengthPIN; -+ uint16_t lengthCertificateDescription, lengthEF_CardAccess, length_IDicc; -+ uint8_t lengthCAR, lengthCARprev; + int old_read_timeout; -+ size_t parsed; + _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; ++ return_value = transform_EstablishPACEChannel_InputData(TxBuffer, TxLength); ++ if (IFD_SUCCESS != return_value) + 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, @@ -141,71 +281,15 @@ Index: ccid-1.3.11/src/commands.c + if (IFD_SUCCESS != return_value) + goto err; + -+ -+ if (6+2 > *RxLength) -+ goto err; -+ DEBUG_INFO3("MSE:Set AT Statusbytes: %02X %02X", -+ RxBuffer[6+0], RxBuffer[6+1]); -+ parsed = 6+2; -+ -+ -+ if (parsed+2 > *RxLength) -+ goto err; -+ lengthEF_CardAccess = w2i(RxBuffer, parsed); -+ if (parsed+2+lengthEF_CardAccess > *RxLength) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); ++ if (*RxLength < 6) { ++ DEBUG_CRITICAL("Malformed Establish PACE output buffer."); + return_value = IFD_COMMUNICATION_ERROR; + goto err; + } -+ if (lengthEF_CardAccess) -+ DEBUG_INFO_XXD("EF.CardAccess:\n", &RxBuffer[parsed+2], lengthEF_CardAccess); -+ parsed += 2 + lengthEF_CardAccess; + -+ if (parsed+1 > *RxLength) ++ return_value = transform_EstablishPACEChannel_OutputData(RxBuffer+6, (*RxLength)-6); ++ if (IFD_SUCCESS != return_value) + goto err; -+ lengthCAR = RxBuffer[parsed+1]; -+ if (parsed+1+lengthCAR > *RxLength) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return_value = IFD_COMMUNICATION_ERROR; -+ goto err; -+ } -+ if (lengthCAR) -+ DEBUG_INFO_XXD("Recent Certificate Authority:\n", -+ &RxBuffer[parsed+1], -+ lengthCAR); -+ parsed += 1 + lengthCAR; -+ -+ if (parsed+1 > *RxLength) -+ goto err; -+ lengthCARprev = RxBuffer[parsed+1]; -+ if (parsed+1+lengthCARprev > *RxLength) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return_value = IFD_COMMUNICATION_ERROR; -+ goto err; -+ } -+ if (lengthCARprev) -+ DEBUG_INFO_XXD("Previous Certificate Authority:\n", -+ &RxBuffer[parsed+1], -+ lengthCARprev); -+ parsed += 1 + lengthCARprev; -+ -+ if (parsed+2 > *RxLength) -+ goto err; -+ length_IDicc = w2i(RxBuffer, parsed); -+ if (parsed+2+length_IDicc > *RxLength) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return_value = IFD_COMMUNICATION_ERROR; -+ goto err; -+ } -+ if (length_IDicc) -+ DEBUG_INFO_XXD("IDicc:\n", &RxBuffer[parsed+2], length_IDicc); -+ parsed += 2 + length_IDicc; -+ -+ if (parsed != *RxLength) { -+ DEBUG_CRITICAL2("Overrun by %d bytes", *RxLength - parsed); -+ return_value = IFD_COMMUNICATION_ERROR; -+ goto err; -+ } + +err: + ccid_descriptor -> readTimeout = old_read_timeout; @@ -245,8 +329,10 @@ Index: ccid-1.3.11/src/commands.c + 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; + } + @@ -254,8 +340,10 @@ Index: ccid-1.3.11/src/commands.c + 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; + } + @@ -287,9 +375,9 @@ Index: ccid-1.3.11/src/commands.c + DEBUG_CRITICAL2("overrun by %d bytes", length + 6 - *RxLength); + return IFD_ERROR_INSUFFICIENT_BUFFER; + } -+ uint32_t s = 0x00000000; -+ memcpy(RxBuffer, &s, 4); /* "Kein Fehler" */ -+ memcpy(RxBuffer+4, &length, 2); /* lengthOutputData */ ++ 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; @@ -299,7 +387,7 @@ Index: ccid-1.3.11/src/commands.c /***************************************************************************** * * Escape -@@ -2081,3 +2297,15 @@ +@@ -2081,3 +2385,15 @@ buffer[3] = (value >> 24) & 0xFF; } /* i2dw */ @@ -315,10 +403,10 @@ Index: ccid-1.3.11/src/commands.c + buffer[1] = (value >> 8) & 0xFF; +} /* i2w */ + -Index: ccid-1.3.11/src/commands.h +Index: src/commands.h =================================================================== ---- ccid-1.3.11/src/commands.h (Revision 4347) -+++ ccid-1.3.11/src/commands.h (Arbeitskopie) +--- 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); @@ -334,10 +422,10 @@ Index: ccid-1.3.11/src/commands.h RESPONSECODE CmdEscape(unsigned int reader_index, const unsigned char TxBuffer[], unsigned int TxLength, unsigned char RxBuffer[], unsigned int *RxLength); -Index: ccid-1.3.11/src/ccid.h +Index: src/ccid.h =================================================================== ---- ccid-1.3.11/src/ccid.h (Revision 4347) -+++ ccid-1.3.11/src/ccid.h (Arbeitskopie) +--- src/ccid.h (Revision 4347) ++++ src/ccid.h (Arbeitskopie) @@ -137,8 +137,10 @@ #define CCID_CLASS_EXCHANGE_MASK 0x00070000 @@ -360,10 +448,10 @@ Index: ccid-1.3.11/src/ccid.h /* all the data rates specified by ISO 7816-3 Fi/Di tables */ #define ISO_DATA_RATES 10753, 14337, 15625, 17204, \ -Index: ccid-1.3.11/src/ccid_ifdhandler.h +Index: src/ccid_ifdhandler.h =================================================================== ---- ccid-1.3.11/src/ccid_ifdhandler.h (Revision 4347) -+++ ccid-1.3.11/src/ccid_ifdhandler.h (Arbeitskopie) +--- 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) diff --git a/ccid/patches/ccid-1.3.13.patch b/ccid/patches/ccid-1.3.13.patch index 0812988..523ed5a 100644 --- a/ccid/patches/ccid-1.3.13.patch +++ b/ccid/patches/ccid-1.3.13.patch @@ -1,7 +1,7 @@ -Index: ccid-1.3.13/src/ifdhandler.c +Index: src/ifdhandler.c =================================================================== ---- ccid-1.3.13/src/ifdhandler.c (Revision 4979) -+++ ccid-1.3.13/src/ifdhandler.c (Arbeitskopie) +--- src/ifdhandler.c (Revision 4979) ++++ src/ifdhandler.c (Arbeitskopie) @@ -1384,6 +1384,16 @@ iBytesReturned += sizeof(PCSC_TLV_STRUCTURE); } @@ -31,7 +31,7 @@ Index: ccid-1.3.13/src/ifdhandler.c + return_value = IFD_COMMUNICATION_ERROR; + } else { + uint16_t lengthInputData; -+ lengthInputData = *((uint16_t *) (TxBuffer + 1)); ++ memcpy(&lengthInputData, &TxBuffer[1], 2); + + if (TxLength != 3+lengthInputData) { + DEBUG_CRITICAL3("Buffer too small or too big to contain only " @@ -63,11 +63,11 @@ Index: ccid-1.3.13/src/ifdhandler.c if (IFD_SUCCESS != return_value) *pdwBytesReturned = 0; -Index: ccid-1.3.13/src/commands.c +Index: src/commands.c =================================================================== ---- ccid-1.3.13/src/commands.c (Revision 4979) -+++ ccid-1.3.13/src/commands.c (Arbeitskopie) -@@ -68,7 +68,13 @@ +--- src/commands.c (Revision 4979) ++++ src/commands.c (Arbeitskopie) +@@ -68,7 +68,19 @@ unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length, unsigned char rx_buffer[]); @@ -75,65 +75,205 @@ Index: ccid-1.3.13/src/commands.c + 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 +718,217 @@ +@@ -712,7 +724,299 @@ 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"); ++ case 0x02: ++ DEBUG_COMM("Initiating PACE with CAN"); ++ case 0x03: ++ DEBUG_COMM("Initiating PACE with PIN"); ++ case 0x04: ++ DEBUG_COMM("Initiating PACE with PUK"); ++ default: ++ DEBUG_COMM("Initiating PACE with unknown PACE secret type"); ++ } ++ 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 += lengthCHAT; ++ ++ if (parsed != input_length) { ++ DEBUG_CRITICAL2("Overrun by %d 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_COMM3("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); ++ 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); ++ 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 %d 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; -+ unsigned char lengthCHAT, lengthPIN; -+ uint16_t lengthCertificateDescription, lengthEF_CardAccess, length_IDicc; -+ uint8_t lengthCAR, lengthCARprev; + int old_read_timeout; -+ size_t parsed; + _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; ++ return_value = transform_EstablishPACEChannel_InputData(TxBuffer, TxLength); ++ if (IFD_SUCCESS != return_value) + 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, @@ -141,71 +281,15 @@ Index: ccid-1.3.13/src/commands.c + if (IFD_SUCCESS != return_value) + goto err; + -+ -+ if (6+2 > *RxLength) -+ goto err; -+ DEBUG_INFO3("MSE:Set AT Statusbytes: %02X %02X", -+ RxBuffer[6+0], RxBuffer[6+1]); -+ parsed = 6+2; -+ -+ -+ if (parsed+2 > *RxLength) -+ goto err; -+ lengthEF_CardAccess = w2i(RxBuffer, parsed); -+ if (parsed+2+lengthEF_CardAccess > *RxLength) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); ++ if (*RxLength < 6) { ++ DEBUG_CRITICAL("Malformed Establish PACE output buffer."); + return_value = IFD_COMMUNICATION_ERROR; + goto err; + } -+ if (lengthEF_CardAccess) -+ DEBUG_INFO_XXD("EF.CardAccess:\n", &RxBuffer[parsed+2], lengthEF_CardAccess); -+ parsed += 2 + lengthEF_CardAccess; + -+ if (parsed+1 > *RxLength) ++ return_value = transform_EstablishPACEChannel_OutputData(RxBuffer+6, (*RxLength)-6); ++ if (IFD_SUCCESS != return_value) + goto err; -+ lengthCAR = RxBuffer[parsed+1]; -+ if (parsed+1+lengthCAR > *RxLength) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return_value = IFD_COMMUNICATION_ERROR; -+ goto err; -+ } -+ if (lengthCAR) -+ DEBUG_INFO_XXD("Recent Certificate Authority:\n", -+ &RxBuffer[parsed+1], -+ lengthCAR); -+ parsed += 1 + lengthCAR; -+ -+ if (parsed+1 > *RxLength) -+ goto err; -+ lengthCARprev = RxBuffer[parsed+1]; -+ if (parsed+1+lengthCARprev > *RxLength) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return_value = IFD_COMMUNICATION_ERROR; -+ goto err; -+ } -+ if (lengthCARprev) -+ DEBUG_INFO_XXD("Previous Certificate Authority:\n", -+ &RxBuffer[parsed+1], -+ lengthCARprev); -+ parsed += 1 + lengthCARprev; -+ -+ if (parsed+2 > *RxLength) -+ goto err; -+ length_IDicc = w2i(RxBuffer, parsed); -+ if (parsed+2+length_IDicc > *RxLength) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return_value = IFD_COMMUNICATION_ERROR; -+ goto err; -+ } -+ if (length_IDicc) -+ DEBUG_INFO_XXD("IDicc:\n", &RxBuffer[parsed+2], length_IDicc); -+ parsed += 2 + length_IDicc; -+ -+ if (parsed != *RxLength) { -+ DEBUG_CRITICAL2("Overrun by %d bytes", *RxLength - parsed); -+ return_value = IFD_COMMUNICATION_ERROR; -+ goto err; -+ } + +err: + ccid_descriptor -> readTimeout = old_read_timeout; @@ -245,8 +329,10 @@ Index: ccid-1.3.13/src/commands.c + 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; + } + @@ -254,8 +340,10 @@ Index: ccid-1.3.13/src/commands.c + 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; + } + @@ -287,9 +375,9 @@ Index: ccid-1.3.13/src/commands.c + DEBUG_CRITICAL2("overrun by %d bytes", length + 6 - *RxLength); + return IFD_ERROR_INSUFFICIENT_BUFFER; + } -+ uint32_t s = 0x00000000; -+ memcpy(RxBuffer, &s, 4); /* "Kein Fehler" */ -+ memcpy(RxBuffer+4, &length, 2); /* lengthOutputData */ ++ 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; @@ -299,7 +387,7 @@ Index: ccid-1.3.13/src/commands.c /***************************************************************************** * * Escape -@@ -2113,3 +2329,15 @@ +@@ -2113,3 +2417,15 @@ buffer[3] = (value >> 24) & 0xFF; } /* i2dw */ @@ -315,10 +403,10 @@ Index: ccid-1.3.13/src/commands.c + buffer[1] = (value >> 8) & 0xFF; +} /* i2w */ + -Index: ccid-1.3.13/src/commands.h +Index: src/commands.h =================================================================== ---- ccid-1.3.13/src/commands.h (Revision 4979) -+++ ccid-1.3.13/src/commands.h (Arbeitskopie) +--- src/commands.h (Revision 4979) ++++ src/commands.h (Arbeitskopie) @@ -37,6 +37,14 @@ unsigned char TxBuffer[], unsigned int TxLength, unsigned char RxBuffer[], unsigned int *RxLength); @@ -334,10 +422,10 @@ Index: ccid-1.3.13/src/commands.h 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 +Index: src/ccid.h =================================================================== ---- ccid-1.3.13/src/ccid.h (Revision 4979) -+++ ccid-1.3.13/src/ccid.h (Arbeitskopie) +--- src/ccid.h (Revision 4979) ++++ src/ccid.h (Arbeitskopie) @@ -142,8 +142,10 @@ #define CCID_CLASS_EXCHANGE_MASK 0x00070000 @@ -360,10 +448,10 @@ Index: ccid-1.3.13/src/ccid.h /* 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 +Index: src/ccid_ifdhandler.h =================================================================== ---- ccid-1.3.13/src/ccid_ifdhandler.h (Revision 4979) -+++ ccid-1.3.13/src/ccid_ifdhandler.h (Arbeitskopie) +--- src/ccid_ifdhandler.h (Revision 4979) ++++ 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 \ diff --git a/ccid/patches/pcsclite_trunk_r5063.patch b/ccid/patches/pcsclite_trunk_r5063.patch index ba5cfc7..01a6c67 100644 --- a/ccid/patches/pcsclite_trunk_r5063.patch +++ b/ccid/patches/pcsclite_trunk_r5063.patch @@ -43,7 +43,7 @@ Index: Drivers/ccid/src/ifdhandler.c + return_value = IFD_COMMUNICATION_ERROR; + } else { + uint16_t lengthInputData; -+ lengthInputData = *((uint16_t *) (TxBuffer + 1)); ++ memcpy(&lengthInputData, &TxBuffer[1], 2); + + if (TxLength != 3+lengthInputData) { + DEBUG_CRITICAL3("Buffer too small or too big to contain only " @@ -79,7 +79,7 @@ Index: Drivers/ccid/src/commands.c =================================================================== --- Drivers/ccid/src/commands.c (Revision 5063) +++ Drivers/ccid/src/commands.c (Arbeitskopie) -@@ -68,7 +68,13 @@ +@@ -68,7 +68,19 @@ unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length, unsigned char rx_buffer[]); @@ -87,65 +87,205 @@ Index: Drivers/ccid/src/commands.c + 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 +718,217 @@ +@@ -712,7 +724,299 @@ 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"); ++ case 0x02: ++ DEBUG_COMM("Initiating PACE with CAN"); ++ case 0x03: ++ DEBUG_COMM("Initiating PACE with PIN"); ++ case 0x04: ++ DEBUG_COMM("Initiating PACE with PUK"); ++ default: ++ DEBUG_COMM("Initiating PACE with unknown PACE secret type"); ++ } ++ 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 += lengthCHAT; ++ ++ if (parsed != input_length) { ++ DEBUG_CRITICAL2("Overrun by %d 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_COMM3("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); ++ 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); ++ 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 %d 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; -+ unsigned char lengthCHAT, lengthPIN; -+ uint16_t lengthCertificateDescription, lengthEF_CardAccess, length_IDicc; -+ uint8_t lengthCAR, lengthCARprev; + int old_read_timeout; -+ size_t parsed; + _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; ++ return_value = transform_EstablishPACEChannel_InputData(TxBuffer, TxLength); ++ if (IFD_SUCCESS != return_value) + 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, @@ -153,71 +293,15 @@ Index: Drivers/ccid/src/commands.c + if (IFD_SUCCESS != return_value) + goto err; + -+ -+ if (6+2 > *RxLength) -+ goto err; -+ DEBUG_INFO3("MSE:Set AT Statusbytes: %02X %02X", -+ RxBuffer[6+0], RxBuffer[6+1]); -+ parsed = 6+2; -+ -+ -+ if (parsed+2 > *RxLength) -+ goto err; -+ lengthEF_CardAccess = w2i(RxBuffer, parsed); -+ if (parsed+2+lengthEF_CardAccess > *RxLength) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); ++ if (*RxLength < 6) { ++ DEBUG_CRITICAL("Malformed Establish PACE output buffer."); + return_value = IFD_COMMUNICATION_ERROR; + goto err; + } -+ if (lengthEF_CardAccess) -+ DEBUG_INFO_XXD("EF.CardAccess:\n", &RxBuffer[parsed+2], lengthEF_CardAccess); -+ parsed += 2 + lengthEF_CardAccess; + -+ if (parsed+1 > *RxLength) ++ return_value = transform_EstablishPACEChannel_OutputData(RxBuffer+6, (*RxLength)-6); ++ if (IFD_SUCCESS != return_value) + goto err; -+ lengthCAR = RxBuffer[parsed+1]; -+ if (parsed+1+lengthCAR > *RxLength) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return_value = IFD_COMMUNICATION_ERROR; -+ goto err; -+ } -+ if (lengthCAR) -+ DEBUG_INFO_XXD("Recent Certificate Authority:\n", -+ &RxBuffer[parsed+1], -+ lengthCAR); -+ parsed += 1 + lengthCAR; -+ -+ if (parsed+1 > *RxLength) -+ goto err; -+ lengthCARprev = RxBuffer[parsed+1]; -+ if (parsed+1+lengthCARprev > *RxLength) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return_value = IFD_COMMUNICATION_ERROR; -+ goto err; -+ } -+ if (lengthCARprev) -+ DEBUG_INFO_XXD("Previous Certificate Authority:\n", -+ &RxBuffer[parsed+1], -+ lengthCARprev); -+ parsed += 1 + lengthCARprev; -+ -+ if (parsed+2 > *RxLength) -+ goto err; -+ length_IDicc = w2i(RxBuffer, parsed); -+ if (parsed+2+length_IDicc > *RxLength) { -+ DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); -+ return_value = IFD_COMMUNICATION_ERROR; -+ goto err; -+ } -+ if (length_IDicc) -+ DEBUG_INFO_XXD("IDicc:\n", &RxBuffer[parsed+2], length_IDicc); -+ parsed += 2 + length_IDicc; -+ -+ if (parsed != *RxLength) { -+ DEBUG_CRITICAL2("Overrun by %d bytes", *RxLength - parsed); -+ return_value = IFD_COMMUNICATION_ERROR; -+ goto err; -+ } + +err: + ccid_descriptor -> readTimeout = old_read_timeout; @@ -257,8 +341,10 @@ Index: Drivers/ccid/src/commands.c + 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; + } + @@ -266,8 +352,10 @@ Index: Drivers/ccid/src/commands.c + 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; + } + @@ -299,9 +387,9 @@ Index: Drivers/ccid/src/commands.c + DEBUG_CRITICAL2("overrun by %d bytes", length + 6 - *RxLength); + return IFD_ERROR_INSUFFICIENT_BUFFER; + } -+ uint32_t s = 0x00000000; -+ memcpy(RxBuffer, &s, 4); /* "Kein Fehler" */ -+ memcpy(RxBuffer+4, &length, 2); /* lengthOutputData */ ++ 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; @@ -311,7 +399,7 @@ Index: Drivers/ccid/src/commands.c /***************************************************************************** * * Escape -@@ -2113,3 +2329,15 @@ +@@ -2113,3 +2417,15 @@ buffer[3] = (value >> 24) & 0xFF; } /* i2dw */ diff --git a/ccid/src/pace.c b/ccid/src/pace.c index 588a457..9857b6f 100644 --- a/ccid/src/pace.c +++ b/ccid/src/pace.c @@ -1199,6 +1199,16 @@ int EstablishPACEChannel(const struct sm_ctx *oldpacectx, sc_card_t *card, goto err; } + /* get enough memory for IDicc */ + p = realloc(*out, (*outlen) + 2); + if (!p) { + r = SC_ERROR_OUT_OF_MEMORY; + goto err; + } + *out = p; + memset((*out) + (*outlen), 0, 2); + *outlen += 2; + /* XXX parse CHAT to check role of terminal */ sctx->authentication_ctx = pace_sm_ctx_create(k_mac,