From Martin Kaiser via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7275 :
iso7816: dissect ATR (answer to reset) svn path=/trunk/; revision=42814
This commit is contained in:
parent
84bfae28e0
commit
25e70c04d7
|
@ -36,12 +36,27 @@
|
|||
#include <glib.h>
|
||||
|
||||
#include <epan/packet.h>
|
||||
#include <epan/expert.h>
|
||||
|
||||
static int proto_iso7816 = -1;
|
||||
|
||||
static int ett_iso7816 = -1;
|
||||
static int ett_iso7816_atr_td = -1;
|
||||
|
||||
static int hf_iso7816_atr = -1;
|
||||
static int hf_iso7816_atr_init_char = -1;
|
||||
static int hf_iso7816_atr_t0 = -1;
|
||||
static int hf_iso7816_atr_ta = -1;
|
||||
static int hf_iso7816_atr_tb = -1;
|
||||
static int hf_iso7816_atr_tc = -1;
|
||||
static int hf_iso7816_atr_td = -1;
|
||||
static int hf_iso7816_atr_next_ta_present = -1;
|
||||
static int hf_iso7816_atr_next_tb_present = -1;
|
||||
static int hf_iso7816_atr_next_tc_present = -1;
|
||||
static int hf_iso7816_atr_next_td_present = -1;
|
||||
static int hf_iso7816_atr_k = -1;
|
||||
static int hf_iso7816_atr_t = -1;
|
||||
static int hf_iso7816_atr_hist_bytes = -1;
|
||||
static int hf_iso7816_atr_tck = -1;
|
||||
static int hf_iso7816_cla = -1;
|
||||
static int hf_iso7816_ins = -1;
|
||||
static int hf_iso7816_p1 = -1;
|
||||
|
@ -55,6 +70,12 @@ static int hf_iso7816_sw2 = -1;
|
|||
#define ADDR_INTF "Interface"
|
||||
#define ADDR_CARD "Card"
|
||||
|
||||
static const value_string iso7816_atr_init_char[] = {
|
||||
{ 0x3B, "Direct convention (A==0, Z==1, MSB==m9)" },
|
||||
{ 0x3F, "Inverse convention (A==1, Z==0, MSB==m2)" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static const value_string iso7816_ins[] = {
|
||||
{ 0x0E, "Erase binary" },
|
||||
{ 0x20, "Verify" },
|
||||
|
@ -69,13 +90,102 @@ static const value_string iso7816_ins[] = {
|
|||
static int
|
||||
dissect_iso7816_atr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||
{
|
||||
gint offset = 0;
|
||||
gint offset=0;
|
||||
guint i=0; /* loop index for TA(i)...TD(i) */
|
||||
proto_item *td_it;
|
||||
proto_tree *td_tree=NULL;
|
||||
guint8 ta, tb, tc, td, k=0;
|
||||
gint tck_len;
|
||||
proto_item *err_it;
|
||||
|
||||
col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "ATR sequence");
|
||||
|
||||
proto_tree_add_item(tree, hf_iso7816_atr, tvb, offset,
|
||||
tvb_reported_length_remaining(tvb, offset), ENC_NA);
|
||||
offset += tvb_reported_length_remaining(tvb, offset);
|
||||
/* ISO 7816-4, section 4 indicates that concatenations are big endian */
|
||||
proto_tree_add_item(tree, hf_iso7816_atr_init_char,
|
||||
tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
offset++;
|
||||
|
||||
do {
|
||||
/* for i==0, this is the T0 byte, otherwise it's the TD(i) byte
|
||||
in each loop, we dissect T0/TD(i) and TA(i+1), TB(i+1), TC(i+1) */
|
||||
td = tvb_get_guint8(tvb, offset);
|
||||
if (i==0) {
|
||||
td_it = proto_tree_add_item(tree, hf_iso7816_atr_t0,
|
||||
tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
}
|
||||
else {
|
||||
td_it = proto_tree_add_uint_format(tree, hf_iso7816_atr_td,
|
||||
tvb, offset, 1, td,
|
||||
"Interface character TD(%d): 0x%02x", i, td);
|
||||
}
|
||||
td_tree = proto_item_add_subtree(td_it, ett_iso7816_atr_td);
|
||||
|
||||
proto_tree_add_boolean_format(td_tree, hf_iso7816_atr_next_ta_present,
|
||||
tvb, offset, 1, td&0x10,
|
||||
"TA(%d) present: %s", i+1, td&0x10 ? "True" : "False");
|
||||
proto_tree_add_boolean_format(td_tree, hf_iso7816_atr_next_tb_present,
|
||||
tvb, offset, 1, td&0x20,
|
||||
"TB(%d) present: %s", i+1, td&0x20 ? "True" : "False");
|
||||
proto_tree_add_boolean_format(td_tree, hf_iso7816_atr_next_tc_present,
|
||||
tvb, offset, 1, td&0x40,
|
||||
"TC(%d) present: %s", i+1, td&0x40 ? "True" : "False");
|
||||
proto_tree_add_boolean_format(td_tree, hf_iso7816_atr_next_td_present,
|
||||
tvb, offset, 1, td&0x80,
|
||||
"TD(%d) present: %s", i+1, td&0x80 ? "True" : "False");
|
||||
|
||||
if (i==0) {
|
||||
k = td&0x0F; /* number of historical bytes */
|
||||
proto_tree_add_item(td_tree, hf_iso7816_atr_k,
|
||||
tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
}
|
||||
else {
|
||||
proto_tree_add_item(td_tree, hf_iso7816_atr_t,
|
||||
tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
}
|
||||
offset++;
|
||||
|
||||
if (td&0x10) {
|
||||
ta = tvb_get_guint8(tvb, offset);
|
||||
/* we read TA(i+1), see comment above */
|
||||
proto_tree_add_uint_format(tree, hf_iso7816_atr_ta, tvb, offset, 1,
|
||||
ta, "Interface character TA(%d): 0x%02x", i+1, ta);
|
||||
offset++;
|
||||
}
|
||||
if (td&0x20) {
|
||||
tb = tvb_get_guint8(tvb, offset);
|
||||
proto_tree_add_uint_format(tree, hf_iso7816_atr_tb, tvb, offset, 1,
|
||||
tb, "Interface character TB(%d): 0x%02x", i+1, tb);
|
||||
offset++;
|
||||
}
|
||||
if (td&0x40) {
|
||||
tc = tvb_get_guint8(tvb, offset);
|
||||
proto_tree_add_uint_format(tree, hf_iso7816_atr_tc, tvb, offset, 1,
|
||||
tc, "Interface character TC(%d): 0x%02x", i+1, tc);
|
||||
offset++;
|
||||
}
|
||||
|
||||
i++;
|
||||
} while (td&0x80);
|
||||
|
||||
if (k>0) {
|
||||
proto_tree_add_item(tree, hf_iso7816_atr_hist_bytes,
|
||||
tvb, offset, k, ENC_NA);
|
||||
offset += k;
|
||||
}
|
||||
|
||||
tck_len = tvb_reported_length_remaining(tvb, offset);
|
||||
/* tck is either absent or exactly one byte */
|
||||
if (tck_len==1) {
|
||||
proto_tree_add_item(tree, hf_iso7816_atr_tck,
|
||||
tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
offset++;
|
||||
}
|
||||
else if (tck_len>1) {
|
||||
err_it = proto_tree_add_text(tree, tvb, offset, tck_len,
|
||||
"Invalid TCK byte");
|
||||
expert_add_info_format(pinfo, err_it, PI_PROTOCOL, PI_WARN,
|
||||
"TCK byte must either be absent or exactly one byte");
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
@ -212,9 +322,61 @@ void
|
|||
proto_register_iso7816(void)
|
||||
{
|
||||
static hf_register_info hf[] = {
|
||||
{ &hf_iso7816_atr,
|
||||
{ "ATR", "iso7816.atr",
|
||||
FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
|
||||
{ &hf_iso7816_atr_init_char,
|
||||
{ "Initial character", "iso7816.atr.init_char",
|
||||
FT_UINT8, BASE_HEX, VALS(iso7816_atr_init_char), 0, NULL, HFILL }
|
||||
},
|
||||
{ &hf_iso7816_atr_t0,
|
||||
{ "Format character T0", "iso7816.atr.t0",
|
||||
FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
|
||||
},
|
||||
{ &hf_iso7816_atr_ta,
|
||||
{ "Interface character TA(i)", "iso7816.atr.ta",
|
||||
FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
|
||||
},
|
||||
{ &hf_iso7816_atr_tb,
|
||||
{ "Interface character TB(i)", "iso7816.atr.tb",
|
||||
FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
|
||||
},
|
||||
{ &hf_iso7816_atr_tc,
|
||||
{ "Interface character TC(i)", "iso7816.atr.tc",
|
||||
FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
|
||||
},
|
||||
{ &hf_iso7816_atr_td,
|
||||
{ "Interface character TD(i)", "iso7816.atr.td",
|
||||
FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
|
||||
},
|
||||
{ &hf_iso7816_atr_next_ta_present,
|
||||
{ "TA(i+1) present", "iso7816.atr.next_ta_present",
|
||||
FT_BOOLEAN, BASE_HEX, NULL, 0x10, NULL, HFILL }
|
||||
},
|
||||
{ &hf_iso7816_atr_next_tb_present,
|
||||
{ "TB(i+1) present", "iso7816.atr.next_tb_present",
|
||||
FT_BOOLEAN, BASE_HEX, NULL, 0x20, NULL, HFILL }
|
||||
},
|
||||
{ &hf_iso7816_atr_next_tc_present,
|
||||
{ "TC(i+1) present", "iso7816.atr.next_tc_present",
|
||||
FT_BOOLEAN, BASE_HEX, NULL, 0x40, NULL, HFILL }
|
||||
},
|
||||
{ &hf_iso7816_atr_next_td_present,
|
||||
{ "TD(i+1) present", "iso7816.atr.next_td_present",
|
||||
FT_BOOLEAN, BASE_HEX, NULL, 0x80, NULL, HFILL }
|
||||
},
|
||||
{ &hf_iso7816_atr_k,
|
||||
{ "Number K of historical bytes", "iso7816.atr.k",
|
||||
FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
|
||||
},
|
||||
{ &hf_iso7816_atr_t,
|
||||
{ "Protocol reference T", "iso7816.atr.t",
|
||||
FT_UINT8, BASE_HEX, NULL, 0x0F, NULL, HFILL }
|
||||
},
|
||||
{ &hf_iso7816_atr_hist_bytes,
|
||||
{ "Historical bytes", "iso7816.atr.historical_bytes",
|
||||
FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
|
||||
},
|
||||
{ &hf_iso7816_atr_tck,
|
||||
{ "Check character TCK", "iso7816.atr.tck",
|
||||
FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
|
||||
},
|
||||
{ &hf_iso7816_cla,
|
||||
{ "Class", "iso7816.apdu.cla",
|
||||
|
@ -254,7 +416,8 @@ proto_register_iso7816(void)
|
|||
}
|
||||
};
|
||||
static gint *ett[] = {
|
||||
&ett_iso7816
|
||||
&ett_iso7816,
|
||||
&ett_iso7816_atr_td
|
||||
};
|
||||
|
||||
proto_iso7816 = proto_register_protocol(
|
||||
|
|
Loading…
Reference in New Issue