diff --git a/ccid/patches/Makefile.am b/ccid/patches/Makefile.am index a1a2f2d..3aef615 100644 --- a/ccid/patches/Makefile.am +++ b/ccid/patches/Makefile.am @@ -1,3 +1,3 @@ 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_r4993.patch + pcsclite_trunk_r5063.patch diff --git a/ccid/patches/ccid-1.3.11.patch b/ccid/patches/ccid-1.3.11.patch index 4d981a9..463997a 100644 --- a/ccid/patches/ccid-1.3.11.patch +++ b/ccid/patches/ccid-1.3.11.patch @@ -1,7 +1,7 @@ -Index: src/ifdhandler.c +Index: ccid-1.3.11/src/ifdhandler.c =================================================================== ---- src/ifdhandler.c (Revision 4347) -+++ src/ifdhandler.c (Arbeitskopie) +--- ccid-1.3.11/src/ifdhandler.c (Revision 4347) ++++ ccid-1.3.11/src/ifdhandler.c (Arbeitskopie) @@ -1266,6 +1266,16 @@ iBytesReturned += sizeof(PCSC_TLV_STRUCTURE); } @@ -63,10 +63,10 @@ Index: src/ifdhandler.c if (IFD_SUCCESS != return_value) *pdwBytesReturned = 0; -Index: src/commands.c +Index: ccid-1.3.11/src/commands.c =================================================================== ---- src/commands.c (Revision 4347) -+++ src/commands.c (Arbeitskopie) +--- ccid-1.3.11/src/commands.c (Revision 4347) ++++ ccid-1.3.11/src/commands.c (Arbeitskopie) @@ -68,7 +68,19 @@ unsigned int tx_length, unsigned char tx_buffer[], unsigned int *rx_length, unsigned char rx_buffer[]); @@ -106,15 +106,15 @@ Index: src/commands.c + } + switch (input[parsed]) { + case 0x01: -+ DEBUG_COMM("Initiating PACE with MRZ"); ++ DEBUG_INFO("Initiating PACE with MRZ"); + case 0x02: -+ DEBUG_COMM("Initiating PACE with CAN"); ++ DEBUG_INFO("Initiating PACE with CAN"); + case 0x03: -+ DEBUG_COMM("Initiating PACE with PIN"); ++ DEBUG_INFO("Initiating PACE with PIN"); + case 0x04: -+ DEBUG_COMM("Initiating PACE with PUK"); ++ DEBUG_INFO("Initiating PACE with PUK"); + default: -+ DEBUG_COMM("Initiating PACE with unknown PACE secret type"); ++ DEBUG_INFO("Initiating PACE with unknown PACE secret type"); + } + parsed += 1; + @@ -186,7 +186,7 @@ Index: src/commands.c + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } -+ DEBUG_COMM3("MSE:Set AT Statusbytes: %02X %02X", ++ DEBUG_INFO3("MSE:Set AT Statusbytes: %02X %02X", + output[parsed+0], output[parsed+1]); + parsed += 2; + @@ -403,10 +403,10 @@ Index: src/commands.c + buffer[1] = (value >> 8) & 0xFF; +} /* i2w */ + -Index: src/commands.h +Index: ccid-1.3.11/src/commands.h =================================================================== ---- src/commands.h (Revision 4347) -+++ src/commands.h (Arbeitskopie) +--- ccid-1.3.11/src/commands.h (Revision 4347) ++++ ccid-1.3.11/src/commands.h (Arbeitskopie) @@ -37,6 +37,14 @@ unsigned char TxBuffer[], unsigned int TxLength, unsigned char RxBuffer[], unsigned int *RxLength); @@ -422,10 +422,10 @@ Index: src/commands.h RESPONSECODE CmdEscape(unsigned int reader_index, const unsigned char TxBuffer[], unsigned int TxLength, unsigned char RxBuffer[], unsigned int *RxLength); -Index: src/ccid.h +Index: ccid-1.3.11/src/ccid.h =================================================================== ---- src/ccid.h (Revision 4347) -+++ src/ccid.h (Arbeitskopie) +--- ccid-1.3.11/src/ccid.h (Revision 4347) ++++ ccid-1.3.11/src/ccid.h (Arbeitskopie) @@ -137,8 +137,10 @@ #define CCID_CLASS_EXCHANGE_MASK 0x00070000 @@ -448,10 +448,10 @@ Index: src/ccid.h /* all the data rates specified by ISO 7816-3 Fi/Di tables */ #define ISO_DATA_RATES 10753, 14337, 15625, 17204, \ -Index: src/ccid_ifdhandler.h +Index: ccid-1.3.11/src/ccid_ifdhandler.h =================================================================== ---- src/ccid_ifdhandler.h (Revision 4347) -+++ src/ccid_ifdhandler.h (Arbeitskopie) +--- ccid-1.3.11/src/ccid_ifdhandler.h (Revision 4347) ++++ ccid-1.3.11/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 523ed5a..c92daa1 100644 --- a/ccid/patches/ccid-1.3.13.patch +++ b/ccid/patches/ccid-1.3.13.patch @@ -1,7 +1,7 @@ -Index: src/ifdhandler.c +Index: ccid-1.3.13/src/ifdhandler.c =================================================================== ---- src/ifdhandler.c (Revision 4979) -+++ src/ifdhandler.c (Arbeitskopie) +--- 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); } @@ -63,10 +63,10 @@ Index: src/ifdhandler.c if (IFD_SUCCESS != return_value) *pdwBytesReturned = 0; -Index: src/commands.c +Index: ccid-1.3.13/src/commands.c =================================================================== ---- src/commands.c (Revision 4979) -+++ src/commands.c (Arbeitskopie) +--- 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[]); @@ -106,15 +106,15 @@ Index: src/commands.c + } + switch (input[parsed]) { + case 0x01: -+ DEBUG_COMM("Initiating PACE with MRZ"); ++ DEBUG_INFO("Initiating PACE with MRZ"); + case 0x02: -+ DEBUG_COMM("Initiating PACE with CAN"); ++ DEBUG_INFO("Initiating PACE with CAN"); + case 0x03: -+ DEBUG_COMM("Initiating PACE with PIN"); ++ DEBUG_INFO("Initiating PACE with PIN"); + case 0x04: -+ DEBUG_COMM("Initiating PACE with PUK"); ++ DEBUG_INFO("Initiating PACE with PUK"); + default: -+ DEBUG_COMM("Initiating PACE with unknown PACE secret type"); ++ DEBUG_INFO("Initiating PACE with unknown PACE secret type"); + } + parsed += 1; + @@ -186,7 +186,7 @@ Index: src/commands.c + DEBUG_CRITICAL("Malformed Establish PACE Channel output data."); + return IFD_COMMUNICATION_ERROR; + } -+ DEBUG_COMM3("MSE:Set AT Statusbytes: %02X %02X", ++ DEBUG_INFO3("MSE:Set AT Statusbytes: %02X %02X", + output[parsed+0], output[parsed+1]); + parsed += 2; + @@ -403,10 +403,10 @@ Index: src/commands.c + buffer[1] = (value >> 8) & 0xFF; +} /* i2w */ + -Index: src/commands.h +Index: ccid-1.3.13/src/commands.h =================================================================== ---- src/commands.h (Revision 4979) -+++ src/commands.h (Arbeitskopie) +--- 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); @@ -422,10 +422,10 @@ Index: src/commands.h RESPONSECODE CmdEscape(unsigned int reader_index, const unsigned char TxBuffer[], unsigned int TxLength, unsigned char RxBuffer[], unsigned int *RxLength); -Index: src/ccid.h +Index: ccid-1.3.13/src/ccid.h =================================================================== ---- src/ccid.h (Revision 4979) -+++ src/ccid.h (Arbeitskopie) +--- 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 @@ -448,10 +448,10 @@ Index: src/ccid.h /* all the data rates specified by ISO 7816-3 Fi/Di tables */ #define ISO_DATA_RATES 10753, 14337, 15625, 17204, \ -Index: src/ccid_ifdhandler.h +Index: ccid-1.3.13/src/ccid_ifdhandler.h =================================================================== ---- src/ccid_ifdhandler.h (Revision 4979) -+++ src/ccid_ifdhandler.h (Arbeitskopie) +--- 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 \ diff --git a/ccid/src/ccid.c b/ccid/src/ccid.c index 200a8da..7fc6103 100644 --- a/ccid/src/ccid.c +++ b/ccid/src/ccid.c @@ -779,7 +779,10 @@ perform_PC_to_RDR_Secure(const __u8 *in, size_t inlen, __u8** out, size_t *outle const __u8* abData = in + sizeof *request; size_t abDatalen = inlen - sizeof *request; u8 *abDataOut = NULL; - size_t resplen = 0; + size_t resplen = 0, parsed; + __le16 word; + struct establish_pace_channel_input pace_input; + struct establish_pace_channel_output pace_output; RDR_to_PC_DataBlock_t *result; if (!in || !out || !outlen) @@ -793,6 +796,8 @@ perform_PC_to_RDR_Secure(const __u8 *in, size_t inlen, __u8** out, size_t *outle memset(&curr_pin, 0, sizeof(curr_pin)); memset(&new_pin, 0, sizeof(new_pin)); + memset(&pace_input, 0, sizeof(pace_input)); + memset(&pace_output, 0, sizeof(pace_output)); if (request->bSlot > sizeof *card_in_slot) { sc_error(ctx, "Received request to invalid slot (bSlot=0x%02x)", request->bSlot); @@ -865,15 +870,69 @@ perform_PC_to_RDR_Secure(const __u8 *in, size_t inlen, __u8** out, size_t *outle goto err; break; case 0x20: + parsed = 1; - if (abDatalen < 1) { - sc_error(ctx, "Not enough data for input of EstablishPACEChannel"); - sc_result = SC_ERROR_INVALID_DATA; + if (abDatalen < parsed+1) { + sc_error(ctx, "Buffer too small, could not get PinID"); goto err; } + pace_input.pin_id = abData[parsed]; + parsed++; + + if (abDatalen < parsed+1) { + sc_error(ctx, "Buffer too small, could not get lengthCHAT"); + goto err; + } + pace_input.chat_length = abData[parsed]; + parsed++; + + if (abDatalen < parsed+pace_input.chat_length) { + sc_error(ctx, "Buffer too small, could not get CHAT"); + goto err; + } + pace_input.chat = &abData[parsed]; + parsed += pace_input.chat_length; + /* XXX make this human readable */ + if (pace_input.chat_length) + bin_log(ctx, "Card holder authorization template", + pace_input.chat, pace_input.chat_length); + + if (abDatalen < parsed+1) { + sc_error(ctx, "Buffer too small, could not get lengthPIN"); + goto err; + } + pace_input.pin_length = abData[parsed]; + parsed++; + + if (abDatalen < parsed+pace_input.pin_length) { + sc_error(ctx, "Buffer too small, could not get PIN"); + goto err; + } + pace_input.pin = &abData[parsed]; + parsed += pace_input.pin_length; + + if (abDatalen < parsed+sizeof(word)) { + sc_error(ctx, "Buffer too small, could not get lengthCertificateDescription"); + goto err; + } + memcpy(&word, &abData[parsed], sizeof word); + pace_input.certificate_description_length = __le16_to_cpu(word); + parsed += sizeof word; + + if (abDatalen < parsed+pace_input.certificate_description_length) { + sc_error(ctx, "Buffer too small, could not get CertificateDescription"); + goto err; + } + pace_input.certificate_description = &abData[parsed]; + parsed+= pace_input.certificate_description_length; + /* XXX make this human readable */ + if (pace_input.certificate_description_length) + bin_log(ctx, "Certificate description", + pace_input.certificate_description, + pace_input.certificate_description_length); sc_result = EstablishPACEChannel(NULL, - card_in_slot[request->bSlot], abData + 1, abDatalen-1, + card_in_slot[request->bSlot], pace_input, &abDataOut, &resplen, &sctx); goto err; break; diff --git a/ccid/src/pace-tool.c b/ccid/src/pace-tool.c index a83920a..df22ff3 100644 --- a/ccid/src/pace-tool.c +++ b/ccid/src/pace-tool.c @@ -30,7 +30,6 @@ static int verbose = 0; static int doinfo = 0; -static u8 pin_id = 0; static u8 dochangepin = 0; static u8 doresumepin = 0; static u8 dounblock = 0; @@ -46,9 +45,7 @@ static u8 usecan = 0; static const char *mrz = NULL; static u8 usemrz = 0; static u8 chat[0xff]; -static size_t chatlen = 0; static u8 desc[0xffff]; -static size_t desclen = 0; static const char *cdriver = NULL; static sc_context_t *ctx = NULL; @@ -107,62 +104,6 @@ static const char *option_help[] = { "Print version, available readers and drivers.", }; -int pace_get_channel(struct sm_ctx *oldpacectx, sc_card_t *card, - enum s_type pin_id, const char *pin, size_t pinlen, - const char *chat, size_t chatlen, const char *desc, size_t desclen, - __u8 **out, size_t *outlen, struct sm_ctx *sctx) -{ - u8 buf[0xff + 0xff + 0xffff + 5]; - __le16 word; - - switch (pin_id) { - case PACE_MRZ: - case PACE_CAN: - case PACE_PIN: - case PACE_PUK: - break; - default: - sc_error(card->ctx, "Type of secret not supported"); - return SC_ERROR_INVALID_ARGUMENTS; - } - - if (pinlen > 0xff) { - sc_error(card->ctx, "%s " - "too long (maximal %u bytes supported)", - pace_secret_name(pin_id), - 0xff); - return SC_ERROR_INVALID_ARGUMENTS; - } - if (chatlen > 0xff) { - sc_error(card->ctx, "CHAT " - "too long (maximal %u bytes supported)", - 0xff); - return SC_ERROR_INVALID_ARGUMENTS; - } - if (desclen > 0xffff) { - sc_error(card->ctx, "Certificate description " - "too long (maximal %u bytes supported)", - 0xffff); - return SC_ERROR_INVALID_ARGUMENTS; - } - - buf[0] = pin_id; - - buf[1] = chatlen; - memcpy(&buf[2], chat, chatlen); - - buf[2 + chatlen] = pinlen; - memcpy(&buf[3 + chatlen], pin, pinlen); - - word = __cpu_to_le16(desclen); - memcpy(&buf[3 + chatlen + pinlen], &word, sizeof word); - memcpy(&buf[3 + chatlen + pinlen + sizeof word], - desc, desclen); - - return EstablishPACEChannel(oldpacectx, card, buf, - 1+1+chatlen+1+pinlen+sizeof(word)+desclen, out, outlen, sctx); -} - int pace_translate_apdus(struct sm_ctx *sctx, sc_card_t *card) { u8 buf[0xff + 5]; @@ -228,10 +169,14 @@ main (int argc, char **argv) __u8 *channeldata = NULL; size_t channeldatalen; struct sm_ctx sctx, tmpctx; + struct establish_pace_channel_input pace_input; time_t t_start, t_end; + u8 *out = NULL; + size_t outlen; memset(&sctx, 0, sizeof(sctx)); memset(&tmpctx, 0, sizeof(tmpctx)); + memset(&pace_input, 0, sizeof(pace_input)); while (1) { i = getopt_long(argc, argv, "hr:i::u::a::z::C:D:N::RUtvoc:", options, &oindex); @@ -282,15 +227,19 @@ main (int argc, char **argv) can = getenv("MRZ"); break; case OPT_CHAT: - chatlen = sizeof chat; - if (sc_hex_to_bin(optarg, chat, &chatlen) < 0) { + pace_input.chat = chat; + pace_input.chat_length = sizeof chat; + if (sc_hex_to_bin(optarg, (u8 *) pace_input.chat, + &pace_input.chat_length) < 0) { parse_error(argv[0], options, option_help, optarg, oindex); exit(2); } break; case OPT_CERTDESC: - desclen = sizeof desc; - if (sc_hex_to_bin(optarg, desc, &desclen) < 0) { + pace_input.certificate_description = desc; + pace_input.certificate_description_length = sizeof desc; + if (sc_hex_to_bin(optarg, (u8 *) pace_input.certificate_description, + &pace_input.certificate_description_length) < 0) { parse_error(argv[0], options, option_help, optarg, oindex); exit(2); } @@ -353,37 +302,56 @@ main (int argc, char **argv) } if (doresumepin) { + pace_input.pin_id = PACE_CAN; + if (can) { + pace_input.pin = can; + pace_input.pin_length = strlen(can); + } else { + pace_input.pin = NULL; + pace_input.pin_length = 0; + } t_start = time(NULL); - i = pace_get_channel(NULL, card, - PACE_CAN, can, can ? strlen(can) : 0, - chat, chatlen, desc, desclen, - &channeldata, &channeldatalen, &tmpctx); + i = EstablishPACEChannel(NULL, card, pace_input, &out, &outlen, + &tmpctx); + t_end = time(NULL); if (i < 0) goto err; - t_end = time(NULL); printf("Established PACE channel with CAN in %.0fs.\n", difftime(t_end, t_start)); - i = pace_get_channel(&tmpctx, card, - PACE_PIN, pin, pin ? strlen(pin) : 0, - chat, chatlen, desc, desclen, - &channeldata, &channeldatalen, &sctx); + pace_input.pin_id = PACE_PIN; + if (pin) { + pace_input.pin = pin; + pace_input.pin_length = strlen(pin); + } else { + pace_input.pin = NULL; + pace_input.pin_length = 0; + } + t_start = time(NULL); + i = EstablishPACEChannel(&tmpctx, card, pace_input, &out, &outlen, + &sctx); + t_end = time(NULL); if (i < 0) goto err; - t_start = time(NULL); printf("Established PACE channel with PIN in %.0fs. PIN resumed.\n", - difftime(t_start, t_end)); + difftime(t_end, t_start)); } if (dounblock) { + pace_input.pin_id = PACE_PUK; + if (puk) { + pace_input.pin = puk; + pace_input.pin_length = strlen(puk); + } else { + pace_input.pin = NULL; + pace_input.pin_length = 0; + } t_start = time(NULL); - i = pace_get_channel(NULL, card, - PACE_PUK, puk, puk ? strlen(puk) : 0, - chat, chatlen, desc, desclen, - &channeldata, &channeldatalen, &sctx); + i = EstablishPACEChannel(NULL, card, pace_input, &out, &outlen, + &sctx); + t_end = time(NULL); if (i < 0) goto err; - t_end = time(NULL); printf("Established PACE channel with PUK in %.0fs.\n", difftime(t_end, t_start)); @@ -394,14 +362,20 @@ main (int argc, char **argv) } if (dochangepin) { + pace_input.pin_id = PACE_PIN; + if (pin) { + pace_input.pin = pin; + pace_input.pin_length = strlen(pin); + } else { + pace_input.pin = NULL; + pace_input.pin_length = 0; + } t_start = time(NULL); - i = pace_get_channel(NULL, card, - PACE_PIN, pin, pin ? strlen(pin) : 0, - chat, chatlen, desc, desclen, - &channeldata, &channeldatalen, &sctx); + i = EstablishPACEChannel(NULL, card, pace_input, &out, &outlen, + &sctx); + t_end = time(NULL); if (i < 0) goto err; - t_end = time(NULL); printf("Established PACE channel with PIN in %.0fs.\n", difftime(t_end, t_start)); @@ -412,20 +386,32 @@ main (int argc, char **argv) } if (dotranslate || (!doresumepin && !dochangepin && !dounblock)) { - enum s_type id; - const char *s; + pace_input.pin = NULL; + pace_input.pin_length = 0; if (usepin) { - id = PACE_PIN; - s = pin; + pace_input.pin_id = PACE_PIN; + if (pin) { + pace_input.pin = pin; + pace_input.pin_length = strlen(pin); + } } else if (usecan) { - id = PACE_CAN; - s = can; + pace_input.pin_id = PACE_CAN; + if (can) { + pace_input.pin = can; + pace_input.pin_length = strlen(can); + } } else if (usemrz) { - id = PACE_MRZ; - s = mrz; + pace_input.pin_id = PACE_MRZ; + if (mrz) { + pace_input.pin = mrz; + pace_input.pin_length = strlen(mrz); + } } else if (usepuk) { - id = PACE_PUK; - s = puk; + pace_input.pin_id = PACE_PUK; + if (puk) { + pace_input.pin = puk; + pace_input.pin_length = strlen(puk); + } } else { fprintf(stderr, "Please specify whether to do PACE with " "PIN, CAN, MRZ or PUK."); @@ -433,14 +419,13 @@ main (int argc, char **argv) } t_start = time(NULL); - i = pace_get_channel(NULL, card, id, s, s ? strlen(s) : 0, - chat, chatlen, desc, desclen, - &channeldata, &channeldatalen, &sctx); + i = EstablishPACEChannel(NULL, card, pace_input, &out, &outlen, + &sctx); + t_end = time(NULL); if (i < 0) goto err; - t_end = time(NULL); printf("Established PACE channel with %s in %.0fs.\n", - pace_secret_name(id), difftime(t_end, t_start)); + pace_secret_name(pace_input.pin_id), difftime(t_end, t_start)); if (dotranslate) { i = pace_translate_apdus(&sctx, card); diff --git a/ccid/src/pace.c b/ccid/src/pace.c index 9857b6f..1a237a5 100644 --- a/ccid/src/pace.c +++ b/ccid/src/pace.c @@ -958,14 +958,12 @@ void ssl_error(sc_context_t *ctx) { } int EstablishPACEChannel(const struct sm_ctx *oldpacectx, sc_card_t *card, - const __u8 *in, size_t inlen, __u8 **out, size_t *outlen, struct sm_ctx *sctx) + struct establish_pace_channel_input pace_input, + __u8 **out, size_t *outlen, struct sm_ctx *sctx) { - __u8 pin_id; - size_t length_chat, length_pin, length_cert_desc, length_ef_cardaccess, recent_car_len, prev_car_len; - const __u8 *chat, *pin, *certificate_description; + size_t length_ef_cardaccess, recent_car_len, prev_car_len; __u8 *ef_cardaccess = NULL, *p = NULL, *recent_car = NULL, *prev_car = NULL; PACEInfo *info = NULL; - __le16 word; PACEDomainParameterInfo *static_dp = NULL, *eph_dp = NULL; BUF_MEM *enc_nonce = NULL, *nonce = NULL, *mdata = NULL, *mdata_opp = NULL, *k_enc = NULL, *k_mac = NULL, *token_opp = NULL, @@ -973,67 +971,13 @@ int EstablishPACEChannel(const struct sm_ctx *oldpacectx, sc_card_t *card, PACE_SEC *sec = NULL; PACE_CTX *pctx = NULL; int r; + __le16 word; if (!card) return SC_ERROR_CARD_NOT_PRESENT; - if (!in || !out || !outlen) + if (!out || !outlen) return SC_ERROR_INVALID_ARGUMENTS; - if (inlen < 1) { - sc_error(card->ctx, "Buffer too small, could not get PinID"); - SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_INVALID_DATA); - } - pin_id = *in; - in++; - - if (inlen < 1+1) { - sc_error(card->ctx, "Buffer too small, could not get lengthCHAT"); - SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_INVALID_DATA); - } - length_chat = *in; - in++; - if (inlen < 1+1+length_chat) { - sc_error(card->ctx, "Buffer too small, could not get CHAT"); - SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_INVALID_DATA); - } - chat = in; - in += length_chat; - /* XXX make this human readable */ - if (length_chat) - bin_log(card->ctx, "Card holder authorization template", - chat, length_chat); - - if (inlen < 1+1+length_chat+1) { - sc_error(card->ctx, "Buffer too small, could not get lengthPIN"); - SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_INVALID_DATA); - } - length_pin = *in; - in++; - if (inlen < 1+1+length_chat+1+length_pin) { - sc_error(card->ctx, "Buffer too small, could not get PIN"); - SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_INVALID_DATA); - } - pin = in; - in += length_pin; - - if (inlen < 1+1+length_chat+1+length_pin+sizeof(word)) { - sc_error(card->ctx, "Buffer too small, could not get lengthCertificateDescription"); - SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_INVALID_DATA); - } - memcpy(&word, in, sizeof word); - length_cert_desc = __le16_to_cpu(word); - in += sizeof word; - if (inlen < 1+1+length_chat+1+length_pin+sizeof(word)+length_cert_desc) { - sc_error(card->ctx, "Buffer too small, could not get CertificateDescription"); - SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_INVALID_DATA); - } - certificate_description = in; - /* XXX make this human readable */ - if (length_cert_desc) - bin_log(card->ctx, "Certificate description", - certificate_description, length_cert_desc); - - if (!oldpacectx) { /* PACE is executed the first time */ r = get_ef_card_access(card, &ef_cardaccess, &length_ef_cardaccess); @@ -1069,7 +1013,8 @@ int EstablishPACEChannel(const struct sm_ctx *oldpacectx, sc_card_t *card, goto err; } - r = pace_mse_set_at(oldpacectx, card, info->protocol, pin_id, chat, length_chat, *out, (*out)+1); + r = pace_mse_set_at(oldpacectx, card, info->protocol, pace_input.pin_id, + pace_input.chat, pace_input.chat_length, *out, (*out)+1); if (r < 0) { sc_error(card->ctx, "Could not select protocol proberties " "(MSE: Set AT)."); @@ -1091,7 +1036,8 @@ int EstablishPACEChannel(const struct sm_ctx *oldpacectx, sc_card_t *card, bin_log(card->ctx, "Encrypted nonce from MRTD", (u8 *)enc_nonce->data, enc_nonce->length); enc_nonce->max = enc_nonce->length; - sec = get_psec(card, (char *) pin, length_pin, pin_id); + sec = get_psec(card, (char *) pace_input.pin, pace_input.pin_length, + pace_input.pin_id); if (!sec) { sc_error(card->ctx, "Could not encode PACE secret."); ssl_error(card->ctx); diff --git a/ccid/src/pace.h b/ccid/src/pace.h index 2c3e479..1a72589 100644 --- a/ccid/src/pace.h +++ b/ccid/src/pace.h @@ -66,10 +66,42 @@ int pace_sm_pre_transmit(sc_card_t *card, const struct sm_ctx *ctx, int pace_sm_post_transmit(sc_card_t *card, const struct sm_ctx *ctx, sc_apdu_t *sm_apdu); + +struct establish_pace_channel_input { + unsigned char pin_id; + + size_t chat_length; + const unsigned char *chat; + + size_t pin_length; + const unsigned char *pin; + + size_t certificate_description_length; + const unsigned char *certificate_description; +}; + +struct establish_pace_channel_output { + unsigned char mse_set_at_sw1; + unsigned char mse_set_at_sw2; + + size_t ef_cardaccess_length; + unsigned char *ef_cardaccess; + + size_t recent_car_length; + unsigned char *recent_car; + + size_t previous_car_length; + unsigned char *previous_car; + + size_t id_icc_length; + unsigned char *id_icc; +}; + int GetReadersPACECapabilities(sc_card_t *card, const unsigned char *in, size_t inlen, unsigned char **out, size_t *outlen); int EstablishPACEChannel(const struct sm_ctx *oldpacectx, sc_card_t *card, - const unsigned char *in, size_t inlen, unsigned char **out, size_t *outlen, struct sm_ctx *sctx); + struct establish_pace_channel_input pace_input, + unsigned char **out, size_t *outlen, struct sm_ctx *sctx); int pace_reset_retry_counter(struct sm_ctx *ctx, sc_card_t *card, enum s_type pin_id, int ask_for_secret,