diff --git a/src/libopensc/ef-atr.c b/src/libopensc/ef-atr.c index 738306c7..89d08d3f 100644 --- a/src/libopensc/ef-atr.c +++ b/src/libopensc/ef-atr.c @@ -31,7 +31,7 @@ #include "asn1.h" #include "iso7816.h" -static int +static int sc_parse_ef_atr_content(struct sc_card *card, unsigned char *buf, size_t buflen) { struct sc_context *ctx = card->ctx; @@ -68,6 +68,21 @@ sc_parse_ef_atr_content(struct sc_card *card, unsigned char *buf, size_t buflen) ef_atr.df_selection, ef_atr.unit_size, ef_atr.card_capabilities); } + if (ef_atr.card_capabilities & ISO7816_CAP_EXTENDED_LENGTH_INFO) { + /* Extended Length Information in EF.ATR/INFO */ + tag = sc_asn1_find_tag(ctx, buf, buflen, ISO7816_TAG_II_EXTENDED_LENGTH, &taglen); + if (tag && taglen >= 8) { + /* The command- and response-APDU size limitations are defined by + * two integers, each nested in a DO'02'. + * We skip parsing the nested DOs and jump directly to the numbers */ + ef_atr.max_command_apdu = bebytes2ushort(tag + 2); + ef_atr.max_response_apdu = bebytes2ushort(tag + 6); + sc_log(ctx, "EF.ATR: Biggest command APDU %u bytes, response APDU %u", + (unsigned long) ef_atr.max_command_apdu, + (unsigned long) ef_atr.max_response_apdu); + } + } + tag = sc_asn1_find_tag(ctx, buf, buflen, ISO7816_TAG_II_AID, &taglen); if (tag) { if (taglen > sizeof(ef_atr.aid.value)) diff --git a/src/libopensc/iso7816.h b/src/libopensc/iso7816.h index 6b6f9cc1..c5334840 100644 --- a/src/libopensc/iso7816.h +++ b/src/libopensc/iso7816.h @@ -38,6 +38,11 @@ extern "C" { #define ISO7816_TAG_II_STATUS_LCS 0x81 #define ISO7816_TAG_II_STATUS_SW 0x82 #define ISO7816_TAG_II_STATUS_LCS_SW 0x83 +#define ISO7816_TAG_II_EXTENDED_LENGTH 0x7F66 + +#define ISO7816_CAP_CHAINING 0x80 +#define ISO7816_CAP_EXTENDED_LENGTH 0x40 +#define ISO7816_CAP_EXTENDED_LENGTH_INFO 0x20 /* Other interindustry data tags */ #define IASECC_TAG_II_IO_BUFFER_SIZES 0xE0 diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 5a76fcad..65d626ed 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -242,6 +242,8 @@ struct sc_ef_atr { unsigned char df_selection; size_t unit_size; unsigned char card_capabilities; + size_t max_command_apdu; + size_t max_response_apdu; struct sc_aid aid;