blob: 4736d6cc32e19a779b6036ac53fd3d84ecd6921e [file] [log] [blame]
Christina Quast69d1f902015-04-03 11:41:23 +02001import usb.core
2import usb.util
Christina Quastfb91bb72015-04-18 13:31:42 +02003import array
Christina Quast69d1f902015-04-03 11:41:23 +02004
Christina Quast88c7fa12015-04-06 00:35:03 +02005from ccid_raw import SmartcardConnection
Christina Quast158c1dd2015-04-17 20:19:29 +02006from smartcard_emulator import SmartCardEmulator
Christina Quast95270b12015-04-04 19:59:03 +02007
Christina Quast88c7fa12015-04-06 00:35:03 +02008from contextlib import closing
9
Christina Quastf2e53f02015-04-11 08:42:38 +020010from util import HEX
Christina Quast9547e9f2015-04-14 22:18:30 +020011from constants import *
Christina Quast53840612015-04-16 11:10:59 +020012from apdu_split import Apdu_splitter, apdu_states
Christina Quast88c7fa12015-04-06 00:35:03 +020013
Christina Quast69d1f902015-04-03 11:41:23 +020014def find_dev():
15 dev = usb.core.find(idVendor=0x03eb, idProduct=0x6004)
16 if dev is None:
17 raise ValueError("Device not found")
18 else:
19 print("Found device")
20 return dev
21
Christina Quast88c7fa12015-04-06 00:35:03 +020022def pattern_match(inpt):
23 print("Matching inpt", inpt)
Christina Quast94ddb912015-04-11 12:29:41 +020024 if (inpt == ATR_SYSMOCOM1) or (inpt == ATR_STRANGE_SIM):
25 print("ATR: ", inpt)
Christina Quast88c7fa12015-04-06 00:35:03 +020026 return NEW_ATR
27 elif (inpt == CMD_SEL_FILE):
Christina Quast94ddb912015-04-11 12:29:41 +020028 print("CMD_SEL_FILE:", inpt)
29 return CMD_SEL_ROOT
30 elif (inpt == CMD_GET_DATA):
31 print("CMD_DATA:", inpt)
Christina Quast88c7fa12015-04-06 00:35:03 +020032 return CMD_SEL_ROOT
33 else:
34 return inpt
Christina Quast69d1f902015-04-03 11:41:23 +020035
Christina Quast88c7fa12015-04-06 00:35:03 +020036def poll_ep(dev, ep):
37 try:
Christina Quast3a47a4f2015-04-11 18:16:14 +020038 return dev.read(ep, 64, 10)
Christina Quast88c7fa12015-04-06 00:35:03 +020039 except usb.core.USBError as e:
40 if e.errno != ERR_TIMEOUT:
41 raise
42 return None
Christina Quast69d1f902015-04-03 11:41:23 +020043
Christina Quast88c7fa12015-04-06 00:35:03 +020044def write_phone(dev, resp):
Christina Quastf2e53f02015-04-11 08:42:38 +020045 print("WR: ", HEX(resp))
Christina Quast3a47a4f2015-04-11 18:16:14 +020046 dev.write(PHONE_WR, resp, 10)
Christina Quast88c7fa12015-04-06 00:35:03 +020047
Christina Quast46a93672015-04-21 23:00:52 +020048def replace(data):
49 if data is None:
50 raise MITMReplaceError
51 else:
52 try:
53 if data[0] == 0x3B:
54 print("*** Replace ATR")
Christina Quastb6e005c2015-05-04 15:28:03 +020055 return array('B', NEW_ATR)
Christina Quast46a93672015-04-21 23:00:52 +020056 elif data[0] == 0x9F:
57 print("*** Replace return val")
58# return array('B', [0x60, 0x00])
Christina Quast34d4eb32015-05-04 17:50:32 +020059 elif data == PHONE_BOOK_RESP:
60 print("*** Replace phone book")
61 return PHONE_BOOK_RESP_MITM
Christina Quast46a93672015-04-21 23:00:52 +020062 except ValueError:
63 print("*** Value error! ")
64 return data
65
Christina Quast158c1dd2015-04-17 20:19:29 +020066def do_mitm(sim_emul=True):
Christina Quast69d1f902015-04-03 11:41:23 +020067 dev = find_dev()
Christina Quast158c1dd2015-04-17 20:19:29 +020068 if sim_emul == True:
69 my_class = SmartCardEmulator
70 else:
71 my_class = SmartcardConnection
72 with closing(my_class()) as sm_con:
Christina Quast6f664a32015-04-06 19:08:04 +020073 atr = sm_con.getATR()
Christina Quast53840612015-04-16 11:10:59 +020074
75 apdus = []
76 apdu = Apdu_splitter()
77
Christina Quast88c7fa12015-04-06 00:35:03 +020078 while True:
79 cmd = poll_ep(dev, PHONE_INT)
80 if cmd is not None:
Christina Quastf2e53f02015-04-11 08:42:38 +020081 print("Int line ", HEX(cmd))
Christina Quast88c7fa12015-04-06 00:35:03 +020082 assert cmd[0] == ord('R')
Christina Quast6f664a32015-04-06 19:08:04 +020083# FIXME: restart card anyways?
84# sm_con.reset_card()
Christina Quastf2e53f02015-04-11 08:42:38 +020085 print("Write atr: ", HEX(atr))
Christina Quast46a93672015-04-21 23:00:52 +020086 write_phone(dev, replace(atr))
Christina Quastfb91bb72015-04-18 13:31:42 +020087 apdus = []
88 apdu = Apdu_splitter()
Christina Quast69d1f902015-04-03 11:41:23 +020089
Christina Quast88c7fa12015-04-06 00:35:03 +020090 cmd = poll_ep(dev, PHONE_RD)
91 if cmd is not None:
Christina Quastf2e53f02015-04-11 08:42:38 +020092 print("RD: ", HEX(cmd))
Christina Quast53840612015-04-16 11:10:59 +020093 for c in cmd:
Christina Quastfb91bb72015-04-18 13:31:42 +020094 if apdu.state == apdu_states.APDU_S_FIN:
95 apdus.append(apdu)
96 apdu = Apdu_splitter()
97
Christina Quast53840612015-04-16 11:10:59 +020098 apdu.split(c)
Christina Quast08ea8612015-05-03 16:34:32 +020099 if apdu.state == apdu_states.APDU_S_FIN and apdu.pts_buf == [0xff, 0x00, 0xff]:
Christina Quastb6e005c2015-05-04 15:28:03 +0200100 #sim_data = sm_con.send_receive_cmd(apdu.pts_buf)
101 #write_phone(dev, replace(array('B', sim_data)))
102 write_phone(dev, replace(array('B', apdu.pts_buf)))
Christina Quast08ea8612015-05-03 16:34:32 +0200103 continue;
Christina Quastfb91bb72015-04-18 13:31:42 +0200104
Christina Quast53840612015-04-16 11:10:59 +0200105 if apdu.state == apdu_states.APDU_S_SW1:
Christina Quastfb91bb72015-04-18 13:31:42 +0200106 if apdu.data is not None and len(apdu.data) == 0:
Christina Quast53840612015-04-16 11:10:59 +0200107 # FIXME: implement other ACK types
Christina Quast46a93672015-04-21 23:00:52 +0200108 write_phone(dev, replace(array('B', [apdu.ins])))
Christina Quast53840612015-04-16 11:10:59 +0200109 apdu.split(apdu.ins)
110 else:
111 sim_data = sm_con.send_receive_cmd(apdu.buf)
Christina Quast46a93672015-04-21 23:00:52 +0200112 write_phone(dev, replace(sim_data))
Christina Quast53840612015-04-16 11:10:59 +0200113 for c in sim_data:
114 apdu.split(c)
Christina Quastfb91bb72015-04-18 13:31:42 +0200115 elif apdu.state == apdu_states.APDU_S_SEND_DATA:
Christina Quast46a93672015-04-21 23:00:52 +0200116 sim_data = sm_con.send_receive_cmd(replace(apdu.buf))
Christina Quastfb91bb72015-04-18 13:31:42 +0200117 sim_data.insert(0, apdu.ins)
Christina Quast46a93672015-04-21 23:00:52 +0200118 write_phone(dev, replace(sim_data))
Christina Quastfb91bb72015-04-18 13:31:42 +0200119 apdu.state = apdu_states.APDU_S_SW1
120 for c in sim_data:
121 apdu.split(c)